How to Install the SSLH Multiplexer

You are here:
< All Topics

My server is using the sslh multiplexer daemon, this uses incoming port 443 for both ssh and https.


Reason for this is to avoid ssh connection problems when trying to connect to the server from outgoing routers which do not permit outgoing ssh port 22 connections.


If you have administrator access to the router you can modify this, but if you don’t have access, eg when using a router in a residential or commercial building complex to which you don’t have admin access yourself, then a viable workaround is to use port 443 for outgoing ssh connections.


This is because port 443 is hardly ever blocked by routers and can thus be relied upon to be accessible.


On my server, incoming port 443 ssh connections are therefore redirected to sshd on port 22, while incoming https 443 connections are redirected to https port 444 on apache.


Apache must then be configured to listen on port 444 instead of the default 443.



sslh accepts connections on specified ports, and forwards them further based on tests performed on the first data packet sent by the remote client.


sslh acts as a protocol demultiplexer, or a switchboard. Its name comes from its original function to serve SSH and HTTPS on the same port.


First, install sslh:


apt install sslh


then in /etc/default/sslh






and set the DAEMON_OPS to use the desired port for sslh and to forward to ssh:


Here we want incoming ssh connections to come in on port 444, and forward ssh calls to 22 and all other calls (which will be https for apache) to be forwarded to 444:


DAEMON_OPTS=”–user sslh –listen –ssh –ssl –pidfile /var/run/sslh/”


so it will look like this:


root@gemini:/# cat /etc/default/sslh
# 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)


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

#DAEMON_OPTS=”–user sslh –listen <change-me>:443 –ssh –ssl –pidfile /var/run/sslh/”
DAEMON_OPTS=”–user sslh –listen –ssh –ssl –pidfile /var/run/sslh/”


then config systemctl to autostart sslh, then start sslh:


systemctl enable sslh
systemctl start sslh


Check that its running and listening correctly:


root@gemini:/# ps -ef | grep sslh
sslh 611 1 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 443 –ssh 22 –tls 444 –pidfile /var/run/sslh/
sslh 612 611 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 443 –ssh 22 –tls 444 –pidfile /var/run/sslh/
sslh 937 612 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 443 –ssh 22 –tls 444 –pidfile /var/run/sslh/
sslh 1073 612 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 443 –ssh 22 –tls 444 –pidfile /var/run/sslh/
sslh 9093 612 0 19:22 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 443 –ssh 22 –tls 444 –pidfile /var/run/sslh/
root 9503 9199 0 20:00 pts/2 00:00:00 grep –color=auto sslh
root@gemini:/# netstat -tulpn | grep sslh
tcp 0 0* LISTEN 611/sslh


then, you can access ssh by using:


ssh -p 443 username@server-ip


and sslh will forward the ssh connection to sshd on port 22 on the server


Don’t forget also you must reconfigure apache to listen on port 444 (/etc/apache2/ports.conf and the appropriate sites-enabled conf file – and restart apache after modifying the files).



sslh Syntax

sslh [ -t num ] [-p listening address] [-l target address for SSL] [-s target address for SSH] [-u username] [-P pidfile] [-v] [-i] [-V] [-f]


-t num
Timeout before a connection is considered to be SSH. Default is 2s.
-p listening address
Interface and port on which to listen, e.g. foobar:443, where foobar is the name of an interface (typically the IP address on which the Internet connection ends up).

Defaults to (listen to port 443 on all available interfaces).
-l target address for SSL
Interface and port on which to forward SSL connection, typically localhost:443.

Defaults to localhost:443 (this assumes you would configure your httpd process to listen to port 443).

Note that you can set sslh to listen on ext_ip:443 and httpd to listen on localhost:443: this allows clients inside your network to just connect directly to httpd.
-s target address for SSH
Interface and port on which to forward SSH connection, defaults to localhost:22.
Increase verboseness.
Prints sslh version.
-u username
Requires to run under the specified username. Defaults to nobody (which is not perfect — ideally sslh should run under its own UID).
-P pidfile
Specifies the file in which to write the PID of the main server. Defaults to /var/run/
Runs as an inetd server. Options -P (PID file), -p (listen address), -u (user) are ignored.
Runs in foreground. The server will not fork and will remain connected to the terminal. Messages normally sent to syslog will also be sent to stderr.



root@gemini:/etc# systemctl status sslh
● sslh.service – SSL/SSH multiplexer
Loaded: loaded (/lib/systemd/system/sslh.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2022-03-22 14:58:58 UTC; 17min ago
Docs: man:sslh(8)
Main PID: 823 (sslh)
Tasks: 2 (limit: 2274)
Memory: 812.0K
CGroup: /system.slice/sslh.service
├─823 /usr/sbin/sslh –foreground ”–user sslh –listen 443 –ssh 22 –tls 4>
└─824 /usr/sbin/sslh –foreground ”–user sslh –listen 443 –ssh 22 –tls 4>



root@gemini:/etc# netstat -tulpn | grep sslh
tcp 0 0* LISTEN 823/sslh




A Note Regarding Apache and sslh


Note also that some programs, such as Lets Encrypt’s SSL Certbot SSL certificate sourcing program automatically define the https port as the default 443, so you then need to remove this and set it to 444, otherwise apache will not start.


Apache ports.conf needs to look like this. Note that port 443 is not used:


root@gemini:/etc/apache2# cat ports.conf
# 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 mod_ssl.c>
#Listen 443
Listen 444


The sites-enabled will also use 444 instead of 443 for virtual host definitions:



DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined


Include /etc/letsencrypt/options-ssl-apache.conf


SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/





Table of Contents