Debian/Ubuntu 環境下自行編譯及安裝 Nginx 網頁伺服器

此篇文章主要記錄在Debian/Ubuntu系統環境中手動編譯及安裝自己所需要的Nginx版本,以方便筆者自己日後需要在Debian/Ubuntu環境中手動編譯及架設Nginx網頁伺服器時可以來做一個參考。筆者日後會持續更新,但並不會以Nginx每一次所釋出的新版本來進行更新,而是以每幾個月的頻率來進行更新此篇文章。

本篇文章所使用的Nginx版本為nginx-1.14.1 stable版本,當然在Nginx的官網上你應該也會看到mainline版本,而mainline版本就是目前還在開發的版本,但因為stable會比mainline版本還要來的穩定,所以一般來說建議在production環境中是使用stable版本。另外,筆者會為網站綁上SSL/TLS憑證,因為網站使用HTTPS協定好處就是,除了可以讓網站更加安全之外,還可以使用一些在HTTP協定中無法使用的技術,比如說HTTP/2或Brotli壓縮格式等等的支援,這樣就可以讓網站在訪問的時候,速度也會有所提升。在編譯Nginx的時候,因為通常系統中內建的OpenSSL加密函數庫版本會有些舊的關係,所以此篇文章也會手動編譯新版本的OpenSSL,當然使用新版本的OpenSSL,也就可以使用到一些新東西,比如說TLS 1.3協定的支援。

**此篇文章最後更新時間為2018/11月。

**目前最新的Chrome 70版本與Firefox瀏覽器,預設已支援TLS 1.3協定,而在OpenSSL中,有支援TLS 1.3的OpenSSL為openssl-1.1.1版本,而這也是本篇文章中所使用的OpenSSL版本。

**假如你不知道要如何為網站加上HTTPS協定,那你參考完此篇文章,及編譯好Nginx之後,就可以參考筆者之前寫的Let's Encrypt機構提供的SSL/TLS憑證服務,來為你自己網站設定好HTTPS協定。

1)進行編譯Nginx與OpenSSL,以及你所需要的Nginx第三方模組。

Step 1:將Debian/Ubuntu系統的套件資訊與版本更新到最新。

sudo apt-get update && sudo apt-get upgrade -y

 

Step 2:安裝在編譯Nginx時,需要用到的套件及函式庫。

sudo apt-get install build-essential libpcre3 libpcre3-dev zlib1g-dev git -y

 

Step 3:新增一個編譯用的目錄,及cd至剛剛新增好的目錄位置。

mkdir ~/nginx_compile && cd ~/nginx_compile

 

Step 4:下載新版本的Nginx網頁伺服器。

**在nginx: download頁面中,你應該可以看到Stable和Mainline兩種的Nginx版本,一般來說Mainline版本的新功能會比Stable版本來得多一些,但在穩定性方面是Stable版本會比Mainline版本還要來得高。

Stable版本

wget -c https://nginx.org/download/nginx-1.14.1.tar.gz && tar zxf nginx-1.14.1.tar.gz && rm nginx-1.14.1.tar.gz

Mainline版本

wget -c https://nginx.org/download/nginx-1.15.6.tar.gz && tar zxf nginx-1.15.6.tar.gz && rm nginx-1.15.6.tar.gz

 

Step 5:下載主流瀏覽器已經有在支援TLS 1.3協定的OpenSSL版本。

**以Chrome 70開始與最新的Firefox版本,已經支援最新版本的TLS 1.3正式版,而在OpenSSL版本中,有支援TLS 1.3為openssl-1.1.1版本。

**目前的openssl-1.1.1版本已經在2018/9月間釋出穩定版本,所以你可以在production環境中使用openssl-1.1.1版本了,關於OpenSSL版本的問題,請自行至OpenSSL-Downloads頁面查看。

wget -c https://www.openssl.org/source/openssl-1.1.1.tar.gz && tar zxf openssl-1.1.1.tar.gz && rm openssl-1.1.1.tar.gz

 

Step 6:下載你所需要的第三方模組,筆者會以ngx_brotli為例。(非必要)

**Nginx網站上有列出第三方模組的資源,你可以至NGINX 3rd Party Modules頁面來參考有哪些是你所需要的模組。

ngx_brotli

Brotli是由Google的工程師所開發的一項壓縮演算法專案,目前運用在資料壓縮,當然主要是為了加快網頁的傳輸速度。目前Brotli已被各大主流瀏覽器支援,包含Chrome、Firefox、Edge與Safari等等。

git clone https://github.com/google/ngx_brotli.git

pushd ngx_brotli

git submodule update --init

popd

 

Step 7:cd至你已解壓縮好的Nginx目錄位置,以可以設定需要編譯的參數。

**下面參數僅作參考,你可以自己更改你所需要的設定。

**因為筆者沒有指定prefix路徑,所以Nginx等下在安裝時,會在預設的『/usr/local/nginx/』目錄,假如你要更改,也是在下面configure參數中進行更改。

**Nginx的Log檔,預設都會存放在『/usr/local/nginx/logs』目錄,但筆者想要日後比較好管理Log檔,所以將http-log-path和error-log-path移到『/var/log/nginx』目錄。

cd nginx-1.14.1

  1. ./configure \
  2. --http-log-path=/var/log/nginx/access.log \
  3. --error-log-path=/var/log/nginx/error.log \
  4. --with-http_v2_module \
  5. --with-http_ssl_module \
  6. --with-http_gzip_static_module \
  7. --with-openssl=../openssl-1.1.1 \
  8. --add-module=../ngx_brotli

 

Step 8:開始進行編譯,編譯過程可能會有些久。

make

 

Step 9:安裝Nginx至你的主機。

sudo make install

 

Step 10:測試有沒有錯誤。

sudo /usr/local/nginx/sbin/nginx -t

如果看到以下的訊息,則代表此次編譯已成功完成。

  1. nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
  2. nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

 

Step 11:當然你也可以使用指令查看你此次編譯好的Nginx版本及其他的詳細資料。

sudo /usr/local/nginx/sbin/nginx -V

 

Step 12:接著就可以啟動Nginx。

sudo /usr/local/nginx/sbin/nginx

 

2)從GitHub下載shell script,以可以方便管理Nginx網頁伺服器及能讓Nginx在伺服器開機時能自動執行。

Step 1:編譯及安裝好Nginx之後,接下來為了可以方便管理Nginx網頁伺服器,所以需要建立一個shell script,你可以直接從GitHub下載nginx-startup-script-for-debian-ubuntu.sh至你的『/etc/init.d』目錄,並將名稱更改為『nginx』。

sudo wget -O /etc/init.d/nginx https://raw.githubusercontent.com/KJieGitHub/Nginx/master/nginx-script/nginx-startup/nginx-startup-script-for-debian-ubuntu.sh

 

Step 2:將其下載好的shell script設定為可執行的權限。

sudo chmod +x /etc/init.d/nginx

 

Step 3:重新載入systemd。

sudo systemctl daemon-reload

 

Step 4:測試指令是否能正常執行。

sudo systemctl start nginx

 

Step 5:以後管理Nginx時,只需輸入以下的指令就可以了。

啟動Nginx

sudo systemctl start nginx

停止Nginx

sudo systemctl stop nginx

重啟Nginx

sudo systemctl restart nginx

重新載入Nginx的config檔

sudo systemctl reload nginx

 

Step 6:設定在開機時自動執行Nginx網頁伺服器。

sudo update-rc.d -f nginx defaults

 

3)讓網頁伺服器支援TLS 1.3協定及Brotli壓縮格式。

TLS 1.3(非必要)

Step 1:因為筆者上面有進行編譯openssl-1.1.1版本,且Nginx在1.13或以上的版本也已開始支援TLS 1.3,所以接下來就可以在Nginx設定檔中添加TLS 1.3的支援。

**筆者在之前已經寫了為Nginx加上SSL憑證的配置(相關配置在第二頁),但那篇教學僅支援TLS 1.0、TLS 1.1及TLS 1.2的協定,當然假如你不知道要怎麼為網站配置SSL憑證,你也可以先參考那篇文章。

如以下在『ssl_protocols』的後面加入『TLSv1.3』的支援:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

因為需要讓瀏覽器優先支援TLS1.3協定,所以一定要在『ssl_ciphers』的開始添加TLS 1.3的密碼套件,而OpenSSL支援了哪些密碼套件?你可以參考OpenSSL Blog的Using TLS1.3 With OpenSSL-Ciphersuites文章。

**不要忘記密碼套件(ciphersuites)之間需要有『:』隔開,如果你添加了新的密碼套件,請不要忘記加上『:』。

**筆者下面所列出的『ssl_ciphers』,是可以支援『TLS 1.0、TLS 1.1、TLS 1.2及TLS 1.3』的協定。

ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

 

Step 2:為網站添加完TLS 1.3協定之後,請不要忘記要先測試設定檔是否有設定錯誤,如果無誤的話,就可以重新載入Nginx的設定檔了。

sudo /usr/local/nginx/sbin/nginx -t

sudo systemctl reload nginx

 

Step 3:接著你應該可以看到遊覽器是有優先執行TLS 1.3協定的,以筆者的此網站來說,可以看到Chrome顯示為『Connection - secure (strong TLS 1.3)』及下面一段文字顯示為『The connection to this site is encrypted and authenticated using TLS 1.3 (a strong protocol), X25519 (a strong key exchange), and AES_256_GCM (a strong cipher).』。要如何查看?以Chrome瀏覽器來說,按下鍵盤的『F12』鍵或者鍵盤的『Ctrl+Shift+C』開啟Chrome開發人員工具,然後在上面的功能列選擇『Security』頁籤,就可以看到『Connection』顯示的TLS版本了。除了可以由瀏覽器來判斷你的網站是否有啟用TLS 1.3協定之外,另外你也可以經由第三方檢測服務,如:Qualys SSL Labs所提供的SSL Server Test線上服務來檢查網站是否有啟用了TLS 1.3協定,如有檢測到網站有啟用TLS 1.3協定,那檢測報告的結果會顯示『This server supports TLS 1.3 (RFC 8446).』。

 

Brotli(非必要)

Step 1:如果你在編譯Nginx時,有為Nginx增加Brotli壓縮格式的支援,那就可以在『nginx.conf』設定檔中添加Brotli的設定檔。

**Brotli壓縮格式僅能在HTTPS協定下才能使用。

**一般來說假如你是跟著此篇教學來進行設定,那『nginx.conf』的預設路徑位置如下:

sudo vim /usr/local/nginx/conf/nginx.conf

開啟『nginx.conf』設定檔之後,就可以添加Brotli的支援了,一般來說,習慣在Gzip的下面添加Brotli的支援:

  1. ## gzip Compression.
  2. gzip on;
  3.     # ... (Gzip壓縮格式的其他設定。)
  4. ## brotli Compression.
  5. brotli on;
  6. brotli_comp_level 6;
  7. #『brotli_types』的值僅作參考,請依你的環境去做設定。
  8. brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/x-icon application/vnd.ms-fontobject font/opentype application/x-font-ttf;

 

Step 2:添加完成後,一樣不要忘記要先測試設定檔是否有設定錯誤,如果無誤的話,就可以重新載入Nginx的設定檔。

sudo /usr/local/nginx/sbin/nginx -t

sudo systemctl reload nginx

 

Step 3:接著就可以檢查網站是否有成功套用到Brotli壓縮格式。

檢查Brotli壓縮格式方法一:筆者以chrome來說,按下鍵盤的『F12』鍵或者鍵盤的『Ctrl+Shift+C』開啟Chrome開發人員工具,在上面的功能列選擇『Network』頁籤,現在載入你的網站頁面,然後在『Name』中選擇第一項,你應該可以看到『Headers』頁籤,接著就可以檢查了,在『Response Headers』區塊,你應該可以看到『content-encoding: br』,這就表示Brotli壓縮格式設定成功了。

檢查Brotli壓縮格式方法二:可以藉由第三方網站來檢查你的網站是否有支援Brotli壓縮格式,當然這檢查方法是最簡單的,連結至KeyCDN-Brotli Test,在URL欄位輸入你網站的網址,取消勾選『Public』不要公開顯示檢測網址,及點擊『Test』,就可以看到檢測結果了。如筆者的網站檢測結果為『Yeah! www.pcsetting.com supports Brotli compression.』,則代表是有支援Brotli壓縮格式的。

 

4)Nginx的Log檔整理。

自己編譯Nginx有一個問題就是,Nginx所產生出來的Log檔,在每天的日夜累積之後,Log檔就變得很肥大,所以希望就是Nginx的Log檔能每日定期分割及歸檔,以及能刪除掉舊的Log檔,當然這很好實現,只需使用Linux的logrotate服務就可以處理了。

Step 1:為了方便日後管理Nginx的Log檔,你可以直接從GitHub下載筆者的nginx-log-logrotate.conf至你的『/etc/init.d』目錄,並將名稱更改為『nginx』。

sudo wget -O /etc/logrotate.d/nginx https://raw.githubusercontent.com/KJieGitHub/Nginx/master/nginx-conf/nginx-logrotate/nginx-log-logrotate.conf

 

Step 2:因為有可能你存放Nginx的Log檔位置會跟筆者不一樣,甚至有可能你還要更改其他的參數,所以建議你還是需要自行再次查看logrotate的nginx檔案內容。

sudo vim /etc/logrotate.d/nginx

 

Step 3:如以下所示你可以自己更改至你自己所需要的設定。

  1. /var/log/nginx/*.log {    #Nginx Log檔存放的位置 #請確定Nginx的Log檔是否存放在這個位置,假如不是請自行更改到正確的路徑位置
  2.     daily    #每日進行分割,當然還有其他值,如:weekly,monthly,yearly
  3.     missingok    #允許Log檔不存在,預設值為nomissingok
  4.     dateext    #使用日期來做命名格式,例子:error.log-20180419
  5.     rotate 10    #允許保留的Log檔份數,筆者設定為10份,如果超過10份,那最舊的Log檔將會被刪除
  6.     compress    #Log檔分割完成後,就會進行壓縮,預設會使用Gzip格式進行壓縮
  7.     delaycompress    #與compress值一起用,Log檔延後一次壓縮
  8.     notifempty    #如果Log檔為空就不分割
  9.     sharedscripts    #執行附加的script
  10.     postrotate    #postrotate/endscript分割log後需要執行的script,nginx需重啟服務之後,才能再寫入新的log
  11.         if [ -f /usr/local/nginx/logs/nginx.pid ]; then
  12.             kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
  13.         fi
  14.     endscript
  15. }

 

Step 4:強制執行logrotate的nginx檔案一次,以可以來測試logrotate在執行時是否會有錯誤。

sudo logrotate -vf /etc/logrotate.d/nginx

 

**此處是logrotate執行Nginx的設定檔有問題時才使用:假如遇到Logrotate服務執行Nginx的logrotate檔有問題,並且無法解決時,那你可以嘗試使用另外一個nginx-log-logrotate-no-script.conf,使用這個設定檔的缺點就是,Log檔在分割的時候,可能會有log沒有記錄到的風險。

sudo wget -O /etc/logrotate.d/nginx https://raw.githubusercontent.com/KJieGitHub/Nginx/master/nginx-conf/nginx-logrotate/nginx-log-logrotate-no-script.conf

 

5)更新Nginx網頁伺服器。

更新Nginx跟在安裝Nginx很像,一樣都是要重新編譯,只是到最後編譯完成時,是『make upgrade』,不是『make install』,這也是主要注意的地方。

**筆者這邊假設將nginx更新至nginx-1.15.6的mainline版本及OpenSSL使用穩定版本的openssl-1.1.1版本。

Step 1:新增一個目錄及cd至該目錄。

mkdir ~/nginx_update && cd ~/nginx_update

 

Step 2:下載你要更新的Nginx版本。

wget -c https://nginx.org/download/nginx-1.15.6.tar.gz && tar zxf nginx-1.15.6.tar.gz && rm nginx-1.15.6.tar.gz

 

Step 3: 下載你要的OpenSSL版本。

wget -c https://www.openssl.org/source/openssl-1.1.1.tar.gz && tar zxf openssl-1.1.1.tar.gz && rm openssl-1.1.1.tar.gz

 

Step 4:下載你所需要的第三方模組,筆者以ngx_brotli為例。

git clone https://github.com/google/ngx_brotli.git

pushd ngx_brotli

git submodule update --init

popd

 

Step 5:cd至你已解壓縮好的Nginx目錄位置,以可以來進行設定參數及進行編譯。

cd nginx-1.15.6

  1. ./configure \
  2. --http-log-path=/var/log/nginx/access.log \
  3. --error-log-path=/var/log/nginx/error.log \
  4. --with-http_v2_module \
  5. --with-http_ssl_module \
  6. --with-http_gzip_static_module \
  7. --with-openssl=../openssl-1.1.1 \
  8. --add-module=../ngx_brotli

make

 

Step 6:備份舊的nginx,並將其命一個名稱。

sudo mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old

 

Step 7:將編譯好的nginx,複製到Nginx執行的目錄。

sudo cp ./objs/nginx /usr/local/nginx/sbin/nginx

 

Step 8:進行Nginx更新。

sudo make upgrade

 

Step 9:測試有沒有錯誤。

sudo /usr/local/nginx/sbin/nginx -t

如果看到以下的訊息,則代表此次編譯已成功完成。

  1. nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
  2. nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

 

Step 10:當然你也可以使用指令查看你此次更新好的Nginx版本及其他的詳細資料。

sudo /usr/local/nginx/sbin/nginx -V