farmerswife

Welcome
Login  Sign up

Using NGINX as a third party proxy service to apply your SSL certificates

In the article “How to SSL farmerswife using your own certificates” we provided information that you can use a third party solution to "proxy" the connection between your "connecting via internet" farmerswife (fw) clients and your farmerswife Server and to secure it by using your own SSL certificates. You can also use solutions like "F5", "HAproxy", "NGINX" or the solution of your choice.

As an example we provide a "NGINX" configuration file with two different scenarios. One where multiple sub-domains are going to be used for the different services. And a second one, where only one sub-domain pointing to raw ports is used for all the connections. Bare in mind that to use the multiple sub-domains you will need to have a SSL certificate for each one or a wildcard certificate.

IMPORTANT: This example here is intended to be used by Linux IT administrators. We also don’t provide support for/on the installation and configuration of the OS or the NGINX service.

An advantage of using NGINX or a third party solution is that you can set which protocols to use and also which cyphers. For example, you can set this up in a way to only allow TLS 1.2 and the newest TLS 1.3. But for this example explained here we only allowed TLS 1.2, since TLS 1.3 isn't fully adopted yet.

This example uses a Debian 9 server and NGINX version 1.14.0 with the "stream module". 

Note: you will need to execute the following commands to generate the needed Diffie-Hellman key.

openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

Within the attached nginx.conf you will find two blocks of config settings:
a) the one "commented out using #" (= not active) is the one to be used with sub-domains
b) and the second block (active) is the one to be configured and used with the single subdomain pointing to the raw ports.

The below rough diagram shows how this will work once proxied through NGINX:

The following values are some of the ones you will need to modify in this config:

  • user root: Change it to the user running the "nginx" process.
  • server_name: Change this on all fields you need to use to match to your sub-domain structure.
  • ssl_certificate: Change this to point to your own certificate.
  • ssl_certificate_key: Change this to point to your own certificate.
  • proxy_pass: Point this to the correct private IP and port of the actual host machine of your farmerswife Server .

DO NOT COPY & PASTE from here! Download the below attached file to avoid "whitespace" or "gremlin character" issues.

user  root;
worker_processes  auto;
include /etc/nginx/modules-enabled/*.conf;
load_module /usr/lib64/nginx/modules/ngx_stream_module.so;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
  worker_connections  1024;
}

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

  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  '$status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"';
  log_format vhosts '$host $remote_addr - $remote_user [$time_local] '
  '"$request" $status $body_bytes_sent '
  '"$http_referer" "$http_user_agent"';

  access_log  /var/log/nginx/access.vhost.log  vhosts;
  access_log  /var/log/nginx/access.log  main;

  sendfile        on;
  #tcp_nopush     on;

  server_tokens off;

  keepalive_timeout  65;

  gzip on;
  gzip_http_version 1.0;
  gzip_comp_level 9;
  gzip_proxied any;
  gzip_types text/plain text/xml text/css text/comma-separated-values text/javascript application/javascript application/x-javascript font/ttf font/otf image/svg+xml application/atom+xml;

  ssl_protocols TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!3DES';
  ssl_dhparam ssl/dhparam.pem;
  ssl_ecdh_curve secp384r1;
  ssl_session_timeout  10m;
  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off;
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8 8.8.4.4;

  add_header Strict-Transport-Security "max-age=31536000" always;
  #add_header X-Frame-Options DENY;
  add_header X-Frame-Options "SAMEORIGIN";
  add_header X-Content-Type-Options nosniff;
  add_header X-XSS-Protection "1; mode=block";
  add_header X-Robots-Tag none;

  server {
    listen 80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
  }

##############################
#  Proxy through subdomains  #
##############################

  ## Legacy HTTPS / WebCal
  #server {
  #  listen 443 ssl http2;
  #  server_name webcal.client.example.com;

  #  error_page 403 404 500 502 503 504 /404.html;
  
  #  location = /404.html {
  #  }

  #  ssl_certificate /etc/nginx/ssl/certificate.crt;
  #  ssl_certificate_key /etc/nginx/ssl/certificate.key;

  #  rewrite ^/webcal/?(.*)$ https://$host/$1;
  #  rewrite ^/$ https://$host/index.html;

  #  location /images {
  #    proxy_intercept_errors on;
  #    proxy_pass http://172.0.0.0:27000$request_uri;
  #  }

  #  location / {
  #    proxy_intercept_errors on;
  #    proxy_pass http://172.0.0.0:27000/webcal$request_uri;
  #  }
  #}

  ## WebClient
  #server {
  #  listen 443 ssl http2;
  #  server_name web.client.example.com;

  #  error_page 403 404 500 502 503 504 /404.html;
  
  #  location = /404.html {
  #  }

  #  ssl_certificate /etc/nginx/ssl/certificate.crt;
  #  ssl_certificate_key /etc/nginx/ssl/certificate.key;

  #  location /webcal {
  #    rewrite ^.* https://webcal.client.example.com$request_uri;
  #  }

  #  location /mobile {
  #    rewrite ^.* https://mobile.client.example.com;
  #  }

  #  location / {
  #    proxy_intercept_errors on;
  #    proxy_pass http://172.0.0.0:26000$request_uri;
  #  }
  #}

  ## Mobile WebClient
  #server {
  #  listen 443 ssl http2;
  #  server_name mobile.client.example.com;

  #  error_page 403 404 500 502 503 504 /404.html;
  
  #  location = /404.html {
  #  }

  #  ssl_certificate /etc/nginx/ssl/certificate.crt;
  #  ssl_certificate_key /etc/nginx/ssl/certificate.key;

  #  location /api {
  #    proxy_intercept_errors on;
  #    proxy_pass http://172.0.0.0:26000$request_uri;
  #  }

  #  location / {
  #    proxy_intercept_errors on;
  #    proxy_pass http://172.0.0.0:26000/mobile$request_uri;
  #  }
  #}

  ## API
  #server {
  #  listen 443 ssl http2;
  #  server_name ios.client.example.com api.client.example.com;

  #  error_page 403 404 500 502 503 504 /404.html;
  
  #  location = /404.html {
  #  }

  #  ssl_certificate /etc/nginx/ssl/certificate.crt;
  #  ssl_certificate_key /etc/nginx/ssl/certificate.key;

  #  location / {
  #    proxy_intercept_errors on;
  #    proxy_pass https://172.0.0.0:25000$request_uri;
  #  }
  #}

  ## Play
  #server {
  #  listen 443 ssl http2;
  #  server_name play.client.example.com;

  #  error_page 403 404 500 502 503 504 /404.html;
  
  #  location = /404.html {
  #  }

  #  ssl_certificate /etc/nginx/ssl/certificate.crt;
  #  ssl_certificate_key /etc/nginx/ssl/certificate.key;

  #  location / {
  #    proxy_intercept_errors on;
  #    proxy_pass http://172.0.0.0:26000/FWP$request_uri;
  #  }
  #}

##############################
#     Proxy raw fw ports     #
##############################

  ## Legacy HTTPS / WebCal
  server {
    listen 27000 ssl http2;
    server_name client.example.com;

    error_page 403 404 500 502 503 504 /404.html;
  
    location = /404.html {
    }

    ssl_certificate /etc/nginx/ssl/certificate.crt;
    ssl_certificate_key /etc/nginx/ssl/certificate.key;

    rewrite ^/webcal/?(.*)$ https://$host/$1;
    rewrite ^/$ https://$host/index.html;

    location /images {
      proxy_intercept_errors on;
      proxy_pass http://172.0.0.0:27000$request_uri;
    }

    location / {
      proxy_intercept_errors on;
      proxy_pass http://172.0.0.0:27000/webcal$request_uri;
    }
  }

  ## WebClient / Mobile WebClient / Play
  server {
    listen 26000 ssl http2;
    server_name client.example.com;

    error_page 403 404 500 502 503 504 /404.html;
  
    location = /404.html {
    }

    ssl_certificate /etc/nginx/ssl/certificate.crt;
    ssl_certificate_key /etc/nginx/ssl/certificate.key;

    location /webcal {
      rewrite ^.* https://client.example.com:27000/webcal$request_uri;
    }

    location / {
      proxy_intercept_errors on;
      proxy_pass http://172.0.0.0:26000$request_uri;
    }
    location /mobile {
      proxy_intercept_errors on;
      proxy_pass http://172.0.0.0:26000/mobile$request_uri;
    }
    location /FWP {
      proxy_intercept_errors on;
      proxy_pass http://172.0.0.0:26000/FWP$request_uri;
    }
  }

  ## iOS / API
  server {
    listen 25000 ssl http2;
    server_name client.example.com;

    error_page 403 404 500 502 503 504 /404.html;
  
    location = /404.html {
    }

    ssl_certificate /etc/nginx/ssl/certificate.crt;
    ssl_certificate_key /etc/nginx/ssl/certificate.key;

    location / {
      proxy_intercept_errors on;
      proxy_pass https://172.0.0.0:25000$request_uri;
    }
  }

}

stream {
  log_format basic '$remote_addr [$time_local] '
  '$protocol $status $bytes_sent $bytes_received '
  '$session_time';

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

  ssl_protocols TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!3DES';
  ssl_dhparam ssl/dhparam.pem;
  ssl_ecdh_curve secp384r1;
  ssl_session_timeout  10m;
  #ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off;

  server {
    listen 22000 ssl;

    ssl_certificate /etc/nginx/ssl/certificate.crt;
    ssl_certificate_key /etc/nginx/ssl/certificate.key;
    ssl_verify_client off;
    #ssl_session_cache builtin:1000 shared:SSL:10m;

    proxy_ssl on;
    proxy_ssl_verify off;
    proxy_ssl_session_reuse off;

    proxy_pass 172.0.0.0:22000;
  }

  # File Transfer Port (Raw-Sockets)
  server {
    listen 8080;
    proxy_pass 172.0.0.0:24000;
  }

  server {
    listen 24000;
    proxy_pass 172.0.0.0:24000;
  }
}


Use the attached nginx.conf file as a guide. Once this is configured and running, this still needs to be maintained from your side. And this can NOT be the only security measure protecting your farmerswife system.

Did you find it helpful? Yes No