将常用的代理隐藏在nginx背后,使其看起来像是正常的HTTPS流量。

需求

部署MTProxy和V2Ray-plugin,要求和现有HTTPS网站共存

  • 共用https端口
  • 使用Web浏览器打开时为正常的网页,而使用对应的代理客户端功能正常

Nginx

编译:

  • nginx 1.13 以上的版本
  • openssl 1.1.1 以上的版本

nginx主要开启的关键模块:

  • http_v2_module
  • stream
  • stream_ssl_module
  • stream_ssl_preread_module

打印信息

user@ubuntu:~# nginx -V
nginx version: nginx/1.17.6
built by gcc 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) 
built with OpenSSL 1.1.1d  10 Sep 2019
TLS SNI support enabled
configure arguments: --with-cc-opt='-O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security
-D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro' --conf-path=/etc/nginx/nginx.conf --with-debug
--with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module
--with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module
--with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module
--with-http_xslt_module --with-stream --with-stream_ssl_module --with-threads --without-mail_pop3_module
--without-mail_imap_module --without-mail_smtp_module --with-stream_ssl_preread_module --with-openssl=../openssl-1.1.1d

MTProxy

用python3写第三方的服务端mtprotoproxy可以满足需求,能作为一个stream服务器隐藏在nginx背后。

官方的MTPorxy和第三方mtg暂时未能满足需求。因为MTP需要知道客户端的ip和端口,如果没有实现HAProxy的proxy_protocol,则无法获IP和端口。。。proxy_protocol就是传达端口信息的。

nginx反代MTProxy和v2ray安装并测试

1
2
git clone https://github.com/alexbers/mtprotoproxy
cd mtprotoproxy

修改config.py内容如下

1
2
3
4
5
6
7
8
PORT = 3000
USERS = { "tg": "xxxxxx" }
MODES = { "classic": False, "secure": False, "tls": True }
TLS_DOMAIN = "www.cloudflare.com"
PROXY_PROTOCOL = False
REPLAY_CHECK_LEN = 655350
TO_CLT_BUFSIZE = 262144
TO_TG_BUFSIZE = 262144

参数解读:

head -c 16 /dev/urandom | xxd -psseveral TLS records
tg://t.me/xxxxxxx
python3 ./mtprotoproxy.py

确认TG可以通过该代理联机后,再进行下一步。此时可以通过wireshark抓包看到与代理连接是TLS1.3方式,且host为cloudflare,是真正的HTTPS/SSL流量。

PROXY_PROTOCOL = True

修改nginx.conf,在最外层加入

stream {
    map $ssl_preread_server_name $name {
        www.cloudflare.com MT; # 映射域名到合适的后端
        default LocalBackEnd;
    }
    upstream MT {
        server 127.0.0.1:3000; # 这里是mtproxy监听端口
    }
    upstream LocalBackEnd {
        server localhost:1024; # 临时的服务器
    }
    upstream RealBackEnd {
        server localhost:1025; # 真正的服务器,见下文用1025端口
    }
    server {
        listen 443 reuseport; # 对外的443端口
        proxy_pass $name;
        proxy_protocol on; # 关键的一步,支持HAProxy的proxy_protocol
        ssl_preread on; # 预读SNI主机名
    }
    server {
        listen localhost:1024 reuseport proxy_protocol;
        proxy_pass RealBackEnd;
    }
}
nginx -t

这样你的代理就真正隐藏在443端口背后了。而且使用curl测试这个域名也能正常伪装成cloudflare。

1
2
# xx.xx.xx.xx为运行nginx的IP地址,下面将解析cloudflare到特定的地址
curl -v -s https://www.cloudflare.com --resolve 'www.cloudflare.com:443:xx.xx.xx.xx'

因为是Python写的,故有优化的余地,可以提高性能,详见官方WIKI

V2Ray-plugin

关键点:

/

运行带插件的libev服务端,监听是HTTP端口,配置文件可参考config.json样例

1
ss-server -c config.json -p 3001 --plugin v2ray-plugin --plugin-opts "server"

修改nginx.conf,在http层加入一个服务器,监听1025端口,与上文的RealBackEnd对应。

server {
    listen                      localhost:1025 ssl http2 reuseport;
    server_name                 abc.example.com;
    ssl_certificate             "/path/to/fullchain.crt";
    ssl_certificate_key         "/path/to/domain.key";
    ssl_ciphers                 HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;
    ssl_protocols               TLSv1.1 TLSv1.2 TLSv1.3;

    location / {
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:3001;
    }
}

其它

流加密/var/log/nginx/access.logssl_preread

自从用上了TLS,我们又可以愉快地刷小黄图了!!

阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。