I’ve recently installed a Keybox on a Raspberry Pi attached to my home network. Keybox is a bastion service that acts as a hardened access point that a protected network sits behind. The idea being that a single locked externally facing machine is easier to defend than allowing access to the whole network. The usual approach is for that one machine to just run an SSH daemon configured to only allow access via a private key. SSH allows terminal access and file transfer via scp, it allows for tunnels to be set up, so a authorised user can with the right config not normally notice that the bastion machine is there.
Keybox extends this model a little, it provides web hosted terminals to access the machines that sit behind it. The upside to this is that users don’t need anything more than a web browser to access the machine and the private keys never leave the bastion machine. Security is handled by 2FA using a OTP generator (e.g. Google Authenticator). One of the major use cases for Keybox is to access AWS machines without public IP addresses.
The reason for all this being that I’ve had some occasions recently where I’ve needed terminal access to my home machines while away but the networks I’ve been connected to did not allow outbound SSH connections. It should also be useful for when I only have access to machines with web access (e.g. locked down Chromebooks) or borrowing machines.
Download the Keybox tgz file from the releases section of the Keybox github page.
Keybox is uses Jetty to host the web app so needs a Java virtual machine to be installed. With this in mind as I am running this on a Raspberry Pi I also reduced the Java heap size in the launch script from 1024mb to 512mb, this shouldn’t be a problem as this instance is not likely to see large amounts of load. I started the service up and tested connecting direct to the Raspberry Pi on port 8443.
The next step was to expose the service to the outside world. To do this I wanted to mount it on a URL on my main machine to make it use my existing SSL certificate. This machine runs Apache so it needs to be configured to proxy for Keybox instance. I found some useful notes to get started here.
I added the following to inside the <VirtualHost> tags in the ssl.conf file:
SSLProxyEngine On SSLProxyCheckPeerName off SSLProxyCheckPeerCN off SSLProxyCheckPeerExpire off SSLProxyVerify none ProxyRequests off ProxyPreserveHost On ProxyPass /box https://192.168.1.1:8443/box ProxyPassReverse /box https://192.168.1.1:8443/box RequestHeader set X-Forwarded-Proto "https" env=HTTPS <LocationMatch "/box/admin/(terms.*)"> ProxyPass wss://192.168.1.1:8443/box/admin/$1 ProxyPassReverse wss://192.168.1.1:8443/box/admin/$1 </LocationMatch>
I also needed to make sure mod_proxy_wstunnel was enabled to ensure the websocket connections were forwarded. The entries at the start (SSLProxyCheckPeerName, SSLProxyCheckPeerExire and SSLProxyVerify) tell Apache not to validate the SSL certificate on the Keybox machine as it is a self signed certificate.
By default Keybox runs in the root of the Jetty server so it needs a quick update to move it to running in /box to match the proxy settings. Edit the keybox.xml file in jetty/webapps to change the contextPath:
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/box</Set> <Set name="war"><Property name="jetty.home" default="." />/keybox</Set> <Set name="extractWAR">false</Set> </Configure>
Now I can access Keybox at https://mymachine/box