TT Lab
开始
学习 学习路径 课程

隔离网络镜像与私有 CA

用轮子仓库搭建内部 Python 索引

在 TT Lab 中继续学习

目标

在联网的一侧把 Python 软件包及其依赖收集为 wheel,并用哈希固定;然后在隔离网络一侧搭建 PEP 503 内部索引,通过 pip.conf 指向它,并确认即使外部被封闭也能完成安装。

为什么重要

隔离网络导入中代价最高的错误,是“带走了却不够,还得再出去”和“带走了却在服务器上不匹配”。前者只要在外部把依赖整体解析后带走就能避免,后者只要写明目标服务器的 Python 版本和平台再下载就能避免。而在介质传递过程中被改动的文件,会被哈希检查模式抓到。这个 Pod 一开始就能访问互联网(80/443),所以承担下载端的角色,而隔离网络一侧的确认,由评分器把发往外部的 HTTP(S) 转到关闭的代理上,在封闭的状态下进行。

步骤

  1. 把 requests==2.32.3 及其依赖只按这个 Pod 的 Python(3.12)所用的 wheel 下载,收集到 /root/pip/wheelhouse/ 中。
  2. 隔离网络服务器是 Python 3.11(x86_64,manylinux2014)。把同样的需求按该目标所用的 wheel 下载,收集到 /root/pip/wheelhouse-py311/ 中。
  3. 创建 /root/pip/requirements.txt,把 /root/pip/wheelhouse/ 中的所有 wheel 都写成 이름==버전 --hash=sha256:<값>(占位符依次为软件包名、版本和哈希值)这样的行。
  4. 在每个 /srv/pypi/simple/<정규화한 이름>/(占位符为规范化后的名称)目录中放入相应的 wheel,做成 PEP 503 形式的索引。
  5. 在 /etc/hosts 中加入 127.0.0.1 pypi.airgap.internal,并启动把 /srv/pypi 通过 8080 端口提供出去的 python3 -m http.server。访问记录保存到 /root/pip/index.log。
  6. 在 /etc/pip.conf 中写入 index-url = http://pypi.airgap.internal:8080/simple,以及信任该地址的设置。评分器会在外部被封闭的情况下,查看仅凭这项配置能否下载到 requests。
  7. 创建 venv /root/pip/venv,并以哈希检查模式安装 requirements.txt。
  8. 假设没有索引,在 venv /root/pip/venv-usb 中用 --no-index --find-links /root/pip/wheelhouse 安装同样的需求。

参考

下载端:连依赖一起下载 wheel

把 requests==2.32.3 及其依赖只按 wheel 下载(使用这个 Pod 的 Python 所对应的版本),收集到 /root/pip/wheelhouse/ 中。

pip 有一个不安装、只收集文件的子命令。如果混入源码分发包(.tar.gz),隔离网络服务器上就会要求构建工具,所以也请同时使用只下载二进制文件的选项。

按目标服务器的 Python 来下载

为 Python 3.11(x86_64,manylinux2014)服务器下载同样的需求,收集到 /root/pip/wheelhouse-py311/ 中。

pip download 可以单独指定目标的平台和 Python 版本。文档写明,有一个选项必须与这些选项一起使用。下载之后,请查看文件名中的标签(cp311 等)。

用版本和哈希固定

创建 /root/pip/requirements.txt,把 /root/pip/wheelhouse/ 中的所有 wheel 都写成 이름==버전 --hash=sha256:<값>(占位符依次为软件包名、版本和哈希值)这样的行。

wheel 文件名的前两段就是名称和版本。有一个子命令可以让 pip 直接计算哈希,其值与 sha256sum 相同。在同一行中同时写上需求和 --hash。

制作 PEP 503 形式的内部索引

在每个 /srv/pypi/simple/<정규화한 이름>/(占位符为规范化后的名称)目录中放入相应的 wheel。

目录名必须是按规范对软件包名称进行规范化后的结果,pip 才能找到。小写,并且连续的点、连字符、下划线换成一个连字符。不要与 wheel 文件名内部的下划线混淆。

用内部名称启动索引

在 /etc/hosts 中加入 127.0.0.1 pypi.airgap.internal,并启动把 /srv/pypi 通过 8080 端口提供出去的服务器。访问记录保存到 /root/pip/index.log。

Python 标准库的 http.server 会以文件名链接的形式提供目录列表。请把要提供的目录和端口作为参数传入,并放到后台启动,使关闭终端后仍然存活。这个服务器把访问记录输出到标准错误。

用 pip.conf 指向内部索引

在 /etc/pip.conf 中写入 index-url = http://pypi.airgap.internal:8080/simple,以及信任该地址的设置。

pip 默认不信任非 https 的索引(只有 localhost 例外)。有一个设置键可以让它信任某个主机名。请用 pip config debug 确认文件是否真的被读取。

用哈希检查模式安装到 venv

创建 venv /root/pip/venv,并以哈希检查模式安装 /root/pip/requirements.txt。

Ubuntu 24.04 的系统 Python 无法直接安装。请先创建 venv,再用其中的 pip 安装 requirements 文件。文件中只要有 --hash,哈希检查模式就会开启,不过也有用来显式指定的选项。

不用索引,只靠 wheelhouse 安装

创建 venv /root/pip/venv-usb,并用 --no-index --find-links /root/pip/wheelhouse 安装 /root/pip/requirements.txt。

把让 pip 完全不看索引的选项,与指定查找文件的目录的选项一起使用。这样安装能成功,就意味着 wheelhouse 本身是完整的。