nginx配置https
原文地址: nginx配置https - FindHao
1. Introduction
前兩天收到letsencrypt的郵件,說https快到期了,抓緊更新一下。我記得用linux的crontab開啟自動更新https證書了,怎麼還會收到?瀏覽器看了下證書日期,的確快要到期了,發現是nginx沒有重啟,證書緩存沒有更新。
本文記錄了使用LNMP搭建的博客添加https的過程,也可以參看uwsgi的配置。
2. HTTPS普及
使用https有哪些好處?
- 防止運營商劫持,家庭網路寬頻運營商經常干這事
- HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網路協議,要比http協議安全,可防止數據在傳輸過程中不被竊取、改變,確保數據的完整性。
- HTTPS是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增加了中間人攻擊的成本。
缺點是什麼?
- 降低網站速度(儘管現在有很多技術可以提高)
- 配置可能麻煩
lets encrypt這個項目通過自動化,把ssl證書使用簡單化了。本文就以針對個人用戶免費的lets encrypt項目作為示範,官方的自動化工具certbot上https的步驟:
- 在vps上安裝certbot
- 創建配置文件
- 執行證書自動化命令
3. 配置HTTPS
3.1 下載certbot
不同的瀏覽器和不同的webserver可以在certbot上看到相應的教程。
我的vps操作系統是 debian 8.0,但是源里並沒有certbot工具,因此需要直接下載可執行文件
wget https://dl.eff.org/certbot-autonchmod a+x certbot-auton
3.2 certbot驗證的過程
certbot實際上在你的webroot下建立了.well-known/acme-challenge/目錄,在驗證的時候,會在此目錄下生成一些驗證文件,然後通過在外部訪問你網站的這個文件,如果正確獲得了,那麼驗證通過,並將生成的文件都刪除掉。
因此,.well-known目錄的許可權很重要,比如lnmp安裝的話,在root下執行certbot-auto,那麼目錄默認www用戶是沒有許可權訪問的,會導致驗證失敗,因此需要在nginx里對這個目錄做特殊排除
修改nginx中你的域名的配置文件,比如在lnmp中,默認是/usr/local/nginx/conf/vhost/,而通過apt默認安裝的nginx,配置文件則在/etc/nginx/conf.d/,在配置文件中添加如下內容:
location ^~ /.well-known {ntallow all;n}n
表示針對這個目錄,允許所有人查看,如果配置文件中含有
location ~ /.n{ntdeny all;n}n
則需要在此段之前。
注意修改以後,別忘了通過service nginx -s reload重啟nginx。
3.3 對域名簽發證書
3.3.1 一個網站目錄映射多個域名
比如我的findspace.name 和http://findhao.net 以及www.的都是一個網站目錄(webroot),在nginx的配置文件里,是通過
server_name findspace.name www.findspace.name findhao.net;n
來實現映射的,那麼使用certbot簽發,只需要運行:
certbot-auto certonly --webroot -w /home/wwwroot/findhao.net -d findhao.net -d findspace.name -d www.findhao.net -d www.findspace.namen
則就會進入自動驗證的過程。 -w是webroot,-d是domain的縮寫。
3.3.2 多個域名多個webroot
如果有好幾個域名需要簽發,而且每個域名的webroot(域名的文件存放目錄)是不一樣的,那就需要運行多次certbot-auto -w a_domain_webroot -d a_domain。我們也可以給多域名多目錄生成一個證書,即一次生成多個域名的一個證書。命令其實和3.3.1是一樣的,只不過幾個域名的驗證文件是相同的。
出現
IMPORTANT NOTES:n - Congratulations! Your certificate and chain have been saved atn /etc/letsencrypt/live/www.findhao.net/fullchain.pem. Your cert willn expire on 2017-09-30. To obtain a new or tweaked version of thisn certificate in the future, simply run certbot-auto again. Ton non-interactively renew *all* of your certificates, runn "certbot-auto renew"n
則表示生成成功!
3.4 修改nginx配置文件
生成好了證書,那麼還需要讓nginx告訴瀏覽器你的證書。修改你的域名證書,比如/etc/nginx/conf.d/findhao.net.conf:
# 一開始默認只有一個server來監聽80埠,現在將80埠的訪問轉發到https上。nserver {ntlisten 80 default_server;nt# 監聽了多個域名ntserver_name youtube.findspace.name findyoutube.net www.findyoutube.net;ntreturn 301 https://$host$request_uri;n}nnnserver {ntlisten 443 ssl http2;n listen [::]:443 ssl http2;n# 你的證書地址ntssl_certificate /etc/letsencrypt/live/findyoutube.net/fullchain.pem;n ssl_certificate_key /etc/letsencrypt/live/findyoutube.net/privkey.pem;n ssl_session_timeout 1d;n ssl_session_cache shared:SSL:50m;n ssl_session_tickets off;nntssl_protocols TLSv1 TLSv1.1 TLSv1.2;n ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;n ssl_prefer_server_ciphers on;n # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)n add_header Strict-Transport-Security max-age=15768000;n # OCSP Stapling ---n # fetch OCSP records from URL in ssl_certificate and cache themn ssl_stapling on;n ssl_stapling_verify on;n ntserver_name findyoutube.net www.findyoutube.net youtube.findspace.name;ntindex index.html index.htm index.nginx-debian.html;n# 這部分是表示將原來的域名,重定向到現在新的域名,如果一台vpsntif ($host = findyoutube.net ) {nttrewrite ^/(.*)$ https://www.findyoutube.net/$1 permanent;nt}ntif ($host = youtube.findspace.name){nttrewrite ^/(.*)$ https://www.findyoutube.net/$1 permanent;nt}n# 由於使用的是uwsgi,所以需要將數據轉發過去。如果是lnmp之類安裝,則這裡默認沒有下面特殊的規則ntlocation / {n include uwsgi_params;n uwsgi_pass 127.0.0.1:5001; n uwsgi_param UWSGI_CHDIR /root/DownloadYoutube;n uwsgi_param UWSGI_SCRIPT manage:app; n }n}n
80埠的監聽部分,不建議此時修改,最好在單獨測試https可以訪問以後,再修改301跳轉。
3.5 重啟服務
重啟nginx服務之前,一定要先用nginx -t檢查配置文件是否有語法錯誤!!
通過service nginx restart 或者nginx -s reload或者systemctl nginx restart。
3.6 nginx 支持HTTP2
如果你按照上面的配置文件添加了http2的關鍵字,那麼在進行配置文件檢查錯誤時,會出現:
nginx: [emerg] invalid parameter "http2" in /etc/nginx/conf.d/ssl.conf:2nnginx: configuration file /etc/nginx/nginx.conf test failedn
HTTP2最低要求nginx 1.9.5,但是我vps的debian系統,nginx才1.6,因此需要手動升級nginx。
添加nginx的官方源:
#建立/etc/apt/sources.list.d/nginx.list 文件,內容如下ndeb http://nginx.org/packages/mainline/debian/ jessie nginxndeb-src http://nginx.org/packages/mainline/debian/ jessie nginxn
然後apt update && apt upgrade即可發現nginx要求更新。注意,在upgrade時,可能會出現錯誤提示,說依賴問題。這是因為新版本的nginx已經沒有nginx-commen包了。所以需要先卸載原來的版本:
apt-get remove nginx nginx-commonn
然後再install nginx即可。
3.7 設置開機啟動項
手動更新nginx,那原來的nginx開機啟動項就沒有了,需要手動編寫,現在systemd幾乎已經統治了常見的linux發行版,因此/etc/rc.local文件很可能已經沒有了。簡單學習下systemd的寫法即可,你也可以直接用下面官方給的配置文件/lib/systemd/system/nginx.service:
[Unit]nDescription=A high performance web server and a reverse proxy servernAfter=network.targetnn[Service]nType=forkingnPIDFile=/run/nginx.pidnExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on;nExecStart=/usr/sbin/nginx -g daemon on; master_process on;nExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reloadnExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pidnTimeoutStopSec=5nKillMode=mixednn[Install]nWantedBy=multi-user.targetn
添加完成後,
# 重載所有修改過的配置文件nsystemctl daemon-reloadn# 先殺掉原來的nginxnpkill nginxn# 立即啟動一個服務nsystemctl start nginx.servicen# 如果提示nginx service is masked,那麼先解鎖nsystemctl unmask nginx.servicen# 添加開機啟動nsystemctl enable nginx.servcen
去訪問下你的網站看是不是已經可以訪問https啦
3.8 設置自動更新證書
由於lets encrypt的證書有效期只有三個月,每隔三個月需要更新一次,官方提供的certbot-auto 即可更新。結合linux的crontab工具即可實現,通過crontab -e來編輯定時任務列表:
5 2 10 * * /usr/bin/certbot-auto renew --post-hook "lnmp nginx restart"n
每個月的10號2點5分執行後面的命令,在執行/usr/bin/certbot renew之後執行--post-hook的參數,即重啟nginx,這裡的lnmp是一鍵安裝工具,如果是普通方式安裝nginx,直接使用3.5的重啟命令即可。注意一定要重啟nginx,不然證書更新以後,nginx還是用的原來的緩存。
Reference
Lets Encrypt 給網站加 HTTPS 完全指南使用 Certbot 自動簽發 Lets Encrypt 證書免費SSL證書Lets Encrypt(certbot)安裝使用教程設置 Nginx 使用 HTTP/2 協議debian8 編譯安裝的 nginx 開機自啟Systemd 入門教程:命令篇-阮一峰
推薦閱讀:
※Nginx基本配置備忘
※淺談前端線上部署與運維
※nginx快速入門之基本原理篇
※如何 windows下nginx+django+flup python3?
※把nginx改為一個普通的tcp伺服器,應用層協議自己定義,有可行性嗎?