On the topic of NGINX Reverse Proxy, it just so happens that the process for installing an SSL certificate onto your ScreenConnect server can be rather difficult, and a much more flexible approach is by using NGINX over SSL to reverse-proxy to the ScreenConnect instance.

This is how you can do it yourself.

Modify ScreenConnect settings:

To begin, we should change the port that ScreenConnect listens on for incoming web connections.

  • This is so NGINX can use ports 80 and 443.

On Linux, screen connect is in installed to /opt/screenconnect/

Open the web.config file:

sudo nano /opt/screenconnect/web.config

Look for and modify the following lines to fit your specification.

  • Here, we are using port :10050 to access ScreenConnect WebUI now.
  • We are also adding the https:// before your domain which you access ScreenConnect with because we use SSL only now.
<add key="WebServerListenUri" value="http://127.0.0.1:10050/">
</add>
 <add key="WebServerAddressableUri" value="https://support.yourdomain.com/">
</add>

Now that you have taken care of that, we’re going to work on NGINX.

 

Generate a strong diffie-hellman group:

You need to define the path you choose for this in the NGINX config

# to generate your dhparam.pem file, run in the terminal
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
  • Whether you use the default site config or create a new config, it’s up to you. This is the config I am using to proxy to the ScreenConnect server in the above example.

Nginx host file:

server {
 listen 80;
 server_name support.yourdomain.com;
 return 301 https://$host$request_uri;
}

server {
 listen 443 default_server ssl;
 server_name support.yourdomain.com;

 ## ENABLE SSL.
 ssl on;

 ## DEFINE THE LOCATION OF YOUR CERTIFICATE AND KEY
 ssl_certificate /etc/nginx/ssl/support.yourdomain.com.crt;
 ssl_certificate_key /etc/nginx/ssl/support.yourdomain.com.key;

 ## PERFORMANCE OPTIONS
 ssl_session_cache shared:SSL:10m;
 ssl_session_timeout 5m;
 keepalive_timeout 60;
 ## TLSv1 AND TLSv1.1 AND TLSv1.2;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
 ssl_dhparam /etc/nginx/ssl/dhparam.pem;

 ## ALWAYS SAFER TO DEFINE AN ORDER - THINK CAREFULLY IF YOU DISABLE THIS.
 ssl_prefer_server_ciphers on;

 ## CIPHERS GOOD FOR AN "A" RATING.
 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';
 ## WANT A QUALYS "A" RATING (100/100/100/100)? BE SURE TO REMOVE/COMMENT ABOVE LINE, ENABLE TLSv1.2 ONLY AND BE MINDFUL THAT CLICKONCE/JNLP DEPLOYMENT MAY NOT WORK.
 # ssl_ciphers "ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA";
 ## ENABLE IF YOU INTEND TO USE ELLIPTIC CURVE DHE
 # ssl_ecdh_curve secp521r1;
   
 ## OPTIONS
 ## ENABLE HSTS - CHROME & FIREFOX ONLY. ONCE ENABLED, ALL SUBSEQUENT REQUESTS WILL BE DIRECTED TO HTTPS.
 add_header Strict-Transport-Security max-age=15768000;

 location / {
 ## WHERE ARE WE PASSING OUR REQUEST TO?
 # IN THIS EXAMPLE, THE NATIVE SCREENCONNECT UI IS NO LONGER ACCESSIBLE DIRECTLY. ALL REQUESTS MUST COME THROUGH NGINX PROXY.
 # BE SURE TO SET SCREENCONNECT WEB.CONFIG FILE TO LISTEN ON 127.0.0.1:10050.
 proxy_pass http://127.0.0.1:10050/;
 proxy_redirect off;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_max_temp_file_size 0;
 client_max_body_size 50m;
 client_body_buffer_size 256k;
 proxy_connect_timeout 180;
 proxy_send_timeout 180;
 proxy_read_timeout 90;
 proxy_buffer_size 16k;
 proxy_buffers 4 64k;
 proxy_busy_buffers_size 128k;
 proxy_temp_file_write_size 128k;
 }
}

I hope you can use this to secure your ScreenConnect site. It is extremely important that we do not authenticate with remote-support software over unsecured HTTP.


32 Comments

Dale Gallosky · August 24, 2019 at 10:19 pm

Followed all of the directions, checked sudo lsof -i -P -n | grep LISTEN I can see that :8041 and 127.0.0.1:8042 is listening, also can see 127.0.0.1:10050 is listening all by mono. I see that :80 and :443 are listening by nginx, however when I use open port check tool, 80 shows open, 443 shows closed. Can’t access the site on 443 as well. I saw some references that I have to create a symlink…does this apply?

Noz · August 5, 2019 at 12:10 pm

I had this working fine. But upgraded to the latest version of control and lost all my unattended Access connections – I assume it has something to do with the reverse proxy?

    Tyler Woods · August 5, 2019 at 12:49 pm

    That’s unlikely because the relay and corresponding clients access aren’t run through the proxy, only the web interface is. It is likely you lost the unattended clients during the upgrade process.

Noz · March 25, 2019 at 2:44 pm

Great, worked for me with a bit of tinkering. The only issue I have now is that the URL for Invites is wrong as it has the internal port used to connect NGINX to screenconnct, not 443.

Is there a way of fixing that?

    Tyler Woods · March 25, 2019 at 2:52 pm

    I believe you’ll need to specify the “WebServerAddressableUri” in the web.config settings as the base URL to your proxied instance.

    https://docs.connectwise.com/ConnectWise_Control_Documentation/On-premises/Advanced_setup/List_of_web.config_settings

      Noz · March 25, 2019 at 3:12 pm

      Sorry not quite following that. I have:

      but the address given out for Invites is:
      http://remote.mydomain.co.uk:10050/

      and it says:

      “Direct guest to:
      http://remote.mydomain.co.uk:10050/
      And instruct to type in the code:”

      I don’t know where Screenconnect is getting that address from? It appears to be creating it since that line does not appear in web.config.

        Tyler Woods · March 25, 2019 at 3:21 pm

        Per the ConnectWise article I linked, that key is not present by default, so you must specify it manually.
        This will override that setting which appears for you automatically.

        Key
        WebServerAddressableUri

        Behavior
        Determines the URI on which the web server addresses

        Default Value
        Not present by default

        here is a link for how to modify the web.config file

        https://docs.connectwise.com/ConnectWise_Control_Documentation/On-premises/Advanced_setup/Edit_the_web.config_file

          Noz · March 25, 2019 at 3:25 pm

          Sorry if I’m being thick here but that like IS in my web.config. I believe I put there and it reads:

          that would appear to be correct no?

            Tyler Woods · March 25, 2019 at 3:28 pm

            Yours didn’t show up, probably because of the brackets, but here check mine:


            Vadd key="WebServerAddressableUri" value="https://remote.yoursite.com:443/"V
            V/addV

            i guess i needed to remove the brackets to share the snippet, replace V with open and close bracket where appropriate

              Noz · March 25, 2019 at 3:39 pm

              Ha! I hadn’t noticed they weren’t showing up

              OK so mine looks exactly like that anyway.

              Have you looked at what your screenconnects invites are sending out? Cos I can’t work out where the address comes from it’s http but otherwise the correct URL and has the 10050 “internal” port. I can only assume it’s creating it as opposed to looking it up in web. config?

                Tyler Woods · March 25, 2019 at 3:41 pm

                Yeah my instance directs to the proper URL.

                make sure you’re restarting the screen connect service after making changes here so it can re-load the web.config with the new settings.

                  Noz · March 25, 2019 at 4:02 pm

                  Aha – got it. Spelling mistake – spelling address with one “s”! So it effectively the entry wasn’t there as far as screenconnect saw it.

                  Thanks for your help mate.

                    Tyler Woods · March 25, 2019 at 4:05 pm

                    Cheers and I’m glad you got it figured out!

                    Noz · March 25, 2019 at 4:08 pm

                    BTW does your External Accessibility check pass? Mine doesn’t. I don’t really care since everything is working perfectly as far as I can tell but I get

                    “Web Server Error:Unrecognized server. Not ScreenConnect Web Server.” and:
                    “Relay error: ”

                    Is that expected?

                Felix · March 25, 2019 at 4:13 pm

                I had the same problem. This fixed it.

                Vadd key=”WebServerListenUri” value=”https://127.0.0.1/”V V/addV
                Vadd key=”WebServerAlternateListenUri” value=”http://127.0.0.1:10050/”V V/addV
                Vadd key=”RelayListenUri” value=”relay://+:8041/”V V/addV
                Vadd key=”RelayAddressableUri” value=”relay://relay.domain.com:8041/”V V/addV

                I tried adding this a while back, but had brackets in it so it didn’t show up. The relay changes might be unnecessary, but that’s what I have in mine. Replace the Vs with proper brackets.

                YMMV, Good luck.

                “WebServerAlternateListenUri” is the only thing I can bring to the table. Thanks for everything else Tyler.

                  Tyler Woods · March 25, 2019 at 4:19 pm

                  Felix, I saw your comment from before but I didn’t make the connection until now. So you also specified your WebServerAddressableUri now and it is fixed? Someone else in the comments had problems with the linux JNLP after this so I want to be clear. Thanks!

                    Felix · March 25, 2019 at 4:55 pm

                    Yes, I have WebServerListenUri pointing to “https://127.0.0.1/” and WebServerAlternateListenUri pointing to ”http://127.0.0.1:10050/”. It wouldn’t work until I added the alternate key.

Wayne Reeves · March 22, 2019 at 10:11 am

How would you go about reusing certificates if you already have SSL configured with mono? Trying to migrate over to this reverse proxy with the existing certs.

    Tyler Woods · March 22, 2019 at 10:19 am

    Without being able to visualize your setup, I can only speculate, but i would adjust your mono instance so that it’s listening on different ports and not using SSL anymore, and you can just point the nginx config to the locations of the SSL certs Mono was using before and proxy the requests to the screen connect service running on HTTP protocol.

      Wayne Reeves · March 22, 2019 at 11:06 am

      So originally GoDaddy provided us with these files:
      30252779f8295a7e.crt
      gd_bundle-g2-g1.crt

      Originally I ran the SSL Configurator from ScreenConnect and it spit out the following files in our /opt/screenconnect/:
      App_Runtime/
      App_Runtime/etc/
      App_Runtime/etc/.mono/
      App_Runtime/etc/.mono/certs/
      App_Runtime/etc/.mono/certs/CA/
      App_Runtime/etc/.mono/certs/CA/tbp-c62fe90d242ca64f1ffd82bfcaac1aef41bdd21d.cer
      App_Runtime/etc/.mono/httplistener/
      App_Runtime/etc/.mono/httplistener/443.cer
      App_Runtime/etc/.mono/httplistener/443.pvk

      So I’m not sure which I should be pointing to. I tried the two 443 files assuming the pvk was the key, but it gives me this error when I try to reload nginx:
      nginx: [emerg] SSL_CTX_use_PrivateKey_file(“/opt/screenconnect/App_Runtime/etc/.mono/httplistener/443.pvk”) failed (SSL: error:0906D06C:PEM routines:PEM_read_bio:no start line:Expecting: ANY PRIVATE KEY error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib)
      Mar 22 11:00:05 mysite.companyname.com systemd[1]: nginx.service: Control process exited, code=exited status=1

        Tyler Woods · March 22, 2019 at 11:29 am

        When you requested this cert you should have created a CSR. This should have given you a .key file. You combine use of the .key file from the CSR, and a concatenated file of both of the crt files provided by godaddy.

        In linux shell:

        cat 30252779f8295a7e.crt gd_bundle-g2-g1.crt > sslcert.chained.crt

        In NGINX config file:

        ssl_certificate /path/to/sslcert.chained.crt
        ssl_certificate_key /path/to/keyfile.key

        Hopefully this helps!

Wayne Reeves · March 22, 2019 at 9:52 am

What if I already have SSL configured with Mono? How do I use the same certs that are already configured for this reverse proxy? I’ve been trying for a couple of days but have yet to be successful.

ustechninja · March 20, 2019 at 8:27 pm

Missing steps.

    Tyler Woods · March 21, 2019 at 12:17 pm

    This article assumes NGINX is installed and you have a basic understanding of the software and configuration files. I’d be happy to help point you to whatever information you are missing; it may help other people in your position as well.

Felix · February 12, 2019 at 10:52 pm

“BE MINDFUL THAT CLICKONCE/JNLP DEPLOYMENT MAY NOT WORK”

Click once stops working because the support client looks for ‘url:10050’. The initial support connection always fails for me.

The work around is to have your guest go back to the browser and click on “Having trouble? Try next option”

The fix I used to enable clickonce:

I may have made unrelated changes to the relays previously. I only include them here for reference. The key here is the “WebServerAlternateListenUri” key.

YMMV

GiowGiow · February 17, 2018 at 9:50 am

When downloading the app it can’t connect to the relay for some reason… Any help ?

GiowGiow · February 14, 2018 at 11:22 pm

Thank you!

Martyn Spencer · October 25, 2017 at 3:26 am

Thanks for taking the time to document this. It worked well.

Easy SSL for ScreenConnect with NGINX Reverse Proxy – Oskamp Tech · May 22, 2018 at 2:43 am

[…] Source: https://tylermade.net/2017/05/04/easy-ssl-for-screenconnect-with-nginx-reverse-proxy/ […]

Leave a Reply to Martyn SpencerCancel reply