概述
你有一个跑在内网的服务——比如本地的Web应用、HomeAssistant或者NAS上的文件管理——你想通过自己的域名从外面访问它。
不用Docker,不用复杂的编排工具。只用最基础的Nginx反向代理,几行配置搞定。
这篇文章教你在Ubuntu服务器上从零部署Nginx反向代理,把内网服务安全地暴露到公网。
准备工作
你需要:
- 一台运行Ubuntu 22.04或24.04的VPS(推荐2核4G以上)
- 一个已解析到VPS IP的域名
- SSH登录权限
- 内网服务的地址(比如
http://192.168.1.100:8080)
如果你还没有域名,去Cloudflare、Namecheap或者阿里云买一个,然后把A记录指向你的VPS公网IP。
步骤
第一步:安装Nginx
SSH登录到你的VPS,执行:
sudo apt update
sudo apt install -y nginx
安装完成后,启动并设置开机自启:
sudo systemctl enable --now nginx
检查Nginx状态:
sudo systemctl status nginx
看到绿色的 active (running) 就对了。
第二步:配置防火墙
如果你的VPS用了UFW防火墙,放行HTTP和HTTPS:
sudo ufw allow 'Nginx Full'
sudo ufw reload
如果用的是云服务商的安全组(比如阿里云、腾讯云),记得在控制台放行80和443端口。
第三步:编写Nginx配置文件
进入Nginx的sites-available目录:
cd /etc/nginx/sites-available/
创建一个新配置文件,名字用你的域名:
sudo nano myapp.example.com
写入以下内容(按需修改):
server {
listen 80;
server_name myapp.example.com;
location / {
proxy_pass http://192.168.1.100:8080;
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_set_header X-Forwarded-Proto $scheme;
}
}
几个关键参数说明:
proxy_pass:你的内网服务地址proxy_set_header Host:把原始域名传给后端X-Real-IP:把访客真实IP传给后端X-Forwarded-Proto:告诉后端原始协议是HTTP还是HTTPS
保存退出。
第四步:启用配置并测试
创建软链接到sites-enabled:
sudo ln -s /etc/nginx/sites-available/myapp.example.com /etc/nginx/sites-enabled/
删除默认配置(避免冲突):
sudo rm /etc/nginx/sites-enabled/default
测试配置文件语法:
sudo nginx -t
输出 syntax is ok 和 test is successful 就没问题。
重载Nginx生效:
sudo systemctl reload nginx
第五步:配置SSL证书
反向代理裸奔在HTTP上不安全。用Certbot免费申请Let’s Encrypt证书:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d myapp.example.com
按提示输入邮箱,同意条款。Certbot会自动修改Nginx配置,把HTTP跳转到HTTPS,并配置好SSL。
验证
打开浏览器,访问 https://myapp.example.com。
如果能看到你的内网服务界面,说明配置成功。
在服务器上也可以快速验证:
curl -I https://myapp.example.com
返回 HTTP/2 200 就是正常响应。
常见问题
Q: 配置后访问502 Bad Gateway怎么办?
A: 检查 proxy_pass 后面的内网地址是否正确。确保VPS能访问那个地址:
curl http://192.168.1.100:8080
不通的话,检查内网服务的IP、端口和防火墙规则。
Q: 多个服务怎么配置?
A: 每个服务一个配置文件,用不同的域名或子域名。比如 app.example.com 指向8080端口,files.example.com 指向9000端口。各自独立配置即可。
Q: 需要WebSocket支持吗?
A: 如果你的服务用了WebSocket(比如实时聊天),在location块里加两行:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Q: 想限制某个IP段访问怎么办?
A: 在server块里加:
allow 192.168.1.0/24;
deny all;
只允许这个网段访问。
Nginx反向代理是运维的基本功。学会这一招,内网的任何服务都能安全地暴露在公网上。
你的内网有什么服务想暴露出来?评论区聊聊。