Nginx配置HTTPS安全连接的完整指南

一、准备工作

1.1  获取SSL证书

购买商业证书:从DigiCert、GeoTrust等机构购买

免费证书:使用Let's  Encrypt(推荐)

自签名证书:仅用于测试环境

1.2  安装必要工具

bash

Ubuntu/Debian

sudo  apt  update

sudo  apt  install  nginx  openssl  certbot  python3-certbot-nginx

CentOS/RHEL

sudo  yum  install  nginx  openssl  certbot  python3-certbot-nginx

二、使用Let's  Encrypt获取免费证书

2.1  使用Certbot自动配置

bash

自动获取并配置证书

sudo  certbot  --nginx  -d  yourdomain.com  -d  www.yourdomain.com

仅获取证书(不修改配置)

sudo  certbot  certonly  --nginx  -d  yourdomain.com

2.2  手动获取证书

bash

1.  停止Nginx

sudo  systemctl  stop  nginx

2.  使用standalone模式获取证书

sudo  certbot  certonly  --standalone  -d  yourdomain.com

3.  重新启动Nginx

sudo  systemctl  start  nginx

三、Nginx  HTTPS基础配置

3.1  基本HTTPS配置

nginx

server  {

        listen  443  ssl  http2;

        listen  [::]:443  ssl  http2;

        server_name  yourdomain.com  www.yourdomain.com;

        #  SSL证书路径

        ssl_certificate  /etc/letsencrypt/live/yourdomain.com/fullchain.pem;

        ssl_certificate_key  /etc/letsencrypt/live/yourdomain.com/privkey.pem;

        #  SSL会话设置

        ssl_session_timeout  1d;

        ssl_session_cache  shared:SSL:50m;

        ssl_session_tickets  off;

        #  现代加密套件配置

        ssl_protocols  TLSv1.2  TLSv1.3;

        ssl_ciphers  ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

        ssl_prefer_server_ciphers  off;

        #  HSTS  (可选但推荐)

        add_header  Strict-Transport-Security  "max-age=63072000"  always;

        #  其他安全头部

        add_header  X-Frame-Options  DENY;

        add_header  X-Content-Type-Options  nosniff;

        add_header  X-XSS-Protection  "1;  mode=block";

        #  网站根目录

        root  /var/www/html;

        index  index.html  index.htm;

        location  /  {

        try_files  $uri  $uri/  =404;

        }

}

3.2  HTTP重定向到HTTPS

nginx

server  {

        listen  80;

        listen  [::]:80;

        server_name  yourdomain.com  www.yourdomain.com;

        #  重定向所有HTTP请求到HTTPS

        return  301  https://$server_name$request_uri;

        #  或者使用Certbot的推荐方式

        #  location  /  {

        #          return  301  https://$host$request_uri;

        #  }

}

四、高级安全配置

4.1  OCSP  Stapling配置

nginx

ssl_stapling  on;

ssl_stapling_verify  on;

ssl_trusted_certificate  /etc/letsencrypt/live/yourdomain.com/chain.pem;

resolver  8.8.8.8  8.8.4.4  valid=300s;

resolver_timeout  5s;

4.2  更严格的安全配置

nginx

仅使用TLS  1.3(最安全,但可能影响老旧客户端)

ssl_protocols  TLSv1.3;

或者使用TLS  1.2及以上

ssl_protocols  TLSv1.2  TLSv1.3;

更严格的加密套件

ssl_ciphers  'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256';

DH参数增强(需要生成)

ssl_dhparam  /etc/nginx/dhparam.pem;

4.3  生成DH参数

bash

sudo  openssl  dhparam  -out  /etc/nginx/dhparam.pem  4096

五、性能优化

5.1  SSL会话缓存优化

nginx

ssl_session_cache  shared:SSL:10m;

ssl_session_timeout  10m;

ssl_buffer_size  4k;

5.2  启用HTTP/2

nginx

listen  443  ssl  http2;

5.3  SSL证书缓存

nginx

ssl_session_cache  shared:SSL:50m;

ssl_session_tickets  on;

ssl_session_ticket_key  /etc/nginx/ssl_ticket.key;

生成会话票据密钥:

bash

sudo  openssl  rand  80  >  /etc/nginx/ssl_ticket.key

sudo  chmod  600  /etc/nginx/ssl_ticket.key

sudo  chown  nginx:nginx  /etc/nginx/ssl_ticket.key

六、多域名配置

6.1  单个服务器块多域名

nginx

server  {

        listen  443  ssl  http2;

        server_name  domain1.com  www.domain1.com  domain2.com  www.domain2.com;

        #  使用通配符证书或SAN证书

        ssl_certificate  /etc/ssl/certs/wildcard.crt;

        ssl_certificate_key  /etc/ssl/private/wildcard.key;

        #  根据域名设置不同的根目录

        if  ($host  =  'domain1.com')  {

                set  $root_path  /var/www/domain1;

        }

        if  ($host  =  'domain2.com')  {

                set  $root_path  /var/www/domain2;

        }

        root  $root_path;

        #  ...  其他配置

}

6.2  多个服务器块

nginx

#  域名1

server  {

        listen  443  ssl  http2;

        server_name  domain1.com  www.domain1.com;

        ssl_certificate  /etc/ssl/domain1/fullchain.pem;

        ssl_certificate_key  /etc/ssl/domain1/privkey.pem;

        root  /var/www/domain1;

        #  ...  其他配置

}

#  域名2

server  {

        listen  443  ssl  http2;

        server_name  domain2.com  www.domain2.com;

        ssl_certificate  /etc/ssl/domain2/fullchain.pem;

        ssl_certificate_key  /etc/ssl/domain2/privkey.pem;

        root  /var/www/domain2;

        #  ...  其他配置

}

七、证书自动续期

7.1  手动测试续期

bash

sudo  certbot  renew  --dry-run

7.2  设置自动续期

bash

编辑crontab

sudo  crontab  -e

添加以下行(每周日凌晨2点检查续期)

0  2  *  *  0  /usr/bin/certbot  renew  --quiet  &&  systemctl  reload  nginx

7.3  强制续期

bash

sudo  certbot  renew  --force-renewal

八、故障排除

8.1  测试SSL配置

bash

使用OpenSSL测试

openssl  s_client  -connect  yourdomain.com:443  -servername  yourdomain.com

使用在线工具

SSL  Labs:  https://www.ssllabs.com/ssltest/

SSL  Checker:  https://www.sslshopper.com/ssl-checker.html

8.2  检查Nginx配置

bash

测试配置文件语法

sudo  nginx  -t

查看详细错误日志

sudo  tail  -f  /var/log/nginx/error.log

查看访问日志

sudo  tail  -f  /var/log/nginx/access.log

8.3  常见错误解决

错误1:证书路径错误

nginx:  [emerg]  cannot  load  certificate  "/path/to/cert.pem"

解决:确保证书文件存在且路径正确

错误2:权限问题

nginx:  [emerg]  BIO_new_file("/path/to/key.pem")  failed

解决:确保私钥文件权限为600,且nginx用户有读取权限

bash

sudo  chmod  600  /etc/ssl/private/yourdomain.key

sudo  chown  nginx:nginx  /etc/ssl/private/yourdomain.key

错误3:端口冲突

nginx:  [emerg]  bind()  to  0.0.0.0:443  failed  (98:  Address  already  in  use)

解决:检查是否有其他服务占用443端口

bash

sudo  netstat  -tulpn  |  grep  :443

九、完整配置示例

nginx

/etc/nginx/sites-available/yourdomain.com

HTTP重定向

server  {

        listen  80;

        listen  [::]:80;

        server_name  yourdomain.com  www.yourdomain.com;

        return  301  https://$server_name$request_uri;

}

HTTPS配置

server  {

        listen  443  ssl  http2;

        listen  [::]:443  ssl  http2;

        server_name  yourdomain.com  www.yourdomain.com;

        SSL证书

        ssl_certificate  /etc/letsencrypt/live/yourdomain.com/fullchain.pem;

        ssl_certificate_key  /etc/letsencrypt/live/yourdomain.com/privkey.pem;

        ssl_trusted_certificate  /etc/letsencrypt/live/yourdomain.com/chain.pem;

        SSL协议和加密套件

        ssl_protocols  TLSv1.2  TLSv1.3;

        ssl_ciphers  ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

        ssl_prefer_server_ciphers  off;

        会话设置

        ssl_session_timeout  1d;

        ssl_session_cache  shared:SSL:50m;

        ssl_session_tickets  off;

        OCSP  Stapling

        ssl_stapling  on;

        ssl_stapling_verify  on;

        resolver  8.8.8.8  8.8.4.4  valid=300s;

        resolver_timeout  5s;

        安全头部

        add_header  Strict-Transport-Security  "max-age=63072000;  includeSubDomains;  preload"  always;

        add_header  X-Frame-Options  DENY  always;

        add_header  X-Content-Type-Options  nosniff  always;

        add_header  X-XSS-Protection  "1;  mode=block"  always;

        add_header  Referrer-Policy  "no-referrer-when-downgrade"  always;

        add_header  Content-Security-Policy  "default-src  'self'  http:  https:  data:  blob:  'unsafe-inline'"  always;

        根目录和索引

        root  /var/www/yourdomain.com/html;

        index  index.html  index.htm  index.nginx-debian.html;

        主location块

        location  /  {

                try_files  $uri  $uri/  =404;

        }

        静态文件缓存

        location  ~*  \.(jpg|jpeg|png|gif|ico|css|js)$  {

                expires  1y;

                add_header  Cache-Control  "public,  immutable";

        }

        禁止访问隐藏文件

        location  ~  /\.  {

                deny  all;

        }

        错误页面

        error_page  404  /404.html;

        error_page  500  502  503  504  /50x.html;

        location  =  /50x.html  {

                root  /usr/share/nginx/html;

        }

}

十、部署和验证

1.  保存配置文件

2.  创建符号链接(如果使用sites-available/sites-enabled)

      bash

      sudo  ln  -s  /etc/nginx/sites-available/yourdomain.com  /etc/nginx/sites-enabled/

3.  测试配置

      bash

      sudo  nginx  -t

4.  重载Nginx**

      bash

      sudo  systemctl  reload  nginx

5.  验证HTTPS

      bash

      curl  -I  https://yourdomain.com

      安全建议

1.  定期更新证书:设置自动续期

2.  监控证书过期:使用监控工具

3.  保持Nginx更新:定期更新到最新版本

4.  使用安全扫描工具:定期检查配置

5.  备份配置:定期备份SSL证书和Nginx配置

这份指南涵盖了从基础到高级的Nginx  HTTPS配置,可根据实际需求调整配置参数。