Ubuntu服务器中隐藏API密钥并允许执行Python脚本的方法
保护API密钥同时允许普通用户运行Python脚本的解决方案
针对你的场景(通过bash陷阱检测npm start并执行Python脚本,需隐藏Bearer token),以下几种简便方案可以实现需求:
方案1:sudo+权限隔离的密钥文件(最安全)
核心思路是把密钥放在只有root可读的文件里,让普通用户通过sudo以root身份执行脚本,从而读取密钥但无法直接查看密钥文件。
操作步骤:
- 创建仅root可读的密钥文件:
sudo touch /root/api_key sudo chmod 600 /root/api_key # 写入API密钥:echo "your_token_here" | sudo tee /root/api_key - 修改Python脚本,改为从密钥文件读取token:
#!/usr/bin/env python3 import requests import json def get_api_key(): # 仅root身份可读取该文件 with open('/root/api_key', 'r') as f: return f.read().strip() HEADERS = { 'Authorization': f'Bearer {get_api_key()}', 'Content-Type': 'application/json' } def get_info(): GET_CONFIG_LINK = 'INSERT_URL_HERE' get_response = requests.get(GET_CONFIG_LINK, headers=HEADERS) if not get_response.ok: return {} return get_response.json() print(get_info()) - 配置sudo允许普通用户无密码执行该脚本:
运行sudo visudo,添加一行(替换为你的脚本路径):ALL ALL=(root) NOPASSWD: /usr/local/bin/action.py - 修改bash陷阱脚本中的执行命令为sudo调用:
actionResult=$(sudo /usr/local/bin/action.py) - 给Python脚本设置合适权限:
sudo chmod 755 /usr/local/bin/action.py
说明:
- 普通用户无法读取
/root/api_key,只能通过sudo执行脚本间接使用密钥 - 脚本本身可以公开,因为里面没有明文密钥
方案2:Python字节码编译(最简便)
利用Python的字节码文件(.pyc)替代明文脚本,字节码不是明文,虽然可以反编译,但对普通用户来说足以隐藏密钥,操作非常简单。
操作步骤:
- 编译Python脚本为字节码:
执行后会在python3 -m py_compile /usr/local/bin/action.py/usr/local/bin/__pycache__目录生成类似action.cpython-3X.pyc的文件(X是你的Python版本号)。 - 移动并重命名字节码文件,设置执行权限:
sudo mv /usr/local/bin/__pycache__/action.cpython-3X.pyc /usr/local/bin/action.pyc sudo chmod 711 /usr/local/bin/action.pyc - 把原明文脚本移到仅root可读的目录:
sudo mv /usr/local/bin/action.py /root/ sudo chmod 600 /root/action.py - 修改bash陷阱脚本中的执行命令,改为运行字节码:
actionResult=$(python3 /usr/local/bin/action.pyc)
说明:
- 字节码文件无法直接看到明文密钥,普通用户很难反编译出原内容
- 操作步骤最少,适合快速实现
方案3:环境变量+受控执行环境
通过root控制的环境变量文件加载密钥,普通用户执行脚本时由root注入环境变量,脚本本身不存储密钥。
操作步骤:
- 创建仅root可读的环境变量文件:
sudo touch /root/api_env sudo chmod 600 /root/api_env echo 'export API_KEY="your_token_here"' | sudo tee /root/api_env - 修改Python脚本,从环境变量读取密钥:
#!/usr/bin/env python3 import requests import json import os HEADERS = { 'Authorization': f'Bearer {os.environ.get("API_KEY", "")}', 'Content-Type': 'application/json' } def get_info(): GET_CONFIG_LINK = 'INSERT_URL_HERE' get_response = requests.get(GET_CONFIG_LINK, headers=HEADERS) if not get_response.ok: return {} return get_response.json() print(get_info()) - 修改bash陷阱脚本中的执行命令,通过sudo加载环境变量并执行脚本:
actionResult=$(sudo bash -c 'source /root/api_env && python3 /usr/local/bin/action.py') - 配置sudo允许无密码执行该bash命令(可选,避免每次输入密码):
运行sudo visudo,添加一行:ALL ALL=(root) NOPASSWD: bash -c 'source /root/api_env && python3 /usr/local/bin/action.py'
说明:
- 密钥存储在环境变量文件中,普通用户无法读取
- 适合需要动态修改密钥的场景,只需编辑环境变量文件即可
内容的提问来源于stack exchange,提问作者jellypancake
相关产品推荐
相关产品推荐

