Centos7.3 升級最新Openssl1.1.0e同時編譯安裝lnmp環境(使用最新openssl1.1.0e)

四五隻羊發表於2019-02-16

專案需要,搭建lnmp環境。
瞭解到之前的openssl曝出的heartbleed漏洞,所以一直想升級到最新的openssl版本以保證安全(其實未必安全。。。強迫症吧)這次伺服器是採用微軟Azure 的Centos7.3系統。中間走過很多坑,每次出問題都重置作業系統實在是無奈,所以記錄下這次經歷,以便日後查閱。
實際上,整個過程看下來,還是要好好系統學習一下Linux 。 還有編譯的原理。

環境

  1. Centos7.3 x64

  2. lnmp一鍵安裝包oneinstack。專案官網:Oneinstack

  3. xshell + xftp + git for windows

一、升級作業系統安裝包

$ yum update -y

二、升級核心到最新並開啟tcp_bbr

之前在搬瓦工搭建ss,速度到晚上一直不理想,瞭解到加速軟體,再瞭解到tcp_bbr 。這是個巨大的特性。實測可以使牆外訪問速度提升10倍以上,具體原理可以去查查。這個特性只有升級到Linux 4.9核心之後才支援,所以慣例升級下。
要在 CentOS 上安裝最新的核心版本,我們需要增加一個 ELRepo 源。首先,讓我們新增 ELRepo GPG key:

$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

再新增 RHEL-6,SL-7,CentOS-7 源:

$ rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

最後,安裝 kernel 4.10(目前最新核心版本)

$ yum --enablerepo=elrepo-kernel install kernel-ml

檢視當前作業系統內有多少個核心

$ awk -F` `$1=="menuentry " {print $2}` /etc/grub2.cfg

可以看到剛才新裝的4.10核心排在第一位,所以修改下系統之後啟動的核心為第一個

$ grub2-set-default 0

然後修改下/etc/sysctl.conf 檔案,使得一些tcp_bbr引數在重啟後生效

$ echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
$ echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf

重啟作業系統

$ reboot

重啟後檢視當前作業系統的核心

$ uname -a

如果是4.10核心,那麼檢視當前是否以啟用tcp_bbr

$ lsmod | grep tcp_bbr

不出意外的話,現在已經可以看到tcp_bbr的程式了。

配置一個新使用者

其實我是為了新建一個home目錄,以便待會下載各種原始碼包。

$ useradd test

給test使用者sudo的許可權,以便需要的時候提權

$ vim /etc/sudoers

找到這個檔案裡面的 root ALL=(ALL) ALL ,在這一行下面加一行一樣的

test  ALL=(ALL)   ALL

wq! 儲存退出

配置ssh免密登入

此時回到test使用者的家目錄 /home/test ,配置下金鑰,待會可以免密登陸到系統。

$ mkdir .ssh
$ cd .ssh/
$ touch authorized_keys
$ chown test:test authorized_keys
$ chmod 600 authorized_keys
$ cd ../
$ cdown -R test:test .ssh
$ chmod 700 .ssh

此時在本地電腦上使用git bash生成一個公鑰金鑰對

$ ssh-keygen -t rsa

然後你就可以在電腦的C盤使用者目錄下找到一個.ssh資料夾,裡面有剛剛生成的id_rsa, id_rsa.pub檔案,在xshell頂部操作欄開啟xftp,把剛生成的id_rsa.pub檔案上傳到/home/test目錄下。
此時回到xsehll,輸入命令

$ cat /home/test/id_rsa.pub >> /home/test/.ssh/authorized_keys

這樣就把公鑰裡面的檔案寫到了test使用者的authorized_keys檔案裡面。剛才已經把許可權都配置好了,所以按道理是可以直接xshell新建一個視窗,然後測試ssh免密登陸了(需要在xsehll的會話屬性裡面配置下私鑰,不然xsehll不知道你要用哪個檔案去登陸)
不過,我們還是需要加強一下ssh的安全性。

增強ssh的安全性

修改ssh的配置檔案/etc/ssh/sshd_config

$ vim /etc/ssh/sshd_config
#找到以下幾項,並按照我的修改
PermitRootLogin no         #禁止root登陸
StrictModes yes            #開啟嚴格模式,審查剛才的600 700許可權
RSAAuthentication yes      #開啟私鑰驗證
PubkeyAuthentication yes   #開啟公鑰驗證
AuthorizedKeysFile      .ssh/authorized_keys  #驗證檔案的位置
PermitEmptyPasswords no    #禁止空密碼登陸
PasswordAuthentication no  #禁止密碼登陸,應該是隻能金鑰登陸了
AllowUsers test            #允許test使用者登陸ssh

好了,儲存退出之後,直接重啟ssh服務(最好先開其他視窗測試下能否免密登陸再做這一步,否則待會可能就連不上了)

$ systemctl restart sshd

好了,以上是一些基本步驟,做完之後進入安裝正題,開始裝lnmp環境。

下載oneinstack安裝包

$ cd /home/test
$ wget http://mirrors.linuxeye.com/oneinstack-full.tar.gz    #我是國外伺服器所以採用這個地址
$ tar xzf oneinstack-full.tar.gz
$ cd oneinstack
$ yum -y install screen    #這個screen是個視窗,可以解決Linux命令只能一個螢幕顯示,不知道怎麼切換到別的視窗看其他程式,而且screen支援你睡個覺再起來看裡面的程式狀態。不像shell關掉之後就看不到裡面發生了什麼

注意事項

因為踩過坑,所以知道這個一鍵安裝包即將給我安裝的是怎樣的環境。我這裡主要想解決的是:

  • 想讓nginx編譯最新的openssl,並且支援http2

  • 想讓php編譯最新的openssl,並且支援http2

  • 讓curl編譯最新的openssl,並且支援http2

一鍵安裝包雖然都是原始碼編譯,但是編譯的時候連結的是系統預設的openssl 1.0.1e ,所以需要研究一鍵安裝包的原始碼。其中研究過程就不贅述了。。有興趣的可以自己一個檔案一個檔案開啟看。總之這個oneinstack寫的還是非常不錯的。。簡直把運維人員當小白了。。什麼事都幹好了。。

根據我的研究,整個oneinstack 需要修改以下幾個檔案:(點選可檢視我修改後的檔案,可以直接copy使用)

  1. ./options.conf

  2. ./versions.txt

  3. ./install.sh

  4. ./include/php-7.1.sh

  5. ./include/init_CentOS.sh

  6. ./include/check_sw.sh

  7. ./include/openssl.sh (這個檔案其實不用改,因為用不到)

修改檔案之後,在開始安裝oneinstack之前,我是先手動編譯安裝了openssl nghttp2 curl。因為nginx和php的編譯引數裡面會用到這些模組。

編譯安裝openssl 1.1.0e

$ wget https://www.openssl.org/source/openssl-1.1.0e.tar.gz
$ tar xzf openssl-1.1.0e.tar.gz
$ cd openssl-1.1.0e
$ ./Configure linux-x86_64 shared no-ssl2 no-ssl3 no-comp enable-ec_nistp_64_gcc_128 -Wl,-rpath,/usr/local/lib64    #我是64位系統,這裡我把lib庫放在lib64

$ make -j 4    #4個程式進行編譯,加快速度(可能)
$ make install

等待成功make install之後,到安裝目錄(預設是/usr/local/)

$ /usr/local/bin/openssl version
OpenSSL 1.1.0e  16 Feb 2017
 
$ ldd /usr/local/bin/openssl    #檢視載入了哪些庫
    linux-vdso.so.1 =>  (0x00007ffe2ffde000)
    libssl.so.1.1 => /usr/local/lib64/libssl.so.1.1 (0x00007faabe51f000)
    libcrypto.so.1.1 => /usr/local/lib64/libcrypto.so.1.1 (0x00007faabe07a000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007faabde6b000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007faabdc4f000)
    libc.so.6 => /lib64/libc.so.6 (0x00007faabd88d000)
    /lib64/ld-linux-x86-64.so.2 (0x000055a7f62cf000)

替換系統舊版openssl

$ mv /usr/bin/openssl /usr/bin/openssl.bak
$ mv /usr/include/openssl /usr/include/openssl.bak
$ ln -s /usr/local/bin/openssl /usr/bin/openssl
$ ln -s /usr/local/include/openssl /usr/include/openssl
$ openssl version    #這裡已經可以直接使用openssl命令了
OpenSSL 1.1.0e  16 Feb 2017

CFLAGS and CXXFLAGS

openssl已經升級完成了,接下來編譯nghttp需要用到GCC編譯器和G++編譯器,需要設定CFLAGS 和 CXXFLAGS引數。

$ export CFLAGS="-I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto"
$ export CXXFLAGS="-I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto"

解釋一下,這裡面的lssl是指 libssl.so , lcryoto 是指 libcrypto.so .
因為我剛才編譯openssl的時候指定的目錄是/usr/local/lib64.所以這裡的 -Wl,-rpath 我都指向了這個目錄。
好了,現在可以編譯安裝nghttp2了

編譯nghttp2

$ cd /home/test/oneinstack/src
$ tar xzf nghttp2-1.21.0.tar.gz
$ cd nghttp2-1.21.0
$ CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ./configure
...
    Compiler:
      C compiler:     gcc
      CFLAGS:         -I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto
      LDFLAGS:        
      C++ compiler:   g++
      CXXFLAGS:       -I/usr/local/include/ -L/usr/local/lib -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -lssl -lcrypto
...
    Libs:
      OpenSSL:        yes (CFLAGS=`-I/usr/local/include` LIBS=`-L/usr/local/lib64 -lssl -lcrypto`)
      
$ make -j 4
$ make install
Libraries have been installed in:
   /usr/local/lib

編譯cURL

$ cd /home/test/oneinstack/src
$ tar xzf curl-7.53.1.tar.gz
$ cd curl-7.53.1
$ ./configure --with-ssl=/usr/local --with-nghttp2=/usr/local
...
configure: Configured to build curl/libcurl:

  curl version:     7.51.0
  Host setup:       x86_64-pc-linux-gnu
  Install prefix:   /usr/local
  Compiler:         gcc
  SSL support:      enabled (OpenSSL)
  SSH support:      no      (--with-libssh2)
  zlib support:     no      (--with-zlib)
  GSS-API support:  no      (--with-gssapi)
  TLS-SRP support:  enabled
  resolver:         default (--enable-ares / --enable-threaded-resolver)
  IPv6 support:     enabled
  Unix sockets support: enabled
  IDN support:      no      (--with-{libidn2,winidn})
  Build libcurl:    Shared=yes, Static=yes
  Built-in manual:  enabled
  --libcurl option: enabled (--disable-libcurl-option)
  Verbose errors:   enabled (--disable-verbose)
  SSPI support:     no      (--enable-sspi)
  ca cert bundle:   /etc/ssl/certs/ca-certificates.crt
  ca cert path:     no
  ca fallback:      no
  LDAP support:     no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
  LDAPS support:    no      (--enable-ldaps)
  RTSP support:     enabled
  RTMP support:     no      (--with-librtmp)
  metalink support: no      (--with-libmetalink)
  PSL support:      no      (libpsl not found)
  HTTP2 support:    enabled (nghttp2)
  Protocols:        DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP

$ make -j 4
$ make install

檢視curl所在位置和連結庫

$ which curl
/usr/local/bin/curl

$ ldd /usr/local/bin/curl
    linux-vdso.so.1 =>  (0x00007fff4a358000)
    libssl.so.1.1 => /usr/local/lib64/libssl.so.1.1 (0x00007f6c3edfa000)
    libcrypto.so.1.1 => /usr/local/lib64/libcrypto.so.1.1 (0x00007f6c3e955000)
    libcurl.so.4 => /usr/local/lib/libcurl.so.4 (0x00007f6c3e6e9000)
    libz.so.1 => /lib64/libz.so.1 (0x00007f6c3e4c8000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f6c3e106000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f6c3df02000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6c3dce6000)
    libnghttp2.so.14 => /usr/local/lib/libnghttp2.so.14 (0x00007f6c3dab6000)
    /lib64/ld-linux-x86-64.so.2 (0x000055cf5fba3000)

$ /usr/local/bin/curl -V
curl 7.53.1 (x86_64-pc-linux-gnu) libcurl/7.53.1 OpenSSL/1.1.0e zlib/1.2.7 nghttp2/1.21.0
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy

可以看到,已經支援openssl 1.1.0e 和 http2 。

更新系統連結庫

現在基本完成了需要的編譯工作,但是為了保證不出錯,需要更新一下系統連結庫。

$ echo "/usr/local/lib" >> /etc/ld.so.conf
$ echo "/usr/local/lib64" >> /etc/ld.so.conf
$ ldconfig -V    #使生效

安裝oneinstack

到此為止,已經完成了前期的鋪墊工作,可以開始裝oneinstack了。

$ cd /home/test/oneinstack
$ screen -S lnmp
$ ./install.sh

我這裡的選擇是:nginx-mysql5.7-php7.1.3-opacache,其他的都沒裝。
不出意外的話,就可以等待著安裝完成了。如果中間有退出shell,再次連線之後可以通過

screen -r

開啟之前的安裝視窗。安裝完成後重啟系統即可。
先寫到這裡,之後的一些額外配置下次再寫。
先佔個位

配置虛擬主機

搭建git伺服器

通過hooks鉤子自動同步git倉庫內容到網站根目錄

配置firewalld防火牆禁用無關埠

配置rm命令為mv命令,防止root誤刪 rm -rf /*

nginx.conf的相關配置

搭建ss伺服器

相關文章