Nignx 配置反向代理

解决问题:使用nignx完成http转https和二级域名转发,将已有http通信的web前端转为https,包括主域和一个二级域名,这两个domain解析到同一ip。
Nginx作用:
(1)HTTP静态服务器:存储图片,文件等静态资源
(2)负载均衡:当一台web服务器不够用时,需要添置一台web服务器,这时候就需要nginx来 做负载均衡,把浏览器的访问量以特定的规则分发到两台web服务器上。
(3)反向代理:正常情况下客户端直接访问服务器。反向代理是客户端请求nginx,nginx请求服务器,然后返回数据给客户端。
(4)虚拟主机:例如将www.aaa.com和www.bbb.com两个网站部署在同一台服务器上,两个域名解析到同一个IP地址,但是用户通过两个域名却可以打开两个完全不同的网站,互相不影响,就像访问两个服务器一样,所以叫两个虚拟主机。个域名解析同一个IP地址。用nginx做反向代理将对不同域名的请求分别转发到该IP的不同端口。

解决上面的问题,用到nginx反向代理,虚拟主机

Nginx安装:选择使用docker,一键部署。具体可参考博客:http://www.ruanyifeng.com/blog/2018/02/nginx-docker.html。在此使用nginx做反向代理而不是web服务器,所以只需要修改nginx配置,将配置文件映射到本地,不需要映射网页html文件。
Nginx配置:
实现功能:

  • 访问http://aa.com时,自动跳转到https://aa.com,然后再转发到http://10.8.5.5:8888
  • 访问http://bb.aa.com时,自动跳转到https://bb.aa.com,然后再转发到https://10.8.5.5:5020/api/,转发时对客户端不透明,浏览器上仍显示https://bb.aa.com,实则请求https://10.8.5.5:5020/api/

以上可以实现的前提是DNS可以自动将domain解析到配置nginx的服务器ip上。

配置文件:

upstream upstream1 {  
    server 10.8.5.5:8888;  
    }   #upstream 实现负载均衡,可在此配置多个服务器
#------------http 重定向到https上----------------------
server {
    listen       80;
    server_name  aa.com;  #主域名
    return      301 https://$server_name; 重定向,浏览器向重定向后的地址重新请求
}

server {
    listen       80;
    server_name  bb.aa.com; #二级域名
    return      301 https://$server_name; 
}
#------------------------https设置反向代理-----------------------
server {
    listen 443 ssl http2;
    server_name  aa.com;  #主域名
    
   ssl                      on;
   ssl_certificate          /etc/nginx/certs/example.crt;   #证书位置
   ssl_certificate_key      /etc/nginx/certs/example.key;

    ssl_session_timeout  5m;

    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers   on;

    location / {
        proxy_pass  http://upstream1 ;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        #proxy_buffer_size 64k;
        #proxy_buffers   32 32k;
        #proxy_busy_buffers_size 128k;

    }

}

server {
    listen 443 ssl http2;
    server_name  bb.aa.com; #二级域名
    
   ssl                      on;
   ssl_certificate          /etc/nginx/apicerts/example.crt;
   ssl_certificate_key      /etc/nginx/apicerts/example.key;

    ssl_session_timeout  5m;

    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers   on;

    location / {

        proxy_pass  https://10.8.5.5:5020/api/;  #被代理服务器地址

        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        #proxy_buffer_size 64k;
        #proxy_buffers   32 32k;
        #proxy_busy_buffers_size 128k;

    }

    location /swaggerui/ {#二级目录转发
            proxy_pass https://10.8.5.5:5020/swaggerui/;  需要转发的二级domain本身为https,
                # 该路径下为web页面的静态文件css,js等,不设置的话网页无法正常展示          
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
         }

    location /api/ {#二级目录转发

            proxy_pass  https://10.8.5.5:5020/api/;

            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
            #proxy_buffer_size 64k;
            #proxy_buffers   32 32k;
            #proxy_busy_buffers_size 128k;
        }

}

至此,所有配置均已完成,启动命令:

docker container run   -d  \
-p 10.8.5.5:80:80 -p 10.8.5.5:443:443 \
--rm   \
--name mynginx \
--volume "/mnt/storage/nginx_docker_demo/conf":/etc/nginx  \
nginx

-d 后台运行
-p 容器80端口映射到10.8.5.5:80
-- rm 停止运行后删除容器文件
-- name 自定义容器名称
-volumn nginx配置文件映射
Bingo Bingo ~~~~
docker ps 可以查看正在运行的容器,可以发现已经启动成功。

番外:配置过程中遇到的一些其他问题:
1.ssl 证书 ,我用的是openssl申请的免费版证书,只能用于一个domain,对二级domain无效(貌似免费的都是这样),因此在nginx配置的时候分别配置,制定各自证书,否则可以配置到一起。配置方法如下:

server {
   listen 443 ssl http2;
    server_name  *.aa.com;  #此处设置为泛域名
    
   ssl                      on;
   ssl_certificate          /etc/nginx/certs/example.crt;  ##一定是相同的证书
   ssl_certificate_key      /etc/nginx/certs/example.key;

   ssl_session_timeout  5m;

   ssl_ciphers HIGH:!aNULL:!MD5;
   ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
   ssl_prefer_server_ciphers   on;

   if ($http_host ~* "^(.*?)\.aa\.com$") {    
                set $domain $1;                    
       }

   location / {
    if ($domain ~* "bb") {
              proxy_pass  https://10.8.5.5:5020/api/;#匹配到子域名时设置相应的转发  
            }
    proxy_pass  http://upstream1;#默认情况,也就是主域名时相应的转发
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
    }
  1. 配置子域名时有些特殊,web页面是flask-restplus框架中封装的swagger UI,本来也是http通信,按照主域名的配置后,静态的页面找不到css,js文件。找到这些文件所在路径后在nginx中添加二级目录可以解决。


    文件路径

    此时又出现了另外一个问题,swagger读某些json文件时为http,这样就产生了https和http混合通信,无法正常工作。在网上找了些解决办法,都不生效。干脆在flask-restplus配置为https,这样就全部是https通信了,修改的代码在此记录下:

###需要安装模块  pip install pyOpenSSL
if __name__ == '__main__':
    from werkzeug.contrib.fixers import ProxyFix
    initialize_app(app)
    app.wsgi_app = ProxyFix(app.wsgi_app) #手动修复代理
    app.run(threaded=True, host='0.0.0.0', port=5020 ,ssl_context='adhoc')#此处一定是adhoc,使用python模块自动生成的证书

你可能感兴趣的:(Nignx 配置反向代理)