我想在 Docker 容器内使用带有密码身份验证的 SSH 转发 Socks5 代理。是的,我知道SSH 密钥会更好。但由于它不是我自己的服务器,我无法使用密钥,它们只提供用户/密码身份验证。autossh
似乎是完成这项工作的正确工具,所以我sshpass
在入口点 shell 脚本中使用了它:
sshpass -P "assphrase" -p "${PASSWORD}" autossh -M0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -oStrictHostKeyChecking=no -oUserKnownHostsFile=custom_known_hosts -4 -N -D *:5080 ${USER}@${HOST}
这两个软件包都安装在Dockerfile
FROM debian:stretch-slim
RUN apt-get update \
&& apt-get upgrade -y
RUN apt-get install -y ssh wget sshpass autossh
RUN wget https://www.provider.com/custom_known_hosts
COPY run.sh .
ENTRYPOINT "./run.sh"
这将建立到 Socks5 代理的 SSH 隧道。但在互联网连接丢失后,身份验证失败:
socks5_forward_1 | Warning: Permanently added 'server.provider.com' (ECDSA) to the list of known hosts.
socks5_forward_1 | SSHPASS searching for password prompt using match "assword"
socks5_forward_1 | SSHPASS read: [email protected]'s password:
socks5_forward_1 | SSHPASS detected prompt. Sending password.
socks5_forward_1 | SSHPASS read:
socks5_forward_1 |
socks5_forward_1 | packet_write_wait: Connection to 1.2.3.4 port 22: Broken pipe
socks5_forward_1 | SSHPASS read: [email protected]'s password:
socks5_forward_1 | SSHPASS detected prompt, again. Wrong password. Terminating.
socks5_forward_1 | Permission denied, please try again.
socks5_forward_1 | Permission denied, please try again.
socks5_forward_1 | Received disconnect from 1.2.3.4 port 22:2: Too many authentication failures
socks5_forward_1 | Authentication failed.
socks5_forward_1 | Permission denied, please try again.
socks5_forward_1 | Permission denied, please try again.
socks5_forward_1 | Received disconnect from 1.2.3.4 port 22:2: Too many authentication failures
socks5_forward_1 | Authentication failed.
我也尝试过
sshpass -v -p "${PASSWORD}" autossh -M0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -oStrictHostKeyChecking=no -oUserKnownHostsFile=custom_known_hosts -4 -N -D *:5080 ${USER}@${HOST}
并自己构建一个循环,因为我认为尝试重新连接sshpass
后将无法正常工作:autossh
while true; do command sshpass -P "assphrase" -p "${PASSWORD}" ssh -M0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -oStrictHostKeyChecking=no -oUserKnownHostsFile=custom_known_hosts -4 -N -D *:5080 ${USER}@${HOST}; [ $? -eq 0 ] && break || sleep 5; done
这两种方法都行不通。由于我的 ISP 每 24 小时重新连接一次,因此每天手动重新启动容器很烦人。我还不明白为什么循环中的最后一种方法无法正确处理重新连接
答案1
问题似乎在于 SSH 本身尝试重新连接,并且sshpass
在发送重新连接的密码时出现问题。所以我自己构建了一个循环,并配置ssh在转发失败时退出:
while :; do
sshpass -v \
-p "${PASSWORD}" \
ssh \
-o "ServerAliveInterval 60" \
-o "ServerAliveCountMax 2" \
-o "ConnectTimeout 15" \
-o "ExitOnForwardFailure yes" \
-o "StrictHostKeyChecking no" \
-o "UserKnownHostsFile perfect_privacy_known_hosts" \
-4 -N -D *:5080 ${USER}@${HOST}
echo "SSH connection exieted, wait 15s before re-trying"
sleep 15
done
通过重新启动 dsl 调制解调器,我模拟了重新连接:
socks5_forward_1 | Ziel: server.provider.com mit User: myUser
socks5_forward_1 | Warning: Permanently added 'server.provider.com' (ECDSA) to the list of known hosts.
socks5_forward_1 | SSHPASS searching for password prompt using match "assword"
socks5_forward_1 | SSHPASS read: [email protected]'s password:
socks5_forward_1 | SSHPASS detected prompt. Sending password.
socks5_forward_1 | SSHPASS read:
socks5_forward_1 |
socks5_forward_1 | Timeout, server server.provider.com not responding.
socks5_forward_1 | SSH connection exieted, wait 15s before re-trying
socks5_forward_1 | ssh: Could not resolve hostname server.provider.com: Temporary failure in name resolution
socks5_forward_1 | SSH connection exieted, wait 15s before re-trying
socks5_forward_1 | ssh: Could not resolve hostname server.provider.com: Temporary failure in name resolution
socks5_forward_1 | SSH connection exieted, wait 15s before re-trying
socks5_forward_1 | ssh: Could not resolve hostname server.provider.com: Temporary failure in name resolution
socks5_forward_1 | SSH connection exieted, wait 15s before re-trying
socks5_forward_1 | ssh: Could not resolve hostname server.provider.com: Temporary failure in name resolution
socks5_forward_1 | SSH connection exieted, wait 15s before re-trying
socks5_forward_1 | SSHPASS searching for password prompt using match "assword"
socks5_forward_1 | SSHPASS read: [email protected]'s password:
socks5_forward_1 | SSHPASS detected prompt. Sending password.
socks5_forward_1 | SSHPASS read:
这很好用,SSH 连接已建立,因此我的袜子5 代理自动重新连接。