国内的大部分服务器会拦截80端口的通信,所以在这种情况下,无论是用webroot还是standalone模式,都是不可能成功签发证书的(因为这俩本质上都是http challenge)。
在这种情况下只能使用DNS challenge了,命令大致如下(renew要稍微麻烦一些):
certbot certonly --manual --preferred-challenges dns
官网详的教程戳我
话说Let's Encrypt已经进入正式版了,咱就来说说怎么签发证书。本人呐,恰巧今日弄了个马甲站www.shemissed.me,还弄了几个子域名,于是乎就顺便也给弄了Let's Encrypt吧!
先声明下我的网站的结构,如果读者和我的建站结构一样,那么,跟着走就可以了!
使用LNMP1.3一键安装包,nginx版本是1.9.5
网站目录全部在/home/wwwroot,其中包含三个子域名(不要管那个default,是我懒得删除了)
通过
lnmp vhost add
添加了三个子域名,配置为文件如下
纯粹的说,www.shemissed.me也是shemissed.me的子域名。
这里我就同一称作子域名啦!
要注意,Let's Encrypt并不是泛域名证书(可以签.abc.com,就代表泛域名的意思啦)
现在Let's Encrypt已经支持泛域名证书啦,使用如下命令,推荐用screen(0.22以后版本):
./certbot-auto --server https://acme-v02.api.letsencrypt.org/directory -d *.example.com --manual --preferred-challenges dns-01 certonly
查询TXT记录
dig txt example.com
准备Let's Encrypt
这里有两种方法,一种是包管理器,一种的repo
包管理器(Ubuntu 16.04)或者官方PPA
sudo apt install certbot
PPA
sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install certbot
使用GitHub的repo
找个目录,执行下两句吧
git clone https://github.com/certbot/certbot cd certbot
包管理器中的Let's Encrypt/certbot版本比较旧。
当然啦,我个人选择GitHub上最新的,因为支持wildcard哟。
值得注意的是,低版本的并不会兼容高版本的!会出现错误的。
使用Let's Encrypt生成证书
无论使用那种方法,只需要执行certonly即可。
如果你是使用包管理器的,那么就
letsencrypt certonly # or certbot certonly
如果你是使用GitHub Repo的,那就cd进对应的目录,然后执行
./certbot-auto certonly
此后这两者的步骤是相同的了。
检测并安装环境……此时只需要等待等待……
很磕碜的界面是不是,PuTTY就这熊样,xshell就没这个问题了。要是有强迫症,就开个screen,就没这么难看啦!
在这一步很多人选择第一项,包括我自己也曾这样尝试过,不知为何会报"dialog error",各位如果失败了的话,就停掉web服务器,就果断选择2吧!
我这次讲解就直接从2来了,先停掉web服务器(以Nginx为例)
service nginx stop
选择2,回车
输入你的邮箱
接受许可条款
输入你的域名,这里我们先给www.shemissed.me签,所以就先输入这一个,要记得www哦(而且我并没有解析@)
其实,在输入域名这一块,你可以输入abc.com,www.abc.com,然后配置的时候直接选择abc.com的那个证书,就可以啦。
至于你想怎么选择,没有太大的安全考虑的情况下,那是随便滴!顺便提一句,这个叫做DNS Name啦……
回车确定就会提示Congratulations啦。
证书(fullchain.pem)和私钥(privkey.pem)已经给你放到了/etc/letsencrypt/live/www.shemissed.me
修改nginx的配置文件
由于我是自行编译安装的,所以配置文件的路径在/usr/local/nginx/conf
我们重点需要编辑的是vhost下的那个www.shemissed.me.conf的配置文件。
没有监听443端口,因此,我们就需要在这后面加入监听443的配置内容。
conf目录下可以看到一个enable-ssl-example.conf,都看到example了,还寻思啥呢,把这个example的内容全部复制到www.shemissed.me.conf最下面
之后我们只需要修改server name, root, ssl_certificate, ssl_certificate_key,并删掉下面多余的监听80的就可以了。我下面把我的完整的配置文件写出来供参考,#后面的是注释。
先生成迪菲-赫尔曼密钥 以增强安全
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
你所需要做的事情就是修改网站目录、域名、证书私钥路径,然后保存。最顺快的情况就是搜索替换www.shemissed.me为你的域名或者子域。(请注意此配置文件启用了HTTP/2、自动跳转到https,有HSTS, X-Frame-Options, X-Xss-Protection, X-Content-Type-Options, Referrer-Policy这几个响应头,会防止一些盗链,请确定这符合你的意愿、并且你的Web服务器支持HTTP/2)
server { listen 80; #listen [::]:80; server_name www.shemissed.me; index index.html index.htm index.php default.html default.htm default.php; root /home/wwwroot/www.shemissed.me; rewrite ^(.*)$ https://$host$1 permanent; #include other.conf; #error_page 404 /404.html; include enable-php.conf; location ~ .*\.(ico|gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; valid_referers none blocked www.shemissed.me *.google.com *.baidu.com *.so.com *.bing.com; if ($invalid_referer) { rewrite ^/ https://o51bfbumd.qnssl.com/link.jpg; } } location ~ .*\.(js|css)?$ { expires 12h; } location ~ /\. { deny all; } access_log /home/wwwlogs/www.shemissed.me.log; } server { listen 443 ssl http2 ; #listen [::]:443 ssl spdy; server_name www.shemissed.me; #此处写你的域名 index index.html index.htm index.php default.html default.htm default.php; root /home/wwwroot/www.shemissed.me; #此处写你的网站目录 ssl on; ssl_certificate /etc/letsencrypt/live/www.shemissed.me/fullchain.pem; #此处写你的证书文件的路径 ssl_certificate_key /etc/letsencrypt/live/www.shemissed.me/privkey.pem; #私钥,同上 ssl_session_timeout 20m; ssl_session_cache builtin:1000 shared:SSL:10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/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_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Xss-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; #add_header Public-Key-Pins 'pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis="; max-age=10; includeSubDomains'; #add_header Content-Security-Policy "default-src https: 'unsafe-inline' 'unsafe-eval' data:;"; add_header Referrer-Policy "no-referrer-when-downgrade"; #error_page 404 /404.html; include enable-php.conf; if ($http_user_agent ~* (python-requests|Python-urllib|Marxico)) { return 403; } location /nginx_status { stub_status on; access_log off; } location ~ .*\.(ico|gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; valid_referers none blocked www.shemissed.me *.google.com *.baidu.com *.so.com; if ($invalid_referer) { rewrite ^/ https://o51bfbumd.qnssl.com/link.jpg; } } location ~ .*\.(js|css)?$ { expires 12h; } location / { try_files $uri $uri/ /index.php; } access_log /home/wwwlogs/www.shemissed.me.log; #日志文件 }
保存,然后启动nginx
service nginx start
我们访问下,自动跳转了哟,而且启用了HSTS支持。
小锁头已经出现
PS,SSLLabs可以来测试你的HTTPS安全性哦!戳我!
其他两个子域,大家看着改吧…生成memory.shemissed.me…我玩不动了,要歇菜了。
大家要注意,let's encrypt的证书会在90天之后过期,快到期的时候
./certbot-auto renew
续期,这就不用说啥了。按照官网的推荐,一天两次cron最好了
另外,如果用webroot模式,这样申请证书
certbot certonly --webroot --webroot-path /home/wwwroot/dmesg.app --renew-by-default --email 111@111.com --text --agree-tos -d dmesg.app
Nginx里这么配置
location ~ /.well-known { allow all; }
对呢,由于咱用的standlone模式,所以要关掉webserver才能续期成功,方法之一是写个bash脚本判断上一条命令返回值,方法之二是用hook,比如说:
certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"
其他的一些小问题
HTTP自动跳转HTTPS
啥都别说啦,在每个vhost的80的server段加个
rewrite ^(.*)$ https://$host$1 permanent;
在
root /home/wwwroot/www.shemissed.me;
这一行下加就行。实测在nginx.conf加这一句是没有用滴……(Apache就用.htaccess吧)
顺便提一句,如果是apache的话,思路也是一样的。同样以我【本站】的配置文件为例(很不幸本站没有vhost啊……),修改httpd-ssl.conf中的
SSLCertificateFile "/etc/letsencrypt/live/dmesg.app/fullchain.pem" SSLCertificateKeyFile "/etc/letsencrypt/live/dmesg.app/privkey.pem" DocumentRoot "/home/wwwroot/default" ServerName dmesg.app:443
自己看着改吧……我可懒得折腾这网站的vhost了
裸域自动跳转www二级域
首先要设置@解析到你的IP,然后在nginx.conf中,在80的server段下添加如下内容
if ($host = 'shemissed.me' ) { rewrite ^/(.*)$ https://www.shemissed.me/$1 permanent; }
WordPress 404
在443段下添加如下即可!
location / { try_files $uri $uri/ /index.php; }
Typecho 404
在对应的443段添加如下信息(仅限于那些使用了lnmp1.3一键安装包的人哟,其他方式的不敢保证成功率。但是就是php path info的事情而已)
include typecho.conf; include enable-php-pathinfo.conf;
写后谈
nginx配置文件真是简单易懂啊……还好编辑!
当初我就为了个WP Super Cache选择了Apache……