Nginx 正向代理配置指南

github.com 于 2025-12-25 发布

概述

本文介绍如何在不影响现有 Nginx Web 服务的前提下,另行部署一套 Nginx 正向代理服务。该配置将:


环境准备

下载必要文件

# 进入源码目录
cd /usr/local/src/

# 下载 Nginx 1.24.0
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar zxvf nginx-1.24.0.tar.gz

# 克隆代理连接模块
git clone https://github.com/chobits/ngx_http_proxy_connect_module.git

编译安装

应用补丁

cd nginx-1.24.0

# 应用 proxy_connect 模块补丁
patch -p1 < ../ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_102101.patch

配置编译选项

./configure \
  --prefix=/opt/nginx-proxy \
  --conf-path=/opt/nginx-proxy/conf/nginx.conf \
  --pid-path=/opt/nginx-proxy/run/nginx.pid \
  --error-log-path=/opt/nginx-proxy/logs/error.log \
  --http-log-path=/opt/nginx-proxy/logs/access.log \
  --with-http_ssl_module \
  --with-http_realip_module \
  --with-http_gzip_static_module \
  --with-pcre \
  --add-module=../ngx_http_proxy_connect_module

编译选项说明

编译并安装

# 多核编译加速
make -j$(nproc)

# 安装
make install

配置验证

验证模块安装

/opt/nginx-proxy/sbin/nginx -V 2>&1 | grep proxy_connect

预期输出:应该能看到 proxy_connect 模块信息

如果没有看到,说明模块未成功编译进去,需要重新检查编译步骤。


配置文件

编辑配置文件

vi /opt/nginx-proxy/conf/nginx.conf

完整配置(标准版 - 推荐)

# 工作进程数(auto 表示自动检测 CPU 核心数)
worker_processes auto;

events {
    # 单个工作进程最大连接数
    worker_connections 10240;
}

http {
    # ===== DNS 解析配置 =====
    # 使用 Google DNS 和 Cloudflare DNS
    resolver 8.8.8.8 1.1.1.1 valid=300s;
    resolver_timeout 5s;

    # ===== 日志格式 =====
    log_format proxy '$remote_addr [$time_local] '
                     '"$request" '
                     '$status $bytes_sent '
                     '"$host"';

    access_log logs/access.log proxy;
    error_log logs/error.log warn;

    # ===== 代理服务器配置 =====
    server {
        listen 3128;

        # ===== 正向代理核心配置 =====
        proxy_connect;
        proxy_connect_allow 443 563;
        proxy_connect_connect_timeout 10s;
        proxy_connect_read_timeout 60s;
        proxy_connect_send_timeout 60s;

        # ===== 访问控制 =====
        # 允许内网访问
        allow 192.168.0.0/16;
        # 拒绝其他所有访问
        deny all;

        # ===== HTTP 代理配置 =====
        location / {
            # 修复:添加 $request_uri 确保完整的请求路径被代理
            proxy_pass http://$host$request_uri;
            proxy_set_header Host $host;
            proxy_set_header Proxy-Connection "";
            proxy_http_version 1.1;
        }
    }
}

增强配置(生产环境推荐)

# 工作进程数
worker_processes auto;

# 错误日志
error_log /opt/nginx-proxy/logs/error.log warn;
pid /opt/nginx-proxy/run/nginx.pid;

events {
    worker_connections 10240;
    use epoll;
}

http {
    include mime.types;
    default_type application/octet-stream;

    # ===== DNS 解析配置 =====
    resolver 8.8.8.8 1.1.1.1 valid=300s;
    resolver_timeout 5s;

    # ===== 日志格式 =====
    log_format proxy '$remote_addr [$time_local] '
                     '"$request" $status $bytes_sent '
                     '"$http_referer" "$http_user_agent" '
                     '"$host"';

    access_log logs/access.log proxy;

    # ===== 基础配置 =====
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # ===== 代理服务器配置 =====
    server {
        listen 3128;
        server_name _;

        # ===== 正向代理核心配置 =====
        proxy_connect;
        proxy_connect_allow 443 563;
        proxy_connect_connect_timeout 10s;
        proxy_connect_read_timeout 60s;
        proxy_connect_send_timeout 60s;

        # ===== 访问控制 =====
        allow 192.168.0.0/16;
        deny all;

        # ===== HTTP 代理配置 =====
        location / {
            proxy_pass http://$http_host$request_uri;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Proxy-Connection "";
            
            # 缓冲配置
            proxy_buffers 256 4k;
            proxy_max_temp_file_size 0k;
            
            # 超时配置
            proxy_connect_timeout 30;
            proxy_send_timeout 60;
            proxy_read_timeout 60;
            
            # HTTP 版本
            proxy_http_version 1.1;
            
            # 错误处理
            proxy_next_upstream error timeout invalid_header http_502;
        }
    }
}

配置说明

配置项 说明
listen 3128 代理服务监听端口
proxy_connect 启用 CONNECT 方法支持(用于 HTTPS)
proxy_connect_allow 443 563 允许代理的端口(HTTPS 和 NNTPS)
proxy_pass http://$host$request_uri 修复后:完整的请求转发,包含路径和参数
resolver DNS 服务器配置
allow 192.168.0.0/16 允许的客户端 IP 段
deny all 拒绝其他所有访问

启动服务

语法检测

/opt/nginx-proxy/sbin/nginx -t

预期输出

nginx: the configuration file /opt/nginx-proxy/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx-proxy/conf/nginx.conf test is successful

启动 Nginx

# 启动服务
/opt/nginx-proxy/sbin/nginx

# 如果端口被占用,可以查看
lsof -i :3128

验证进程

# 查看进程
ps aux | grep nginx-proxy

# 查看端口监听
netstat -tlnp | grep 3128
# 或使用 ss 命令
ss -tlnp | grep 3128

客户端配置

浏览器代理设置

手动配置代理

  1. 打开浏览器代理设置
  2. 选择”手动代理配置”
  3. HTTP 代理:<Nginx服务器IP>
  4. 端口:3128
  5. HTTPS 代理:<Nginx服务器IP>
  6. 端口:3128

系统代理设置(Linux)

export http_proxy=http://<Nginx服务器IP>:3128
export https_proxy=http://<Nginx服务器IP>:3128

# 测试代理
curl -I http://www.google.com

系统代理设置(Windows)

设置 -> 网络和Internet -> 代理 -> 手动设置代理

测试代理

# 使用 curl 测试 HTTP
curl -x http://<Nginx服务器IP>:3128 http://www.baidu.com

# 测试 HTTPS
curl -x http://<Nginx服务器IP>:3128 https://www.google.com

# 查看返回头信息
curl -I -x http://<Nginx服务器IP>:3128 http://www.baidu.com

服务管理

常用命令

# 启动服务
/opt/nginx-proxy/sbin/nginx

# 停止服务
/opt/nginx-proxy/sbin/nginx -s stop

# 优雅停止
/opt/nginx-proxy/sbin/nginx -s quit

# 平滑重启
/opt/nginx-proxy/sbin/nginx -s reload

# 重新打开日志文件
/opt/nginx-proxy/sbin/nginx -s reopen

# 测试配置
/opt/nginx-proxy/sbin/nginx -t

# 查看版本和编译选项
/opt/nginx-proxy/sbin/nginx -V

创建 Systemd 服务(推荐)

创建服务文件:

vi /etc/systemd/system/nginx-proxy.service

服务配置:

[Unit]
Description=Nginx Forward Proxy Server
After=network.target

[Service]
Type=forking
PIDFile=/opt/nginx-proxy/run/nginx.pid
ExecStartPre=/opt/nginx-proxy/sbin/nginx -t
ExecStart=/opt/nginx-proxy/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

启用服务:

# 重载 systemd 配置
systemctl daemon-reload

# 启动服务
systemctl start nginx-proxy

# 开机自启
systemctl enable nginx-proxy

# 查看状态
systemctl status nginx-proxy

# 查看日志
journalctl -u nginx-proxy -f

日志分析

访问日志

# 实时查看访问日志
tail -f /opt/nginx-proxy/logs/access.log

# 统计访问最多的域名(Top 10)
awk '{print $7}' /opt/nginx-proxy/logs/access.log | sort | uniq -c | sort -nr | head -10

# 统计客户端 IP
awk '{print $1}' /opt/nginx-proxy/logs/access.log | sort | uniq -c | sort -nr

# 统计状态码
awk '{print $4}' /opt/nginx-proxy/logs/access.log | sort | uniq -c | sort -nr

错误日志

# 查看错误日志
tail -f /opt/nginx-proxy/logs/error.log

# 统计错误类型
grep -oP '\[error\].*' /opt/nginx-proxy/logs/error.log | sort | uniq -c

# 查看最近的错误
tail -20 /opt/nginx-proxy/logs/error.log

安全加固

基本认证(可选)

如果需要用户名密码认证:

# 安装 htpasswd 工具
yum install httpd-tools -y  # CentOS/RHEL
apt install apache2-utils -y  # Debian/Ubuntu

# 创建密码文件(第一个用户)
htpasswd -c /opt/nginx-proxy/conf/.htpasswd username1

# 添加更多用户(不使用 -c 参数)
htpasswd /opt/nginx-proxy/conf/.htpasswd username2

在配置文件中添加:

server {
    listen 3128;
    
    # 添加基本认证
    auth_basic "Proxy Authentication Required";
    auth_basic_user_file /opt/nginx-proxy/conf/.htpasswd;
    
    # ... 其他配置 ...
}

IP 白名单优化

根据实际需求调整允许的 IP 段:

# 允许特定 IP
allow 192.168.1.100;
allow 192.168.1.101;

# 允许多个 IP 段
allow 192.168.0.0/16;
allow 10.0.0.0/8;
allow 172.16.0.0/12;

# 拒绝其他所有 IP
deny all;

限制访问速率

http {
    # 定义限速区域
    limit_req_zone $binary_remote_addr zone=proxy_limit:10m rate=10r/s;
    
    server {
        location / {
            # 应用限速
            limit_req zone=proxy_limit burst=20 nodelay;
            # ... 其他配置 ...
        }
    }
}

故障排查

常见问题

1. 端口被占用

# 检查端口占用
lsof -i :3128
netstat -tlnp | grep 3128

# 修改监听端口
vi /opt/nginx-proxy/conf/nginx.conf
# 将 listen 3128 改为其他端口,如 listen 8128

2. DNS 解析失败

# 测试 DNS
nslookup google.com 8.8.8.8

# 更换其他 DNS 服务器
# 国内可用的 DNS:
resolver 114.114.114.114 223.5.5.5;
resolver 119.29.29.29 180.76.76.76;

3. 客户端无法连接

# 检查防火墙(firewalld)
firewall-cmd --list-ports
firewall-cmd --add-port=3128/tcp --permanent
firewall-cmd --reload

# 检查防火墙(iptables)
iptables -L -n | grep 3128
iptables -I INPUT -p tcp --dport 3128 -j ACCEPT
service iptables save

# 检查 SELinux
getenforce
# 如果是 Enforcing,临时关闭测试
setenforce 0

4. HTTPS 代理失败

# 确认模块已加载
/opt/nginx-proxy/sbin/nginx -V 2>&1 | grep proxy_connect

# 确认配置正确
grep -A 3 "proxy_connect" /opt/nginx-proxy/conf/nginx.conf

# 测试 HTTPS 连接
curl -v -x http://<server_ip>:3128 https://www.google.com

5. 502 Bad Gateway 错误

# 检查 DNS 解析
dig @8.8.8.8 google.com

# 检查目标主机连通性
ping -c 3 google.com

# 增加超时时间
proxy_connect_timeout 30s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;

6. 日志显示权限错误

# 检查日志目录权限
ls -ld /opt/nginx-proxy/logs/
chmod 755 /opt/nginx-proxy/logs/

# 检查运行用户
ps aux | grep nginx-proxy

性能优化

连接数优化

# 系统层面优化
# 编辑 /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_fin_timeout = 30
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192

# 应用配置
sysctl -p
# Nginx 配置优化
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 20480;
    use epoll;
    multi_accept on;
}

http {
    keepalive_timeout 65;
    keepalive_requests 100;
    
    # 开启文件缓存
    open_file_cache max=10000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
}

缓冲优化

http {
    # 代理缓冲设置
    proxy_buffering on;
    proxy_buffer_size 8k;
    proxy_buffers 32 8k;
    proxy_busy_buffers_size 16k;
    proxy_max_temp_file_size 0;
    
    # 客户端请求缓冲
    client_body_buffer_size 256k;
    client_header_buffer_size 2k;
    large_client_header_buffers 4 8k;
}

监控和维护

日志轮转

创建日志轮转配置:

vi /etc/logrotate.d/nginx-proxy

配置内容:

/opt/nginx-proxy/logs/*.log {
    daily
    rotate 30
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        [ -f /opt/nginx-proxy/run/nginx.pid ] && kill -USR1 `cat /opt/nginx-proxy/run/nginx.pid`
    endscript
}

测试轮转:

logrotate -d /etc/logrotate.d/nginx-proxy
logrotate -f /etc/logrotate.d/nginx-proxy

监控脚本

创建简单的监控脚本:

vi /opt/nginx-proxy/monitor.sh
#!/bin/bash

# Nginx 代理监控脚本
NGINX_PID="/opt/nginx-proxy/run/nginx.pid"
NGINX_BIN="/opt/nginx-proxy/sbin/nginx"
LOG_FILE="/opt/nginx-proxy/logs/monitor.log"

if [ ! -f "$NGINX_PID" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Nginx is not running, starting..." >> $LOG_FILE
    $NGINX_BIN
elif ! kill -0 $(cat $NGINX_PID) 2>/dev/null; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Nginx process dead, restarting..." >> $LOG_FILE
    $NGINX_BIN
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Nginx is running normally" >> $LOG_FILE
fi

设置定时任务:

chmod +x /opt/nginx-proxy/monitor.sh

# 添加到 crontab(每5分钟检查一次)
crontab -e
*/5 * * * * /opt/nginx-proxy/monitor.sh

总结

通过本文配置,你已经成功搭建了一个完整的 Nginx 正向代理服务,主要特点:

✅ 核心优势

📋 最佳实践

  1. 安全性
    • 配置严格的 IP 白名单
    • 考虑启用基本认证
    • 定期更新 Nginx 版本
  2. 性能
    • 根据服务器配置调整 worker 数量
    • 合理设置连接数和超时时间
    • 启用日志轮转避免磁盘占满
  3. 运维
    • 使用 systemd 管理服务
    • 配置监控脚本自动恢复
    • 定期检查日志文件
  4. 测试
    • 配置修改后务必测试语法
    • 先在测试环境验证
    • 准备回滚方案

参考资源