说实话,我最开始学反向代理的时候是被坑惨了的。网上的教程要么就三行proxy_pass贴完就走人,要么堆一堆配置让你看不懂哪里是干嘛的。我按某篇教程改完配置,nginx -t也显示OK了,结果一访问就是502,折腾了一晚上最后发现是少了一行proxy_ssl_server_name on——这玩意儿网上一半教程根本不提。
所以这篇我打算按真实操作顺序来写,从装Nginx到能正常打开被代理的网站,每一步做了什么、为什么要这么写、不写会出什么问题,都说清楚。跟着做下来你应该能避开我踩过的大部分坑。
目录
反向代理到底是个什么东西
别被名字吓到。说白了,反向代理就是个"中间商":用户访问你的VPS,你的VPS在背后去请求真正的目标网站,拿到内容再原样返回给用户。对用户来说,他以为内容就是你服务器提供的,其实你只是代人拿了个货。
跟翻墙那个"代理"的区别是:普通代理(VPN那种)是客户端主动告诉代理服务器"我要访问XX",反向代理是在服务器端就写死了"只要有人来访问我,我就去XX拿内容"。用户端不用装任何软件,浏览器直接访问你的域名就行。
这玩意儿的实际用途其实很广:
- 把Google Fonts、GitHub等在国内慢或者打不开的静态资源套一层,让你自己的网站加载快一些
- 公司内网服务暴露到公网(要加认证)
- 跨域调试前端页面
- 给没有HTTPS的老服务套一层SSL
- 做多服务器的负载均衡
准备工作
你需要的东西不多:
- 一台境外VPS。香港日本新加坡都行,带宽别太小,推荐至少3M以上。我一直用的LuckVM香港标准版,5M CN2带宽,跑代理很稳,晚高峰也不卡。延迟低到国内基本感觉不到绕路。
- 一个域名(不需要备案,因为服务器在境外)。二级域名就行,比如
proxy.yourdomain.com。 - SSH能连上服务器。
第一步:装Nginx
连上服务器之后,先装Nginx。CentOS 7用yum:
yum install -y epel-release
yum install -y nginx
Ubuntu/Debian用户用apt:
apt update
apt install -y nginx
装完启动,顺便设成开机自启:
systemctl start nginx
systemctl enable nginx

看到"Complete!"和Created symlink的提示就说明装好了
这时候你浏览器直接访问VPS的IP地址,应该能看到Nginx的默认欢迎页。看不到的话,先检查服务器防火墙/安全组有没有放行80端口。
第二步:写一个最小可用的反向代理配置
Nginx的配置文件在/etc/nginx/下面。主配置是nginx.conf,但我们一般不去改它,而是在/etc/nginx/conf.d/目录里新建一个.conf文件,Nginx启动时会自动加载这个目录下所有配置。
vi /etc/nginx/conf.d/proxy.conf
把下面这段贴进去(我逐行加了注释,你看着改):
server {
listen 80;
server_name proxy.yourdomain.com; # 改成你自己的域名
location / {
proxy_pass https://www.google.com; # 你要代理的目标地址
proxy_set_header Host www.google.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
# 下面这行很重要,代理HTTPS站点必须加
# 我第一次就是漏了它,返回403搞了半天
proxy_ssl_server_name on;
proxy_redirect off;
}
}

proxy_pass这一行是整个配置的核心,其余几行都是为了让请求看起来像正常浏览器发出去的
这里几个地方新手容易搞晕,说清楚:
proxy_pass后面的地址,末尾加不加斜杠意思完全不一样。https://example.com和https://example.com/转发路径的规则不同。想原样转发路径,就别加末尾斜杠。proxy_set_header Host后面填的值要跟目标网站一致,很多网站会校验Host头,填错直接404或403。proxy_ssl_server_name on这行是在告诉Nginx,TLS握手时要带上SNI(就是告诉对方服务器我要访问哪个域名)。现在几乎所有支持HTTPS的大站点都要求SNI,不写就握手失败。我真的见太多教程漏了这一行。
第三步:测试配置并重载
Nginx这点做得比Apache好——改完配置不会立刻生效,你先测一下有没有语法错误,测试通过了再平滑重载,不影响正在跑的连接。
nginx -t

看到syntax is ok和test is successful就可以放心reload
然后重载:
nginx -s reload
这时候去把你的域名A记录解析到VPS的IP,浏览器访问你的域名,应该就能看到Google首页了。

地址栏显示的是你自己的域名,内容却是Google——反向代理就这么简单
第四步:配HTTPS证书
用Let's Encrypt免费证书就行,用Certbot装最省事。
# CentOS
yum install -y certbot python3-certbot-nginx
# Ubuntu
apt install -y certbot python3-certbot-nginx
然后一行命令申请证书并自动改Nginx配置:
certbot --nginx -d proxy.yourdomain.com
它会问你要不要自动跳转到HTTPS,选2(Redirect),它会自动帮你把80端口的请求301跳转到443。完成之后再访问你的域名,地址栏就有小锁了。

Let's Encrypt证书90天过期,Certbot会自动加一个定时任务续期,不用你管。可以用下面这条命令验证自动续期能不能正常跑:
certbot renew --dry-run
几个必须加的优化项
最小配置能跑,但不好用。加上下面这几堆配置,稳定性和速度会好很多。
1. 超时设置(默认60秒太长)
location / {
# ... 前面那些保留 ...
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 大文件上传用得上
client_max_body_size 100m;
}
2. WebSocket支持(代理TikTok、聊天类网站必须加)
location / {
# ... 保留原有配置 ...
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
3. 解决部分网站跳转回真实域名的问题
有些网站在返回的响应头里会带Location字段指向它自己的域名,浏览器就直接跳走了。加一行把它替换掉:
location / {
# ...
proxy_redirect https://www.google.com/ /;
# 如果响应里的HTML/CSS/JS也写死了真实域名,可以用sub_filter替换
sub_filter "www.google.com" "proxy.yourdomain.com";
sub_filter_once off;
}

进阶玩法
开启缓存:重复访问快很多
在server {}块外面(也就是http块里)定义一个缓存区,然后在location里启用:
# 写在conf.d/proxy.conf的最顶部,server块外面
proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=7d;
server {
# ...
location / {
# ...
proxy_cache my_cache;
proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 5m;
add_header X-Cache $upstream_cache_status; # 调试用,HIT就是走了缓存
}
}
负载均衡:多台后端服务器轮询
如果你有多台后端机器,Nginx可以自动分流:
upstream backend {
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=1;
}
server {
location / {
proxy_pass http://backend;
}
}
weight是权重,3比1意味着前三台请求发到第一台,第四台发到第二台。
我踩过的6个坑
这些坑我全中过,一个都没落下:
- 502 Bad Gateway — 十有八九是后端地址写错了,或者后端根本没起来。看Nginx错误日志:
tail /var/log/nginx/error.log,它会告诉你是连接被拒还是DNS解析失败。 - 403 Forbidden — 大概率是Host头不对,或者目标网站对服务器IP段有拦截(比如Google对某些机房IP就会封)。换个IP或者换个节点试试。
- 页面打开但样式全乱 — 混合内容问题(HTTPS页面加载了HTTP资源),或者是页面里写死了绝对路径。把sub_filter加上,或者先确保你代理的目标和你自己的协议一致。
- 配置改了没生效 — 99%的人改完配置忘了
nginx -s reload。改完一定要reload。改完一定要reload。改完一定要reload。(重要的事说三遍) - 大文件上传失败 — 默认client_max_body_size是1M,超过就413。把它改成你需要的大小。
- 自己改完配置直接把Nginx弄挂了 — 永远先
nginx -t再reload。如果t通了但reload之后还是挂了,systemctl status nginx看报错。所以买VPS的时候一定要选带VNC控制台的(LuckVM后台有),万一SSH连不上还能VNC进去修。
# 先装htpasswd工具
yum install -y httpd-tools # CentOS
# apt install -y apache2-utils # Ubuntu
# 创建密码文件(把yourname换成你想用的用户名)
htpasswd -c /etc/nginx/.htpasswd yourname
# 输入两次密码
# 然后在location里加两行:
# auth_basic "Restricted";
# auth_basic_user_file /etc/nginx/.htpasswd;
FAQ
能。Nginx本身非常轻,纯反代1核1G扛几千并发都没问题。但如果你同时跑着MySQL、PHP、WordPress一堆东西,那就另说了。纯反代用途最低配1核512M都能跑。
CDN本质上就是部署在全球各地的反向代理节点,只不过它还多了智能调度、缓存、防攻击这些功能。你自己搭的反代可以理解成一个单点CDN。
因为Google对机房IP(相对家宽IP)天然不信任,尤其是一些被滥用严重的IP段。如果你就是想方便自己用搜素,建议搭配密码保护不要公开,或者换一台IP干净的机器。
当然可以。每个站点写一个server块,server_name不同就行。或者你也可以用一个server块通过路径区分,比如/google/代理Google,/github/代理GitHub,但这种路径方式容易遇到相对路径资源加载的问题,不如子域名方便。
Caddy自动申请证书比较省心,适合懒人。Traefik在Docker/K8s环境下更方便。但Nginx生态最成熟、资料最多、遇到问题基本都能搜到答案,新手从Nginx学起不会错。
看你VPS线路怎么样。香港CN2线路到国内延迟30-50ms,代理海外站点通常比你直连快(因为VPS带宽更大、路由更优)。但如果你拿美西的机器反代,那肯定会慢。
Nginx反向代理这个东西,说穿了就十几行配置,但要把细节做对、坑踩完,还真的得自己亲手搭一次才知道。写完配置记得nginx -t,记得reload,记得加SNI,记得加密码保护——记住这几件事,基本就不会有大问题。
下一篇我打算写怎么用Nginx做负载均衡+健康检查,适合手上有多台服务器的玩家。感兴趣可以收藏一下本站。
想练手但还没VPS?
LuckVM香港CN2线路VPS,月付78港币起,支持VNC控制台(弄挂了也能救),免费快照备份(改配置之前拍一张,弄坏了一键回滚),新用户有24小时无理由退款。
查看LuckVM VPS配置 →




