如何提升Azure Function运行权限 解决paramiko unknown cipher报错
问题描述
计时器触发的Python Azure Function部署到Azure Linux环境后,运行时抛出ValueError("unknown cipher")报错。通过门户SSH进入运行主机调试时发现:
- 用普通用户身份运行和函数逻辑一致的独立Python脚本,可稳定复现上述报错
- 用
sudo python 脚本名.py执行同个脚本,报错消失
当前使用Azure DevOps流水线完成函数部署,核心疑问为:如何提升Azure Function运行权限,是否支持配置函数以sudo权限运行。
函数代码如下:
import datetime import logging import azure.functions as func from azure.identity import DefaultAzureCredential from azure.keyvault.secrets import SecretClient import paramiko def main(mytimer: func.TimerRequest) -> None: utc_timestamp = datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc).isoformat() if mytimer.past_due: logging.info('The timer is past due!') logging.Logger.root.level = 10 logging.basicConfig() logging.getLogger("paramiko").setLevel(logging.DEBUG) # 从Key Vault获取SFTP认证所需密钥 credential = DefaultAzureCredential() secret_client = SecretClient(vault_url="InsertVaultURL", credential=credential) secret_name = secret_client.get_secret("InsertSecretUsernameName") secret_pass = secret_client.get_secret("InsertSecretPasswordName") secret_host_key = secret_client.get_secret("InsertSecretHostKeyName") # SFTP服务器地址 host_name = 'InsertFSTPHostAddress' # 连接SFTP服务器 ssh = paramiko.SSHClient() ssh.get_host_keys().add(hostname = host_name, keytype='ssh-rsa', key = paramiko.PKey(data = secret_host_key.value.encode('ascii'))) ssh.load_system_host_keys() ssh.connect(hostname = host_name, port = 22, username=secret_name.value, password=secret_pass.value) sftp = ssh.open_sftp() # 执行SFTP操作逻辑 # 关闭SFTP会话 sftp.close() # 关闭SSH客户端 ssh.close()
解答
首先明确两个核心结论:
- Azure Function 原生不支持配置进程以sudo/root权限运行。Linux托管环境为多租户共享的沙箱架构,函数进程默认以非特权用户身份启动,平台层面做了权限隔离,所有修改sudoers、自定义启动脚本提权的操作都会在实例重启时被平台重置,没有稳定可用的sudo运行方案。
- 你之前的根因判断错误。sudo执行脚本不报错和权限高低没有直接关系,本质是root账号加载的系统OpenSSL加密配置、Python依赖路径与函数运行所用的非特权账号不一致,导致普通用户身份运行时paramiko找不到匹配的SSH加密套件,才抛出unknown cipher错误,完全不需要提权就能修复。
具体修复步骤如下:
- 补全并固定项目依赖
不要依赖Azure Function环境自带的系统级Python包,在项目根目录的requirements.txt中明确声明paramiko及其加密相关依赖,避免不同用户加载全局包时出现路径/权限问题:azure-functions azure-identity azure-keyvault-secrets paramiko>=3.4.0 cryptography>=42.0.0 cffi>=1.16.0 - 调整Azure DevOps部署逻辑
不要依赖部署后平台自动安装依赖,在流水线的构建阶段直接把所有依赖安装到函数项目的本地包目录,随代码一起打包部署,避免安装时权限不对导致函数运行用户读不到依赖文件,构建阶段添加如下命令:pip install --target="./.python_packages/lib/site-packages" -r requirements.txt - 显式指定paramiko加密套件
不要让paramiko自动从用户环境加载可用加密算法,在调用connect方法时手动传入常用的SSH加密套件列表,绕开用户环境配置不全的问题,修改对应代码段:ssh = paramiko.SSHClient() ssh.get_host_keys().add(hostname = host_name, keytype='ssh-rsa', key = paramiko.PKey(data = secret_host_key.value.encode('ascii'))) ssh.load_system_host_keys() # 显式声明支持的加密算法,跳过系统配置探测 ssh.connect( hostname = host_name, port = 22, username=secret_name.value, password=secret_pass.value, ciphers=( "aes256-ctr", "aes192-ctr", "aes128-ctr", "aes256-gcm@openssh.com", "aes128-gcm@openssh.com", "chacha20-poly1305@openssh.com" ) ) - 验证逻辑
SSH进入实例后,先通过ps aux | grep func命令查看函数进程实际的运行用户,切换到该用户身份执行测试脚本,确认脚本能正常跑通后再发布,不要用sudo执行的结果作为验证依据。
内容的提问来源于stack exchange,提问作者PythonForAzure3942
相关产品推荐
相关产品推荐

