我有一个任务是保护 nginx 服务器,该服务器与 docker-container 一起作为端口上的反向代理8732。我必须禁用除端口 80 之外的所有传入连接,以便颁发 SSL 证书,当然还有 SSH 连接。我设置了一些规则,但它们无法与 INPUT 和 OUTPUT 默认策略设置为 DROP 一起使用,而这是任务所必需的。关键是,所有规则都像魔法一样工作,策略设置为 ACCEPT。这是我的 iptables 规则:
root@bw:/home/user# iptables -S
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A INPUT -s <**external address**/24> -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -d <mail server/32> -p tcp -m tcp --dport 587 -m state --state ESTABLISHED -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-9c6ddba356b8 -o br-9c6ddba356b8 -p tcp -m tcp --dport 80 -j ACCEPT
这是 nmap 的输出:
root@bw:/home/user# netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 886/nginx: master p
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 766/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 842/sshd: /usr/sbin
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 886/nginx: master p
tcp 0 0 0.0.0.0:8732 0.0.0.0:* LISTEN 49697/docker-proxy
tcp6 0 0 :::443 :::* LISTEN 886/nginx: master p
tcp6 0 0 :::22 :::* LISTEN 842/sshd: /usr/sbin
tcp6 0 0 :::80 :::* LISTEN 886/nginx: master p
tcp6 0 0 :::8732 :::* LISTEN 49702/docker-proxy
以及 iptables 的输出:
user@bw:~$ sudo iptables -L -v -n
Chain INPUT (policy DROP 110 packets, 30439 bytes)
pkts bytes target prot opt in out source destination
11398 751K ACCEPT tcp -- * * <my subnet address.0/24> 0.0.0.0/0 tcp dpt:22 state NEW,ESTABLISHED
33540 15M ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
2129 230K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 state NEW,ESTABLISHED
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy DROP 838 packets, 54784 bytes)
pkts bytes target prot opt in out source destination
8303 1951K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:22 state ESTABLISHED
33551 15M ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 <mail server ip> tcp dpt:587 state ESTABLISHED
176 19390 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:80 state ESTABLISHED
Chain DOCKER (0 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- !br-9c6ddba356b8 br-9c6ddba356b8 0.0.0.0/0 172.19.0.2 tcp dpt:80
答案1
您的OUTPUT
链缺少允许从端口 80 建立连接的规则。
使用
iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
您的nmap
输出来自netstat
,这是一个完全不同的工具。
输出netstat
显示哪些进程具有活动的侦听 TCP 套接字。每当您运行打开侦听套接字的守护进程时,它始终会出现在列表中。
防火墙规则在网络堆栈内部运行,并充当访问服务的单独隔离层。当您配置防火墙条目时,它们将限制到服务器的流量。这些规则对netstat
显示的内容没有影响。
您需要通过运行 来检查规则是否有效iptables -nvL
,它将显示每条规则提供的数据包数的计数器。另一种检查是从外部向服务器发出请求,看看规则是否有效。
答案2
我必须禁用除端口 80 之外的所有传入连接,以便颁发 SSL 证书,当然还有 SSH 连接
我尝试连接到端口 80,它给了我 301 并将我重定向到 https 版本,之后我收到 504。如果我直接转到 443,我会立即得到 504
默认情况下 - HTTP 为 80/tcp,HTTPS 为 443/tcp。您仅打开了 80/tcp。
-A INPUT -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -p tcp -m tcp -m multiport --sports 80,443 -m state --state ESTABLISHED,RELATED -j ACCEPT
还要注意,在 OUTPUT 中不允许任何新连接(因此有效地阻止所有新连接) 从主机。例如,DNS查询被阻止,或者可能是其他原因导致您的主机无法正常运行。此外,您不需要在OUTPUT中为每个相应的INPUT规则重复规则。
更好地以更清晰、可预测和安全的方式组织 INPUT 和 OUTPUT 中的规则,就像这种模式一样
-P MAIN_CHAIN DROP
-A MAIN_CHAIN -o lo -j ACCEPT
-A MAIN_CHAIN -m state --state ESTABLISHED,RELATED -j ACCEPT
# next rules ACCEPT only NEW for all your needs
-A MAIN_CHAIN -m state --state NEW match-something1 -j ACCEPT
-A MAIN_CHAIN -m state --state NEW match-something2 -j ACCEPT
#... and so on
因此你的规则是:
-P INPUT DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -m state --state NEW -j ACCEPT
-A INPUT -p tcp -s <**external address**/24> --dport 22 -m state --state NEW -j ACCEPT
-A INPUT -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT
-P OUTPUT DROP
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT