You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下uv管理的Python无法创建Socket:能否给解释器签名?

问题:macOS上uv管理的Python无法通过Socket连接目标主机,系统Python/root运行正常

问题背景

使用LetsEncrypt和Nginx Proxy Manager配置了SSL域名(例如host.mydomain.com),浏览器访问https://host.mydomain.com完全正常,但在macOS 14.4上运行ansible、esphome这类依赖socket模块的Python包时,与主机通信失败。

排查现象

普通用户用uv管理的Python运行Socket连接命令报错,root身份或系统自带Python则正常:

❯ uv run python -c 'import socket; s = socket.socket(); s.connect(("host.mydomain.com", 443)); print("Ok")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import socket; s = socket.socket(); s.connect(("host.mydomain.com", 443)); print("Ok")
                                        ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 65] No route to host
❯ /usr/bin/python3 -c 'import socket; s = socket.socket(); s.connect(("host.mydomain.com", 443)); print("Ok")'
Ok
❯ sudo uv run python -c 'import socket; s = socket.socket(); s.connect(("host.mydomain.com", 443)); print("Ok")'
Ok

❯ uv run python --version
Python 3.13.13
❯ /usr/bin/python3 --version
Python 3.9.6

我的推测与尝试

推测macOS因系统Python已签名而给予特殊权限,尝试给uv管理的Python解释器签名但未成功:

❯ codesign --sign - --force --preserve-metadata=entitlements,identifier $(readlink -f .venv/bin/python)

疑问

  1. 是否可以通过给uv管理的Python签名解决Socket连接问题?
  2. 如果签名不是解决方案,还有其他办法吗?

解决方案

一、正确的代码签名步骤(针对uv的Python)

直接用--sign -生成的自签名证书不被macOS隐私机制认可,需用带网络权限的签名流程:

  1. 打开「钥匙串访问」,创建一个「代码签名」类型的自签名证书(或使用Apple开发者账号证书),记录证书名称(例如My Code Sign Cert)。
  2. 创建权限配置文件entitlements.plist,添加网络访问权限:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>com.apple.security.network.client</key>
        <true/>
    </dict>
    </plist>
    
  3. 执行签名命令,替换证书名称为你创建的证书:
    codesign --sign "My Code Sign Cert" --force --entitlements entitlements.plist --preserve-metadata=identifier,entitlements $(readlink -f .venv/bin/python)
    
  4. 签名完成后,进入「系统设置」→「隐私与安全性」,确认该Python解释器的网络访问权限已被允许。

二、绕过签名限制的替代方法

如果签名流程繁琐,可尝试以下方案:

  • 修改防火墙规则:进入「系统设置」→「网络」→「防火墙」→「选项」,添加uv管理的Python解释器(.venv/bin/python),允许其网络连接。
  • 切换到系统Python虚拟环境:放弃uv,直接用系统Python创建虚拟环境:
    /usr/bin/python3 -m venv myenv
    source myenv/bin/activate
    pip install ansible esphome
    
  • 手动配置hosts解析:若存在域名解析差异,将目标域名与对应IP写入/etc/hosts:
    sudo echo "192.168.x.x host.mydomain.com" >> /etc/hosts
    
  • 检查隐私权限:进入「系统设置」→「隐私与安全性」,确保终端(或使用的Shell)拥有「完全磁盘访问」权限,同时确认uv的Python已被授予网络访问权限。

内容的提问来源于stack exchange,提问作者big_gie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 05:23:14