利用 ssh 端口转发功能搭建代理

ssh 常用的有三种端口转发功能,下面记录一下这三种转发都能做些什么。

动态端口转发

一条命令实现 socks5://127.0.0.1:<port> 代理:

ssh -p <remote_ssh_port> -fND 127.0.0.1:<proxy_port> <remote_user>@<remote_host>

远程端口转发

场景是有一台内网服务器 machine1,一台公网服务器 machine2,并且 machine1 不能通过内网直接访问 machine2,但是 machine2 可以访问 machine1。现在需要从外网的 machine3 访问 machine1。

我们可以使用 ssh 的远程端口转发功能来实现 machine3 通过 machine2 来访问 machine1。

ssh server 配置

首先需要在 machine2 上的 /ect/ssh/sshd_config 设置

AllowTcpForwarding yes # 允许 TCP 转发
GatewayPorts yes       # 允许远程主机连接转发的端口

为了安全性,最好只使用密钥验证:

PubkeyAuthentication yes  # 使用密钥验证
PasswordAuthentication no # 禁用密码验证

使用不同的 ssh key

为了安全,这里使用单独的 ssh key 来访问 machine1。

首先生成新的 key:

ssh-keygen -C "external_visitor" -f ~/.ssh/id_ed25519_external_visitor

ed25519 是目前 ssh 使用的默认密钥算法。可以使用 -t 来指定想要使用的密钥算法。

然后在 machine3 上的 ~/.ssh/config 中添加配置,指定访问 machine2 的时候使用的 key:

Host my_internal_server
    HostName machine2
    User ouonline
    IdentityFile ~/.ssh/id_ed25519_external_visitor

别忘了把新的 public key ~/.ssh/id_ed25519_external_visitor.pub 加到 machine1 的 ~/.ssh/authorized_keys 中。注意这里不需要把 public key 加到 machine2 中,这样虽然我们通过 machine2 能登录 machine1,但是我们仍然不能登录 machine2。

映射端口

假设我要通过 machine2 的 2222 端口来访问 machine1 的 22 端口,则需要在 machine1 上执行

ssh -o ServerAliveInterval=3 -o ExitOnForwardFailure=yes -fNR *:2222:machine1:22 machine2_user@machine2

这里的 -f 选项表示后台执行;-N 表示不执行命令,只做端口转发;-R 表示将任意来源访问 machine2 的 2222 端口的 tcp 流量转发到 machine1 的 22 端口。多加的两个 -o 选项是为了在 ssh 快速发现抖动或掉线。

ssh 可能会因为网络抖动或者空闲超时等原因中断,可以加一个 while 循环重连:

while true; do
    ssh ...
    sleep 2
done

现在可以在 machine3 上登录 machine1 了:

ssh -p 2222 machine1_user@machine2

注意这里用的是 machine1 上的用户名。

本地端口转发

简单说就是将远程内网服务暴露到本地。还没用到,以后补充。

Comments (2)

    1. 我会尽量用系统自带的工具。反向代理的功能很多软件都有,像 frp,nginx 都可以,在我的使用场景 ssh 就足够了。

回复 xuzhao9 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注