Router (简体中文) - ArchWiki

Jump to content
翻译状态：本文是 Router 的翻译。上次翻译日期：2020-04-26。如果英文版本有所更改，则您可以帮助同步翻译。

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

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

注意： 在本文中，intern0和extern0是网络接口的名称。进一步说明参见#网络接口名称约定.

## 硬件需求

- 至少 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.1` 至 `10.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

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

### 用shorewall共享连接

详细配置说明参见Shorewall。

## IPv6说明

很有用的参考： IPv6 和 wikipedia:IPv6。

### 唯一本地地址

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

This article or section needs expansion.

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 流量可分配低优先级。其他流量介于二者之间。

## 参阅

- Simple stateful firewall (简体中文)
- Internet sharing (简体中文)

Categories:

- Network sharing (简体中文)
- Security (简体中文)
- Firewalls (简体中文)

Hidden category:

- Pages or sections flagged with Template:Expansion