本文记录梅林固件华硕路由器配置ipv6、防火墙、DDNSv6、Cloudflare代理与Nginx配置。
原本自2017年以来使用的联通300M宽带,EPON,有公网IP、可以多拨,能稳定700M下行,于是利用端口转发内网的文件服务器使用了很长时间。但自2023年9月起,天津联通部分地区拨号不再提供公网ipv4地址,因此将路由改为获取ipv6使用。
本例中光猫桥接,路由拨号并获取到公网ipv6,服务器获取到全球单播地址。域名配置 AAAA
记录指向服务器ipv6,服务器定期向域名DNS更新ip,并且正确配置路由器ipv6防火墙使只允许指向服务器的特定端口放行。
graph LR
1(域名) --> |AAAA| 2[[路由器防火墙]] -->|放行| 3[服务器]
3 -.-> |DDNS更新| 1
ipv6构成
2408:8210:8433:160::1/64
,2408:8210:8f03:20ed:6d4:c49d:2c42:a650/64
ipv6为128位ip地址,上面为两个典型的示例ipv6地址,/64
为子网掩码表示该地址前64位是固定的。一般前64位为子网ID,表示某个具体的子网;后64位为接口ID,可以由设备MAC地址计算得到,表示用户的唯一标识。
上网设备的ipv6地址分为单播、组播和任播地址。由运营商得到每个设备的ipv6全球唯一单播地址,均为公网ip,以二进制001
开头,即16进制2000::/3
,如2408:8xxx
即为联通的网络。除此之外还有链路本地地址fe80::1/10
、私网地址 fc0d::/7
(类比ipv4的192.168.x.x
)。
一般可以从运营商处获得/60
的子网,有空余的4位可以最多再划分成最多16个子网,不过一般路由器倾向于只保留一个子网。
如
240e:3c1:5665:1cd/60
子网可划分成:
240e:3c1:5665:1cdf/64
给IoT设备、240e:3c1:5665:1cd3/64
给语音、240e:3c1:5665:1cd0/64
用于上网
接口ID可以由MAC自动生成(如EUI-64算法),无需DHCPv6,这也是ipv6无状态自动配置的一大特点。华硕路由中ipv6地址的获取分为stateless
和stateful
,无状态获得的地址会自动变化,而有状态的地址可以划定地址池固定不变。为了能更好地写路由器ipv6防火墙配置,本文中采用stateful
获取ipv6地址。
路由器设置
在华硕/梅林路由器中,开启ipv6,获取模式为native,状态为stateful,这样每个设备能获取到不变的接口ID。
IPV6防火墙
参考:路由器梅林固件如何设置IPV6端口转发_路由器_什么值得买 (smzdm.com)
服务器有后缀不变的公网ipv6后,还需配置路由器的ipv6防火墙使得服务器对应端口能被正确访问。在ipv6防火墙规则处添加你想放行的端口,内网ip和子网掩码实测这样写能够正常配置,注意前面ip的0
不可省略。
0:0:0:0:0:0:0:1234/::FFFF:FFFF:FFFF:FFFF
(上面参考文章中的方法实测iptables
会录入不全,可以ssh进路由器,使用 ip6tables --list
查看记录)
外网访问 DDNSv6
你内网的服务器现在有了公网ipv6,如何能访问到它呢?因为这是一个纯ipv6站,所以需要你的访问设备也支持ipv6,没有ipv6地址的设备是无法访问纯ipv6站点的。
可以使用 https://ipw.cn/ 和 https://ipv6ready.me/ 来检测自己设备对ipv6的支持状况。
若显示OK则您的设备可以正常访问ipv6网站!倘若您的设备没有通过测试(像是使用纯ipv4的代理服务器访问时)也是有办法能公网访问ipv6服务器的。
这里我们采用DNSPOD
做域名解析,在服务器上使用ddns-go
程序负责DDNSv6。
先在DNSPOD上配置一条指向服务器的AAAA记录
AAAA ddnsv6.example.com 2408:8210:8333:4cda::1234
之后在服务器上配置DDNS项目,本次使用ddns-go
项目: https://github.com/jeessy2/ddns-go
ddns-go
也可以很方便的使用docker部署:
sudo docker run -d --name ddns-go --restart=always --net=host -v /opt/ddns-go:/root jeessy/ddns-go
启动成功后通过 http://[server ip]:9876
访问web界面
这里填入DNSPOD的domain id和API Token,勾选启用IPV6并填如你需要DDNS到的子域名。
ddns-go也可以使用webhook启用通知功能,下面以方糖Server酱为例,可传入的参数可参考ddns-go说明文档。
https://sctapi.ftqq.com/YOUR_KEY.send?title=你的公网IP变了&desp=主人IPv6变了#{ipv6Addr},域名更新结果:#{ipv6Result},涉及变更的子域名为#{ipv6Domains}
这样每当ip地址变化时,你可以通过微信公众号等方式得到通知。
Nginx 反代
在ipv4配合端口转发使用时,我们采取单一子域名,使用不同映射端口配合Nginx反向代理来实现外网访问服务器的不同功能。而在使用ipv6+防火墙放行时,可以采用固定传输端口,不同子域名对应不同业务的方式访问服务器。
对于某些地区ipv6开放80、443端口,使用后者方法会更加方便,而天津联通矢志不渝地封禁80、8080和443端口,这一方法似乎也不很优雅。不过事实上固定传输端口有另外的好处。
前面说过纯ipv4设备无法直接访问纯ipv6站点,这一困境可以通过Cloudflare CDN来实现,即通过Cloudflare的代理实现6to4,让你的源站拥有ipv4,而Cloudflare仅能代理固定的几个端口。
我们给不同服务安排了不同的子域名,并在DNSPOD上申请了免费证书(期限一年不用白不用),在nginx中配置反向代理,把https端口挪到8443
,在路由器防火墙只放行https端口,不放行http端口。
子域名与反向代理可以灵活搭配,例如访问https://ddns.example.com:8443/
为提示页面
访问https://ddns.example.com:8443/ddns-go
为ddns-go管理页面
访问https://ha.example.com:8443/
为homeassistant管理页面
下面是一个含有反向代理地示例:
# ddns.example.com
server
{
listen [::]:880;
listen [::]:8443 ssl http2;
server_name ddns.example.com; #填写你需要的泛域名
charset utf-8;
ssl_certificate /root/cert/ddns.example.com_nginx/ddns.example.com_bundle.pem;
ssl_certificate_key /root/cert/ddns.example.com_nginx/ddns.example.com.key;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
###### MCS Daemon deepin Reverse Proxy ######
location /mcs-daemon {
#proxy_redirect off;
proxy_pass http://127.0.0.1:24444/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
#proxy_set_header Host $Host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Sec-WebSocket-Protocol wss;
}
}
阻止纯ip访问:
在Nginx
1.19.4
或更高版本中可以直接使用ssl_reject_handshake on
阻止握手,防止通过IP访问握手获得网站证书,进而同时获得网站域名与IP地址,参见 Cloudflare证书与Nginx安全不过本deepin服务器使用debian10的古老源,只能设置返回错误页面来阻止纯ip访问。
# default ip access
server {
listen [::]:880 default_server;
listen [::]:8443 ssl http2 default_server;
server_name _;
#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
# 阻止握手
# ssl_reject_handshake on;
return 444;
}
Cloudflare 6to4
为了使无ipv6设备也能访问你的纯ipv6服务器,我们可以借助Cloudflare提供的免费的CDN代理,缺点是你需要另外一个域名,而且流量会在国外绕一圈,延迟更高。
在Cloudflare的DNS中新建一条CNAME记录,记得要开启小云朵Proxy:
CNAME ddnscf.cloudflare.com ddns.example.com
之后我们就可以通过访问https://ddnscf.cloudflare.com:8443
到达源服务器了。注意Cloudflare支持代理的端口有限,一定要将https端口设置成Cloudflare支持的端口:
Network ports · Cloudflare Fundamentals docs
你可以直接使用Cloudflare解析做DDNS,也可以使用443转8443来绕过端口限制等等。