目標是:
- 允許 VPN 用戶端存取互聯網
- 有權存取 docker 子網路(例如 178.18.0.0/24)
- 透過修改 iptables 防止 docker 自動暴露自身
- 手動允許 docker 連接埠暴露於互聯網
我已經用範例配置解決了 1這裡, 2 透過將子網路推入server.conf
問題:如何防止 docker 自動繞過 INPUT DROP iptable 鏈公開端口,而不斷開 eth0 和 tun0 上的互聯網連接?
嘗試:
- 我已經嘗試過記錄的 docker 方式:https://docs.docker.com/network/iptables/但一旦我應用它,它就會斷開我的 VPN 用戶端的所有互聯網連接- 他們可以正常存取 docker 的子網,但無法存取互聯網。如果我將 DROP 反轉為 ACCEPT,則會出現相反的情況:互聯網可以工作,而 docker 子網路則不能工作並且會暴露。
- 我還嘗試
iptables -I DOCKER-USER -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
按此處所述添加:https://riptutorial.com/docker/topic/9201/iptables-with-docker- 可悲的是這並沒有改變任何事情
我的 docker 相關 iptables 條目目前如下所示:
iptables -I DOCKER-USER -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I DOCKER-USER -i eth0 ! -s 10.0.0.0/24 -j DROP
我的網路看起來像這樣:
eth0 - publicly facing
tun0 - vpn on 10.0.0.0/24
docker - 172.18.0.0/24
目前的整個配置:
#!/bin/bash
# A Sample OpenVPN-aware firewall.
# eth0 is connected to the internet.
# eth1 is connected to a private subnet.
# Change this subnet to correspond to your private
# ethernet subnet. Home will use 10.0.1.0/24 and
# Office will use 10.0.0.0/24.
PRIVATE=10.0.0.0/24
# Loopback address
LOOP=127.0.0.1
# Delete old iptables rules
# and temporarily block all traffic.
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -F
# Set default policies
iptables -P OUTPUT ACCEPT
iptables -P INPUT DROP
iptables -P FORWARD DROP
# Prevent external packets from using loopback addr
iptables -A INPUT -i eth0 -s $LOOP -j DROP
iptables -A FORWARD -i eth0 -s $LOOP -j DROP
iptables -A INPUT -i eth0 -d $LOOP -j DROP
iptables -A FORWARD -i eth0 -d $LOOP -j DROP
# Anything coming from the Internet should have a real Internet address
iptables -A FORWARD -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A FORWARD -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A FORWARD -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
# Block outgoing NetBios (if you have windows machines running
# on the private subnet). This will not affect any NetBios
# traffic that flows over the VPN tunnel, but it will stop
# local windows machines from broadcasting themselves to
# the internet.
iptables -A FORWARD -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A FORWARD -p udp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p udp --sport 137:139 -o eth0 -j DROP
# Check source address validity on packets going out to internet
iptables -A FORWARD -s ! $PRIVATE -i eth1 -j DROP
# Allow local loopback
iptables -A INPUT -s $LOOP -j ACCEPT
iptables -A INPUT -d $LOOP -j ACCEPT
# Allow incoming pings (can be disabled)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Allow services such as www and ssh (can be disabled)
iptables -A INPUT -p tcp --dport http -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
# Allow incoming OpenVPN packets
# Duplicate the line below for each
# OpenVPN tunnel, changing --dport n
# to match the OpenVPN UDP port.
#
# In OpenVPN, the port number is
# controlled by the --port n option.
# If you put this option in the config
# file, you can remove the leading '--'
#
# If you taking the stateful firewall
# approach (see the OpenVPN HOWTO),
# then comment out the line below.
iptables -A INPUT -p udp --dport 1194 -j ACCEPT
# Allow packets from TUN/TAP devices.
# When OpenVPN is run in a secure mode,
# it will authenticate packets prior
# to their arriving on a tun or tap
# interface. Therefore, it is not
# necessary to add any filters here,
# unless you want to restrict the
# type of packets which can flow over
# the tunnel.
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT
# Allow packets from private subnets
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT
# Keep state of connections from local machine and private subnets
iptables -A OUTPUT -m state --state NEW -o eth0 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth0 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Docker allow only VPN by default
iptables -I DOCKER-USER -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I DOCKER-USER -i eth0 ! -s 10.0.0.0/24 -j DROP
# Masquerade local subnet
iptables -t nat -A POSTROUTING -s $PRIVATE -o eth0 -j MASQUERADE
謝謝!
答案1
解決方案是將 docker 正確地放在 ufw 後面,在 stack Overflow 上發布了一篇很棒的文章:https://stackoverflow.com/a/58098930/11821602其起源於:https://github.com/moby/moby/issues/4737#issuecomment-419705925
在 /etc/ufw/after.rules 末尾附加以下內容(將 eth0 替換為您的外部介面):
# Put Docker behind UFW *filter :DOCKER-USER - [0:0] :ufw-user-input - [0:0] -A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A DOCKER-USER -m conntrack --ctstate INVALID -j DROP -A DOCKER-USER -i eth0 -j ufw-user-input -A DOCKER-USER -i eth0 -j DROP COMMIT
並撤銷任何及全部:
- 從 /etc/docker/daemon.json 刪除 "iptables": "false"
- 恢復為 /etc/default/ufw 中的 DEFAULT_FORWARD_POLICY="DROP"
- 刪除對 /etc/ufw/before.rules 的任何與 docker 相關的更改
請務必測試重新啟動後一切正常。