Skip to content

Instantly share code, notes, and snippets.

@Raymo111
Last active August 4, 2023 04:00
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Raymo111/55bc3b830abadf2da1f5eebc980e62e8 to your computer and use it in GitHub Desktop.
Save Raymo111/55bc3b830abadf2da1f5eebc980e62e8 to your computer and use it in GitHub Desktop.
How to SSH over 443 while Apache runs SSL with socat, stunnel4 and sslh

How to SSH over 443 while Apache runs SSL with socat, stunnel4 and sslh

By Raymond Li (Raymo111), December 11th, 2019

Table of Contents

Step 0: Preparation
Step 1: Server
Step 2: Client

Step 0: Preparation

Note: Don't skip over this section! You could lose all access to your system if it is headless!

First open a lifesaver connection to your server via normal SSH. Get root access either with su or sudo -s. Don't close this until the end of this tutorial.

Step 1: Server

Note: The following instructions need to be run on your SERVER, that is, the machine you want to SSH INTO.

On your server, install stunnel4, sslh, certbot, and python-certbot-apache

Use letsencrypt to generate a certificate for apache. Follow the instructions carefully.

sudo certbot --apache

Now edit the stunnel configuration

sudo nano /etc/stunnel/stunnel.conf

Use this config, replacing <SERVER DOMAIN> with your server's domain or subdomain. (e.g. example.com or good.example.com)

pid = /var/run/stunnel.pid
# Sets the Process ID of stunnel to stunnel.pid
cert = /etc/letsencrypt/live/<SERVER DOMAIN>/fullchain.pem
# Sets the certificate stunnel will use with your traffic
key = /etc/letsencrypt/live/<SERVER DOMAIN>/privkey.pem
# Sets the private key stunnel will use in decrypting your traffic
[ssh]
accept = 0.0.0.0:443
# 0.0.0.0 means any and all IP addresses
connect = localhost:1022
# Accepts all traffic on port 443, regardless oforigin and connects it to port 1022

Enable stunnel4

sudo nano /etc/default/stunnel4

Set Enabled=0 to Enabled=1. Now setup sslh. Edit its config

sudo nano /etc/default/sslh

Put this in

# Default options for sslh initscript
# sourced by /etc/init.d/sslh

# Disabled by default, to force yourself
# to read the configuration:
# - /usr/share/doc/sslh/README.Debian (quick start)
# - /usr/share/doc/sslh/README, at "Configuration" section
# - sslh(8) via "man sslh" for more configuration details.
# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)

RUN=yes # Run sslh

# binary to use: forked (sslh) or single-thread (sslh-select) version
# systemd users: don't forget to modify /lib/systemd/system/sslh.service
DAEMON=/usr/sbin/sslh

# Customize this if you want. Uses the user sslh, listens on port 1022 (from stunnel, remember?), and after a bit of automagical analysis, redirects SSH traffic to port 22 and ssl (Apache/webserver/https) traffic to 443. Uses process id of sslh.pid
DAEMON_OPTS="--user sslh --listen 127.0.0.1:1022 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"

Now check your Apache ports config file

sudo nano /etc/apache2/ports.conf

And make sure only port 80 is uncommented. If not, just add a # in the beginning of all the uncommented lines but Listen 80

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80

#<IfModule ssl_module>
#       Listen 443
#</IfModule>

#<IfModule mod_gnutls.c>
#       Listen 443
#</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Start and enable stunnel4 and sslh

sudo systemctl start stunnel4 sslh && sudo systemctl enable stunnel4 sslh

Enable gateway ports

sudo nano /etc/ssh/sshd_config

Find GatewayPorts and set it to yes:

GatewayPorts yes

If there are any errors, you have messed something up. Recheck all the config files and make sure they match the ones above. Finally, restart stunnel4, sslh, and apache2

sudo systemctl restart stunnel4 sslh apache2

Step 2; Client

Note: The following instructions need to be run on your CLIENT, that is, the machine you want to SSH FROM.

Edit your SSH config

nano .ssh/config

Put the following in, replacing with whatever you want, with your username on your SERVER and with your server's domain or subdomain.

Host <HOSTNAME>
user <USERNAME>
Proxycommand /usr/bin/socat - OPENSSL:<SERVER DOMAIN>:443.verify=0

Test out your setup!

ssh <HOSTNAME>

You should be able to SSH through 443 now! Also check to make sure Apache is still running and you can still SSH normally BEFORE closing your lifesaver connection.

If my tutorial helped you, or if you encountered any errors or have any suggestions for me, leave a comment below to let me know!

@willy666rumster
Copy link

so... wha'bou' sslh thought stunnel?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment