1
sslh -- A ssl/ssh multiplexer
2
=============================
4
`sslh` accepts connections on specified ports, and forwards
5
them further based on tests performed on the first data
6
packet sent by the remote client.
8
Probes for HTTP, SSL, SSH, OpenVPN, tinc, XMPP are
9
implemented, and any other protocol that can be tested using
10
a regular expression, can be recognised. A typical use case
11
is to allow serving several services on port 443 (e.g. to
12
connect to SSH from inside a corporate firewall, which
13
almost never block port 443) while still serving HTTPS on
16
Hence `sslh` acts as a protocol demultiplexer, or a
17
switchboard. Its name comes from its original function to
18
serve SSH and HTTPS on the same port.
26
`sslh` uses [libconfig](http://www.hyperrealm.com/libconfig/)
27
and [libwrap](http://packages.debian.org/source/unstable/tcp-wrappers).
29
For Debian, these are contained in packages `libwrap0-dev` and
32
For OpenSUSE, these are contained in packages libconfig9 and
33
libconfig-dev in repository
34
<http://download.opensuse.org/repositories/multimedia:/libs/openSUSE_12.1/>
36
For Fedora, you'll need packages `libconfig` and
39
yum install libconfig libconfig-devel
41
If you can't find `libconfig`, or just don't want a
42
configuration file, set `USELIBCONFIG=` in the Makefile.
47
After this, the Makefile should work:
51
There are a couple of configuration options at the beginning
54
* `USELIBWRAP` compiles support for host access control (see
55
`hosts_access(3)`), you will need `libwrap` headers and
56
library to compile (`libwrap0-dev` in Debian).
58
* `USELIBCONFIG` compiles support for the configuration
59
file. You will need `libconfig` headers to compile
60
(`libconfig8-dev` in Debian).
66
The Makefile produces two different executables: `sslh-fork`
69
* `sslh-fork` forks a new process for each incoming connection.
70
It is well-tested and very reliable, but incurs the overhead
72
If you are going to use `sslh` for a "small" setup (less than
73
a dozen ssh connections and a low-traffic https server) then
74
`sslh-fork` is probably more suited for you.
76
* `sslh-select` uses only one thread, which monitors all connections
77
at once. It is more recent and less tested, but only incurs a 16
78
byte overhead per connection. Also, if it stops, you'll lose all
79
connections, which means you can't upgrade it remotely.
80
If you are going to use `sslh` on a "medium" setup (a few thousand ssh
81
connections, and another few thousand ssl connections),
82
`sslh-select` will be better.
84
If you have a very large site (tens of thousands of connections),
85
you'll need a vapourware version that would use libevent or
95
cp sslh-fork /usr/local/sbin/sslh
96
cp scripts/etc.default.sslh /etc/default/sslh
100
cp scripts/etc.init.d.sslh /etc/init.d/sslh
104
cp scripts/etc.rc.d.init.d.sslh /etc/rc.d/init.d/sslh
107
You might need to create links in /etc/rc<x>.d so that the server
108
start automatically at boot-up, e.g. under Debian:
110
update-rc.d sslh defaults
116
You can edit settings in /etc/default/sslh:
122
A good scheme is to use the external name of the machine in
123
`$LISTEN`, and bind `httpd` to `localhost:443` (instead of all
124
binding to all interfaces): that way, HTTPS connections
125
coming from inside your network don't need to go through
126
`sslh`, and `sslh` is only there as a frontal for connections
127
coming from the internet.
129
Note that 'external name' in this context refers to the
130
actual IP address of the machine as seen from your network,
131
i.e. that that is not `127.0.0.1` in the output of
137
Sslh can optionnaly perform `libwrap` checks for the sshd
138
service: because the connection to `sshd` will be coming
139
locally from `sslh`, `sshd` cannot determine the IP of the
145
OpenVPN clients connecting to OpenVPN running with
146
`-port-share` reportedly take more than one second between
147
the time the TCP connexion is established and the time they
148
send the first data packet. This results in `sslh` with
149
default settings timing out and assuming an SSH connexion.
150
To support OpenVPN connexions reliably, it is necessary to
151
increase `sslh`'s timeout to 5 seconds.
153
Instead of using OpenVPN's port sharing, it is more reliable
154
to use `sslh`'s `-o` option to get `sslh` to do the port sharing.
156
Using proxytunnel with sslh
157
---------------------------
159
If you are connecting through a proxy that checks that the
160
outgoing connection really is SSL and rejects SSH, you can
161
encapsulate all your traffic in SSL using `proxytunnel` (this
162
should work with `corkscrew` as well). On the server side you
163
receive the traffic with `stunnel` to decapsulate SSL, then
164
pipe through `sslh` to switch HTTP on one side and SSL on the
167
In that case, you end up with something like this:
169
ssh -> proxytunnel -e ----[ssh/ssl]---> stunnel ---[ssh]---> sslh --> sshd
170
Web browser -------------[http/ssl]---> stunnel ---[http]--> sslh --> httpd
172
Configuration goes like this on the server side, using `stunnel3`:
174
stunnel -f -p mycert.pem -d thelonious:443 -l /usr/local/sbin/sslh -- \
175
sslh -i --http localhost:80 --ssh localhost:22
178
* `-f` for foreground/debugging
179
* `-p` for specifying the key and certificate
180
* `-d` for specifying which interface and port
181
we're listening to for incoming connexions
182
* `-l` summons `sslh` in inetd mode.
185
* `-i` for inetd mode
186
* `--http` to forward HTTP connexions to port 80,
187
and SSH connexions to port 22.
192
On Linux (only?), you can compile sslh with `USELIBCAP=1` to
193
make use of POSIX capabilities; this will save the required
194
capabilities needed for transparent proxying for unprivileged
197
Alternatively, you may use filesystem capabilities instead
198
of starting sslh as root and asking it to drop privileges.
199
You will need `CAP_NET_BIND_SERVICE` for listening on port 443
200
and `CAP_NET_ADMIN` for transparent proxying (see
203
You can use the `setcap(8)` utility to give these capabilities
206
# setcap cap_net_bind_service,cap_net_admin+pe sslh-select
208
Then you can run sslh-select as an unpriviledged user, e.g.:
210
$ sslh-select -p myname:443 --ssh localhost:22 --ssl localhost:443
212
Caveat: `CAP_NET_ADMIN` does give sslh too many rights, e.g.
213
configuring the interface. If you're not going to use
214
transparent proxying, just don't use it (or use the libcap method).
216
Transparent proxy support
217
-------------------------
219
On Linux (only?) you can use the `--transparent` option to
220
request transparent proying. This means services behind `sslh`
221
(Apache, `sshd` and so on) will see the external IP and ports
222
as if the external world connected directly to them. This
223
simplifies IP-based access control (or makes it possible at
226
`sslh` needs extended rights to perform this: you'll need to
227
give it `CAP_NET_ADMIN` capabilities (see appropriate chapter)
228
or run it as root (but don't do that).
230
The firewalling tables also need to be adjusted as follow.
231
The example connects to HTTPS on 4443 -- adapt to your needs ;
232
I don't think it is possible to have `httpd` listen to 443 in
233
this scheme -- let me know if you manage that:
235
# iptables -t mangle -N SSLH
236
# iptables -t mangle -A OUTPUT --protocol tcp --out-interface eth0 --sport 22 --jump SSLH
237
# iptables -t mangle -A OUTPUT --protocol tcp --out-interface eth0 --sport 4443 --jump SSLH
238
# iptables -t mangle -A SSLH --jump MARK --set-mark 0x1
239
# iptables -t mangle -A SSLH --jump ACCEPT
240
# ip rule add fwmark 0x1 lookup 100
241
# ip route add local 0.0.0.0/0 dev lo table 100
243
This will only work if `sslh` does not use any loopback
244
addresses (no `127.0.0.1` or `localhost`), you'll need to use
245
explicit IP addresses (or names):
247
sslh --listen 192.168.0.1:443 --ssh 192.168.0.1:22 --ssl 192.168.0.1:4443
251
sslh --listen 192.168.0.1:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:4443
256
You can subscribe to the `sslh` mailing list here:
257
<http://rutschle.net/cgi-bin/mailman/listinfo/sslh>
259
This mailing list should be used for discussion, feature
260
requests, and will be the prefered channel for announcements.