内网穿透

文章目录

1.内网穿透

  对于IPv4,可用的公网IPv4地址资源的越来越少,国内运营商为了节省公网IPv4地址资源,为用户宽带分配的基本都是内网IPv4地址,通过NAT(网络地址转换)实现多个宽带用户共享同一个公网IP地址资源。服务必须拥有公网IP才能被访问,如何将内网的服务暴露到公网中供其他人进行访问,这就是内网穿透技术该做的事情。

  本文针对IPv4地址内网穿透情况进行讨论,IPv6地址资源丰富,需要内网穿透的场景还是比较少的。

2.内网穿透方案

  这里介绍几种笔者了解到的内网穿透方案,各有各的优缺点。

2.1 UDP打洞

  NAT在将内网地址转换为公网地址的过程中会记录公网地址和端口与内网地址和端口的映射关系,只要内网机器向公网发起请求,NAT设备就会对映射关系开放一段时间。对于Full Cone NAT,只要对应关系被打开,公网上所有主机都可以通过该映射关系对内网机器发起请求。

  基于Full Cone NAT的特点,UDP打洞的原理就是通过一个公网服务器提供客户端信息注册和打洞服务。服务器流程基本如下:客户端A和B向打洞服务器S注册客户端A和B信息,S记录A和B的公网信息。打洞服务器可以向客户端发送对端的端口信息,随后客户端A和B可直接通信,期间客户端A和B定期发送心跳包连接维持NAT映射关系。常见的开源实现有pwnat(原理有点不太一样,有兴趣的了解一下)、tailscale和zerotier。

  • 优点:大带宽、低延迟、免费(不包含宽带费用)。
  • 缺点:连接稳定性低,打洞成功率低,受运营商策略和网络环境因素等多方面限制。

2.2 FRP中继

  frp中继是最稳定和最简单的方法,同时也是搭建低延迟内网穿透网络的最好方案。原理是通过一个含有公网IP的服务器对内网流量进行中转。最热门开源中继服务器项目即frp

  • 优点:稳定性高、低延迟。
  • 缺点:带宽低、费用高(国内服务器费用不便宜,一年大几百)。

2.3 CF隧道

  cf即cloudflare,是一家国外非常著名的云计算厂商。这里介绍的是他们家的Zero Trust Tunnel功能。通过他们的开源客户端cloudflared, 可以将内网服务暴露到cloudflare的公网IP并使用域名进行访问。使用隧道服务必须将自己的域名DNS交由cloudflare托管。

  • 优点:带宽高、免费。
  • 缺点:高延迟、稳定性一般

3.FRP中继配置

  Linux服务器可以使用curl -o文件名 "下载地址"下载,选择合适cpu架构的可执行程序。下载地址可以浏览器中点击右键复制下载地址获得。

3.1 配置服务端

 1# 以root权限运行
 2cp -a /path/to/your/frps/binary  /usr/bin
 3if [ ! -d /etc/frp ]; then 
 4  mkdir -p /etc/frp
 5fi
 6
 7# 编写服务端配置文件
 8cat >> /etc/frp/frps.ini << EOF
 9[common]
10bind_port = 7000
11token = frp通信密钥
12EOF
13
14# 编写systemd服务配置
15cat >> /etc/systemd/system/frps.service << EOF
16[Unit]
17Description=frp server.
18After=network.target
19
20[Service]
21Type=simple
22Restart=always
23ExecStart=/usr/bin/frps -c /etc/frp/frps.ini
24
25[Install]
26WantedBy=multi-user.target
27EOF
28
29# 开机启动
30systemctl enable frps
31
32# 开启frps服务 
33systemctl start frps

3.2 配置客户端

 1# 以root权限运行
 2cp -a /path/to/your/frpc/binary  /usr/bin
 3if [ ! -d /etc/frp ]; then 
 4  mkdir -p /etc/frp
 5fi
 6
 7# 编写服务端配置文件
 8cat >> /etc/frp/frpc.ini << EOF
 9[common]
10server_addr = frp服务器地址
11server_port = 7000
12admin_addr = 127.0.0.1
13admin_port = 7400
14token = frp通信密钥
15
16[lxc-centos-ssh]
17type = tcp
18local_ip = 内网ip地址
19local_port = 内网ip端口
20remote_port = 远程端口
21EOF
22
23# 编写systemd服务配置
24cat >> /etc/systemd/system/frpc.service << EOF
25[Unit]
26Description=frp clien.
27After=network.target
28
29[Service]
30Type=simple
31Restart=always
32ExecStart=/usr/bin/frpc -c /etc/frp/frpc.ini
33
34[Install]
35WantedBy=multi-user.target
36EOF
37
38# 开机启动
39systemctl enable frpc
40
41# 开启frpc服务 
42systemctl start frpc

4.CF隧道配置

下载cloudflared客户端

  Linux服务器可以使用curl -o文件名 "下载地址"下载,选择合适cpu架构的可执行程序。下载地址可以浏览器中点击右键复制下载地址获得。

4.1 登陆cloudflare

  按照提示将终端生成的URL复制到浏览器中访问,完成登陆认证。登陆认证完成后客户端证书会自动下载到服务器。

1cloudflared tunnel login

4.2 创建隧道并配置隧道服务

  此操作cf会自动为你的域名创建子域名的CNAME记录,并将结果解析到cf的隧道主机。

1cloudflared tunnel create 隧道名称
2# cloudflared tunnel create lxc-tunnel
3
4cloudflared tunnel route dns 隧道名称 子域名
5#cloudflared tunnel route dns lxc-tunnel aaabbb.rubitcat.cn
 1cat >> ~/.cloudflared/config.yml << EOF
 2tunnel: 你的隧道ID 例如 58ef03bb-6d61-47e9-b903-b771550c02e6 
 3credentials-file: 你的隧道认证文件 例如~/.cloudflared/58ef03bb-6d61-47e9-b903-b771550c02e6 .json
 4protocol: http2
 5originRequest:
 6  connectTimeout: 30s
 7  noTLSVerify: false
 8
 9ingress:
10  - hostname: 服务子域名
11    service: 内网服务,该服务不一定需要部署在运行cloudflared的机器上,例如https://192.168.3.33:2300
12  - hostname: ... 多条服务开多个数组记录
13    service: ...
14  - service: http_status:404
15EOF

4.3 启动隧道

1cloudflared --config 隧道配置文件 tunnel run 隧道名
2# loudflared --config /root/.cloudflared/config.yml tunnel run lxc-centos-streams