刚刚学会怎么给自己的网站升级到 HTTPS,使用了 nginx + certbot,实现自动更新证书。
安装 nginx 和 certbot
首先我们需要去给服务器安装 nginx,这个就按照官网来就行。
然后我们还要装 certbot,也是去官网跟着下完就行。
配置 nginx
我们先需要去 /etc/nginx/nginx.conf
,给配置文件包含一下 conf.d
目录,这样我们就可以将配置文件按照域名来隔离开配置。
$ cd /etc/nginx/nginx.conf
我的配置如下,当然具体配置需按照实际情况进行修改:
user root; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 102400; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' '$request_time $upstream_response_time $upstream_addr $upstream_status'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; map $http_upgrade $connection_upgrade { default upgrade; '' close; } # 包含 conf.d 目录下所有配置文件 include /etc/nginx/conf.d/*.conf; }
然后我们进到 conf.d 目录,新建一个 root.conf 来配置一些通用的配置:
server { listen 80; server_name example.com; # acme-challenge 目录,签署证书时需要来访问这里面的文件来验证身份 location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; # 签证书时,会去校验你的网站身份,这个文件会被自动生成到这个目录下,然后请求它 # http://example.com/.well-known/acme-challenge/xxxxxx root /var/www/letsencrypt; } location = /.well-known/acme-challenge/ { return 404; } # 将根域名的请求重定向到 www 子域名上(如果没有这个需求,就不要配这个) location / { return 301 https://www.example.com$request_uri; } } # 对所有子域名,保证签证书的时候还能访问到 /var/www/letsencrypt 下的静态资源 server { listen 80; server_name *.example.com; location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/letsencrypt; } location = /.well-known/acme-challenge/ { return 404; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; listen 443 quic; http2 on; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions ssl_session_tickets off; ssl_early_data on; quic_retry on; quic_gso on; # modern configuration ssl_protocols TLSv1.3; ssl_prefer_server_ciphers off; add_header Alt-Svc 'h3=":443"; ma=86400'; location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/letsencrypt; } location = /.well-known/acme-challenge/ { return 404; } location / { return 301 https://www.example.com$request_uri; } }
现在我们完成了基本的配置,可以使用 nginx -t
检查一下配置文件是否正确,然后启动一下服务(如果你起不来,就改下配置让他能起来先,比如注释掉第三个 server 块,因为它配置了证书,而这时候还没有证书,所以肯定找不到,但其实我感觉第三个 server 块也没有用,应该可以删?)。
然后我们就可以指定具体子域名的配置,比如我有一个 test.example.com 的子域名用于测试环境:
server { listen 443 ssl; listen 443 quic; http2 on; server_name test.example.com; ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions ssl_session_tickets off; ssl_early_data on; quic_retry on; quic_gso on; # modern configuration ssl_protocols TLSv1.3; ssl_prefer_server_ciphers off; add_header Alt-Svc 'h3=":443"; ma=86400'; proxy_set_header X-Real-IP $remote_addr; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Ssl on; proxy_set_header Accept-Encoding gzip; proxy_redirect off; gzip on; gzip_min_length 10k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json; gzip_disable "MSIE [1-6]\."; gzip_vary on; client_max_body_size 20M; # 下面就是具体的转发规则了,这里只是随便写了个流量转发 location / { proxy_pass http://127.0.0.1:8080/; } }
由于上面我们已经配置过任意子域名对 /var/www/letsencrypt
的转发,所以现在我们就可以直接来签证书了:
$ certbot certonly --webroot -w /var/www/letsencrypt -d test.example.com
如果这里提示超时失败,可以多尝试几次,但是一个小时内只能失败 5 次,如果超了 5 次,则需要等一个小时后再试。
如果成功了,那么恭喜你,证书已经拿下了。而且 certbot 会启动定时任务,来自动帮你续证书。我们可以使用以下命令测试自动续签:
$ certbot renew --dry-run
还可以查看证书信息:
$ certbot certificates