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服務
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上釋出的,不過以後我就搬家了,改在這裡了,這篇是近期的文章,順手就搬過來吧。