Ale*_*ies 19 ssh proxy systemd socks socket-activation
为了避免每次将详细信息添加到~/.ssh/config:
$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
Hostname pcit
BatchMode yes
RequestTTY no
Compression yes
DynamicForward localhost:9118
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个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
Run Code Online (Sandbox Code Playgroud)
我让守护进程重新加载新的服务定义,启用新服务,启动它,检查它的状态,并验证它正在侦听:
$ 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/user@1000.service/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
Run Code Online (Sandbox Code Playgroud)
这按预期工作。然后,我想通过使用systemd套接字激活进行按需(重新)生成,避免手动启动服务,或使用autossh永久运行它。那不起作用,我认为(我的版本)无法接收套接字文件描述符。 ssh
我找到了文档 ( 1 , 2 ),以及使用-tool 创建 2 个“包装器”服务、一个“服务”和一个“套接字”的示例systemd-socket-proxyd:
$ 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
Run Code Online (Sandbox Code Playgroud)
这似乎有效,直到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 套接字激活支持将是一个更好的解决方案。
为了便于将来参考,我将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
Run Code Online (Sandbox Code Playgroud)
~/.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
Run Code Online (Sandbox Code Playgroud)
~/.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
Run Code Online (Sandbox Code Playgroud)
在上面的脚本中,您必须替换以下字符串:
1000- (ssh-tunnel-proxy.socket文件)1001-(ssh-tunnel-proxy.service和ssh-tunnel.service文件)代理转发到 ssh 服务进程时使用hostname_in_ssh_config- (ssh-tunnel.service文件)localhost:2000- (ssh-tunnel.service文件)ssh-tunnel-proxy.service和ssh-tunnel.service文件)ssh-tunnel-...- (所有单元文件的前缀)mysql-tunnel-....Description=所有单元文件的指令中)MYSql.[Unit]
Description=Socket-activation for SSH-tunnel
[Socket]
ListenStream=1000
[Install]
WantedBy=sockets.target
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3395 次 |
| 最近记录: |