Monthly Archives: March 2015

Nginx Reverse Proxy on Asus Merlin

A reverse proxy is what you need when you want to make your home things with Web GUIs, like web cameras, media servers, web servers, etc available on the internet.

I´ve got a Asus RT-N66U router with Asuswrt-Merlin firmware installed which means I can install lots of additional stuff using OPTWARE with ipkg command, like nginx.

So, here´s the step by step guide.

1. I want nginx to listen to the standard http and https ports and since the administration web interface listens on the http port, I need to move the admin web interface to a different port.
In the Web-GUI: Administration / System – Change Authentication Method to https and enter port 8443, Save.

2. SSH to your asus router and login with the admin account.

3. Install nginx package

ipkg install nginx

4. Add startup scripts for allowing http/https in firewall and for starting nginx.

admin@RT-N66U-6370:/# vi /jffs/scripts/firewall-start

#!/bin/sh
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -j ACCEPT

admin@RT-N66U-6370:/# vi /jffs/scripts/services-start

#!/bin/sh
/opt/etc/init.d/S80nginx start

5. Chmod the scripts making them executable.

chmod 755 /jffs/scripts/*

6. Create self-signed SSL certificate with openssl (google it if unsure, lots of howtos out there). Copy to /opt/etc/nginx/ directory with name cert.pem and cert.key . (If you don´t need https skip this part and comment out the servers listening on 443 in nginx.conf below)

7. Edit nginx config file, below is an example config file.

admin@RT-N66U-6370:/# vi /opt/etc/nginx/nginx.conf

user nobody nobody ;
worker_processes  1;
 
events {
    worker_connections  1024;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    server_names_hash_bucket_size  64;
 
    sendfile        on;
    #tcp_nopush     on;
 
    #keepalive_timeout  0;
    keepalive_timeout  65;
 
    #gzip  on;
 
    #HTTP default website
    server {
        listen 80;
        server_name  localhost;
 
        location / {
            root   html;
            index  index.html index.htm;
        }
 
        error_page  404              /404.html;
 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
 
    #HTTP reverse proxies
    server {
        listen 80;
        server_name  www.mydomain.com;
        location / {
            # A backend apache server
            proxy_pass http://192.168.1.4;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
 
    server {
        listen 80;
        server_name  myplex.mydomain.com;
        if ($request_uri !~ "^/web/.*")
        {
          return 301 http://$host/web/index.html;
        }
        location / {
            # Plex Web
            proxy_pass http://192.168.1.9:32400;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
 
    server {
        listen 80;
        server_name  webcam.mydomain.com;
        location / {
            # My webcam
            proxy_pass http://192.168.1.30;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
 
    server {
        listen 80;
        server_name  torrents.mydomain.com;
        location / {
            # Transmission Web interface.
            proxy_pass http://192.168.1.8:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
 
    # HTTP to HTTPS redirects
    server {
        listen 80;
        # Force SSL for Owncloud
        server_name  owncloud.mydomain.com;
        return 301 https://$host;
    }
 
    # HTTPS default website
    server {
        listen       443;
        server_name  localhost;
        ssl                  on;
        ssl_certificate      cert.pem;
        ssl_certificate_key  cert.key;
        ssl_session_timeout  5m;
        ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;
        location / {
            root   html;
            index  index.html index.htm;
        }
    }
 
    # HTTPS reverse proxies
    server {
        listen       443;
        server_name  owncloud.mydomain.com;
        ssl                  on;
        ssl_certificate      cert.pem;
        ssl_certificate_key  cert.key;
        ssl_session_timeout  5m;
        ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;
        location / {
            # Owncloud
            proxy_pass http://192.168.1.7;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }

8. Start nginx

/opt/etc/init.d/S80nginx start

9. If you want to show the correct Remote IP adress of clients connecting in logs on backend webservers, you need to change so the backends uses the X-Forwarded-For HTTP header instead, otherwise it will look like your asus router is the client.

Apache example:
Add a row in httpd.conf:
LogFormat “\”%{X-Forwarded-For}i\” %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\”” combined_revproxy
And in your vhost:
CustomLog /path/to/your/logfile combined_revproxy

OR: You can install apache module mod_extract_forwarded which will change the REMOTE_ADDR to display the correct Remote IP adress.
RHEL/CentOS: Make sure you have EPEL yum repository, yum install mod_extract_forwarded , edit /etc/httpd/conf.d/mod_extract_forwarded.conf , add MEFaccept all.

PS: Don´t forget to backup your jffs partition before upgrading firmware – in my experience it´s often wiped when you upgrade.
A backup is most easily done by SSH to your router and running tar cvf /tmp/mnt/sda1/backup/jffs-backup.tar /jffs

Installing Deluge on FreeNAS

Here´s my quick and dirty notes on how I installed Deluge on FreeNAS 9.2.
In my case I did a dual torrent client setup in the same jail as transmission but you might as well install a new jail if you like.

freenas> jls
JID  IP Address      Hostname                      Path
  1  -               transmission_1                /mnt/vol1/jails/transmission_1
freenas> jexec 1 csh
transmission_1> pkg_add -r deluge
# deluge and dependencies will now compile
transmission_1> pw usermod transmission -s /bin/csh
transmission_1> vi /usr/pbi/transmission-amd64/control.py
# To the top of control.py, add:
import subprocess
# And in this function:
def transmission_fcgi_start(args):
# Add (dont forget the indents):
    subprocess.call("/usr/bin/su - transmission -c /usr/local/bin/deluged", shell=True)
    subprocess.call("/usr/bin/su - transmission -c /usr/local/bin/deluge-web &", shell=True)
transmission_1> exit
freenas> warden stop transmission_1
freenas> warden start transmission_1
# Enter jail again and verify with "ps aux" that transmission and deluge is running
# Visit http://JAIL-IP:8112/ and login with password "deluge".