自签SSL证书及Nginx反代理

487 阅读2分钟

安装Chocolatey

iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

执行choco看是否安装成功

image.png

什么是mkcert?

mkcert是一个使用go语言编写的生成本地自签证书的小程序,具有跨平台,使用简单,支持多 域名,自动信任CA等一系列方便的特性可供本地开发时快速创建https环境使用 安装mkcert执行脚本,安装完choco使用下面的命令安装mkcert。

choco install mkcert

image.png

image.png

生成CA证书

 mkcert -install

执行mkcert -install 之后,会在 C:Users\你的用户名\AppData\Local\mkcert 生成本地的CA证 书,并自动安装。

打开证书管理器。

certmgr.msc

image.png 证书保存位置:

C:\Users\[你的用户名]\AppData\Local\mkcert

域名签发证书

mkcert 命令详解, 官方给的命令。

Created a new certificate valid for the following names 📜
- "example.com"
- "*.example.com"
- "example.test"
- "localhost"
- "127.0.0.1"
- "::1"
//可以生成指定域名证书也可生成泛域名证书

生成一个域名证书

mkcert juejin.host.com

image.png

使用了本地的 CA 创建了关于 juejin.host.com 这个域名的证书和密钥文件。文件就在你powshell内显示的文件夹内,有效期默认2年。

image.png

我这里显示的是在system32这个文件夹,我们也可以通过cd 命令,去到指定的文件夹,然后再生成证书,这样比较好找。

Nginx配置SSL

以下是我自用的,不一定准确,您可能需要先自己了解Nginx的相关知识。

server {
    listen 443 ssl;
    server_name localhost;
    ssl_certificate /usr/local/nginx/ssl/local.com.pem;
    ssl_certificate_key /usr/local/nginx/ssl/local.com-key.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    location / {
        root html;
        index index.html index.htm;
    }
}

Nginx反代理模板

server {
  listen       80;
  listen       443 ssl;
    server_name  note.zto58.com;
    ssl_certificate      /usr/local/nginx/ssl/zto58.pem;
    ssl_certificate_key  /usr/local/nginx/ssl/key_zto58.pem;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    location / {
        proxy_pass http://10.10.10.3:1880;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
    }
}

Nginx proxy_pass参数解释

proxy_set_header Host $proxy_host;

proxy_set_header Host $proxy_host;

当Host设置为$http_host时,则不改变请求头的值,所以当要转发到bbb.example.com的时候,请求头还是aaa.example.com的Host信息,就会有问题;当Host设置为$proxy_host时,则会重新设置请求头为bbb.example.com的Host信息。

$http_host:代理服务器本身IP,不改变请求头的值.

$proxy_host 会重新设置请求头

$host 请求未携带HOST请求头时为虚拟主机的主域名

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Real-IP $remote_addr;

$remote_addr:前一节点的IP,并不一定是用户的真实IP,客户端的ip,若有代理的话表示最后一个代理服务器的ip。

remote_addr表示的IP不可更改.如果可以随意更改的话,就无法建立正常的TCP连接。

proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for

设置被代理端接收到的远程客户端IP,如果不设置,则header信息中并不会透传远程真实客户端的IP地址。

X-Forwarded-For :XFF头,代表客户端,就是HTTP请求段的真实IP,只有通过了HTTP代理或负载均衡服务器时才会添加该项。

标准格式如下:

X-Forwarded-For: client1, proxy1, proxy2

从标准格式可以看出,X-Forwarded-For头信息可以有多个,中间用逗号分隔,第一项为真实的客户端ip,剩下的就是曾经经过的代理或负载均衡的ip地址,经过几个就会出现几个。

此变量只是记录请求的服务器路由顺序,因为这个变量不管在客户端还是代理服务商都可以伪造。

不设置proxy_set_header,则默认host的值为proxy_pass后面跟的那个域名或者IP(一般写IP)

proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for; 

proxy_add_x_forwarded_for变量包含客户端请求头中的"X-Forwarded-For",与remote_addr用逗号分开,如果没有"X-Forwarded-For" 请求头,则proxy_add_x_forwarded_for等于remote_addr。

Nginx 自动转发443

配置了ssl之后访问80端口还是走的http,想要访问http协议时自动跳转到https需要做如下配置:

server {
    listen 80;
    server_name note.zto58.com;
    rewrite ^(.*)$ https://${server_name}$1 permanent; 
}
server {
    listen       443 ssl;
    server_name  note.zto58.com;
    ssl_certificate      /usr/local/nginx/ssl/zto58.pem;
    ssl_certificate_key  /usr/local/nginx/ssl/key_zto58.pem;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    location / {
        proxy_pass http://10.10.10.3:1880;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
    }
}