隔離されたネットワークに到達するには、 ssh-D
socksproxy を使用します。
詳細を~/.ssh/config
に追加するたびに詳細を入力する手間を省くために:
$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
Hostname pcit
BatchMode yes
RequestTTY no
Compression yes
DynamicForward localhost:9118
次に systemd-user サービスユニット定義ファイルを作成しました。
$ cat ~/.config/systemd/user/SocksProxy.service
[Unit]
Description=SocksProxy Over Bridge Host
[Service]
ExecStart=/usr/bin/ssh -Nk socks-proxy
[Install]
WantedBy=default.target
デーモンに新しいサービス定義をリロードさせ、新しいサービスを有効にし、開始し、ステータスをチェックし、リスニングしていることを確認しました。
$ systemctl --user daemon-reload
$ systemctl --user list-unit-files | grep SocksP
SocksProxy.service disabled
$ systemctl --user enable SocksProxy.service
Created symlink from ~/.config/systemd/user/default.target.wants/SocksProxy.service to ~/.config/systemd/user/SocksProxy.service.
$ systemctl --user start SocksProxy.service
$ systemctl --user status SocksProxy.service
● SocksProxy.service - SocksProxy Over Bridge Host
Loaded: loaded (/home/alex/.config/systemd/user/SocksProxy.service; enabled)
Active: active (running) since Thu 2017-08-03 10:45:29 CEST; 2s ago
Main PID: 26490 (ssh)
CGroup: /user.slice/user-1000.slice/[email protected]/SocksProxy.service
└─26490 /usr/bin/ssh -Nk socks-proxy
$ netstat -tnlp | grep 118
tcp 0 0 127.0.0.1:9118 0.0.0.0:* LISTEN
tcp6 0 0 ::1:9118 :::* LISTEN
これは意図したとおりに機能します。次に、サービスを手動で開始したり、 systemdsocket-activation をオンデマンドで使用して autossh で恒久的に実行したりすることを避けたかった(再)産卵。 (私のバージョンの)ssh
はソケットファイル記述子を受信できないと思います。
私はドキュメント( 1 、 2 )を見つけました [例]systemd-socket-proxyd
-の使用について2つの「ラッパー」サービス、「サービス」と「ソケット」を作成するツール:
$ cat ~/.config/systemd/user/SocksProxyHelper.socket
[Unit]
Description=On Demand Socks proxy into Work
[Socket]
ListenStream=8118
#BindToDevice=lo
#Accept=yes
[Install]
WantedBy=sockets.target
$ cat ~/.config/systemd/user/SocksProxyHelper.service
[Unit]
Description=On demand Work Socks tunnel
After=network.target SocksProxyHelper.socket
Requires=SocksProxyHelper.socket SocksProxy.service
After=SocksProxy.service
[Service]
#Type=simple
#Accept=false
ExecStart=/lib/systemd/systemd-socket-proxyd 127.0.0.1:9118
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
$ systemctl --user daemon-reload
これはssh
が死ぬか殺されるまで機能するようです。そうすれば、次の接続試行時に必要なときに再生成されません。
BindTodevice
オプションを使用できますか?
- / usr/bin/sshは本当にsystemdで渡されたソケットを受け入れませんか?
次の点を考慮すると、それほど驚くことではないと思います。
- ルートのユニットのみが
BindTodevice
オプションを使用できますか?
ユーザーsystemdインスタンスは一般的にかなり隔離されています。メインのpid-0インスタンスと通信できません。ユーザー単位ファイルからシステム単位に依存するようなことはできません。
BindToDevice
のドキュメントには、次のように記載されています。
このパラメーターを設定すると、ユニットに追加の依存関係が追加される可能性があることに注意してください(上記を参照)。
上記の制限により、このオプションはユーザーのsystemdインスタンスからは機能しないことを意味します。
- 古いトンネルが停止した後、最初の新しい接続でプロキシサービスが正しく再生成されないのはなぜですか?
私が理解しているように、一連のイベントは次のとおりです。
SocksProxyHelper.socket
が開始されました。SocksProxyHelper.service
を起動します。SocksProxyHelper.service
の依存関係として、systemdもSocksProxy.service
を起動します。systemd-socket-proxyd
はsystemdソケットを受け入れ、そのデータをssh
に転送します。ssh
は死ぬか、殺されます。SocksProxy.service
を非アクティブ状態にしますが、何もしません。SocksProxyHelper.service
は実行を続け、接続を受け入れますが、ssh
は実行されていないため、接続に失敗します。修正は、BindsTo=SocksProxy.service
をSocksProxyHelper.service
に追加することです。そのドキュメントの引用(強調を追加):
要件の依存関係を構成します。スタイルは
Requires=
とよく似ています。ただし、この依存タイプはより強力です。Requires=
の効果に加えて、それはバインドされたユニットが停止すると、このユニットも停止すると宣言します。つまり、突然非アクティブ状態になった別のユニットにバインドされているユニットも停止します。ユニットは、さまざまな理由で突然、突然、非アクティブ状態になることがあります。サービスユニットのメインプロセスが独自に終了する可能性があります、デバイスユニットのバッキングデバイスが取り外されているか、マウントのマウントポイントですユニットは、システムおよびサービスマネージャの関与なしにマウント解除される場合があります。同じユニットで
After=
と組み合わせて使用すると、BindsTo=
の動作がさらに強力になります。この場合、バインドされているユニットはこのユニットもアクティブ状態になるには、厳密にアクティブ状態でなければなりませんです。これは、突然非アクティブ状態になる別のユニットにバインドされているユニットだけでなく、条件チェックの失敗によりスキップされた別のユニットにバインドされているユニット(ConditionPathExists=
、ConditionPathIsSymbolicLink=
、…など)も意味します—下記を参照)実行されている場合は停止します。したがって、多くの場合、BindsTo=
とAfter=
を組み合わせるのが最適です。
- これは「オンデマンドのSSHソックスプロキシ」を設定する正しい方法ですか?そうでない場合、どうやってそれを行うのですか?
おそらく「正しい方法」はありません。この方法には、長所(すべてが「オンデマンド」)と短所(systemdに依存しているため、sshがまだリッスンしていないため、最初の接続が通過しない)があります。おそらく、autosshにsystemdソケットアクティベーションサポートを実装する方が良いソリューションでしょう。