当前位置: 首页 > news >正文

Jenkins - CICD 注入环境变量避免明文密码暴露

Jenkins - CICD 注入环境变量避免明文密码暴露

  • 🔧 Jenkins 注入环境变量的方式
    • 在 Job 配置里直接写环境变量,代码中可通过环境变量访问
    • 使用 Jenkins Credentials 插件(推荐)
    • 通过 withEnv 临时注入
    • ✅ 对比总结
  • 示例:从 Jenkins Credentials 到 Pipeline 再到代码访问环境变量的全过程
    • 场景说明
    • 1️⃣ Jenkinsfile 示例
    • 2️⃣ Python 代码(app.py)
    • 3️⃣ 工作流程

上篇《 Pyhon - 环境变量本地开发方案避免明文密码暴露在代码里》介绍了本地开发方案将明文密码注入环境变量,但实际线上测试和生产环境,CICD 该如何注入明文密码,避免安全问题呢。

🔧 Jenkins 注入环境变量的方式

在 Jenkins 里,环境变量是最常用的方式来传递密码、API Key、数据库连接信息等敏感配置。

在 Job 配置里直接写环境变量,代码中可通过环境变量访问

Freestyle Job GUI 配置

  • 进入 Job → Configure → Build Environment

  • 勾选 Inject environment variables to the build process

  • 手动添加环境变量:

    DB_HOST=127.0.0.1
    DB_USER=myuser
    

    在这里插入图片描述

  • 在 Pipeline 脚本里可以直接用:

    echo "DB user is ${env.DB_USER}"
    

Pipeline Job 里是没有 GUI 勾选的,所有环境变量都要在 Jenkinsfile 里配置

pipeline {agent anyenvironment {DB_USER = 'myuser'}stages {stage('Show env') {steps {sh 'echo "Key: $DB_USER"'}}}}

⚠️ 缺点:敏感信息容易暴露,不推荐存密码。

使用 Jenkins Credentials 插件(推荐)

👉 如果将敏感信息直接写在代码或 Jenkinsfile 里会有安全隐患,因此推荐通过 Credentials 插件来管理。这是安全管理敏感信息(密码、API Key)的最佳方式。
步骤:

  • 添加 Credentials 的位置, 在 Jenkins 界面:

    • 进入 Dashboard → Manage Jenkins → Credentials
    • 选择 系统(System) → 全局凭据(Global credentials)
    • 点击 Add Credentials 添加新的凭据
  • 尝见的凭据类型

    类型用途配置项
    Username with password需要用户名 + 密码的场景(DB、Git、FTP、Docker Registry)用户名、密码
    Secret text单个敏感值(API Key、Token、Password)Secret
    SSH Username with private key通过 SSH 连接服务器、Git 仓库用户名、私钥
    Secret file整个敏感文件(如 kubeconfig、JSON Key)上传文件
    CertificateSSL 证书、PKCS#12 格式证书上传证书文件、密码
  • 方式一:用 bash command 来加载这些 Credentials,以便 code 中通过环境变量来访问
    示例 GUI 上配置 credentia file 绑定,定义变量 API_KEY_FILE
    在这里插入图片描述
    shell 脚本里导出 credentia,以便 app.py 通过环境变量来访问 credential 文件中配置的变量

    echo "Credential temp file path is: $API_KEY_FILE"
    export $(grep -v '^#' "$API_KEY_FILE" | xargs)
    python3 -c "import os; print(os.getenv('DEV_CAAS_DL_API_KEY'))"
    echo "export credential end"
    python3 app.py
    

    ⚠️ 注意:这种方式注入只在当前会话时有效,也就是说在其他 bash 会话中是无效,需要访问到这些环境变量就加载

  • 方式二:在 jenkinsfile 中加载这些 Credentials, 以便 code 中通过环境变量来访问:

    • 使用 withCredentials
      示例:数据库用户名/密码
      withCredentials([usernamePassword(credentialsId: 'db-creds', usernameVariable: 'DB_USER', passwordVariable: 'DB_PASS')]) {sh '''echo "Database user: $DB_USER"# echo "Password: $DB_PASS"  # 切勿打印密码!'''}
      
      示例:Secret Text
      		withCredentials([string(credentialsId: 'api-key', variable: 'API_KEY')]) {sh 'curl -H "Authorization: Bearer $API_KEY" https://api.example.com'
      }
      
      示例:SSH Key
      		withCredentials([sshUserPrivateKey(credentialsId: 'ssh-key', keyFileVariable: 'SSH_KEY_FILE', usernameVariable: 'SSH_USER')]) {sh 'ssh -i $SSH_KEY_FILE $SSH_USER@server.example.com'
      }
      
      示例:Secret file,创建了一个上传了 .env 文件的 credential id 为 api_key_file
      工作机制
      • withCredentials([file(…)]) → Jenkins 把 .env Secret file 下载到一个临时路径,并写到 $SECRET_FILE 变量里。
      • source $SECRET_FILE → 加载 .env 内容到 shell。
      • 用 set -o allexport / set +o allexport 确保 .env 文件里的 KEY=value 都会自动 export。
      • 这样 .env 配置 DEV_CAAS_DL_API_KEY 就能被后续的 shell、Python 程序读取。
        ⚠️ 注意:
      • 如果 jenkins 执行 shell 时默认用的是 /bin/sh,就用 . “$SECRET_FILE”
      • 如果 jenkins 执行 shell 时默认用的是 /bin/bash, 就用 source $SECRET_FILE
      	withCredentials([file(credentialsId: 'api_key_file', variable: 'SECRET_FILE')]) {sh '''set -o allexport. "$SECRET_FILE"set +o allexportecho "test DEV_API_KEY=$DEV_API_KEY"'''
      }
      

    这样,密码不会出现在 Job 配置和日志里,安全性高。

通过 withEnv 临时注入

如果需要在某个阶段设置环境变量,可以用 withEnv:

pipeline {agent anystages {stage('Deploy') {steps {withEnv(["APP_ENV=production", "DB_HOST=10.0.0.1"]) {sh 'echo "Environment: $APP_ENV, Host: $DB_HOST"'}}}}
}

好处:只在这个 stage 有效,不会污染全局。

✅ 对比总结

方式适用场景优点缺点
Job 配置里写变量非敏感配置简单密码不安全
Credentials 插件敏感信息(推荐)安全、审计J需要额外配置
withEnv临时变量控制作用域只适合少量变量

示例:从 Jenkins Credentials 到 Pipeline 再到代码访问环境变量的全过程

场景说明

  • 创建 Jenkins Credentials:
    • 类型:Secret file
    • ID:api_key_file
    • 文件内容(.env 格式):
      	DEV_API_KEY=abc123DEV_API_USER=adminDEV_DB_PASS=super-secret
      
  • 目标:
    • 在 Jenkinsfile 中安全加载 .env 文件
    • 在 Python 代码里通过 os.getenv 访问环境变量
    • 不在日志中泄露敏感信息

1️⃣ Jenkinsfile 示例

pipeline {agent anystages {stage('Load Secret File') {steps {// 使用 Jenkins Credentials 拉取 secret filewithCredentials([file(credentialsId: 'api_key_file', variable: 'SECRET_FILE')]) {sh '''#!/bin/shecho "Loading secret file from $SECRET_FILE"# 把 .env 文件里的变量导入当前 shell 环境set -o allexport. "$SECRET_FILE"set +o allexport# 验证(生产环境不要打印敏感信息)echo "DB_USER=$DEV_DB_USER"# 运行 Python 程序python3 app.py'''}}}}
}

⚠️ 注意:

  • 在 /bin/sh 中没有 source 命令,所以用 . 替代
  • set -o allexport 可以确保 .env 文件里的 KEY=value 全部被 export

2️⃣ Python 代码(app.py)

import osapi_key = os.getenv("DEV_CAAS_DL_API_KEY")
db_user = os.getenv("DEV_CAAS_DL_DB_USER")
db_pass = os.getenv("DEV_CAAS_DL_DB_PASS")print("API Key:", api_key)
print("DB User:", db_user)
# 千万不要打印 db_pass

3️⃣ 工作流程

  • Jenkins Pipeline 执行 withCredentials([file(…)]),把 .env secret file 下载到临时路径 $SECRET_FILE
  • Shell 脚本用 . 和 set -o allexport 把 .env 变量导入环境
  • Python 里直接通过 os.getenv 访问环境变量
  • Pipeline 结束后,Jenkins 会自动删除临时文件,保证安全
  • 这样,你的 敏感信息不会硬编码在代码或 Jenkinsfile 中,也不会在日志中直接泄露,同时代码可以正常访问环境变量。
http://www.dtcms.com/a/336306.html

相关文章:

  • 用MTEB对Embedding模型进行benchmark
  • Pell数列
  • 基本的设计原则
  • SONiC (4) - redis的介绍以及应用
  • 远程协作绘图:借助 cpolar 内网穿透服务访问 Excalidraw
  • 用PaddleDetection套件训练自己的数据集,PP-YOLO-SOD训练全流程
  • 领域快速入门过程记录之--电力网络
  • ROS常用命令手册
  • # C++ 中的 `string_view` 和 `span`:现代安全视图指南
  • GaussDB常用术语缩写及释义
  • 【Linux】IO多路复用
  • nodejs 错误处理
  • Shell脚本-条件判断相关参数
  • 任务型Agent架构简介
  • JUC并发编程04 - 同步/syn-ed(01)
  • prototype 和 _ _ proto _ _的关联
  • 计算机网络 OSI 七层模型和 TCP 五层模型
  • 【Linux系列】如何在 Linux 服务器上快速获取公网
  • 遥感数据介绍——MODIS、VIIRS、Sentinel-2
  • 飞算JavaAI结合Redis实现高性能存储:从数据瓶颈到极速读写的实战之旅
  • 三种变量类型在局部与全局作用域的区别
  • 大模型算法岗面试准备经验分享
  • 【Linux网络编程】NAT、代理服务、内网穿透
  • css中 hsl() 的用法
  • Java-I18n
  • 43 C++ STL模板库12-容器4-容器适配器-堆栈(stack)
  • 百度笔试编程题 选数
  • PWM控制LED亮度:用户态驱动开发详解
  • Soundraw - 你的AI音乐生成器
  • 51单片机-驱动静态数码管和动态数码管模块