nginx

  • 七层负载均衡器,可以通过访问的域名转发
  • 重新加载配置命令为nginx -s reload
  • nginx -t检查配置文件是否正确

配置文件解析

以下这部分server是放在http块中的

    server{
	    listen 80;
        server_name _;#配置访问的域名,依赖七层负载均衡
       location /api/ {
		    proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:5200;
        }
		# 会优先匹配长的(/api和/优先/api,一样长优先匹配先定义的)
        location / {
            root /data/frontend/dist;
            add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
            try_files $uri $uri/ /index.html;# 这行是找不到自动跳到index.html
            index index.html;
        }
        location /file/ {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:5200;
        }
    }

https ssl配置

	# 80 端口配置转发
	server{
        listen 80;
        server_name chenxuanweb.top;
        return 302 https://$host$request_uri;
    }

	# ssl 443 端口配置
    server{
        listen 443 ssl;
        server_name chenxuanweb.top;
        ssl_certificate /root/ssl/note.chenxuanweb.top.pem;
        ssl_certificate_key /root/ssl/note.chenxuanweb.top.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-RSA-AES129-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;

        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:6888;
        }
    }

常见问题

403

  • 权限问题,考虑配置文件第一行的user更改为root,然后重启
  • 大概率是因为文件夹的权限不是755 可以检查一下

错误日志查看

  • tail /var/log/nginx/error.log

反向代理的四个斜杠

  • 整体如下文,核心就是
    1. proxy_pass 代理地址端口后无任何字符(就是类似 http://ip:port ) 转发后实际地址:代理地址+访问URL接口路径部分。
    2. proxy_pass 代理地址端口后有目录(就是类似 http://ip:port/abc/ 包括 / ),转发后实际地址:代理地址+访问URL目录部分去除location匹配目录。
    3. location部分如果有 /,并且代理地址端口后有字符或者目录(包括 /),那么意思是将 location_path/* 转发到 proxy_pass/path* 进行访问, 其中*为请求的静态资源,此时 proxy_pass/path 后面必须有 / 否则会直接拼接导致错误. 如果此时代理地址端口后无字符或者目录,会自动追加localtion部分的location_path,使得变得正确
    4. location 部分没有 /,基本和有的差不多,但是如果是 http://ip:port/ 的出现双斜杠问题
二、location匹配路径末尾有 /
此时proxy_pass后面的路径需要分为以下四种情况讨论:

(1)proxy_pass后面的路径只有域名且最后没有 /
location /sta/
{
      proxy_pass http://192.168.1.1;
}

外面访问:http://外网IP/sta/sta1.html
相当于访问:http://192.168.1.1/sta/sta1.html

(2)proxy_pass后面的路径只有域名同时最后有 /
location /sta/
{
      proxy_pass http://192.168.1.1/;
}

外面访问:http://外网IP/sta/sta1.html
相当于访问:http://192.168.1.1/sta1.html

(3)proxy_pass后面的路径还有其他路径但是最后没有 /:
location /sta/
{
      proxy_pass http://192.168.1.1/abc;
}

外面访问:http://外网IP/sta/sta1.html
相当于访问:http://192.168.1.1/abcsta1.html

(4)proxy_pass后面的路径还有其他路径同时最后有 /:
location /sta/
{
      proxy_pass http://192.168.1.1/abc/;
}
外面访问:http://外网IP/sta/sta1.html
相当于访问:http://192.168.1.1/abc/sta1.html

总结

  • 两个都加上斜杠!!!,并且proxy_pass 后面的路径补充完整(带着api,除非需要截取)
location /nacos/ {
    proxy_pass http://127.0.0.1:5000/nacos/;
}
 # or
location / {
    proxy_pass http://127.0.0.1:5000/;
}

[!tip] 参考 Nginx 带不带斜杆的区别最全分析 Nginx 故障排查之斜杠(/) --(附 Nginx 常用命令) nginx proxy_pass后的url加和不加反斜杠‘/’的区别 | ActPi's Blog

代理https的原理

Charles抓包工具

  1. 客户端向服务器发起HTTPS请求
  2. Charles拦截客户端的请求,伪装成客户端向服务器进行请求
  3. 服务器向“客户端”(实际上是Charles)返回服务器的CA证书
  4. Charles拦截服务器的响应,获取服务器证书公钥,==然后自己制作一张证书,将服务器证书替换后发送给客户端==。(这一步,Charles拿到了服务器证书的公钥)
  5. 客户端接收到“服务器”(实际上是Charles)的证书后,生成一个对称密钥,用Charles的公钥加密,发送给“服务器”(Charles)
  6. Charles拦截客户端的响应,用自己的私钥解密对称密钥,然后用服务器证书公钥加密,发送给服务器。(这一步,Charles拿到了对称密钥)
  7. 服务器用自己的私钥解密对称密钥,向“客户端”(Charles)发送响应
  8. Charles拦截服务器的响应,替换成自己的证书后发送给客户端
  9. 至此,连接建立,Charles拿到了 服务器证书的公钥 和 客户端与服务器协商的对称密钥,之后就可以解密或者修改加密的报文了。

实现的核心

  • 客户端首先需要加入charles的CA证书,实际上的核心是伪造了证书,步骤是

    1. 自己制造证书,域名什么的都写上去,计算哈希值,然后用自己的私钥加密后写入证书,假装是Charles发的ssl证书
    2. 客户端拿到之后根据Charles的CA公钥进行验证,发现没问题
  • 验证和加密过程参考### 握手流程

    1. 客户端发起请求,发送clirand

    2. 服务端发送签名证书,公钥,serrand

    3. 客户端校验证书合法性

      1. 证书签发会对内容进行hash计算签名值,然后对签名进行私钥加密,并把加密后的签名加到证书
      2. 客户端根据证书CA获取签发的机构的公钥,对签名解密,获取hash值
      3. 客户端自己对证书hash,比较hash是否相同,相同则信任^[https://www.zhihu.com/question/37370216]

        因为CA的私钥是未知的,伪造证书无法生成相同hash值

    4. 客户端再生成secretrand,并且使用公钥加密,发送到服务端

    5. 服务端进行私钥解密得到secretrand,将三个随机数连接并进行hash算法,得到值作为加密密钥,进行对称加密^[https://www.cnblogs.com/enoc/p/tls-handshake.html]

中间人进攻

  • 实际上就是上面代理的原理,也就是https防火墙的原理
  • 这部分需要进攻的难点在于
    1. 同时掌握证书+网关硬件,才能做到完整的中间人攻击,一般来说,只有在公司(电脑+网络都属于公司)的情况下才能做到
    2. 需要模拟真实的https,如果出现大量请求,会很慢

参考

  • https://zhuanlan.zhihu.com/p/372610935
  • https://www.jianshu.com/p/405f9d76f8c4
  • https://zhuanlan.zhihu.com/p/412540663