如何在OS X中升级OpenSSL?

今天在野外宣布了心脏出血 OpenSSL漏洞,该漏洞允许攻击者秘密地检测和窃取私有服务器密钥(从而使他们能够中间人攻击并解密您的加密数据并窃取密码)。这影响了包括1.0.1f在内的OpenSSL版本,这也是我最新的Mavericks电脑Mac(因为我使用端口/ brew安装其他软件时更新了我的openssl,而我没有意识到)的版本。
$ openssl version
OpenSSL 1.0.1f 6 Jan 2014

这证明我没有使用 Mavericks 版本的 OpenSSL。
$ which openssl
/opt/local/bin/openssl

OpenSSL 今天发布了一个修复版本 1.0.1g,我想知道如何将这个修复版本安装到我的当前版本上?

17没有使用随OS X Mavericks一起提供的版本--那是0.9.8y,它没有心脏出血漏洞(该漏洞在1.0.1中引入)。您最好的更新路径将取决于您安装较新版本的位置和方式。which openssl可能会提供信息。此外,主要问题不是openssl命令,而是openssl库(其他程序使用的库)--这些库在版本0.9.x和1.0.x之间不兼容API,因此您不想更新系统提供的openssl库! - Gordon Davisson
@GordonDavisson - 你说得完全正确。我搞错了。显然我在这台机器上安装了MacPort,它升级了我的openssl。(可能是当我试图让python2.7工作时)。也许应该删除这个问题,但为了其他人犯同样错误的时候能找到SapphireSun的好答案,我不会删除。 - dr jimbob
有了这个澄清的更新,我会保留它。可能还有其他人处于同样的困境,将这个放在这里应该能给他们一个需要做什么的想法。 - Gordon Davisson
2如果你使用bew安装OpenSSL,它将不会将二进制文件链接到/usr/bin。因此,如果你在命令行上输入openssl时,它将无法运行。 - bot47
@MaxRied,你是怎么运行Homebrew安装的版本的?我按照接受答案中的指示安装了新的openssl,并且openssl version返回1.0.1g,但你说openssl命令没有使用那个版本? - inorganik
当你使用brew安装openssl时,它会告诉你不会链接它,因为他们担心这会破坏一些OS X内部。 - bot47
Gordon:你应该将你的评论升级为一个答案。两个命令和两套库的使用方式太容易引起混淆了。 - dan
4个回答

就我所知,我刚刚使用了Homebrew(http://brew.sh/):
brew update  
brew install openssl  
brew link --force openssl 
openssl version -a  

如果出现了不好的版本之一(1.0.1a-f),你可以通过以下方式找出你正在使用的openssl版本:
which openssl

通常这个路径是 /usr/bin。为了确保您获得更新的版本,请在 /usr/local/bin 中创建一个符号链接,指向更新的 openssl,就像这样:
ln -s /usr/local/Cellar/openssl/1.0.1g/bin/openssl /usr/local/bin/openssl

作为替代最后一步的方法,有些人将/usr/bin中的openssl替换为指向/usr/local/Cellar/openssl/1.0.1g/bin/openssl(或您的版本)的符号链接:
mv /usr/bin/openssl /usr/bin/openssl_OLD  
ln -s /usr/local/Cellar/openssl/1.0.1g/bin/openssl /usr/bin/openssl

但是这已经被知道会导致一些较新版本的OSX出现问题。最好只需在/usr/local/bin中插入一个新的符号链接,这样它应该优先于路径上的/usr/bin。


9不要删除原文件,只需重命名它。如果你发现 Homebrew 版本无法满足某些需求,那么没有理由让自己陷入无助的境地(没有可用的工具或资源)。 - Terry N
1说得也没错,但另一方面,我不会称那个版本为可行的... - SapphireSun
1即使存在漏洞,只要你愿意冒一定的风险,它在任何情况下仍然对你有用,以便让依赖于它的应用程序X短暂地工作。或者,如果你更喜欢的话... 就像一个破损的桨仍然可以推动水一样,它也可以“工作”。:-p - Terry N
8只是一个注释 - 在执行完这些步骤后,输入"openssl"在终端窗口中失败了,并出现了一个指向旧副本的"没有这个文件或目录"错误(但在新的终端窗口中却可以运行)。 要修复我正在使用的终端窗口,我需要执行以下命令: hash -r - Mike Hedman
在OS X 10.9.5上,我使用Homebrew获取了openssl二进制文件,但是不得不手动创建符号链接(答案的最后部分)。 - Nikolay Tsenkov
尝试了10种不同的方法后,我终于成功修复了OpenSSL在升级后的工作问题。 - snowYetis
如果我可以提及另一个在这里可能有用的命令... php -r "print_r(openssl_get_cert_locations());" 会告诉你OpenSSL正在寻找证书的位置。我之前遇到了一个“composer update”的失败问题,提示"ssl3_get_server_certificate:certificate verify failed",结果除了更新Mozilla ca绑定之外,我还需要在我的php.ini文件中添加openssl.cafile=/usr/local/etc/openssl/cert.pem一行,以便让它知道在哪里查找它。 - William Turrell
7不如在/usr/bin/openssl创建符号链接,可以在/usr/local/bin/openssl创建链接。这样应该会在你的$PATH中位于/usr/bin之前,并且绕过在较新版本的OS X中出现的“系统完整性保护”引起的任何问题。 - mrKelley
@SapphireSun 对我来说,openssl没有更新。你能帮我看一下吗?http://pastebin.com/gZv4zcYj - Mona Jalal
如果没有权限重命名/usr/bin/openssl文件,请禁用csrutil。 重新启动您的Mac,在启动时按住cmd+r。然后进入实用工具>终端,并输入以下命令: csrutil disable reboot 之后,您可以重命名/usr/bin/openssl。按照@SapphireSun的回答执行以下命令。 ln -s /usr/local/Cellar/openssl/<OpenSsl_version_number>/bin/openssl /usr/bin/openssl 并检查您的openssl version - Abduhafiz
brew link openssl --force命令将二进制文件链接到/usr/local/bin,这样就不需要手动链接这些二进制文件了。然而,brew会抛出一个无法忽略的警告。 - Ram on Rails React Native
ln -s /usr/local/opt/openssl/bin/openssl /usr/local/bin/ 这条命令将动态连接到由Homebrew安装的(或稍后更新的)任何版本。Homebrew使用符号链接将其连接到 /usr/local/opt/openssl -> ../Cellar/openssl/1.0.2h_1 - Ram on Rails React Native
设置符号链接路径后需要重新启动终端。 - damithH
1我会避免维护符号链接,如果 --force 失败,只需按照运行 brew info openssl 时给出的说明进行操作。这些说明要求将 $PATH 更新为首先包含openssl bin。有关更多信息,请参阅http://stackoverflow.com/a/42385568/3985886。 - PanPipes
我发现这篇Medium的帖子很有帮助。找到文本“[UPDATE] 2016/12/11”,然后按照第3步进行操作。我复制并粘贴了列出的命令,结果成功了。我还在我的.bash_profile文件中添加了export PATH="/usr/local/opt/openssl/bin:$PATH"。https://medium.com/@katopz/how-to-upgrade-openssl-8d005554401 - JustinDanielson
如果您正在使用brew,只需使用brew upgrade openssl来升级openssl。 - Sukhjinder Singh

对于那些使用Mac Ports的人来说,如果不担心保留版本的话,可以这样做。
sudo port upgrade openssl

简单呀!:-)

3sudo port upgrade outdated 也可以使用。 - dr jimbob
1这真是有趣,我的机器上同时安装了macports和brew,实际上这就是导致这个问题发生的原因。运行sudo port -f uninstall openssl @<old-version>对我来说解决了问题 :) - yair
@yair 同时安装MacPorts和Homebrew会导致很多问题。 - mmmmmm

要在启用了System Integrity Protection的macOS Sierra上使用brew解决OCSP Status Request extension unbounded memory growth (CVE-2016-6304)问题:

临时调整`/usr/local`的权限,以便brew可以更新: ``` sudo chgrp -R admin /usr/local sudo chmod -R g+w /usr/local ```
安装更新版本的OpenSSL(可能需要1.0.2i): ``` brew install openssl ```
您可能需要删除`/usr/local/bin`中现有的openssl符号链接: ``` rm /usr/local/bin/openssl ```
重新链接正确的brew版本: ``` sudo ln -s /usr/local/Cellar/openssl/1.0.2i/bin/openssl /usr/local/bin/openssl ```
恢复`/usr/local/bin`的原始权限: ``` sudo chown root:wheel /usr/local ```

在我的情况下,旧版本的OpenSSL位于/usr/bin目录中。当尝试更改bin权限时,它会失败。 - Ramis
你在使用Sudo吗? - brandonscript
是的,我使用了sudo。我发现在最新版本的OS X中,没有办法更改此文件的权限。所以我停止尝试了。 - Ramis
为什么不直接将你的$PATH变量改为查找/usr/local/bin呢? - brandonscript
大家好,我对所有的答案感到困惑,包括符号链接、链接、心脏出血漏洞等等... 当我运行 $ openssl version 时,我得到的结果是 OpenSSL 0.9.8zh 14 Jan 2016,但是当我运行 $ brew install openssl 时,我得到的警告是 Warning: openssl 1.0.2l is already installed。这是否意味着我安装了两个版本?现在我应该做些什么? - Mary Jane
@Joshua提出一个新问题 - brandonscript
@brandonscript 我有 => 链接 - Mary Jane
root:wheel是什么意思? - ThisClark

不想使用brew或ports,只是想替换默认的OpenSSL 0.9.8安装的人可以通过进入恢复模式(cmd+R)并输入以下命令来禁用系统完整性保护。

csrutil disable

然后使用以下命令编译openssl
./config --prefix=/usr
make install

这对我来说是在ElCapitan中成功替代OpenSSL的,我能够直接从源代码编译curl和apache的httpd 2.4而没有任何问题。采用这种方法的原因是,ElCapitan不再由苹果维护,也不会有更新,所以很可能不会出现问题。其次,它省去了在每次编译程序时都指向/usr/local中的openssl文件夹的步骤,使编译更加稳定。