nginx作为一个web和反向服务器,应用广泛,尤其适合学习c/c++的人进行使用学习,今天就对这个我听了很多的nginx进行了一次安装配置,主要是针对菜鸟教程中的安装引导进行的个人试验。主要的关注点是nginx的安装依赖的openssl的升级踩坑。
一、安装准备
服务器配置:
CentOS Linux release 7.9.2009
gcc version 4.8.5
我的服务器是占了学生福利购买的,不过也算堪用,所以算是较新的,所以接下来的就安装一些nginx所需的一些依赖即可:
yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
(重要的点)
这里有个不同的安装,就是nginx的pcre依赖和nginx的安装,我都采用的获取安装包,然后编译安装的方式,有时候这就是离线安装,当你需要安装配置的主机在内网,不能连通外网时,从外网获取压缩包,传输到内网主机,解压编译。
wget https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz #获取压缩包
tar -xzvf pcre-8.45.tar.gz #解压
cd pcre-8.45
./configure
make && make install #编译安装
pcre-config --version #查看pcre版本
我是在登录云服务器的当前目录下创建了一个download目录,然后我的所有安装包、编译安装所需压缩包就保存在里面(在linux系统要强迫自己做好文档分类管理,因为它不像windows那么一眼分明)。
在安装完毕以后,便是nginx的安装了,地址如下,重复上面操作即可:
nginx的安装,我选择的是较新版本的nginx。
wget http://nginx.org/download/nginx-1.21.1.tar.gz
tar -xzvf nginx-1.21.1.tar.gz
cd nginx-1.21.1
#使用nginx自带的configure生成适合的makefile
./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=~/download/pcre-8.45
#编译安装
make && make install
一般来说,流程就这么走完了,但好像事情总不会正常进行,所以它又给我整幺蛾子了。
checking for OpenSSL library ... not found
checking for OpenSSL library in /usr/local/ ... not found
checking for OpenSSL library in /usr/pkg/ ... not found
checking for OpenSSL library in /opt/local/ ... not found
./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
很明显的,它说我的openssl不对,那为啥子啊?这是我用yum下载的,是较旧的openssl版本,我们可以查看一下,也可以大概知道需要的openssl版本了。
[root@Jack download]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
二、升级openssl
这里的openssl的安装是使用的yum安装,不过我百度到的资料基本都是在不删除现版本openssl的情况下进行升级的,但我的操作下,嗯。。。。。。还是有问题。首先是我参考的做法:
在这里可以找到需要的openssl包,选择你需要的就行。
wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1j.tar.gz
tar -xzvf openssl-1.1.1j.tar.gz
cd openssl-1.1.1j
#生成适合的makefile
./config --prefix=/usr/local/openssl
./config –t
#编译安装
make && make install
接下来就是关键了,现在我们只是编译安装好了新版的openssl,但当你检查版本时,使用的依然是旧版本的,显示如下:
[root@Jack download]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
所以接下来就是一些更替工作:
#备份当前openssl
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak
#为编译好的openssl创建软链接
ln -sf /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -sf /usr/local/openssl/include/openssl /usr/include/openssl
#检查函数库
cd /usr/local
ldd /usr/local/openssl/bin/openssl
#更新函数库
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf
ldconfig -v
#最后查看版本
[root@Jack local]# openssl version
OpenSSL 1.1.1j 16 Feb 2021(Library: OpenSSL 1.0.2k-fips 26 Jan 2017)
这里就有意思了,又是一个莫名其妙的错误,结果显示虽然是新版本库,但openssl执行文件却是旧版本的!(因为操作完了才来写博客,然后又复现不出来,所以问题是按照我的印象打上去的,如果有不对应的不要介意)。
这是因为上面只是更换了openssl的可执行文件,但库目录依然是系统默认的路径,所以现在要更换:
mv /usr/lib64/libssl.so /usr/lib64/libssl.so.bak
ln -sf /usr/local/openssl/lib/libssl.so /usr/lib64/libssl.so
嗯,然后我觉得ok了,就把所有旧版本备份文件删掉了,然后openssl无法执行了。。。。。。
[root@Jack ~]# openssl version
-bash: openssl: no such file or directory
[root@Jack ~]# /usr/bin/openssl
OpenSSL 1.1.1j 16 Feb 2021
这样问题就明显了,就是没有把我们创建的软链接添加进环境变量path中,这里我选择使用编译环境变量文件的办法使其生效:
#1
vim ~/.bashrc
#2 文件末尾添加下面命令
export PATH=/usr/bin:$PATH
#3 重置生效
source ~/.bashrc
然后openssl就能正常使用了,重复上面的nginx安装步骤:
./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=~/download/pcre-8.45
#编译安装
make && make install
#查看nginx历史版本
/usr/local/webserver/nginx/sbin/nginx -v
如果你遇到的是另一个问题:
objs/ngx_modules.o \
-ldl -lpthread -lcrypt -lpcre -lssl -lcrypto -ldl -lpthread -lz \
-Wl,-E
/usr/bin/ld: warning: libcrypto.so.1.1, needed by /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libssl.so, may conflict with libcrypto.so.10
/usr/bin/ld: objs/src/core/nginx.o: undefined reference to symbol 'OpenSSL_version@@OPENSSL_1_1_0'
//usr/local/openssl/lib/libcrypto.so.1.1: error adding symbols: DSO missing from command line
collect2: 错误:ld 返回 1
make[1]: *** [objs/nginx] 错误 1
make[1]: 离开目录“/root/download/nginx-1.21.1”
make: *** [build] 错误 2
这是因为libcrypto.so.10作为软链接,所指示的依赖还是旧版本的openssl的库,所以需要把libssl.so所指示的库进行替换,可以直接把我们编译好的openssl库下的libcrypto.so.10连接到/usr/lib64/libcrypto.so.10:
ln -sf /usr/local/openssl/lib/libcrypto.so /usr/lib64/libcrypto.so
连接后检查库是这样的:
[root@Jack nginx-1.21.1]# ll /usr/lib64/libcrypto.so*
lrwxrwxrwx 1 root root 35 2月 20 14:03 /usr/lib64/libcrypto.so -> /usr/local/openssl/lib/libcrypto.so
lrwxrwxrwx 1 root root 19 2月 20 00:58 /usr/lib64/libcrypto.so.10 -> libcrypto.so.1.0.2k
-rwxr-xr-x 1 root root 2520744 1月 18 21:56 /usr/lib64/libcrypto.so.1.0.2k
[root@Jack nginx-1.21.1]# ll /usr/local/openssl/lib/libcrypto.so*
lrwxrwxrwx 1 root root 16 2月 20 11:18 /usr/local/openssl/lib/libcrypto.so -> libcrypto.so.1.1
-rwxr-xr-x 1 root root 3388728 2月 20 11:18 /usr/local/openssl/lib/libcrypto.so.1.1
nginx安装好以后,检查版本
[root@Jack nginx-1.21.1]# /usr/local/webserver/nginx/sbin/nginx -v
nginx version: nginx/1.21.1
启动一下
[root@centos ~]# /usr/local/webserver/nginx/sbin/nginx
[root@centos ~]# ps aux | grep nginx
root 8729 0.0 0.0 28472 996 ? Ss 23:49 0:00 nginx: master process /usr/local/webserver/nginx/sbin/nginx
nobody 8730 0.0 0.0 30992 1780 ? S 23:49 0:00 nginx: worker process
root 9785 0.0 0.0 112824 988 pts/0 R+ 23:50 0:00 grep --color=auto nginx
我的服务器已经配置好安全组了,直接就可以在外部访问
到这里就算安装好了。
踩坑
为了记录之前的坑,我用yum卸载了前面安装的openssl和openssl-devel,然后把之前安装好的nginx、新版本openssl编译后的库删除恢复在此之前的环境重新安装一遍,然后出现下面的问题了:
objs/ngx_modules.o \
-ldl -lpthread -lcrypt ~/download/pcre-8.45/.libs/libpcre.a -lssl -lcrypto -ldl -lpthread -lz \
-Wl,-E
/usr/bin/ld: warning: libcrypto.so.1.1, needed by /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libssl.so, may conflict with libcrypto.so.10
/usr/bin/ld: objs/src/core/nginx.o: undefined reference to symbol 'OpenSSL_version@@OPENSSL_1_1_0'
//usr/local/openssl/lib/libcrypto.so.1.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[1]: *** [objs/nginx] Error 1
make[1]: Leaving directory `/root/download/nginx-1.21.5'
make: *** [build] Error 2
具体问题描述就是这样,我升级后的openssl版本为新版本,但在nginx编译链接的库是旧版本。为了确保清除干净,我只好把之前的备份文件删除,写进环境变量文件恢复然后再推倒重来。所以我手欠删掉了libssl.so.1.0.2k,为啥?我手欠啊!然后就无法登陆了,一直是connection closed的状态,我还以为是它机房出事了呢,就去睡觉了,结果第二天还是这样!
试了一下vnc登陆,可以,然后本地cmd去尝试ssh方式登陆,失败:
PS C:\Users\Jack\Desktop> ssh root@121.5.47.242
kex_exchange_identification: read: Connection reset
PS C:\Users\Jack\Desktop> ssh -v root@121.5.47.242
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2
debug1: Connecting to 121.5.47.242 [121.5.47.242] port 22.
debug1: Connection established.
debug1: identity file C:\\Users\\samu/.ssh/id_rsa type -1
debug1: identity file C:\\Users\\samu/.ssh/id_rsa-cert type -1
debug1: identity file C:\\Users\\samu/.ssh/id_dsa type -1
debug1: identity file C:\\Users\\samu/.ssh/id_dsa-cert type -1
debug1: identity file C:\\Users\\samu/.ssh/id_ecdsa type -1
debug1: identity file C:\\Users\\samu/.ssh/id_ecdsa-cert type -1
debug1: identity file C:\\Users\\samu/.ssh/id_ed25519 type -1
debug1: identity file C:\\Users\\samu/.ssh/id_ed25519-cert type -1
debug1: identity file C:\\Users\\samu/.ssh/id_xmss type -1
debug1: identity file C:\\Users\\samu/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_for_Windows_8.1
kex_exchange_identification: Connection closed by remote host
PS C:\Users\Jack\Desktop>
不过倒是让我找到问题出处了,对照着kex_exchange_identification: Connection closed by remote host这个问题去百度,倒是找到一个说是并发连接背锅,然后就是更改MaxStartups和MaxSessions,更改后重启ssh服务,但我重启失败(在vnc登陆处进行操作):
#修改MaxStartups和MaxSessions
vim /etc/ssh/sshd_config
#重启ssh服务
systemctl restart sshd
如果是并发连接的问题呢,那就好了,但它结果显示无法重启,让我查看ssh状态:
#查看ssh服务情况
status sshd.service
#报具体错误
sshd -t
这里报错就很清楚了,就是加载libssl.so.10时出错,确定以后,就把之前更改的文件变量恢复先,不然不知道又出啥事呢。对于云服务器登陆,能用vnc登陆的,基本都是一些配置问题,所以可以用ssh -v @来查看是否ssh登录有问题,然后就可以针对性去解决,
#检查ssh服务
service sshd status
#测试模式查看
sshd -t
sshd是openssh软件套件中的守护进程,可以用来查看ssh问题。那接下来就是如何安装libssl.so.10的问题了。
让我们查看库文件是什么问题,ll查看/usr/lib64库中的libssl.so开头的文件信息,从下面可以看出,libssl.so.10链接到的libssl.so.1.0.2k文件缺失。
不过许多的办法都不对应现在的版本了,我干脆选择重装系统,毕竟是云服务器,有着它自己的镜像,不过大家以后做操作前还是保存一下镜像吧。
ps:这个原本是在csdn上发布的,不过以后我就搬家了,改在这里了,这篇是近期的文章,顺手就搬过来吧。