Iptables:将匹配 IP 的请求重定向到专用服务器端口

Iptables:将匹配 IP 的请求重定向到专用服务器端口

我遇到了一个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 浏览器访问专用时,会返回正确的错误响应以及状态。Nginx8911 port8911 portcurl403

不幸的是,当使用被阻止的 IP 访问服务器时,iptables不会将请求重定向到专用的8911 port。连接尝试超时(不返回任何内容),就像连接被简单地丢弃一样iptables

我还将--to-destinationIP(在iptables规则中)从 更改127.0.0.10.0.0.0172.23.0.14Docker接口) - 但它不起作用。

我的问题是:

(1)我必须在iptables规则中更改哪些内容才能将 IP 匹配的请求正确重定向到专用的8911 port

(2)一旦iptables最终正确重定向 IP 匹配的请求,httpsIP 匹配的请求(上面的第一个 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

DNATiptables当目标主机位于正在运行的路由器后面的网络中时,应该使用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 允许这些端口。

相关内容