结合动态域名的端口转发工具:haproxy

家庭宽带通常可以轻松获得公网IPv6地址。因此,通过一台IPv4/IPv6双栈VPS来做端口转发实现家庭设备的访问是常见的需求。之前曾经提过可以用socat来实现(11 用nginx和socat实现ipv4与ipv6的转换),但socat有一个局限性:它对域名的解析只在启动时执行一次。由于家庭宽带的公网IPv6是典型的动态域名(使用he.net的动态域名服务),如果socat启动后,家庭设备的动态域名解析IP发生了变化,那么socat的端口转发就失效了。

当然,可以为socat.serivce设置timer,让它定期重启(比如每半个小时重启一次)。这勉强算是能解决,但不优雅。更好的做法是haproxy。

1、安装haproxy

非常简单:

apt update
apt install haproxy

即可完成安装。安装会同时在/lib/systemd/system/中创建haproxy.service,以确保其每次开机自动运行。

2、配置haproxy

haproxy的配置文件默认在\etc\haproxy\haproxy.cfg。打开它进行编辑。

用于我们通常转发是用于远程桌面,建议先将defaults段中的mode和option将原来的http模式改成tcp模式:

defaults
    mode tcp
    option tcplog

试验表明,tcp模式兼容性强一点儿,也可用于http,不会报错。

然后在文件的最后,加上若干frontend、backend配置对:

frontend site1-front
	bind *:3390
	mode tcp
	default_backend site1-back

backend site1-back
	mode tcp
	server site1 site1.com:3389 resolvers mydns resolve-prefer ipv6 check

需要注意的是,frontend、backend的名称要唯一。在这里,frontend接收IPv4端口3390的请求,并转发到IPv6网站site1.com的3389端口。为了解析site1.com,指定了解析器为mydns。mydns后面需要手动定义。

配置好所有的frontend和backend后,追加mydns配置:

resolvers mydns
 	nameserver dns1 8.8.8.8:53      # Google DNS IPv4
	nameserver dns2 2001:4860:4860::8888:53  # Google DNS IPv6
 	nameserver dns3 1.1.1.1:53      # Cloudflare DNS IPv4
  	nameserver dns4 2606:4700:4700::1111:53  # Cloudflare DNS IPv6
	resolve_retries 3
	timeout resolve 5s
	timeout retry   1s
	hold valid 300s

添加了IPv4和IPv6的DNS,设置解析重试次数为3,解析超时为5s,重试间隔为1s,缓存时间为5分钟(300s)。

保存haproxy.cfg文件。

3、检查防火墙配置

开放刚刚设置的所有frontend监听端口。例如,frontend设置监听端口为3390,则:

ufw allow 3390/tcp

可以用ufw status来查看当前的防火墙设置情况。

4、重启haproxy

用systemctl来重新加载haproxy:

systemctl reload haproxy

不出意外的话,现在已经可以使用了。haproxy的另一个好处是,它一旦执行,即使当时site1.com没有在线,它也会锲而不舍地对它进行解析,确保它一上线就可以建立连接。

5、用iperf3测试机器之间的实际连接带宽

在设置了如迷宫一样的端口转发后,有时候速度不太理想,此时可以用跨平台工具iperf3来测试两点之间的实际连接速度。

在ubuntu-A上,安装iperf3:

apt update
apt install iperf3

然后就可以用它来创建一个监听端(默认监听端口5201,注意在ufw中放行):

iperf3 -s

或加上-p指定端口(注意在ufw中放行):

iperf3 -s -p 12345

同样地,在另一台ubuntu-B上,连接ubuntu-A:

iperf3 -c ubuntu-A-IP -p 12345 -t 30

其中-p为指定端口,-t为连接时间(不设置则默认为10s)。

windows版本的iperf3项目地址:https://github.com/ar51an/iperf3-win-builds,下载解压缩后,用cmd执行同样的命令即可。