I love Screenconnect (now known as Connectwise Control) but it drives me absolutely bonkers to think that a modern app doesn’t come with basic levels of security built in. All communication between the client and server are encrypted, but your login (yep username and password) are not straight out of the box.
They provide a script which will install an SSL cert for you, but it took me several tries to get it to work- it really should have a GUI for SSL cert installation built into the product. Great, the login details are now protected. But recently, a lot of clients have been complaining that they can’t access the frame we have on our website that contains a portal to our Control instance.
What was going on? Well it turns out that Control uses an old framework called Mono that doesn’t support modern encryption, and Chrome decided to not just mark it as insecure, but to block it altogether. Not good.
Update 12 August 2019– I broke my install over the weekend, and when I came back here to figure it out I realised that there isn’t much in the way of explanations about what is going on. So this update tries to make it clear about what we’re trying to achieve.
HAProxy will take your SSL cert and make sure that all communication is encrypted between the dirty internet and itself. It will then send the data back to Connectwise Control. There’s a few ports involved here – 8443 for secure comms, 8041 is the Relay port (already encrypted according to Connectwise) and 5000 which is the proxy port for HAProxy to hand off to Connectwise Control.
outside world >>> port 8443 >>> HAProxy >>> port 5000 >>> Connectwise Control
outside world >>> port 8041 >>> Connectwise Control
Most of the work here was done by ‘stylnchris‘ (thank you!) on the forum I will link, but here’s the slightly more explanatory version.
WARNING- initially I tried to download and compile a newer version of HAProxy, and I also wanted TLS v1.3 support, which requires OpenSSL v1.1.1, so I also attempted to download, compile and install that. THERE BE DRAGONS. Do not do this- I wasted 2 DAYS trying all sorts of gymnastics to get the f/ing thing to work. I can send you page of notes about what doesn’t work…
You will be using this thread as a starting point – go towards the bottom where you see the HAProxy instructions. I actually think Chris had it already installed because he kind of brushed over some bits, and I’m not that smart so it took ages to push on.
*I’m using CentOS 7 for no particular reason
Firstly- you REALLY need that SSL cert, and in the correct format. I’m using a $10 one from Sectigo. Spend as much time as you need to get it in PEM format, good info here
Make sure you’re up to date, then make sure all the required packages are installed
sudo yum update
sudo yum install make gcc perl pcre-devel lib-devel
Then install HAProxy
sudo yum install haproxy
Then you need to add an exception for selinux because otherwise it’ll block the application –
setsebool haproxy_connect_any on
Set it to launch at boot
systemctl enable haproxy.service
The instructions say that for stats you need haproxy.sock to run in /run/haproxy/haproxy.sock but I couldn’t get that directory to persist, so let’s put that somewhere else (this requires another edit to Chris’ .cfg file)
sudo touch /var/lib/haproxy/stats
add a user space for the app (this may have been added by the yum install)
sudo user add -r haproxy
Now here is Chris’ .cfg file, below I will add mine below and highlight my changes due to my slightly different setup
Edit this file with (yes I use nano!)
sudo nano /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0 notice
maxconn 2000
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
stats socket /run/haproxy/haproxy.sock mode 660 level admin
stats timeout 2m # Wait up to 2 minutes for input
ssl-server-verify none
defaults
log global
mode http
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 5m
timeout server 5m
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
listen Web-Services
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/
mode http
option httplog
redirect scheme https if { hdr(host) -i help.myscreenconnect.com } !{ ssl_fc }
stats enable
stats uri /stats
stats realm Strictly\ Private
stats auth <username>:<password>
acl host_help hdr(host) -i help.myscreenconnect.com
use_backend ScreenConnect if host_help
backend ScreenConnect
balance roundrobin
option httpclose
option forwardfor
cookie JSESSIONID prefix
server node1 127.0.0.1:5000 cookie A check
reqadd X-Forwarded-Proto:\ https
reqadd X-Forwarded-Port:\ 443
And here is mine-
global
log 127.0.0.1 local0 notice
maxconn 2000
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
stats socket /var/lib/haproxy/haproxy.sock mode 660 level admin
stats timeout 2m # Wait up to 2 minutes for input
ssl-server-verify none
defaults
log global
mode http
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 5m
timeout server 5m
listen Web-Services
bind *:80
bind *:8443 ssl crt /etc/haproxy/certs/
mode http
option httplog
redirect scheme https if { hdr(host) -i remotesupport.servicemax.com.au:8443 } !{ ssl_fc }
stats enable
stats uri /stats
stats realm Strictly\ Private
stats auth <username>:<password>
acl host_remotesupport hdr(host) -i remotesupport.servicemax.com.au:8443
use_backend ScreenConnect if host_help
backend ScreenConnect
balance roundrobin
option httpclose
option forwardfor
cookie JSESSIONID prefix
server node1 127.0.0.1:5000 cookie A check
reqadd X-Forwarded-Proto:\ https
reqadd X-Forwarded-Port:\ 8443
I deleted the error pages because they would have to be added manually, and you can see I had to adjust the .sock location, and the port numbers of my server- because that’s what it is currently running on. Right now the stats page is not working but I’ll fix that later as it is now after midnight on a Monday. It took ages to get the referring URLs right as I was constantly getting 503 errors, if you have the same, keep checking your .cfg file
The last part of this is to make sure your Connectwise Control instance is talking to all the other bits. This took a while to figure out because I think an upgrade ‘fixed’ (ie. broke) my CWC web.config file. In the end I needed to add a new line to web.config for RelayAddressableUri as per this article
Here is the final config of my web.config file-
<add key=“WebServerListenUri” value=“http://+:5000/“></add><add key=“RelayListenUri” value=“relay://+:8041/“></add><add key=“RelayAddressableUri” value=“relay://remotesupport.servicemax.com.au:8041/“>
Notice that 2 of these items use the simple ‘+’ URI style and one needs the FQDN? Yeah, that’s the only config in which it worked.
What do I think Connectwise should do?
They should get this fixed real soon. But if that’s a long term project they should provide instructions on how to run a Docker instance of HAProxy to secure an existing instance of Control. That should be good enough to cover us for a while…