两种内网穿透方式:ssh端口转发和cloudflare zerotrust

介绍两种内网穿透的方式:ssh端口转发和cloudflare zerotrust。ssh端口转发需要一个带有公网IP的云主机;cloudflare的zerotrust则需要一个域名。 Modified: 2023-07-04 20:24:23 Created: 2023-06-24 10:30:59 Tags: #linux #ssh #cloudflare #intranet_penetration

家中台式机刷了个 RedHat,上面跑着各种服务。但是家中宽带并没有公网 IP,而有些服务需要暴露到互联网上。所以需要一些内网穿透的工具,实现在外部访问内部服务。本文将介绍两种方式:

  1. 基于 ssh 的远程端口转发
  2. 基于 cloudflare zertorust 的端口映射

1. 基于 ssh 远程端口转发

ssh 一般被用做本地和远程服务器之间的连接,当然,它还有个更加重要的功能是端口转发。

这里就使用 ssh 的远程端口转发功能,将本地机器 A 的 c 端口远程转发到一个有公网 ip 的机器 B 的端口 d 上上。实现在互联网上访问 B 的 d 端口,获取 A 的 c 端口的数据。

使用这种方式需要购买一个带有公网 ip 的云服务器。

1.1 云服务器购买

这里推荐使用 vultr 的 vps,它按使用量收费,而且支持支付宝付款。

1.2 远程服务器端 ssh 安装和配置

通常购买的云服务器会开启 sshd 服务,否则就无法通过 ssh 连接。关于远程云服务器的配置,可以查看这里

1.2.1 服务器端 ssh 的安装与配置

但是也可能遇到奇葩的云服务器,需要自己先安装 ssh,这里用openssh

sudo dnf install openssh-server -y

安装完成之后,需要在远程服务器上开启 sshd 服务:

sudo systemctl enable sshd.service
sudo systemctl start sshd.service

同时还要在防火墙中允许 ssh 流量:

sudo firewall-cmd --add-port 22/tcp --zone=public --permanent
sudo firewall-cmd --reload

有的云服务器还有自己的防火墙,还需要登陆网页去修改防火墙,放行一些端口。

还要配置服务器上的 sshd 服务,使其允许端口转发,修改/etc/ssh/sshd_config

AllowAgentForwarding yes
AllowTcpForwarding yes
GatewayPorts yes

完成之后在远程服务器上重启 sshd 服务:

sudo systemctl daemon-reload
sudo systemctl restart sshd.service

1.3 客户端配置 ssh 连接

在本地服务器上连接远程云服务器:

ssh -N -R remote_port:localhost:local_port user_name@server_ip
  • -N 让 ssh 不要登陆远程服务器
  • -R 远程端口转发,R 是 remote 的意思,通过访问远程服务器的remote_port,可以实现访问本地服务器local_port的效果

如果是第一次连接,还需要将远程服务器的地址加入known_hosts里面。就是在输入命令之后,问你是否加入,敲一下回车就行。

1.3.1 SSH 密钥(免密码)登陆

当然,一般要免密码登陆,需要配置 sshkey。在本地云服务器上运行:

ssh-keygen -t rsa # 然后就回车几次

默认会在~/.ssh/文件夹下生成id_rsa.pub文件,将这个文件从本地服务器传送到远程云服务器。在本地服务器上运行:

scp ~/.ssh/id_rsa.pub user_name@server_ip

在远程云服务器上处理公钥:

mkdir -p ~/.ssh
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys

此时再到本地服务器上运行 ssh 命令:

ssh -N -R remote_port:localhost:local_port user_name@server_ip

可以发现不需要输入密码就能登陆了。通常我会将本地的 22 端口远程转发到云服务器的另外一个端口(比如2022)。然后公网访问:

ssh -p 2022 client_user@server_ip

1.4 autossh 自动连接 systemd 管理服务

上面直接用 ssh 的方式已经能够实现远程端口转发了。但是问题是每次都要运行一下 ssh 命令,也没有办法开机启动。这时候可以用 autossh 和 systemd 来进行操作。

1.4.1 autossh 自动连接 ssh

首先在本地服务器上安装 autossh:

sudo dnf install autossh -y

将之前的 ssh 命令更换:

autossh -M manage_port -i ~/.ssh/id_rsa -N -R remote_port:localhost:local_port user_name@server_ip

这样就会在 ssh 掉线的时候自动重新连接了。

1.4.2 systemd 管理服务

经过上面的操作,还是没有做到开机自动启动,此时需要在本地服务器上用 systemd 来管理服务。

新建/etc/systemd/system/auto_ssh_server.service

[Unit]
Description=Auto SSH Server Servie
StartLimitInterval=180
StartLimitBurst=4
After=network.target
Wants=network.target

[Service]
User=chinglin
Group=chinglin
Type=simple
PIDFile=/run/auto_ssh_server.pid
ExecStart=/usr/bin/autossh -M 4011 -i ~/.ssh/id_rsa -NR remote_port:localhost:local_port user_name@server_ip
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target

# the manage port should be different from the remote listen port

编辑保存后:

sudo systemctl daemon-reload
sudo systemctl enable auto_ssh_server.service
sudo systemctl start auto_ssh_server.service

此时本地服务器开机启动这个 autossh 的连接了。我通常会用将本地服务器的 22 端口转发到远程的某个端口(如 2022),这样就可以远程 ssh 到本地了。找到另外一台电脑运行 ssh:

ssh -p 2022 local_server_user@remote_server_ip

2. 使用 cloudflare 进行内网穿透

cloudflare 是一家全球的 CDN 厂商,在中国大陆境内也有相关服务。cloudflare 提供的 zerotrust 套餐,则是很好的内网穿透工具,稳定且免费。

2.1 注册 cloudflare 账户

需要一张 visa 或者 mastercard 的信用卡,帮我们注册。注册网址

2.2 购买一个域名

使用 cloudflare 的 zerotrust 需要一个域名,可以在 cloudflare 或者 namecheap 上购买。

在 cloudflare 上购买域名:

cloudflare_domain

2.3 用 cloudflare 解析域名

在购买域名的地方,将域名服务器修改为 cloudflare 提供的域名服务器。这时候要选择一个套餐,选择 0 元套餐就可以了。

2.4 cloudflare 的 zerotrust 做内网穿透

1 控制台上找到 zerotrust

zerotrust

2 找到 Access -> Tunnels -> Create a tunnel

create_a_tunnel

3 输入名字相关信息

new_tunnel_name

4 找到名字,选择 configure

configure

5 在本地服务器安装 cloudflare 客户端

这里有多种方式,选择 docker 来安装。拷贝网页上的命令就行了。

docker_cloudflared

6 在 Public Hostname 处添加新的穿透 new_hostname

7 填写相关参数

new_host_configure

  • subdomain: 想要访问的二级域名
  • domain:通过下拉菜单来选择
  • path:留空
  • service:选择协议,根据实际需要进行选择
  • url:填写本地服务器上服务器的 ip 和端口,比如说本地服务器 ip 为 10.10.10.11,端口为 9090,则 url 填写 10.10.10.11:9090。应为 cloudflared 在 docker 中运行,一定要填写服务器 ip(不能是 localhost)

至此,zerotrust 已经配置完成。

2.5 实例,转发 cockpit 到云服务

尝试转发22端口,发现并不能通过。但是 redhat 有一个插件叫做 Cockpit。可以远程管理我们的机器。

在本地机器上安装 cockpit:

sudo dnf install cockpit -y
sudo systemctl enable cockpit
sudo systemctl start cockpit

cockpit 通常使用的是9090端口,要用 zerotrust 转发9090端口。

Cockpit

用户名和密码就是本地服务器的账户和密码。

总结

本文介绍了两种内网穿透的方式。一种是用 ssh 的端口转发,另一种是用 cloudflare 的 zerotrust 工具。梁总方式均实现了在没有公网 ip 的情况下,将本地服务暴露到整个互联网的功能。