我正在尝试在我的 Linux 服务上创建一个安全组,在端口 8080 上运行后端服务,并且我想确保只有在端口 80 上运行的 Apache 可以访问端口 8080 上的后端服务,而其他端口则不能。
请注意,它是同一台机器,有点像一台服务器,它有我的前端(即网站)和后端服务器(即 API 服务器)。但我希望实现一个内部防火墙,基本上只允许我的 Apache 服务器访问此 API。但如果对我的服务器进行 bash 并执行 curl,后端 API 应该不可用。将其视为在端口 80 上运行的网站或 html 页面,后端 API 服务可能是在 8080 上运行的 nodejs 服务器。我的目标是让这个端口 80 向端口 8080 发出请求。
基本上,我正在尝试实现一种 AWS 安全类型的东西,如果这有意义的话。
任何帮助都将不胜感激!
答案1
我希望实现一个内部防火墙,基本上只允许我的 Apache 服务器访问此 API。但如果对我的服务器进行 bash 并执行 curl,后端 API 应该不可用。
选项 1:使用基于 UID 的匹配设置防火墙规则。在 nftables 和 ip[6]tables 中,您都可以匹配套接字所有者 UID,仅允许“http”或“www-data”帐户。
对于 nftables,使用meta skuid <user>
match(其他一切都与基于 IP 的示例相同)。对于 ip[6]tables,使用--uid-owner <user>
match 选项。
tcp dport 8080 jump {
meta skuid "www-data" accept
reject
}
使用 iptables 时,不要忘记添加两个 iptables和ip6tables 规则。
选项 2:让后端监听“本地”(AF_UNIX)套接字,而不是 TCP 套接字。本地套接字的行为有点像文件,因此您可以使用常规文件权限将它们放在仅限“http”用户帐户的目录中。
gunicorn --bind=unix:/run/mybackend.sock myapp.wsgi:application
curl --unix-socket /run/mybackend.sock http://whatever/index.html
Apache 和 Nginx 都支持代理到本地套接字;语法如下:
ProxyPass unix:/run/mybackend.sock|http://localhost
选项 3:在 Apache 和后端之间设置 HTTPS 并实施 mTLS,后端需要来自 Apache 的客户端证书。
选项 4:让后端要求代理提供特定的身份验证标头(这有点冒险,因为标头可能会泄漏)。
原始答案:
在后端系统上设置防火墙规则。如果您的后端服务器使用 ufw 或firewalld,请查找如何配置它们以将端口 8080 仅限制为特定来源;如果尚未安装防火墙,那么下一步可能是使用 nftables(或 Ferm,或 raw iptables)。
请注意,来自 Apache 的“后端”连接不要来自端口 80。它们使用随机临时源端口,就像任何其他 TCP 连接一样。因此,您的防火墙规则应配置为匹配源IP地址Apache 代理,而不是端口。
client:13456 --> apache:80
||
apache:23147 --> backend:8080
(为了更清楚起见,“客户端-代理”和“代理-后端”连接是独立的。在 IP 层,后端只能看到代理的地址,而看不到客户端的地址,而且 Apache 本身聆听端口 80 完全不相关。)
例如,在 nftables(的最新版本)中:
table inet filter {
chain input {
[...]
tcp dport 8080 jump {
ip saddr 192.168.42.3 accept
ip6 saddr 2001:db8:42::7 accept
reject
}
[...]
}
}
或者,如果后端正在运行相同的系统,配置后端服务器来监听(又名绑定)::1
和/或127.0.0.1
,即“localhost”地址可能会更简单。
一旦服务绑定到特定的本地地址,与后端的其他 IP 地址的连接将被隐式拒绝,因为没有任何内容监听它们 - 而同一系统上的 Apache 仍然能够连接到 或http://localhost:8080
或[::1]:8080
的后端127.0.0.1:8080
。
请注意,“同一系统”不包括虚拟机甚至容器,因为它们有自己独立于主机系统的“本地主机”。
较大的系统有时也使用“mTLS”,即代理和后端之间的具有客户端证书身份验证的 TLS(要求 Apache 代理作为客户端向后端服务器提供其自己的证书)。