人間とウェブの未来

「ウェブの歴史は人類の歴史の繰り返し」という観点から色々勉強しています。

クライアントプロセスのオーナ情報によるTCPを介した透過的な権限分離

研究アイデアや構想の公開

まつもとりースタイルとして、研究開発をしつつあいであがまとまってきたら公開しながらやっていくスタイルをとっていますので、国際会議などの延期に伴い、新しい研究をやり始めているのでそれをアイデアや構想ベースで公開します。

また、僕の研究のやり方として、まずはこのように考えて研究を組み立てているんだという紹介でもあります。是非ご笑覧下さい。

本研究のアイデア紹介

単一のOS環境に複数のテナントを配置するようなマルチテナント環境において、一般的に各テナント間での権限分離はプロセスのオーナやパーミッション情報を利用します。 一方で、Webホスティングサービスをはじめ、Webサービスにおいてもコンテナによって処理を担当するプロセスの権限分離が普及している状況において、データ処理に関しては、複数の異なるオーナのプロセスがデータベースのようなミドルウェアをネットワークを介して通信し共有することで実現されるケースがあります。

そのようなシステム構成においては、単一のOS内でのプロセス間は権限分離されていても、ネットワークを介した分散システムと捉えたときには、OS側の権限分離とは独立してユーザとパスワードによってデータベースを始めとしたミドルウェアの認証を行うことになります。 すなわち、アプリケーションやシステムの脆弱性によって、特定のプロセスが他のオーナのプロセスのユーザとパスワードを取得できた場合、容易に通信先ミドルウェアの情報にアクセスできることになります。 そこで、Linuxのプロセスのオーナ情報をTCPを介したミドルウェアの認証に付与し、特定のオーナからのみミドルウェアの認証を可能とする透過的なTCPを介した権限分離手法を考えています。

以下、研究の組み立てに使った言語化なので、デスマス調ではなくなります。

ユースケース・キラーアプリ

コンテナを使った分散システム環境

コンテナの普及によって、ステートレスな処理はコンテナで分離するようになってきているが、それによってよりデータの接続先が共有されるようにもなっていくかもしれない。その際に、コンテナのシステム周りで脆弱性があり、他のコンテナの処理のread権限があった場合に、データベースアクセス等の認証情報を得られると、ネットワークリーチアビリティがあるケースでは簡単にデータベースにアクセスして情報を抜くことができる。このようなケースでも、コンテナはプロセスであるのでオーナ情報等を利用して、接続先でオーナの情報を認証に追加しておけば、しかるべきコンテナからしかアクセスができないようになる。

コンテナの普及によって、処理の権限分離は進んでいるが、依然としてデータの権限分離はネットワークレベルでのセグメントを分ける程度の分離になっているので、提案手法を使うことで同じセグメントであってもプロセスの権限分離の情報をTCPの通信先でも有効であるように権限分離できるようになる。

大規模Webホスティング

Webホスティングサービスなどのマルチテナント環境において、オーナでテナントの権限分離を行っている状況で、とあるテナントが別テナントのファイルを何らかの脆弱性で読み取れた場合、DBは共有であることが多いため、簡単に別テナントのデータを抜き取れてしまう。そのような状況で、プロセスのオーナ情報もDB側で認証に使うことができれば、別テナントのデータを抜き取れなくなる。また、クライアントプロセス側でそのオーナ情報をコントロールしてDBにアクセスできると意味がないので、ユーザランドでは操作できないようにカーネル側で透過的にオーナ情報を伝達するようにする。

Webサービス

とあるアプリケーションが脆弱性により任意のコマンドを叩けるようになったという状況で、例えば、とあるスクリプトがデータのアップロード処理であり任意のコマンドを叩ける脆弱性を持っており、他のスクリプトにデータベース連携の処理がかかれているようなケースを想定した場合において、アップロードスクリプトがデータベース連携スクリプト等のread権限を保持することによって、他のアプリケーションが扱うDBなどのパスワードが書かれたプログラムや設定を読み取ることにより、同一OSに稼働しているアプリケーションの情報を抜かれる情報がある。この状況においても、アップロード処理とデータベース連携処理のオーナを分けておきさえすれば、データベースなどの通信先ミドルウェアが、通信元クライアントのオーナ情報を認証に利用することにより、認証を突破できなくすることができる。

これにより、そもそも、データベースアクセスするアプリケーションのオーナを分けるということ自体が、DBやネットワーク経由でのアクセスにおいてはあまりメリットがないため、あまり気にせず設計されているが、この研究によって、同一OS上で稼働している複数のアプリケーションもオーナを分けることによってセキュリティのリスクを限定的にすることが可能になる。

DBの認証

キラーアプリ的には上述したとおり、マルチテナント環境や複数のアプリケーションからTCP接続でDB認証する際に、オーナ単位でさらに細かく認証を行えるようにするようなDBのプラグインが上げられる。このような、TCPを介したミドルウェアの認証にクライアントプロセスのオーナ情報を活用する系の拡張が主なキラーアプリになりうるだろうと思える。

設計

プロセスからTCPを介して接続する際に、TCP/IPヘッダのどこかにプロセスのオーナ情報を埋め込むカーネルモジュールやTCPスタックを作る。つまり、基本戦略として、ユーザランド側からはそのオーナ情報を変更することは不可能になるようにカーネル側で制御する。

その上で、TCPを介した接続先のプロセスでは、埋め込まれたオーナ情報を取得できるようにする。これもユーザランドで改変できると意味がないので、基本的にはカーネル側で構造体を持ちたい。が、まずの最小スコープとしては、クライアント側からの認証について、オーナを使って認証できれば良いとすると、サーバ側ではライブラリなどでオーナ情報を取得できるようにし、そのライブラリを使ってミドルウェアで認証を行うプラグインやモジュールなどを開発するというのでも良さそうだ。

@pyama86 さんのSTNSによるユーザ名の名前解決などを活用する*1ことにより、オーナ情報をうまく統一的に扱う方法があるかも?

実装

ユーザランドで操作可能にしては、アプリケーションの脆弱性を踏まれる、すなわち、最悪の場合はそのプロセスをのっとれるわけなので、プロセスのオーナ情報は透過的にユーザランドでコントロール不可能にしながらカーネル側で制御する必要がある。

そこで、ひとまずの最小スコープとしてDBなどにアクセスするクライアント側のプロセスが起動しているカーネルのカーネルモジュールから、TCP/IPスタックにおいてヘッダ情報のどこかに、プロセスのオーナに関するtask_struct構造体の情報を埋め込む。その上で、接続先のDBのようなミドルウェアが起動しているOS上でTCP/IPヘッダを読み取るライブラリによって、そのオーナ情報を受取る。これはユーザランドでも一旦良い(ミドルウェア側の脆弱性は一旦別問題とする)。そして、DBをはじめとしたミドルウェアのプラグインやモジュールで、そのライブラリを利用してオーナ情報を取得し、認証に利用できるような実装にすることで、データベースだけでなく、各種TCP通信による認証系の共有ミドルウェアに対して、接続元クライアントのID/PASSに加えた独自性の高いオーナ情報を利用することにより、セキュアなシステムが組める。

問題としては、オーナ情報のシステム全体としての一意性をどうするかなどがあるが、比較的小規模システムにおいては、オーナは個別にかぶらないように設定することもあるので、利用できることが多そうではある。

実験

ひとまず強引にでもカーネルモジュール or テスト的にTCPスタックをユーザランドに組んで*2*3、そこからヘッダにオーナ情報を埋め込みつつ通信して、それを接続先から取り出すような実装を行って試す。

それをミドルウェアで認証に使ってたしかに制限できていることも確認や、それを利用することによるスループットやオーバーヘッドの差を調べるとか。