我的根本目标是能够阻止攻击者在我的服务器上建立未经授权的传出连接(例如,连接回 shell)。
我可以通过使用“ufw”阻止所有传出流量的端口来实现这一点,除了服务器需要运行的端口(即DNS,HTTP,SSH和SMTP)。
ufw 允许我只允许到静态 IP 地址的传出 DNS 连接(所以我将配置服务器以使用 Google DNS),并且它允许我限制发往 127.0.0.1 的传出 SSH(我的自动部署脚本需要使用 Git 来实现这一点)。
据我所知,ufw 并不真正允许基于域名的传出限制,这是有道理的(从性能角度来看)。我需要能够做到这一点,以限制到我的邮件服务器域的传出 SMTP 连接(目前仅使用 Gmail 进行测试)和到 Ubuntu 服务器的 HTTP 连接(用于系统更新)。
我知道 iptables 允许您根据域指定规则,但它们在启动时被转换,而不是每次都执行(即反向 DNS)。我知道这是出于性能原因而设计的。
那么,通过域名限制传出网络流量的解决方案是什么(即每个传出连接都需要对其目标 IP 地址进行反向 DNS 并与域名白名单匹配)?
我在想,如果我无法使基于域的一半传出限制发挥作用,那么使用 ufw 通过 IP 限制 DNS 和 SSH 就没有多大意义了。
- 编辑 1* 所以我已经研究出如何直接使用 iptables 将发往某个端口(例如 80)的传出数据“转发”到另一个端口。
然后我意识到,在接收转发流量时,无法知道原始目标 IP 地址是什么。就在那时,我发现https://github.com/mitmproxy/mitmproxy并发现它(作为一个透明的 Python 代理)与 iptables 接口交互以确定套接字的原始目标 IP 地址。
我还没有完成所有工作,但我很确定这种方法应该有效。
答案1
这只在一台机器上有效,因为它依赖于透明代理能够与iptables
传出流量交互并获取其原始目标 IP。
还要注意,这种方法有点不合法,为了克服无限循环问题(重定向到代理->重定向到代理->...),防火墙规则应用于操作系统用户组,这意味着任何不在该组中的用户都不会通过代理转发其传出流量。
脚步:
创建一个名为“代理人
将每个操作系统用户(root 除外)添加到这个新组
获取ID的代理人将其分组并记住以供日后使用
设置某种类型的透明代理服务器,该服务器可以接受您想要代理的协议并可以与之交互
iptables
。我使用了mitmproxy
(基于 Python)并将其设置为作为根服务运行并监听代理端口。添加一条规则,
iptables
将所有发往特定端口(例如 http)的传出流量重定向至 127.0.0.1:代理端口,像这样:iptables -t nat -A OUTPUT -m owner --gid-owner proxyGID -p tcp --dport 80 -j DNAT --to 127.0.0.1:proxyPort
,替换代理GID和代理端口适当配置
iptables
或ufw
允许传出流量代理端口,允许任何端口被代理(例如 80)并且默认禁止所有其他端口。配置透明代理以随意丢弃请求。要回答这个问题,您需要配置代理以对原始目标 IP 执行反向 DNS,并检查结果域是否在预配置的白名单中,否则应丢弃流量。