加密保证可重复执行的“pip安装”
项目描述
Peep
长期以来,对安全的关注一直是部署 Python 项目的痛点:PyPI 或其第三方 CDN 的妥协可能会导致你得到与所签注不同的软件包。为了确保部署的已知良好依赖项,你必须运行本地包索引,手动上传经过审查的包,维护该服务器的 ACL 集合,并试图记录谁做了什么。或者,你可以将一切提交给供应商库,但这意味着需要对版本控制系统(或维护自定义工具)进行大量操作以进行升级。
Peep 解决了所有这些问题。
审查你的包,并将 PyPI 源 tarball 的哈希值放入 requirements.txt 中,如下所示
# sha256: L9XU_-gfdi3So-WEctaQoNu6N2Z3ZQYAOu4-16qor-8 Flask==0.9 # sha256: qF4YU3XbdcEJ-Z7N49VUFfA15waKgiUs9PFsZnrDj0k Jinja2==2.6
然后,使用 peep install 而不是 pip install,让加密完成剩下的工作。如果下载的包与预期的哈希值不匹配,Peep 将会异常,安装将无法继续。
无需维护服务器,无需处理庞大的供应商库,无需信任包作者的密钥管理实践。通过在需求文件中添加一些哈希值,你可以知道你的信任链安全地根植于你自己的源代码树中。
切换到 Peep
安装 Peep
pip install peep
(或者更好,如以下嵌入部分所述,将 peep.py 嵌入到你的代码库中。这样,如果你第一次手动审查 peep.py,就可以消除信任未经身份验证的 PyPI 下载的需要。)
使用 Peep 安装你的项目一次
cd yourproject peep install -r requirements.txt
你会得到如下输出
<a bunch of pip output> The following packages had no hashes specified in the requirements file, which leaves them open to tampering. Vet these packages to your satisfaction, then add these "sha256" lines like so: # sha256: L9XU_-gfdi3So-WEctaQoNu6N2Z3ZQYAOu4-16qor-8 Flask==0.9 # sha256: qF4YU3XbdcEJ-Z7N49VUFfA15waKgiUs9PFsZnrDj0k Jinja2==2.6 # sha256: u_8C3DCeUoRt2WPSlIOnKV_MAhYkc40zNZxDlxCA-as Pygments==1.4 # sha256: A1gwhyCNozcxug18_9RjJTmJQa1rctOt-AnP7_yR0PM https://github.com/jsocol/commonware/archive/b5544185b2d24adc1eb512735990752400ce9cbd.zip#egg=commonware ------------------------------- Not proceeding to installation.
以你通常的方式审查来自 PyPI 的包。例如,阅读它们,或者将它们与已知的良好本地副本进行比较。
将推荐的哈希行添加到你的 requirements.txt 中,每行直接位于它所应用的依赖项上方。(这些哈希值来自 PyPI 的原始压缩 tarball。)
将来,始终使用 peep install 来安装你的需求。现在你是加密安全的!
可怕的警告
如果在安装过程中哈希值不匹配,Peep 将显示类似以下内容
THE FOLLOWING PACKAGES DIDN'T MATCH THE HASHES SPECIFIED IN THE REQUIREMENTS FILE. If you have updated the package versions, update the hashes. If not, freak out, because someone has tampered with the packages. requests: expected FWvz7Ce6nsfgz4--AoCHGAmdIY3kA-tkpxTXO6GimrE got YhddA1kUpMLVODNbhIgHfQn88vioPHLwayTyqwOJEgY
然后,它将以状态码 1 退出。相应地惊慌。
其他功能
Peep 默认启用 pip 的 --no-deps 选项,因此无法通过未经验证的依赖项悄悄地通过。
所有非安装命令都会直接转到 pip,因此如果你想的话,可以始终使用 Peep。这对于顶部有大量 $PIP=/path/to/pip 的现有脚本来说非常有用。
Peep 兼容的需求文件可以完全与 pip 一起使用,因为哈希值毕竟只是注释。
你有手动下载并审查过的软件包吗?运行 peep hash 命令来获取其 tarball 的哈希值(来自 PyPI 的原始 tarball –确保将其保留好)
% peep hash nose-1.3.0.tar.gz # sha256: TmPMMyXedc-Y_61AvnL6aXU96CRpUXMXj3TANP5PUmA
如果一个包已经存在(例如在非空虚拟环境中安装时),Peep 就不会再次下载或构建它。它假设您在之前的调用中已使用 Peep 安装了它,因此信任它。唯一例外的是 URL 指定的需求,其中 URL 包含类似 SHA 的文件名(例如 https://github.com/foo/bar/archive/<SHA>.zip),因为包版本号通常不会在每次提交时递增,所以 Peep 不能确定内容是否已更改。注意:在部署期间重用虚拟环境可以真正加快速度,但您需要手动删除不再在需求文件中的依赖项。
peep port 将 peep 精通的需求文件转换为与 pip 8 的新哈希功能 兼容的文件。
% peep port requirements.txt certifi==2015.04.28 \ --hash=sha256:268fa00c27de756d71663dd61f73a4a8d8727569bb1b474b2ce6020553826872 \ --hash=sha256:99785e6cf715cdcde59dee05a676e99f04835a71e7ced201ca317401c322ba96 click==4.0 --hash=sha256:9ab1d313f99b209f8f71a629f36833030c8d7c72282cf7756834baf567dca662
请注意,注释和 URL 无法通过,但为您处理的难点——哈希格式转换——已经解决。
嵌入
Peep 是为无监督持续部署场景设计的。在这种情况下,在部署机器上手动提前准备是一项负债:又多了一件事可能出错。为了减轻您需要在您的服务器或构建箱上手动安装(和升级)Peep 的负担,我们已经使 Peep 可嵌入。您可以直接将 peep.py 文件复制到您的项目源树中,并在部署脚本中从那里调用它。这也为您信任的链提供了明显的起点:您如何信任您的源代码,就是您如何信任您的 Peep 复制,Peep 通过哈希验证其他所有内容。(如果您的操作系统提供 Peep 作为软件包,您可能已经信任您的操作系统软件包了,但这还不是常见做法。)
安全和不安全
以下是您使用 Peep 可以免费获得的东西——以及您不能获得的东西。
您获得可重复性。如果您使用 peep install package Foo==1.2.3 安装包,则后续安装 Foo==1.2.3 将与原始安装相同(或者 Peep 将会抱怨)。
Peep 不会神奇地审核您的包。 Peep 不能替代您仔细检查包中的恶意代码或将其与已知良好版本进行比较。如果您不检查它们,它们就不会被检查。
Peep 不会使作者或索引可信。 Peep 所做的只是保证后续下载的 Foo==1.2.3 与第一个相同。它不能保证该包的作者是可信的。它不能保证该包的作者就是发布该包的人。它也不能保证包索引是可信的。
故障排除
多个哈希:特定架构的包和 PyPI 的旧版本
您是否突然收到可怕的警告?也许您真的遇到麻烦了,但也许正在发生更无害的事情。
如果您的包从 wheel 或其他可能具有特定架构的来源安装,它们的哈希将在各个平台上显然不同。如果您在多个平台上部署,您将需要多个哈希。
此外,一些包提供多种格式的下载:例如,zip 和 tarball,或 zip 和 wheel。下载哪个版本可能取决于您的 pip 版本,这意味着一些包可能实际上具有多个有效的哈希。
为了支持这些场景,您可以在需求上方堆叠多个已知良好哈希,只要它们在连续的注释行块中即可。
# Tarball: # sha256: lvpN706AIAvoJ8P1EUfdez-ohzuSB-MyXUe6Rb8ppcE # # And the zip file: # sha256: 6QTt-5DahBKcBiUs06BfkLTuvBu1uF7pblb_bPaUONU mock==0.8.0
如果您不想等到被这个惊喜咬到才采取行动,请使用peep hash命令查找每个软件包等效存档的哈希值。我喜欢审查其中一个(比如说,tar包),然后下载其他版本,并使用文件比较工具来验证它们的文件内容是否相同。然后我像这样对两个原始存档运行peep hash,并将结果添加到我的requirements.txt文件中。
% peep hash mock-0.8.0.tar.gz mock-0.8.0.zip # sha256: lvpN706AIAvoJ8P1EUfdez-ohzuSB-MyXUe6Rb8ppcE # sha256: 6QTt-5DahBKcBiUs06BfkLTuvBu1uF7pblb_bPaUONU
使用旧版本的pip升级Wheels
如果您正在重用virtualenv并使用pip <6.0版本,那么您应该避免使用wheels。否则,由于https://github.com/pypa/pip/issues/1825,在安装新版本之前,旧版本的软件包将不会被完全删除。
如果您正在使用pip 1.4,请不要传递--use-wheel参数。
如果您正在使用pip 1.5,请传递--no-use-wheel参数。
版本历史
- 3.1.2
修复与pip 8.1.2的兼容性。(abbeyj)
- 3.1.1
对于pip安装错误(并非peep的过错)的几个案例,"peep had a problem"的跟踪输出不再输出,例如指定的软件包版本或要求文件不存在。
peep port现在在您使用pip 6.1.0或更高版本时发出基于URL的要求的URL。 (jotes)
- 3.1
在peep port过程中打印我们遇到的每个新的要求文件名称。这有助于解决如果您的文件使用包含时造成的混乱。(pmac)
始终将哈希值放在单独的行上,即使只有一行。 (pmac)
- 3.0
添加对pip 8.x的支持。
删除对--allow-external、--allow-unverified和--allow-all-external参数的支持(以兼容pip 8)。
删除对Python 3.1/3.2的支持。
- 2.5
支持pip 7.x,通过目前最新的7.1.2版本,绕过其有问题的行计数。 (kouk)
添加peep port命令,以方便过渡到pip 8的哈希模式。
修复了一个错误,其中不会自动检测调用parse_requirements()的正确方法。
- 2.4.1
容忍pip.__version__缺失,这在错误处理过程中可能发生,可能会在跟踪输出中隐藏有用的信息。
再次修复flake8警告,并将flake8添加到Travis运行中。
- 2.4
添加对要求文件中的标志的支持,类似于pip风格的,例如使用-i指定替代索引。
从错误消息中删除重复的#egg=部分。
- 2.3
将MIT许可的运作部分复制到peep.py中,这样嵌入它就不会破坏许可证。
修复flake8检查器的警告。
使peep与pip v6.1.0+兼容。
将针对pip 6.0.8、6.1.0和6.1.1的测试添加到tox配置中。
在Travis上运行完整的tox测试套件。
- 2.2
在下载时添加进度指示。与pip 6.0及更高版本一起使用时,我们显示一个漂亮的进度条。在此之前,我们只是在下载时提及软件包。
从输出中删除多余的跳过行。
将针对pip 6.0.7的测试添加到tox配置中。
- 2.1.2
当一条消息适用于多个软件包时,在运行结束时删除重复的解释性消息。
- 2.1.1
修复了一个错误,其中如果GitHub上的zip文件版本没有更改,peep不会升级用GitHub上的zip文件表示的软件包。
将针对pip 6.0.4、6.0.5和6.0.6的测试添加到tox配置中。
- 2.1
支持pip 6.x。
使错误报告友好,在跟踪输出中发出错误报告URL和环境信息。
- 2.0
修复了一个主要的安全漏洞,即在下载包后,无论包的存档是否匹配哈希值,都会执行包的setup.py文件。具体来说,停止依赖pip下载包,因为pip喜欢运行setup.py来提取元数据。使用无处不在的urllib2实现我们自己的下载。因此,目前不支持HTTP代理、基本身份验证和--download-cache。
对代码进行重大重构以提高可读性。
大幅度提高测试覆盖率。
注意,HTTPS证书不再进行检查。考虑到我们的哈希检查,这应该没问题。
- 1.4
允许部分行注释。
开始构建测试套件。
将requirements文件中的包名视为不区分大小写,如pip。
- 1.3
将大多数参数传递给实际安装下载的存档的pip install调用。这意味着您可以使用诸如--install-options之类的功能。
通过修正导入来添加Python 3.4支持。
安装一个名为活动Python版本的第二个peep脚本,例如peep-2.7。这对于使用多个Python版本而不使用virtualenv的用户来说是一种便利。
- 1.2
在requirements文件中支持GitHub风格的tar包(即,文件名不包含发行版名称或版本,且版本号不可靠)。(Will Kahn-Greene)
当基于URL的要求缺少#egg=时发出警告。(Chris Adams)
- 1.1
支持Python 3。(Keryn Knight)
- 1.0.2
添加对.tar.bz2存档的支持。(Paul McLanahan)
- 1.0.1
修复安装包含下划线的发行版名称的包时出现的错误(这个错误没有失败)。(Chris Ladd)
- 1.0
添加对wheel的支持。当pip决定下载wheel文件时,Peep将正常工作。(Paul McLanahan)
- 0.9.1
在尝试报告已安装包缺失的哈希值时不会崩溃。
- 0.9
将peep的操作部分放入一个模块而不是一个包中,并使其可直接执行。(Brian Warner)
- 0.8
为了提高速度,支持将包安装到非空virtualenv中。我们通过信任任何已经安装的满足要求的包来实现这一点。这意味着您不必每次部署时都重新构建lxml等包。
将文本输出包裹为80列,以便更好的换行。
- 0.7
对通过将peep的tar包检查到其源树中来启动信任链的项目进行一些实际调整。
开始支持pip回退到0.6.2版本(2010年1月发布)。这样,您只需将peep的tar包检查到源树中并使用pip安装它,就可以在旧版本的RHEL上可靠地部署;您不需要检查in pip本身或麻烦地解压peep的tar包并从您的部署脚本中运行python setup.py install。
删除对pip的显式依赖。这样,在没有--no-deps的情况下,简单的pip install peep.tar.gz调用不会从PyPI拉取未信任的包。相反,如果在运行时pip不存在或版本太旧,我们会发出警告。安全失败。
- 0.6
添加peep hash子命令。
要求pip>=1.2,因为较旧版本有一个在peep install上导致崩溃的错误。
- 0.5
允许一个包有多个可接受的哈希值。这可以解决PyPI对像mock这样的包的非稳定处理,这些包提供等效的zips和tar包:https://bitbucket.org/pypa/pypi/issue/64/order-of-archives-on-index-page-is-not。
- 0.4
重新设计peep下载文件和确定版本的方式,以便我们可以容忍PEP-386不符的包版本号。这相当于一个小的重写。
从哈希输出中删除缩进,这样您就不需要在将内容粘贴到requirements.txt后重新缩进。
- 0.3
支持Windows和其他非Unix操作系统。
哈希输出现在包括包的实际版本号,因此您可以直接将其粘贴到您的requirements.txt文件中。
- 0.2.1
添加一个shebang行,以便在执行pip install peep后实际运行peep。抱歉,大家,我在自己的机器上做了setup.py develop。
- 0.2
修复重复记录错误。
修复关于没有要求文件的错误消息。
将pip的退出代码传递给非install子命令的外部调用。
改进最终输出的间距。
- 0.1
概念验证。做所有加密事情。应该是安全的。UI有粗糙的边缘。
项目详情
下载文件
下载适合您平台文件的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分布
构建分布
peep-3.1.2.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 96565873c3bff616789fef180bcce3c03f18118b8c7bba80b2c7529d18a4d156 |
|
MD5 | 04607549fe82a4422fbc9e52a5bb4cf1 |
|
BLAKE2b-256 | 28e6c26504cc609efe302700cd2a10691dbbe28e59a659dedb9633b6b9ee9bd3 |
peep-3.1.2-py2.py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 23047e8dfba2bb825e337fb233e060d181f3b66f039d972ca6e74383dada402b |
|
MD5 | e221a0dc9cdf7aa10b5f714ac8ff8fcf |
|
BLAKE2b-256 | de29441095975f5246f43125f05f4de9b8b48cdc832d34acdff603fdf4b867c7 |