SYSWARDEN

ConnectWise Automate: Basic Nginx Reverse Proxy

Jesse Connor, Tue Jun 16 2020

This is a guide on configuring a basic reverse proxy using NGINX for a ConnectWise Automate and Control server. This guide assumes pre-existing knowledge with both Linux and the Microsoft Windows Server features used by ConnectWise Automate and Control. I suggest testing this in a development environment before putting it into production as well as further researching the various values used in this example configuration. There may be settings you need to adjust based on your agent count as well as settings based on your own setup such as split servers. If there are any questions, issues or improvements you would like to see please file an issue on the GitHub repo and I will do my best to assist.

Resources

Scenario

  • connectwise automate
  • connectwise control
  • microsoft windows server 2016
  • same-server configuration
  • http/s reverse proxy only
  • ubuntu server 18.04.4 lts

    • versions > 18 do not support tls 1.0/1.1
    • currently tls 1.0/1.1 is still used by automate

Instructions: Reverse Proxy Sever

  1. setup your base system and make sure it's updated
sudo su
apt update
apt upgrade -y
shutdown -r now
  1. ssh back in and clone the config repository
git clone https://github.com/syswarden/swl-blog-nginx-basic.git nginx-basic
cd nginx-basic
  1. generate your configs files (outputs to generated)
python3 configure.py \
--ssh-port '22' \
--control-port '8040' \
--automate-ip '10.1.1.1' \
--whitelist-ip '1.1.1.1' \
--ssl-domain 'syswarden.com' \
--site-domain 'example.syswarden.com' \
--notify-email '[email protected]' \
--cloudflare-email '[email protected]' \
--cloudflare-apikey 'jumanji'
  1. remove ufw and configure iptables
sudo su
ufw --force reset
ufw disable
apt remove ufw -y
apt install iptables-persistent -y
rsync -rvi generated/etc/iptables/ /etc/iptables/
  1. restore iptables and verify (make sure your ssh port is correct)
sudo su
iptables-restore < /etc/iptables/rules.v4
iptables -v -L --line-numbers
  1. install letsencrypt certbot and generate your certificate
sudo su
add-apt-repository universe -y
add-apt-repository ppa:certbot/certbot -y
apt update
apt install certbot software-properties-common python3-certbot-dns-cloudflare -y
rsync -rvi generated/etc/letsencrypt/ /etc/letsencrypt/
chmod -R 600 /etc/letsencrypt
certbot certonly --no-eff-email --agree-tos -n -d *.syswarden.com
  1. generate an internal certificate for the automate server
sudo su
rsync -rvi generated/etc/inner-cert/ /etc/inner-cert/
openssl genrsa -out /etc/inner-cert/inner-cert.key 2048
openssl req -new -out /etc/inner-cert/inner-cert.csr -key /etc/inner-cert/inner-cert.key -config /etc/inner-cert/inner-cert.cnf
openssl x509 -req -days 9125 -in /etc/inner-cert/inner-cert.csr -signkey /etc/inner-cert/inner-cert.key -out /etc/inner-cert/inner-cert.crt -extensions v3_req -extfile /etc/inner-cert/inner-cert.cnf
openssl pkcs12 -inkey /etc/inner-cert/inner-cert.key -in /etc/inner-cert/inner-cert.crt -export -out /etc/inner-cert/inner-cert.pfx
cp /etc/inner-cert/inner-cert.pfx /home/ubuntu/inner-cert.pfx
chown ubuntu:ubuntu /home/ubuntu/inner-cert.pfx
chmod -R 600 /etc/inner-cert/
  1. install nginx and configure it
sudo su
curl https://nginx.org/keys/nginx_signing.key | apt-key add -
cp generated/etc/apt/sources.list.d/nginx.list /etc/apt/sources.list.d/nginx.list
apt update
apt install nginx -y
rsync -rvi generated/etc/nginx/ /etc/nginx/
  1. generate the nginx dhparam file (this can take a long time, 1+ hours)
sudo openssl dhparam -out /etc/nginx/custom/dhparam.pem 2048
  1. restart nginx and verify everything
sudo systemctl restart nginx
sudo systemctl status nginx
sudo nginx -T

Instructions: Automate Server

  1. download the generated /home/ubuntu/inner-cert.pfx on the proxy
  2. open mmc and add the certificates snap-in for local computer
  3. import inner-cert.pfx to web hosting > certificates
  4. open iis manager > sites > default site > bindings
  5. change the 443 binding to the imported certificate
  6. open cmd as admin and run the following commands
REM # remove the existing control cert (replace 8040 with your own control https port)
netsh http delete sslcert ipport=0.0.0.0:8040

REM # get the certificate hash for the 0.0.0.0:443 binding
netsh http show sslcert

REM # update the control cert replacing the port and certhash=123456
netsh http add sslcert ipport=0.0.0.0:8040 certhash=123456 appid={00000000-0000-0000-0000-000000000000} certstorename=WebHosting

REM # validate the two cert hashes match
netsh http show sslcert
  1. open powershell as admin and run the following commands
# replace the proxy_ip with your own
$proxy_ip = '10.1.1.1.3'
$rule_name = 'correct_ip_rewrite'
$rule_site = 'IIS:\Sites\Default Web Site'
$filter_root = 'system.webServer/rewrite/rules'
$filter_base = "${filter_root}/rule[@name='${rule_name}']"

Add-WebConfiguration -Filter '/system.webServer/rewrite/allowedServerVariables' -Location 'Default Web Site' -AtIndex 0 -Value @{name="REMOTE_ADDR"}
Add-WebConfigurationProperty -PSPath $rule_site -Filter $filter_root -Name '.' -Value @{name=$rule_name; patternSyntax='Wildcard';}
Set-WebConfigurationProperty -PSPath $rule_site -Filter "${filter_base}/match" -Name 'url' -Value '*'
Set-WebConfigurationProperty -PSPath $rule_site -filter "${filter_base}/conditions" -Name '.' -Value @{input='{REMOTE_ADDR}'; pattern=$proxy_ip; }
Set-WebConfigurationProperty -PSPath $rule_site -filter "${filter_base}/serverVariables" -Name '.' -Value @{name='REMOTE_ADDR'; value='{HTTP_X_FORWARDED_FOR}'; }
  1. example server variable added by powershell above at C:\Windows\System32\inetsrv\config\applicationHost.config
<location path="Default Web Site">
  <system.webServer>
    <rewrite>
      <allowedServerVariables>
        <remove name="REMOTE_ADDR" />
        <add name="REMOTE_ADDR" />
      </allowedServerVariables>
    </rewrite>
  </system.webServer>
</location>
  1. example rewrite rule added by powershell above at C:\inetpub\wwwroot\web.config
<rewrite>
  <rules>
    <rule name="correct_ip_rewrite" patternSyntax="Wildcard">
      <match url="*" />
      <conditions>
        <add input="{REMOTE_ADDR}" pattern="10.1.1.3" />
      </conditions>
      <serverVariables>
        <set name="REMOTE_ADDR" value="{HTTP_X_FORWARDED_FOR}" />
      </serverVariables>
    </rule>
  </rules>
</rewrite>

Instructions: Firewall

  1. forward these ports to your automate server

    • 8041 Control Relay
    • 8484 Automate Solution Center (optional)
    • 75 UDP Automate Heartbeat
    • 3389 RDP (optional / change port / lock down to ip)
  2. forward these ports to your reverse proxy

    • 80 Automate HTTP
    • 443 Automate HTTPS
    • 8040 Control HTTPS
    • 22 SSH (optional / change port / lock down to ip)
  3. other ports may be required depending on your specific setup

Security Recommendations

  • isolate your automate and reverse proxy servers

    • put them both on a separate subnet with nothing else
    • do not route any other network traffic to the subnet
    • only allow the specific ports needed to the reverse proxy
  • do not install your own automate or control agent on either server
  • limit rdp and ssh to each server only to specific, static ips
  • make use of a multi-factor tool such as duo on both servers
  • use a completely different domain than your primary website
  • use a wild card certificate to prevent exposing subdomains
  • do not use common subdomains: automate, labtech, rmm, etc.
  • do not directly link to your server urls from your website

Known Issues

  • cannot rewrite to the correct ip in the connectwise control logs

References


Subscribe for Updates