Jump to content

C2 on subdomain behind NGINX over HTTPS


reinaertvdc

Recommended Posts

I have an existing domain mydomain.com, already secured with Let's Encrypt, and hosted through NGINX. Now I wanted to make C2 available at c2.mydomain.com, and I accomplished this using an NGINX proxy_pass, of which I put a simplified version below.

server {
    listen 443 ssl;
    server_name c2.mydomain.com;
    proxy_pass http://127.0.0.1:8080;
    ...
}

C2 is then run simply as follows.

c2_community-linux-64 -hostname c2.mydomain.com

As you can see, NGINX converts the incoming HTTPS connections to HTTP before passing them through to C2, which is how I would prefer it. This setup works fine when surfing to c2.mydomain.com using my browser, but my LAN Turtle won't show up in the C2 device list. I've tried several different combinations of parameters for C2, but nothing worked so far. I've deleted c2.db after each attempt and I've made sure that device.config is placed in /etc on my Turtle. For the C2 arguments, I'm assuming I should not use the -https flag, since I want C2 to be a plain HTTP server and let NGINX handle HTTPS. My latest attempt was to enable reverse proxy with port 443, but that didn't fly either.

c2_community-linux-64 -hostname c2.mydomain.com -reverseProxy -reverseProxyPort 443

Is what I'm trying to do even possible? Any help would be much appreciated.

Link to comment
Share on other sites

I've done some more testing and it seems the LAN Turtle will just never phone home over HTTPS. No matter if I run C2 with the -https flag or set -reverseProxyPort 443 or set -listenport 443, the LAN Turtle will always use plain HTTP when connecting to C2. Is this correct?

My current setup checks almost all boxes. C2 is available at c2.mydomain.com through HTTPS, and HTTPS is handled transparently by NGINX while the proxied C2 remains plain HTTP. The only thing I'm missing is the Turtle also connecting over HTTPS, but at this point I'm assuming that's just not supported. For reference, I run C2 as follows.

c2_community-linux-64 -hostname c2.mydomain.com -reverseProxy -reverseProxyPort 80

The accompanying NGINX configuration looks as follows (simplified).

server {
    listen 80;

    server_name c2.mydomain.com;

    # Requests by Hak5 devices remain on plain HTTP.
    location /dapi {
        proxy_pass http://localhost:8080;
    }

    # All other requests are redirected to HTTPS.
    location / {
        return 301 https://$server_name$request_uri;
    }
}

server {
    listen 443 ssl;

    server_name c2.mydomain.com;

    # Browser only, Hak5 devices don't seem to use HTTPS.
    location / {
        proxy_pass http://localhost:8080;
    }
}

Again, is there a way to move the Turtle to HTTPS too, or is this the best I can do?

Link to comment
Share on other sites

23 hours ago, reinaertvdc said:

I've done some more testing and it seems the LAN Turtle will just never phone home over HTTPS. No matter if I run C2 with the -https flag or set -reverseProxyPort 443 or set -listenport 443, the LAN Turtle will always use plain HTTP when connecting to C2. Is this correct?

My current setup checks almost all boxes. C2 is available at c2.mydomain.com through HTTPS, and HTTPS is handled transparently by NGINX while the proxied C2 remains plain HTTP. The only thing I'm missing is the Turtle also connecting over HTTPS, but at this point I'm assuming that's just not supported. For reference, I run C2 as follows.


c2_community-linux-64 -hostname c2.mydomain.com -reverseProxy -reverseProxyPort 80

The accompanying NGINX configuration looks as follows (simplified).


server {
    listen 80;

    server_name c2.mydomain.com;

    # Requests by Hak5 devices remain on plain HTTP.
    location /dapi {
        proxy_pass http://localhost:8080;
    }

    # All other requests are redirected to HTTPS.
    location / {
        return 301 https://$server_name$request_uri;
    }
}

server {
    listen 443 ssl;

    server_name c2.mydomain.com;

    # Browser only, Hak5 devices don't seem to use HTTPS.
    location / {
        proxy_pass http://localhost:8080;
    }
}

Again, is there a way to move the Turtle to HTTPS too, or is this the best I can do?

Afaik, devices call back via auto ssh on port 2022. the web interface is just for you to control everything.

 

I too have a problem with a similar config though, but with my TETRA.

I am also using c2 behind an NGINX reverse proxy with HTTPS. For me The TETRA connects back fine (via ssh), but Terminal wont work properly.

 

When i select it I just get a double disconnected error message in the window.

Disconnected.
Disconnected.

 

And on my VPS I get the following error message.

[*] Initializing Hak5 Cloud C2
[*] Running Hak5 Cloud C2
2018/12/24 12:40:02 http: multiple response.WriteHeader calls

 

I suspect this is being caused by my reverse_proxy configuration. I think I should be able to solve it with the correct nginx directive to tell the webserver to correctly handle the asynchronous terminal stuff?

I haven't for the life of me been able to solve it yet though.

If anyone has any suggestions, I'd be very grateful.

 

EDIT...

This is my nginx sites-available file for the domain I'm using

 

server {

        ssl_certificate /opt/C2C/certs/cert.pem;
        ssl_certificate_key /opt/C2C/certs/key.pem;
        listen 443 ssl;
        server_name ctl.mydomain.com;

        location / {
                    proxy_pass          http://127.0.0.1:8080;
                    proxy_http_version  1.1;

                    # adds gzip
                    gzip_static on;
        }

}

 

 

 

 

Link to comment
Share on other sites

My server logs indicate that devices call back via HTTP, and that's confirmed by Darren Kitchen in another thread.

https://forums.hak5.org/topic/44491-guide-hak5c2/?do=findComment&comment=311892

From his post I understand that SSH is optional and only needed if you want the terminal. Now if I respond to the device callbacks with a 301 redirect to https, the devices ignore it. If I set my reverse proxy port on 443, NGINX logs complain of invalid requests, so I'm guessing the devices are trying to connect to 443 via plain HTTP. Therefore I see no way to get the devices to use HTTPS.

Concerning your "Disconnected." problem, my LAN Turtle did the same, while my Tetra and my Squirrel worked just fine. Rebooted my Turtle, problem remained. Rebooted again, problem was gone. Rebooted again, problem still gone. So I'm guessing it's a bug and your configuration is fine. I suggest rebooting your Tetra and/or server and see if that helps. I didn't check my C2 logs at the time, and I've reinstalled the server since, so I have no idea if I had those "multiple response.WriteHeader calls" errors too.

Link to comment
Share on other sites

  • 11 months later...

Sorry for the thread necromancy, but I just went through this.  For future visitors: hello, see what worked for me below.

First, the nginx samples given by OP and others here are insufficient.  They will work to proxy *all* traffic to the internal service, but that's not what we want.  What we want is for the Nginx proxy to handle the SSL and for the internal service to work with both.  For that to work, you have to make your SSL a) be real (e.g. not self-signed), and b) be integrated into nginx.

 

This will create a reverse Nginx proxy which will handle SSL for c2 (rather than using c2's built-in ssl).

The general guide I followed was this one: https://howtoforge.com/tutorial/install-letsencrypt-and-secure-nginx-in-debian-9/

First, install letsencrypt (certbot).  Do this first using the --standalone option so you don't need to dink around with nginx/apache/etc. webhosts to pass the https checks that certbot does  (the --standalone option tells certbot to spool up a webserver listening on 80 and 443, and will fail if those ports are in use).

The basic command is below, check the tutorial linked above if you need different options or have a more exotic install.

sudo certbot certonly --standalone -d your.site.name

Next, you'll need Diffie Hillman for nginx.  Here's how you do it
 

sudo mkdir -p /etc/nginx/ssl.crt
sudo openssl dhparam -out /etc/nginx/ssl.crt/dhparams.pem 2048

 

Edit  /etc/nginx/sites-enabled/your.site.name in your favorite text editor (which is vi, right?)

# Default server configuration
#
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
         listen 443 ssl default_server;
         listen [::]:443 ssl default_server;

        root /var/www/html;

# Sample SSL config included from howtoforge.com
# tutorial on NGINX + Let's Encrypt
# https://howtoforge.com/tutorial/install-letsencrypt-and-secure-nginx-in-debian-9/
#
                access_log /var/log/nginx/access.log;
                error_log /var/log/nginx/error.log;

               # SSL Certificates
               ssl_certificate "/etc/letsencrypt/live/your.site.name/cert.pem";
               ssl_certificate_key "/etc/letsencrypt/live/your.site.name/privkey.pem";
               ssl_dhparam /etc/nginx/ssl.crt/dhparams.pem;
               #
               ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
              
               ssl_session_cache shared:SSL:1m;
               ssl_session_timeout 10m;
               ssl_ciphers HIGH:!aNULL:!MD5;
               ssl_prefer_server_ciphers  on;
               #
               add_header Strict-Transport-Security "max-age=31536000;
               #

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name your.site.name;



        location / {
                proxy_pass http://127.0.0.1:8080;
        }




}

Restart nginx and double-check that there are no errors.

sudo service nginx restart && sudo systemctl status nginx

You should see something like this:

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) 
     Docs: man:nginx(8)
  Process: 7452 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS)
  Process: 7457 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 7455 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
 Main PID: 7460 (nginx)
    Tasks: 4 (limit: 9830)
   CGroup: /system.slice/nginx.service
           ├─7460 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           ├─7461 nginx: worker process
           └─7462 nginx: worker process

Dec 10 15:19:31 debian systemd[1]: Starting A high performance web server and a reverse proxy server...
Dec 10 15:19:31 debian systemd[1]: Started A high performance web server and a reverse proxy server

Run the c2 server.  Note that I have reverseProxy and reverseProxyPort configured, but HTTPS is not configured!  This is because Nginx is handling SSL for us!

c2_community-linux-64 -hostname your.site.name -listenip 127.0.0.1 -listenport 8080 -reverseProxy -reverseProxyPort 443

Configured as above, the c2 service will be available using HTTPS on port 443.  Requests to port 80 will be redirected to https on 443.  Since nginx handles the SSL, there is no need for c2 to even be aware of it.  

 

Link to comment
Share on other sites

  • 3 months later...

@CaPerryPO : Thank you very much for your detailed explanation!

Additionally to your parameters for starting c2_community-linux-64 i needed to add "-https" as well. (without configuring any certificate on the c2 server as this is handled by the nginx)

And very important: Whenever you change parameters of c2, YOU NEED TO REDOWNLOAD YOUR device.config AS THE PARAMETERS HAVE CHANGED (!!!)

 

I had some issues with getting the Terminal to work, so my config can be found here:

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...