Install me!

sslh has been packaged for Debian, Gentoo, FreeBSD and many other operating systems, so check out your favourite package repository before installing by hand. Do note that packaged version often are outdated, so check the change log for bug fixes and new features if you run into problems.

You can compile sslh for Cygwin 1.7 (older version will not work), or download the binary version provided below by Arnaud Gendre. You will need at least cygwin1.dll installed, and maybe the entire Cygwin package.

Mailing list

Announcements of new versions will be posted on the sslh mailing list. This list can also be used to discuss usage, request features and so on. Traffic is expected to be low (a dozen mail a year on average). It will be further split into a “discussion” list and an “announcement” list if required.

Git repository

sslh is managed in Git and pushed to Github. Patches and new features will be pushed there, probably long before they make it into actual releases…

Tags are normally all signed off using my public key, which you should also be able to get from your neighbourhood key server.

Get it!

sslh 2.1.2 [asc]

  • Fix inetd and various minor bugs

  • Support for the Landlock LSM. After initial setup, sslh gives up all local file access rights.

  • Reintroduced –ssl as an alias to –tls.

  • Introduce autoconf to adapt to landlock presence. (./configure to have a Makefile).

  • Close connexion without error message if remote client forcefully closes connexion, for Windows.

sslh 2.0.1 [asc]

  • New semver-compatible version number

  • New sslh-ev: this is functionaly equivalent to sslh-select (mono-process, only forks for specified protocols), but based on libev, which should make it scalable to large numbers of connections.

  • New log system: instead of –verbose with arbitrary levels, there are now several message classes. Each message class can be set to go to stderr, syslog, or both. Classes are documented in example.cfg.

  • UDP connections are now managed in a hash to avoid linear searches. The downside is that the number of UDP connections is a hard limit, configurable with the ‘udp_max_connections’, which defaults to 1024. Timeouts are managed with lists.

  • inetd merges stderr output to what is sent to the client, which is a security issue as it might give information to an attacker. When inetd is activated, stderr is forcibly closed.

  • New protocol-level option resolve_on_forward, requests that target names are resolved at each connection instead of at startup. Useful for dynamic DNS situations. (Paul Schroeder/milkpirate)

WARNING: v2.0-rc contains a vulnerability CVE-2022-4639. Do not use it.

sslh 1.23.1 [asc]

  • Re-introduce --ssl as alias to --tls.
  • Bug fix: Check accept() for failure in sslh-fork. Aborted connections otherwise result in crashes.

sslh 1.22c [asc]

  • sslh-select now supports UDP protocols. Probes specified in the protocols configuration entry are tried on incoming packets, TCP or UDP, and forwarded based on the input protocol (an incoming TCP connection will be forwarded as TCP, and same with UDP). This has been tested with DNS as shown in udp.cfg: incoming packets that contain my domain name are assumed to be a DNS request and forwarded accordingly. Note this could cause problems if combined with incoming TLS with SNI. UDP clients and servers need to agree on the IPv4/IPv6 they use: use the same protocol on all sides! Often, this means explicitely using ‘ip4-localhost’. UDP sender-receiver pairs (connections, so to speak) are kept for 60s, which can be changed with udp_timeout in the configuration.

  • Added probes for UDP protocols QUICK and Teamspeak.

  • Added probes for syslog protocol.

  • sslh-select refactored to change linear searches through connections to linear searches through fd_set.

  • Fixed a libconfig call to support libconfig 1.7.3.

  • Added symbol to support libconfig 1.4.9, still in use in CentOS7.

  • Warn about unknown settings in the configuration file.

  • Added per-protocol transparent option. sslh-fork drops the capability after creating the server-side transparent socket. Transparent now uses CAP_NET_RAW instead of CAP_NET_ADMIN.

  • Removed compile-time option to use POSIX regex. Now regex must be PCRE2 (Perl-Compatible). This was in fact the case since v1.21, as PCRE are used to parse the config file.

sslh 1.21c [asc]

  • WARNING: Moved configuration and command-line management to use conf2struct. Changes are:
    • --ssl and using name: 'ssl' in config file is no longer supported, use tls instead.
    • command line option <-F –config> no longer defaults to /etc/sslh.cfg, so you have to specify it explicitly.
    • command line option <-v –verbose> takes a mandatory integer parameter
  • Added TCP_FASTOPEN support for client sockets (if tfo_ok is specified in their configuration) and for listenint socket, if all client protocols support it. (Craig Andrews)

  • Added ‘minlength’ option to skip a probe if less than that many bytes have been received (mostly for regex)

  • Update Let’s Encrypt entry in example.cfg for tls-alpn-01 challenges; tls-sni-* challenges are now deprecated.

  • Log to syslog even if in foreground (for people who use fail2ban)

  • Use syslog_facility: “none” to disable syslog output.

  • Changed exit code for illegal command line parameter from 1 to 6 (for testing purposes)

sslh 1.20 [asc]

  • Added support for socks5 protocol (Eugene Protozanov)
  • New probing method: Before, probes were tried in order, repeating on the same probe as long it returned PROBE_AGAIN before moving to the next one. This means a probe which requires a lot of data (i.e. returne PROBE_AGAIN for a long time) could prevent sucessful matches from subsequent probes. The configuration file needed to take that into account. Now, all probes are tried each time new data is found. If any probe matches, use it. If at least one probe requires more data, wait for more. If all probes failed, connect to the last one. So the only thing to know when writing the configuration file is that ‘anyprot’ needs to be last.
  • Test suite heavily refactored; t uses test.cfg to decide which probes to test and all setup is automatic; probes get tested with ‘fast’ (entire first message in one packet) and ‘slow’ (one byte at a time); when SNI/ALPN are defined, all combinations are tested. Old ‘tls’ probe removed, ‘sni_alpn’ probe renamed as ‘tls’. You’ll need to change ‘sni_alpn’ to ‘tls’ in your configuration file, if ever you used it.

sslh 1.19 [asc]

  • Added ‘syslog_facility’ configuration option to specify where to log.
  • TLS now supports SNI and ALPN (Travis Burtrum), including support for Let’s Encrypt challenges (Jonathan McCrohan)
  • ADB probe. (Mike Frysinger)
  • Added per-protocol ‘fork’ option. (Oleg Oshmyan)
  • Added chroot option. (Mike Frysinger)
  • A truckload of bug fixes and documentation improvements (Various contributors)

sslh 1.18 [asc]

  • Added USELIBPCRE to make use of regex engine optional.
  • Added support for RFC4366 SNI and RFC7301 ALPN (Travis Burtrum)
  • Changed connection log to include the name of the probe that triggered.
  • Changed configuration file format: ‘probe’ field is no longer required, ‘name’ field can now contain ‘tls’ or ‘regex’, with corresponding options (see example.cfg)
  • Added ‘log_level’ option to each protocol, which allows to turn off generation of log at each connection.
  • Added ‘keepalive’ option.

sslh 1.17

i686 Cygwin binary
x86_64 Cygwin binary

  • Support RFC5952-style IPv6 addresses, e.g. [::]:443.
  • Transparant proxy support for FreeBSD. (Ruben van Staveren)
  • Using -F with no argument will try /etc/sslh/sslh.cfg and then /etc/sslh.cfg as configuration files. (argument to -F can no longer be separated from the option by a space, e.g. must be -Ffoo.cfg)
  • Call setgroups() before setgid() (fixes potential privilege escalation). (Lars Vogdt)
  • Use portable way of getting modified time for OSX support. (Aaron Madlon-Kay)
  • Example configuration for fail2ban. (Every Mouw)

sslh 1.16

Cygwin binary [Includes DLLs necessary to run without a full install of Cygwin]

  • Probes made more resilient, to incoming data containing NULLs. Also made them behave properly when receiving too short packets to probe on the first incoming packet. (Ondrej Kuzník)
  • Libcap support: Keep only CAP_NET_ADMIN if started as root with transparent proxying and dropping priviledges (enable USELIBCAP in Makefile). This avoids having to mess with filesystem capabilities. (Sebastian Schmidt/yath)
  • Fixed bugs related to getpeername that would cause sslh to quit erroneously (getpeername can return actual errors if connections are dropped before getting to getpeername).
  • Set IP_FREEDBIND if available to bind to addresses that don’t yet exist.

sslh 1.15

Cygwin binary [Includes DLLs necessary to run without a full install of Cygwin]

  • Added –transparent option for transparent proxying. See README for iptables magic and capability management.
  • Fixed bug in sslh-select: if number of opened file descriptor became bigger than FD_SETSIZE, bad things would happen.
  • Fixed bug in sslh-select: if socket dropped while defered_data was present, sslh-select would crash.
  • Increased FD_SETSIZE for Cygwin, as the default 64 is too low for even moderate load. Thanks to Arnaud Gendre and Michael K. Avanessian for helping with investigation of the last three points.

sslh 1.14 (AE)

Cygwin binary [Includes an additional patch that’ll be in sslh-1.15 and Cygwin libraries]

  • Corrected OpenVPN probe to support pre-shared secret mode (OpenVPN port-sharing code is… wrong). Thanks to Kai Ellinger for help in investigating and testing.
  • Added an actual TLS/SSL probe.
  • Added configurable –on-timeout protocol specification.
  • Added a –anyprot protocol probe (equivalent to what –ssl was).
  • Makefile respects the user’s compiler and CFLAG choices (falling back to the current values if undefined), as well as LDFLAGS. (Michael Palimaka)
  • Added “After” and “KillMode” to systemd.sslh.service (Thomas Weißschuh).
  • Added LSB tags to etc.init.d.sslh (Tomas Varil).

sslh 1.13

  • Write PID file before dropping privileges.
  • Added –background, which overrides ‘foreground’ configuration file setting.
  • Added example systemd service file from Archlinux in scripts/ (Sébastien Luttringer)

sslh 1.12

  • Added support for configuration file.
  • New protocol probes can be defined using regular expressions that match the first packet sent by the client.
  • sslh now connects timed out connections to the first configured protocol instead of ‘ssh’ (just make sure ssh is the first defined protocol).
  • sslh now tries protocols in the order in which they are defined (just make sure sslh is the last defined protocol).

sslh 1.11

  • WARNING: defaults have been removed for –user and –pidfile options, update your start-up scripts!
  • No longer stop sslh when reverse DNS requests fail for logging.
  • Added HTTP probe.
  • No longer create new session if running in foreground.
  • No longer default to changing user to ‘nobody’. If –user isn’t specified, just run as current user.
  • No longer create PID file by default, it should be explicitely set with –pidfile.
  • No longer log to syslog if in foreground. Logs are instead output to stderr.
  • The four changes above make it straightforward to integrate sslh with systemd, and should help with launchd.

sslh 1.10

  • Fixed calls referring to sockaddr length so they work with FreeBSD.
  • Try target addresses in turn until one works if there are several (e.g. “localhost:22” resolves to an IPv6 address and an IPv4 address and sshd does not listen on IPv6).
  • Heavily cleaned up test suite. Added stress test t_load script. Added coverage (requires lcov).
  • Support for XMPP (Arnaud Gendre).
  • Updated README.MacOSX (Aaron Madlon-Kay).

sslh 1.9

  • WARNING: 1.9 does not currently work on FreeBSD and derivatives (such as MacOSX). The problem is identified and will be corrected shortly.
  • WARNING: Options changed, you’ll need to update your start-up scripts! Log format changed, you’ll need to update log processing scripts!
  • Now supports IPv6 throughout (both on listening and forwarding)
  • Logs now contain IPv6 addresses, local forwarding address, and resolves names (unless –numeric is specified).
  • Introduced long options.
  • Options -l, -s and -o replaced by their long counterparts.
  • Defaults for SSL and SSH options suppressed (it’s legitimate to want to use sslh to mux OpenVPN and tinc while not caring about SSH nor SSL).
  • Bind to multiple addresses with multiple -p options.
  • Support for tinc VPN (experimental).
  • Numeric logging option.

sslh 1.8

  • Changed log format to make it possible to link connections to subsequent logs from other services.
  • Added single-threaded, select(2)-based version.
  • Added -o “OpenVPN” and OpenVPN probing and support.
  • Added support for “Bold” SSH clients (clients that speak first) Thanks to Guillaume Ricaud for spotting a regression bug.
  • Updated CentOS init.d script (Andre Krajnik).
  • Fixed zombie issue with OpenBSD (The SA_NOCLDWAIT flag is not propagated to the child process, so we set up signals after the fork.) (François FRITZ)
  • Added -f “foreground” option.
  • Added test suite. (only tests connexions. No test for libwrap, setsid, setuid and so on) and corresponding ‘make test’ target.
  • Added README.MacOSX (thanks Aaron Madlon-Kay)
  • Documented use with proxytunnel and corkscrew in README.

sslh 1.7

  • Added CentOS init.d script (Andre Krajnik).
  • Fixed default ssl address inconsistancy, now defaults to “localhost:443” and fixed documentation accordingly (pointed by Markus Schalke).
  • Children no longer bind to the listen socket, so parent server can be stopped without killing an active child (pointed by Matthias Buecher).
  • Inetd support (Dima Barsky).

sslh 1.6

  • Added -V, version option.
  • Install target directory configurable in Makefile.
  • Changed syslog prefix in auth.log to “sslh[%pid]”
  • Man page
  • new ‘make install’ and ‘make install-debian’ targets
  • PID file now specified using -P command line option
  • Actually fixed zombie generation (the v1.5 patch got lost, doh!)

sslh 1.5

  • Added libwrap support for ssh service (Christian Weinberger)
  • Fixed zombie generation.
  • Added support scripts, Makefile.

sslh 1.3

  • Added parsing for local interface to listen on (e.g.: -p
  • Changed default SSL connexion to port 442 (443 doesn’t make sense as a default as we’re already listening on 443)
  • Syslog incoming connexions

sslh 1.2

  • Fixed compilation warning for AMD64.

sslh 1.1

sslh 1.0


This feature was already implemented as a Perl script which has since disappeared from CPAN. I re-implemented it because I was uncomfortable having a network service written in Perl, and because that simple script lacked too many features to be mature (e.g. privilege dropping was the first added feature, and many followed).