记一次Nginx反代突破区域限制

发布于 / 代码·杂谈 / 3 条评论

前言:最近痴迷于追剧,发现一个不错的影视站主打1080/无广/可采, 遗憾的一点是所有资源引用只能海外ip,国内通过扶墙可正常使用,顺便讲讲Nginx反代突破采集站流媒体区域限制,达到国内播放目的。

提示:按本文操作后所有流量经自己服务器,如果你手头正有不限流G口机不妨试试,如何本地搭建+采集过程这里不多说了。


操作需要:

国外小鸡+Nginx环境

本地:127.0.0.1

举例采集地址:https://example.com        简称example采集

举例播放地址:https://m3u8.example.com/xm3u8/f11e97d0da21.m3u8

 

一、尝试反代m3u8文件的域名

因为example采集站所有资源限制海外ip访问,国外机子反代m3u8文件的域名是个不错的法子。

代码如下:

    location ~* \.(m3u8|ts|aac)$ {
    proxy_cache off;                                   # 禁用代理缓存
    gzip off;
    expires -1;                                        # 禁用页面缓存
    proxy_pass https://m3u8.example.com;                    # 反代目标 URL
    sub_filter 'https://127.0.0.1/' 'https://$host/'; # 替换 m3u8 文件里的资源链接
    sub_filter_last_modified off;                      # 删除原始响应里的浏览器缓存值
    sub_filter_once off;                               # 替换所有匹配内容
    sub_filter_types *;                                # 匹配任何 MIME 类型
}

 

配置好反代,本地访问127.0.0.1/xm3u8/f11e97d0da21.m3u8返回502 Bad Gateway,错误信息显示 SSL_do_handshake() failed

返回502 Bad Gateway 是由于网站启用了 SNI , 宝塔Nginx反代默认没有加入 SNI proxy_ssl_server_name on; ,Nginx 无法成功 handshake 上游的 SSL , 导致 502 Bad Gateway. 补充代码加上proxy_ssl_server_name on; 后正常返回m3u8文件

补充后的代码如下:

    location ~* \.(m3u8|ts|aac)$ {
    proxy_cache off;                                   # 禁用代理缓存
    gzip off;
    expires -1;                                        # 禁用页面缓存
    proxy_pass https://m3u8.example.com;                    # 反代目标 URL
    proxy_ssl_server_name on;
    sub_filter 'https://127.0.0.1/' 'https://$host/'; # 替换 m3u8 文件里的资源链接
    sub_filter_last_modified off;                      # 删除原始响应里的浏览器缓存值
    sub_filter_once off;                               # 替换所有匹配内容
    sub_filter_types *;                                # 匹配任何 MIME 类型
}

尝试播放m3u8文件,播放器可正常加载m3u8文件,但所有ts文件403

打开m3u8文件,发现sub_filter没起作用,nginx反代替换关键字前并不会自动解压缩,所以无法执行替换内容

因为m3u8.example.com域名使用的Brotli压缩,检测Accept-Encoding,如果客户端未设置Content-Encoding或设置为支持br压缩,则强制返回Content-Encoding:br。如果强制指定了只支持gzip,defalte,则Content-Encoding:gizp.defalter。在请求中增加Accept-Encoding "gzip,deflate";等内容

再次补充后的代码如下

    location ~* \.(m3u8|ts|aac)$ {
    proxy_cache off;                                   # 禁用代理缓存
    proxy_set_header Sec-Fetch-Mode "navigate";
    proxy_set_header Sec-Fetch-Site "cross-site";
    proxy_set_header Cache-Control "max-age=0";
    proxy_set_header Accept-Encoding "gzip,deflate";
    gunzip on;
    gzip_disable ".";
    expires -1;                                        # 禁用页面缓存
    proxy_pass https://m3u8.example.com;                    # 反代目标 URL
    proxy_ssl_server_name on;
    sub_filter 'https://127.0.0.1/' 'https://$host/'; # 替换 m3u8 文件里的资源链接
    sub_filter_last_modified off;                      # 删除原始响应里的浏览器缓存值
    sub_filter_once off;                               # 替换所有匹配内容
    sub_filter_types *;                                # 匹配任何 MIME 类型
}

到此步常规站基本能正常使用了,最骚点来了,example采集这个站很多剧在更新,除了m3u8文件地址固定,文件内ts文件地址随机变化,如何解决这种情况!

二、来了来了,它来了,反代任意站

顾名思义,它、嗯、对、是的

举例1. 访问 xxx.com/fd/https://www.baidu.com  进入到百度搜索

举例2. 访问xxx.com/fd/https://cdn1.xxx.com/xvod/00db111e97d0da21/eee_0.ts 返回ts文件

举例3. 二哥说了凡事讲三点,举一反三,

代码如下



server {
        listen        80;
	listen 443 ssl http2;
        server_name  xxx.com; #改成自己的域名
        root   "/www/wwwroot/xxx.com"; #改自己的服务器目录
         #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    ssl_certificate    /www/server/panel/vhost/cert/xxx.com/fullchain.pem;
    ssl_certificate_key    /www/server/panel/vhost/cert/xxx.com/privkey.pem;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=31536000";
    error_page 497  https://$host$request_uri;
                set $custom_PATH /iss;
        set $custom_host "https://www.baidu.com";
        set $custom_host3 "/";
        set $custom_host5 "/";
        if ($request_uri ~* ^\/(.+)\/((http|https)://(www.)?([\w-]+(\.)?)+)(.*?)$) {
            set $custom_host $2;

            set $custom_host3 $7;
        }

        if ($custom_host3 = ""){
            set $custom_host3 "/";
        }
        if ($custom_host3 = " "){
            set $custom_host3 "/";
        }
        if ($request_uri ~* ^\/(.+)\/((http|https)://(www.)?([\w-]+(\.)?)+)(.+)\?(.+)$) {
            set $custom_host3 $7;
        }
        if ($request_uri ~* ^\/(.+)\/((http|https)://)((www.)?(\w+(\.)?)+)$) {
            return 301 $custom_PATH/$custom_host/;
        }
        set $custom_host2 "www.baidu.com";


        if ($custom_host ~* ^((http|https)://)((www.)?([\w-]+(\.)?)+)$) {
            set $custom_host2 $3;
            set $custom_host5 $1;
        }
        set $referer $custom_host;
        if ($http_referer ~* ^((http|https)://)(.*?)\/(.+)\/((http|https)://)(.*?)$) {
            set $referer $5$7;

        }
        set $current "http://";
        if ($scheme = https) {
            set $current "https://";
        }
        proxy_hide_header content-security-policy;



        location /fd/ {
            # proxy_connect_timeout 100s;
            # add_header Content-Security-Policy "default-src 'self' https://$host http://$host 'unsafe-inline' 'unsafe-eval' blob: data: ;";
            # proxy_set_header x-forwarded-for $remote_addr;
            # proxy_set_header X-Real-IP $remote_addr;
            # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            set $ishttp "http";
            if ($custom_host5 = https://) {
                set $ishttp "https";
            }
            proxy_ssl_server_name on;
            proxy_set_header X-Forwarded-Proto $ishttp;
            proxy_set_header Host $custom_host2;
            proxy_cache_key    $host$uri$is_args$args;
            proxy_headers_hash_max_size 512;
            proxy_pass_header Server;
            proxy_headers_hash_bucket_size 128;
            proxy_buffer_size  64k;
            proxy_buffers   32 64k;
            proxy_busy_buffers_size 128k;
            proxy_set_header Cookie $http_cookie;
            proxy_cache_methods GET;
            proxy_cache_methods POST;
            proxy_cache_methods HEAD;
            proxy_redirect $upstream_http_location "$current$host$custom_PATH/$upstream_http_location";
            proxy_set_header  Referer           $referer;
            proxy_set_header  User-Agent        $http_user_agent;
            # 防止谷歌返回压缩的内容,因为压缩的内容无法替换字符串
            proxy_set_header Accept-Encoding "";
            proxy_connect_timeout      15000;
            proxy_send_timeout         15000;
            proxy_read_timeout         15000;
            proxy_cache_valid 200 304 301 1s;
            add_header MJJCDN-Cache "$upstream_cache_status";
            # proxy_temp_file_write_size 512000k;
            resolver 1.1.1.1; #改为自己想要的DNS
            proxy_set_header Accept-Encoding "";
            sub_filter_types text/plain  text/javascript text/xml text/css application/x-javascript application/xml;

            sub_filter_once off;
            proxy_temp_file_write_size 512000k;
            sub_filter "<head" '<base href="$current$host$custom_PATH/$custom_host/" />\n<head';
            sub_filter '\'https://' '\'$current$host$custom_PATH/https://';
            sub_filter '\'http://' '\'$current$host$custom_PATH/https://';
            sub_filter '\"https://' '\"$current$host$custom_PATH/https://';
            sub_filter '\"http://' '\"$current$host$custom_PATH/https://';
            sub_filter "\"//" '"$current$host$custom_PATH/https://';
            sub_filter '"/' '"$current$host$custom_PATH/$custom_host/';
            sub_filter "'//" "'$current$host$custom_PATH/https://";
            sub_filter "'/" "'$current$host$custom_PATH/$custom_host/";
            sub_filter '"/search' '"search';
            sub_filter "(http" "($current$host$custom_PATH/http";

            sub_filter '"/images' '"images';
            sub_tifilter ', /images' ', images';
            sub_filter 'integrity' ', kkkk';
            sub_filter '../' '$current$host$custom_PATH/$custom_host/../';
            sub_filter "'http://$custom_host2" "'$current$host$custom_PATH/$custom_host";
            sub_filter "'https://$custom_host2" "'$current$host$custom_PATH/$custom_host";
            sub_filter "\"http://$custom_host2" "\"$current$host$custom_PATH/$custom_host";
            sub_filter "\"https://$custom_host2" "\"$current$host$custom_PATH/$custom_host";
            if ($request_uri ~* ^\/(.+)\/((http|https)://(www.)?([\w-]+(\.)?)+)(.*?)$) {
                proxy_pass $custom_host$7$is_args$query_string;
            }


            # # set $request_uri "qqqq";
            # add_header Content-Type "text/plain;charset=utf-8";
            # return 200 "Your IP Address:$referer</br>$http_referer";
        }

        location / {
            add_header Content-Type "text/plain;charset=utf-8";
            return 200 "这是个正经网站";
        }
}

所以怎么应用到m3u8文件里呢?这里需更改以下sub_filter替换内容http' 'https://xxx.com/fd/http,详见代码

再再次补充后的代码如下:

    location ~* \.(m3u8|ts|aac)$ {
    proxy_cache off;                                   # 禁用代理缓存
    proxy_set_header Sec-Fetch-Mode "navigate";
    proxy_set_header Sec-Fetch-Site "cross-site";
    proxy_set_header Cache-Control "max-age=0";
    proxy_set_header Accept-Encoding "gzip,deflate";
    gunzip on;
    gzip_disable ".";
    expires -1;                                        # 禁用页面缓存
    proxy_pass https://m3u8.example.com;                    # 反代目标 URL
    proxy_ssl_server_name on;
    sub_filter 'http' 'https://xxx.com/fd/http';       # 替换 m3u8 文件里的资源链接
    sub_filter_last_modified off;                      # 删除原始响应里的浏览器缓存值
    sub_filter_once off;                               # 替换所有匹配内容
    sub_filter_types *;                                # 匹配任何 MIME 类型
}

测试国内正常播放,舒服的一批!

完!感谢浏览此文章,感谢提供参考的博主!
参考

https://www.hostarr.com/reverse-proxy-for-hls-stream/

https://blog.samsam123.name.my/articles/bt-nginx-502-bad-gateway-ssl-upstream-handshake-fail

https://www.yeeach.com/post/1541

https://www.yeeach.com/post/1523

https://hostloc.com/thread-1011338-1-1.html

转载原创文章请注明,转载自: 白纸博客 » 记一次Nginx反代突破区域限制
  1. cdn密码是多少?

    1. @碉堡 抱歉最近较忙,回复迟了,请参考https://blog.tanglu.me/cdnfly/
  2. 老板有好用的国外g口服务器推荐吗