- 网络安全
- 应用安全
- CLI
- 漏洞扫描
【免费下载链接】testssl.sh
Testing TLS/SSL encryption anywhere on any port
导读
本文以仓库根目录下的 Dockerfile.md 为骨架,结合 Dockerfile、Dockerfile.alpine 与 .dockerignore 的源码细节,系统讲解 testssl.sh 官方容器镜像的两种用法:直接拉取官方镜像运行 TLS/SSL 检测,以及基于 openSUSE Leap / Alpine 两种基础镜像自行构建。读完本文,你将掌握容器内输出文件的落盘与权限处理、镜像标签选择、本地与远程两种构建方式,以及镜像内部的多阶段构建原理,可直接把这些命令用于自己的扫描与 CI 场景。
一、为什么用容器运行 testssl.sh
testssl.sh 是一个纯 bash 编写的 TLS/SSL 检测工具,按 Readme.md 的描述,它本身"依赖极少、无需安装任何东西,clone 下来即可运行"。但在以下场景中,容器化是更优选择:
- 不想在宿主机上保留源码目录或安装依赖;
- 需要在 CI/CD 流水线里做一次性、可复用的 TLS 基线检测;
- 需要在不同平台上获得一致的 OpenSSL 版本与检测行为。
官方镜像的入口(ENTRYPOINT)已经直接设置为testssl.sh,因此使用体验和直接执行命令别无二致。
二、快速开始:一条命令完成 TLS 检测
最简单的方式是直接拉取官方镜像运行,把testssl.sh的命令行参数追加在镜像名之后:
docker run --rm -it ghcr.io/testssl/testssl.sh:3.2 github.com几点说明:
- 镜像的 ENTRYPOINT 已设为
testssl.sh,所以上面命令等价于在容器内执行testssl.sh github.com; - 若不带任何参数,容器默认执行
testssl.sh --help(对应 Dockerfile 与 Dockerfile.alpine 中的CMD ["--help"]); --rm让容器退出后自动清理,-it提供交互式终端以便实时查看扫描输出。
三、输出文件与数据导出:卷挂载实战
3.1 输出文件默认落在容器内
需要特别留意:--log、--html、--json、--csv等所有输出文件默认生成在容器内部的文件系统里,容器一旦删除,数据也随之消失。从 testssl.sh 的源码可以看到默认命名规则统一为${NODE}-p${port}${YYYYMMDD-HHMM}.log(同理还有.html、.json、.csv),即"主机名-端口-日期时间"格式。
3.2 用 bind mount + --workdir 把结果写到宿主机
官方推荐的做法是:挂载宿主机目录为卷,并设置容器的--workdir,这样输出参数可以直接使用相对路径:
# Writes the HTML output to the host path: /tmp/example.com_p443-<date>-<time>.html docker run --rm -it -v /tmp:/data --workdir /data ghcr.io/testssl/testssl.sh:3.2 --htmlfile ./ example.com拆解这条命令:
| 参数 | 作用 |
|---|---|
-v /tmp:/data | 将宿主机/tmp挂载为容器内/data卷 |
--workdir /data | 将容器工作目录设为/data,相对路径的落点 |
--htmlfile ./ | 输出目录参数(-oH的等价长选项),.即当前工作目录 |
同样的套路可套用到--logfile(-oL)、--jsonfile(-oj)、--csvfile(-oC)等所有输出参数上。
3.3 文件所有权与权限陷阱
- 容器内以非 root 用户
testssl(UID/GID 均为1000)运行,因此写入卷的文件属主是1000:1000,权限为644; - 宿主机挂载目录必须允许
1000这个 UID/GID(或对应组)写入,否则会报权限错误; - 如果不想处理卷权限,官方也给出了替代方案:不挂卷,容器退出后用
docker cp把文件拷出来。
四、镜像来源与可用标签
官方镜像同时发布到两个容器仓库:
- DockerHub:
drwetter/testssl.sh - GHCR(GitHub Container Registry):
ghcr.io/testssl/testssl.sh
当前支持的标签为:
3.2(对应 3.2 稳定版)latest(跟随最新发布)
按 Readme.md 的说明,GHCR 支持更多平台(linux/amd64、linux/386、linux/arm64、linux/arm/v7、linux/arm/v6、linux/ppc64le),在有跨平台拉取需求时优先选用 GHCR 地址。
五、本地构建:git clone + docker build
如果需要自己构建镜像(例如出于供应链审计、离线部署或自定义镜像内容的考虑),标准流程是 clone 源码后在仓库根目录执行构建:
mkdir /tmp/testssl && cd /tmp/testssl git clone --branch 3.2 --depth 1 https://github.com/testssl/testssl.sh . docker build --tag localhost/testssl.sh:3.2 .给镜像打上本地 tag(示例中的localhost/testssl.sh:3.2)便于后续引用。
5.1 两种官方基础镜像的选择
构建时支持两种基础镜像,它们在 Dockerfile 与 Dockerfile.alpine 中分别实现:
| 变体 | 基础镜像 | libc | 特点 |
|---|---|---|---|
| 默认 | openSUSE Leap(glibc) | glibc | 性能更快,约 54MB(本地构建) |
| Alpine | Alpine(musl) | musl | 体积约小一半,约 27MB(本地构建),平台支持更广,性能略慢 |
官方说明 Alpine 变体的体积大约比 Leap 变体小 30MB,代价是略微的性能下降;当需要更广的平台支持或对镜像体积敏感(如边缘设备、嵌入式环境)时选择 Alpine。
六、远程构建:一条命令从 Git 仓库直接构建
6.1 远程构建上下文
不必先 clone,可以直接用 Git 仓库地址作为构建上下文:
docker build --tag localhost/testssl.sh:3.2 https://github.com/testssl/testssl.sh.git#3.2#3.2指定要检出的分支或 tag。需要知晓的代价是:远程构建上下文不支持.dockerignore,无法过滤多余文件,因此产物镜像会比本地构建略大。
6.2 远程构建 Alpine 变体
构建 Alpine 版本时,额外用--file指定远程的Dockerfile.alpine:
docker build \ --tag localhost/testssl.sh:3.2-alpine \ --file https://raw.githubusercontent.com/testssl/testssl.sh/3.2/Dockerfile.alpine \ https://github.com/testssl/testssl.sh.git#3.2七、镜像内部原理:从 Dockerfile 源码看实现
7.1 openSUSE Leap 变体的多阶段构建
Dockerfile 采用三阶段结构:
builder阶段:基于opensuse/leap:15.6,用zypper将运行所需包安装到自定义的${INSTALL_ROOT}根目录,包列表为bash procps grep gawk sed coreutils busybox ldns libidn2-0 socat openssl curl。构建时还会移除openh264与non-oss仓库以缩短同步时间,并在最后清理/usr/share/{licenses,man,locale,doc,help,info}、termcap和 RPM 数据库,回收约 13MiB 空间。base-leap阶段:FROM scratch之上,把 builder 阶段安装好的根文件系统整体COPY进来,并完成三项关键配置:- 为
busybox手工创建tar、hexdump、xxd三个命令的符号链接(Leap 的 busybox 包不支持busybox --install -s); - 手工向
/etc/passwd、/etc/group、/etc/shadow追加条目创建非 root 用户testssl(UID/GID1000),等价于useradd --uid 1000 --user-group --create-home --shell /bin/bash testssl; - 将
/home/testssl/testssl.sh符号链接到/usr/local/bin/testssl.sh,使它成为 PATH 中的命令。
- 为
- 最终阶段二选一(默认取最后一个
dist-local):dist-git:通过ADD从远程 Git 仓库克隆项目文件到/home/testssl,产物约62MB(无法用.dockerignore过滤内容);dist-local:用COPY把本地构建上下文复制到/home/testssl,产物约54MB(可享受.dockerignore过滤)。
最后统一设置USER testssl、ENTRYPOINT ["testssl.sh"]、CMD ["--help"]。
7.2 Alpine 变体的差异
Dockerfile.alpine 结构类似但更精简:基于alpine:3.21,apk add安装bash procps drill coreutils libidn curl socat openssl xxd(用drill提供 DNS 查询能力),同样手工创建testssl用户与命令符号链接;最终镜像体积为dist-git35MB、dist-local27MB。
7.3 .dockerignore 与构建上下文裁剪
.dockerignore 的规则解释了两种最终阶段的大小差异:
# Exclude everything from the Docker build context: * # Except for this content: !bin/ !etc/ !testssl.sh # But additionally exclude this nested content: bin/openssl.Darwin.* bin/openssl.FreeBSD.*即本地构建时只把bin/、etc/和主脚本testssl.sh送入构建上下文,并排除 macOS/FreeBSD 平台的 OpenSSL 二进制,从而大幅缩小上下文与镜像体积。这同时印证了远程构建镜像更大的原因——远程上下文不受这些规则约束。
八、实践建议与注意事项
- 版本选择:生产环境建议锁定
3.2标签而非latest,保证行为可复现; - 数据落盘:凡是需要保留的
--log/--html/--json/--csv结果,务必配合-v卷挂载 +--workdir使用,或事后用docker cp取出; - 权限规划:挂载目录需提前放开
1000:1000的写权限,或改用docker cp规避; - 镜像体积:对体积敏感时选 Alpine 变体,对扫描性能敏感时选 openSUSE Leap 变体;
- 审计与离线:可结合 Readme.md 中的"clone 即用"模式,把镜像构建纳入自己的版本管理流水线,实现完全可控的供应链。
综合来看,官方容器镜像把 testssl.sh 变成了一个即插即用的"TLS 扫描命令",无论是单次交互扫描还是自动化流水线,都可以围绕上文给出的卷挂载、构建与标签策略快速落地。
- 网络安全
- 应用安全
- CLI
- 漏洞扫描
【免费下载链接】testssl.sh
Testing TLS/SSL encryption anywhere on any port
相关推荐
Apache Pulsar Docker 镜像实战:官方镜像体系、非 root 安全运行与自定义镜像构建
Apache Pulsar Docker 镜像实战:官方镜像体系、非 root 安全运行与自定义镜像构建 Apache Pulsar 社区在每个官方版本发布时都
消息队列后端流处理MXNet Docker 镜像使用与构建指南:从官方预编译镜像到自定义构建
MXNet Docker 镜像使用与构建指南:从官方预编译镜像到自定义构建 本篇技术指南围绕 MXNet 官方仓库中的 Docker 支撑体系展开,系统讲解如何
深度学习人工智能机器学习分布式训练Glances Docker 镜像构建、运行与安全扫描实战指南
Glances Docker 镜像构建、运行与安全扫描实战指南 Glances 是一个跨平台(GNU/Linux、BSD、macOS、Windows)的系统监控
指标监控监控大盘CLI告警MCP 服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考