Simple Nginx 6

什么是正向代理和反向代理

反向代理(Reverse Proxy)方式是指,以代理服务器来接收internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求的客户端,此时代理服务器对外的表现就是一个服务器.

通常的代理服务器,只用于代理内部网络对internet的连接请求,客户机必须指定代理服务器,并将原来直接要发送到Web服务器上的请求发送到代理服务器中.由于外部网络上的主机并不会配置并使用这个代理服务器,普通代理服务器也会被设计为在internet上搜寻多个不确定的服务器.而不是针对internet上多个客户机的请求访问某一个固定的服务器,因此普通的web服务器不支持外部对内部的网络访问请求.

当一个代理服务器能够能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式叫做反向代理服务.此时代理服务器对外就表现为一个Web服务器,外部网络就可以简单把他当做一个标准的Web服务器而不需要特定的配置.不同之处在于,这个服务器没有保存任何网页上的真实数据,所有的静态网页或CGI程序,都保存在内部服务器上.因此对反向代理服务器的攻击并不会使得网页信息遭到破坏,这样就增强了Web服务的安全性.

为何叫做反向?

从原理上来说,代理服务器都是处理来自客户端的请求,并将其转发到目的服务器上,所以代理服务器的工作并没有任何反向的意思,而下面这张图说明了叫做反向代理的原因:

Reverse-Server

从结构上来看,正向代理和反向代理的左右两边换了一下,原本代理服务器的客户端来自内网,其和代理服务器组成一个LAN,而在反向代理中,代理服务器和服务器成了一组,所以从结构上来看,是反向的.

正向代理配置

server {
    resolver 8.8.8.8;                           # 配置DNS解析地址,如Google public DNS,可以有多个进行轮询
    resolver_timeout 5s;                        # 超时设置

    listen 0.0.0.0:8080;                        

    access_log  /home/reistlin/logs/proxy.access.log;
    error_log   /home/reistlin/logs/proxy.error.log;

    location / {
        proxy_pass $scheme://$host$request_uri; # 配置正向代理参数,均由Nginx变量构成
        proxy_set_header Host $http_host;

        proxy_buffers 256 4k;                   # 配置缓存大小
        proxy_max_temp_file_size 0;             # 关闭磁盘缓存读写减少IO

        proxy_connect_timeout 30;               # 代理超时设置

        proxy_cache_valid 200 302 10m;          # 配置代理服务器HTTP状态缓存时间
        proxy_cache_valid 301 1h;
        proxy_cache_valid any 1m;
    }
}

反向代理配置

基本配置:

user www www;
worker_processes 1;
error_log logs/error.log;
pid logs/nginx.pid;
worker_rlimit_nofile 65535;
events {
    use epoll;
    worker_connections 65535;
}
http {
    include mime.types;
    default_type application/octet-stream;
    include /usr/local/nginx/conf/reverse-proxy.conf;
    sendfile on;
    keepalive_timeout 65;
    gzip on;
    client_max_body_size 50m; #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户
    client_body_buffer_size 256k;
    client_header_timeout 3m;
    client_body_timeout 3m;
    send_timeout 3m;
    proxy_connect_timeout 300s; #nginx跟后端服务器连接超时时间(代理连接超时)
    proxy_read_timeout 300s; #连接成功后,后端服务器响应时间(代理接收超时)
    proxy_send_timeout 300s;
    proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
    proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
    proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
    proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
    proxy_ignore_client_abort on; #不允许代理端主动关闭连接
    server {
        listen 80;
        server_name localhost;
        location / {
            root html;
            index index.html index.htm;
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }
    }
}

反向代理配置:

server
{
    listen 80;
    server_name xxx123.tk;
    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://192.168.10.38:3000;
    }
    access_log logs/xxx123.tk_access.log;
}

server
{
    listen 80;
    server_name xxx456.tk;
    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://192.168.10.40:80;
    }
    access_log logs/xxx456.tk_access.log;
}

首先,将域名指向该反向代理服务器的公网IP,这是访问域名xxx123.tk时,会将请求代理到192.168.10.38:3000服务器,xxx456.tk会被代理到192.168.10.40:80服务器.

负载均衡配置:

upstream monitor_server {
    server 192.168.0.131:80;
    server 192.168.0.132:80;
}

server
{
    listen 80;
    server_name nagios.xxx123.tk;
    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://monitor_server;
    }
    access_log logs/nagios.xxx123.tk_access.log;
}

以上配置将nagios.xxx123.tk的请求分发到131和132这两台服务器.

由于http请求都是由反向代理服务器传递给后端的服务器,所以后端的机器原来的访问日志记录的访问IP都是反向代理服务器的IP,如果需要真实的请求IP,需要修改后端机器的日志格式,这里假设后端也是一台nginx服务,在后端nginx配置文件中:

log_format access '$HTTP_X_REAL_IP - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $HTTP_X_Forwarded_For';

access_log logs/access.log access;

对比原来的日志配置:

# log_format main '$remote_addr - $remote_user [$time_local] "$request" '
#  '$status $body_bytes_sent "$http_referer" '
#  '"$http_user_agent" "$http_x_forwarded_for"';

# access_log logs/access.log main;

支持websocket配置

upstream ws_server {
  server 127.0.0.1:3000;
}

server {
  listen 80;
  server_name ws.repo;

  location / {
    proxy_pass http://ws_server/;
    proxy_redirect off;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

参考链接