Router (简体中文)

From ArchWiki
翻译状态:本文是 Router翻译。上次翻译日期:2020-04-26。如果英文版本有所更改,则您可以帮助同步翻译。

此文章是将一台电脑配置为一台网关/路由器的指南。为加强安全性,不应在此机器上运行对外服务。对于局域网(LAN),只运行特定的网关服务而不运行httpd、ftpd、samba、nfsd等属于局域网服务器的服务,因为这样会带来风险。

此文章不涉及如何设置两台PC用交叉网线进行网络连接共享。简单网络连接共享,参见Internet sharing

注意: 在本文中,intern0extern0是网络接口的名称。进一步说明参见#网络接口名称约定.

硬件需求

  • 至少 1GB 硬盘空间。基本安装约需 500MB 硬盘空间,如果使用web代理缓存还需额外预留缓存空间。
  • 至少两个实体网络接口:网关要将两个网络彼此连通(实际上路由器可以用一个物理网络接口实现两个VLAN接口并连接到VLAN交换机,这称为单臂路由/router-on-a-stick,但本文不讨论这种情况)。需要将两个网络连接到同一台实体机器,其中一个网口连接到外部网络,另一个连接内部网络。其中一个接口必须连接到外部网络,其他接口连接到内部网络。
  • 一个集线器、交换机或UTP线缆:将其他机器连接到网关。

网络接口配置

网络接口名称约定

Systemd 会自动为网口选择唯一接口名称。命名是持续不变的,直到重启。你可能希望更改接口名称,以便标记不同的网络接口。在以下的说明中,我们约定使用以下名称:

  • intern0:连接到局域网(LAN)的网络接口。真实名称可能是 enp2s0、enp1s1 等等。
  • extern0:连接到外部网络或广域网的网络接口。真实名字可能是 enp2s0、enp1s1 等等。

你可以通过Systemd-networkd#Renaming an interface中说明的方法使用Systemd-networkd的配置文件,或通过Network configuration#Change interface name中说明的方法使用udev规则重新分配设备名称。由于本文是示例性质,使用以上约定名称。

IP 配置

首先需要配置网络接口。配置网络接口最好的方式是编辑 netctl 配置文件。下面需要创建两个配置文件。

注意: 如果仅通过PPPoE连接到互联网(只有一个广域网接口),则不要设置或启用外网口配置文件(extern0-profile)。参见#PPPoE配置
  • /etc/netctl/extern0-profile
Description='Public Interface.'
Interface=extern0
Connection=ethernet
IP='dhcp'
  • /etc/netctl/intern0-profile
Description='Private Interface'
Interface=intern0
Connection=ethernet
IP='static'
Address=('10.0.0.1/24')
注意: 上面示例中假定路由器面向整个子网。如果只要面向少数几台机器,可以修改 CIDR 后缀缩减范围。例如 /27 是限定范围在 10.0.0.110.0.0.30。有很多在线CIDR计算器可用,例如sipcalc

下一步是用 netctl 启用网络接口配置。

# netctl enable extern0-profile
# netctl enable intern0-profile

ADSL连接/PPPoE

可以用 rp-pppoe 将防火墙的 extern0 接口连接到ADSL modem并管理该连接。确认已将modem设置为桥接(或半桥接或RFC1483)模式,否则modem工作于路由器模式。安装 rp-pppoe 包。

需要注意的是:如果仅能通过PPPoE连接到互联网(除了能连接modem之外没有其它广域网接口),则不必启用 extern0-profile ,因为此时外网口使用名为 ppp0 的伪接口。

PPPoE配置

可以使用 netctl 设置 pppoe 连接。首先,

# cp /etc/netctl/examples/pppoe /etc/netctl/

然后编辑它。选择连接到modem的接口并配置。如果你仅仅通过PPPoE连接到互联网,这就是 extern0 接口。其他字段填入ISP的信息。详情参阅 netctl.profile(5) 手册。

DNS 和 DHCP

可以使用专为小型站点设计的 dnsmasq 为局域网提供DNS和DHCP服务。安装 dnsmasq 包即可。

Dnsmasq 要配置为DHCP服务器。编辑 /etc/dnsmasq.conf

/etc/dnsmasq.conf
interface=intern0 # 使dnsmasq只侦听来自内网口(intern0,即局域网)的请求
expand-hosts      # 为 /etc/hosts 中的主机名添加一个域名
domain=foo.bar    # 允许DHCP主机的完全限定域名(需要启用“expand-hosts”)
dhcp-range=10.0.0.2,10.0.0.255,255.255.255.0,1h # 定义局域网中DHCP地址范围:从 10.0.0.2 至10.0.0.255,子网掩码为 255.255.255.0,DHCP 租期为 1 小时 (可按需修改)

下面将看到,只能添加静态DHCP租约。例如,分配一个IP地址给局域网中某一台指定MAC地址的机器。这样,无论这台机器何时请求DHCP,都获得同一个IP地址。对于需要DNS记录的网络服务来说这非常有用。这也可以拒绝特定MAC的机器获取IP地址。

现在 启动 dnsmasq.service 服务。

连接共享

现在可以连通两个网络接口。

Manual

首先,需要允许数据包从一个网络接口跳转到另一个网络接口。这样需要通过内核中的 sysctl(8) 功能启用包转发功能。详情参阅 Internet sharing#Enable packet forwarding

假设 net.**forwarding 设置正确(即设置为 1),数据包仍需要正确地发送和接收。因此,必须在外部网路和内部子网之间转换IP地址。这种技术称为“伪装”(masquerading)。还需要两个转发规则保持连接,并使LAN能够转发到WAN。为此,我们可以使用iptables

/etc/iptables/iptables.rules
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o extern0 -j MASQUERADE
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i intern0 -o extern0 -j ACCEPT
COMMIT

如果通过PPPoE连接,还需要将 mss 钳制到 pmtu,防止产生碎片:

/etc/iptables/iptables.rules

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A FORWARD -o ppp0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT

Startenable iptables.service。路由器现在应该完全正常运行,并路由数据。但是,要面向公共Internet使用,还需要通过Simple stateful firewall进行额外的保护。

用shorewall共享连接

详细配置说明参见Shorewall

IPv6说明

Merge-arrows-2.pngThis article or section is a candidate for merging with IPv6.Merge-arrows-2.png

Notes: 合并到文章中,主体不特定用于路由器配置。措辞可能需要更改。 (Discuss in Talk:Router (简体中文))

很有用的参考: IPv6wikipedia:IPv6

唯一本地地址

即使ISP没有提供IPv6地址,仍然可以将路由器设置为IPv6模式。除非禁用IPv6,否则所有接口都会分配唯一的 fe80::/10 地址。

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: 添加脱机方式生成ULA。 (Discuss in Talk:Router (简体中文))

对于内部网络,已保留地址块 fc00::/7。这些地址保证是唯一的,且不可从开放的互联网路由。属于 fc00::/7 的地址称为 Unique Local Addresses。要在内部网络生成和使用 generate a ULA /64 block,如希望使用 fd00:aaaa:bbbb:cccc::/64,我们首先要在内部接口上分配静态IPv6地址。修改上面的 intern0-profile,添加以下一行:

 Address6=('fd00:aaaa:bbbb:cccc::1/64')

这样将ULA添加到内部网络接口。就路由器而言,这是唯一需要配置的地方。

全局单播地址

如果ISP或WAN网络可以访问IPv6 Internet,则可以将全局链路地址分配给路由器,并通过 SLAAC传播到内部网络。全局单播前缀通常是静态或通过前缀委派提供的。

静态IPv6前缀

如果ISP提供静态前缀,则编辑 /etc/netctl/extern0-profile配置文件,简单添加IPv6地址和前缀即可:

 Address6=('2002:1:2:3:4:5:6:7/64')

可以在使用上述ULA地址之外,同时使用此功能。

通过DHCPv6-PD获取IPv6前缀

如果ISP通过前缀委派处理IPv6,则可以按照main IPv6 article中的说明进行操作。按照本说明的约定,WAN接口为 extern0(或如果通过PPPoE连接时是 ppp0),LAN接口为 intern0

路由通告与无状态自动配置(SLAAC)

要向网络客户端正确分发IPv6,需要使用通告守护进程。按照 main IPv6 article 中关于如何设置 radvd的说明进行操作。按照本说明的约定,LAN接口是 intern0。可以通告所有前缀,或选择哪些前缀分配给本地网络。

可选附加功能

UPnP

上述 shorewall 的配置不包含 UPnP 支持。尽管可能使路由器遭到来自局域网内部的攻击,然而某些应用要求必须使用UPnP。

要在路由器上启用UPnP,需要安装一个UPnPInternet Gateway Device (IGD) protocol。可从官方仓库安装 miniupnpd

更详细信息请查阅 Shorewall guide on UPnP

远程管理

OpenSSH 可用于远程管理路由器,十分适合运行在“无头”模式(无显示器或输入设备)的机器。

缓存网页代理

参阅 Squid 如何配置代理为网页浏览加速和/或添加额外的安全层。

时间服务器

将路由器用作一台时间服务器,参阅System time#Time synchronization,配置网络时间协议(NTP)服务器。

然后配置 shorewall 或者 iptables 允许 NTP 流量流出。

内容过滤

如果需要内容过滤,可以安装配置 DansGuardian 或者 Privoxy

流量共享

流量共享很有用,尤其当局域网中不止一台机器时。基本思路是为不同类型的流量分配优先级。交互型流量(ssh、在线游戏等)可能需要高优先级,而 P2P 流量可分配低优先级。其他流量介于二者之间。

参阅