Dockerfile系列(四) 安全与最佳实践-生产环境不是游乐场
安全与最佳实践生产环境不是游乐场本文基于 Docker 24.x聚焦生产环境 Dockerfile 的安全红线与最佳实践。场景引入线上容器被入侵了去年组里出过一次安全事故测试环境的容器被人挖矿了CPU 飙到 100%。排查发现攻击者通过某个漏洞拿到了容器的 shell然后下载挖矿程序…为什么能拿到 shell因为容器跑的是root 用户而且镜像里自带了curl、wget攻击者想下载啥就下载啥。生产环境的 Dockerfile不是能跑就行得按安全标准来写。今天咱们把红线划清楚。安全实践 1绝不用 root 跑容器默认有多危险大部分基础镜像默认用 rootUID 0。如果容器被攻破攻击者在容器里是 root → 如果挂载了主机目录能读写主机文件Docker 漏洞逃逸时root 容器更容易拿到主机 root 权限正确姿势创建非 root 用户FROM node:18-alpine # 创建用户组和用户Alpine 用 addgroup/adduser RUN addgroup -g 1001 -S nodejs \ adduser -S nextjs -u 1001 WORKDIR /app COPY package*.json ./ RUN npm ci --onlyproduction COPY . . # 改文件所有者 RUN chown -R nextjs:nodejs /app # 切换到非 root 用户 USER nextjs EXPOSE 3000 CMD [npm, start]验证一下$dockerrun--rmmy-appiduid1001(nextjs)gid1001(nodejs)groups1001(nodejs)注意USER之后的所有指令都以该用户身份运行如果前面需要 root 权限如装系统包在USER之前做Kubernetes 里还可以加securityContext.runAsNonRoot: true双重保险安全实践 2选精简基础镜像镜像越小攻击面越小镜像类型大小适用场景风险ubuntu:latest~80MB通用工具多攻击面大node:18~180MB开发/构建包含编译工具node:18-alpine~50MB生产推荐精简工具少node:18-slim~70MB平衡选择比 alpine 兼容性好distroless~20MB极致安全无 shell难调试生产环境推荐# ✅ 推荐Alpine 或 Slim FROM node:18-alpine # 或者更安全的 Distroless需要多阶段构建 FROM gcr.io/distroless/nodejs18-debian12Alpine 的坑基于 musl libc某些原生模块可能不兼容。遇到诡异崩溃时换slim试试。安全实践 3敏感信息绝不硬编码错误示范千万别学# ❌ 错误密钥写死在 Dockerfile 里 ENV DATABASE_PASSWORDSuperSecret123! ENV API_KEYsk-live-abcdef123456 RUN curl -H Authorization: $API_KEY https://api.example.com/data问题密码永久留在镜像层里即使后面删掉也能通过docker history看到镜像推送到仓库密码跟着走任何人docker inspect都能看到环境变量正确做法构建时参数不敏感或临时ARG BUILD_VERSIONlatest LABEL version${BUILD_VERSION}运行时注入敏感信息# 启动时传入dockerrun-eDATABASE_PASSWORDsecretmy-app# 或用 Docker SecretSwarm/Kubernetes 更好dockerrun--secretdb_password my-app代码里读取// Node.jsconstdbPassprocess.env.DATABASE_PASSWORD;if(!dbPass){thrownewError(DATABASE_PASSWORD is required);}安全实践 4.dockerignore 是你的守门员不设置.dockerignoreCOPY . .会把啥都塞进去.git/ # 整个 git 历史 node_modules/ # 本地依赖可能含平台相关二进制 .env # 本地环境变量 *.pem # 证书密钥 Dockerfile # 自己 .dockerignore # 自己 dist/ # 构建产物如果多阶段不需要标准 .dockerignore 模板# 依赖镜像里会重新装 node_modules/ vendor/ # 构建产物 dist/ build/ target/ *.exe *.dll # 环境文件含敏感信息 .env .env.local .env.*.local # 版本控制 .git/ .gitignore .gitattributes # 编辑器 .idea/ .vscode/ *.swp *.swo # 测试 coverage/ *.test.js __tests__/ # 文档和配置不需要进镜像 README.md CHANGELOG.md Dockerfile* docker-compose*.yml .dockerignore # 日志 *.log logs/ # 证书密钥 *.pem *.key *.crt安全实践 5健康检查与资源限制HEALTHCHECK让 Docker 知道你的服务还活着FROM node:18-alpine # ... 其他指令 ... # 每 30 秒检查一次超时 3 秒失败 3 次认为不健康 HEALTHCHECK --interval30s --timeout3s --start-period5s --retries3 \ CMD node healthcheck.js || exit 1 CMD [npm, start]// healthcheck.jsconsthttprequire(http);constoptions{hostname:localhost,port:3000,path:/health,method:GET,timeout:2000};constreqhttp.request(options,(res){process.exit(res.statusCode200?0:1);});req.on(error,()process.exit(1));req.end();运行时资源限制docker run# 限制 CPU 和内存dockerrun\--memory512m\--memory-swap512m\--cpus1.0\--pids-limit1000\--read-only\--security-optno-new-privileges:true\my-app参数作用--read-only根文件系统只读--no-new-privileges禁止提升权限--pids-limit限制进程数防 fork 炸弹安全实践 6镜像扫描构建完扫一遍看看有没有已知漏洞# Docker 内置扫描需要登录 Docker Hubdockerscan my-app# 更推荐 Trivy开源速度快trivy image my-app# 或 Snyksnyk containertestmy-app扫描报告会列出 CVE 漏洞按严重度分级。生产镜像应该零高危漏洞。一句话总结生产级 Dockerfile 的安全三板斧非 root 用户、精简镜像、敏感信息外置——再配合.dockerignore守门和镜像扫描兜底才能把攻击面压到最小。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2555836.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!