SOCKS

SOCKSは、インターネット・プロトコル・スイートにおいて、Transmission Control Protocolおよび User Datagram Protocolによる通信を代理するプロキシのプロトコルである。主にTCPのために設計されている。認証の機能の規定もあるため、それが実装されていれば認証にもとづき、認可された接続のみ接続を許可するような設定もできる。DARPAモデルの観点からは、3番めの層にあるTCP及びUDPによる通信を代理するものであり、使い方にも依るが通常は4番目のアプリケーション層からは透過ではない。例えばウェブブラウザのようなアプリケーションから利用する場合は、ネットワーク接続に関する設定として明示的にプロキシとして指定が必要である。ポート番号には1080がよく使われている。

1. 歴史
-----

SOCKSは当初、MIPS Computer Systemsのシステム管理者であるDavid Koblasによって開発された。Koblasは、MIPS Computer Systemsが1992年にSilicon Graphicsによって吸収合併された後に、その年のUsenix Security SymposiumでSOCKSの研究論文を公開した。これによりSOCKSはパブリックに利用できるようになった。SOCKSは、NECのYing-Da Leeによってバージョン4に拡張された。

SOCKS関連のアーキテクチャやクライアントはPermeo Technologiesが所有している。なお、Permeo Technologiesは、NECからスピンオフしたBlue Coat Systemsによって吸収合併された。

SOCKS5プロトコルは、もともとはファイアウォールの一部として、他のセキュリティ製品とともに管理を容易にするために作られたセキュリティプロトコルだった。1996年にIETFによって承認された。SOCKS5は、アジア外の技術を販売している企業Aventail Corporationの協力のもとに開発された。

2. 使用例
------

//SOCKS//は迂回のためのツールとしても使用されることがある。たとえば、政府、職場、学校、特定の国限定のウェブサービスなどで、インターネットのコンテンツへのアクセスフィルタやブロッキングが行われている場合に、それらを回避することができる。

たとえば、Tor onion proxyソフトウェアは、クライアントに対して、SOCKSインターフェイスを提供している。

OpenSSHはSOCKSプロトコルを利用した「動的ポートフォワード」の機能を持っている。SSHサーバ側で許可されていれば、クライアント側からは ssh コマンドにある -D オプションで利用でき、sshコマンドのプロセスがローカルなSOCKSプロキシのようにして見えるようになる。そのプロキシへの接続はSSHサーバ側へポートフォワードされ、最終的な接続先からはSSHサーバからのアクセスとして見える。。

3. サイバー犯罪における使用
---------------

クラッキングされたコンピュータには、ボットネットの制御を隠したりクレジットカード詐欺等といった、マルウェア的な目的のために、SOCKS proxyソフトウェアが設定されることがある。

4. 解説
-----

SOCKSは、ネットワーク・ファイアウォール越えやアクセス制御等を目的として、クライアントサーバ型のプロトコルが、透過的に使用できるよう設計されたプロキシのプロトコル、及びシステムである。"SOCKetS" の略。

いわゆるTCP/IPの4層モデルの観点からは、Internet Protocolの上の、TCPやUDPのようなトランスポート層における通信の手続きを中継・代理するメカニズムとなっている。SOCKSサーバ自身とクライアント間の通信はストリーム指向であり、一般にはLAN内からTCPで接続する。

プロトコル上は多段にもできるが、原理の説明には1段階で十分なので、以下はそのような前提とする。またファイアウォールを設けないシステムでもユースケースは考えられるが、以下ではファイアウォールの存在を前提とする。

似たような目的のための他のプロキシ類と同様、SOCKSサーバはその目的から、内外のネットワークの両方が見えるファイアウォール自身、あるいはDMZ内に置く。そうでない場合は、SOCKSサーバのみは外部との通信を可能にする、あるいは、内部からSOCKサーバにだけは通信を可能にする、といったような設定が必要となる。

そして、内側から外部に通信する必要があるノードは、代わりにSOCKSサーバに接続し、SOCKSサーバがプロキシとして代わりに外部と通信する。SOCKSプロキシは、例えば、クライアントが外部サーバにアクセスする資格を制御するなどといった、認証や認可を掛けることもできる。SOCKSはまた正反対にも使用することができる。つまり、ファイアウォールの外側の許可された外部クライアントのみが、物理的にはファイアウォールの内側にある、公開のサービスを提供するサーバのみに接続できるようにする、といった用途のための設定もできる。

5. プロトコル
--------

5.1. SOCKS 4
------------

標準の SOCKS 4 接続では、以下のような通信が行われる。

SOCKS クライアントからサーバ:

フィールド 1: SOCKS バージョン番号,1バイト,このバージョンでは 0x04 でなくてはならない
フィールド 2: コマンドコード,1バイト：
0x01 = TCP/IP ストリーム接続を確立する
0x02 = TCP/IP ポートバインディングを確立する
フィールド 3: ネットワークバイトオーダのポート番号,2バイト
フィールド 4: ネットワークバイトオーダの IP アドレス,4バイト
フィールド 5: ユーザID文字列, 可変長, null  で終了させるSOCKS サーバからクライアント:

フィールド 1: null バイト
フィールド 2: 状態,1バイト
0x5a = リクエストの許可
0x5b = リクエストの拒絶または失敗
0x5c = リクエストはクライアントが identd を起動していなかったので失敗
0x5d = リクエストはクライアントの identd がリクエストにユーザID文字列を確認できなかったので失敗
フィールド 3: 任意の2バイト,無視されなければならない
フィールド 4: 任意の4バイト,無視されなければならない例:

これは、66.102.7.99:80にユーザ「Fred」を接続する SOCKS 4 のリクエストである。そして、サーバは、"OK"の返事をする。

クライアント: 0x04 | 0x01 | 0x00 0x50 | 0x42 0x66 0x07 0x63 | 0x46 0x72 0x65 0x64 0x00
最後のフィールドは ASCII コードの「Fred」であり、次に1バイトの null が続く
サーバ: 0x00 | 0x5a | 0xXX 0xXX | 0xXX 0xXX 0xXX 0xXX
0xXX は全てのバイト値になることができる。 Socks 4 プロトコルはそれらのバイト値が無視されなければならないことを規定している。この時点以降、 SOCKS クライアントから SOCKS サーバまで送る全てのデータは66.102.7.99に向けて中継される。そして、 SOCKS サーバから SOCKS クライアントに送る場合も同様である。

コマンドフィールドは、 "connect" で 0x01 、あるいは、 "bind" で 0x02 になることができる。 "bind" は動作中の FTP のようなプロトコルのために入ってくる接続を許可する。

5.2. SOCKS 4a
-------------

SOCKS 4a は、 SOCKS 4 プロトコルのシンプルな拡張機能であり、宛先ホストのドメイン名を解決できないクライアントがドメイン名を指定することを可能にする。

クライアントは宛先アドレスの最初の3バイトを NULL に、そして最後のバイトを0でない値に設定すべきである。

ユーザ ID を終了する NULL バイトの次に、クライアントは宛先ドメイン名を送らなければならない、そして、それを別の NULL バイトで終了させなければならない。これは "connect" と "bind" の両方のリクエストに使われる。

SOCKS クライアントからサーバ:

フィールド 1: SOCKS バージョン番号,1バイト,このバージョンでは 0x04 でなくてはならない
フィールド 2: コマンドコード,1バイト：
0x01 = TCP/IP ストリーム接続を確立する
0x02 = TCP/IP ポートバインディングを確立する
フィールド 3: ネットワークバイトオーダのポート番号,2バイト
フィールド 4: ネットワークバイトオーダの IP アドレス,4バイト
フィールド 5: ユーザ ID 文字列, 可変長, null  で終了させる
フィールド 6: 接続先のホストのドメイン名, 可変長, null  で終了させるSOCKS サーバからクライアント:

フィールド 1: null バイト
フィールド 2: 状態,1バイト
0x5a = リクエストの許可
0x5b = リクエストの拒絶または失敗
0x5c = リクエストはクライアントが identd を起動していなかったので失敗
0x5d = リクエストはクライアントの identd がリクエストにユーザ ID 文字列を確認できなかったので失敗
フィールド 3: ネットワークバイトオーダのポート番号,2バイト
フィールド 4: ネットワークバイトオーダの IP アドレス,4バイト4A プロトコルを使用するサーバはリクエストパケット内の宛先アドレスをチェックしなければならない。宛先アドレスが、 x を非零の値としてアドレス 0.0.0.x を表現するならば、サーバはクライアントがパケット内に送付するドメイン名を読み込まなければならない。サーバはドメイン名を解決すべきであり、そしてそれが可能であるならば、宛先ホストへの接続を確立しなくてはならない。

5.3. SOCKS 5
------------

より多くの認証の選択を提供する SOCKS 4 プロトコルの拡張である SOCKS 5 プロトコルは [1] 内で定義されている。最初のハンドシェイクは下記の事項から成り立つ。

クライアントは接続し、サポートされた認証方法のリストを含む挨拶を送る。
サーバは一つ選ぶ。
いくつかのメッセージが、選択された認証方法に応じて、クライアントとサーバーの間を送受信される。
クライアントは、接続要求を SOCKS 4 と同じように送る。
サーバは SOCKS 4 と同じように応答する。サポートされた認証方法は次の通りに番号を割り付けている：

0x00 - 認証なし
0x01 - GSSAPI
0x02 - ユーザ名/パスワード
0x03-0x7F - IANA により割り当てられたメソッド
0x80-0xFE - プライベート使用のために予約されたメソッドクライアントからの最初の挨拶：

フィールド 1: SOCKS バージョンナンバ
フィールド 2: サポートされた認証方法の数,1バイト
フィールド 3: 認証方法, 可変長, サポートされたメソッドにつき1バイトサーバの選択が伝えられる：

フィールド 1: SOCKS バージョン, 1バイト
フィールド 2: 選択された認証方法, 1バイト, もしくはアクセスできないメソッドが提供した 0xFF次の認証は認証方法によって異なり、 [2] で記述されている。

クライアントの認証要求：

フィールド 1: バージョン番号, 1バイト
フィールド 2: ユーザ名長,1バイト
フィールド 3: ユーザ名
フィールド 4: パスワード長,1バイト
フィールド 5: パスワード認証のためのサーバの応答:

フィールド 1: バージョン, 1バイト
フィールド 2: 状態コード,1バイト
0x00 = 成功
他の全ての値 = 失敗, 接続は終了されなければならないクライアントの接続要求：

フィールド 1: SOCKS バージョン番号, 1バイト
フィールド 2: コマンドコード,1バイト：
0x01 = TCP/IP ストリーム接続を確立する
0x02 = TCP/IP ポートバインディングを確立する
0x03 = UDP ポートを結合させる
フィールド 3: 予約されている, 0x00 でなければならない
フィールド 4: アドレスタイプ, 1バイト:
0x01 = IPv4アドレス
0x03 = ドメイン名
0x04 = IPv6アドレス
フィールド 5: 宛先アドレス
IPv4 用の4バイト
1バイトのドメイン名長に続けて、ドメイン名
IPv6 用の16バイト
フィールド 6: ネットワークバイトオーダのポート番号, 2バイトサーバの応答：

フィールド 1: SOCKS プロトコルバージョン, 1バイト
フィールド2: 状態,1バイト
0x00 = リクエストの許可
0x01 = 一般的な失敗
0x02 = ルール設定により許可されない接続
0x03 = 到達できないネットワーク
0x04 = 到達できないホスト
0x05 = 宛先ホストにより拒否された接続
0x06 = TTL の期限切れ
0x07 = サポートされていないコマンド/ プロトコルエラー
0x08 = サポートされないアドレスタイプ
フィールド 3: 予約されている, 0x00 でなければならない
フィールド 4: アドレスの種類, 1バイト:
0x01 = IPv4 アドレス
0x03 = ドメイン名
0x04 = IPv6 アドレス
フィールド 5: サーバ側でbindされたアドレス
IPv4 用の4バイト
1バイトのドメイン名長に続けて、ドメイン名
IPv6 用の16バイト
フィールド 6: ネットワークバイトオーダのポート番号, 2バイトSOCKSによって外部ネットワークに接続する、全てのネットワーク・ソフトウェアの適合を可能にする "socksify"[3] というクライアント用のプログラムがある。

6. ソフトウェア
---------

[4] は [5] によって開発され、商業的サポートを伴ったオープンソースの SOCKS4/SOCKS5 実装である。
DeleGate 多機能なProxyソフトウェア。SOCKS4/SOCKS5サーバとしての他、多段プロキシ的に自身の接続のためにSOCKSを使うクライアントとしての機能もある。
[6] Windows 用の Socksifyer , 全てのアプリケーションは、一つの SOCKS あるいは HTTP proxy によって、そのネットワークトラフィックを透過的に実行することができる。
[7] ksb26  は socks 4/5 chains を介して、TCP接続をリダイレクトする Linux Kernel 2.6.x Loadable Kernel Module である。
OpenSSH は、動的ポートフォワード機能を利用するためのインタフェースのひとつとして、SOCKS プロトコルを使うことができる。OpenSSH クライアントを仮想的な SOCKS サーバの受付側にすることができ、接続先の OpenSSH サーバが仮想的な SOCKS サーバの出口側となって、クライアントからのネット接続を代理する。
[8] Multipurpose は  を中継する: socks4 とsocks4a の機能性を含む 
[9] はオープンソースの SOCKS4/SOCKS5 サーバである.
Tor
WinSocks は [10] により開発された軽量 SOCKS4/SOCKS5 サーバである。

7. 参考文献
-------

8. 外部リンク
--------

[11] Challenge-Handshake Authentication Protocol for SOCKS V5
3089}} - A SOCKS-based IPv6/IPv4 Gateway Mechanism
1961}} - GSS-API Authentication Method for SOCKS Version 5
1929}} - Username/Password Authentication for SOCKS V5
1928}} - SOCKS Protocol Version 5
[12] - SOCKS Protocol Version 4