![将所有传入的 HTTPS 流量重定向到另一个端口](https://linux22.com/image/717581/%E5%B0%86%E6%89%80%E6%9C%89%E4%BC%A0%E5%85%A5%E7%9A%84%20HTTPS%20%E6%B5%81%E9%87%8F%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%AB%AF%E5%8F%A3.png)
我有一个 Linux 路由器和两个本地托管的页面(在此服务器上运行),我想将所有传入的 HTTPS 流量重定向到在端口 14902 上运行的应用程序,并将所有传入的 HTTP 流量重定向到在端口 14901 上运行的应用程序。
类似这样的规则 (nat table) 可以完美处理端口 80 (HTTP) 上的传入流量。这意味着,我通过 Web 浏览器请求的每个页面都会重定向到应用程序 (端口)。
-A PREROUTING -i eth2 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.1:14901
...但对于 HTTPS,情况并非如此。
-A PREROUTING -i eth2 -p tcp --dport 443 -j DNAT --to-destination 192.168.0.1:14902
尽管我已强制我的机器将所有 DNS 名称解析为我的 Linux 路由器的 IP(因此 Web 浏览器无法通过其他方式对指定域的真实 IP 地址进行任何验证),但通过某种有关 SSL 证书的机制或我不知道的其他技术,Web 浏览器会通知我必须登录网络,每次我请求以下页面时https://facebook.com或者https://youtube.com。
无需强制 DNS(如我所提到的),Web 浏览器就会找到访问http://youtube.com,尽管我为以 443 为目标端口的传入流量设置了这样的规则,但这种情况只发生在 YouTube 上。只是提一下这个“有趣的事实”。但好吧。继续。
如果我的防火墙规则不允许与远程网络服务器联系,那么我的网络浏览器如何知道远程网络服务器正在声明“严格传输安全”?
Web 浏览器是否在进行 SSL 握手之前首先执行 HTTP 请求,这就是它通知我有关身份验证(如 Captive Portal)的原因?
我的主要问题是:是否有任何技术可以应用于 IPTABLES/Netfilter(例如,使用
raw
或mangle
表),可以保证目标端口为 443 的数据包必须始终重定向到特定端口,就像这个例子一样?
我理解在网络上请求登录的行为,认为这是 HTTP 请求,因为浏览器和操作系统具有强制门户检测机制,对特定页面执行 HTTP GET。但是,如果防火墙配置正确,认为传入流量以端口 443 为目的地,我不明白为什么会发生这种情况。
我检查了 Nginx 虚拟主机的日志(使用自签名证书),确实没有请求发送到运行在端口 14902 上的应用程序。
我知道在mangle
表格中,您可以调整 MTU 之类的东西,并且raw
您也可以在表格中对连接跟踪状态之前的数据包应用 PREROUTING。也许有 IPTABLES/Netfilter 高级背景的人(我的情况不是这样)可以提出一个可能的解决方案。
答案1
为什么不使用 nginx 呢?
server {
listen 80;
return 301 http://192.168.0.1:14901/$request_uri;
}
server {
listen 443 ssl;
return 301 https://192.168.0.1:14902/$request_uri;
}
但是如果没有主机名,您的证书可能无法起作用:
server {
listen 80;
server_name app1.example.com
return 301 http://app1.example.com:14901/$request_uri;
}
server {
listen 443 ssl;
server_name app2.example.com
return 301 https://app2.example.com:14902/$request_uri;
}
使用 iptables 打开端口 80 和 443 并让 nginx 执行其操作。
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
如果需要 UDP,只需添加
iptables -A INPUT -p udp -m udp --dport 80 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 443 -j ACCEPT