我遇到了一个iptables
似乎无法解决的配置问题。
我有一个已知的不良 IP 地址列表,我阻止通过ipset
和访问我的服务器iptables
。最初的方法是,iptables
如果 IP 与ipset
列表匹配,则简单地断开通过 的连接。这种方法效果很好。
现在我决定显示一条简短的服务器消息,而不是默默地断开连接。我想通知访问者访问已被阻止,并提供解决此问题的说明(如果他/她认为阻止是没有道理的)。
我修改后的方法如下,但如果你有更好的解决方案请评论:
因为据我所知,iptables
不能简单地返回请求的自定义响应(如果错误,请更正,我知道reject
可以返回一些固定的响应代码,但不是自定义消息),我想将匹配/识别的 IP 地址重定向到服务器8911 port
上的专用Nginx
地址,以便我可以处理请求Nginx
并返回错误消息。
该Nginx
实例托管在Docker
容器中。
iptables
这是我插入的两条规则,如果 IP 匹配,则NAT table
重新路由http
并向https
专用服务器发出请求:8911 port
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -m set --match-set badips src,dst -j DNAT --to-destination 127.0.0.1:8911
sudo iptables -t nat -I PREROUTING -p tcp --dport 443 -m set --match-set badips src,dst -j DNAT --to-destination 127.0.0.1:8911
这是NAT table
我插入规则之后的样子:
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 DNAT tcp -- anywhere anywhere tcp dpt:https match-set badips src,dst to:127.0.0.1:8911
2 DNAT tcp -- anywhere anywhere tcp dpt:http match-set badips src,dst to:127.0.0.1:8911
3 DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
1 DOCKER all -- anywhere !localhost/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
1 MASQUERADE all -- 172.23.0.0/16 anywhere
2 MASQUERADE all -- 172.16.0.0/16 anywhere
3 MASQUERADE tcp -- 172.23.0.14 172.23.0.14 tcp dpt:8911
4 MASQUERADE tcp -- 172.23.0.14 172.23.0.14 tcp dpt:https
5 MASQUERADE tcp -- 172.23.0.14 172.23.0.14 tcp dpt:http
Chain DOCKER (2 references)
num target prot opt source destination
1 RETURN all -- anywhere anywhere
2 RETURN all -- anywhere anywhere
3 DNAT tcp -- anywhere anywhere tcp dpt:8911 to:172.23.0.14:8911
4 DNAT tcp -- anywhere anywhere tcp dpt:https to:172.23.0.14:443
5 DNAT tcp -- anywhere anywhere tcp dpt:http to:172.23.0.14:80
如您所见,专用端口8911 port
在容器上是开放的Nginx
Docker
(端口当前向外界开放以进行测试,稍后将仅服务器主机可以访问)。
这是Nginx
专用的服务器块配置8911 port
:
server {
listen 0.0.0.0:8911;
server_name _;
add_header X-Frame-Options "SAMEORIGIN" always;
error_page 403 /e403.html;
location /e403.html{
root /usr/share/nginx/html/error;
access_log off;
internal;
}
location / {
access_log off;
return 403;
}
}
专用的Docker
和配置本身可以工作,因为当我从良好的(不匹配的)IP直接通过或 Web 浏览器访问专用时,会返回正确的错误响应以及状态。Nginx
8911 port
8911 port
curl
403
不幸的是,当使用被阻止的 IP 访问服务器时,iptables
不会将请求重定向到专用的8911 port
。连接尝试超时(不返回任何内容),就像连接被简单地丢弃一样iptables
。
我还将--to-destination
IP(在iptables
规则中)从 更改127.0.0.1
为0.0.0.0
或172.23.0.14
(Docker
接口) - 但它不起作用。
我的问题是:
(1)我必须在iptables
规则中更改哪些内容才能将 IP 匹配的请求正确重定向到专用的8911 port
?
(2)一旦iptables
最终正确重定向 IP 匹配的请求,https
IP 匹配的请求(上面的第一个 PREROUTING 规则)是否会被重定向到http
专用的8911 port
?例如https://foo.bar
->http://foo.bar:8911
(3)你对以下方面有什么建议或推荐?其他方法如何快速有效地为 IP 匹配的请求提供错误响应?
更新2024.04.20:
删除了以前的NAT prerouting
规则并根据建议添加了这些规则:
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -m set --match-set badips src,dst -j REDIRECT --to-ports 8911
sudo iptables -t nat -I PREROUTING -p tcp --dport 443 -m set --match-set badips src,dst -j REDIRECT --to-ports 8912
现在NAT table
看起来像这样:
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 REDIRECT tcp -- anywhere anywhere tcp dpt:https match-set badips src,dst redir ports 8912
2 REDIRECT tcp -- anywhere anywhere tcp dpt:http match-set badips src,dst redir ports 8911
3 DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
1 DOCKER all -- anywhere !localhost/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
1 MASQUERADE all -- 172.25.0.0/16 anywhere
2 MASQUERADE all -- 172.16.0.0/16 anywhere
6 MASQUERADE tcp -- 172.25.0.13 172.25.0.13 tcp dpt:8912
7 MASQUERADE tcp -- 172.25.0.13 172.25.0.13 tcp dpt:8911
8 MASQUERADE tcp -- 172.25.0.13 172.25.0.13 tcp dpt:https
9 MASQUERADE tcp -- 172.25.0.13 172.25.0.13 tcp dpt:http
Chain DOCKER (2 references)
num target prot opt source destination
1 RETURN all -- anywhere anywhere
2 RETURN all -- anywhere anywhere
6 DNAT tcp -- anywhere anywhere tcp dpt:8912 to:172.25.0.13:8912
7 DNAT tcp -- anywhere anywhere tcp dpt:8911 to:172.25.0.13:8911
8 DNAT tcp -- anywhere anywhere tcp dpt:https to:172.25.0.13:443
9 DNAT tcp -- anywhere anywhere tcp dpt:http to:172.25.0.13:80
还为 https 重定向添加了额外的 nginx 服务器块port 8912
,以加载正确的 SSL 证书...
server {
listen 0.0.0.0:8912 ssl http2;
server_name _;
include conf.d/my_server.cf;
default_type text/plain;
return 403 "IP address blocked for security reasons.";
}
这是 iptablesfilter
表 cfg:
Chain INPUT (policy DROP)
num target prot opt source destination
1 ufw-before-logging-input all -- anywhere anywhere
2 ufw-before-input all -- anywhere anywhere
3 ufw-after-input all -- anywhere anywhere
4 ufw-after-logging-input all -- anywhere anywhere
5 ufw-reject-input all -- anywhere anywhere
6 ufw-track-input all -- anywhere anywhere
7 ACCEPT all -- anywhere anywhere
8 ACCEPT all -- anywhere anywhere
9 ACCEPT all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 DOCKER-USER all -- anywhere anywhere
2 DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
3 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
4 DOCKER all -- anywhere anywhere
5 ACCEPT all -- anywhere anywhere
6 ACCEPT all -- anywhere anywhere
7 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
8 DOCKER all -- anywhere anywhere
9 ACCEPT all -- anywhere anywhere
10 ACCEPT all -- anywhere anywhere
11 ufw-before-logging-forward all -- anywhere anywhere
12 ufw-before-forward all -- anywhere anywhere
13 ufw-after-forward all -- anywhere anywhere
14 ufw-after-logging-forward all -- anywhere anywhere
15 ufw-reject-forward all -- anywhere anywhere
16 ufw-track-forward all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
1 ufw-before-logging-output all -- anywhere anywhere
2 ufw-before-output all -- anywhere anywhere
3 ufw-after-output all -- anywhere anywhere
4 ufw-after-logging-output all -- anywhere anywhere
5 ufw-reject-output all -- anywhere anywhere
6 ufw-track-output all -- anywhere anywhere
Chain DOCKER (2 references)
num target prot opt source destination
4 ACCEPT tcp -- anywhere 172.29.0.13 tcp dpt:8912
5 ACCEPT tcp -- anywhere 172.29.0.13 tcp dpt:8911
6 ACCEPT tcp -- anywhere 172.29.0.13 tcp dpt:https
7 ACCEPT tcp -- anywhere 172.29.0.13 tcp dpt:http
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
num target prot opt source destination
1 DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
2 DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
3 RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
num target prot opt source destination
1 DROP all -- anywhere anywhere
2 DROP all -- anywhere anywhere
3 RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
num target prot opt source destination
1 RETURN all -- anywhere anywhere
Chain ufw-after-forward (1 references)
num target prot opt source destination
Chain ufw-after-input (1 references)
num target prot opt source destination
1 ufw-skip-to-policy-input udp -- anywhere anywhere udp dpt:netbios-ns
2 ufw-skip-to-policy-input udp -- anywhere anywhere udp dpt:netbios-dgm
3 ufw-skip-to-policy-input tcp -- anywhere anywhere tcp dpt:netbios-ssn
4 ufw-skip-to-policy-input tcp -- anywhere anywhere tcp dpt:microsoft-ds
5 ufw-skip-to-policy-input udp -- anywhere anywhere udp dpt:bootps
6 ufw-skip-to-policy-input udp -- anywhere anywhere udp dpt:bootpc
7 ufw-skip-to-policy-input all -- anywhere anywhere ADDRTYPE match dst-type BROADCAST
Chain ufw-after-logging-forward (1 references)
num target prot opt source destination
Chain ufw-after-logging-input (1 references)
num target prot opt source destination
1 LOG all -- anywhere anywhere limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "
Chain ufw-after-logging-output (1 references)
num target prot opt source destination
Chain ufw-after-output (1 references)
num target prot opt source destination
Chain ufw-before-forward (1 references)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
2 ACCEPT icmp -- anywhere anywhere icmp destination-unreachable
3 ACCEPT icmp -- anywhere anywhere icmp source-quench
4 ACCEPT icmp -- anywhere anywhere icmp time-exceeded
5 ACCEPT icmp -- anywhere anywhere icmp parameter-problem
6 ACCEPT icmp -- anywhere anywhere icmp echo-request
7 ufw-user-forward all -- anywhere anywhere
Chain ufw-before-input (1 references)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere
2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
3 ufw-logging-deny all -- anywhere anywhere ctstate INVALID
4 DROP all -- anywhere anywhere ctstate INVALID
5 ACCEPT icmp -- anywhere anywhere icmp destination-unreachable
6 ACCEPT icmp -- anywhere anywhere icmp source-quench
7 ACCEPT icmp -- anywhere anywhere icmp time-exceeded
8 ACCEPT icmp -- anywhere anywhere icmp parameter-problem
9 ACCEPT icmp -- anywhere anywhere icmp echo-request
10 ACCEPT udp -- anywhere anywhere udp spt:bootps dpt:bootpc
11 ufw-not-local all -- anywhere anywhere
12 ACCEPT udp -- anywhere mdns.mcast.net udp dpt:mdns
13 ACCEPT udp -- anywhere 239.255.255.250 udp dpt:1900
14 ufw-user-input all -- anywhere anywhere
Chain ufw-before-logging-forward (1 references)
num target prot opt source destination
Chain ufw-before-logging-input (1 references)
num target prot opt source destination
Chain ufw-before-logging-output (1 references)
num target prot opt source destination
Chain ufw-before-output (1 references)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere
2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
3 ufw-user-output all -- anywhere anywhere
Chain ufw-logging-allow (0 references)
num target prot opt source destination
1 LOG all -- anywhere anywhere limit: avg 3/min burst 10 LOG level warning prefix "[UFW ALLOW] "
Chain ufw-logging-deny (2 references)
num target prot opt source destination
1 RETURN all -- anywhere anywhere ctstate INVALID limit: avg 3/min burst 10
2 LOG all -- anywhere anywhere limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "
Chain ufw-not-local (1 references)
num target prot opt source destination
1 RETURN all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
2 RETURN all -- anywhere anywhere ADDRTYPE match dst-type MULTICAST
3 RETURN all -- anywhere anywhere ADDRTYPE match dst-type BROADCAST
4 ufw-logging-deny all -- anywhere anywhere limit: avg 3/min burst 10
5 DROP all -- anywhere anywhere
Chain ufw-reject-forward (1 references)
num target prot opt source destination
Chain ufw-reject-input (1 references)
num target prot opt source destination
Chain ufw-reject-output (1 references)
num target prot opt source destination
Chain ufw-skip-to-policy-forward (0 references)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere
Chain ufw-skip-to-policy-input (7 references)
num target prot opt source destination
1 DROP all -- anywhere anywhere
Chain ufw-skip-to-policy-output (0 references)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere
Chain ufw-track-forward (1 references)
num target prot opt source destination
1 ACCEPT tcp -- anywhere anywhere ctstate NEW
2 ACCEPT udp -- anywhere anywhere ctstate NEW
Chain ufw-track-input (1 references)
num target prot opt source destination
Chain ufw-track-output (1 references)
num target prot opt source destination
1 ACCEPT tcp -- anywhere anywhere ctstate NEW
2 ACCEPT udp -- anywhere anywhere ctstate NEW
Chain ufw-user-forward (1 references)
num target prot opt source destination
Chain ufw-user-input (1 references)
num target prot opt source destination
1 ACCEPT tcp -- anywhere anywhere tcp dpt:9933
2 ACCEPT udp -- anywhere anywhere udp dpt:9933
3 tcp -- anywhere anywhere tcp dpt:ssh ctstate NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
4 ufw-user-limit tcp -- anywhere anywhere tcp dpt:ssh ctstate NEW recent: UPDATE seconds: 30 hit_count: 6 name: DEFAULT side: source mask: 255.255.255.255
5 ufw-user-limit-accept tcp -- anywhere anywhere tcp dpt:ssh
6 ACCEPT tcp -- anywhere anywhere tcp dpt:2375
7 ACCEPT tcp -- anywhere anywhere tcp dpt:2376
8 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh /* 'dapp_OpenSSH' */
9 ACCEPT tcp -- anywhere anywhere tcp dpt:https
Chain ufw-user-limit (1 references)
num target prot opt source destination
1 LOG all -- anywhere anywhere limit: avg 3/min burst 5 LOG level warning prefix "[UFW LIMIT BLOCK] "
2 REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain ufw-user-limit-accept (1 references)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere
Chain ufw-user-logging-forward (0 references)
num target prot opt source destination
Chain ufw-user-logging-input (0 references)
num target prot opt source destination
Chain ufw-user-logging-output (0 references)
num target prot opt source destination
Chain ufw-user-output (1 references)
num target prot opt source destination
但:
(1)iptables 重定向到端口 8911/8912 仍然不起作用
谢谢!
答案1
DNAT
iptables
当目标主机位于正在运行的路由器后面的网络中时,应该使用target 。
但是,你的情况是在同一台机器上。因此我建议你使用REDIRECT
如下目标:
iptables -t nat -I PREROUTING -p tcp --dport 80 -m set --match-set badips src,dst -j REDIRECT --to-ports 8911
此外,你https
的 nginx 中需要一个单独的端口。HTTP 和 TLS 是两种不同的协议,你不能在同一个端口上运行它们。
因此您需要在端口 8912 上设置另一个具有适当证书的虚拟主机,然后制定规则:
iptables -t nat -I PREROUTING -p tcp --dport 443 -m set --match-set badips src,dst -j REDIRECT --to-ports 8912
您的防火墙规则似乎阻止了到端口 8911 和 8912 的传入连接。
您需要使用 UFW 允许这些端口。