nginx+ssl+certbot安裝設定雜記

URL Link //n.sfs.tw/11391

2017-06-23 15:01:57 By jung

2022更新

certbot-auto這支程式已經沒有在維護了~~

<!-- 以下內容已失效

更新內容

發現使用certbot-auto這個程式更容易設定喔

先新增一個目錄,把cerbot-auto程式放進去

可參考 https://blog.gtwang.org/linux/secure-nginx-with-lets-encrypt-ssl-certificate-on-ubuntu-and-debian/

-->

但是這裡要修正一下

在nginx還沒設定好之前,先不要執行cerbot-auto程式

所以正確步驟應該是:

一、下載cerbot

二、修改nginx設定,在server block加入

location ^~ /.well-known/acme-challenge/ {
                root /opt/letsencrypt;//這是certbot-auto放的目錄
        }
        location ~ /\. {
                deny all;
        }

三、直接執行certbot-auto指令就好,不需要certonly

只要一切正常,certbot-auto會自動寫入/etc/letsencrypt目錄及修改nginx設定

會發現/etc/nginx/conf.d/default.conf多出幾行

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/pass.wtes.tc.edu.tw/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/pass.wtes.tc.edu.tw/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

如果你有使用rewrite設定,可將下列內容刪除,使用 rewrite ^ https://$http_host$request_uri? permanent; 即可
server {
    if ($host = test.org) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        server_name test.org;
    return 404; # managed by Certbot

 

四、再次修改nginx設定,如果你有使用proxy_pass,須將listen 80區塊獨立出來

例如:

server {
        listen 80;
        server_name test.org;
        rewrite ^ https://$http_host$request_uri? permanent;
        server_tokens off;
}
server {
        location / {
                proxy_pass http://127.0.0.1:8080/;
        }
        location ^~ /.well-known/acme-challenge/ {
                root /opt/letsencrypt;//這個目錄可自行設定想要的位置
        }
        location ~ /\. {
                deny all;
        }
    ssl on;
    server_tokens off;
    listen 443 ssl; # managed by Certbot

這樣就完成了,接下來可以修改options-ssl-nginx.conf將不安全的SSL協定拿掉

只留下TLSv1.2即可

但是我發現要用ssl_protocols參數,在apache可用的SSLProtocol到了nginx是會失敗的

還有apache用SSLCipherSuite,但是nginx用的是:ssl_ciphers

 

最後可以參考上面網頁的範例,建立自動更新憑證的執行程序

 

=====================================================================

其中網站建置很重要的https連線需要ssl憑證

之前在apache2上使用certbot這支程式很簡單就達成了

echo 'deb http://ftp.debian.org/debian jessie-backports main' | tee /etc/apt/sources.list.d/backports.list
apt-get update
apt-get install python-certbot-apache -t jessie-backports
nano /etc/apache2/sites-available/000-default.conf  (改ServerName參數)
apache2ctl configtest
a2enmod ssl
service apache2 restart

然後開啟防火牆允許80&443連線(我使用ufw)

執行certbot --apache就完成了~我以為nginx會更簡單~我錯了@@

以下節錄自https://www.nginx.com/blog/free-certificates-lets-encrypt-and-nginx/

The first thing you need to do is download and install the Let’s Encrypt client, certbot. You can access the complete documentation at Let’s Encrypt, but in summary the commands are:

sudo apt-get update

sudo apt-get install -y git

sudo git clone https://github.com/certbot/certbot /opt/letsencrypt

certbot會在放網站的資料夾下新增驗證token的相關檔案,所以接著要設定檔案權限

Create the directory where Let’s Encrypt stores the temporary file, and set the required permissions:

cd /var/www

mkdir letsencrypt  ##名稱應該可以自訂

chgrp www-data letsencrypt

而在git上放的這個程式似乎會自動把相關檔案分開放,於是設定檔的部分被放到了/etc/letsencrypt下

接著依照說明在/etc/letsencrypt下新增configs資料夾再新增與自己主機domain name名稱相同的conf設定檔

Create the file /etc/letsencrypt/configs/my-domain.conf, where my‑domain is your fully qualified domain name (for example, http://www.example.com).

# the domain we want to get the cert for;
# technically it's possible to have multiple of this lines, but it only worked
# with one domain for me, another one only got one cert, so I would recommend
# separate config files per domain.
domains = my-domain ##這裡要改成自己的主機域名
# increase key size rsa-key-size = 2048 # Or 4096
# the current closed beta (as of 2015-Nov-07) is using this server server = https://acme-v01.api.letsencrypt.org/directory
# this address will receive renewal reminders email = my-email   ##這裡可寫自己有用的email當憑證過期就會提醒
# turn off the ncurses UI, we want this to be run as a cronjob text = True
# authenticate by placing a file in the webroot (under .well-known/acme-challenge/) # and then letting LE fetch it authenticator = webroot webroot-path = /var/www/letsencrypt/

 

接下來要到nginx去修改設定檔

nano /etc/nginx/conf.d/default.conf

把下面這段加到server{ ......}區塊裡

location /.well-known/acme-challenge { root /var/www/letsencrypt; }

檢查一下語法

nginx -t && nginx -s reload 如果正確sucessful就沒錯

開始下載憑證之前,必須先在dns上加入這台主機的A紀錄正反解,fortigate及ufw防火牆開啟外聯內部該主機的http&https連線

開始執行

cd /opt/letsencrypt

chmod a+x certbot-auto

./certbot-auto --config /etc/letsencrypt/configs/domain.conf cert only

上面的domain.conf就是自己創建的設定檔

順利完成就會出現恭喜的訊息

最後為了讓主機自動更新憑證

做一個script定期執行

Renewal

I put a script in /etc/cron.monthly:

#!/bin/sh
    
# create new certs
cd /root/letsencrypt
    
for conf in $(ls /etc/letsencrypt/configs/*.conf); do
  ./letsencrypt-auto --renew --config "$conf" certonly
done
    
# make sure nginx picks them up
service nginx restart

And now I get new certs on the first of every month. Done.

接下來,讓連線全都轉到https上

回到/etc/nginx/conf.d/default.conf 修改設定

試了幾次照下面這樣才成功@@

server {
        listen       80;
        server_name  seafile.example.com;
        rewrite ^ https://$http_host$request_uri? permanent;    # force redirect http to https
        server_tokens off;
    }

    server {
        listen 443;
        ssl on;
        ssl_certificate  /etc/letsencrypt/live/my-domain(要改成主機域名,前面步驟正確會自動產生該域名的資料夾)/fullchain.pem ; # path to your cacert.pem
        ssl_certificate_key  /etc/letsencrypt/live/my-domain/privkey.pem ;    # path to your privkey.pem
        server_name seafile.example.com;
        server_tokens off;
        # ......
        
    }

然後重新啟動nginx就成功了