Nginx Stream代理绕过网络隔离策略
- Nginx Stream介绍
- 配置示例
- 环境搭建
-
- 1. 安装最新版Nginx(含Stream模块)
- 2. 启用Stream模块配置文件
- 3. 配置Stream代理HTTP服务
- 4. 添加简易HTTP测试服务(可选)
- 5. 重启nginx配置使其生效
- Nginx Stream代理绕过网络隔离策略复现
- 修复测试
Nginx Stream介绍
Q:Nginx Stream是什么?
stream 模块是从 nginx 1.9.0 版本开始引入的。nginx 的 stream 模块一般以 stream { } 的形式存在于 nginx 配置文件中。
简单理解为,常用的nginx只是做应用层的代理转发,但是nginx stream模块使其拥有四层转发能力,能直接转发udp、tcp数据流。
配置示例
stream块
配置与 http块
并列,在nginx.conf
中配置,可以用include方式将我们配置实例单独配置,方便管理。
# /etc/nginx/nginx.conf中配置
stream {
include /etc/nginx/stream.d/*.conf;
}
# /etc/nginx/stream.d/中的配置文件dns.conf
upstream mydns {
hash $remote_addr consistent; #配置ip_hash方式,默认轮询
server 192.168.10.10:53; #这里配置成要访问的地址和端口
server 192.168.10.20:53;
server 192.168.10.30:53;
}
server {
listen 53 udp reuseport; #需要监听的端口,因为udp非可靠传输协议,使用reuseport保证请求分配到统一会话中
proxy_connect_timeout 5s;
proxy_timeout 20s;
proxy_pass mydns;
}
环境搭建
1. 安装最新版Nginx(含Stream模块)
# 更新软件源
sudo apt update
# 安装Nginx(默认包含Stream模块)
sudo apt install nginx -y
# 验证安装成功
nginx -v
2. 启用Stream模块配置文件
- 创建Stream模块专用配置目录
sudo mkdir /etc/nginx/stream.d
- 在主配置文件
/etc/nginx/nginx.conf
中启用Stream模块stream { include /etc/nginx/stream.d/*.conf; }
- 检查配置语法
sudo nginx -t
3. 配置Stream代理HTTP服务
(实际上代理mysql、redis服务较多,http服务直接用http七层代理即可,不必走四层代理)
假设有两个本地HTTP服务
- Web服务1:运行在127.0.0.1:8000
- Web服务2:运行在127.0.0.1:9000
分别创建两个http代理配置,代理效果如下:
# /etc/nginx/stream.d/web1.conf配置
# 创建web服务1的Stream代理配置
upstream backend_web1 {
server 127.0.0.1:8000;
}
server {
listen 8081;
proxy_pass backend_web1;
proxy_connect_timeout 5s;
proxy_timeout 30s;
}
# /etc/nginx/stream.d/web2.conf配置
# 创建web服务2的Stream代理配置(使用不同端口)
upstream backend_web2 {
server 127.0.0.1:9000;
}
server {
listen 8082;
proxy_pass backend_web2;
proxy_connect_timeout 5s;
proxy_timeout 30s;
}
4. 添加简易HTTP测试服务(可选)
- 安装Python3用于创建临时Web服务
sudo apt install python3 -y
- 启动第一个测试服务(端口8000)
python3 -m http.server 8000 --directory /tmp/ >/dev/null 2>&1 &
- 启动第二个测试服务(端口9000)
python3 -m http.server 9000 --directory /etc/nginx/ >/dev/null 2>&1 &
- 验证服务运行
curl http://127.0.0.1:8000 && curl http://127.0.0.1:9000
5. 重启nginx配置使其生效
sudo systemctl restart nginx
Nginx Stream代理绕过网络隔离策略复现
经过上述配置后,访问8081和8082端口效果如下,直接可以访问到nginx stream代理后的8000和9000端口的实际服务
同理,如果代理的是mysql或redis服务,即就直接访问到实际真实服务。
在内网,这种代理是可以接受的,但是如果代理被开在外网,攻击面就暴露出去了。
修复测试
在我的stream配置中加上了allow
和deny
控制访问来源为127.0.0.1
后,在办公网就无法再访问到nginx stream代理后的http服务了
# 修改web服务1的Stream代理配置
upstream backend_web1 {
server 127.0.0.1:8000;
}
server {
listen 8081;
proxy_pass backend_web1;
proxy_connect_timeout 5s;
proxy_timeout 30s;
allow 127.0.0.1;
deny all; # 拒绝其他IP
}