前一段时间买了台 HPE Microserver Gen10,考虑到这货有两块千兆网卡,总觉得不把它当成路由器/网关来用有点浪费,于是忍不住拆掉了原来的 EdgeRouter X,开始折腾软路由。
基础配置
连接
Microserver Gen10 有两块网卡,在 Debian 中分别对应 enp2s0f0
和 enp2s0f1
,这里我将 enp2s0f0
作为LAN口,连接到家里的交换机,用于连接各种有线设备和无线AP;另一个 enp2s0f1
作为WAN口,连接到光猫。
系统
没什么好说的,习惯用 Debian,其他主流 Linux 发行版应该都可以用。不过在装 Debian 的过程中遇到了些 Microserver 特有的坑,回头再写篇文章详解。
PPPoE 拨号
作为网关,PPPoE 拨号是必须的,安装 pppoeconf
包,然后按照提示配置即可:
sudo apt install pppoeconf sudo pppoeconf
网关 IP
跟大多数家用路由器一样,网关的LAN口需要拥有一个固定的内网IP地址,这里我设置为 192.168.1.1/24
(假设LAN网段为192.168.1.0/24
),编辑 /etc/network/interfaces
,添加LAN口配置:
allow-hotplug enp2s0f0 auto enp2s0f0 iface enp2s0f0 inet static address 192.168.1.1/24
重启 networking 服务使之生效:
sudo systemctl restart networking
DHCP 服务和 DNS 服务
网关开启DHCP服务,给局域网内的设备自动分发IP地址,这里我用的是非常流行的 dnsmasq,不仅可以作为DHCP服务器,还能作为DNS服务器。安装 dnsmasq:
sudo apt install dnsmasq
编辑 /etc/dnsmasq.conf
,添加如下配置:
interface=enp2s0f0 listen-address=192.168.1.1 dhcp-range=192.168.1.10,192.168.1.150,255.255.255.0,12h dhcp-option=3,192.168.1.1
重启 dnsmasq 服务使之生效:
sudo systemctl restart dnsmasq
IP 转发和 NAT
光有IP地址还不够,作为网关,必须要能够转发来自局域网的所有数据。编辑 /etc/sysctl.conf
,将 net.ipv4.ip_forward
这一行的注释去掉:
net.ipv4.ip_forward=1
然后执行 sudo sysctl -f
使其生效。
同时,为了使局域网内的设备能够访问外网,还需要配置NAT规则:
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
进阶配置
至此,所有局域网设备应该能够通过刚刚设置好的网关访问互联网了。但是既然用 Debian 服务器作为软路由,当然要充分利用 Linux 的灵活性,进行更进一步的配置。
防火墙
屏蔽掉除了 PING 和 SSH 服务以外的一切外部来源请求:
sudo iptables -A INPUT -p icmp -m icmp-type 8 -j ACCEPT sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A INPUT -i ppp0 -j DROP
Wireguard
为了方便从外网访问家里的局域网,我在一台外网的服务器上配置了 Wireguard,只需要将网关与外网的服务器通过 Wireguard 连接,不论我在哪里,只要能连上 Wireguard 网络,就能穿透互联网回到家中。
Wireguard 的安装可以参考官网介绍 https://www.wireguard.com/install/
安装好 Wireguard 之后,创建 Wireguard 的配置文件,假设为 /etc/wireguard/wg0.conf
:
[Interface] PrivateKey = [PRIVATE KEY] ListenPort = 51820 [Peer] Endpoint = [ENDPOINT]:51820 PublicKey = [PEER'S PUBLIC KEY] AllowedIPs = 192.168.10.0/24 PersistentKeepalive = 30
这里使用了端口 51820,因此需要在防火墙开启这一端口:
sudo iptables -I INPUT -p udp -m udp -s ENDPOINT --dport 51820 -j ACCEPT
同时,编辑 /etc/network/interfaces
添加 Wireguard 的相关配置:
auto wg0 iface wg0 inet static address 192.168.10.x/24 pre-up ip link add $IFACE type wireguard pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf post-down ip link del $IFACE
启动 Wireguard 后,这时候 Wireguard 的虚拟网络为 192.168.10.0/24
,而内网网段为 192.168.1.0/24
,为了让连接到 Wireguard 网络的所有设备(比如手机)能够顺利访问到所有内网设备,还需要在网关上进行 NAT 的配置:
sudo iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 192.168.1.1
这样所有来自 Wireguard 网段的请求的源地址都会被翻译成 192.168.1.1
从而得以访问内网其他设备。此外,还需要在外网的服务器上将 192.168.1.0/24
加入 AllowedIPs
,这里贴一个外网服务器的 Wireguard 配置:
[Interface] ListenPort = 51820 PrivateKey = [PRIVATE KEY] [Peer] PublicKey = [PEER'S PUBLIC KEY] AllowedIPs = 192.168.10.x/32, 192.168.1.0/24 PersistentKeepalive = 30
SS-REDIR 和 SS-TUNNEL
由于家里有两个 Google Home 音箱,为了让它们能够顺利连到 Google,需要在网关上进行相应的配置。这里我选择使用 ss-redir 和 ss-tunnel,其中 ss-redir 用于透明代理,ss-tunnel 用于 DNS 代理。
ss-redir 和 ss-tunnel 的安装和配置可以参考官方介绍 https://github.com/shadowsocks/shadowsocks-libev#transparent-proxy
我将 ss-redir 配置在了1081端口,ss-tunnel
配置在了5300端口。假设 Google Home 音箱的 IP 地址是 192.168.1.x
,只需如下配置即可完成对 TCP 流量的转发:
sudo iptables -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.x -j REDIRECT --to-port 1081
然而光配置好 TCP 流量的转发还不够,Google Home 音箱使用 Google 的 DNS 服务器进行 DNS 解析,因此需要将其重定向到 ss-tunnel 所在的5300端口:
sudo iptables -t nat -A PREROUTING -p udp -m udp -s 192.168.1.x --dport 53 -j REDIRECT --to-port 5300
解决 DNS 污染
既然有了 ss-tunnel 顺便解决一下 DNS 污染问题吧,把所有的 DNS 请求都转发到国外去请求是不现实的,会导致 DNS 解析时间过长不说还会使很多国内网站解析到国外的 IP 从而使访问变慢。考虑到前面我已经装了 dnsmasq,因此,我选择了dnsmasq-china-list 这个项目来解决 DNS 污染问题。
dnsmasq-china-list 的思路很简单,国内域名用国内 DNS 服务器解析,其他域名用国外 DNS 服务器解析,为了实现这一目的,需要将项目目录中的 accelerated-domains.china.conf
和 bogus-nxdomain.china.conf
放到 /etc/dnsmasq.d/
目录中,同时编辑 /etc/dnsmasq.conf
,将上游 DNS 服务器指向 ss-tunnel:
no-resolv server=192.168.1.1#5300 conf-dir=/etc/dnsmasq.d
重启 dnsmasq 使之生效:
sudo systemctl restart dnsmasq
IPv6
由于江苏联通至今没有提供原生的 IPv6 接入,因此现阶段若要体验 IPv6 还只能通过 HE 提供的 IPv6 Tunnel Broker 接入。
在 Tunnel Broker 网站上申请好 IPv6 Tunnel 之后, 编辑 /etc/network/interfaces
,添加 tunnel 配置:
auto tun0 iface tun0 inet6 v4tunnel address [Client IPv6 Address] netmask 64 endpoint [Server IPv4 Address] local 0.0.0.0 ttl 255 gateway [Server IPv6 Address]
别忘了将 Tunnel Broker 的 Endpoint IPv4 地址加入防火墙白名单:
sudo iptables -I INPUT -s [Server IPv4 Address] -j ACCEPT
网关有了 IPv6 地址之后,还得给局域网内的设备分配 IPv6 地址,这里需要用到 radvd:
sudo apt install radvd
编辑 /etc/radvd.conf
,将 Tunnel Broker 分配的 /64 地址段填进去:
interface enp2s0f0 { AdvSendAdvert on; AdvIntervalOpt on; MinRtrAdvInterval 60; MaxRtrAdvInterval 300; AdvLinkMTU 1280; AdvOtherConfigFlag on; AdvHomeAgentFlag off; prefix [Routed IPv6 Prefix /64] { AdvOnLink on; AdvAutonomous on; AdvRouterAddr on; }; };
重启 radvd,局域网内的设备应该都能获得 IPv6 地址了:
sudo systemctl restart radvd
Leave a Comment