firewalld防火墙阻止docker容器间通信的排查思路及解决方案

news/2024/11/28 10:27:01/

摘要

现有两个docker容器nginx、openjdk分别部署前后端服务,假设默认防火墙为firewalld,发现在默认配置下,本地直接curl后台服务器能正确响应,nginx的代理的请求proxy_pass无法得到后台服务器的响应,只得到502 BadGateway

排查

关闭防火墙

首先怀疑是防火墙的问题,临时关闭防火墙试试:
systemctl stop firewalld
重新用nginx发起代理连接,发现nginx容器能向java容器通信了,看来是防火墙组织了两个容器的网络访问,先恢复防火墙再继续排查
systemctl start firewalld

查询防火墙拦截日志

查看firewalld拦截日志,注意,firewalld服务默认关闭所有类型的被拒绝访问的日志记录,即

>>>firewall-cmd --get-log-denied 
>>>off
# 其中denied参数
# all: 表示记录所有被拒绝的访问,无论是单播、组播还是广播。
# unicast: 表示记录被拒绝的单播访问。
# broadcast: 表示记录被拒绝的广播访问。
# multicast: 表示记录被拒绝的组播访问。
# off: 表示关闭所有类型的被拒绝访问的日志记录。

需要在/etc/firewalld/firewalld.conf 文件中修改设置
LogDenied=all
或者输入命令
firewall-cmd --set-log-denied=all --permanent
无论哪种方法,最后都要重启服务使配置生效
firewall-cmd --reload
拦截日志在/var/log/message 中,使用tail跟踪日志输出
tail -f /var/log/messages
再测试一次便可以看到连接被拦截的原因了:

"filter_IN_public_REJECT: "
IN=docker0 OUT= 
PHYSIN=veth3050f50 MAC=02:42:56:73:8c:b3:02:42:ac:11:00:02:08:00 
SRC=172.17.0.2 DST=192.168.174.132 
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=28276 DF 
PROTO=TCP SPT=58746 DPT=11260 WINDOW=64240 RES=0x00 SYN URGP=0 

日志的详细解释如下:

  • filter_IN_public_REJECT: 这部分表示这是一个在filter表、IN_public链上的规则触发的拒绝(REJECT)动作。filter表是iptables默认的表,用于决定如何处理进入的数据包;IN_public链可能是用户自定义的链,用于处理进入公共接口的数据包。

  • IN=docker0 OUT= PHYSIN=veth3050f50:IN=docker0表示数据包是从名为docker0的网络接口进入的,这是Docker默认的虚拟网桥。OUT=表示数据包没有从这个方向出去(因为是入站规则)。PHYSIN=veth3050f50表示物理入站接口是veth3050f50,这是一个虚拟以太网接口,通常用于Docker容器docker0网桥之间的通信。

  • MAC=02:42:56:73:8c:b3:02:42:ac:11:00:02:这部分显示了数据包的源MAC地址和目标MAC地址。源MAC地址是02:42:56:73:8c:b3(可能是Docker容器的MAC地址),目标MAC地址是02:42:ac:11:00:02(属于docker0网桥上的另一个设备)。

  • SRC=172.17.0.2 DST=192.168.174.132:SRC是源IP地址,DST是目标IP地址。这里表示数据包是从IP地址172.17.0.2(Docker容器内的一个IP)发送到192.168.174.132(可能是宿主机的另一个IP或网络上的其他设备)。

  • LEN=60:数据包长度是60字节。

  • TOS=0x00 PREC=0x00:服务类型(Type of Service, TOS)和优先级(Precedence, PREC)都是0,表示没有特殊的服务类型或优先级要求。

  • TTL=64:生存时间(Time To Live, TTL)是64,表示数据包在网络中可以经过的最大路由器数量。

  • ID=36194 DF:数据包ID是36194,DF(Don’t Fragment)标志设置为1,表示数据包不应该被分片。

  • PROTO=TCP:协议是TCP(传输控制协议)。

  • SPT=58696 DPT=11260:源端口(Source Port, SPT)是58696,目标端口(Destination Port, DPT)是11260。

  • WINDOW=64240 RES=0x00 SYN URGP=0:TCP窗口大小是64240字节,保留字段(RES)是0,SYN标志位设置为1表示这是一个TCP连接建立的请求(三次握手的第一步),紧急指针(Urgent Pointer, URGP)是0。

综上所述,这条日志表示一个从Docker容器(IP地址为172.17.0.2)尝试建立到IP地址为192.168.174.132的TCP连接(端口11260)的数据包被防火墙规则拒绝。

排查小结

由上可知,但容器中发出的请求仍然视为外界的连接,它具有独立的ip地址172.17.0.2和MAC地址02:42:56:73:8c:b3,数据包进入的网络接口是 docker0等,所以,需要根据这些信息为docker定制安全策略,使外来连接不能访问而仅让docker可以访问。但实际操作上是不好定制的,规则太严会导致在大量容器的部署过程出现”误杀“,规则太松有可能有安全隐患。

解决思路

方法1:关闭防火墙(不推荐)

systemctl stop firewalld && systemctl disable firewalld

方法2: 暴露端口(不推荐)

firewall-cmd --add-port xx/tcp --permanent && firewall-cmd --reload

docker17217001611260_71">方法3: 给docker的源地址172.17.0.0/16的开放11260端口,隔离其他网段的访问,注意,这个策略简单粗暴,本质上是对特定网段暴露了特定端口,可以基于源地址、目标地址和端口做更详细的安全策略。


firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="172.17.0.0/16" port port="11260" protocol="tcp" accept' --permanentfirewall-cmd --reload

docker_79">方法4: 开放zone区域给docker访问

在步骤三的基础上限制网络接口为docker0的才能访问,进一步提高安全性
先删除步骤3的配置:

firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="172.17.0.0/16" port port="11260" protocol="tcp" accept' --permanent

再采用新配置

  • 创建了一个名为 docker 的新防火墙区域
    firewall-cmd --new-zone=docker --permanent
  • docker0 接口分配给了 docker 区域。docker0 是 Docker 默认的虚拟网桥接口,用于容器之间的通信。
    firewall-cmd --zone=docker --add-interface=docker0 --permanent
  • docker 区域的默认目标策略设置为 DROP,意味着默认情况下会丢弃所有进入该区域的流量。这是一种非常严格的安全策略
    firewall-cmd --zone=docker --set-target=DROP --permanent
  • 添加了一条富规则,允许来自 IPv4 地址范围 172.17.0.0/16 的 TCP 流量,如果目标端口是 1125,则接受这些流量。这个规则覆盖了区域的默认 DROP 策略,仅对符合条件的流量开放。
    firewall-cmd --zone=docker --add-rich-rule='rule family="ipv4" source address="172.17.0.0/16" port port="1125" protocol="tcp" accept' --permanent
  • 重新加载 firewalld 配置以使更改生效
    firewall-cmd --reload

这些设置将影响所有通过 docker0 接口的流量,包括 Docker 容器之间的通信以及从外部网络到容器的流量(如果外部网络能够访问到 docker0 接口)。由于将默认策略设置为 DROP,并且只添加了一条非常具体的允许规则,因此需要确保这条规则涵盖了所有需要允许的流量,否则可能会导致意外的连接问题

小结

总之,四个思路安全性由低到高,然而越严格的策略越容易”误杀“,本人能力有限,在这里提出自己的思路,可根据对服务配置的理解设置更高效的安全策略。


http://www.ppmy.cn/news/1550593.html

相关文章

[产品管理-156]:《领先的密码-BLM方法论全面解读与应用指南》- 全书概述

目录 前言: 一、BLM方法论概述 二、BLM方法论的核心要素 三、BLM方法论的应用指南 四、BLM方法论的实际应用案例 五、总结 前言: “领先的密码:BLM方法论全面解读与应用指南”这一主题涉及对Business Leadership Model(业务…

DataWhale—PumpkinBook(TASK06神经网络)

课程开源地址及相关视频链接:(当然这里也希望大家支持一下正版西瓜书和南瓜书图书,支持文睿、秦州等等致力于开源生态建设的大佬✿✿ヽ(▽)ノ✿) Datawhale-学用 AI,从此开始 【吃瓜教程】《机器学习公式详解》(南瓜…

探索 Python 任务自动化的新境界:Invoke 库揭秘

文章目录 探索 Python 任务自动化的新境界:Invoke 库揭秘背景:为何选择 Invoke?什么是 Invoke?如何安装 Invoke?5个简单的库函数使用方法1. 定义任务2. 带参数的任务3. 运行 Shell 命令4. 任务参数化5. 列出任务 场景应…

【竞技宝】LOL-传奇杯:KB3-1击败M3

北京时间2024年11月27日,英雄联盟第二届传奇杯正在如火如荼的进行之中。昨天首场比赛迎来胜者组首轮KB(leyan队)对阵M3(icon队)。本场比赛M3以出色的表现拿下首局之后被KB打出完美运营连追两局,最后一局更是在大优势的情况下接连出现失误被KB翻盘,最终KB3-1击败M3。以下是本场比…

去哪儿大数据面试题及参考答案

Hadoop 工作原理是什么? Hadoop 是一个开源的分布式计算框架,主要由 HDFS(Hadoop 分布式文件系统)和 MapReduce 计算模型两部分组成 。 HDFS 工作原理 HDFS 采用主从架构,有一个 NameNode 和多个 DataNode。NameNode 负责管理文件系统的命名空间,维护文件和目录的元数据信…

设计模式之 迭代器模式

迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种顺序访问聚合对象元素的方法,而又不暴露该对象的内部表示。简单来说,迭代器模式的目的是将集合对象(例如列表、数组等)的遍历过…

Mongodb入门到放弃

Mongodb分片概括 分片在多台服务器上分布数据的方法, Mongodb使用分片来支持具有非常大的数据集和高吞吐量的操作的部署 具有大数据集和高吞吐量应用程序的数据库系统,可以挑战单台服务器的容量。 例如,高查询率可以耗尽服务器的cpu容量&…

docker-compose文件的简介及使用

Docker Compose是Docker官方的开源项目,主要用于定义和运行多容器Docker应用。以下是对Docker Compose的详细介绍: 一、主要功能: 容器编排:Docker Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML格…