HTTPS 可以使用免费的 Let's Encrypt 证书。
configure arguments: --prefix=/usr/local/nginx --with-openssl=/usr/local/nginx/src/openssl-1.1.0e --add-module=/usr/local/nginx/src/echo-nginx-module-0.60 --with-http_ssl_module
1. 配置域名验证
使用一个私钥来进行账号的创建与登陆
openssl genrsa 4096 > account.key
2. 创建域名的CSR
Let’s Encrypt 使用的ACME协议需要一个CSR文件,可以使用它来重新申请HTTPS证书,在创建CSR之前,我们需要给我们的域名创建一个私钥(这个和上面的账户私钥无关)
openssl genrsa 4096 > domain.key
如果你有多个域名,比如:www.test.com和test.net,
subjectAltName=DNS:www.test.com,DNS: test.net
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /usr/local/etc/openssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:www.test.com")) > domain.csr
(在我的mac机器上 /usr/local/etc/openssl/openssl.cnf )
3. 配置域名验证
传统 CA 的验证方式一般是往 [email protected] 发验证邮件,而 Let's Encrypt 是在你的服务器上生成一个随机验证文件,再通过创建 CSR 时指定的域名访问,如果可以访问则表明你对这个域名有控制权。 这个验证服务以后更新证书还要用到,需要一直保留。
- mkdir -p /var/www/challenges
server {
listen 80;
server_name www.test.com test.net;
location ^~ /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
...the rest of your config
}
4. 获取网站证书
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
指定账户私钥、CSR 以及验证目录,执行 acme-tiny 脚本:
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt
如果一切正常,当前目录下就会生成一个 signed.crt,
这就是申请好的证书文件。
5. 安装证书
证书生成后,就可以把它配置在web 服务器上了,需要注意的是,Nginx需要追加一个Let's Encrypt的中间证书,在 Nginx 配置中,需要把中间证书和网站证书合在一起。网站如果用CDN的话,那么需要CDN也支持HTTPS才行,否则无法正常加载CDN的资源
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pemcat signed.crt intermediate.pem > chained.pem
server {
listen 443;
server_name foofish.net, www.foofish.net;
ssl on;
ssl_certificate /path/to/chained.pem;
ssl_certificate_key /path/to/domain.key;
}
一个完整的 HTTPS 如下
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include 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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name www.test.com test.net;
location ^~ /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
...the rest of your config
}
# HTTPS server
server {
listen 443;
ssl on;
server_name www.test.com localhost;
ssl_certificate /usr/local/nginx-1.9.7/conf/www.test.com.crt;
#为虚拟服务器指定PEM格式的证书文件。如果文件除了制定基础证书证书外还制定了中级证书,则他们应该制定到相同文件中, 并且基础证书应该放到前面, 然后后是中级证书。如果一个PEM格式的秘钥文件也被制定了, 也应该放到相同文件中。
ssl_certificate_key /usr/local/nginx-1.9.7/conf/www.test.com.key;
#https://www.devconf.cn/
#######证书安全######
# https://cipherli.st/
# https://www.ssllabs.com/ssltest/index.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
#启用密码。密码用OpenSSL库能了解格式
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
location / {
root /home/www.test.com;
index index.html index.htm;
}
}
}