路由器
本文是一个将计算机变成互联网网关/路由器的教程。为了加强其安全性,它不应运行任何面向外部世界的服务。对于局域网,仅运行网关特定的服务;尤其不要运行 httpd、ftpd、samba、nfsd 等,因为这些服务应在局域网中的服务器上运行,因为它们会引入安全风险。
本文不尝试展示如何使用交叉电缆在两台机器之间设置共享连接。对于简单的互联网共享解决方案,请参阅互联网共享。
硬件需求
- 有关所需最小磁盘空间的建议,请参阅分区#分区方案。
- 至少两个物理网络接口:网关将两个网络相互连接(实际上,可以使用单个物理接口来制作路由器,该接口下层是两个 VLAN 接口,并连接到支持 VLAN 的交换机,即所谓的单臂路由配置,但本文未涵盖)。您需要能够将这些网络连接到同一台物理计算机。一个接口必须连接到外部网络,而另一个接口连接到内部网络。
- 集线器、交换机或 UTP 电缆:您需要一种将其他计算机连接到网关的方法
网络接口配置
持久接口命名
systemd 会自动为您的所有接口选择唯一的接口名称。这些名称是持久的,并且在您重新启动时不会更改。但是,您可能想要重命名您的接口,例如,为了突出显示它们连接的不同网络。在本指南的以下部分中,将使用以下约定
- intern0:连接到局域网的网卡。在实际计算机上,它可能具有名称 enp2s0、enp1s1 等。
- extern0:连接到外部网络(或 WAN)的网卡。它可能具有名称 enp2s0、enp1s1 等。
您可以通过遵循网络配置#更改接口名称来更改设备的分配名称。由于本文示例丰富,您可能希望选择上述名称。
IP 配置
使用 netctl
现在您需要配置网络接口。一种方法是使用 netctl 配置文件。您将需要创建两个配置文件。
/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')
/27
将为您提供 10.0.0.1
到 10.0.0.30
。有许多 CIDR 计算器,在线和离线,例如 sipcalc。SkipNoCarrier=yes
以确保即使 LAN 上的客户端尚未启动,连接也已启用。接下来,我们使用 netctl 设置接口
# netctl enable extern0-profile # netctl enable intern0-profile
使用 systemd-networkd
配置网络接口的一种直接而简单的方法是通过 systemd-networkd。
- 为
extern0
接口应用 DHCP 客户端配置。 - 为
intern0
接口应用 静态 IP 配置。
有关配置详细信息和可用选项的概述,请参阅 systemd-networkd#配置文件。运行 networkctl reload
以应用配置更改。
ADSL 连接/PPPoE
使用 rp-pppoe,我们可以将 ADSL 调制解调器连接到防火墙的 extern0
接口,并让 Arch 管理连接。请务必将调制解调器置于桥接模式(半桥接或 RFC1483),否则,调制解调器也将充当路由器。安装 rp-pppoe 软件包。
应该注意的是,如果您仅使用 PPPoE 连接到互联网(即,除了连接到调制解调器的端口外,您没有其他 WAN 端口),则无需设置 extern0-profile
,因为外部伪接口将是 ppp0。
PPPoE 配置
您可以使用 netctl 设置 PPPoE 连接。要开始,请执行
# cp /etc/netctl/examples/pppoe /etc/netctl/
并开始编辑。对于接口配置,选择连接到调制解调器的接口。如果您仅通过 PPPoE 连接到互联网,则这可能是 extern0
。使用您的 ISP 信息填写其余字段。有关字段的更多信息,请参阅 netctl.profile(5) 手册页中的 PPPoE 部分。
DNS 和 DHCP
下表列出了可用的 DHCP 服务器及其功能
服务器 | DHCPv4 | DHCPv6 | IPv6 路由器通告 | GUI | 接口 | 存储后端 | 注意 |
---|---|---|---|---|---|---|---|
dhcpd | 是 | 是 | 否 | Glass-ISC-DHCP | ? | 文件 | 已被 Kea 取代。 |
dnsmasq | 是 | 是 | 是 | 否 | ? | 文件 | 也是 DNS、PXE 和 TFTP。 |
kea | 是 | 是 | 否 | Stork | REST、RADIUS、NETCONF | 文件、MySQL、PostgreSQL、Cassandra | 也是 DNS。取代 dhcpd。 |
pi-hole-ftlAUR | 是 | 是 | 是 | Pi-hole#Web 界面 | ? | SQLite | Pi-hole 项目的组件。dnsmasq 的分支。 |
systemd-networkd | 是 | 否 | 是 | 否 | ? | 文件 | 随 systemd 安装。 |
可用 DNS 服务器的比较可以在域名解析#DNS 服务器中找到。
dnsmasq
要将 dnsmasq 用作局域网的 DNS 服务器,以及可选的 DHCP 服务器,请安装 dnsmasq 软件包。
默认配置已启用其 DNS 服务器,有关选项,请参阅 Dnsmasq#配置。
对于此路由器示例,可以将 dnsmasq 配置为 DHCP 服务器,配置类似于以下内容
/etc/dnsmasq.conf
interface=intern0 # make dnsmasq listen for requests only on intern0 (our LAN) #no-dhcp-interface=intern0 # optionally disable the DHCP functionality of dnsmasq and use systemd-networkd instead expand-hosts # add a domain to simple hostnames in /etc/hosts domain=foo.bar # allow fully qualified domain names for DHCP hosts (needed when # "expand-hosts" is used) dhcp-range=10.0.0.2,10.0.0.255,255.255.255.0,1h # defines a DHCP-range for the LAN: # from 10.0.0.2 to .255 with a subnet mask of 255.255.255.0 and a # DHCP lease of 1 hour (change to your own preferences)
有关其他选项,请参阅 Dnsmasq#DHCP 服务器。例如,您还可以添加“静态”DHCP 租约,即为局域网上计算机的 MAC 地址分配 IP 地址。这样,每当计算机请求新租约时,它都会获得相同的 IP。这对于具有 DNS 记录的网络服务器非常有用。您还可以拒绝某些 MAC 获取 IP。
systemd-networkd
要使用 systemd-networkd 而不是 dnsmasq 作为 DHCP 服务器,请将 [DHCPServer]
部分添加到 intern0
接口的配置文件中。有关可用选项,请参阅 systemd-networkd#[DHCPServer]。
要使 systemd-resolved 回答路由器接口上的 DNS 请求,必须按照 systemd-resolved#附加侦听接口 中所述添加其地址。
连接共享
是时候将两个网络接口连接在一起了。
手动
首先,我们需要允许数据包从一个网络接口跳到另一个网络接口。为此,需要通过 sysctl(8) 在内核中启用数据包转发。有关详细信息,请参阅 互联网共享#启用数据包转发。
假设 net.**forwarding
设置正确(即为 1
),数据包仍需要正确发送和接收。因此,有必要在面向外部的网络和本地使用的子网之间转换 IP 地址。该技术称为伪装。我们还需要两条转发规则来保持连接畅通并启用 LAN 到 WAN 转发。对于此任务,我们将使用 iptables。
有关如何伪装 extern0
接口以及从 intern0
到 extern0
的数据包,请参阅互联网共享#启用 NAT 部分。之后,通过 iptables-save -f /etc/iptables/iptables.rules
持久化新添加的规则,有关详细信息,请参阅 iptables#配置和使用。
启动并启用 iptables.service
。路由器现在应该完全正常工作并路由您的流量。由于它面向公共互联网,因此使用简单有状态防火墙对其进行额外保护是有意义的。
使用 systemd-networkd
修改或创建先前讨论的 intern0
网络配置,以在 [Network]
部分中包含 IPMasquerade=ipv4
选项。此配置将隐式启用所有接口上的数据包转发,请参阅 systemd.network(5)。有关示例配置,请参阅 systemd-networkd#[DHCPServer]。
使用 shorewall 进行连接共享
有关详细的配置指南,请参阅 Shorewall。
IPv6 技巧
有用的阅读材料:IPv6 和 wikipedia:IPv6。
唯一本地地址
即使您没有从 ISP 获得 IPv6 地址,也可以在 IPv6 模式下使用路由器。除非您禁用 IPv6,否则所有接口都应已分配唯一的 fe80::/10
地址。
对于内部网络,已保留 fc00::/7
块。保证这些地址是唯一的且无法从开放互联网路由。属于 fc00::/7
块的地址称为 唯一本地地址。要开始,生成一个 ULA /64 块以在您的网络中使用。对于此示例,我们将使用 fd00:aaaa:bbbb:cccc::/64
。首先,我们必须在内部接口上分配静态 IPv6。修改我们上面创建的 intern0-profile
以包含以下行
Address6=('fd00:aaaa:bbbb:cccc::1/64')
这会将 ULA 添加到内部接口。就路由器而言,这就是您需要配置的全部内容。
全球单播地址
如果您的 ISP 或 WAN 网络可以访问 IPv6 互联网,您可以另外为路由器分配全局链路地址,并通过 SLAAC 将其传播到您的内部网络。全局单播前缀通常是静态的,或者通过前缀委派提供。
静态 IPv6 前缀
如果您的 ISP 为您提供了静态前缀,则编辑 /etc/netctl/extern0-profile
并简单地添加您已获得的 IPv6 和 IPv6 前缀(通常为 /64)
Address6=('2002:1:2:3:4:5:6:7/64')
除了上面描述的 ULA 地址之外,您还可以使用它。
通过 DHCPv6-PD 获取 IPv6 前缀
如果您的 ISP 通过前缀委派处理 IPv6,那么您可以按照 IPv6#前缀委派 (DHCPv6-PD) 中的说明正确配置路由器。按照本文的约定,WAN 接口是 extern0
(如果您通过 PPPoE 连接,则为 ppp0
),LAN 接口是 intern0
。
路由器通告和无状态自动配置 (SLAAC)
为了正确地将 IPv6 分发给网络客户端,我们将需要使用广告守护程序。按照主 IPv6 文章中的详细信息,了解如何设置 radvd
。根据本指南的约定,面向局域网的接口是 intern0
。您可以通告所有前缀,也可以选择将哪些前缀分配给本地网络。
可选附加功能
UPnP
上述 shorewall 配置不包含 UPnP 支持。不鼓励使用 UPnP,因为它可能会使网关容易受到来自局域网内部的攻击。但是,某些应用程序需要此功能才能正常运行。
要在路由器上启用 UPnP,您需要安装 UPnP 互联网网关设备 (IGD) 协议守护程序。要获取它,请安装 miniupnpd 软件包。
阅读 Shorewall 关于 UPnP 的指南以获取更多信息。
远程管理
OpenSSH 可用于远程管理您的路由器。这对于以无头模式(无显示器或输入设备)运行它很有用。
缓存 Web 代理
有关设置 Web 代理以加速浏览和/或添加额外安全层的步骤,请参阅 Squid。
时间服务器
要将路由器用作时间服务器,请参阅 系统时间#时间同步,了解可用的网络时间协议 (NTP) 服务器实现。
然后,配置 shorewall 或 iptables 以允许 NTP 流量进出。
内容过滤
如果您需要内容过滤解决方案,请安装并配置 Privoxy。
流量整形
流量整形非常有用,尤其是在局域网上不仅您一个人时。这个想法是为不同类型的流量分配优先级。交互式流量(ssh、在线游戏)可能需要最高优先级,而 P2P 流量可以最低。然后是介于两者之间的一切。
使用 shorewall 进行流量整形
请参阅 Shorewall#流量整形。