Fabric のリモートコマンドは SSH を介して流れます。その SSH 接続を SOCKS サーバー経由で通すには、SOCKS を話し、接続先のバイトストリームを返すコネクタを Fabric に渡します。

Fabric 2 で導入された Connection API は、コマンド文字列を gateway として受け取ります。Fabric はその文字列を ProxyCommand として使います。プロキシオプションをサポートする OpenBSD 互換の nc があれば、設定は次のようになります。

from fabric import Connection

connection = Connection(
    "app.example.net",
    user="deploy",
    gateway="nc -X 5 -x proxy.example.net:1080 %h %p",
)

この例では通常の SSH ポート 22 を使います。コネクタの -X 5 は SOCKS5 を選び、-x はプロキシのエンドポイントを指定します。ホストとポートのプレースホルダーが SSH の接続先を渡します。公開 SSH 接続先の場合、SOCKS5 プロキシ一覧にある認証不要のエンドポイントが、その接続先とポートを許可していればプロキシのアドレスとして使えます。コマンドは、そのマシンに実際にインストールされたコネクタのオプションに合わせて設定してください。nc という名前のプログラムがすべて同じインターフェースを提供するわけではありません。

コネクタは Fabric が動作する場所でローカルに動作します。アプリケーションサーバーは、SSH の接続先であるという理由だけでその補助プログラムを必要としません。ストリームが確立された後も、Fabric は SSH のネゴシエーションを行い、deploy アカウントを app.example.net 上で認証します。SOCKS サーバーが要求する認証はコネクタ側のものであり、コネクタがサポートしている必要があります。

Fabric は ProxyCommand を SSH 設定から読むこともできます。同じ経路を複数の SSH ツールで使う場合に便利です。同じ接続先に対して、コマンド形式のゲートウェイと別個のジャンプホスト用ゲートウェイを組み合わせるのではなく、接続には意図した 1 つのゲートウェイ定義を使ってください。

中継者が SSH サーバーの場合

Fabric の Connection オブジェクトを gateway として渡すと意味が異なります。Fabric はその SSH ゲートウェイに接続し、最終ホストへのチャネルを要求します。SSH ジャンプホストにはその形式を使ってください。SOCKS リスナーは SSH サーバーではないため、上記のコマンド形式のコネクタが必要です。

このトランスポートの選択には明確な限界もあります。Fabric の SSH 接続を経路指定するだけです。リモートホスト上で実行されるコマンドが後からリポジトリやパッケージをダウンロードすると、そのプログラム自身のプロキシ設定に従って、そのホストから新しい外向き接続が作られます。

関連記事