内网穿透神器大盘点!frp、WireGuard让你的服务器随时在线

内网穿透神器大盘点!frp、WireGuard让你的服务器随时在线

家里的测试环境、办公室的开发机器,还有那台放在机房角落吃灰但关键时刻要用的备用服务器,怎么让你能随时能访问到?内网穿透!

说起内网穿透,我算是踩过不少坑了。从最开始用花生壳被限速限到怀疑人生,到后来自己搭建各种开源方案,这几年下来也算是摸出了点门道。今天就跟大家聊聊几个好用的内网穿透工具,特别是frp和WireGuard这两个我用得最多的。

什么是内网穿透,为什么我们需要它简单说,内网穿透就是让外网能够访问到内网的服务。你想想,公司内网的服务器,家里的NAS,或者你在虚拟机里跑的测试环境,正常情况下外面是访问不到的。

这里面涉及到NAT(网络地址转换)的概念。现在IPv4地址不够用,运营商基本都会给你分配一个内网IP,然后通过NAT转换访问外网。比如你家里的路由器分配给设备的192.168.1.x这种地址,外网是直接访问不到的。

但有时候你就是需要在外面连进去看看,比如:

• 在家远程连接公司的开发机器,改个bug或者重启个服务• 让客户访问你本地搭建的演示环境,展示最新的功能• 监控家里的各种智能设备,看看空调开了没有,摄像头有没有异常传统的解决方案是在路由器上做端口映射(Port Forwarding),但这玩意儿有个大问题:很多宽带运营商不给你公网IP,或者给了也是动态的。而且端口映射配置起来也挺麻烦,每个服务都要单独配置,安全性还不好控制。

我之前为了在家能连公司的服务器,专门买了个支持DDNS的路由器,结果发现运营商根本不给公网IP。

frp:简单粗暴的穿透利器frp(Fast Reverse Proxy)应该是目前最流行的内网穿透工具了。这个项目是国人开发的,GitHub上有4万多个star,社区很活跃。我第一次用它的时候就被它的简单程度震惊了,配置文件就几行,跑起来就能用。

frp的工作原理详解frp采用的是客户端-服务端模式,工作原理其实不复杂。你需要一台有公网IP的服务器作为中转(这台服务器叫frps,s代表server),然后在内网机器上运行frp客户端(叫frpc,c代表client)。

具体的流程是这样的:

代码语言:javascript代码运行次数:0运行复制内网服务frpc (客户端)frps (服务端)外部客户端内网服务frpc (客户端)frps (服务端)外部客户端初始化阶段请求处理阶段建立控制连接连接确认发送请求到frps暴露的端口通过控制连接通知frpc建立新的数据传输连接转发外部请求数据转发请求到内网服务返回响应数据转发响应数据转发响应给外部客户端这种设计的好处是,内网的机器不需要有公网IP,只要能访问外网就行。而且所有的连接都是frpc主动发起的,不会被防火墙阻挡。

frp的详细部署过程先说服务端配置。我一般用阿里云的轻量应用服务器,1核2G的配置就够用了,一个月几十块钱。系统选择Ubuntu 20.04,比较稳定。

首先下载frp:

代码语言:javascript代码运行次数:0运行复制wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz

tar -zxvf frp_0.52.3_linux_amd64.tar.gz

cd frp_0.52.3_linux_amd64服务端配置文件 frps.toml(新版本用toml格式了):

代码语言:javascript代码运行次数:0运行复制bindPort = 7000

vhostHTTPPort = 80

vhostHTTPSPort = 443

webServer.addr = "0.0.0.0"

webServer.port = 7500

webServer.user = "admin"

webServer.password = "your_complex_password"

auth.method = "token"

auth.token = "your_very_secret_token_here"

# 日志配置

log.to = "/var/log/frps.log"

log.level = "info"

log.maxDays = 3

# 限制配置

transport.maxPoolCount = 5

transport.maxPortsPerClient = 0这个配置比基础版本详细多了。bindPort是frp服务监听的端口,vhostHTTPPort和vhostHTTPSPort是HTTP和HTTPS服务的端口。webServer是管理界面的配置,通过浏览器访问 http://your_server_ip:7500 就能看到连接状态。

auth.token记得设置复杂一点,这是客户端连接的凭证。我一般用随机生成的32位字符串。

创建systemd服务文件 /etc/systemd/system/frps.service:

代码语言:javascript代码运行次数:0运行复制[Unit]

Description=Frp Server Service

After=network.target

[Service]

Type=simple

User=nobody

Restart=on-failure

RestartSec=5s

ExecStart=/opt/frp/frps -c /opt/frp/frps.toml

LimitNOFILE=1048576

[Install]

WantedBy=multi-user.target启动服务:

代码语言:javascript代码运行次数:0运行复制sudo mkdir -p /opt/frp

sudo cp frps frps.toml /opt/frp/

sudo systemctl daemon-reload

sudo systemctl enable frps

sudo systemctl start frps客户端配置就更灵活了。我一般会根据不同的需求创建不同的配置文件。

基础的客户端配置 frpc.toml:

代码语言:javascript代码运行次数:0运行复制serverAddr = "your_server_ip"

serverPort = 7000

auth.method = "token"

auth.token = "your_very_secret_token_here"

# SSH服务穿透

[[proxies]]

name = "ssh"

type = "tcp"

localIP = "127.0.0.1"

localPort = 22

remotePort = 6000

# Web服务穿透

[[proxies]]

name = "web"

type = "http"

localPort = 8080

customDomains = ["your_domain.com"]

# HTTPS服务穿透

[[proxies]]

name = "web-https"

type = "https"

localPort = 8443

customDomains = ["your_domain.com"]

# 文件服务器

[[proxies]]

name = "file-server"

type = "tcp"

localIP = "127.0.0.1"

localPort = 9000

remotePort = 9000

# 数据库访问(谨慎使用)

[[proxies]]

name = "mysql"

type = "tcp"

localIP = "127.0.0.1"

localPort = 3306

remotePort = 3306这个配置把本地的SSH服务映射到服务器的6000端口,把本地8080端口的web服务通过域名暴露出去。还包括了HTTPS、文件服务器和数据库的配置。

启动客户端:

代码语言:javascript代码运行次数:0运行复制./frpc -c frpc.tomlfrp的高级功能详解frp不只是简单的端口转发,还有很多高级功能。

HTTP基本认证:

代码语言:javascript代码运行次数:0运行复制[[proxies]]

name = "web-auth"

type = "http"

localPort = 8080

customDomains = ["admin.your_domain.com"]

httpUser = "admin"

httpPassword = "password"这样访问的时候会弹出认证框,增加一层安全保护。

负载均衡:

代码语言:javascript代码运行次数:0运行复制# 服务器1

[[proxies]]

name = "web1"

type = "http"

localPort = 8080

customDomains = ["app.your_domain.com"]

group = "web"

groupKey = "123456"

# 服务器2(另一台机器)

[[proxies]]

name = "web2"

type = "http"

localPort = 8080

customDomains = ["app.your_domain.com"]

group = "web"

groupKey = "123456"多台机器配置相同的group和groupKey,frp会自动做负载均衡。

带宽限制:

代码语言:javascript代码运行次数:0运行复制[[proxies]]

name = "limited-web"

type = "http"

localPort = 8080

customDomains = ["slow.your_domain.com"]

transport.bandwidthLimit = "1MB"可以限制单个代理的带宽,避免某个服务占用太多资源。

健康检查:

代码语言:javascript代码运行次数:0运行复制[[proxies]]

name = "web-health"

type = "http"

localPort = 8080

customDomains = ["health.your_domain.com"]

healthCheck.type = "http"

healthCheck.timeoutSeconds = 3

healthCheck.maxFailed = 3

healthCheck.intervalSeconds = 10

healthCheck.path = "/health"frp会定期检查后端服务的健康状态,如果检查失败会自动停止转发。

frp的监控和日志生产环境使用frp,监控是必不可少的。frp提供了几种监控方式:

Web Dashboard:

访问 http://your_server_ip:7500 可以看到:

• 当前连接的客户端列表• 每个代理的流量统计• 连接状态和错误信息• 实时的请求日志Prometheus监控:

在frps.toml中添加:

代码语言:javascript代码运行次数:0运行复制webServer.pprofEnable = true

# Prometheus metrics

enablePrometheus = true然后就可以通过 http://your_server_ip:7500/metrics 获取Prometheus格式的监控数据。

日志分析:

frp的日志很详细,包含了所有连接和错误信息。我一般会配合ELK或者Grafana Loki来做日志分析。

常见的日志格式:

代码语言:javascript代码运行次数:0运行复制2024-01-15 10:30:15 [I] [service.go:349] frps tcp listen on 0.0.0.0:7000

2024-01-15 10:30:20 [I] [control.go:464] [ssh] new proxy connection from [192.168.1.100:54321]

2024-01-15 10:30:25 [W] [control.go:123] [ssh] connection timeout, retry in 5 seconds通过分析日志可以发现网络问题、性能瓶颈等。

frp的性能优化连接池优化:

代码语言:javascript代码运行次数:0运行复制transport.poolCount = 10

transport.tcpMux = true

transport.tcpMuxKeepaliveInterval = 60增加连接池大小,启用TCP多路复用,可以显著提高并发性能。

压缩配置:

代码语言:javascript代码运行次数:0运行复制[[proxies]]

name = "web-compressed"

type = "http"

localPort = 8080

customDomains = ["compressed.your_domain.com"]

transport.useCompression = true对于文本内容较多的服务,启用压缩可以节省带宽。

缓冲区调优:

代码语言:javascript代码运行次数:0运行复制transport.tcpKeepalive = 7200调整TCP keepalive参数,在网络不稳定的环境下可以提高连接稳定性。

frp的安全加固安全性是frp部署中最重要的考虑因素:

TLS加密:

代码语言:javascript代码运行次数:0运行复制transport.tls.enable = true

transport.tls.certFile = "/path/to/cert.pem"

transport.tls.keyFile = "/path/to/key.pem"启用TLS可以加密frpc和frps之间的通信。

IP白名单:

代码语言:javascript代码运行次数:0运行复制# 只允许特定IP连接

allowPorts = "6000-6010,7000,9000-9010"

[[proxies]]

name = "ssh-restricted"

type = "tcp"

localPort = 22

remotePort = 6000

allowUsers = ["user1", "user2"]防火墙配置:

代码语言:javascript代码运行次数:0运行复制# 只允许必要的端口

ufw allow 7000/tcp

ufw allow 80/tcp

ufw allow 443/tcp

ufw allow 7500/tcp from your_admin_ip

ufw enablefrp的常见问题和解决方案在实际使用中,我遇到过不少问题,这里分享一些解决方案:

连接频繁断开:

这通常是网络不稳定导致的。可以调整心跳参数:

代码语言:javascript代码运行次数:0运行复制transport.heartbeatInterval = 30

transport.heartbeatTimeout = 90端口被占用:

代码语言:javascript代码运行次数:0运行复制# 检查端口占用

netstat -tlnp | grep :7000

# 或者用ss命令

ss -tlnp | grep :7000DNS解析问题:

如果使用自定义域名,确保DNS记录正确:

代码语言:javascript代码运行次数:0运行复制# 检查DNS解析

nslookup your_domain.com

dig your_domain.com性能问题:

可以通过iperf3测试网络性能:

代码语言:javascript代码运行次数:0运行复制# 服务端

iperf3 -s -p 5201

# 客户端

iperf3 -c server_ip -p 5201 -t 60WireGuard:现代化的VPN解决方案说到WireGuard,这玩意儿真的是让我眼前一亮。我第一次听说WireGuard是在前前年,当时还是实验性质的项目。现在它已经集成到Linux内核里了,成为了VPN领域的新标准。

WireGuard VPNWireGuard的技术原理WireGuard最大的特点就是简单和高效。传统的VPN协议像OpenVPN、IPSec配置复杂,代码量庞大。OpenVPN有几十万行代码,IPSec的实现更是复杂得让人头疼。

WireGuard的代码量只有4000行左右,这意味着什么?代码少意味着bug少,安全性更高,性能也更好。而且代码简单,审计起来也容易,安全专家可以很快发现潜在的问题。

WireGuard使用了现代的加密算法:

• ChaCha20用于对称加密• Poly1305用于认证• Curve25519用于密钥交换• BLAKE2s用于哈希• SipHash24用于哈希表密钥这些都是经过密码学专家验证的安全算法,而且性能优异。

WireGuard的网络模型WireGuard没有传统VPN的服务端客户端概念,它更像是点对点的网络。每个节点(peer)都有自己的密钥对,通过公钥来识别对方。

这种设计的好处是配置灵活,你可以搭建星型网络(所有节点连接到一个中心节点),也可以搭建网状网络(节点之间互相连接)。

WireGuard的路由是基于密钥的,每个peer配置了允许的IP范围(AllowedIPs),只有匹配的流量才会通过VPN隧道发送。这种设计既简单又安全。

WireGuard的详细部署我以Ubuntu 20.04为例,演示完整的部署过程。

安装WireGuard:

代码语言:javascript代码运行次数:0运行复制sudo apt update

sudo apt install wireguard wireguard-tools resolvconf现在的Linux发行版基本都内置了WireGuard支持,安装很简单。resolvconf是用来管理DNS的,虽然不是必须的,但建议安装。

生成密钥对:

代码语言:javascript代码运行次数:0运行复制# 切换到root用户,因为密钥文件权限要求很严格

sudo su

# 创建配置目录

mkdir -p /etc/wireguard

cd /etc/wireguard

# 生成服务端密钥对

wg genkey | tee server_private.key | wg pubkey > server_public.key

# 生成客户端密钥对

wg genkey | tee client1_private.key | wg pubkey > client1_public.key

wg genkey | tee client2_private.key | wg pubkey > client2_public.key

# 设置正确的权限

chmod 600 *.keyWireGuard使用Curve25519椭圆曲线加密,密钥长度是32字节,用base64编码后是44个字符。

服务端配置:

创建 /etc/wireguard/wg0.conf:

代码语言:javascript代码运行次数:0运行复制[Interface]

# 服务端私钥

PrivateKey = your_server_private_key_here

# VPN网段地址

Address = 10.0.0.1/24

# 监听端口

ListenPort = 51820

# 保存配置

SaveConfig = true

# 网络转发规则

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# 客户端1

[Peer]

# 客户端公钥

PublicKey = client1_public_key_here

# 允许的IP范围

AllowedIPs = 10.0.0.2/32

# 客户端2

[Peer]

PublicKey = client2_public_key_here

AllowedIPs = 10.0.0.3/32

# 保持连接活跃

PersistentKeepalive = 25这个配置创建了一个10.0.0.0/24的VPN网段,服务端IP是10.0.0.1。PostUp和PostDown是启动和关闭时执行的命令,用来配置iptables规则,实现NAT转发。

%i是WireGuard的变量,代表接口名称(这里是wg0)。eth0需要替换成你服务器的实际网卡名称,可以用 ip route 命令查看。

启用IP转发:

代码语言:javascript代码运行次数:0运行复制echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf

echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf

sudo sysctl -p这一步很重要,没有IP转发,客户端就无法通过VPN访问外网。

启动WireGuard:

代码语言:javascript代码运行次数:0运行复制sudo systemctl enable wg-quick@wg0

sudo systemctl start wg-quick@wg0

# 检查状态

sudo wg show

sudo systemctl status wg-quick@wg0如果一切正常,你应该能看到类似这样的输出:

代码语言:javascript代码运行次数:0运行复制interface: wg0

public key: your_server_public_key

private key: (hidden)

listening port: 51820客户端配置:

创建客户端配置文件 client1.conf:

代码语言:javascript代码运行次数:0运行复制[Interface]

# 客户端私钥

PrivateKey = client1_private_key_here

# 客户端VPN IP

Address = 10.0.0.2/24

# DNS服务器

DNS = 8.8.8.8, 1.1.1.1

[Peer]

# 服务端公钥

PublicKey = server_public_key_here

# 服务端地址和端口

Endpoint = your_server_ip:51820

# 允许的IP范围(0.0.0.0/0表示所有流量都走VPN)

AllowedIPs = 0.0.0.0/0

# 保持连接活跃

PersistentKeepalive = 25如果你只想访问内网资源,可以把AllowedIPs改成 10.0.0.0/24, 192.168.1.0/24 这样的内网网段。

客户端连接:

代码语言:javascript代码运行次数:0运行复制# Linux客户端

sudo wg-quick up client1

# 检查连接状态

sudo wg show

# 断开连接

sudo wg-quick down client1WireGuard的高级配置多网段支持:

如果你的内网有多个网段,可以这样配置:

代码语言:javascript代码运行次数:0运行复制[Interface]

PrivateKey = server_private_key

Address = 10.0.0.1/24

ListenPort = 51820

# 添加额外的路由

PostUp = ip route add 192.168.1.0/24 dev %i

PostUp = ip route add 172.16.0.0/16 dev %i

PostDown = ip route del 192.168.1.0/24 dev %i

PostDown = ip route del 172.16.0.0/16 dev %i

[Peer]

PublicKey = client_public_key

AllowedIPs = 10.0.0.2/32, 192.168.1.0/24, 172.16.0.0/16动态DNS支持:

如果服务器IP会变化,可以使用域名:

代码语言:javascript代码运行次数:0运行复制[Peer]

PublicKey = server_public_key

Endpoint = vpn.your_domain.com:51820

AllowedIPs = 0.0.0.0/0

PersistentKeepalive = 25流量分流:

只让特定流量走VPN:

代码语言:javascript代码运行次数:0运行复制# 只有访问公司内网的流量走VPN

AllowedIPs = 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16

# 或者只让特定域名走VPN(需要配合路由表)

PostUp = ip route add 1.2.3.4/32 dev %i # 某个特定服务器的IPWireGuard的性能优化MTU调优:

代码语言:javascript代码运行次数:0运行复制[Interface]

PrivateKey = your_private_key

Address = 10.0.0.2/24

MTU = 1420WireGuard的默认MTU是1420,在某些网络环境下可能需要调整。可以用ping测试最佳MTU:

代码语言:javascript代码运行次数:0运行复制# 测试MTU大小

ping -M do -s 1392 server_ipCPU亲和性:

对于高流量的服务器,可以绑定WireGuard到特定CPU核心:

代码语言:javascript代码运行次数:0运行复制# 查看WireGuard进程

ps aux | grep wg

# 设置CPU亲和性

taskset -cp 2,3 $(pgrep wg)内核参数调优:

代码语言:javascript代码运行次数:0运行复制# 增加网络缓冲区

echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf

echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf

echo 'net.ipv4.udp_mem = 102400 873800 16777216' >> /etc/sysctl.conf

sudo sysctl -pWireGuard的移动端配置WireGuard在移动端的表现特别出色,我经常用手机连接公司网络。

Android配置:

1. 在Google Play下载WireGuard官方app2. 点击"+"号,选择"从文件导入"或"扫描二维码"3. 导入客户端配置文件4. 点击开关连接iOS配置:

1. 在App Store下载WireGuard2. 点击"+"号,选择"从文件创建"3. 导入配置文件或手动输入配置生成二维码:

代码语言:javascript代码运行次数:0运行复制# 安装qrencode

sudo apt install qrencode

# 生成二维码

qrencode -t ansiutf8 < client1.conf手机扫描二维码就能直接导入配置,很方便。

WireGuard的监控和管理状态监控:

代码语言:javascript代码运行次数:0运行复制# 查看详细状态

sudo wg show all

# 查看流量统计

sudo wg show wg0 transfer

# 实时监控

watch -n 1 'sudo wg show wg0'日志查看:

代码语言:javascript代码运行次数:0运行复制# 查看系统日志

journalctl -u wg-quick@wg0 -f

# 查看内核日志

dmesg | grep wireguardWireGuard的故障排除连接问题:

代码语言:javascript代码运行次数:0运行复制# 检查防火墙

sudo ufw status

sudo iptables -L

# 检查端口监听

sudo netstat -ulnp | grep 51820

# 测试UDP连通性

nc -u server_ip 51820路由问题:

代码语言:javascript代码运行次数:0运行复制# 查看路由表

ip route show table all

# 手动添加路由

sudo ip route add 10.0.0.0/24 dev wg0DNS问题:

代码语言:javascript代码运行次数:0运行复制# 检查DNS配置

cat /etc/resolv.conf

# 测试DNS解析

nslookup google.com其他值得关注的内网穿透工具除了frp和WireGuard,还有一些其他的工具也挺不错的,各有特色。

ngrok:快速原型和演示的利器ngrok应该是最知名的内网穿透服务了,特别适合临时演示用。我记得第一次用ngrok的时候,就被它的简单程度震惊了。

基本使用:

代码语言:javascript代码运行次数:0运行复制# 下载ngrok

wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip

unzip ngrok-stable-linux-amd64.zip

# 注册账号获取token

./ngrok authtoken your_auth_token

# 暴露HTTP服务

./ngrok http 8080

# 暴露TCP服务

./ngrok tcp 22

# 暴露多个端口

./ngrok http 8080 --region=apngrok会给你分配一个随机的子域名,比如 https://abc123.ngrok.io,外网就能通过这个地址访问你的本地服务了。

配置文件:

创建 ~/.ngrok2/ngrok.yml:

代码语言:javascript代码运行次数:0运行复制authtoken: your_auth_token_here

region: ap

tunnels:

web:

proto: http

addr: 8080

subdomain: myapp

ssh:

proto: tcp

addr: 22

remote_port: 2222然后可以这样启动:

代码语言:javascript代码运行次数:0运行复制# 启动单个隧道

./ngrok start web

# 启动所有隧道

./ngrok start --all自建ngrok服务:

ngrok是开源的,你也可以自己搭建:

代码语言:javascript代码运行次数:0运行复制git clone https://github.com/inconshreveable/ngrok.git

cd ngrok

# 生成证书

openssl genrsa -out rootCA.key 2048

openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=your_domain.com" -days 5000 -out rootCA.pem

# 编译

make release-server release-client

# 启动服务端

./bin/ngrokd -tlsKey=rootCA.key -tlsCrt=rootCA.pem -domain="your_domain.com" -httpAddr=":8080" -httpsAddr=":8443"但说实话,自建ngrok比较麻烦,而且功能不如frp完善。

ZeroTier:虚拟局域网的魅力ZeroTier是一个很有意思的项目,它的理念是创建一个全球性的虚拟以太网。你可以把分布在世界各地的设备组成一个虚拟局域网,就像它们在同一个交换机下一样。

基本使用:

代码语言:javascript代码运行次数:0运行复制# 安装ZeroTier

curl -s https://install.zerotier.com | sudo bash

# 加入网络

sudo zerotier-cli join your_network_id

# 查看状态

sudo zerotier-cli status

sudo zerotier-cli listnetworksZeroTier的配置主要在web界面完成:

1. 注册ZeroTier账号2. 创建网络,获得16位的网络ID3. 设备加入网络后,在web界面授权4. 分配IP地址高级配置:

ZeroTier支持很多高级功能,比如路由规则、流量规则等。

路由配置:

代码语言:javascript代码运行次数:0运行复制# 让192.168.1.0/24网段通过特定节点路由

192.168.1.0/24 via 10.147.17.100流量规则:

代码语言:javascript代码运行次数:0运行复制# 只允许HTTP和HTTPS流量

accept ipprotocol tcp and dport 80 or dport 443;

drop;我用ZeroTier管理家里的各种设备,包括NAS、树莓派、软路由等等。出门在外也能随时访问,很方便。而且ZeroTier的移动端app做得很好,手机上也能轻松管理。

Tailscale:基于WireGuard的商业方案Tailscale基于WireGuard开发,但提供了更友好的管理界面和更简单的配置方式。它的理念是"零配置VPN",确实做到了开箱即用。

安装和使用:

代码语言:javascript代码运行次数:0运行复制# Ubuntu/Debian

curl -fsSL https://tailscale.com/install.sh | sh

# 启动并认证

sudo tailscale up

# 查看状态

tailscale status

# 查看IP

tailscale ip第一次运行会给你一个认证链接,在浏览器中完成认证后,设备就自动加入你的Tailscale网络了。

高级功能:

Tailscale有很多企业级功能:

子网路由:

代码语言:javascript代码运行次数:0运行复制# 让某台机器作为子网网关

sudo tailscale up --advertise-routes=192.168.1.0/24

# 在管理界面启用子网路由出口节点:

代码语言:javascript代码运行次数:0运行复制# 设置出口节点

sudo tailscale up --advertise-exit-node

# 使用出口节点

tailscale up --exit-node=exit-node-nameACL(访问控制列表):

代码语言:javascript代码运行次数:0运行复制{

"acls": [

{

"action": "accept",

"src": ["group:admin"],

"dst": ["*:*"]

},

{

"action": "accept",

"src": ["group:dev"],

"dst": ["tag:dev-servers:*"]

}

]

}不过Tailscale是商业服务,免费版本有设备数量限制(20台)。如果你不想自己维护服务器,而且设备不多,Tailscale是个不错的选择。

Cloudflare Tunnel:免费的企业级方案Cloudflare Tunnel(以前叫Argo Tunnel)是Cloudflare提供的免费内网穿透服务。它的优势是完全免费,而且性能很好,缺点是只支持HTTP/HTTPS协议。

安装和配置:

代码语言:javascript代码运行次数:0运行复制# 下载cloudflared

wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb

sudo dpkg -i cloudflared-linux-amd64.deb

# 登录认证

cloudflared tunnel login

# 创建隧道

cloudflared tunnel create my-tunnel

# 配置隧道

cat > ~/.cloudflared/config.yml << EOF

tunnel: my-tunnel

credentials-file: /home/user/.cloudflared/tunnel-id.json

ingress:

- hostname: app.example.com

service: http://localhost:8080

- hostname: api.example.com

service: http://localhost:3000

- service: http_status:404

EOF

# 配置DNS

cloudflared tunnel route dns my-tunnel app.example.com

cloudflared tunnel route dns my-tunnel api.example.com

# 运行隧道

cloudflare tunnel run my-tunnel高级配置:

Cloudflare Tunnel支持很多高级功能:

负载均衡:

代码语言:javascript代码运行次数:0运行复制ingress:

- hostname: app.example.com

service: http://localhost:8080

originRequest:

connectTimeout: 30s

tlsTimeout: 10s

- hostname: app.example.com

service: http://localhost:8081访问控制:

代码语言:javascript代码运行次数:0运行复制ingress:

- hostname: admin.example.com

service: http://localhost:8080

originRequest:

access:

required: true

teamName: your-team我用Cloudflare Tunnel部署了几个内部工具,比如监控面板、文档系统等。因为有Cloudflare的CDN加速,访问速度很快,而且自动HTTPS,省去了证书管理的麻烦。

Headscale:自建的Tailscale如果你喜欢Tailscale的功能,但不想依赖商业服务,可以试试Headscale。它是Tailscale控制服务器的开源实现。

部署Headscale:

代码语言:javascript代码运行次数:0运行复制# 下载Headscale

wget https://github.com/juanfont/headscale/releases/latest/download/headscale_linux_amd64

chmod +x headscale_linux_amd64

sudo mv headscale_linux_amd64 /usr/local/bin/headscale

# 创建配置文件

sudo mkdir -p /etc/headscale

sudo cat > /etc/headscale/config.yaml << EOF

server_url: https://headscale.example.com

listen_addr: 0.0.0.0:8080

metrics_listen_addr: 127.0.0.1:9090

grpc_listen_addr: 0.0.0.0:50443

grpc_allow_insecure: false

private_key_path: /etc/headscale/private.key

ip_prefixes:

- fd7a:115c:a1e0::/48

- 100.64.0.0/10

derp:

server:

enabled: false

urls:

- https://controlplane.tailscale.com/derpmap/default

auto_update_enabled: true

update_frequency: 24h

disable_check_updates: false

ephemeral_node_inactivity_timeout: 30m

db_type: sqlite3

db_path: /etc/headscale/db.sqlite

acme_url: https://acme-v02.api.letsencrypt.org/directory

acme_email: your-email@example.com

tls_letsencrypt_hostname: headscale.example.com

tls_letsencrypt_cache_dir: /etc/headscale/cache

tls_letsencrypt_challenge_type: HTTP-01

log_level: info

EOF

# 生成私钥

sudo headscale generate private-key > /etc/headscale/private.key

# 创建systemd服务

sudo cat > /etc/systemd/system/headscale.service << EOF

[Unit]

Description=headscale controller

After=syslog.target

After=network.target

[Service]

Type=simple

User=headscale

Group=headscale

ExecStart=/usr/local/bin/headscale serve

Restart=always

RestartSec=5

[Install]

WantedBy=multi-user.target

EOF

# 启动服务

sudo systemctl enable headscale

sudo systemctl start headscale客户端连接:

代码语言:javascript代码运行次数:0运行复制# 创建用户

sudo headscale users create myuser

# 生成认证密钥

sudo headscale --user myuser preauthkeys create --reusable --expiration 24h

# 客户端连接

sudo tailscale up --login-server https://headscale.example.com --authkey your-auth-keyHeadscale的功能还在快速发展中,虽然不如Tailscale官方服务完善,但基本功能都有了。

方案选择指南:什么场景用什么工具按使用场景选择用户类型

使用场景

推荐方案

优势

个人开发者

临时演示

ngrok

简单快速

长期使用

frp + 便宜VPS

成本低,功能全

安全要求高

WireGuard

端到端加密

多设备管理

ZeroTier/Tailscale

组网方便

小团队

预算有限

frp自建

一次投入,长期使用

追求简单

Tailscale

零配置,但有设备限制

需要管理界面

ZeroTier

免费版够用

Web应用为主

Cloudflare Tunnel

免费且性能好

企业用户

安全第一

WireGuard + 企业级VPS

高安全性

需要审计

frp + 完整日志系统

可追溯性

多云环境

Tailscale企业版/Headscale

跨云管理

合规要求

自建方案

数据不出境

按技术要求选择技术需求

推荐方案

说明

只需HTTP/HTTPS

Cloudflare Tunnel

免费,自动HTTPS

ngrok

功能强大,但付费

frp

自建,完全控制

需要TCP/UDP

frp

支持最全面

WireGuard

VPN方案,支持所有协议

ZeroTier

虚拟局域网

需要高性能

WireGuard

内核级别,性能最好

frp

Go语言,性能不错

Tailscale

基于WireGuard

需要移动端支持

WireGuard

官方app,体验最好

ZeroTier

跨平台支持好

Tailscale

移动端体验优秀

写在最后如果你觉得干的话,请点赞!收藏!转发!谢谢!!!

想了解更多运维实战经验和技术干货,记得关注微信公众号@运维躬行录,领取学习大礼包!!!我会持续分享更多接地气的运维知识和踩坑经验。让我们一起在运维这条路上互相学习,共同进步!

公众号:运维躬行录

个人博客:躬行笔记

相关推荐

全球Top15最具影响力葡萄酒品牌都有谁?榜单公布!
痛惜!今年已有22位演艺界名人逝世
炒菜锅哪个品牌更值得入手?五款高性价比无涂层炒锅大推荐