使用 Nginx 建立 SNI Proxy

前言

最近一直在想 SNI Proxy 這種東西,因為想要繞過各種影音平台鎖區的限制,但又不想太複雜的處理方式。而剛好看到 Nginx 其實本身也可以做 SNI Proxy 的工作,因此這篇文章就將設定方法簡易的記錄下來。

操作方式

我們會需要 Nginx 的 stream 模組,所以你的機器上也應該先裝上 Nginx。

sudo apt-get install -y nginx nginx-extras

接著開始編輯 /etc/nginx/nginx.conf 檔案,通常我會調整一下 events 區塊來調整性能。

events {
        worker_connections 2048;
        multi_accept on;
        use epoll;
}

拉到文件的末端,如果你不想特別指定允許哪些網域,你可以這樣寫:

stream {
    map $ssl_preread_server_name $ssl_target {
        default $ssl_preread_server_name:443;
    }
    server {
        listen [::]:443;
        resolver 8.8.8.8 ipv6=on ipv4=on;
        resolver_timeout 1s;
        proxy_pass $ssl_target;
        ssl_preread on;
    }
}

或者,如果你想詳細指定(例如 Netflix),那你可以改成這樣的寫法:

stream {
    map $ssl_preread_server_name $ssl_target {
        ~^(.*|)netflix\.com$ $ssl_preread_server_name;
        ~^(.*|)netflix\.net$ $ssl_preread_server_name;
        ~^(.*|)nflximg\.com$ $ssl_preread_server_name;
        ~^(.*|)nflximg\.net$ $ssl_preread_server_name;
        ~^(.*|)nflxvideo\.net$ $ssl_preread_server_name;
        ~^(.*|)nflxext\.com$ $ssl_preread_server_name;
        ~^(.*|)nflxso\.net$ $ssl_preread_server_name;
        ~^(.*|)fast\.com$ $ssl_preread_server_name;
    }
    server {
        listen [::]:443;
        resolver 8.8.8.8 ipv6=on ipv4=on;
        resolver_timeout 1s;
        proxy_pass $ssl_target;
        ssl_preread on;
    }
}

接者,可以使用以下方式驗證有沒有錯誤。

sudo nginx -t

沒有錯誤的話,可以使用這個命令重啟一下 Nginx。

sudo systemctl restart nginx

接著,你只需要用 DNS 的 rewrite 功能,將這些網域都指向這台主機,就可以透過這台主機的 SNI Proxy 代理囉。