使用SSH反向隧道进行内网穿透

本文介绍如何利用SSH反向隧道穿透NAT并维持稳定连接。通过在B机器上建立SSH隧道,将A机器的6766端口转发到B机器的22端口,实现从A机器反向连接B机器。文中详细讲解了如何使用autossh保持隧道的稳定性,以及如何自动化建立隧道。

这篇文章主要介绍了如何利用SSH 反向隧道穿透NAT,并演示了如何维持一条稳定的SSH 隧道。

假设有机器A 和B,A 有公网IP,B 位于NAT 之后并无可用的端口转发,现在想由A 主动向B 发起SSH 连接。由于B 在NAT 后端,无可用公网IP + 端口 这样一个组合,所以A 无法穿透NAT,这篇文章应对的就是这种情况。

首先有如下约定,因为很重要所以放在前面:

机器代号 机器位置 地址 账户 ssh/sshd 端口 是否需要运行sshd
A 位于公网 a.site usera 22
B 位于NAT 之后 localhost userb 22
C 位于NAT 之后 localhost userc 22

这里默认你的系统init 程序为systemd,如果你使用其他的init 程序,如果没有特殊理由还是换到一个现代化的GNU/Linux 系统吧……

SSH 反向隧道

这种手段实质上是由B 向A 主动地建立一个SSH 隧道,将A 的6766 端口转发到B 的22 端口上,只要这条隧道不关闭,这个转发就是有效的。有了这个端口转发,只需要访问A 的6766 端口反向连接B 即可。

首先在B 上建立一个SSH 隧道,将A 的6766 端口转发到B 的22 端口上:

        
1
        
B $ ssh - p 22 -qngfNTR 6766:localhost: 22 usera@ a.site

然后在A 上利用6766 端口反向SSH 到B:

        
1
        
A $ ssh -p 6766 userb @localhost

要做的事情其实就是这么简单。

隧道的维持

稳定性维持

然而不幸的是SSH 连接是会超时关闭的,如果连接关闭,隧道无法维持,那么A 就无法利用反向隧道穿透B 所在的NAT 了,为此我们需要一种方案来提供一条稳定的SSH 反向隧道。

一个最简单的方法就是autossh,这个软件会在超时之后自动重新建立SSH 隧道,这样就解决了隧道的稳定性问题,如果你使用Arch Linux,你可以这样获得它:

        
1
        
$ sudo pacman -S autossh

下面在B 上做之前类似的事情,不同的是该隧道会由autossh 来维持:

        
1
        
B $ autossh - p 22 -M 6777 -NR 6766:localhost: 22 usera@ a.site

-M 参数指定的端口用来监听隧道的状态,与端口转发无关。

之后你可以在A 上通过6766 端口访问B 了:

        
1
        
A $ ssh -p 6766 userb @localhost

隧道的自动建立

然而这又有了另外一个问题,如果B 重启隧道就会消失。那么需要有一种手段在B 每次启动时使用autossh 来建立SSH 隧道。很自然的一个想法就是做成服务,之后会给出在systemd 下的一种解决方案。

“打洞”

之所以标题这么起,是因为自己觉得这件事情有点类似于UDP 打洞,即通过一台在公网的机器,让两台分别位于各自NAT 之后的机器可以建立SSH 连接。

下面演示如何使用SSH 反向隧道,让C 连接到B。

首先在A 上编辑sshd 的配置文件/etc/ssh/sshd_config,将GatewayPorts 开关打开:

        
1
        
GatewayPorts yes

然后重启sshd

        
1
        
A $ sudo systemctl restart sshd

然后在B 上对之前用到的autossh 指令略加修改:

        
1
        
B $ autossh - p 22 -M 6777 -NR '*:6766:localhost:22' usera@ a.site

之后在C 上利用A 的6766 端口SSH 连接到B

        
1
        
C $ ssh - p 6766 userb@ a.site

至此你已经轻而易举的穿透了两层NAT。

最终的解决方案

整合一下前面提到的,最终的解决方案如下:

首先打开A 上sshd 的GatewayPorts 开关,并重启sshd(如有需要)。

然后在B 上新建一个用户autossh,根据权限最小化思想,B 上的autossh 服务将以autossh 用户的身份运行,以尽大可能避免出现安全问题:

        
1
2
        
B $ sudo useradd -m autossh
B $ sudo passwd autossh

紧接着在B 上为autossh 用户创建SSH 密钥,并上传到A:

        
1
2
3
        
B $ su - autossh
B $ ssh-keygen -t 'rsa' -C 'autossh@B'
B $ ssh-copy-id usera @a.site

注意该密钥不要设置密码,也就是运行ssh-keygen 指令时尽管一路回车,不要输入额外的字符。

然后在B 上创建以autossh 用户权限调用autossh 的service 文件。将下面文本写入到文件/lib/systemd/system/autossh.service,并设置权限为644:

        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        
[Unit]
Description=Auto SSH Tunnel
After=network- online.target
[Service]
User=autossh
Type=simple
ExecStart=/bin/autossh -p 22 -M 6777 -NR '*:6766:localhost:22' usera@a.site -i /home/autossh/.ssh/id_rsa
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always
[Install]
WantedBy=multi-user.target
WantedBy=graphical.target

在B 上让network-online.target 生效:

        
1
        
B $ systemctl enable NetworkManager- wait-online

如果你使用systemd-networkd,你需要启用的服务则应当是systemd-networkd-wait-online 。

然后设置该服务自动启动:

        
1
        
B $ sudo systemctl enable autossh

如果你愿意,在这之后可以立刻启动它:

        
1
        
B $ sudo systemctl start autossh

然后你可以在A 上使用这条反向隧道穿透B 所在的NAT SSH 连接到B:

        
1
        
A $ ssh -p 6766 userb @localhost

或者是在C 上直接穿透两层NAT SSH 连接到B:

        
1
        
C $ ssh - p 6766 userb@ a.site

如果你对SSH 足够熟悉,你可以利用这条隧道做更多的事情,例如你可以在反向连接时指定动态端口转发:

        
1
        
C $ ssh - p 6766 -qngfNTD 7677 userb@ a.site

假设C 是你家中的电脑,A 是你的VPS,B 是你公司的电脑。如果你这样做了,那么为浏览器设置端口为7677 的sock4 本地(localhost)代理后,你就可以在家里的浏览器上看到公司内网的网页。

<think> 我们正在讨论dropbear ssh反向隧道使用方法和原理。根据用户要求,需要包括使用方法、原理和配置等信息。 由于dropbear是一个轻量级的SSH服务器和客户端,常用于嵌入式系统,因此其反向隧道配置与OpenSSH类似,但命令可能略有不同。 原理部分: SSH反向隧道(Reverse SSH Tunnel)是一种通过SSH协议将内网主机的端口映射到公网服务器的方法,从而实现从外部访问内网主机的目的。 其核心是在内网主机上建立一条到公网服务器的SSH连接,并在该连接上创建反向隧道(即远程端口转发)。这样,公网服务器上的指定端口就会被转发到内网主机的某个端口。 具体来说: 1. 内网主机(称为Client)主动连接到公网服务器(称为Server)。 2. Client在连接时请求将Server的某个端口(例如:10022)转发到Client本地的SSH端口(22)。 3. 这样,当外部用户连接Server的10022端口时,数据就会通过已建立的SSH隧道转发到Client的22端口。 使用场景: 适用于内网主机没有公网IP,但需要被外部访问的情况。 使用dropbear配置反向隧道的方法: 由于dropbear的命令行参数与OpenSSH有所不同,因此需要调整命令格式。 基本命令格式: dropbear -R [远程绑定地址:]远程端口:本地地址:本地端口 [其他选项] 用户名@远程服务器 对于反向隧道(远程端口转发),使用`-R`选项。 例如,假设我们想将公网服务器(123.57.14.71)的10022端口映射到内网主机(Client)的22端口,命令如下: dropbear -R 10022:localhost:22 root@123.57.14.71 但是,dropbear的`-R`选项要求必须同时指定要执行的远程命令(如果没有命令,则执行默认的shell)。为了只建立隧道而不执行远程命令,我们可以使用`-N`(不执行远程命令)和`-f`(后台运行)选项。 然而,需要注意的是,dropbear并不完全支持OpenSSH的所有选项。在dropbear中,`-N`选项是用于不执行远程命令,而`-f`用于后台运行。但dropbear的`-R`选项的格式与OpenSSH不同,它不支持在命令行中直接指定多个端口转发。实际上,dropbear只支持单个端口转发(每个`-R`选项只能指定一个转发),并且不能像OpenSSH那样使用多个`-R`。 因此,上面的命令在dropbear中可能无法直接使用。根据dropbear的文档,其端口转发的语法如下: -L [本地地址:]本地端口:远程主机:远程端口 (本地端口转发) -R [远程地址:]远程端口:本地主机:本地端口 (远程端口转发) 但是,在建立连接时,dropbear默认会提供一个shell,如果我们不需要shell,可以使用`-N`选项。 所以,完整的命令可能是: dropbear -R 10022:localhost:22 -N -f root@123.57.14.71 然而,需要注意的是,dropbear的`-f`选项(后台运行)需要配合密码输入或密钥认证,通常我们会使用密钥认证来实现无密码登录。 另外,dropbear也支持通过配置文件设置,但通常命令行更常用。 配置步骤: 1. 在公网服务器上运行dropbear或OpenSSH服务器(假设使用OpenSSH,因为公网服务器通常使用OpenSSH)。 2. 在内网主机(运行dropbear)上生成密钥对(如果使用密钥认证): dropbearkey -t rsa -f ~/.ssh/id_rsa # 然后提取公钥 dropbearkey -y -f ~/.ssh/id_rsa | grep "^ssh-rsa" > ~/.ssh/id_rsa.pub 3. 将公钥内容添加到公网服务器的~/.ssh/authorized_keys文件中。 4. 在内网主机上执行反向隧道连接命令。 但上述命令存在一个问题:dropbear在建立连接后,如果没有指定远程命令(使用`-N`)且没有使用`-f`,它会等待输入密码(如果未使用密钥认证)。而使用`-f`要求必须输入密码(除非已经配置了密钥认证且免密码登录)。所以,确保配置好密钥认证。 另外,反向隧道建立后,公网服务器上的10022端口将绑定在localhost上(默认情况下),这意味着只能从公网服务器本地访问这个端口。如果希望监听在公网IP上,需要指定远程绑定地址为0.0.0.0,例如: dropbear -R 0.0.0.0:10022:localhost:22 -N -f root@123.57.14.71 但是,请注意这样可能会带来安全风险,因为任何能访问公网服务器10022端口的人都可以连接到内网主机。因此,建议在公网服务器上设置防火墙,只允许特定的IP访问该端口。 另外,反向隧道连接可能会因为网络波动而断开,因此需要保持连接的稳定性。可以使用autossh等工具来监控连接,并在断开时自动重连。 使用autossh配合dropbear: 由于autossh是为OpenSSH设计的,我们可以通过包装dropbear命令来使用autossh。 首先,确保内网主机安装了autossh。然后,使用类似下面的命令: autossh -M 0 -f -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 0.0.0.0:10022:localhost:22 root@123.57.14.71 但是,这里使用的是OpenSSHssh客户端,而不是dropbear。如果我们希望使用dropbear作为ssh客户端,那么需要将autossh配置为调用dropbear。然而,autossh默认调用ssh,因此我们可以通过设置环境变量AUTOSSH_PORT或者使用包装脚本。 实际上,autossh并不直接支持dropbear,因此可能需要使用其他方法来保持dropbear连接的稳定性(例如,编写监控脚本)。 另一种方法是使用systemd服务或者cron定时任务来检查连接。 总结: 1. 原理:通过远程端口转发,将公网服务器的端口映射到内网主机的端口。 2. 使用dropbear建立反向隧道: dropbear -R [远程地址:]远程端口:本地地址:本地端口 [用户@]远程服务器 [其他选项] 3. 常用选项:-N(不执行远程命令),-f(后台运行),同时需要配置密钥认证。 4. 为了安全,建议仅允许特定IP访问公网服务器上的转发端口。 5. 为了稳定性,需要实现断线重连(可以使用脚本监控,或使用autossh配合OpenSSH客户端,或者使用其他守护进程工具)。 注意:由于dropbear的轻量特性,它可能不支持OpenSSH的所有功能。因此,在复杂场景下,可能需要在公网服务器上使用OpenSSH,而在内网主机上使用dropbear作为客户端建立反向隧道。 引用说明:我们参考了站内引用中关于autossh反向代理的内容,其中提到了反向SSH的本质是端口映射[^1]。 </think> ### Dropbear SSH反向隧道使用方法与原理 #### 原理说明 Dropbear SSH反向隧道本质是通过**远程端口转发**实现内网穿透。其核心原理是: 1. **主动出站连接**:内网设备(Client)主动连接到公网服务器(Server) 2. **端口绑定**:在公网服务器上创建监听端口(如 `10022`) 3. **隧道映射**:公网端口流量通过SSH隧道转发到内网设备 ```mermaid graph LR subgraph 公网服务器 S[端口 10022] end subgraph 内网设备 C[SSH服务 22端口] end S -- SSH隧道流量 --> C C == 建立反向连接 ==> S ``` 数学表达为: $$ \text{Server}:p_{\text{remote}} \xrightarrow{\text{SSH Tunnel}} \text{Client}:p_{\text{local}} $$ #### 配置步骤 1. **生成密钥对**(内网设备执行): ```bash dropbearkey -t rsa -f ~/.ssh/id_dropbear dropbearkey -y -f ~/.ssh/id_dropbear | grep "^ssh-rsa" > ~/.ssh/id_dropbear.pub ``` 2. **公钥部署**(复制 `id_dropbear.pub` 内容到服务器的 `~/.ssh/authorized_keys`) 3. **建立反向隧道**: ```bash dropbear -R 10022:localhost:22 -N -f user@public-server-ip ``` - `-R 10022:localhost:22`:将服务器的10022端口映射到本机22端口 - `-N`:不执行远程命令 - `-f`:后台运行 4. **连接验证**(外部设备访问内网): ```bash ssh -p 10022 user@public-server-ip ``` #### 高级配置 **1. 开机自启(systemd服务)** 创建 `/etc/systemd/system/dropbear-tunnel.service`: ```ini [Unit] Description=Dropbear Reverse SSH Tunnel After=network.target [Service] User=root ExecStart=/usr/bin/dropbear -R 10022:localhost:22 -N -f user@public-server-ip Restart=always RestartSec=30 [Install] WantedBy=multi-user.target ``` 启用服务:`systemctl enable --now dropbear-tunnel` **2. 多端口转发** ```bash dropbear -R 10022:localhost:22 -R 8080:localhost:80 user@server-ip ``` **3. 稳定性增强(autossh方案)** ```bash autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \ -N -R 10022:localhost:22 user@server-ip ``` #### 安全建议 1. 服务器防火墙限制源IP: ```bash ufw allow from 192.168.0.0/24 to any port 10022 ``` 2. 使用非标准端口(避免10022等常见端口) 3. 定期轮换密钥(建议每90天) 4. 在服务器端限制绑定地址: ```bash dropbear -R 127.0.0.1:10022:localhost:22 ... # 仅允许本地访问 ``` > 反向SSH的核心价值在于**通过出站连接规避防火墙限制**,使内网服务无需公网IP即可被访问。这种技术本质是端口映射的加密实现[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值