概述
本文介绍如何在不影响现有 Nginx Web 服务的前提下,另行部署一套 Nginx 正向代理服务。该配置将:
- 独立运行,不影响现有服务
- 启动独立的 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
编译选项说明:
--prefix=/opt/nginx-proxy:安装到独立目录--with-http_ssl_module:支持 HTTPS 代理--add-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
客户端配置
浏览器代理设置
手动配置代理:
- 打开浏览器代理设置
- 选择”手动代理配置”
- HTTP 代理:
<Nginx服务器IP> - 端口:
3128 - HTTPS 代理:
<Nginx服务器IP> - 端口:
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 正向代理服务,主要特点:
✅ 核心优势
- 独立部署,不影响现有服务
- 支持 HTTP 和 HTTPS 代理
- 完整的访问控制机制
- 详细的日志记录功能
- 易于管理和维护
📋 最佳实践
- 安全性:
- 配置严格的 IP 白名单
- 考虑启用基本认证
- 定期更新 Nginx 版本
- 性能:
- 根据服务器配置调整 worker 数量
- 合理设置连接数和超时时间
- 启用日志轮转避免磁盘占满
- 运维:
- 使用 systemd 管理服务
- 配置监控脚本自动恢复
- 定期检查日志文件
- 测试:
- 配置修改后务必测试语法
- 先在测试环境验证
- 准备回滚方案