相关文章推荐
低调的钱包  ·  用了这个 IDE ...·  1 周前    · 
近视的春卷  ·  SQL ...·  1 年前    · 
通过 Nginx 的正向代理审计监控内网用户的外网访问记录

通过 Nginx 的正向代理审计监控内网用户的外网访问记录

正向代理

一个位于客户端和目标服务器之间的 Nginx 正向代理服务器, 客户端向 Nginx 正向代理发送一个请求并指定目标服务器,然后代理向目标服务器转交请求并将获得的内容返回给客户端及本地代理服务器缓存

适用场景:

  • 用于解决内网服务器通过代理服务器访问外网
  • 监控内网终端的外网访问记录
  • 代理端缓存外网访问的响应结构,加速外网访问

正向代理又细分为 http、https 流量的 透明代理 非透明代理

  • 透明代理指利用内网 dns 将待访问的域名解析到 Nginx 的透明代理, 终端用户利用内网 dns 后不需要进行任何代理服务器设置
  • 非透明代理指终端用户需要设置代理服务器信息

如何代理加密的 HTTPS 流量是正向代理需要解决的主要问题, 当前主要的两种方式:

  • 七层解决:HTTP CONNECT 透传(隧道)模式, 即不解密不感知上层流量
  • 四层解决: NGINX Stream

http 流量

1、透明代理, 利用本机 hosts 或 DNS 解析待访问的目标域名到代理服务器 Ip

# Nginx 透明正向代理 http 流量主要配置
server {
    resolver 114.114.114.114;
    listen 80;
    access_log   /var/log/nginx/access.80.log  main;
    location / {
        proxy_pass http://$http_host$request_uri;
        proxy_set_header HOST $http_host;
        proxy_buffers 256 4k;
        proxy_max_temp_file_size 0k;
        proxy_connect_timeout 30;
        proxy_send_timeout 60;
        proxy_read_timeout 60;
        proxy_next_upstream error timeout invalid_header http_502;

2、非透明代理, 需在客户终端设置代理服务器信息

# Nginx 非透明正向代理 http 流量主要配置
server {
    resolver 114.114.114.114;
    listen 1080;
    location / {
        proxy_pass http://$http_host$request_uri;
        proxy_set_header HOST $http_host;
        proxy_buffers 256 4k;
        proxy_max_temp_file_size 0k;
        proxy_connect_timeout 30;
        proxy_send_timeout 60;
        proxy_read_timeout 60;
        proxy_next_upstream error timeout invalid_header http_502;

https 流量

1、HTTP CONNECT 隧道 方式(非透明代理)

# 需要 ngx_http_proxy_connect_module 模块支持; 客户端需要指定 https 代理服务器
yum -y install gcc-c++ zlib-devel openssl-devel.x86_64 pcre-devel gd-devel patch
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar xf nginx-1.20.1.tar.gz && cd nginx-1.20.1
# 给 nginx 打补丁, 需要根据不同的 nginx 版本 选择对应的补丁
cd /root/src/ && git clone https://github.com/chobits/ngx_http_proxy_connect_module
cd nginx-1.20.1
patch -p1 < /root/src/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_1018.patch
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' \
--add-module=/root/src/ngx_http_proxy_connect_module
make && make install
mkdir -p /var/cache/nginx/client_temp && useradd -M -r -s /sbin/nologin nginx
# nginx server 配置
server {
    listen  8443;
    resolver  114.114.114.114;
    access_log  /var/log/nginx/access.8443.log  main;
    proxy_connect;
    proxy_connect_allow            443;
    proxy_connect_connect_timeout  10s;
    proxy_connect_read_timeout     10s;
    proxy_connect_send_timeout     10s;
    location / {
        proxy_pass http://$host;
        proxy_set_header Host $host;
# linux 命令行设置 http 代理服务器
export http_proxy="192.168.31.68:1080"
export http_proxy="192.168.31.68:8443"
# 通过 curl 测试代理服务器是否正常
curl --proxy 192.168.31.68:8443 https://www.baidu.com -svo /dev/null
curl http://192.168.31.17:1083 -svo /dev/null

2、NGINX Stream 方式(HTTPS 流量的透明正向代理)

  • 需要 --with-stream,--with-stream_ssl_preread_module、--with-stream_ssl_module 模块的支持;
  • 利用 ngx_stream_ssl_preread_module 模块, 在不解密的情况下拿到 HTTPS 流量待访问目标域名(利用 TLS/SSL 握手的第一个 Client Hello 报文中的扩展地址 SNI (Server Name Indication)来获取);
  • 如果客户端没有携带 SNI 字段,会造成代理服务器无法获取待访问目标服务域名,导致访问不成功; 因此要求所有客户端都需要在 TLS/SSL 握手中带上 SNI 字段!!
  • 将待访问的所有域名利用内网 dns 或 hosts 解析到代理服务器; 客户端侧则不需要指定代理服务器信息
stream {
    resolver 114.114.114.114;
    log_format main '$remote_addr - [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received $session_time "$upstream_addr" '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time" '
                 '$remote_addr $remote_port $server_addr $server_port';
    access_log /var/log/nginx/access.443.log main;
    server {
        listen 443;
        ssl_preread on;
        proxy_connect_timeout 5s;
        proxy_pass $ssl_preread_server_name:$server_port;