转载自:https://blog.bling.moe/post/3/

在这篇文章里,小玲将教你如何将一个装着干净的 Debian 系统的设备变成一个能让局域网内设备上网的软路由。小玲使用一台 Nanopi R4S 作为演示用的设备,刷入的系统为 Armbian 21.08.1,Debian 版本为 11。你也可以用 X86 的设备,设置过程基本上没有区别。

将 Armbian 系统刷入 TF 卡后,咱们将卡插入 R4S 的 TF 卡槽里,使用一条网线接在原本的路由器的 LAN 口上,然后给 R4S 通电。

找到 R4S 通过 DHCP 获取的 IP 地址。用默认用户名 root,默认密码 1234 登录 SSH。在完成 Armbian 系统的初始设置后,咱们现在得到了一个干净的 Armbian 系统。下面的步骤都是用在 Armbian 系统的初始设置里创建的非 root 用户操作的。小玲不建议大家直接用 root 用户操作。

设置密钥

安装完后第一步是要确保路由器安全,因为当设置好后路由器是要暴露在公网上的。有人会扫描 IPv4 的 IP 段,然后再扫描能连通的 IP 地址的端口。如果发现是 SSH 端口,还会爆破。所以咱们要使用密钥文件登录,而且要把密码登录关闭。

创建存放密钥的文件夹,默认路径是家目录下的 .ssh 文件夹。

mkdir ~/.ssh

写入密钥。这里密钥请替换成你自己的。

echo 'ssh-rsa <private_key>' >> ~/.ssh/authorized_keys

编辑 sshd 配置文件。

sudo vim /etc/ssh/sshd_config

PermitRootLogin 设为 no 以关闭 root 账号登录;将 PubkeyAuthentication 设为 yes 以开启密钥登录;AuthorizedKeyFile 为密钥路径;将 PasswordAuthentication 设为 no 以关闭密码登录。

PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeyFile .ssh/authorized_keys .ssh/authorized_keys2
PasswordAuthentication no

保存后,重启 SSH 服务。

sudo systemctl restart ssh

现在咱们可以在不关闭当前 SSH 连接的情况下新建一个用密钥登录的 SSH 连接。如果登录成功了,就可以断开用密码登录的 SSH 连接了。如果不出意外,现在就不能用密码登录了。

更新系统

先把系统更新到最新。

sudo apt update
sudo apt upgrade -y

更新过后,如果是 Armbian 系统,有可能会更新内核。更新内核时需要重启以使用新内核。不过咱们先不着急重启。

设置网络

查看一下网络配置文件

cat /etc/network/interfaces

如果是 Armbian 系统,默认内容如下。

source /etc/network/interfaces.d/*
# Network is managed by Network manager
auto lo
iface lo inet loopback

可以看到现在网络的配置是由 NetworkManager 接管的,原本的 Debian 系统是不预装 NetworkManager 的,为了和原本的 Debian 系统设置方法统一,Armbian 系统要把 NetworkManager 卸载掉。这个步骤只是 Armbian 系统才有的,Debian 系统不需要做此步骤。

在卸载 NetworkManager 前,需要先把 /etc/network/interfaces 文件的配置写上。咱们先查看一下接口名称。

ip a

返回如下。小玲自己的 IP 地址和 MAC 地址已打码。

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether ██:██:██:██:██:██ brd ff:ff:ff:ff:ff:ff
    inet 192.168.███.███/24 brd 192.168.███.███ scope global dynamic noprefixroute enp1s0
       valid_lft 2338sec preferred_lft 2338sec
    inet6 fdb0:████:████:████:████:████:████:████/64 scope global dynamic noprefixroute
       valid_lft 3455sec preferred_lft 3455sec
    inet6 240█:████:████:████:████:████:████:████/64 scope global dynamic noprefixroute
       valid_lft 3455sec preferred_lft 3455sec
    inet6 fe80::████:████:████:████/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether ██:██:██:██:██:██ brd ff:ff:ff:ff:ff:ff

现在咱们可以看到 LAN 口的接口名称是 enp1s0,WAN 口的接口名称是 eth1。因为接下来咱们要使用 IPv6 网络,所以咱们要先规划一下局域网的 IPv6 网段,咱们可以打开这个 网站,输入 LAN 口 的 MAC 地址就能生成一个局域网 IPv6 网段,生成出来的是一个 /48 的网段(例如 fddd:afcf::/48)。不过小玲觉得 /48 实在是太大了。所以小玲取了 /48 里面的第一个 /64 网段 fddd:afcf::/64 来作为演示用的局域网 IPv6 网段。

编辑 /etc/network/interfaces

sudo vim /etc/network/interfaces

将文件改写成现在这个样子。小玲将 IPv4 网段设成了 192.168.3.0/24。当然网段你也可以改成你喜欢的。

source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback

auto enp1s0
allow-hotplug enp1s0
iface enp1s0 inet static
    address 192.168.3.1/24
iface enp1s0 inet6 static
    address fddd:afcf::/64

auto eth1
allow-hotplug eth1
iface eth1 inet dhcp

保存好以后就可以卸载 NetworkManager 了。

sudo apt remove -y network-manager
sudo apt autoremove -y

开启 IPv6(Armbian专属)

在小玲做教程的时候 Armbian 系统有个 bug。如果你不做这个操作的话,后面 PPPoE 拨号时会获取不了 IPv6 地址。所以这个步骤是 Armbian 系统才需要做的,原版 Debian 系统可以跳过这里。

首先执行下面这条命令打开 armbian-config

sudo armbian-config

通过上下键移动光标到 Network 选项,通过左右键移动光标到 Ok 选项,然后回车。可以看到 IPv6 选项是 Disable IPv6 for APT and system。表明它现在显示是开启的,但实际上并没有开启。DisableEnable 一下 IPv6 这个选项。现在是真的开启了。

开启转发

编辑 /etc/sysctl.conf 文件。

sudo vim /etc/sysctl.conf

/etc/sysctl.conf 的末尾添加以下内容。

net.ipv4.ip_forward=1
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.default.accept_ra=2
net.ipv6.conf.default.use_tempaddr=1

应用配置。

sudo sysctl -p

因为之前咱们更新了系统。现在最好重启一下,顺便应用新的网络设置。

sudo reboot

重启之后 R4S 的 LAN 口的 IP 地址已经变成了 192.168.3.0/24 这个网段了,不能再通过将 R4S 的 LAN 口连接原来的路由器的 LAN 口来获取原来的路由器的 IP 地址了。所以咱们需要使用一条网线连接着 R4S 的 LAN 口和电脑,一条网线连接的原本路由器的 LAN 口和 R4S 的 WAN 口。因为 R4S 上现在还没有 DHCP 服务,所以咱们需要把电脑的 IPv4 地址设为与 R4S 的 LAN 口的 IPv4 地址同一网段的 IPv4 地址。这里咱们就设成 192.168.3.2,子网前缀长度是 24,网关是 R4S 的 IP 地址 192.168.3.1。IPv6 先不用管。

设置完电脑的 IP 地址后,通过 SSH 连接到 192.168.3.1 来继续设置 R4S。

安装必要的软件

这些软件都是接下来要使用的。

sudo apt install -y nftables pppoeconf 

使用 Docker 能减少软件的部署的难度。所以也安装上。

sudo wget -qO- https://get.docker.com/ | sh

安装 Docker Compose。

sudo wget "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" -O /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

配置 Dnsmasq

创建一个文件夹来存放 Dnsmasq 的配置文件。

mkdir -p ~/config/dnsmasq

编写 dnsmasq.conf

vim ~/config/dnsmasq/dnsmasq.conf

写入以下内容。

interface=enp1s0
port=53
server=8.8.8.8
server=8.8.4.4
enable-ra
dhcp-range=192.168.3.2,192.168.3.254,1h
dhcp-range=::,constructor:enp1s0,slaac,1h
dhcp-option=option:router,192.168.3.1
dhcp-option=option:dns-server,192.168.3.1
dhcp-option=option6:dns-server,[fddd:afcf::]

interface 是 LAN 口的接口名称。

port 是 R4S 上的 DNS 服务的端口,一般都要设为 53

server 是上游 DNS 服务器的地址,这里就以谷歌的 DNS 服务器作为例子。

enable-ra 是用于向局域网内分发 IPv6 地址的。

dhcp-range 是 DHCP 分发 IP 地址的范围,后面的 1h 是过期所需要的时间。

dhcp-option=option:router 是向局域网内宣告的 IPv4 网关地址。

dhcp-option=option:dns-server 是向局域网内宣告的 IPv4 DNS 服务器地址。

dhcp-option=option6:dns-server 是向局域网内宣告的 IPv6 DNS 服务器地址,这个地址也可以用 fe80 开头的那个地址来代替。

编辑 docker-compose.yml 文件,咱们使用 Dnsmasq 的 Docker 版来提供 DNS 和 DHCP 服务。

vim ~/docker-compose.yml

写入以下内容。

version: "3"
services:
  dnsmasq:
    container_name: dnsmasq
    cap_add: 
      - NET_ADMIN
    image: anzevalher/dnsmasq
    network_mode: host
    volumes:
      - ./config/dnsmasq/dnsmasq.conf:/etc/dnsmasq.conf:ro
    restart: always

这里的 dnsmasq 容器必须要使用 host 网络模式,bridge 是不行的。

启动容器。

sudo docker-compose -f ~/docker-compose.yml up -d

现在把电脑的 IP 地址从静态改回 DHCP 的。咱们可以发现现在已经可以通过 DHCP 获取 IP 地址了。

PPPoE 拨号

现在咱们可以开始连接外网了,咱们把连接 R4S 的 WAN 口的那条网线连接到光猫上。然后执行

sudo pppoeconf

这时候开始扫描哪个接口能连接 PPPoE。

┌───────────────────┤ SCANNING DEVICE ├────────────────────┐
│ Looking for PPPoE Access Concentrator on enp1s0...       │
│                            66%                           │
└──────────────────────────────────────────────────────────┘

这里选择 Yes

┌────────────────────────┤ POPULAR OPTIONS ├─────────────────────────┐
│ Most people using popular dialup providers prefer the options      │
│ 'noauth' and 'defaultroute' in their configuration and remove the  │
│ 'nodetach' option. Should I check your configuration file and      │
│ change these settings where neccessary?                            │
│                  <Yes>                     <No>                    │
└────────────────────────────────────────────────────────────────────┘

这里输入宽带用户名。

┌────────────────────┤ ENTER USERNAME ├────────────────────┐
│ Please enter the username which you usually need for the │
│ PPP login to your provider in the input box below. If    │
│ you wish to see the help screen, delete the username and │
│ press OK.                                                │
│                                                          │
│ ________________________________________________________ │
│                          <Ok>                            │
└──────────────────────────────────────────────────────────┘

这里输入宽带密码。

┌────────────────────┤ ENTER PASSWORD ├────────────────────┐
│ Please enter the password which you usually need for the │
│ PPP login to your provider in the input box below.       │
│                                                          │
│ NOTE: you can see the password in plain text while       │
│ typing.                                                  │
│                                                          │
│ ________________________________________________________ │
│                          <Ok>                            │
└──────────────────────────────────────────────────────────┘

这里选 No,因为咱们已经有 Dnsmasq 了,咱们可以将路由器自身的 DNS 请求交给 Dnsmasq 处理。

┌─────────────────────┤ USE PEER DNS ├─────────────────────┐
│ You need at least one DNS IP address to resolve the      │
│ normal host names. Normally your provider sends you      │
│ addresses of useable servers when the connection is      │
│ established. Would you like to add these addresses       │
│ automatically to the list of nameservers in your local   │
│ /etc/resolv.conf file? (recommended)                     │
│               <Yes>                  <No>                │
└──────────────────────────────────────────────────────────┘

这里选 Yes

┌──────────────────────┤ LIMITED MSS PROBLEM ├───────────────────────┐
│                                                                    │
│ Many providers have routers that do not support TCP packets with a │
│ MSS higher than 1460. Usually, outgoing packets have this MSS when │
│ they go through one real Ethernet link with the default MTU size   │
│ (1500). Unfortunately, if you are forwarding packets from other    │
│ hosts (i.e. doing masquerading) the MSS may be increased depending │
│ on the packet size and the route to the client hosts, so your      │
│ client machines won't be able to connect to some sites. There is a │
│ solution: the maximum MSS can be limited by pppoe. You can find    │
│ more details about this issue in the pppoe documentation.          │
│                                                                    │
│ Should pppoe clamp MSS at 1452 bytes?                              │
│                                                                    │
│ If unsure, say yes.                                                │
│                                                                    │
│ (If you still get problems described above, try setting to 1412 in │
│ the dsl-provider file.)                                            │
│                                                                    │
│                  <Yes>                     <No>                    │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

这里问咱们是否要在开机时自动拨号,作为一个路由器当然要在开机时自动拨号啦。所以咱们选 Yes

┌─────────────────────────┤ DONE ├─────────────────────────┐
│ Your PPPD is configured now. Would you like to start the │
│ connection at boot time?                                 │
│               <Yes>                  <No>                │
└──────────────────────────────────────────────────────────┘

这里告诉咱们可以使用 pon dsl-provider 开启连接;使用 poff 关闭连接。然后问咱们是否现在就开启连接?咱们选择 Yes

┌────────────────┤ ESTABLISH A CONNECTION ├────────────────┐
│ Now, you can make a DSL connection with "pon             │
│ dsl-provider" and terminate it with "poff". Would you    │
│ like to start the connection now?                        │
│               <Yes>                  <No>                │
└──────────────────────────────────────────────────────────┘

选择 Ok,结束配置。

┌─────────────────┤ CONNECTION INITIATED ├─────────────────┐
│ The DSL connection has been triggered. You can use the   │
│ "plog" command to see the status or "ip addr show ppp0"  │
│ for general interface info.                              │
│                          <Ok>                            │
└──────────────────────────────────────────────────────────┘

现在可以查看一下所有接口的 IP 地址。

ip a

咱们可以看到多了一个名为 ppp0 的接口,并且成功获取了外网的 IP 地址。

4: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc pfifo_fast state UNKNOWN group default qlen 3
    link/ppp
    inet ███.███.███.███ peer ███.███.███.1/32 scope global ppp0
       valid_lft forever preferred_lft forever
    inet6 240█:████:████:████:████:████:████:████/64 scope global temporary dynamic
       valid_lft 259127sec preferred_lft 85894sec
    inet6 240█:████:████:████:████:████:████:████/64 scope global dynamic mngtmpaddr
       valid_lft 259127sec preferred_lft 172727sec
    inet6 fe80::████:████:████:████ peer fe80::████:████:████:████/128 scope link
       valid_lft forever preferred_lft forever

咱们在 R4S 上 ping 一下外网的 IP,已经可以 ping 通。

nanopi-r4s:~:% ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=19.9 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=19.8 ms

但是 ping 域名就不行了。查看一下 /etc/resolv.conf

cat /etc/resolv.conf

原来这里的 DNS 还是使用以前的路由器宣告的 DNS。

# Generated by NetworkManager
nameserver 192.168.█.1
nameserver fe80::████:████:████:████%enp1s0

编辑 /etc/resolv.conf

sudo vim /etc/resolv.conf

将文件内容改为

nameserver ::1

保存后,ping 域名也能 ping 通了,这是因为路由器自身的 DNS 请求已经交给自身的 Dnsmasq 处理了。所以为了路由器自身能正常上网,Dnsmasq 要一直运行着。

但是现在电脑还是不能 ping 通外网的 IPv4 地址 ,这是因为咱们没有做 IPv4 的 NAT 转换。

开启 NAT 转换

咱们使用 nftables 来开启 NAT 转换。

编辑 /etc/nftables.conf 文件。

sudo vim /etc/nftables.conf

里面已经写好了一些规则。

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0;
    }
    chain forward {
        type filter hook forward priority 0;
    }
    chain output {
        type filter hook output priority 0;
    }
}

咱们把规则修改成这个样子。

#!/usr/sbin/nft -f

table inet filter
delete table inet filter

table inet filter {
    chain input {
        type filter hook input priority 0;
        iifname "ppp0" tcp dport { 80, 443 } drop
        iifname "ppp0" udp dport { 53 } drop
    }
    chain forward {
        type filter hook forward priority 0;
    }
    chain output {
        type filter hook output priority 0;
    }
}

table ip ipv4-nat
delete table ip ipv4-nat

table ip ipv4-nat {
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        oifname { eth1, ppp0 } masquerade
    }
}

咱们在 filter 表里的 input 链创建了一条规则 iifname "ppp0" tcp dport { 80, 443 } drop。这条规则的意思是从 ppp0 接口进来的访问 TCP 端口 80 和 443 的数据包全部禁止。设置这条规则的原因是在中国,家宽是不能私自做 WEB 服务的。咱们提前禁止这两个端口从外部的访问。之后就算在路由器上开了 WEB 服务。因为从外部访问不了,就不会有喝茶的风险了。

iifname "ppp0" udp dport { 53 } drop 这条规则的意思是禁止从 ppp0 接口进来的对 UDP 端口 53 的访问。因为咱们的 Dnsmasq 只是用来对局域网提供 DNS 服务,没有必要对外网提供 DNS 服务,所以顺便禁止了。

这里咱们创建了一个表 ipv4-nat。表名前面的 ip 意思是这个表只对 IPv4 有效。然后在表里新建了链 postroutingtype nat 的意思是这条链的类型是 nathook postrouting 的意思是这条链会被挂到 postrouting 钩子上;priority srcnat 的意思是这条链的优先级是 srcnatpolicy accept 的意思是这条链的默认规则是“接受”。小玲这么说你可能不太理解,如果你理解 iptables,那么现在的 ipv4-nat 表中的 postrouting 链的功能就和 iptables 中的 nat 表的 POSTROUTING 链的功能差不多。

oifname { eth1, ppp0 } masquerade 的意思是从 eth1ppp0 出去的数据包做 NAT 转换。

table inet filterdelete table inet filter 这两句的作用是在使用 sudo systemctl reload nftables 命令重载 nftables 规则时先把已有的表删除再添加,防止规则重复添加。

启动 nftables 服务,这样咱们写的规则就会被加载了,顺便将 nftables 设为自启。

sudo systemctl enable nftables
sudo systemctl start nftables

给内网分配 IPv6 地址

这时候虽然路由器有公网 IPv6 地址了,可是局域网的设备并没有公网 IPv6 地址。现在咱们要安装 wide-dhcpv6-client 来获取 PD 前缀,这样局域网的设备就能被分配到公网 IPv6 地址了。

sudo apt install -y wide-dhcpv6-client

这里输入与外网连接的接口名称。

Package configuration
┌─────────────────────────────┤ Configuring wide-dhcpv6-client ├─────────────────────────────┐
│ Network interfaces on which the DHCPv6 client sends requests should be specified here.     │
│ Multiple interfaces are separated with spaces. An empty line temporarily disables dhcp6c.  │
│                                                                                            │
│ Interfaces on which the DHCPv6 client sends requests:                                      │
│                                                                                            │
│ ppp0______________________________________________________________________________________ │
│                                                                                            │
│                                           <Ok>                                             │
│                                                                                            │
└────────────────────────────────────────────────────────────────────────────────────────────┘

安装完 wide-dhcpv6-client 后,还需要修改配置文件。

sudo vim /etc/wide-dhcpv6/dhcp6c.conf

默认的配置文件是这个样子的。

# Default dhpc6c configuration: it assumes the address is autoconfigured using
# router advertisements.

profile default
{
  information-only;

  request domain-name-servers;
  request domain-name;

  script "/etc/wide-dhcpv6/dhcp6c-script";
};

咱们修改成这个样子。

interface ppp0 {
    send ia-pd 0;
};
id-assoc pd 0 {
    prefix-interface enp1s0 {
        sla-len 0;
        ifid 0;
    };
};

interface ppp0 这里的 ppp0 是连接外网的接口名称。

send ia-pd 0 的意思是发送获取 PD 的请求,并把这个 PD 的 ID 设为 0

id-assoc pd 0 的意思是对 ID 为 0 的 PD 进行处理。

prefix-interface enp1s0 的意思是将 PD 前缀绑定到 enp1s0 接口上。这里的接口名称请替换成你的 LAN 口的接口名称。

sla-len 这个值要根据你能获取到的 PD 前缀长度来决定。公式是 64 - 你能获取到的 PD 长度1。小玲只能获取到 /64 的前缀。所以小玲的 sla-len 的值为 64-64=0

ifid 这个值可以用来固定 LAN 口接口的主机号,把 ifid 设为 0 并且 sla-len0 的话,那么 LAN 口的公网 IPv6 地址将会是 240█:████:████:████::。如果不希望这个地址固定,还可以用 if-id-random 来替换这行。

修改好之后,咱们将 wide-dhcpv6-client 设为自启并重启一下。

sudo systemctl enable wide-dhcpv6-client
sudo systemctl restart wide-dhcpv6-client

不出意外的话,现在 LAN 口应该能获取到公网 IPv6 地址了。因为咱们前面已经将 Dnsmasq 设置好了,所以局域网的设备应该也能被分配公网 IPv6 地址。

2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether ██:██:██:██:██:██ brd ff:ff:ff:ff:ff:ff
    inet 192.168.3.1/24 brd 192.168.3.255 scope global enp1s0
       valid_lft forever preferred_lft forever
    inet6 240█:████:████:████::/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fddd:afcf::/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::████:████:████:████/64 scope link
       valid_lft forever preferred_lft forever

你可以试试在内网 ping 外网的 IPv6 地址,在外网 ping 内网设备的公网 IPv6 地址。只要没被设备上的防火墙挡住,应该都是可以 ping 通的。

UPnP

咱们最好启用 UPnP 功能,这样电脑上如果有 BT 下载软件,通过 UPnP 映射了端口之后。与别人连接会更容易一点。咱们使用 miniupnpd 来提供 UPnP 服务。

sudo apt install -y miniupnpd

这里选 Yes,将 miniupnpd 设为自启。

Package configuration
┌───────────────────────────────┤ Configuring miniupnpd ├────────────────────────────────┐
│                                                                                        │
│ Choose this option if the MiniUPnP daemon should start automatically, now and at boot  │
│ time.                                                                                  │
│                                                                                        │
│ Start the MiniUPnP daemon automatically?                                               │
│                                                                                        │
│                         <Yes>                            <No>                          │
│                                                                                        │
└────────────────────────────────────────────────────────────────────────────────────────┘

这里输入连接外网的接口名称。

Package configuration
┌─────────────────────────────────┤ Configuring miniupnpd ├─────────────────────────────────┐
│ The MiniUPnP daemon will listen on a specific IP address on the local network, then open  │
│ ports on the WAN interface. Please enter the name of the WAN network interface on which   │
│ the MiniUPnP daemon should perform port forwarding.                                       │
│                                                                                           │
│ External WAN network interface to open ports on:                                          │
│                                                                                           │
│ ppp0_____________________________________________________________________________________ │
│                                                                                           │
│                                          <Ok>                                             │
│                                                                                           │
└───────────────────────────────────────────────────────────────────────────────────────────┘

这里输入 LAN 口接口的名称。

Package configuration
┌────────────────────────────────┤ Configuring miniupnpd ├─────────────────────────────────┐
│ The MiniUPnP daemon will listen for requests on the local network. Please enter the      │
│ interfaces or IP addresses it should listen on, separated by space.                      │
│                                                                                          │
│ Interface names are preferred, and required if you plan to enable IPv6 port forwarding.  │
│                                                                                          │
│ Interfaces to listen on for UPnP queries:                                                │
│                                                                                          │
│ enp1s0__________________________________________________________________________________ │
│                                                                                          │
│                                          <Ok>                                            │
│                                                                                          │
└──────────────────────────────────────────────────────────────────────────────────────────┘

安装完 miniupnpd 后,咱们还要设置哪些端口允许被映射。编辑 /etc/miniupnpd/miniupnpd.conf 文件。

sudo vim /etc/miniupnpd/miniupnpd.conf

确保文件有这些配置。

# 这三行配置的作用是检测路由器是否有公网 IP 或者在不受限制的 NAT 类型下面。
# 如果检测不通过 UPnP 就不会起作用。 
ext_perform_stun=yes
ext_stun_host=stun.stunprotocol.org
ext_stun_port=3478

# WAN 口的接口名称
ext_ifname=ppp0

# 是否启用 UPnP
enable_upnp=yes

# 是否启用 NAT-PMP
enable_natpmp=yes

# LAN 口的接口名称
listening_ip=enp1s0

# 这两行的配置的意思是只允许将路由器 WAN 口的 1024-65535 的端口映射到内网任意地址的 1024-65535 端口
allow 1024-65535 0.0.0.0/0 1024-65535
deny 0-65535 0.0.0.0/0 0-65535

allow 的意思是允许哪些端口被映射,你也可以把 allow 改为 deny 来禁止哪些端口被映射。格式都是一样的。

第 1 个 1024-65535 是路由器本身也就是外网能访问的端口范围。

第 2 个 1024-65535 是内网的端口范围。

0.0.0.0/0 是内网的 IPv4 网段。

修改完成后,重启 miniupnpd。

sudo systemctl restart miniupnpd

结尾

好了,你现在拥有了一个能正常上网的软路由啦。不过软路由的强大之处可不止这么点,小玲以后还会带来软路由的更多玩法。

文章目录