NGINX Reverse Proxy Print

  • nginx, nginx reverse proxy, xtreamui reverse, xtreamui proxy, xtreamcode reverse, xtreamcode proxy
  • 101

Hi Guys,

I've seen this subject come up a lot recently so hopefully this can help someone out.

I have been playing around trying to get an nginx reverse proxy server setup and after some initial frustrations I have got there in the end.

The idea is to setup a server that sits in front of your main server and load balance servers. Clients will contact the reverse proxy server which in turn communicates with your main and then passes the response back to the client so that your main server IP or DNS is not exposed to the client, only the reverse proxy server is.

See the below data flow diagram with obfuscated / mocked up DNS addresses if still unclear.

 

For testing this I used four dedicated servers.

Server 1: Xtream UI MAIN / Admin
Server 2: Xtream UI LB1 Server
Server 3: Xtream UI LB2 Server
Server 4: Nginx Reverse Proxy Server

I created a single user within the admin panel and added a handful of streams onto LB1 and a handful of VOD content onto LB2.

Finally I edited an APK file to point the DNS address within the APK file to the NGINX Reverse Proxy server and the HTTP broadcast port.

I won't include how to install and setup Xtream UI in this guide so will assume you already know how to do that and you now have your Xtream UI server and panel up and running and you are now ready to setup the reserve proxy.

So firstly we must SSH into the server that we are going to be using as the reverse proxy server and setup nginx.

PHP:
 
apt-get update; apt-get install nginx;


Next we unlink the default enabled site for nginx that is setup following the installation.

PHP:
 
unlink /etc/nginx/sites-enabled/default


Now we want to create our config file for the reserve proxy service we want to run:

PHP:
 
nano /etc/nginx/sites-available/reverse-proxy.conf

 

PHP:
 
server {
listen ####; replace hashes with the http broadcast port your service is using (such as 8080 or 25461).

location / {
      proxy_pass http://thednsoripaddressofyourmainserver;
      proxy_redirect off;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Original-Scheme $scheme;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass_request_headers on;
      proxy_max_temp_file_size 0;
      client_max_body_size 10m;
      client_body_buffer_size 128k;
      client_body_timeout 12;
      keepalive_timeout 15;
      send_timeout 10;
      proxy_connect_timeout 90;
      proxy_send_timeout 90;
      proxy_read_timeout 90;
      proxy_buffer_size 4k;
      proxy_buffers 4 32k;
      proxy_busy_buffers_size 64k;
      proxy_temp_file_write_size 64k;
}
}
 


Save the file and exit the editor and then copy the file from sites-available to sites-enabled:

PHP:
 
ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf


Test if the config file is okay or if you have any errors run:

PHP:
 
service nginx configtest


If the config file is okay then restart nginx

PHP:
 
service nginx restart


To check on the status of the reverse proxy you can run:

PHP:
 
systemctl status nginx


Next we want to update our existing nginx.conf file for Xtream UI on our Main server so we can close our SSH session on the Reverse Proxy server and SSH into our MAIN Server. We do not need to change much to the existing nginx config file for Xtream UI other than to add an entry so that we listen on port 80 for the nginx comms and that we want to set the real ip address from the proxy server.

PHP:
 
nano /home/xtreamcodes/iptv_xtream_codes/nginx/conf/nginx.conf

 

PHP:
 
user  xtreamcodes;
worker_processes  auto;

worker_rlimit_nofile 300000;
events {
    worker_connections  16000;
    use epoll;
                accept_mutex on;
                multi_accept on;
}
thread_pool pool_xtream threads=32 max_queue=0;
http {

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

    sendfile           on;
    tcp_nopush         on;
    tcp_nodelay        on;
                reset_timedout_connection on;
    gzip off;
    fastcgi_read_timeout 200;
                access_log off;
                keepalive_timeout 10;
                include balance.conf;
                send_timeout 20m;     
                sendfile_max_chunk 512k;
                lingering_close off;
                aio threads=pool_xtream;
                client_body_timeout 13s;
                client_header_timeout 13s;
                client_max_body_size 3m;
                set_real_ip_from ##.##.#.###; This is the IP address of the proxy server that will communicate with the clients.

                limit_req_zone $binary_remote_addr zone=one:30m rate=20r/s;
    server {
        listen 8080;
        listen ####; Adjsut these ports as required based upon the ports you're using for panel and broadcasting.
                listen 25463 ssl;
                listen 80;
                ssl_certificate server.crt;ssl_certificate_key server.key; ssl_protocols SSLv3 TLSv1.1 TLSv1.2;
        index index.php index.html index.htm;
        root /home/xtreamcodes/iptv_xtream_codes/wwwdir/;
        server_tokens off;
        chunked_transfer_encoding off;

                                if ( $request_method !~ ^(GET|POST)$ ) {
                                                return 200;
                                }

        rewrite_log on;
        rewrite ^/live/(.*)/(.*)/(.*)\.(.*)$ /streaming/clients_live.php?username=$1&password=$2&stream=$3&extension=$4 break;
        rewrite ^/movie/(.*)/(.*)/(.*)$ /streaming/clients_movie.php?username=$1&password=$2&stream=$3&type=movie break;
                                rewrite ^/series/(.*)/(.*)/(.*)$ /streaming/clients_movie.php?username=$1&password=$2&stream=$3&type=series break;
        rewrite ^/(.*)/(.*)/(.*).ch$ /streaming/clients_live.php?username=$1&password=$2&stream=$3&extension=ts break;
        rewrite ^/(.*)\.ch$ /streaming/clients_live.php?extension=ts&stream=$1&qs=$query_string break;
        rewrite ^/ch(.*)\.m3u8$ /streaming/clients_live.php?extension=m3u8&stream=$1&qs=$query_string break;
                                rewrite ^/hls/(.*)/(.*)/(.*)/(.*)/(.*)$ /streaming/clients_live.php?extension=m3u8&username=$1&password=$2&stream=$3&type=hls&segment=$5&token=$4 break;
                                rewrite ^/hlsr/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)$ /streaming/clients_live.php?token=$1&username=$2&password=$3&segment=$6&stream=$4&key_seg=$5 break;
                                rewrite ^/timeshift/(.*)/(.*)/(.*)/(.*)/(.*)\.(.*)$ /streaming/timeshift.php?username=$1&password=$2&stream=$5&extension=$6&duration=$3&start=$4 break;
                                rewrite ^/timeshifts/(.*)/(.*)/(.*)/(.*)/(.*)\.(.*)$ /streaming/timeshift.php?username=$1&password=$2&stream=$4&extension=$6&duration=$3&start=$5 break;
                             
                                rewrite ^/(.*)/(.*)/(\d+)$ /streaming/clients_live.php?username=$1&password=$2&stream=$3&extension=ts break;
                                #add pvr support
                                rewrite ^/server/load.php$ /portal.php break;
                             
                                location /stalker_portal/c {
                                                alias /home/xtreamcodes/iptv_xtream_codes/wwwdir/c;
                                }
                             
                                #FFmpeg Report Progress
                                location = /progress.php {
                                    allow 127.0.0.1;
                                                deny all;
                                                fastcgi_pass php;
                                                include fastcgi_params;
                                                fastcgi_ignore_client_abort on;
                                                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                                                fastcgi_param SCRIPT_NAME $fastcgi_script_name;
                                }


        location ~ \.php$ {
                                                limit_req zone=one burst=8;
            try_files $uri =404;
                                                fastcgi_index index.php;
                                                fastcgi_pass php;
                                                include fastcgi_params;
                                                fastcgi_buffering on;
                                                fastcgi_buffers 96 32k;
                                                fastcgi_buffer_size 32k;
                                                fastcgi_max_temp_file_size 0;
                                                fastcgi_keep_conn on;
                                                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                                                fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }
    }
    server {
        listen 8081;
        listen 80;
        listen ####; As above this section relates to admin panel so if you're using 25500 then add this in here rather than 8081
                index index.php index.html index.htm;
        root /home/xtreamcodes/iptv_xtream_codes/admin/;

        location ~ \.php$ {
                                                limit_req zone=one burst=8;
            try_files $uri =404;
                                                fastcgi_index index.php;
                                                fastcgi_pass php;
                                                include fastcgi_params;
                                                fastcgi_buffering on;
                                                fastcgi_buffers 96 32k;
                                                fastcgi_buffer_size 32k;
                                                fastcgi_max_temp_file_size 0;
                                                fastcgi_keep_conn on;
                                                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                                                fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }
    }
}
 


Exit the editor and save the file and the test and reload the nginx config with the following:

Test

PHP:
 
/home/xtreamcodes/iptv_xtream_codes/nginx/sbin/nginx -t


Reload

PHP:
 
/home/xtreamcodes/iptv_xtream_codes/nginx/sbin/nginx -s reload


Next you need to edit the APK file and ensure the DNS address uses the DNS/IP address of the reverse proxy server and the broadcast port. E.g. http://MYNGINXPROXYDNS.NET:8080

Recompile your apk and log in and you should now be to play streams from your panel that are routed from the nginx reverse proxy.

HTTPS UPDATE

Hi All,

The above config works where there are no SSL certs on the proxy or XUI servers. I had been having trouble getting this to work on servers with SSL certs, but have now managed to get this working also, In order to get this working with SSL do the following:

1) Buy any old domain (e.g. bagofvegtables.net) from somewhere like noip and then assign your proxy servers IP address to the domain and update the A records and Nameservers.
2) Install SSL cert onto proxy server with

PHP:
 
sudo apt-get install certbot

and then

PHP:
 
sudo certbot certonly --standalone --preferred-challenges http -d bagofvegtables.net

3) Provide E-mail and agree to terms and allow letsencrypt to install certs.

Next on your proxy server run

PHP:
 
sudo apt-get install nginx


Once nginx is installed run

PHP:
 
sudo nano /etc/nginx/nginx.conf


Then enter the below as your config file contents (changing the domain name from the bagofvegtables.net one I just made up to the one you actually installed the cert for and changing the example ports listed for whatever ones you're XUI is currently configured to use and also replacing the dns to your main server from the example one entered below).

PHP:
 
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 1024;
    multi_accept on;
}

http {

    ##
    # Basic Settings
    ##
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;
    server_names_hash_bucket_size 128;
    server_name_in_redirect off;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    limit_req_zone $binary_remote_addr zone=one:10m rate=3r/m;
    ##
    # SSL Settings
    ##
    ssl_certificate /etc/letsencrypt/live/bagofvegtables.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/bagofvegtables.net/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/bagofvegtables.net/chain.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_dhparam dhparam.pem;
    ssl_prefer_server_ciphers on;
    ##
    # Logging Settings
    ##
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    ##
    # Gzip Settings
    ##
    gzip on;
    gzip_disable "msie6";
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_http_version 1.1;
    gzip_min_length 1100;
    gzip_buffers 16 8k;
    gzip_vary on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    ##
    # Virtual Host Configs
    ##
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

server {
listen 80; Example HTTP Ports
listen 8080;
listen 2095;
    return 301 https://$host$request_uri;
}

server {
listen 8443; Example HTTPS Ports
listen 443;
server_name bagofvegtables.net;

ssl_certificate           /etc/letsencrypt/live/bagofvegtables.net/fullchain.pem;
ssl_certificate_key       /etc/letsencrypt/live/bagofvegtables.net/privkey.pem;
ssl_trusted_certificate   /etc/letsencrypt/live/bagofvegtables.net/chain.pem;
    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

        proxy_pass          https://mymainserversdns.net:8443;
        proxy_read_timeout  90;
        proxy_redirect      off;
    proxy_http_version  1.1;
    proxy_cache_bypass  $http_upgrade;
    proxy_pass_request_headers on;
    proxy_max_temp_file_size 0;
    client_max_body_size 10m;
    client_body_buffer_size 128k;
    client_body_timeout 12;
    keepalive_timeout 15;
    send_timeout 10;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_buffer_size 4k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    }
  }

}
 


Upon saving the nginx.conf file you will then need to run the following command:

PHP:
 
wget --no-check-certificate "https://ssl-config.mozilla.org/ffdhe4096.txt" -O /etc/nginx/dhparam.pem


Then test if the config file is okay or if you have any errors run:

PHP:
 
service nginx configtest


If the config file is okay then restart nginx

PHP:
 
service nginx restart


Next you need to go to your MAIN server and update your firewall to allow connections from your proxy server IP address to your MAIN server and edit your nginx.conf to set_real_ip_from then add the ip address of your proxy server.


Was this answer helpful?

« Back