To connect to the Dropbox Server we need to have it establish reverse SSH tunnels on the Dropbox Relay.
First we need to upload our Dropbox Server’s public key to the Dropbox Relay. Since we can’t access the relay directly – it requires key authentication – you can copy the file to a USB and move it over to the Dropbox Client which does have access to the Dropbox Server, or since you’re probably setting up the Dropbox Server on the same network as your Dropbox Client just ncat it…
On the Dropbox Client
ncat -l > dbox-01.id_rsa.pub
On the Dropbox Server
ncat --send-only <IP ADDRESS OF Dropbox CLIENT> < /root/.ssh/dbox-01.id_rsa.pub
Now paste the key up to the Dropbox Relay.
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDYLth9fKJYB9NU79L3OasBUOTVrnIRBgJH4VwVPhXs23xnpG4sYmDel3xoChglPvM50wgkWxm/JFcrW5DHi4ndkZBR8Wp6bSvEVkijIYejDdeJVfmmpChnJopGgPO5w+vDTgP5I1fjDQvocXscjPJdAqFEQKtWOoGd+SzpCfwG4wD/egHMZIchLjpkexuJpG9k2Q5cgqRd/CEAJ0QL8+4lqbYCqapw6zIBZiOHnv3WR3QXhSY1gvX1Isri1D7Oh8ZFI7jqv0cYteX2f1iDbfwN6YYqkkIA6BrkMBincC/FSZ/mpo8hlRRnIrcCHfYrSVc3bsuocesz/b/UJngVzCjV root@dbox-01
Do this for each Dropbox Server you have, e.g. dbox-02.id_rsa.pub, dbox-03.id_rsa.pub, dbox-04.id_rsa.pub…
Let’s start simple and work our way up.
Can we SSH from the Dropbox Server to the Dropbox Relay as the dbox-relay user with our Dropbox Server private key?
ssh -i /root/.ssh/dbox-01.id_rsa -p 22 dbox-relay@<FQDN of Dropbox Relay>
You should be prompted to add the server’s fingerprint to the known_hosts file and then see a command prompt for the Dropbox Relay. Remember you won’t be asked to enter the passphrase for the key because we didn’t set one.
Okay, can we do the same thing, but over an SSL/TLS tunnel?
ssh -i /root/.ssh/dbox-01.id_rsa -o ProxyCommand="/usr/bin/ncat --ssl <FQDN of Dropbox Relay> 443" -p 22 dbox-relay@localhost
And, now let’s verify the certificate to add an additional layer of security against MitM attacks.
ssh -i /root/.ssh/dbox-01.id_rsa -o ProxyCommand="/usr/bin/ncat --ssl-verify <FQDN of Dropbox Relay> 443" -p 22 dbox-relay@localhost
Running all the above from the command line also populated the known_hosts file, which is a requirement since we’re going to be implementing strict host checking.
Do this on each Dropbox Server you will be connecting to the Dropbox Relay. There’s no point in proceeding until the above works.
Finally we need to build an SSH configuration file on the Dropbox Server that will support the following:
- Key authentication to the Dropbox Relay server
- Strict host checking (only allow automated authentication to the Dropbox Relay)
- Tunnel SSH over SSL/TLS
- Tunnel VNC over an SSL/TLS encapsulated SSH session
- Tunnel HTTP(S) proxied traffic over an SSL/TLS encapsulated SSH session
- Tunnel SOCKS proxied traffic over an SSL/TLS encapsulated SSH session
- Support client outbound proxies with Basic or NTLM authentication
Here’s what we’re going to start with, assuming Dropbox Server 01 (modify for 02, 03, 04…by changing the IdentityFile and RemoteForward ports accordingly). This will be replaced on every boot at a later step so if you make any modifications make sure to back the file up!
Host dbox* HostName localhost AddressFamily inet User dbox-relay Port 22 IdentityFile /root/.ssh/dbox-01.id_rsa ProxyCommand /usr/bin/ncat --ssl-verify <FQDN of Dropbox Relay> 443 ServerAliveInterval 10 ServerAliveCountMax 3 ExitOnForwardFailure yes StrictHostKeyChecking yes UserKnownHostsFile /root/.ssh/known_hosts Host dbox-ssh-tunnel RemoteForward 11095 localhost:22 Host dbox-vnc-tunnel RemoteForward 11096 localhost:5901 Host dbox-squid-tunnel RemoteForward 11097 localhost:3128 Host dbox-socks-tunnel RemoteForward 11098 localhost:9999 Host client HostName localhost AddressFamily inet User root Port 22 IdentityFile /root/.ssh/dbox-01.id_rsa LocalForward 9999 192.168.1.69:3306 ServerAliveInterval 10 ServerAliveCountMax 3 ExitOnForwardFailure yes NoHostAuthenticationForLocalhost yes
The more than help, but less than man explanation of the above…
Host dbox* – All entries under this apply to any entry that starts with ‘dbox’, so basically all entries other than ‘client’ in this case.
HostName – In this case localhost is localhost on the Dropbox Relay. We establish an SSL/TLS connection with ncat to the HAProxy listening on the Dropbox Relay. It sees that we have encapsulated SSH and routes to the local SSH server so at that point we are localhost.
User – Same reasoning as above. We’re authenticating to the SSH server on the Dropbox Relay.
Port – This is the port the Dropbox Relay SSH Server is listening on. We’ll see later that it is bound to all interfaces, but we’ll firewall it so it can only be accessed via the HAProxy over port 443.
IdentityFile – This is the private key we will be using to authenticate to the Dropbox Relay. We uploaded the corresponding public key previously.
ProxyCommand – This is what we are using to encapsulate our SSH traffic in. In later examples where the client requires going through an outbound proxy we’ll replace ncat with proxytunnels.
ServerAliveInterval and ServerAliveCountMax – These settings can be higher for pure SSH connections, but to keep SSL/TLS alive seems to require a bit more consistent traffic.
ExitOnForwardFailure – If a connection dies ungracefully the Dropbox Relay won’t necessarily know and will keep the remote ports open. The auto-restart services we define later on the Dropbox Server will notice the dead service and reanimate it. If this setting is not set to yes then the service will assume everything is OK even though it was not able to create the remote ports (because they already exist). With this set to yes it will fail until the Dropbox Relay times out and releases the orphaned tunnels. This ensures new good tunnels because the service will keep trying until it succeeds.
StrictHostKeyChecking – This is an added measure of security as we will only accept fingerprints of servers in the known_hosts file. It can also cause problems if servers change. If problems do occur, though, we can always comment it out and send the client a new config to place on the USB.
UserKnownHostsFile – The file we store all those fingerprints in. Can be customized.
Host dbox-ssh-tunnel – All the dbox* apply to this entry plus we create a reverse SSH tunnel on port 11095 of the Dropbox Relay and forward all traffic that connects to it to our local port 22 (SSH). Note 11095 is arbitrary, but needs to be unused.
Host dbox-vnc-tunnel – All the dbox* apply to this entry plus we create a reverse SSH tunnel on port 11096 of the Dropbox Relay and forward all traffic that connects to it to our local port 5901 (VNC). Note 11096 is arbitrary, but needs to be unused.
Host dbox-squid-tunnel – All the dbox* apply to this entry plus we create a reverse SSH tunnel on port 11097 of the Dropbox Relay and forward all traffic that connects to it to our local port 3128 (Squid). Note 11097 is arbitrary, but needs to be unused.
Host dbox-socks-tunnel – All the dbox* apply to this entry plus we create a reverse SSH tunnel on port 11098 of the Dropbox Relay and forward all traffic that connects to it to our local port 9999. Note 11098 is arbitrary, but needs to be unused.
Note: Each Dropbox Server needs a unique set of ports on the Dropbox Relay. I’ve gone with quadruplets of 11095/11096/11097/11098,12095/12096/12097/12098, 13095/13096/13097/13098, 14095/14096/14097/14098, etc. Use whatever you like and whatever is easy for you to remember. None of these are exposed to the client or the Internet so it doesn’t really matter.
Host Client – This can really be thought of as SOCKS proxy Part 2. All of the other services will be autostarted for us, but this we will only define and start manually as needed since it requires specific client information. For example we will always want to SSH and VNC to our Dropbox Server or even use it as a proxy for running Burp Suite against client applications, but if we’re going to have it act as a SOCKS proxy to test a client’s MySQL server (as shown in the example config above) we need to know specific IP address and port information.
There are a few Host Client configuration settings that deserve special attention.
HostName – This time localhost means our localhost, which is why we can’t do StrictHostKeyChecking here because we already have an entry for localhost and that’s for the Dropbox Relay, which won’t match. Not really an issue, though, since if an attacker can MitM our local connection it’s already game over.
LocalForward – Now we’re forwarding everything that’s coming over the already forwarded, forwarded port 9999 to the client’s MySQL database on port 3306.
NoHostAuthenticationForLocalhost – As described above Dropbox Server localhost will conflict with Dropbox Relay localhost in known_hosts. Setting this to yes alleviates that issue.
You should now be able to manually test your tunnels!
First lets look at what the current connections on the Dropbox Relay look like.
From the Dropbox Relay type the following.
You should see something like this.
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 968/sshd tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 20979/haproxy tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN 1062/dnsmasq tcp6 0 0 :::22 :::* LISTEN 968/sshd tcp6 0 0 :::80 :::* LISTEN 20900/apache2 tcp6 0 0 :::53 :::* LISTEN 1062/dnsmasq
Now let’s try establishing some tunnels from the Dropbox Server.
This should log you into the Dropbox Relay. From this terminal checkout the current active connections.
There’s port 11095 waiting for our Dropbox Client to connect!
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:11095 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN - tcp6 0 0 :::22 :::* LISTEN - tcp6 0 0 :::11095 :::* LISTEN - tcp6 0 0 :::80 :::* LISTEN - tcp6 0 0 :::53 :::* LISTEN -
Verify this for dbox-vnc-tunnel, dbox-squid-tunnel, and dbox-socks-tunnel in the same manner.