网络分享

来自 Arch Linux 中文维基
(重定向自Internet sharing

这篇文章解释了如何从一台机器向其他机器分享网络连接。

依赖[编辑 | 编辑源代码]

作为服务器的机器应该有一个额外的网络设备。这个网络设备需要一个数据链路层来连接到将要获得网络访问的机器:

  • 如果想给若干台机器分享网络连接,交换机可以提供数据连接。
  • 一个无线设备同样可以给若干台机器分享网络访问,参见Software access point
  • 如果只需分享网络给一台机器,一根交叉网线就可以了。 如果两台电脑的网卡支持MDI-X,交叉网线也不是必须的,一根普通直连网线也可以。 运行 ethtool interface | grep MDI 确认网卡是否支持MDI-X。

配置[编辑 | 编辑源代码]

这个章节假定,连接到客户机的网络设备被命名为 net0而连接到互联网的网络设备被命名为internet0

提示:为了此事,你可以使用Udev#Setting static device names所述的方法重命名你的设备。

所有的配置都是在服务器计算机上完成的,除了最后一步#给客户机分配IP地址.

静态IP地址[编辑 | 编辑源代码]

在服务器计算机上,给要连接到其他机器的网卡分配一个静态的IP地址。IP地址的前3个字节不能和其他网卡的一模一样,除非两个网卡都有一个严格大于/24的子网掩码。

# ip link set up dev net0
# ip addr add 192.168.123.100/24 dev net0 # arbitrary address

为了使你的静态IP在启动时被分配,你可以使用network manager

启用包转发[编辑 | 编辑源代码]

警告: 如果没有正确配置防火墙则会有安全隐患。

检查当前的包转发设置:

# sysctl -a | grep forward

这将显示全局和端口默认转发设置以及每个接口分别的 IPv4 和 IPv6 转发设置。内核文档(英文)中有各个选项的详细描述。

要启用 IPv4 和 IPv6 包转发,配置 sysctl 并设置这些选项:

net.ipv4.ip_forward = 1
net.ipv4.conf.all.forwarding = 1
net.ipv6.conf.all.forwarding = 1
提示:要只为某个接口启用包转发,设置 net.ipv[46].conf.interface_name.forwarding=1
警告: 如果系统使用了systemd-networkd来控制网卡,就不能为单个网卡配置 IPv4 的设置,换言之,systemd 的操作规则会将所有配置过的转发发送到一个全局(针对所有网卡)的 IPv4 的设置。建议的变通方法是使用防火墙在选中的网卡上禁止转发。参考 systemd.network(5) 手册页以获取更多信息。在之前的 systemd 220/221 版本中引入的执行内核设置的 IPForward=kernel 已不再适用。[1] [2]

要是更改在重启后仍生效,见 Sysctl#配置。可以考虑将设置写到 /etc/sysctl.d/30-ipforward.conf 这种有描述性文件名的文件中。

建议在重启之后再次检查,确认转发已经按要求启用。

启用 NAT[编辑 | 编辑源代码]

使用 iptables[编辑 | 编辑源代码]

安装iptables包。使用iptables来启用NAT:

# iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE
# iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# iptables -A FORWARD -i net0 -o internet0 -j ACCEPT
注意: 当然了,这对移动宽带连接(一般在电脑上叫做ppp0)也有用。

阅读iptables的文章以获取更多信息(特别是关于保存规则并在重启之后应用的东西)。 还有一篇关于iptables的很好的文章:Simple stateful firewall

使用 nftables[编辑 | 编辑源代码]

安装 nftables包。要通过nftables启用NAT,你必须在一个新的或者现有的表中创建prerouting和postrouting链(即使它们是空的你也还是需要这两个链):

# nft add table ip nat
# nft add chain ip nat prerouting { type nat hook prerouting priority 0 \; }
# nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
注意: 如果想要使用IPv6,你需要将所有的ip替换为ip6

然后,你还要将net0的地址转换为internet0的地址(这里就是网络地址转换NAT了):

# nft add rule nat postrouting oifname internet0 masquerade

你可能还向在forwarding链上添加更多的防火墙显示(加入filter表已经存在,就像Nftables#Server中配置的那样):

# nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop}
# nft add rule filter forward ct state related,established accept
# nft add rule filter forward iifname net0 oifname internet0 accept


你可以在nftables Wiki找到更多的关于nftables中的NAT的信息。如果你想要持久化这些更改,照着nftables说的做。

给客户机分配IP地址[编辑 | 编辑源代码]

如果你计划经常要有几台机器使用这台电脑共享的网络,那么建议你安装一个DHCP服务器,比如dhcpd 或者 dnsmasq。然后在每一台连这个网的电脑上配置DHCP客户端(比如说dhcpcd)。

本文或本章节的语言、语法或风格需要改进。参考:Help:Style

原因:这不是 iptables 指南。使用 iptables -I 扩展链可能会跳过其他重要规则 ; 如果需要为此编写一个开关脚本,请使用自定义链,并在 INPUT 链中小心地放置一个跳转。(在Talk:网络分享讨论)

必须把67端口的UDP传入连接开给DHCP服务器。为了允许DNS请求,还要打开53端口的UDP/TCP传入连接。

# iptables -I INPUT -p udp --dport 67 -i net0 -j ACCEPT
# iptables -I INPUT -p udp --dport 53 -s 192.168.123.0/24 -j ACCEPT
# iptables -I INPUT -p tcp --dport 53 -s 192.168.123.0/24 -j ACCEPT

如果你不打算经常使用这套配置,你也可以手动给每台电脑配置IP。

手动添加IP地址[编辑 | 编辑源代码]

本文或本章节的语言、语法或风格需要改进。参考:Help:Style

原因:Duplicates 网络配置#Static IP address.(在Talk:网络分享讨论)

除了使用DHCP,你还可以在每台客户端电脑上添加IP地址和默认网关:

# ip addr add 192.168.123.201/24 dev eth0  # 地址随便填,但是网段和子网掩码必须和服务端在这个子网的配置一样
# ip link set up dev eth0
# ip route add default via 192.168.123.100 dev eth0   # 服务端的地址

为每一个客户端电脑配置DNS服务器, 细节位于resolv.conf

搞定。客户端电脑现在应该有网了。

问题解决[编辑 | 编辑源代码]

如果你可以连接两台电脑但没法传输数据(比如说,客户端发送了DHCP请求给服务器,服务器受到了并且给了一个IP,但是客户端没收到,最后超时了),检查以确保你没有其他Iptables规则在干扰

客户端无法连接Wi-Fi或者无法上网

问题还包括:很久都拿不到ip,DHCP offer穿不过虚拟网桥,设备ping电脑的时候得到"host is down", ping外部网络的时候得到"no route to host"……

目前已知docker可能导致这个问题。禁用docker.service和docker.socket就可以解决了。

在github上的issue

另请参见[编辑 | 编辑源代码]