設置br0,無需 VPN

設置br0,無需 VPN

我試圖強制來自來賓(Windows 或 Linux)的所有流量都通過主機(Linux)的 VPN。為了確保訪客無法存取 VPN 以外的互聯網,我在主機系統上建立了連接,這會建立一個新介面tun0。 VPN 隧道在主機上運作良好。

設置br0,無需 VPN

為了在訪客中無需 VPN 即可訪問互聯網,我創建了一個橋接設備br0並連接enp7s0到它。這樣,網路就可以在訪客中運作。

ip link add name br0 type bridge
ip link set br0 up
ip link set enp7s0 master br0

在主機上,vnet5已新增裝置並橋接至br0。但同時,從主機到遠端的 ping 操作不再運作。

## On the Host
sudo ip a
# ...
# 14: vnet5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN group default qlen 1000
# link/ether ab:ab:ab:ab:ab:ab brd ff:ff:ff:ff:ff:ff
# inet6 fe80::fc54:ff:fe92:5aa9/64 scope link
# valid_lft forever preferred_lft forever
ping www.google.com
# ping: www.google.com: Temporary failure in name resolution
ping 8.8.8.8
# From 192.168.1.100 icmp_seq=1 Destination Host Unreachable

然後我啟動虛擬機器virt-manager並檢查連接。客人有網路:

## On the Guest
ip a
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
# ...
# 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
#     link/ether 52:54:00:92:5a:a9 brd ff:ff:ff:ff:ff:ff
#     inet 192.168.1.221/24 brd 192.168.1.255 scope global dynamic noprefixroute enp1s0
#        valid_lft 67432sec preferred_lft 67432sec
ping www.google.ch
# PING www.google.ch (172.217.168.35) 56(84) bytes of data.
# 64 bytes from zrh04s14-in-f3.1e100.net (172.217.168.35): icmp_seq=1 ttl=117 time=2.47 ms

我想除了設定之外,ip link set enp7s0 master br0我還可以在br0和之間建立路由規則enp7s0

使用 VPN 和tun0介面

當我建立 VPN 連線時,tun0會建立一個無法指派給網橋的介面。因此,無論如何我都需要建立路由規則。所以我猜情況和上面的情況是類似的。首先,我enp7s0再次從 中刪除br0

ip link set enp7s0 nomaster
sudo openvpn my_vpn_tcp.ovpn
# ...
# Initialization Sequence Completed
sudo ip a
# ...
# 3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
# link/ether ab:ab:ab:ab:ab:ab brd ff:ff:ff:ff:ff:ff permaddr ab:ab:ab:ab:ab:ab
# inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic noprefixroute enp7s0
# valid_lft 82702sec preferred_lft 82702sec
# ...
# 10: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
# link/none
# inet 10.7.7.5/24 scope global tun0
# valid_lft forever preferred_lft forever
# ...
# 12: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
# link/ether 72:eb:06:e5:1e:5a brd ff:ff:ff:ff:ff:ff
# inet6 fe80::70eb:6ff:fee5:1e5a/64 scope link
# valid_lft forever preferred_lft forever

無需進一步操作,主機上使用VPN連接,即可。

ping www.google.com
# PING www.google.com (172.217.168.3) 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=1 ttl=117 time=9.64 ms
# ...
ping www.google.com -I tun0
# PING www.google.com (172.217.168.3) from 10.7.7.5 tun0: 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=2 ttl=117 time=10.0 ms
# ...
ping www.google.com -I enp7s0
# PING www.google.com (172.217.168.3) from 192.168.1.100 enp7s0: 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=1 ttl=115 time=4.59 ms
# ...

但正如已經說過的,我無法添加tun0br0.因此,客人也無法上網。

sudo ip link set tun0 master br0
# RTNETLINK answers: Invalid argument

我搜尋了解決方案,但找不到有效的解決方案,或者我的情況略有不同,這需要對我沒有的網路有更多的了解。例如(這並沒有完成這項工作)或(這並不完全適合我的情況)。

答案1

同一個問題中有兩個問題,它們實際上並不相互依賴。我仍然會回答兩個。

此外,noprefixroute位址選項暗示網路配置的一部分由一些附加工具(如 NetworkManager)管理以新增路由。這個答案不會嘗試處理網路工具的整合。這包括處理 DHCP 配置,如果未正確重新配置,則該配置可能會覆蓋以後的變更。當介面關閉或刪除時,許多設定都會消失,並且必須再次完成,因此最好透過各種負責的網路工具的各種掛鉤來完成。

設置br0,無需 VPN

設定為橋接連接埠的介面將放棄參與路由

一旦設定為橋接端口,與該接口關聯的路由將被忽略。保留地址時可能仍有有害的副作用。詳細資訊可以在部落格中找到Linux 橋的正確隔離:

  1. 將框架移交給特定於設備的接收處理程序,如果有的話,
  2. 將幀移交給全域或設備特定的協議處理程序(例如 IPv4、ARP、IPv6)

對於橋接接口,內核已經配置了一個特定於設備的接收處理程序,br_handle_frame().此功能不允許在傳入介面的上下文中進行任何附加處理,STP 和 LLDP 訊框除外,或啟用「路由」時除外。所以,協議處理程序永遠不會被執行在這種情況下。

在成為網橋連接埠的介面上設定的 IP 位址應該會移動到特殊網橋的自身介面(br0:網橋本身),這是唯一能夠參與路由的介面(還有其他選項,但讓我們保持簡單)。相關路線也是如此。

假設 OP 的預設閘道是 192.168.1.1/24。讓我們針對第一種情況重寫:

ip link add name br0 up type bridge
ip link set dev enp7s0 master br0

ip address flush dev enp7s0
# previous command will also have removed all associated routes as a side effect
ip address add 192.168.1.100/24 dev br0
# previous command added the LAN route too as a side effect (no noprefixroute here)
ip route add default via 192.168.1.1

這樣主機和虛擬機器就都可以存取Internet了。

注意,對於VM部分來說,vnet5也是一個橋接端口,也不參與路由。主機只是在虛擬機器和路由器(192.168.1.1)之間交換訊框:不涉及路由。

使用 VPN 和tun0介面

OpenVPN 依賴 TUN/TAP 驅動程式(在 Linux 上由核心模組提供)tun)。司機可以提供:

  • 第 2 層 TAP 介面

    它的行為類似於乙太網路設備,可以設定為乙太網路橋接連接埠:vnet5由 VM 管理程式建立。

  • 或第 3 層 TUN 接口

    它不包含幀資訊(乙太網路 MAC 位址),也不處理幀,而僅處理第 3 層或第 3 層以上的協定:IPv4 或 IPv6。因此不能將其設定為乙太網路橋接器連接埠。這是tun0OpenVPN 在 TUN 模式下建立的 OP。

OpenVPN也可以使用TAP模式,可以橋接,但這需要重新配置遠端伺服器側面以及所有網路佈局:遠端伺服器也將是 192.168.1.0/24 LAN 的一部分。 OP似乎無法控制它。

因此,讓我們考慮一下 OP 的 TUN 介面可以做什麼:這將在第 3 層(路由)完成,而不是在第 2 層。

僅對受信任的虛擬機器重複使用先前的設置

如果主機不包含高級防火牆,包括防火牆限制和/或橋接路徑的更改,則它無法強制虛擬機將自身用作網關:像以前一樣橋接的虛擬機可以簡單地忽略主機並保留 192.168.1.1作為網關並使其流量tun0最終不使用主機的介面。

如果 VM 可以信任並重新配置,則可以保留br0上述內容,套用基於的任何 OpenVPN 設定br0(將任何enp7s0參考替換為br0),並在 VM 運行(位址為 192.168.1.221)且 VPN 啟動後執行此操作:

  • 在主機上

    使用基於策略/來源的路由為此特定來源選擇不同的路由結果:

    ip rule add from 192.168.1.221 lookup 1000
    ip rule add iif tun0 lookup 1000
    ip route add 192.168.1.0/24 dev br0 table 1000
    ip route add default dev tun0 table 1000
    

    設定為路由器:

    sysctl -w net.ipv4.ip_forward=1
    

如果沒有類似的 NAT 規則可以處理這種情況:

  iptables -t nat -A POSTROUTING -s 192.168.1.221 -o tun0 -j MASQUERADE
  • 在 (Linux) VM 上,使用主機作為網關而不是主機的路由器

    ip route flush to default
    ip route add default via 192.168.1.100
    

建議不受信任的虛擬機器:不要將主機主介面設定為橋接端口

這使得強制執行虛擬機器流量變得更加容易,tun0因為它無法查看不應篡改的網路部分。

  • 更改虛擬機器設定以使用其自己的 IP 網路

    範例:192.168.100.0/24 和靜態 IP 192.168.100.2/24(而非主機的網路 DHCP),預設閘道為 192.168.100.1。在 Linux 虛擬機器上:

    ip address add 192.168.100.2/24 dev enp1s0
    ip route add default via 192.168.100.1
    
  • 在主機上,從初始配置開始(不橋接enp7s0

    甚至可以使用下面的零橋(即:直接ip address add 192.168.100.1/24 dev vnet5vnet5設定為橋端口),但是庫虛擬機可能會讓這變得更加困難。

    只需為虛擬機器設定一個專用橋(此處使用位址 192.168.100.1/24,儘管通常庫虛擬機提供預設網橋virbr0192.168.122.1/24):

    ip link add name br0 up type bridge
    ip address add 192.168.100.1/24 dev br0
    ip link set dev vnet5 master br0
    

    並且也使用策略路由更改與兩個相關介面的虛擬機器相關的流量行為:br0tun0。像往常一樣,它涉及對備用路由表中現有路由的一些複製和更改。這裡tun0假設只為主機及其虛擬機器提供服務。最終目標是:無論來自 VM 端的內容都會路由到 tun 端,無論來自 TUN 端的內容都會路由到 VM 端,忽略任何不需要的端。

    ip rule add iif br0 lookup 2000
    ip rule add iif tun0 lookup 2000
    ip route add 192.168.100.0/24 dev br0 table 2000
    ip route add default dev tun0 table 2000 # layer 3 interfaces don't need a gateway
    

    注意:來自tun0主機的傳入資料包(即:未路由)已由主機處理當地的路由表,不需要表 2000 中任何額外的路由。

    設定為路由器:

    sysctl -w net.ipv4.ip_forward=1
    

    然後完成 NAT,因為遠端 OpenVPN 伺服器不知道 192.168.100.0/24:

    iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o tun0 -j MASQUERADE
    

如果虛擬機器仍然能夠存取 192.168.1.0/24 LAN:

  • 再次更新表 2000 以適應這一點

    將 LAN 路由從主表複製到表 2000:

    ip route add 192.168.1.0/24 dev enp7s0 table 2000
    
  • 並且再次加入適當的 MASQUERADE 規則

    ……因為VM現在位於其他系統不知道的不同LAN:

    iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o enp7s0 -j MASQUERADE
    

    (可以完成一些 iptables 規則分解)。

相關內容