CentOS 6使用Let’s Encrypt遇到openssl相关问题的解决

问题出现

因为应急的原因,要给一台老服务器临时换上免费的Let's Encrypt生成的HTTPS证书,想简单一点直接采用自动化方案,但是无论是参照certbot的方案,还是直接从letsencrypt的源码仓库里拉取执行letsencrypt-auto命令,总是会在ssl相关的模块出错,后来参照在网上各处找到的方案,却总是得到不同的错误信息,问题总是指示python相关模块引用的_openssl.so相关的库构建错误,不是少这个变量就是少那个变量

问题分析

第一时间,我想绕过python版本引发的问题,先升级吧,于是把老服务器上的python2.6.6升级到了最新的python2.7,还顺带升级了pip,但是ssl相关问题还是会出现。

折腾了很多次,发现问题可能出现在我曾经手动升级过openssl,因为机器比较老,要支持ALPN,所以就升级到了较高等级的版本,但是当时升级的openssl的用途主要就是单独提供命令和提供源码给nginx编译,实际上系统内部的动态链接库应该还是之前的。参考了这篇文章,决定要让letsencrypt编译安装时链接到正确的openssl库,但是这篇文章只是提供了系统包含了正确的库的前提下怎么重新构建的方法,现在的问题是如何让系统包含正确的库。另外,目前来看,这个问题和python版本是没有关系的,我先恢复到phthon2.6的版本,让问题的能控制的变化因子到一个最小的集合。

问题解决过程

之前的openssl版本是1.0.1的,先是想升级到当时安装比较新的1.1.0,但是编译的时候出错,当时也懒的去把环境里的必须的库去升级一下,发现1.0.2也是满足要求的,所以就直接编译升级到了1.0.2h,然后替换了下相关的openssl命令,编译nginx的时候直接关联openssl的源码包,在/usr/local/lib64(具体看环境,也有可能在/usr/local/lib里)里应该有对应的输出库文件,到这个目录观察,发现只有libcrypto.alibssl.a这两个静态函数库,显然我需要的是.so动态链接库,google了下,发现可以在openssl构建的时候加上shared参数(来指定生成.so文件,所以以后如果给openssl升级,最佳做法应该是安装两遍,还有一遍就是要生成.so文件。

然而在生成过程中,编译openssl出现问题,提示要加入-fPIC编译参数,参考了Compiling openssl - what does .rodata and -fPIC mean?
compile openssl with the 'shared' option
两个帖子后,加上相应的参数来编译

cd /usr/local/src/openssl-1.0.2h
make clean && make dclean
export CFLAGS=-fPIC
./config --prefix=/usr/local --openssldir=/usr/local/openssl shared
make depend
make
make install

果然顺利得到了libcrypto.so.1.0.0libssl.so.1.0.0,另外的libcrypto.solibssl.so是分别指向它们的软链接。

编辑/etc/ld.so.conf,加上/usr/local/lib64(注意是包含那两个.so文件的文件夹,也可能是/usr/local/lib,具体看环境),然后执行

ldconfig
ldconfig -v

查看有没有加入/usr/local/lib64里的那两个.so文件。

注意链接到的openssl库应该是和当前系统使用的openssl是保持一致的,比如当前系统使用的是1.0.2h的库,但是/usr/local/lib64有之前编译的其它版本的libssl.so,链接到了不一致版本的库也会导致letsencrypt-auto执行失败,所以整个系统最好只保持一个版本的openssl库就行,其他的全删了或者从编译路径里去除。

假如之前没有删除系统自带的openssl库,要先删除

yum remove openssl-devel

最后开始重新编译letsencrypt相关模块

cd /usr/local/src/letsencrypt
cd ~/.local/share/letsencrypt/bin/
./pip uninstall cryptography pyopenssl -y
rm -rf ~/.cache/
./pip install cryptography pyopenssl
ldd ~/.local/share/letsencrypt/lib/python2.6/site-packages/cryptography/hazmat/bindings/_openssl.so

查看_openssl.so里链接到的库是不是指向自己生成的那两个.so库,如果是对的,就可以执行letsencrypt-auto来生成证书了。

Show Comments