Debian 8.6, Proxy guacamole via NGINX using HTTPS and Fail2Ban

Slight variation on the proxying guacamole via Apache2 post (much content is the same) but this is post will guide you through proxying guacamole via nginx, fail2ban and ufw config for guacamole.

In my previous article I explained how to install guacamole on Debian 8.6.

First, install nginx using official nginx reporsitory (will enable you to use a more recent, thus more secure version):

apt-get install curl

touch /etc/apt/sources.list.d/nginx.list

echo 'deb http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list.d/nginx.list

echo 'deb-src http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list.d/nginx.list

curl http://nginx.org/keys/nginx_signing.key | apt-key add -

apt-get update
apt-get install -y nginx

mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
# This will take *an age* to complete 
openssl dhparam -out dhparams.pem 4096

Now, we will modify the tomcat8 config

vi /etc/tomcat8/server.xml

Uncomment and modify the AJP/1.3 line accordingly:

 <Connector port="8009" protocol="AJP/1.3"
    URIEncoding="UTF-8"
    redirectPort="8443" />

Now restart tomcat8:

systemctl restart tomcat8.service

Now for SSL configuration; generate your private key and CSR (yo can then process these with an external, third-part CA such as StartSSL – which is free.

openssl req -newkey rsa:2048 -keyout guac.key -out guac.csr

I’m now assuming you now have the following files:

  1. Root certificate bundle for your CA (.crt from third-part CA)
  2. Public key for your certificate (.crt from third-part CA)
  3. Private key for your certificate (.key file form OpenSSL command)

Now, copy these files to /etc/apache2/ssl.

You may need to combine the root_bundle and your specific FWDN certificate – an example command to do this is below:

cat 2_guacamole.domain.com.crt 1_root_bundle.crt >> /etc/nginx/ssl/guac-bundle.crt

Note, your .key file (private key) likely has a passphrase, you’ll want to remove this otherwise you’ll have to manually enter this when ngnix loads:

openssl rsa -in guac.key -out guac-nopass.key

Now, protect those files!

chmod 600 /etc/nginx/ssl/*

Now, we’ll configure the site definition in nginx – change the file name to match your environment:

vi /etc/nginx/conf.d/guacamole.domain.com.conf

Contents as below – make sure you change the text in bold to match your setup:

server {
 listen 80;
 server_name guacamole.domain.com;
 return 301 https://$server_name$request_uri;
}

# Guacamole Reverse Proxy HTTPS Server
server {
 if ($blockedagent) {
 return 403;
 }
 if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|PATCH)$) {
 return 444;
 }
 listen 443 ssl;
 server_name guacamole.domain.com;
 rewrite_log on;
 ssl_dhparam /etc/nginx/ssl/dhparams.pem;
 ssl_certificate /etc/nginx/ssl/1_guacamole.domain.com_bundle.crt;
 ssl_certificate_key /etc/nginx/ssl/guacamole.key;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_prefer_server_ciphers on;
 ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";

 # Hardening as-per https://gist.github.com/plentz/6737338
 ssl_session_cache shared:SSL:50m;
 ssl_session_timeout 5m;
 resolver 8.8.8.8;
 ssl_stapling on;
 ssl_trusted_certificate /etc/nginx/ssl/1_guacamole.domain.com_bundle.crt;

 location / {
 proxy_pass http://127.0.0.1:8080/guacamole/;
 proxy_redirect off;
 proxy_buffering off;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection $http_connection;
 proxy_cookie_path /guacamole/ /;
 access_log off;
 }
}

Now, start nginx:

/etc/init.d/nginx start

Next, configure Apache2 to load on boot:

systemctl enable nginx

You’ll now be able to access your guacamole instance by using the URL: https://<your chosen url>

Now for the fail2ban installation and configuration – first download and install fail2ban:

cd ~
git clone https://github.com/fail2ban/fail2ban
apt-get install python-minimal
cd fail2ban
python setup.py install
cp files/debian-initd /etc/init.d/fail2ban
systemctl daemon-reload
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

No we’ll enable the guacamole by editing /etc/fail2ban/jail.local

vi /etc/fail2ban/jail.local

# Add a new line "enabled = true" under [guacamole]
[guacamole]
enabled = true
port     = http,https,8080
logpath  = /var/log/tomcat*/catalina.out

# Now save and close /etc/fail2ban/jail.local

# Prevent local network from banning - change as per your setup
sed -i "s|ignoreip = 127.0.0.1/8 ::1|ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24|" /etc/fail2ban/jail.local

Lastly for fail2ban config, we need to adjust the regexthat detects failures – as per this site (where I found this fix!).

vi /etc/fail2ban/filter.d/guacamole.conf

# change this incorrect regex: failregex = ^.*\nWARNING: Authentication attempt from <HOST> for user "[^"]*" failed\.$ to this:

failregex = \bAuthentication attempt from \[<HOST>(?:,.*)?\] for user ".*" failed\.

Now, enable fail2ban to start on boot

/etc/init.d/fail2ban restart
systemctl enable fail2ban

Home straight now… ufw config. The commands below are specifically designed for the solution outlined in this post where the LAN is 192.168.1.0/24 and the guacamole server is 192.168.1.249 – please review and consider rules that apply to your environment. If you lose access to your server it’s not my fault!

# Install Uncomplicated Firewall
apt-get install ufw

# Allow HTTPS from 192.168.1.0/24 to guacamole/apache2 server
ufw allow from 192.168.1.0/24 to 192.168.1.249 port 443
# Allow HTTP from local LAN (for redirect only)
ufw allow from 192.168.1.0/24 to 192.168.1.249 port 80
# Enable Firewall
ufw enable