私が使用している孤立したネットワークに到達するにはSSH -D
靴下 代理人。
追加するたびに詳細を入力したくない場合は、次の手順に従います~/.ssh/config
。
$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
Hostname pcit
BatchMode yes
RequestTTY no
Compression yes
DynamicForward localhost:9118
それから私はシステムユーザーサービスユニット定義ファイル:
$ 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
これは期待どおりに機能します。その後、手動でサービスを開始したり永久に実行したりするのを防ぎたいと思います。自動SSH、使用してシステム ソケットの有効化オンデマンド(再生)生成に使用されます。うまくいかないようです。 (マイバージョン)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
死ぬか殺されるまで働きます。これにより、次の接続試行時に再生成されません。
質問:
- / usr / bin / sshがsystemdによって渡されたソケットを受け入れることができないというのは本当ですか?それとも最新バージョンですか?私のもの最新のDebian 8.9の1つ。
- このオプションはルートユニットでのみ使用できますか
BindTodevice
? - 古いトンネルが期限切れになった後、最初の新しい接続でプロキシサービスが正しく再生成されないのはなぜですか?
- これが「要求時にSSHプロキシ」を設定する正しい方法ですか?そうでなければどうしますか?
答え1
- / usr / bin / sshがsystemdによって渡されたソケットを受け入れることができないというのは本当ですか?
次の点を考慮すると、これはあまり驚くべきことではないようです。
- OpenSSHはOpenBSDプロジェクトです
- systemdはLinuxカーネルのみをサポートします。
- systemdサポートはオプション/ビルドタイム依存関係でOpenSSHに明示的に追加する必要があるため、販売が難しい場合があります。
- このオプションはルートユニットでのみ使用できますか
BindTodevice
?
ユーザーの systemd インスタンスは、マスター pid-0 インスタンスと通信できないなど、非常に隔離されていることがよくあります。ユーザー単位ファイルのシステム単位に依存するようなことは不可能です。
言及された文書BindToDevice
:
このパラメータを設定すると、デバイスに追加の依存関係が追加される可能性があります(上記を参照)。
上記の制限により、このオプションはユーザーのシステムインスタンスに影響を与えないことを暗示できます。
- 古いトンネルが期限切れになった後、最初の新しい接続でプロキシサービスが正しく再生成されないのはなぜですか?
私が知っている限り、一連のイベントは次のとおりです。
SocksProxyHelper.socket
始まった。- SOCKSクライアントはlocalhost:8118に接続します。
- システムが起動します
SocksProxyHelper.service
。 - 依存関係として
SocksProxyHelper.service
systemdも起動しますSocksProxy.service
。 systemd-socket-proxyd
システムソケットを受け入れ、そのデータをssh
。ssh
死亡または殺された。- systemdはこれを認識して非アクティブに設定します
SocksProxy.service
が、何もしません。 SocksProxyHelper.service
ssh
引き続き実行され、接続を受け入れますが、実行されなくなったため接続できません。
修正は、そのドキュメントを引用して追加することですBindsTo=SocksProxy.service
(SocksProxyHelper.service
強調追加)。
設定には、スタイル設定された依存関係が必要です。ただし、この依存関係タイプは宣言された効果
Requires=
に加えてより強力です。Requires=
バインドされたユニットが停止すると、本ユニットも停止します。。つまり、突然無効になった他のデバイスにバインドされたデバイスも停止します。さまざまな理由で、デバイスが突然予期せず無効になることがあります。サービスユニットの主なプロセスはそれ自体で終了する可能性があります。、デバイスデバイスのサポートデバイスを取り外したり、デバイスが取り付けられている取り付けポイントをシステムおよびサービスマネージャの介入なしに取り外すことができます。同じデバイスに結合すると、
After=
動作がBindsTo=
より強力になります。この場合、そのユニットは次のようにバインドされます。デバイスも有効にするには厳密に有効にする必要があります。。これは、他のユニットにバインドされたユニットが突然非アクティブになるという意味に加えて、他のユニットにバインドされたユニットが条件の確認に失敗したためスキップしたことを意味します(例えば、、、、ConditionPathExists=
…ConditionPathIsSymbolicLink=
- 以下を参照)。ランニング。したがって、多くの場合でBindsTo=
一緒に使用するのが最善ですAfter=
。
- これが「要求時にSSHプロキシ」を設定する正しい方法ですか?そうでなければどうしますか?
「正しい方法」がない可能性があります。このアプローチには、利点(すべてが「オンデマンド」である)と欠点(systemdに依存し、sshがまだ受信を開始していないため、最初の接続が進行していない)があります。おそらくautosshでsystemdソケットアクティベーションサポートを実装する方が良い解決策になるでしょう。
答え2
後で参照できるように、systemd --user
以下のデーモンを使用して、オンデマンドSSHトンネルの設定ファイルをsystemd-socket-proxyd
さまざまな改良と説明の説明と共に貼り付けました。
~/.config/systemd/user/ssh-tunnel-proxy.socket
[Unit]
Description=Socket-activation for SSH-tunnel
[Socket]
ListenStream=1000
[Install]
WantedBy=sockets.target
~/.config/systemd/user/ssh-tunnel-proxy.service
[Unit]
Description=Socket-activation proxy for SSH tunnel
## Stop also when stopped listening for socket-activation.
BindsTo=ssh-tunnel-proxy.socket
After=ssh-tunnel-proxy.socket
## Stop also when ssh-tunnel stops/breaks
# (otherwise, could not restart).
BindsTo=ssh-tunnel.service
After=ssh-tunnel.service
[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd --exit-idle-time=500s localhost:1001
~/.config/systemd/user/ssh-tunnel.service
[Unit]
Description=Tunnel to SSH server
## Stop-when-idle is controlled by `--exit-idle-time=` in proxy.service
# (from `man systemd-socket-proxyd`)
StopWhenUnneeded=true
[Service]
Type=simple
## Prefixed with `-` not to mark service as failed on net-fails;
# will be restarted on-demand by socket-activation.
ExecStart=-/usr/bin/ssh -kaxNT -o ExitOnForwardFailure=yes hostname_in_ssh_config -L 1001:localhost:2000
## Delay enough time to allow for ssh-authentication to complete
# so tunnel has been established before proxy process attaches to it,
# or else the first SYN request will be lost.
ExecStartPost=/bin/sleep 2
カスタムメイド
上記のスクリプトでは、次の文字列を置き換える必要があります。
1000
- (ssh-tunnel-proxy.socket
ドキュメント)
何(ホスト:)ポートローカルMYSqlポートエミュレーションなどのローカルリスニングトンネル用のソケットを有効にします。1001
- (ssh-tunnel-proxy.service
およびssh-tunnel.service
ファイル)
ローカルとは何ですか?(ホスト:)ポートエージェントが SSH サービスプロセスに渡すときに使用されます。
未使用のポートを選択してください。hostname_in_ssh_config
- (ssh-tunnel.service
ファイル)
接続するホストグループです。SSH構成 (すべてのSOCKS構成はここに属します)。localhost:2000
- (ssh-tunnel.service
ファイル)
SSHトンネルリモートホスト:ポートリモート MYSql がバインドされる場所と同じエンドポイントです。- x2 遅延時間(
ssh-tunnel-proxy.service
およびssh-tunnel.service
ドキュメント)
コメントに記載されています。 ssh-tunnel-...
- (すべてのユニットファイルのプレフィックス)
トンネリングの必要性を説明しますmysql-tunnel-...
。例: 。- SSH- (
Description=
すべてのユニットファイルのディレクティブで)
トンネリングの要件を説明しますMYSql
。例: 。
トンネルを制御するコマンド
# After any edits.
systemctl --user daemon-reload
# If socket's unit-file has been edited.
systemctl --user restart ssh-tunnel-proxy.socket
# To start listening for on-demand activation of the tunnel
systemctl --user start ssh-tunnel.socket
# To enable on-demand tunnel on Boot
systemctl --user enable ssh-tunnel-proxy.socket
# To gracefully stop tunnel (any cmd will do)
systemctl --user stop ssh-tunnel.service
systemctl --user stop ssh-tunnel-proxy.service
# To gracefully stop & disable tunnel (till next reboot)
systemctl --user stop ssh-tunnel-proxy.socket
# To view the health of the tunnel
systemctl --user status ssh-tunnel-proxy.{socket,service} ssh-tunnel
# To reset tunnel after errors (both cmds may be needed)
systemctl --user reset-failed ssh-tunnel ssh-tunnel-proxy
systemctl --user restart ssh-tunnel-proxy.socket
答え3
評判システムのため、@ankostisソリューションについては言及できません。
systemdにbash睡眠ループの使用を避けるためのオプションがあるようです。
はい、systemd-notifyがあります。
また、次のようにローカルポートの無駄を避けるために、systemd-socket-proxydとsshの間にソケットを使用するように@noamの提案と一緒に:
~/.config/systemd/user/ssh-tunnel-proxy.service
[Unit]
Description=Socket-activation proxy for SSH tunnel
## Stop also when stopped listening for socket-activation.
BindsTo=ssh-tunnel-proxy.socket
After=ssh-tunnel-proxy.socket
## Stop also when ssh-tunnel stops/breaks
# (otherwise, could not restart).
BindsTo=ssh-tunnel.service
After=ssh-tunnel.service
[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd --exit-idle-time=500s ${XDG_RUNTIME_DIR}/ssh-tunnel-proxy
~/.config/systemd/user/ssh-tunnel.service
[Unit]
Description=Tunnel to SSH server
## Stop-when-idle is controlled by `--exit-idle-time=` in proxy.service
# (from `man systemd-socket-proxyd`)
StopWhenUnneeded=true
[Service]
Type=notify
NotifyAccess=all
## Prefixed with `-` not to mark service as failed on net-fails;
# will be restarted on-demand by socket-activation.
ExecStart=-/usr/bin/ssh -kaxNT -o ExitOnForwardFailure=yes -o ControlMaster=no -o StreamLocalBindUnlink=yes -o PermitLocalCommand=yes -o LocalCommand="systemd-notify --ready" hostname_in_ssh_config -L ${XDG_RUNTIME_DIR}/ssh-tunnel-proxy:localhost:2000
ssh_configのマニュアルページでは、LocalCommand「サーバーに正常に接続した後にローカルコンピュータで実行するコマンドの指定」について説明します。
ControlMaster=no
多重化を使用するときにSSHセッションがマスターされないようにしてください。これは、同じホストに対する他のすべての多重化SSHセッションが自動的に閉じて終了するためです。
最後に、ソケットポートをlocalhostにバインドすることをお勧めします。
~/.config/systemd/user/ssh-tunnel-proxy.socket
[Unit]
Description=Socket-activation for SSH-tunnel
[Socket]
ListenStream=127.0.0.1:1000
ListenStream=[::1]:1000
[Install]
WantedBy=sockets.target
答え4
まだこれをテストしていますが(この回答を書くときに使用しています)、欠落している成分がバイナリに-o ExitOnForwardFailure=yes
オプションとして含まれていると思いますssh
。