我正在尝试通过 openvpn 路由一个用户的流量。如果 vpn 出现故障,他们的流量将被拒绝。我想使用附加到 openvpn 的脚本来执行此操作。
在我的测试中,这适用于通过 vpn 路由用户,直到我使用 DROP iptable...然后用户失去所有连接并且其他规则被忽略..
这一切都在 debian stretch 上。
我在这里找到了一个很好的综合指南:https://www.niftiestsoftware.com/2011/08/28/making-all-network-traffic-for-a-linux-user-use-a-specific-network-interface/comment-page-1/
在大多数情况下,它运行良好,但我遇到了与以前相同的问题。我可以将用户的流量路由到 vpn,但如果 vpn 不存在,它就会返回到 eth0 或其他地方。
如果我尝试使用相当于“允许tun0
,不允许eth0
”的方式阻止这种情况,我最终会阻止 tun0 和 eth0”
iptables -A OUTPUT -o eth0 -m owner --uid-owner $VPNUSER -j REJECT
与……相冲突
iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT
iptables -A OUTPUT -o tun0 -m owner --uid-owner $VPNUSER -j ACCEPT
我在这里做错了什么?
下面是我的第一次尝试,但现在我遵循上面链接的格式:
iptables -F OUTPUT
iptables -I OUTPUT -m owner --uid-owner foo -j MARK --set-mark 42
iptables -I OUTPUT -d 10.20.0.0/24 -m owner --uid-owner foo
iptables -I OUTPUT -d VPNSERVERIP -p udp -j ACCEPT -m owner --uid-owner foo
iptables -I OUTPUT -j DROP -m owner --uid-owner foo
iptables -t nat -I POSTROUTING -o tun0 -j MASQUERADE
然后再做一些其他的事情来让路由正常工作......
ip rule add fwmark 42 table 42
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 0 > $f
done;
ip route add default via $(ifconfig -a tun0 | grep -o 'destination [^ ]*' | cut -d \ -f 2) table 42
毕竟这iptables -L OUTPUT
看起来像这样:
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere owner UID match foo
ACCEPT udp -- anywhere VPNSERVERIP owner UID match foo
all -- anywhere 10.20.0.0/24 owner UID match foo
MARK all -- anywhere anywhere owner UID match foo MARK set 0x2a
答案1
这可能会有所帮助:
他们阻止了所有到 eth0 的流量,然后允许一些流量稍后通过(DNS,ping)
戈尔德施泰因
2014 年 8 月一般隐私讨论
帖子:4
(更新)
大家好你们好,
我试图构建一个解决方案,将 Debian 或 Ubuntu 机器转变为只能通过 VPN 访问互联网(以避免断开连接或 OpenVPN 崩溃时出现任何错误)。
供您参考,我使用配置了 PIA 配置文件的 OpenVPN,并且我假设您的计算机上只有 eth0。
1/ 当接口启动时,禁用流量
/etc/网络/接口
auto eth0 iface eth0 inet dhcp pre-up iptables-restore < /etc/iptables.rules
然后:/etc/iptables.rules
*filter # Default Policy :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] # Broadcast without logging -A INPUT -m pkttype --pkt-type broadcast -j DROP -m comment --comment "Block Broadcast INPUT (No log)" -A INPUT -m pkttype --pkt-type multicast -j DROP -m comment --comment "Block Multicast INPUT (No Log)" # Allow localhost -A INPUT -i lo -m comment --comment "Accept localhost Input" -j ACCEPT -A OUTPUT -o lo -m comment --comment "Accept localhost Output" -j ACCEPT ## Allow to connect to upd 1194 (openvpn) -A OUTPUT -p udp --dport 1194 -j ACCEPT -m comment --comment "Allow my computer to query the DNS server" -A INPUT -p udp --sport 1194 -m state --state ESTABLISHED -j ACCEPT -m comment --comment "Allow the server to reply (related to lport)" # Allow DNS -A OUTPUT -p udp -d 209.222.18.222 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT -m comment --comment "Allow my machine to connect to the DNS1" -A INPUT -p udp -s 209.222.18.222 --sport 53 -m state --state ESTABLISHED -j ACCEPT -m comment --comment "Allow the DNS1 to answer" -A OUTPUT -p udp -d 209.222.18.218 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT -m comment --comment "Allow my machine to connect to the DNS2" -A INPUT -p udp -s 209.222.18.218 --sport 53 -m state --state ESTABLISHED -j ACCEPT -m comment --comment "Allow the DNS2 to answer" # Logging -A INPUT -m limit --limit 10/min -j LOG --log-prefix "FW DROP INPUT: " --log-level 7 -m comment --comment "Log Input" -A FORWARD -m limit --limit 10/min -j LOG --log-prefix "FW DROP FORWARD: " --log-level 7 -m comment --comment "Log Forward" -A OUTPUT -m limit --limit 10/min -j LOG --log-prefix "FW DROP OUTPUT: " --log-level 7 -m comment --comment "Log Output" # Ping -A OUTPUT -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT -m comment --comment "Allow ping to Outside" COMMIT
然后,如果你不启动 VPN,你将一无所有,除了 localhost、DNS 和 OpenVPN
要应用更改:
# ifdown eth0 # ifup eth0
当你启动 VPN 时,为了避免 DNS 泄漏,我会启动一个脚本
我必须“破解”/etc/default/openvpn 文件以在其顶部添加:
# A pre script for Private Internet Access
/etc/openvpn/before_start.sh
/etc/openvpn/before_start.sh 包含:
#!/bin/bash DNS1=209.222.18.222 DNS2=209.222.18.218 ## Change the DNS to avoid DNS Leak echo "nameserver $DNS1" > /etc/resolv.conf echo "nameserver $DNS2" >> /etc/resolv.conf
然后进入 /etc/openvpn/vpn.conf,我在最后添加了(不要忘记删除 nobind,因为我强制使用本地端口)
lport 1194 ipchange up_script.sh down down_script.sh
查找 up_script.sh(我已经改进了它,添加了日志并删除了所有广播地址,但我现在没有这个文件)。防火墙规则之所以存在,是因为我之前不知道公共 IP。网关许可仅用于满足我的个人需求,您可以将其删除
#!/bin/bash # Firewall Rules IP=$(echo $1 | sed 's/\[AF_INET\]//g') GW=$(/sbin/ip route | awk '/default/ { print $3 }') IPT=iptables # Start logger "ovpn: Got public IP $IP" # tun interfaces (VPN) $IPT -A INPUT -i tun+ -j ACCEPT -m comment --comment "Accept TUN Input" $IPT -A OUTPUT -o tun+ -j ACCEPT -m comment --comment "Accept TUN Output" # Allow traffic with my VPN server $IPT -A INPUT -s $IP -j ACCEPT -m comment --comment "Accept PIA Input" $IPT -A OUTPUT -d $IP -j ACCEPT -m comment --comment "Accept PIA Output" # Allow my gateway on eth0 $IPT -A OUTPUT -d $GW -o eth+ -j ACCEPT -m comment --comment "Accept My Gateway"
然后down_script.sh
#!/bin/bash GW=$(/sbin/ip route | awk '/default/ { print $3 }') IPT=iptables # Push DNS again echo "nameserver 127.0.0.1" > /etc/resolv.conf # Restart my interface ! ifdown -a ifup -a
那么您对此有什么看法?
G。
答案2
我使用以下配置使它工作:
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N f2b-sshd
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A INPUT -i tun0 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -m pkttype --pkt-type broadcast -m comment --comment "Block Broadcast INPUT (No log)" -j DROP
-A INPUT -m pkttype --pkt-type multicast -m comment --comment "Block Multicast INPUT (No Log)" -j DROP
-A INPUT -i lo -m comment --comment "Accept localhost Input" -j ACCEPT
-A INPUT -p udp -m udp --sport 1194 -m state --state ESTABLISHED -m comment --comment "Allow the server to reply (related to lport)" -j ACCEPT
-A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
-A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 8.8.8.8/32 -p udp -m udp --sport 53 -m state --state ESTABLISHED -m comment --comment "Allow the DNS1 to answer" -j ACCEPT
-A INPUT -s 8.8.4.4/32 -p udp -m udp --sport 53 -m state --state ESTABLISHED -m comment --comment "Allow the DNS2 to answer" -j ACCEPT
-A INPUT -m limit --limit 10/min -m comment --comment "Log Input" -j LOG --log-prefix "FW DROP INPUT: " --log-level 7
-A INPUT -i tun+ -m comment --comment "Accept TUN Input" -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -m limit --limit 10/min -m comment --comment "Log Forward" -j LOG --log-prefix "FW DROP FORWARD: " --log-level 7
-A OUTPUT -o lo -m owner --uid-owner 1001 -j ACCEPT
-A OUTPUT -o tun0 -m owner --uid-owner 1001 -j ACCEPT
-A OUTPUT ! -s $EXTERNALIP -o $EXT_INT -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o lo -m owner --uid-owner 1002 -j ACCEPT
-A OUTPUT -o tun0 -m owner --uid-owner 1002 -j ACCEPT
-A OUTPUT ! -s $EXTERNALIP/32 -o $EXT_INT -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o lo -m owner --uid-owner 1003 -j ACCEPT
-A OUTPUT -o tun0 -m owner --uid-owner 1003 -j ACCEPT
-A OUTPUT ! -s $EXTERNALIP/32 -o $EXT_INT -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o lo -m comment --comment "Accept localhost Output" -j ACCEPT
-A OUTPUT -p udp -m udp --dport 1194 -m comment --comment "Allow my computer to query the DNS server" -j ACCEPT
-A OUTPUT -p tcp -m multiport --sports 22,80,443 -j ACCEPT
-A OUTPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o $EXT_INT -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT
-A OUTPUT -o $EXT_INT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A OUTPUT -d 8.8.8.8/32 -p udp -m udp --dport 53 -m state --state NEW,ESTABLISHED -m comment --comment "Allow my machine to connect to the DNS1" -j ACCEPT
-A OUTPUT -d 8.8.4.4/32 -p udp -m udp --dport 53 -m state --state NEW,ESTABLISHED -m comment --comment "Allow my machine to connect to the DNS2" -j ACCEPT
-A OUTPUT -m limit --limit 10/min -m comment --comment "Log Output" -j LOG --log-prefix "FW DROP OUTPUT: " --log-level 7
-A OUTPUT -p icmp -m icmp --icmp-type 0 -m state --state RELATED,ESTABLISHED -m comment --comment "Allow ping to Outside" -j ACCEPT
-A OUTPUT -o tun+ -m comment --comment "Accept TUN Output" -j ACCEPT
-A f2b-sshd -j RETURN