网络分享
这篇文章解释了如何从一台机器向其他机器分享网络连接。
依赖[编辑 | 编辑源代码]
作为服务器的机器应该有一个额外的网络设备。这个网络设备需要一个数据链路层来连接到将要获得网络访问的机器:
- 如果想给若干台机器分享网络连接,交换机可以提供数据连接。
- 一个无线设备同样可以给若干台机器分享网络访问,参见Software access point。
- 如果只需分享网络给一台机器,一根交叉网线就可以了。 如果两台电脑的网卡支持MDI-X,交叉网线也不是必须的,一根普通直连网线也可以。 运行
ethtool interface | grep MDI
确认网卡是否支持MDI-X。
配置[编辑 | 编辑源代码]
这个章节假定,连接到客户机的网络设备被命名为 net0而连接到互联网的网络设备被命名为internet0。
所有的配置都是在服务器计算机上完成的,除了最后一步#给客户机分配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
。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
阅读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 \; }
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)。
必须把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地址[编辑 | 编辑源代码]
除了使用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就可以解决了。
另请参见[编辑 | 编辑源代码]
- Xyne关于设置一个有DHCP和DNS服务器的子网的指引和脚本
- NetworkManager 可以用来配置网络共享。