NGINX部署HTTPS

0x00 前言

nginx是一款高性能的Web服务器,可以用作反向代理和负载均衡。随着HTTPS的不断推进,越来越多的网站都开始转到HTTPS方式,HTTP仅仅作为重定向到HTTPS的途径。

本文介绍了如何在Ubuntu 16.04服务器上搭建基于nginx的HTTPS服务器,并且支持SNI。

0x01 准备域名和HTTPS证书

域名分为免费域名和收费域名

免费域名

免费域名包含一级域名和二级域名。

一级域名推荐的是:TK域名,每次申请12个月以下是免费的,到期前14天可以免费续期。不过网上说可能会被收回,不过我还没有遇到(估计是我访问量太小吧)。

二级域名就比较多了,但是质量参差不齐,很多只能修改A记录,而且很有可能子域名被用作非法用途导致被列入黑名单,浏览器访问时可能会有拦截提示。

收费域名

如果可以的话,尽量还是购买收费的域名,比如腾讯云,经常会有活动(1元购买域名之类)。要绑定国内服务器,域名还需要备案,使用腾讯云的话备案只要提供少量信息,不用自己邮寄材料,总共花了大概40天左右。

证书可以分为自签名证书(Self-Signed Certificate)、个人网站证书、企业网站证书。

自签名证书

该类型证书可以通过以下命令行创建:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt -subj '/CN=<SERVER-IP>'

完成后会在当前目录创建私钥文件(privateKey.key)和证书文件(certificate.crt)。部署后浏览器会提示不安全的证书。

由于该类型证书无法通过验证,通常只在某些特殊场景下使用(如HTTPS抓包)。

个人网站证书

通常可以申请免费的个人网站证书,如腾讯云(https://buy.cloud.tencent.com/ssl)。该类型证书基本可以满足个人使用,建议使用。

企业网站证书

该类型证书可以提供企业认证,泛域名等,收费一般较高。不建议个人使用。

0x02 部署服务器

安装nginx

apt install nginx -y

使用如下命令确认是否支持HTTPSSNI

root@VM-171-28-ubuntu:/# nginx -V
nginx version: nginx/1.10.3 (Ubuntu)
built with OpenSSL 1.0.2g  1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads

TLS SNI support enabled表示SNI已经启用;--with-http_ssl_module表示支持HTTPS

创建配置文件

将证书文件和私钥文件放到/etc/nginx/ssl目录下。在/etc/nginx/conf.d目录下创建mysite.conf文件。内容如下:

server {
    listen 80;
    return 400;
}

server {
    listen 80;
    server_name mysite.com;
    return 301 https://$server_name$request_uri;
}

server{
    listen 443 default;
    ssl on;
    ssl_certificate /etc/nginx/ssl/default.crt;
    ssl_certificate_key /etc/nginx/ssl/default.key;
    return 400;
    access_log /data/log/nginx/default.access.log;
}

server{
    #比起默认的80 使用了443 默认 是ssl方式  多出default之后的ssl
    listen 443;
    #开启  如果把ssl on;这行去掉,ssl写在443端口后面。这样http和https的链接都可以用
    ssl on;
    #证书(公钥.发送到客户端的)
    ssl_certificate /etc/nginx/ssl/mysite.crt;
    #私钥,
    ssl_certificate_key /etc/nginx/ssl/mysite.key;
    #下面是绑定域名
    server_name mysite.com;

    location / {
        proxy_redirect off; #禁止跳转
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #配置反向代理
        proxy_pass http://127.0.0.1:8081;
    }

    access_log /data/log/nginx/mysite.access.log;
}

前两个server配置项是为了已配置域名使用HTTP访问时,强制跳转到HTTPS;ip或未配置域名访问时,返回400错误。

第三个server配置项中使用了default.crt证书,这是个自签名证书,是为了当用户通过ip或未配置域名使用HTTPS访问时,能够返回400错误。本来是想做成SSL握手时只要发现没有传SNI或不支持的域名时,就直接断开连接。但是,发现貌似nginx不支持这一特性(参考此链接),只能使用这种折中的解决方法。

重启nginx

systemctl restart nginx

如果没有报错的话,HTTPS服务就可以正常访问了。

0x03 后记

使用nginx反向代理的优点是:可以使用nginx实现HTTPS,而自己的Web服务使用HTTP。这样,开发、调试都很方便,也便于使用负载均衡。

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=nl0eqa3ypzk8

分享