Replacing sniproxy with Nginx for unlocking OTT content

Most current solutions for OTT content unlock use sniproxy. Unfortunately, sniproxy has become another open-source project abandoned by the original author. The maintainer is no longer active, and the last commit was merged over 1 year ago despite multiple pull requests. The future of sniproxy does not look promising.

One of the most annoying issues of sniproxy is that sometimes the software completely hangs for no obvious reason, and a restart is required for recovery. I haven't tested it yet, but this fork probably has fixed the issue - that is, if you insist on using sniproxy. Switching to Nginx might be a better solution, as it is actively maintained, and is well-known for its high performance.

The latest release of Nginx provides most of the features of sniproxy, except the fine control over resolver behavior. The resolver of Nginx now supports IPv4-only mode and IPv6-only mode. By comparison, sniproxy has ipv4_only, ipv4_first, ipv6_only, and ipv6_first modes.

Nginx Installation

You will need to compile your own version of Nginx with stream_ssl and stream_ssl_preread modules for proxying HTTPS traffic by SNI. Here is a step-by-step tutorial.

sudo apt install -y nginx build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev
tar -xf nginx-1.24.0.tar.gz
cd nginx-1.24.0/
./configure --prefix=/var/www/html --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --with-pcre  --lock-path=/var/lock/nginx.lock --pid-path=/var/run/ --with-http_ssl_module --with-http_image_filter_module=dynamic --modules-path=/etc/nginx/modules --with-http_v2_module --with-stream=dynamic --with-http_addition_module --with-http_mp4_module --with-stream_ssl_preread_module --with-stream_ssl_module
sudo make install
sudo apt-mark hold nginx* libnginx*

Example Configuration of /etc/nginx/nginx.conf

user www-data;
worker_processes auto;
pid /run/;
load_module /etc/nginx/modules/;

error_log  /var/log/nginx/error.log;

events {
    worker_connections 2048;

http {
    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    gzip on;
    include /etc/nginx/conf.d/*.conf;

stream {
    map $ssl_preread_server_name $ssl_target {
        ~^ipv4-(?<suffix>.*)    ipv6-${suffix}:443;
        ~^(.*|)netflix\.com    $ssl_preread_server_name:443;
        ~^(.*|)fast\.com    $ssl_preread_server_name:443;
        ~^(.*|)netflix\.com    $ssl_preread_server_name:443;
        ~^(.*|)netflix\.net    $ssl_preread_server_name:443;
        ~^(.*|)nflxext\.com    $ssl_preread_server_name:443;
        ~^(.*|)nflximg\.com    $ssl_preread_server_name:443;
        ~^(.*|)nflximg\.net    $ssl_preread_server_name:443;
        ~^(.*|)nflxso\.net    $ssl_preread_server_name:443;
        ~^(.*|)nflxvideo\.net    $ssl_preread_server_name:443;

    server {
        listen 443;
        resolver ipv6=on ipv4=off;
        resolver_timeout 1s;
        proxy_pass $ssl_target;
        ssl_preread on;

Nginx Tuning

Add the option LimitNOFILE=65536 under [Service] section of /lib/systemd/system/nginx.service.

Save the file and reload: systemctl daemon-reload && systemctl restart nginx.

Increase maximum open file descriptors: ulimit -n 65536

You can also tune kernel parameters in /etc/sysctl.conf, especially the ones related to TCP connection. For example:

fs.file-max = 65536
net.core.wmem_default = 37500000
net.core.wmem_max = 75000000
net.core.rmem_default = 37500000
net.core.rmem_max = 75000000
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_window_scaling = 2
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 4096

Note: wmem can be calculated by bandwidth-delay product.

IPv6-only Mode for Nginx

It has been natively supported by the latest version of Nginx.

Was this article helpful?

mood_bad Dislike 0
mood Like 10
visibility Views: 5130