如何解决Python3.7 Docker镜像OpenSSL漏洞扫描未生效问题?
问题描述
我们尝试将Flask服务构建为Docker镜像,使用python:3.7作为基础镜像时出现大量漏洞,即使升级版本后问题仍存在。
复现步骤
基础Dockerfile:
FROM python:3.7 CMD ["sleep", "300"]
构建、标记及推送命令:
sudo docker build -t p37:basic-f ./Dockerfile . sudo docker tag p37:basic $DOCKER_LOGIN_URL/repo:p37_basic sudo docker push $DOCKER_LOGIN_URL/repo:p37_basic
将该镜像推送到AWS容器注册表后,扫描报告显示大量漏洞,例如CVE-2022-2097,该漏洞要求将OpenSSL升级至openssl 1.1.1q。本地运行镜像后发现当前安装的是OpenSSL 1.1.1n:
sudo docker run p37:basic & sudo docker container list # 输出: # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 77a25f41da01 p37:basic "sleep 6000" 15 seconds ago Up 14 seconds eager_black sudo docker exec -it 77a25f41da01 /bin/bash root@77a25f41da01:/# openssl version -a # 输出: # OpenSSL 1.1.1n 15 Mar 2022 # built on: Fri Jun 24 20:22:19 2022 UTC # platform: debian-amd64 # options: bn(64,64) rc4(16x,int) des(int) blowfish(ptr) # compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-qQYEec/openssl-1.1.1n=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2 # OPENSSLDIR: "/usr/lib/ssl" # ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-1.1" # Seeding source: os-specific
于是我们尝试在Docker镜像中通过源码编译升级OpenSSL,修改后的Dockerfile:
FROM python:3.7 RUN apt-get update RUN apt-get install software-properties-common --yes # 升级OPENSSL RUN apt-get update && \ apt-get install --yes --no-install-recommends wget build-essential libcurl4 && \ wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz && \ tar -xvf openssl-1.1.1q.tar.gz && cd openssl-1.1.1q && \ ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib && make && make install RUN echo "/usr/local/ssl/lib" >> /etc/ld.so.conf.d/openssl-1.1.1q.conf RUN cat /etc/ld.so.conf.d/openssl-1.1.1q.conf RUN ldconfig -v RUN mv /usr/bin/c_rehash /usr/bin/c_rehash.backup RUN mv /usr/bin/openssl /usr/bin/openssl.backup ENV PATH="${PATH}:/usr/local/ssl/bin" CMD ["sleep", "6000"]
本地运行该镜像并进入容器验证,确认已安装OpenSSL 1.1.1q:
sudo docker exec -it c3314b7efeea /bin/bash root@c3314b7efeea:/# openssl version -a # 输出: # OpenSSL 1.1.1q 5 Jul 2022 # built on: Fri Aug 5 17:26:11 2022 UTC # platform: linux-x86_64 # options: bn(64,64) rc4(16x,int) des(int) idea(int) blowfish(ptr) # compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -O3 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DZLIB -DNDEBUG # OPENSSLDIR: "/usr/local/ssl" # ENGINESDIR: "/usr/local/ssl/lib/engines-1.1" # Seeding source: os-specific
但将该镜像推送到AWS ECR或GCR后,扫描报告仍显示OpenSSL漏洞。请问为何修复未在扫描报告中生效?或有其他修复方案吗?
原因分析
- 扫描工具检测逻辑限制:AWS ECR、GCR这类容器扫描工具通常依赖系统包管理器(如
apt)的数据库来检测软件版本。通过源码编译安装的OpenSSL不会更新apt的包信息,工具仍会读取旧版本的包记录,判定漏洞未修复。 - 基础镜像遗留漏洞:
python:3.7基础镜像可能包含其他未更新的系统依赖,这些依赖也可能存在漏洞,扫描报告中的漏洞不一定全部来自OpenSSL。 - 扫描缓存未刷新:部分容器注册表的扫描服务可能存在缓存,即使镜像更新,也需要手动触发重新扫描才能获取最新结果。
解决方案
方案1:使用官方更新的基础镜像
优先选择官方维护的、已修复漏洞的python:3.7衍生镜像,比如:
- 使用
python:3.7-slim(精简版,漏洞更少)的最新版本,官方会定期更新基础系统包 - 直接升级到更高版本的Python(如
python:3.8及以上),这些版本的基础镜像通常包含更新的系统库
示例Dockerfile:
FROM python:3.7-slim # 安装Flask依赖 RUN pip install flask CMD ["flask", "run"]
方案2:通过apt直接升级OpenSSL
如果基础镜像的软件源中已有修复后的OpenSSL版本,直接通过apt升级,这样会更新包管理器的版本记录,扫描工具能识别到:
FROM python:3.7 RUN apt-get update && apt-get upgrade -y openssl libssl-dev # 后续安装Flask等依赖 CMD ["sleep", "6000"]
方案3:多阶段构建清理镜像
如果必须源码编译,使用多阶段构建分离编译环境和运行环境,减少镜像中的漏洞点,同时确保运行环境只包含必要文件:
# 第一阶段:编译OpenSSL FROM python:3.7 as builder RUN apt-get update && apt-get install --yes wget build-essential libcurl4 RUN wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz && \ tar -xvf openssl-1.1.1q.tar.gz && cd openssl-1.1.1q && \ ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib && make && make install # 第二阶段:构建运行镜像 FROM python:3.7 # 复制编译好的OpenSSL COPY --from=builder /usr/local/ssl /usr/local/ssl RUN echo "/usr/local/ssl/lib" >> /etc/ld.so.conf.d/openssl-1.1.1q.conf && ldconfig -v RUN mv /usr/bin/openssl /usr/bin/openssl.backup ENV PATH="${PATH}:/usr/local/ssl/bin" # 安装Flask依赖 RUN pip install flask CMD ["flask", "run"]
方案4:手动验证扫描结果
如果确认本地镜像已修复,可在容器注册表中手动触发重新扫描,或查看扫描报告的详细内容,确认漏洞对应的具体文件和版本,排除误报情况。
内容的提问来源于stack exchange,提问作者Nandha
相关产品推荐
相关产品推荐

