只需设置一个 ElasticSearch 容器即可与公司的 Laravel 应用程序一起使用。创建 docker-compose.yml 并运行它是完美而直接的,但是当我想为这个东西设置防火墙以便它只能从提到的 Laravel 应用程序的一个特定 IP 访问时,就会出现问题。
在研究过程中,我注意到很多人都遇到了这些问题,即 Docker 转发的端口流量完全暴露给公众,并且他们无法正确设置防火墙。
我在过去 6 小时内找到了几个解决方案,但没有一个有效。我认为这与 Docker 处理/转发入站流量的方式有关,而且我的 iptables 知识并不丰富,因此我可以自己理解正在发生的事情。
这是我的 docker-compose.yml (物有所值):
version: '3.4'
services:
elasticsearch:
image: khezen/elasticsearch:6.1.1
container_name: elasticsearch
environment:
NETWORK_HOST: 0.0.0.0
HOSTS: 127.0.0.1
CLUSTER_NAME: fd-es
NODE_NAME: node-1
HEAP_SIZE: 31g
HTTP_SSL: "true"
ELASTIC_PWD: "somepasswd"
HTTP_CORS_ENABLE: "true"
HTTP_CORS_ALLOW_ORIGIN: /https?:\/\/localhost(:[0-9]+)?/
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./config/elasticsearch.yml:/elasticsearch/config/elasticsearch.yml
- ./data:/elasticsearch/data
- ./logs:/elasticsearch/logs
ports:
- 9200:9200
networks:
- es-network
restart: always
networks:
es-network:
driver: bridge
这些是我目前使用的 iptables 规则,这在某种程度上是我想要的,但仍然允许从任何客户端到端口 9200 的所有流量通过,而不是只能从我的应用程序访问:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [779:162776]
:DOCKER - [0:0]
-A DOCKER -s xxx.xxx.xxx.xxx -p tcp -m tcp --dport 9200 -j ACCEPT
-A DOCKER -o docker0 -p tcp -m tcp --dport 9200 -j ACCEPT
-A DOCKER -p tcp --dport 9200 -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp -m tcp --dport 44344 -j ACCEPT
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A INPUT -j DROP
我尝试禁用 Docker 的 iptables 支持并禁用桥接网络并调整 iptables 规则几十次,但无济于事。
我很感激任何建议和帮助来实现这一点,因为我没有这个问题的想法和搜索结果。
提前致谢!
对于每个寻求解决这个问题的人来说,答案是这样的:
在这里找到它:https ://unrouted.io/2017/08/15/docker-firewall/
完美运行。
我将解释我已经测试过您想要实现的目标的场景。
我已经启动了一个 docker 容器,其中端口 9010 被转发到端口 8080:
Docker 为 PREROUTING 链创建一个 DNAT 规则,将流量从端口 9010 转发到端口 8080:
Docker 还在 DOCKER 链中创建了一条规则,允许所有流量发送到容器的 IP 地址和端口 8080。
DOCKER 链用于 FORWARD 链,其中所有发送到 docker0 网桥的流量都由 DOCKER 链中的规则处理。
现在我想过滤发送到端口 8080 的流量(到端口 9010 的流量已由 PREROUTING 处理,现在它是发送到端口 8080 的流量)阻止所有 IP 地址,同时允许来自 IP 192.168.1.142 的流量。当然,可以将容器的 IP 地址添加到这些规则中以增加粒度。
我在FORWARD链的开头添加了以下规则。或者,您可以将 FORWARD 替换为 DOCKER。
由于这些规则,只有 IP 192.168.1.142 可以访问容器使用的 8080 端口。
对于那些访问此答案的人,如果您只想允许一个特定的 IP 地址访问容器,请使用Docker 文档中建议的 iptables 命令。
我认为添加这一行可以解决您的问题: