📑 课程信息
- 领域:Python与Linux环境下的敏感信息安全管理

知识精讲
本课程由拥有20年Cisco认证讲师经验的专家授课,系统讲解了软件开发中避免将敏感参数硬编码进代码的4种主流解决方案,覆盖Python标准库、Linux命令行工具、Ansible Vault与HashiCorp Vault两类专业密钥管理工具,帮助开发者在不同场景下安全存储与调用凭证、IP地址等敏感配置。
课程整体框架与学习目标
-
课程核心背景:软件开发过程中,直接将凭证、主机名、IP地址等敏感安全参数写入代码存在极大安全隐患,本课程提供4种标准化方法在Python与Linux环境下安全管理这类敏感数据。
-
四大核心学习模块:ConfigParser Python模块、Linux环境变量、Python命令行参数、Ansible与HashiCorp两款专业Vault应用。
- 🚩重点:课程配套包含视频、示意图、复习题与实操实验,覆盖软件开发者与网络自动化工程师两类人群的核心技能需求。
ConfigParser Python标准库模块
-
模块基础特性 :ConfigParser是Python标准库内置模块,无需从PyPI等第三方仓库安装,专门用于解析类INI格式的配置文件,配置文件以方括号标识不同section,内部存储
key=value格式的配置项。-
🚩重点:section名称区分大小写,配置项名称(option)不区分大小写;DEFAULT section中的所有配置项会自动继承到其他所有section中。
-
INI配置文件示例:
[DEFAULT]
username = cisco
password = 12345Qwer
port = 22[server_a]
ip_address = 10.254.0.10[server_b]
ip_address = 10.254.0.20[switch]
password = 1234QWer*
ip_address = 10.254.0.100
port = 23
-
-
三种配置数据解析方式 :支持从本地INI文件、多行字符串、Python字典三类数据源加载配置,分别对应
read()、read_string()、read_dict()方法。-
代码示例:
import configparser
1. 从本地INI文件读取
file_config = configparser.ConfigParser()
file_config.read('access_info.ini')2. 从多行字符串读取
string_config = configparser.ConfigParser()
config_example = """
[DEFAULT]
username = cisco
password = 1234QWer
[server]
ip_address = 10.254.0.10
"""
string_config.read_string(config_example)3. 从Python字典读取
dict_config = configparser.ConfigParser()
dict_config.read_dict({
"DEFAULT": {"username": "cisco", "password": "1234QWer"},
"server": {"ip_address": "10.254.0.10"}
})
-
-
配置值访问与校验方法:ConfigParser对象的访问逻辑与Python嵌套字典完全一致,同时提供了一系列内置校验方法实现防御式编程,避免因配置缺失导致程序异常。
-
🚩重点:访问section时返回的section proxy对象并非原生字典,对该对象的所有修改会直接同步到原始ConfigParser实例中。
-
常用校验与访问代码示例:
import configparser
config = configparser.ConfigParser()
config.read('access_info.ini')字典式访问
config['server_a']['username']
config['switch']['password']内置校验方法
config.sections() # 返回所有非DEFAULT的section列表
config.has_section('server_a') # 检查section是否存在
config.defaults() # 返回DEFAULT section的字典
config.options('server_a') # 返回指定section下的所有配置项
config.items('server_a') # 返回指定section下所有键值对元组
config.has_option('server_a', 'password') # 检查指定配置项是否存在
config.get('server_a', 'password') # 安全获取配置值
-
-
配置项修改、删除与持久化 :支持动态修改配置内容、删除指定配置项或整个section,最终通过
write()方法将修改后的配置持久化到本地文件。-
🚩重点:使用
remove_option()方法删除DEFAULT section中的配置项时,仅会移除DEFAULT内的该配置,不会同步删除其他继承该配置的section中的对应值。 -
代码示例:
删除指定配置项
config.remove_option('server_b', 'ip_address')
删除整个section
config.remove_section('server_b')
将修改后的配置写入新文件
with open('server_access_modified.ini', 'w') as configfile:
config.write(configfile)
-
Linux环境变量管理
-
环境变量基础概念 :环境变量是Linux Shell中存储的全局变量,可被当前Shell以及所有子进程继承,典型示例为
$HOME存储当前用户的家目录路径。- 🚩重点:将敏感信息存储在环境变量中,可避免其被提交到Git等版本控制系统,从根源上防止凭证泄露。
-
Shell层面环境变量操作 :使用
export命令创建环境变量,遵循变量名全大写、等号两侧无空格的命名规范,配套提供查看、修改、删除的完整操作命令。-
Shell命令示例:
创建环境变量
export SERVER_CONFIG_PATH="/home/configs/server"
查看所有Shell变量与环境变量
set
仅查看所有环境变量
env
覆盖更新已有环境变量
export SERVER_CONFIG_PATH="/opt/configs/server"
删除指定环境变量
unset SERVER_CONFIG_PATH
-
-
.env配置文件最佳实践 :手动逐条输入环境变量效率极低且容易出错,行业通用方案是使用名为
.env的隐藏文件批量定义所有环境变量,通过source命令一次性加载。-
🚩重点:必须将
.env文件加入.gitignore忽略列表,仅向版本库提交无敏感值的.env示例模板,避免真实凭证被意外提交。 -
.env文件示例:
IP Address
export HOST="192.168.1.10"
Credentials
export USERNAME="cisco"
export PASSWORD="1234Qwer"
-
-
Python中读取环境变量 :可通过第三方库
python-dotenv加载.env文件,结合Python标准库os模块读取环境变量,实现敏感信息与代码完全解耦。-
安装与代码示例:
安装第三方依赖
pip install python-dotenv
import os
from dotenv import load_dotenv加载当前目录下的.env文件,自动生成系统环境变量
load_dotenv()
安全读取环境变量,不存在时返回None而非抛出KeyError
username = os.environ.get("USERNAME")
password = os.getenv("PASSWORD")
-
Python命令行参数传递敏感信息
-
命令行参数特性与安全注意事项:程序启动时通过命令行传入的字符串参数,天然不会被写入代码仓库,但直接在终端明文输入敏感信息会被Shell历史记录捕获,存在安全隐患。
- 🚩重点:最佳实践是先通过
source .env加载环境变量,再将环境变量作为参数传入脚本,避免敏感信息出现在命令行历史中。
- 🚩重点:最佳实践是先通过
-
sys.argv模块使用方法 :Python标准库
sys模块提供sys.argv列表存储所有命令行参数,列表的第0位永远是脚本自身的文件名,后续位置依次为用户传入的参数。-
代码示例:
import sys
打印参数总数量与完整参数列表
print(f"参数数量: {len(sys.argv)}")
print(f"参数列表: {sys.argv}")按位置提取参数
script_name = sys.argv[0]
username = sys.argv[1]
password = sys.argv[2]
host_ip = sys.argv[3]
-
Ansible Vault加密工具
-
Ansible Vault核心功能:Ansible官方内置的加密工具,使用AES-256算法对文件或字符串进行静态加密,解决敏感数据明文存储在版本控制系统中的安全问题。
- 🚩重点:Ansible执行Playbook解密数据时,内存中仅保留解密后的临时数据,不会将明文敏感信息写入磁盘。
-
Ansible Vault常用操作命令:覆盖加密文件全生命周期管理,支持创建、加密、解密、编辑、查看、重置密码等操作。
-
命令示例:
创建新的加密文件
ansible-vault create switch_credentials.yml
加密已存在的明文文件
ansible-vault encrypt plain_text.yml
解密已加密文件
ansible-vault decrypt encrypted.yml
原地编辑加密文件
ansible-vault edit switch_credentials.yml
查看加密文件明文内容
ansible-vault view switch_credentials.yml
重置加密文件的访问密码
ansible-vault rekey switch_credentials.yml
加密单个字符串并格式化为YAML变量
ansible-vault encrypt_string "my_api_key" --name api_key
-
-
自动化场景下密码管理方案 :支持将Vault密码存储在本地隐藏文件中,通过
--vault-password-file参数或ANSIBLE_VAULT_PASSWORD_FILE环境变量指定密码文件路径,适配CI/CD自动化流水线场景。
HashiCorp Vault企业级密钥管理平台
-
HashiCorp Vault核心定位:集中式密钥管理系统,提供细粒度访问控制、操作审计日志、动态密钥生成能力,彻底解决企业内敏感信息分散存储导致的"密钥 sprawl"安全问题。
- 🚩重点:与Ansible Vault的本质区别是,HashiCorp Vault将所有敏感信息集中存储在加密后端,完全脱离代码与自动化脚本,而非对本地文件进行静态加密。
-
HashiCorp Vault核心架构:由请求处理核心、多类型认证后端、审计后端、加密存储后端、各类密钥引擎(Secret Engine)组成,支持对接LDAP、Kubernetes、云服务等多种认证源。
-
KV V2密钥引擎实操 :最常用的键值存储引擎,支持密钥多版本管理、误删恢复等高级特性,通过
vault kv命令集完成所有操作。-
命令示例:
存储密钥
vault kv put secret/switch username=cisco password=1234QWER
部分更新已有密钥
vault kv patch secret/switch password=newpass
读取密钥
vault kv get secret/switch
读取指定版本的密钥
vault kv get -version=1 secret/switch
删除密钥
vault kv delete secret/switch
恢复已删除的指定版本密钥
vault kv undelete -versions=2 secret/switch
-
-
避免Shell历史记录泄露密钥的方案:支持交互式输入、通过JSON文件批量导入、禁用Vault命令历史记录三种方式,防止敏感密钥被写入Shell历史文件。
🖍️ 重点速览
🚩 考点重点
-
敏感信息存储核心原则:绝对不能将凭证、IP地址等敏感参数硬编码写入代码,这是所有安全管理方案的核心出发点。
-
ConfigParser继承规则:DEFAULT section中的配置项会自动继承到其他所有section,section名称区分大小写,配置项名称不区分大小写。
-
.env文件安全规范 :必须将真实.env文件加入
.gitignore,仅提交无敏感值的模板文件到版本库,防止凭证泄露。 -
sys.argv索引规则 :
sys.argv列表的第0位永远是脚本自身文件名,用户传入的参数从索引1开始计数。 -
Ansible Vault加密特性:Ansible执行Playbook解密时,仅在内存中保留明文数据,不会将解密后的敏感信息写入磁盘。
-
两款Vault核心差异:Ansible Vault是本地文件静态加密工具,HashiCorp Vault是集中式密钥管理平台,二者定位完全不同。
-
KV V2引擎恢复特性:删除KV V2引擎中的密钥后,元信息不会立即销毁,支持误删恢复操作。
💡 核心概念
-
ConfigParser模块:Python标准库内置的INI格式配置文件解析工具,无需第三方安装,支持嵌套字典式访问配置内容。
-
环境变量:Linux Shell中可被子进程继承的全局变量,可在运行时被程序读取,实现敏感信息与代码解耦。
-
.env文件:行业通用的批量定义环境变量的隐藏配置文件,是手动逐条输入环境变量的高效替代方案。
-
Ansible Vault:Ansible官方内置的AES-256加密工具,用于静态加密敏感配置文件与字符串,安全存储在版本库中。
-
HashiCorp Vault:企业级集中式密钥管理平台,提供访问控制、审计日志、动态密钥生成能力,解决企业级密钥分散泄露问题。
-
sys.argv:Python标准库sys模块中的列表对象,存储脚本启动时传入的所有命令行参数。
✨ 课堂金句
-
"处理敏感安全信息是软件开发中的普遍挑战,你可以选择最适配项目的工具,最终目标都是让安全信息更安全。"
-
"不要把敏感信息留在Shell历史里,这是很多开发者最容易忽略的低级安全错误。"
-
"Ansible Vault和HashiCorp Vault名字相似,但本质完全不同,一个管本地文件加密,一个管全企业的密钥集中管理。"
📝 待办事项
-
实操练习:分别使用ConfigParser、环境变量、命令行参数、Ansible Vault四种方式实现Python脚本读取交换机登录凭证。
-
环境准备 :安装
python-dotenv第三方库,搭建HashiCorp Vault开发测试环境。 -
复习重点:掌握ConfigParser的DEFAULT section继承规则、.env文件的Git忽略规范、sys.argv的索引特性。
🎯 课程总结
🔐 配置数据管理概述
-
核心挑战:开发中需以可移植、安全的方式存储和访问配置数据(如凭证、主机信息、IP地址),避免在环境切换时修改代码中的配置常量。
-
应用场景:团队开发中共享数据库的个人凭证不应出现在代码或版本控制系统中。
-
解决方案:配置文件、环境变量、命令行参数,以及专用工具(如Ansible Vault、HashiCorp Vault)。
📚 课程学习目标
-
技术栈:ConfigParser、环境变量、Linux CLI、Ansible与HashiCorp Vault。
-
实践能力:掌握多环境下密钥与敏感数据管理技能,通过实操实验室巩固应用。
🐍 ConfigParser Python模块
-
基础特性:Python标准库模块,无需额外安装,用于管理.ini格式的配置文件。
-
配置文件结构:
-
以
[SECTION]划分区块,键值对用=或:分隔。 -
[DEFAULT]区块为所有其他区块提供默认值,键名不区分大小写,区块名区分大小写。 -
示例:
[DEFAULT] username = cisco password = 12345Qwer port = 22 [server_a] ip_address = 10.254.0.10 [switch] password = 1234QWer* ip_address = 10.254.0.100 port = 23
-
-
数据解析方式:
-
read():读取配置文件,如config.read('access_info.ini')。 -
read_string():解析字符串形式的配置数据。 -
read_dict():从字典结构加载配置。
-
-
数据访问与操作:
-
类似嵌套字典访问:
config['section']['option']。 -
sections():返回所有非默认区块列表。 -
has_section(section)/has_option(section, option):检查区块或选项是否存在。 -
get(section, option):获取选项值,支持默认值参数。 -
items(section):返回区块内所有键值对元组列表。
-
-
数据修改与持久化:
-
直接赋值修改:
config['switch']['password'] = 'Cisco12345'。 -
remove_option(section, option)/remove_section(section):删除选项或区块。 -
write():将配置写入文件,需以写模式打开文件对象。
-
🌐 环境变量
-
定义:Linux系统中shell存储的键值对,可被当前shell及子进程访问,用于传递非硬编码的配置信息。
-
优势:避免敏感数据进入版本控制系统,支持多环境灵活配置。
-
常用操作:
-
创建 :
export VAR_NAME="value"(变量名惯例大写)。 -
查看 :
echo $VAR_NAME、env(仅环境变量)、set(所有shell变量)。 -
修改 :
export VAR_NAME="new_value"(覆盖原变量)。 -
删除 :
unset VAR_NAME。
-
-
.env文件管理:
-
隐藏文件(
.env)集中定义环境变量,格式为KEY="VALUE",注释以#开头。 -
示例:
# .env file export HOST="192.168.1.10" export USERNAME="cisco" export PASSWORD="1234Qwer" -
加载方式:
-
终端:
source .env(使变量生效)。 -
Python:通过
python-dotenv库加载,需安装:pip install python-dotenv。
-
-
📖 实验演示
















python
###########
# IMPORTS #
###########
from dataclasses import dataclass
import hvac
import os
from hvac.api.system_backend.wrapping import Wrapping
import requests
###################
# IMPORT ENV VARS #
###################
VAULT_ADDRESS = os.environ.get('VAULT_ADDRESS')
VAULT_APPROLE_ROLE_ID = os.environ.get('VAULT_APPROLE_ROLE_ID')
VAULT_APPROLE_SECRET_ID_FILE = os.environ.get('VAULT_APPROLE_SECRET_ID_FILE')
VAULT_API_KEY_PATH = os.environ.get('VAULT_API_KEY_PATH')
VAULT_API_KEY_FIELD = os.environ.get('VAULT_API_KEY_FIELD')
SECURE_SERVICE_ENDPOINT = os.environ.get('SECURE_SERVICE_ENDPOINT')
#######################
# SET UP APPROLE AUTH #
#######################
# Read the content of /tmp/secret and trim the whitespaces
# Print the wrapped token from the file
#print(f'Wrapped token: {wrapped_token}')
# Create a havc.Client object using wrapped token
# Use unwrap method, pass client
# Print the response
#print(f'vault_auth_response: {vault_auth_response}')
# Get the secret_id form the response
# Print the secret_id
#print(f'Secret ID: {secret_id}')
# Authenticate with auth.approle.login
# Print authentication status
#print(f'Authenticated with role_id and secred_id: {client.is_authenticated()}')
###################################################
# GET SECRET API KEY and POST TO A SECURE SERVICE #
###################################################
# Get the secret version for VAULT_API_KEY_PATH
# Print secret_version_response
#print(f'secret_version_response: {secret_version_response}')
# Get api key from response
# Print API key
#print(f'api_key: {api_key}')
# POST to an API
# Use SECURE_SERVICE_ENDPOINT
# Set X-API-KEY in header to api_key
# Create a POST request
# Print response JSON
#print(response.json())




















