連接到 VPN Server 時產生 iptables 規則

連接到 VPN Server 時產生 iptables 規則

我正在建立一個虛擬 Ubuntu 伺服器(Proxmox 上的 LXC),它將充當路由器並透過 VPN(expressVPN)為我的本地網路的某些裝置(例如 AppleTV)建立隧道。到不同 VPN 目的地(不同國家)的連線和路由正常。

但有些服務仍然知道我不是從 VPN 伺服器所在的國家/地區撥打電話。DNS 洩漏?

那是因為我的客戶端,假設 AppleTV 盒子使用 1.1.1.1 作為 DNS。它不知道 VPN 伺服器發佈到我的網關的 DNS 伺服器。

為了防止這種情況發生,我想使用連線時收到的 VPN 的 DNS 服務。我將 AppleTV 指向我的網關作為 DNS,並編寫了一些 iptables 規則,將請求 DNAT 發送到 VPN 伺服器提供的 DNS 伺服器。 (希望這是有道理的)

# Route DNS Traffic
iptables -t nat -A PREROUTING -p tcp --dst x.x.x.x --dport 53 -j DNAT --to-destination 10.54.0.1:53
iptables -t nat -A PREROUTING -p udp --dst x.x.x.x --dport 53 -j DNAT --to-destination 10.54.0.1:53

效果很好。

問題

如何在建立OpenVPN連線時自動產生這些規則?當連接到另一個 VPN 站(例如不同的國家)時,特定的 DNS 位址將會改變。或者有更好的解決方案嗎?

我本來想把它放進去update-systemd-resolved,但這似乎太複雜了。我認為有一個簡單的方法可以離開。

我很感謝任何提示。

答案1

歡迎,您可以在 openvpn *.conf 檔案中 使用up和命令,這些命令允許執行自訂腳本。如果您走這條路,則需要此範例:downscript-security 2

script-security 2
up /usr/local/bin/set-redirect-dns.sh
down /usr/local/bin/unset-redirect-dns.sh

真正的iptables命令在這些腳本中。請查看手冊頁是否script-security 2適合您。

答案2

我將回答我自己的問題以展示我的解決方案。

我了解到,resolved 透過存根 (127.0.0.53) 使用 dns,因此知道如何使用 VPN 的 DNS。

我「只是」必須轉發/nat 來自使用此伺服器作為網關(和 DNS)的 LAN 用戶端的 DNS 請求。

在 openvpn 用戶端設定中,我新增了以下幾行:

mci@vpngateway:/etc/openvpn$ head destinations/belgium_udp.ovpn -n4
script-security 2
up /etc/openvpn/linkup.sh
down /etc/openvpn/linkdown.sh
down-pre

我的劇本已經出來了...

mci@vpngateway:/etc/openvpn$ cat linkup.sh 
#!/bin/bash

# First let systemd-resolved do its magic
/etc/openvpn/update-systemd-resolved $@

# Set iptable rules
/etc/openvpn/iptables_baserules.sh

# Set DNS
/etc/openvpn/iptables_setdns.sh

和向下

mci@vpngateway:/etc/openvpn$ cat linkdown.sh 
#!/bin/bash

# First delete DNS iptables rules
/etc/openvpn/iptables_removedns.sh

# After let systemd-resolved do its magic
/etc/openvpn/update-systemd-resolved $@

基本規則主要是放棄其他東西

mci@vpngateway:/etc/openvpn$ cat iptables_baserules.sh 
#!/bin/bash

# Flush
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X

# Block All
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP

# allow Localhost
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

# Make sure you can communicate with any DHCP server
iptables -A OUTPUT -d 255.255.255.255 -j ACCEPT
iptables -A INPUT -s 255.255.255.255 -j ACCEPT

# Make sure that you can communicate within your own network
iptables -A INPUT -s x.x.x.0/24 -d x.x.x.0/24 -j ACCEPT
iptables -A OUTPUT -s x.x.x.0/24 -d x.x.x.0/24 -j ACCEPT

# Allow established sessions to receive traffic:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow TUN
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
iptables -A OUTPUT -o tun0 -j ACCEPT

# allow VPN connection
iptables -I OUTPUT 1 -p udp --destination-port 1195 -m comment --comment "Allow VPN connection" -j ACCEPT
iptables -I OUTPUT 1 -p tcp --destination-port 1195 -m comment --comment "Allow VPN connection" -j ACCEPT

# Block All
iptables -A OUTPUT -j DROP
iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP

請注意這些規則,我必須添加它們,以便節點本身可以在 VPN 連接關閉後查找名稱(也許是因為我想將 VPN 配置切換到另一台伺服器)。

iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

最後一件事是動態添加 DNS nat

mci@vpngateway:/etc/openvpn$ cat iptables_setdns.sh 
#!/bin/bash

# Route DNS Traffic
# Get DNS from VPN
dns=$(resolvectl dns -i tun0)
dns=${dns##* }
echo "Found DNS on tun0: ${dns}"
iptables -t nat -A PREROUTING -p tcp --dst x.x.x.x --dport 53 -j DNAT --to-destination ${dns}:53
iptables -t nat -A PREROUTING -p udp --dst x.x.x.x --dport 53 -j DNAT --to-destination ${dns}:53

然後將其刪除

mci@vpngateway:/etc/openvpn$ cat iptables_removedns.sh 
#!/bin/bash

# Route DNS Traffic
# Get DNS from VPN
dns=$(resolvectl dns -i tun0)
dns=${dns##* }
echo "Found DNS on tun0: ${dns}"
iptables -t nat -D PREROUTING -p tcp --dst x.x.x.x --dport 53 -j DNAT --to-destination ${dns}:53
iptables -t nat -D PREROUTING -p udp --dst x.x.x.x --dport 53 -j DNAT --to-destination ${dns}:53

也許這會對正在建置 VPN 網關的其他人有所幫助。

相關內容