網絡分享

出自 Arch Linux 中文维基

這篇文章解釋了如何從一台機器向其他機器分享網絡連接。

依賴[編輯 | 編輯原始碼]

作為伺服器的機器應該有一個額外的網絡設備。這個網絡設備需要一個數據鏈路層來連接到將要獲得網絡訪問的機器:

  • 如果想給若干台機器分享網絡連接,交換機可以提供數據連接。
  • 一個無線設備同樣可以給若干台機器分享網絡訪問,參見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

另請參見[編輯 | 編輯原始碼]