於 GCP ubuntu 20.04 同時運行 odoo 10 & odoo 15

使用 NGINX 提供多個網站的 SSL 加密服務 – 2020 版

使用 NGINX 為 Odoo 提供 SSL 加密服務 中的設定在 2020 年已經有點過時了,因此追加更新修正後的內容在此篇

由於安全性的問題,所有瀏覽器在 2020 年三月移除支援 TLS v1.0、TLS v1.1 協定

在 ssl labs 的測試中,有支援 TLS v1.0、TLS v1.1 協定時只能拿到 B

因此需將此部份

        ssl_protocols TLSv1.0 TLSv1.1 TLSv1.2;

修正為

        ssl_protocols TLSv1.2;

而在多個網站同時架設在一台主機上時,因此 ssl_session_cache 會出現快取無法重複設定的問題

這時候可以通過修改 nginx.conf 讓全部網站共用此 ssl_session_cache

vim /etc/nginx/nginx.conf

將這段

    include /etc/nginx/conf.d/*.conf;

修改為

    include /etc/nginx/conf.d/*.conf;

    ## SSL Cache Setting
    ssl_session_cache   shared:SSL:50m;
    ssl_session_timeout 10m;

以下是以 Magento 2 作為範例寫出來的設定檔(仍需要修改)

/etc/nginx/nginx.conf

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    server_tokens       off;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    ## Magento 2 fastcgi_backend
    upstream fastcgi_backend {
        server  unix:/run/php-fpm/php-fpm.sock;
    }

    ## SSL Cache Setting
    ssl_session_cache   shared:SSL:50m;
    ssl_session_timeout 10m;
}

/etc/nginx/conf.d/m2.cewolf.com.tw.conf

    server {
        listen 80;
        server_name m2.cewolf.com.tw;
        #set $MAGE_ROOT /usr/share/nginx/magento_hanyu;
        #include /usr/share/nginx/magento_hanyu/nginx.conf.sample;
        return 301 https://m2.cewolf.com.tw$request_uri;

        #location ^~ /.well-known/acme-challenge/ {
        #default_type    "text/plain";
        #root /etc/letsencrypt/;
        #}
    }

    server {
        listen [::]:443 ssl http2;
        listen 443 ssl http2;

        server_name m2.cewolf.com.tw;
        set $MAGE_ROOT /usr/share/nginx/magento_hanyu;
        include /usr/share/nginx/magento_hanyu/nginx.conf.sample;

        ssl_certificate /etc/letsencrypt/live/m2.cewolf.com.tw/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/m2.cewolf.com.tw/privkey.pem;
        ssl_protocols TLSv1.2;
        ssl_dhparam /etc/dehydrated/dhparam.pem;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
        ssl_prefer_server_ciphers on;

        # Enable OSCP Stapling for Nginx web server
        # If you're using the SSL from Letsencrypt,
        # use the 'chain.pem' certificate
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8 8.8.4.4;
        ssl_trusted_certificate /etc/letsencrypt/live/m2.cewolf.com.tw/chain.pem;

        # Enable HTTP Strict-Transport-Security
        # If you have a subdomain of your site,
        # be carefull to use the 'includeSubdomains' options
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    }

 

PHP-FPM 效能調校 on CentOS 7

目前在 GCloud 託管的網站經常會出現不明情況死機

進去使用 TOP 稍微檢查一下,發現記憶體的使用量非常大

使用下面語法檢查 PHP-FPM 每一個行程平均記憶體使用量,發現每個行程約用 170 MB

ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

使用下面語法檢查共有多少開啟的行程,可以發現有許多開啟中的行程

ps -ylC php-fpm --sort:rss

根據分析我們的網站同時上線人數並沒有很多,所以初步判定是設定上的問題

vim /etc/php-fpm.d/www.conf

pm.max_requests

每個子程序在接受多少請求後自動重啟,可有效防止記憶體溢出,預設值等於0,如果等於0不會自動終止。

網路上部份設置較大52100、102400之類的,建議可以抓在1000左右,基礎服務量提高應先調整線程數為主要重點,雖然重啟會消耗資源跟風險比起來安全更重要。

如果是瞬間流量就是要調整此數值來對應,數字越大瞬間能接受的高峰量越高,調整線程數是每秒一次,超過一秒仍有需求後會另開新線程來輔助。

pm.max_requests = 1000

修改完後重啟服務

systemctl restart php-fpm

修改這個參數後,同時開啟的行程只剩下 9 個,記憶體平均使用量只剩下 100MB

還需要再繼續觀察看看

 

2020.04.14

同時開啟的行程共有 35 個,每個消耗 123M,但網站線上只有三個人

再次調整設定

pm.max_requests = 1000
pm.max_spare_servers = 35

改成

pm.max_requests = 500
pm.max_spare_servers = 20

看看能否讓線程提早關閉,並減少閒置的線程

經過兩天的測試,同時開啟的行程剩下 15 個,平均每個消耗 88M

 

於 2020/06/28

經過兩天的測試,同時開啟的行程達到 20 個,平均每個消耗 84M,共消耗 1680 MB

試著再調整看看

pm.max_requests = 400
pm.max_spare_servers = 15

於 2020/07/02

同時開啟的行程達到 15 個,平均每個消耗 51M,共消耗 765MB

剩餘記憶體還有 1042M,在可以接受的範圍內

參考資料:

php-fpm 效能優化

Nginx 與 PHP-FPM 最佳化效能設定教學與技巧

Nginx 啟用 PHP-FPM 服務狀態監控網頁教學

使用 certbot 申請 Let’s Encrypt 免費 SSL 憑證

由於目前 Dehydrated 無法正常使用,官方的 certbot 改的簡單許多,建議使用 certbot 來申請

目前我使用過兩種申請方式

  1. webroot 驗證:優點是不需要中斷現有的網路服務,但需要修改 NGINX 設定檔
  2. DNS 驗證:只需要修改 DNS 設定即可通過認證,但後續會需要手動續約,不推薦

安裝 certbot-nginx 主程式

yum install -y python-certbot-nginx

Method 1:webroot 驗證申請

需要先修改網址的 NGINX 設定,最前面改為下方樣式

    # http -> https
    server {
        listen 80;
        server_name  www.cewolf.com.tw;

        location ~ /\.well-known\/acme-challenge {
                root /etc/letsencrypt;
        allow all;
        }
        if ($request_uri !~ /\.well-known) {
                return 301 https://$server_name$request_uri;
        }
    }

重新載入 NGINX 設定檔

 service nginx reload

申請 SSL 憑證

certbot certonly --webroot -w /etc/letsencrypt/ -d www.cewolf.com.tw

跳出以下的內容就代表成功了

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for m2.cewolf.com.tw
Using the webroot path /etc/letsencrypt for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.cewolf.com.tw/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.cewolf.com.tw/privkey.pem
Your cert will expire on 2020-03-20. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

接著修改 NGINX 設定檔的 SSL 設定

vim /etc/nginx/conf.d/www.cewolf.com.tw.ssl.conf

加入這兩行

ssl_certificate /etc/letsencrypt/live/www.cewolf.com.tw/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.cewolf.com.tw/privkey.pem;

重新載入 NGINX 設定即可

systemctl reload nginx

Method 2:DNS 驗證申請

certbot -d m2.cewolf.com.tw --manual --preferred-challenges dns certonly

會跳出 DNS 驗證值

Please deploy a DNS TXT record under the name
_acme-challenge.www.cewolf.com.tw with the following value:

O3kP443ms6OP84K8NQnZv_vvZ5HAHMKMBdqqSIyxKlo

直接在 DNS Record 設定 txt 之後需確認可成功查詢

nslookup -type=TXT _acme-challenge.www.cewolf.com.tw

接著按下 Enter 就看到,就代表成功了

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.cewolf.com.tw/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.cewolf.com.tw/privkey.pem
Your cert will expire on 2020-03-20. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

接著修改 NGINX 設定檔的 SSL 設定

vim /etc/nginx/conf.d/www.cewolf.com.tw.ssl.conf

加入這兩行

ssl_certificate /etc/letsencrypt/live/www.cewolf.com.tw/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.cewolf.com.tw/privkey.pem;

重新載入 NGINX 設定

systemctl reload nginx

記得確認 SSL 憑證失效日是否有成功延後喔!

自動展延憑證

我們可以利用 cron 這個小程式來定期自動展期,首先編輯 crontab 設定檔

vim /etc/crontab

加入這兩行(於每周六 AM 3:00 檢查第一組網域是否需要展期,AM 3:30 reload NGINX)

00 3 * * 6 root certbot -d www.cewolf.com.tw --no-redirect
10 3 * * 6 root certbot -d km.cewolf.com.tw --no-redirect
20 3 * * 6 root certbot -d www.gapl.com.tw --no-redirect
30 3 * * 6 root systemctl reload nginx.service

重新啟動 cron service

systemctl restart crond.service

完成!

確認憑證狀態

有時候會收到 letsencrypt 寄來的「憑證即將到期通知 Let’s Encrypt certificate expiration notice for domain “your_domain.com”」。這時候可以輸入下面的指令確認狀態。

sudo certbot certificates

使用 NGINX 為 Odoo 提供 SSL 加密服務

於 Google Compute Engine CentOS 7.0 建置 Magento 使用環境

隨著官網的重要性越來越高,將 Magento 雲端化已經是必要的事情了(免除停電、網路斷線等風險)

以下是在 Google Compute Engine(GCE) 中的 CentOS 7.0 進行環境設定

GCE CentOS 7.0 預設模組版本為 PHP 5.4.16、NGINX 1.12.2、OpenSSL 1.0.2k,已經符合我們的最低需求了

資料庫則嘗試採用 Google SQL 取代本機安裝 MariaDB(MySQL) 的方式

 

安裝

為了方便設定,先設定 root 密碼,在用 su 指令切換至 root 使用者

sudo passwd root
su

安裝 NGINX 1.12.2

yum -y install nginx

安裝 PHP 5.4.16 + Zend Optimizer+

yum -y install php php-mysql php-gd php-fpm php-mbstring php-mcrypt php-pear php-process php-tidy php-xml php-xmlrpc php-soap
yum -y install php-pecl-zendopcache

安裝 PHP 5.6 + opcache

rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum -y install php56w php56w-mysql php56w-gd php56w-fpm php56w-mbstring php56w-mcrypt php56w-pear php56w-process php56w-tidy php56w-xml php56w-xmlrpc php56w-soap php56w-devel php56w-opcache

安裝新版 CURL(Magento 必須套件)

rpm -Uvh http://www.city-fan.org/ftp/contrib/yum-repo/rhel7/x86_64/city-fan.org-release-1-13.rhel7.noarch.rpm
sed -i '5c enabled=1' /etc/yum.repos.d/city-fan.org.repo
yum -y install curl libcurl

設定

修改 SELINUX 模式,http_can_sendmail 設定

sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config && setsebool -P httpd_can_sendmail 1

修改 php.ini 設定

sed -i 's/short_open_tag = Off/short_open_tag = On/' /etc/php.ini && sed -i 's/memory_limit = 128M/memory_limit = 512M/' /etc/php.ini && sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php.ini

修改 php-fpm 設定

sed -i 's@listen = 127.0.0.1:9000@listen = /var/run/php-fpm/php-fpm.sock@' /etc/php-fpm.d/www.conf && sed -i 's@;listen.owner = nobody@listen.owner = nginx@' /etc/php-fpm.d/www.conf && sed -i 's/;listen.group = nobody/listen.group = nginx/' /etc/php-fpm.d/www.conf && sed -i 's/user = apache/user = nginx/' /etc/php-fpm.d/www.conf && sed -i 's/group = apache/group = nginx/' /etc/php-fpm.d/www.conf

優化 /etc/php.d/opcache.ini 設定

sed -i 's/opcache.memory_consumption=128/opcache.memory_consumption=256/' /etc/php.d/opcache.ini && sed -i 's/opcache.max_accelerated_files=4000/opcache.max_accelerated_files=16000/' /etc/php.d/opcache.ini

修改 nginx.conf 設定檔

vim /etc/nginx/nginx.conf

移除此區塊

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        location / {
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

新增 nginx/conf.d/magento.conf (80 port 專用)

vim /etc/nginx/conf.d/magento.conf

填入以下設定

server {
    listen       80;
    server_name  104.199.145.27;
    root   /usr/share/nginx/html;
    index index.php index.html index.htm;
    location ~* \.(ico|css|js|gif|jpe?g|png|ogg|ogv|svg|svgz|eot|otf|woff)(\?.+)?$ {
        expires max;
        log_not_found off;
        add_header Access-Control-Allow-Origin "*";
    }
    #location /.well-known/acme-challenge/ {
    #    alias /var/www/dehydrated/;
    #}
    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }
    ## These locations are protected
    location /downloader/ {
        allow 192.168.0.0/24;
        deny all;
    }
    ## These locations are protected
    location ~ /(dev|app|includes|lib|media/downloadable|pkginfo|var)/ {
        deny all;
    }
    location @handler { ## Magento uses a common front handler
        rewrite / /index.php;
    }
    location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
        rewrite ^(.*.php)/ $1 last;
    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    #if ($bad_referer) {
    #    return 444;
    #}
}

新增 nginx/conf.d/magento.ssl.conf (443 port 專用)

vim /etc/nginx/conf.d/magento.ssl.conf

填入以下設定

server {
    listen       443 ssl http2;
    server_name  www.gapl.com.tw www.glamp.com.tw;
    root   /usr/share/nginx/html;
    index index.php index.html index.htm;

    ssl_certificate      /etc/dehydrated/certs/www.gapl.com.tw/fullchain.pem;
    ssl_certificate_key  /etc/dehydrated/certs/www.gapl.com.tw/privkey.pem;
    ssl_dhparam /etc/dehydrated/dhparam.pem;

    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 180m;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4;
    add_header Strict-Transport-Security "max-age=31536000" always;

    location ~* \.(ico|css|js|gif|jpe?g|png|ogg|ogv|svg|svgz|eot|otf|woff)(\?.+)?$ {
        expires max;
        log_not_found off;
        add_header Access-Control-Allow-Origin "*";
        add_header Strict-Transport-Security "max-age=31536000" always;
    }

    location / {
        deny 203.24.188.5;
        deny 203.24.188.10;
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    ## These locations are protected
    location /dev/ {
        allow 192.168.0.0/16;
        deny all;
    }

    location /downloader/ {
        allow 192.168.0.0/16;
        deny all;
    }
    ## These locations are protected
    location ~ /(app|includes|lib|media/downloadable|pkginfo|var)/ {
        deny all;
    }

    location @handler { ## Magento uses a common front handler
        rewrite / /index.php;
    }

    location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
        rewrite ^(.*.php)/ $1 last;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 600s;
    }

    if ($bad_referer) {
        return 444;
    }

}

 

設定開機啟動 NGINX & PHP-FPM 服務

systemctl enable nginx.service && systemctl enable php-fpm.service

下載 Magento 備份檔並轉移至網站資料夾,並重新啟動讓 SELINUX 設定生效

curl -O https://storage.googleapis.com/www-gapl/magento_2017-12-29.tar.gz
rm -rf /usr/share/nginx/html
tar -C /usr/share/nginx/ -zxvf magento_2017-12-29.tar.gz
chown -R nginx: /usr/share/nginx/html
reboot

下一步 SSL 轉移請前往:於 Google Compute Engine CentOS 7.0 設定 Dehydrated 與轉移 SSL 憑證

 

 

 

 

遇到 403 Forbidden
Nginx Error Log(/var/log/nginx/error.log) 中顯示
2017/12/30 18:16:42 [error] 871#0: *2 open() “/usr/share/nginx/html/LICENSE.txt” failed (13: Permission denied), client: 60.251.46.241, s
erver: 104.199.145.27, request: “GET /LICENSE.txt HTTP/1.1”, host: “104.199.145.27”

 

 

延伸閱讀

Google Compute Engine 使用 root 和密碼登入

PHP 5.4, APC/Zend Optimizer+ on Centos 7

PHP 5.6 on CentOS/RHEL 7.4 and 6.9 via Yum

使用 Dehydrated 申請 Let’s Encrypt 免費 SSL 憑證

使用 NGINX 作為 Reverse Proxy 加速 Odoo

要加速 Odoo 可以從幾個方向著手:

  • 調整 Odoo 的 config 檔
  • 調整 PosgreSQL 的 config 檔
  • 使用 NGINX 作為 Reverse Proxy(反向代理),甚至進一步開啟 HTTP/2(需一併設定 SSL)

我們在這一篇會著重在設定 NGINX 作為 Reverse Proxy

編輯 NGINX 的 conf 檔

 vim /etc/nginx/conf.d/odoo.conf

內容設定為

server {
    listen       80;
    server_name  192.168.1.244 odoo.glamping.tw;

    location  / {
        proxy_pass http://odoo.gapl.com.tw;
        proxy_buffer_size 128k;
        proxy_buffers 16 64k;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~* /web/static/ {
        proxy_cache_valid 200 60m;
        proxy_buffering on;
        expires 864000;
        proxy_pass http://odoo.gapl.com.tw;
    }

    error_page   500 502 503 504  /50x.html;
#    location = /50x.html {
#        root   /usr/share/nginx/html;
#    }
}

關於其中的參數可以參考 Understanding Nginx HTTP Proxying, Load Balancing, Buffering, and Caching 這篇

REVERSE PROXY WITH ODOO 8 | NGINX | UBUNTU 14.04 LTS | LONGPOLLING 這篇

建議加大  proxy_buffer_size 與 proxy_buffers 才能處理 Odoo 的 Web requests

設定完後,重新啟動 NGINX 就可以進行測試囉

 

 

/etc/letsencrypt/live/odoo.glamping.tw/fullchain.pem

注意事項:

NGINX 設定檔中的 proxy_pass 參數如果有加入 port 號,NGINX 會啟動失敗,不確定原因

 

參考資料:

REVERSE PROXY WITH ODOO 8 | NGINX | UBUNTU 14.04 LTS | LONGPOLLING

Install Odoo on a Debian 8 VPS with Nginx as a reverse proxy

Setting Up OpenERP (Odoo) 9 with Nginx on RHEL/CentOS and Debian/Ubuntu

Running Odoo with nginx in https mode

Understanding Nginx HTTP Proxying, Load Balancing, Buffering, and Caching

加速 Magento – 讓 NGINX 支援 HTTP/2 與 ALPN

有鑑於支援 HTTP/2 後,網站連線速度加快不少(可參考 https://www.httpvshttps.com/

所以著手升級現有的系統加速 Magento 運行的速度

升級 OpenSSL 至 1.0.2+

ALPN 需要 OpenSSL 1.0.2 以上才支援,參照 CentOS 更新 OpenSSL 到最新版 1.0.2j or CentOS 更新 OpenSSL 到最新版 1.1.0 更新到最新版

下載並手動編譯 NGINX

可先用 YUM 將 NGINX 更新至最新版

su
yum -y update

再下載對應的 NGINX 來編譯,這樣子比較不會有問題

接下來檢查我們的 NGINX 版本與『編譯參數』

[root@www nginx-1.12.0]# nginx -V
nginx version: nginx/1.12.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

可以看出 NGINX 版本為 1.12.0,編譯的 OpenSSL 版本為 1.0.1e

最後方的 configure arguments 就是編譯的參數,重新編譯需要在最後加上『–with-openssl=/usr/src/openssl-1.1.0f』

讓 NGINX 將新版 OpenSSL 編譯進去

yum -y install libxslt-devel gd-devel perl-devel perl-ExtUtils-Embed GeoIP GeoIP-devel GeoIP-data
cd /root
wget http://nginx.org/download/nginx-1.12.0.tar.gz
tar zxvf nginx-1.12.0.tar.gz
cd nginx-1.12.0
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --with-openssl=/usr/src/openssl-1.1.0f
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-openssl=/usr/local/openssl-1.0.2j/ --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'
make
make install

編輯 NGINX conf 檔

於 /etc/nginx/conf.d/xxxx.conf 新增 http2 即可

server {
 listen 443 ssl http2;

檢查 NGINX 是否編譯成功

[root@www nginx-1.12.0]# nginx -V
nginx version: nginx/1.12.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.1.0f 25 May 2017
TLS SNI support enabled

重新啟動後才會正式啟用 ALPN 的功能

service nginx restart

可來此網站測試是否成功

https://tools.keycdn.com/http2-test

參考資料:

本博客 Nginx 配置之完整篇

How to get already installed NGINX to use OpenSSL 1.0.2 for ALPN?

NGINX 下載頁面

用 Let’s Encrypt 為 Magento 安裝免費的 SSL 憑證 / CENTOS 7

==================== 更新至新版後,無法正常 renew,請改用 Dehydrated 來處理 ====================

 

Let’s Encrypt 是各大廠為了提升網路安全性而共同合作推出免費提供憑證的機構(CA), 以下是在 CentOS 7 將 Let’s encrypt 配置到 NGINX 的方法

先安裝 git、 EPEL repo 與 Let’s encrypt 所需套件

su
yum install -y git epel-release gcc libffi-devel python-devel openssl-devel

下載 Let’s encrypt:

cd /root
git clone https://github.com/letsencrypt/letsencrypt

系統會將 Let’s Encrypt 的最新版本下載到 /root/letsencrypt

先停用 NGINX 後用 letsencrypt-auto 取得 SSL 憑證檔

cd /root/letsencrypt
./letsencrypt-auto certonly -a standalone -d yourdomain.com

or 

cd /root/letsencrypt
./letsencrypt-auto --config /home/test/configs/[your-domain].conf certonly

mkdir /root/webroot
cd /root/letsencrypt
./letsencrypt-auto certonly -a webroot --webroot-path=/usr/share/nginx/html -d odoo.glamping.tw
./letsencrypt-auto certonly -a webroot --webroot-path=/root/webroot -d odoo.glamping.tw

Let’s encrypt 會將憑證檔案放到 /etc/letsencrypt/live/.

接下來生成 DH Parameter

mkdir /etc/nginx/cert
openssl dhparam 2048 -out /etc/nginx/cert/dhparam.pem
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

接著設定 NGINX 的 SSL 設定,加入以下參數

    ssl_certificate      /etc/letsencrypt/live/odoo.glamping.tw/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/odoo.glamping.tw/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 180m;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4;
    add_header Strict-Transport-Security "max-age=31536000 always;

接下來重新啟動 NGINX

service nginx reload

去測試網站跑分,這樣子的設定應該可以直接拿到最高評分 A+ !

最後,由於 Lets Encrypt 憑證有效期限只有 90 天,建議每 60 天自動續約

先建立 renew script:auto-renew.sh

/root/letsencrypt/letsencrypt-auto certonly --webroot --renew-by-default --agree-tos -m cewolf@cewolf.com -w /root/webroot -d gapl.com.tw -d www.gapl.com.tw -d glamp.tw
nginx -s reload

接著設定 CRON 於每兩個月的 20號 凌晨 3 點續約

0 3 20 2,4,6,8,10,12 * root /root/auto-renew.sh

Reload crond

systemctl reload crond.service

大功告成!

目前 nginx reload 並不會換上新的憑證

再找到解決方案前先這樣子跑

systemctl stop crond.service
/root/letsencrypt/letsencrypt-auto renew
/bin/systemctl start nginx.service

 

測試網站:

Qualys SSL Labs SSL Server Test

DigiCert® SSL Installation Diagnostics Tool

SSL Checker

參考資料:

LinuxRHEL / CentOS 7 安裝 Let’s encrypt RHEL / CentOS 7 安裝 Let’s encrypt

Let’s Encrypt 的 SSL 憑證安裝

Configure Magento with SSL

Optimizing HTTPS on Nginx

Guide to Deploying Diffie-Hellman for TLS

用 nginx 建置一個 A+ 等級的 https 網頁伺服器

SSL延遲有多大?

How to Validate a Let’s Encrypt Certificate on a Site Already Active on CloudFlare