翼度科技»论坛 编程开发 .net 查看内容

前后端都用得上的 Nginx 日常使用经验

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
前言

nginx 是一个高性能的开源反向代理服务器和 web 服务器,一般用来搭建静态资源服务器、负载均衡器、反向代理,本文将分享其在 Windows/docker 中的使用,使用 nssm 部署成服务的方案脚本,局域网中自定义域名解决https提示不安全的解决方案,以及一路踩过的坑。
特点


  • 高性能:事件驱动的异步架构,能够处理大量并发连接
  • 静态资源服务器:部署前端静态页面及静态资源
  • 反向代理服务器:接收客户端请求,并将请求转发到后端服务,可以实现负载均衡、请求分发和缓存等功能
  • 支持 HTTPS
使用情况


  • 配置域名转发到项目服务
  • 外网穿透请求转发到局域网服务器
  • 测试环境项目的 https 配置
  • 需要明白 nginx 默认启动后会发生什么?

    • 监听指定端口(默认 80)
    • 拦截本机访问 80 端口的请求到 nginx 来进行处理
    • 可以添加配置监听不同的端口
    • 同样监听 80,但是可以通过 server_name 来指定不同的域名使用不同的规则
    • 本地测试可以通过修改 hosts 文件(C:\Windows\System32\drivers\etc\hosts)来将域名请求转发到本机
    • 服务器需要解析域名到服务器 IP,不同的云商还需要注意其安全组,防火墙是否开启或需要设置规则

  • Windows 中路径需要使用 / 或者 \,如路径 D:\Software\nginx-1.24.0\ssl nginx.conf 需要配置为 D:/Software/nginx-1.24.0/ssl/ 或 D:\Software\nginx-1.24.0\ssl\
实践

准备


  • 本文版本:v1.24.0
  • 使用端口:80 443
  • 最基本组成:一个 server 节点一个域名配置,要添加其他配置添加 server 节点即可
    1. worker_processes  1;
    2. events {
    3.      worker_connections  1024;
    4. }
    5. http {
    6.      server {
    7.          listen       80;
    8.          server_name  localhost;
    9.          error_page   500 502 503 504  /50x.html;
    10.          location = /50x.html {
    11.              root   html;
    12.          }
    13.      }
    14. }
    15. ```
    复制代码
Windows 安装使用 nginx

安装运行


  • 直接官网下载即可 v1.24.0
  • 下载后解压到:D:\Software\nginx-1.24.0
  • 在目录输入框打开 cmd 并运行:start nginx运行 nginx,如果端口没有被占用的话访问 localhost 即可出现 welcome 页面


  • 尝试修改配置:D:\Software\nginx-1.24.0\confi\nginx.conf 添加一个文本返回

  • 添加的文本及 json 返回
    1. #server{....
    2. #返回文本
    3. location /text {
    4.      add_header Content-Type text/plain;
    5.      return 200 'This is a plain text response.';
    6. }      
    7. #返回json
    8. location /json {
    9.      add_header Content-Type application/json;
    10.      return 200 '{"message": "This is a JSON response.233"}';
    11. }
    12. #默认配置
    13. location / {
    14.      root   html;
    15.      index  index.html index.htm;
    16. }
    17. #...}
    18. ```
    复制代码
域名配置


  • 因在本地测试,所以需要使用域名访问到 nginx,需要配置 hosts(服务器外网域名配置就将域名解析到服务器)
  • 添加一条记录: 127.0.0.1  ``nginx.devops.test.com 现在默认就访问nginx.devops.test.com 的时候就请求到了 nginx 的默认配置了,nginx 默认监听了 localhost:80 使其返回我们指定的内容

  • 添加 server 配置节点,重载配置后访问,即可看到访问显示了配置中的内容
    1.     server {
    2.             listen       80;
    3.             server_name  nginx.devops.test.com;
    4.            location / {
    5.                 add_header Content-Type text/plain;
    6.                 return 200 'nginx.devops.test.com';
    7.             }
    8.         }
    9.     ```
    10. ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e62a40257ae548b29b9fab8389027ad5~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=359&h=23&s=1371&e=png&b=0c0c0c)
    11. ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d33c2a30c4e14bd68faacd92ac8330d8~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=410&h=122&s=6676&e=png&b=fcfcfc)
    复制代码
  • 因为浏览器的一些机制,可能会自己默认跳转到 https,然后还看不到协议,此时就需要手动改下
SSL 证书申请

为了给网站加把锁(数据传输的私密性),一般个人项目用免费的就行,不过有限制,比如通配符、有效期、安全性等,企业一般会使用付费证书,自行购买即可,一般云商也会提供免费证书,其他免费的目前使用过的就下面两种

  • 在线网站申请:可以在 freessl 根据需要申请免费/付费证书,其还包含有证书管理和到期提醒等服务
  • win-acme:一个免费的开源工具,用于 Windows 上的 Let's Encrypt 证书的自动化获取和续订
如果本地也需要使用 https 的话,也可以通过 nginx 来配置证书,为应用加把锁。服务器的证书配置使用上面两种生成,参考下面配置即可
nginx 本地配置 https


  • 使用 openssl 生成自签证书(会提示不安全,下一步解决)
  1. #依次执行,输入信息,我这里都输入了 ym
  2. openssl genrsa -out server.key 1024
  3. openssl req -new -key server.key -out server.csr
  4. openssl genrsa -out ca.key 1024
  5. openssl req -new -key ca.key -out ca.csr
  6. openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
  7. openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
复制代码


  • 从图里面可以看到都加上 https 了,怎么还是不安全,甚至第一次还被拦截了,这个是浏览器机制问题,找了一晚上,终于找到了解决方案 思路来源 stackoverflow,下面详细说明步骤

  • 生成 CA 证书(所在目录:D:/Software/nginx-1.24.0/ssl)
    1.    winpty openssl genrsa -des3 -out myCA.key 2048
    2.    winpty openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem
    3.    ```
    复制代码
  • 导入 myCA.pem 证书到受信任的根证书颁发机构(Win+R 打开:certlm.msc)

  • 创建 CA 签名证书(不同域名创建不同的证书)
  1. winpty openssl genrsa -out nginx.devops.test.com.key 2048
  2. winpty openssl req -new -key nginx.devops.test.com.key -out nginx.devops.test.com.csr
复制代码

  • 创建 X509 V3 证书扩展配置文件 nginx.devops.test.com。ext
    1.   authorityKeyIdentifier=keyid,issuer
    2.   basicConstraints=CA:FALSE
    3.   keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    4.   subjectAltName = @alt_names
    5.   [alt_names]
    6.   DNS.1 = nginx.devops.test.com
    7.   ```
    复制代码
  • 生成证书
    1.   winpty openssl x509 -req -in nginx.devops.test.com.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out nginx.devops.test.com.crt -days 825 -sha256 -extfile nginx.devops.test.com.ext
    2.   ```
    复制代码
  • 配置 nginx
    1.       server {
    2.          listen       80;
    3.          listen       443 ssl;
    4.          server_name  nginx.devops.test.com;
    5.          ssl_certificate      D:/Software/nginx-1.24.0/ssl/nginx.devops.test.com.crt;
    6.          ssl_certificate_key  D:/Software/nginx-1.24.0/ssl/nginx.devops.test.com.key;
    7.          ssl_session_cache    shared:SSL:1m;
    8.          ssl_session_timeout  5m;
    9.          ssl_ciphers  HIGH:!aNULL:!MD5;
    10.          ssl_prefer_server_ciphers  on;
    11.          location / {
    12.               add_header Content-Type text/plain;
    13.               return 200 'nginx.devops.test.com666';
    14.           }
    15.       }
    16.   ```
    复制代码
  • 成功,没有不安全字样了

  • 如果要在局域网其他机器访问,也需要执行第 2 步操作导入 myCA.pem 证书,并配置对应的 hosts
使用 nssm 创建 nginx 服务


  • 每次改完配置还要敲命令重启,开机还要启动,那很明显是不太方便的,所以部署 nginx 服务就很有必要了
  • 和 Windows 计划任务设置开机启动相比,我更倾向和习惯于使用 nssm(一个服务封装程序,它可以方便的将程序封装成 windows 服务运行)来为应用创建一个服务进行管理。
  • 下面分享两个快速创建服务的脚本及使用。通过这两个脚本,只需修改对应路径,就可以为应用创建服务并做到开机自启了
  • 添加一个启动 nginx 的脚本 start.bat

    • 放在 nginx 目录中(D:\Software\nginx-1.24.0\start.bat ) ,以管理员 身份运行即可删除 nginx 进程并重新启动
    • 删除进程并重启,测试环境使用,生产环境不建议直接使用
      1. @echo off
      2. cd  /d %~dp0
      3. echo kill nginx
      4. taskkill /fi "imagename eq nginx.EXE" /f
      5. echo start nginx
      6. start nginx
      7. echo start nginx success
      8. pause
      复制代码

  • 将 start.bat 脚本使用 nssm 的方式设置为服务 nssm v2.24 下载

    • 下载后解压:D:\Software\nssm\nssm-2.24\win64
    • 在目录添加 Nginx-service.bat,以快速创建并启动 nginx 服务,根据需要修改服务名和 nginx 启动脚本的路径即可

        1. @echo off
        2. cd  /d %~dp0
        3. nssm stop Nginx-service
        4. nssm remove Nginx-service confirm
        5. nssm install Nginx-service D:\Software\nginx-1.24.0\start.bat
        6. sc start Nginx-service
        7. pause
        复制代码

    • 管理员 身份运行,即可创建并启动服务,



    • 至此,电脑重启服务也将自启,并且还可以通过服务的重新启动来重启应用

常用命令


  • 启动:start nginx
  • 重载配置:nginx -s reload 如果出错会回滚到上一次正确配置文件保持正常运行,可能会存在缓存,Ctrl+F5 刷新浏览器
  • 停止 nginx(删除 nginx 进程):taskkill /fi "imagename eq nginx.EXE" /f

    • windows 下使用 nginx 一直有个问题就是重载配置后,不管有没有问题都可能会启动多个 nginx 进程,最后重载配置无效,就只能删除进程后再启动了

使用 Docker Compose 安装 nginx

本篇文章基于 Docker V24 及 Docker Compose V2,安装可以参考之前的文章
配置说明


  • 镜像版本:nginx:1.24.0
  • 指定端口:80 443
  • 指定时区:TZ : 'Asia/Shanghai',让日志文件显示北京时间
  • 指定挂载目录

    • ./config/nginx.conf:/etc/nginx/nginx.conf:默认配置文件,会加载 conf.d 下的所有配置
    • ./config/conf.d:/etc/nginx/conf.d:自定义配置文件
    • ./html:/usr/share/nginx/html:默认的静态文件目录
    • ./logs:/var/log/nginx:默认的日志目录
    • ./ssl:/ssl:证书目录,配置中使用 /ssl/xxx 指定

  • 配置重载:docker exec nginx_1_24 nginx -s reload
  • 指定网络:devopsnetwork (docker network create devopsnetwork)
  • 目录结构

配置文件 compose.yml


  • 将准备好的 compose.yml config ssl html 拷贝到服务器
  • 然后运行docker compose up -d即可
  1. version: '3.1'
  2. services:
  3.   nginx:
  4.     image: nginx:1.24.0
  5.     container_name: nginx_1_24
  6.     restart: always
  7.     environment:
  8.       TZ : 'Asia/Shanghai'
  9.     ports:
  10.       - "80:80"
  11.       - "443:443"
  12.     volumes:
  13.       - ./config/nginx.conf:/etc/nginx/nginx.conf
  14.       - ./config/conf.d:/etc/nginx/conf.d
  15.       - ./html:/usr/share/nginx/html
  16.       - ./logs:/var/log/nginx
  17.       - ./ssl:/ssl
  18.       
  19.     networks:
  20.       - devopsnetwork
  21. networks:
  22.   devopsnetwork:
  23.     external: true
复制代码
默认的 nginx.conf v1.24
  1. user  nginx;
  2. worker_processes  auto;
  3. error_log  /var/log/nginx/error.log notice;
  4. pid        /var/run/nginx.pid;
  5. events {
  6.     worker_connections  1024;
  7. }
  8. http {
  9.     include       /etc/nginx/mime.types;
  10.     default_type  application/octet-stream;
  11.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  12.                       '$status $body_bytes_sent "$http_referer" '
  13.                       '"$http_user_agent" "$http_x_forwarded_for"';
  14.     access_log  /var/log/nginx/access.log  main;
  15.     sendfile        on;
  16.     #tcp_nopush     on;
  17.     keepalive_timeout  65;
  18.     #gzip  on;
  19.     include /etc/nginx/conf.d/*.conf;
  20. }
复制代码
自定义配置 conf.d/default.conf

将前文 Windows 的配置部分修改到 default.conf 如下所示
  1. server {
  2.   listen       80;
  3.   listen       443 ssl;
  4.   server_name  nginx.devops.test.com;
  5.   ssl_certificate      /ssl/nginx.devops.test.com.crt;
  6.   ssl_certificate_key  /ssl/nginx.devops.test.com.key;
  7.   ssl_session_cache    shared:SSL:1m;
  8.   ssl_session_timeout  5m;
  9.   ssl_ciphers  HIGH:!aNULL:!MD5;
  10.   ssl_prefer_server_ciphers  on;
  11.   location / {
  12.       add_header Content-Type text/plain;
  13.       return 200 'nginx.devops.test.com 001';
  14.   }
  15. }
复制代码
创建证书 ssl 目录

上传生成的 ssl 证书或者在 linux 中使用上面 openssl 的方式重新生成域名证书,然后本地添加 pem 证书,即可使用 https
Nginx 的应用


  • 前面文章我们安装了 Apollo,RabbitMQ 及各种常用数据库,下面将通过 nginx 给之前文章中的应用配置域名转发
  • 通过域名访问到各自应用中,而无需再使用 IP+端口来访问应用,这样就算后面部署方式/IP、端口发送变化,只需要修改 nginx 的转发配置即可
本地使用域名前的配置

要想在局域网使用自定义的域名访问应用,需要先配置 hosts 文件,这里使用 hosts 将域名请求指向目标服务器 192.168.123.214
  1. 192.168.123.214 apollo.devops.test.com
  2. 192.168.123.214 rabbitmq.devops.test.com
复制代码
还可以搭建一个 dns 服务,设置本机的 dns,即可将域名请求交友 dns 解析到对应服务,并且能够实现泛解析
Apollo 的转发配置


  • Apollo 面板地址:http://192.168.123.214:8070/
  • 设定域名:apollo.devops.test.com
  • 对应 server 配置,因为同属一个网络,所以使用容器名加端口访问即可
    1. server {
    2.        listen       80;
    3.        server_name  apollo.devops.test.com;
    4.        location / {
    5.          proxy_pass   http://apollo_portal_2_1:8070/;
    6.          #上游主机名
    7.          proxy_set_header Host $host;
    8.          # 客户端发送的原始主机名
    9.          #proxy_set_header host $http_host;
    10.          proxy_set_header X-Real-IP $remote_addr;
    11.          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    12.          proxy_set_header X-Forwarded-Proto $scheme;
    13.        }
    14.    }
    15. ```
    复制代码
  • Apollo 配置 https,并重定向 http 到 https
    1. server {
    2.      listen       80;
    3.      server_name  apollo.devops.test.com;
    4.      return 301 https://$host$request_uri;
    5. }
    6. server {
    7.      listen       443 ssl;
    8.      server_name  apollo.devops.test.com;
    9.      ssl_certificate      /certs/apollo.devops.test.com/server.crt;
    10.      ssl_certificate_key  /certs/apollo.devops.test.com/server.key;
    11.      ssl_session_cache    shared:SSL:1m;
    12.      ssl_session_timeout  5m;
    13.      ssl_ciphers  HIGH:!aNULL:!MD5;
    14.      ssl_prefer_server_ciphers  on;
    15.      location / {
    16.        proxy_pass   http://apollo_portal_2_1:8070/;
    17.        proxy_set_header host $http_host;
    18.        proxy_set_header x-real-ip $remote_addr;
    19.        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
    20.        proxy_set_header x-forwarded-proto $scheme;
    21.      }
    22. }
    23. ```
    复制代码
RabbitMQ 的转发配置


  • RabbitMQ 面板地址:http://192.168.123.214:15672/#/
  • 设定域名:rabbitmq.devops.test.com
  • 对应 server 配置,因为同属一个网络,所以使用容器名加端口访问即可
    1. server {
    2.      listen       80;
    3.      server_name  rabbitmq.devops.test.com;
    4.      location / {
    5.        proxy_pass   http://rabbitmq_3_12:15672/;
    6.        proxy_set_header Host $host;
    7.        proxy_set_header X-Real-IP $remote_addr;
    8.        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    9.        proxy_set_header X-Forwarded-Proto $scheme;
    10.      }
    11. }
    12. ```
    复制代码
  • RabbitMQ 配置 https,并重定向 http 到 https
    1. server {
    2.      listen       80;
    3.      server_name  rabbitmq.devops.test.com;
    4.      return 301 https://$host$request_uri;
    5. }
    6. server {
    7.      listen       443 ssl;
    8.      server_name  apollo.devops.test.com;
    9.      ssl_certificate      /certs/apollo.devops.test.com/server.crt;
    10.      ssl_certificate_key  /certs/apollo.devops.test.com/server.key;
    11.      ssl_session_cache    shared:SSL:1m;
    12.      ssl_session_timeout  5m;
    13.      ssl_ciphers  HIGH:!aNULL:!MD5;
    14.      ssl_prefer_server_ciphers  on;
    15.      location / {
    16.        proxy_pass   http://apollo_portal_2_1:8070/;
    17.        proxy_set_header host $http_host;
    18.        proxy_set_header x-real-ip $remote_addr;
    19.        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
    20.        proxy_set_header x-forwarded-proto $scheme;
    21.      }
    22. }
    23. ```
    复制代码
相关脚本汇总

<ul>脚本本地目录预览,添加了系统判断 linux,执行需要给要执行的脚本添加执行权限:chmod +x ./01.build-pem.sh

nginx-start.bat :删除 nginx 进程并启动 nginx 服务
  1. @echo off
  2. cd  /d %~dp0
  3. echo kill nginx
  4. taskkill /fi "imagename eq nginx.EXE" /f
  5. echo start nginx
  6. start nginx
  7. echo start nginx success
  8. pause
  9. ```
复制代码
nginx-nssm-service.bat 创建 nginx 服务脚本
  1. @echo off
  2. cd  /d %~dp0
  3. nssm stop Nginx-service
  4. nssm remove Nginx-service confirm
  5. nssm install Nginx-service D:\Software\nginx-1.24.0\start.bat
  6. sc start Nginx-service
  7. pause
  8. ```
复制代码
01.build-pem.sh 创建自签证书
  1. #!/bin/sh
  2. # 生成根证书,访问客户端需要安装导入 myCA.pem,根据myCA.key,myCA.pem再生成nginx需要的证书
  3. if uname | grep -q "MINGW"; then
  4.    winpty openssl genrsa -out myCA.key 2048
  5.    winpty openssl req -x509 -new -nodes -key myCA.key -days 1825 -out myCA.pem
  6. else
  7.    openssl genrsa -out myCA.key 2048
  8.    openssl req -x509 -new -nodes -key myCA.key -days 1825 -out myCA.pem
  9. fi
  10. ```
复制代码
02.build-ssl.sh 创建域名证书
[code] #!/bin/bash if [ "$#" -ne 1 ]; then   echo "Usage: Must supply a domain"   exit 1 fi DOMAIN=$1 mkdir $DOMAIN #!/bin/sh if uname | grep -q "MINGW"; then   winpty openssl genrsa -out $DOMAIN/server.key 2048   winpty openssl req -new -key $DOMAIN/server.key -out $DOMAIN/server.csr else   openssl genrsa -out $DOMAIN/server.key 2048   openssl req -new -key $DOMAIN/server.key -out $DOMAIN/server.csr fi cat >$DOMAIN/server.ext

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具