Configuration
=============

If you use the scripts provided, sslh will get its
configuration from /etc/sslh.cfg. Please refer to
example.cfg for an overview of all the settings.

A good scheme is to use the external name of the machine in
`listen`, and bind `httpd` to `localhost:443` (instead of all
binding to all interfaces): that way, HTTPS connections
coming from inside your network don't need to go through
`sslh`, and `sslh` is only there as a frontal for connections
coming from the internet.

Note that 'external name' in this context refers to the
actual IP address of the machine as seen from your network,
i.e. that that is not `127.0.0.1` in the output of
`ifconfig(8)`.

Libwrap support
---------------

Sslh can optionally perform `libwrap` checks for the sshd
service: because the connection to `sshd` will be coming
locally from `sslh`, `sshd` cannot determine the IP of the
client.

OpenVPN support
---------------

OpenVPN clients connecting to OpenVPN running with
`-port-share` reportedly take more than one second between
the time the TCP connection is established and the time they
send the first data packet. This results in `sslh` with
default settings timing out and assuming an SSH connection.
To support OpenVPN connections reliably, it is necessary to
increase `sslh`'s timeout to 5 seconds.

Instead of using OpenVPN's port sharing, it is more reliable
to use `sslh`'s `--openvpn` option to get `sslh` to do the
port sharing.

Using proxytunnel with sslh
---------------------------

If you are connecting through a proxy that checks that the
outgoing connection really is SSL and rejects SSH, you can
encapsulate all your traffic in SSL using `proxytunnel` (this
should work with `corkscrew` as well). On the server side you
receive the traffic with `stunnel` to decapsulate SSL, then
pipe through `sslh` to switch HTTP on one side and SSL on the
other.

In that case, you end up with something like this:

	ssh -> proxytunnel -e ----[ssh/ssl]---> stunnel ---[ssh]---> sslh --> sshd
	Web browser -------------[http/ssl]---> stunnel ---[http]--> sslh --> httpd

Configuration goes like this on the server side, using `stunnel3`:

	stunnel -f -p mycert.pem  -d thelonious:443 -l /usr/local/sbin/sslh -- \
		sslh -i  --http localhost:80 --ssh localhost:22

* stunnel options:
  * `-f` for foreground/debugging
  * `-p` for specifying the key and certificate
  * `-d` for specifying which interface and port
	we're listening to for incoming connections
  * `-l` summons `sslh` in inetd mode.

* sslh options:
  * `-i` for inetd mode
  * `--http` to forward HTTP connections to port 80,
	and SSH connections to port 22.

Capabilities support
--------------------

On Linux (only?), you can compile sslh with `USELIBCAP=1` set 
in the Makefile to make use of POSIX capabilities; this will 
save the required capabilities needed for transparent proxying 
for unprivileged processes.

Alternatively, you may use filesystem capabilities instead
of starting sslh as root and asking it to drop privileges.
You will need `CAP_NET_BIND_SERVICE` for listening on port 443
and `CAP_NET_RAW` for transparent proxying (see
`capabilities(7)`).

You can use the `setcap(8)` utility to give these capabilities
to the executable:

	sudo setcap cap_net_bind_service,cap_net_raw+pe sslh-select

Then you can run sslh-select as an unprivileged user, e.g.:

	sslh-select -p myname:443 --ssh localhost:22 --tls localhost:443

Transparent proxy support
-------------------------

Transparent proxying is described in its own
[document](tproxy.md).

It might be easier to configure `sslh` to use Proxyprotocol
if the backend server supports it.

Systemd Socket Activation
-------------------------
If compiled with `USESYSTEMD` then it is possible to activate 
the service on demand and avoid running any code as root.

In this mode any listen configuration options are ignored and 
the sockets are passed by systemd to the service.

Example socket unit:

	[Unit]
	Before=sslh.service
	
	[Socket]
	ListenStream=1.2.3.4:443
	ListenStream=5.6.7.8:444
	ListenStream=9.10.11.12:445
	FreeBind=true

	[Install]
	WantedBy=sockets.target

Example service unit:

	[Unit]
	PartOf=sslh.socket
	
	[Service]
	ExecStart=/usr/sbin/sslh -v -f --ssh 127.0.0.1:22 --tls 127.0.0.1:443
	KillMode=process
	CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_RAW
	PrivateTmp=true
	PrivateDevices=true
	ProtectSystem=full
	ProtectHome=true
	User=sslh


With this setup only the socket needs to be enabled. The sslh service 
will be started on demand and does not need to run as root to bind the 
sockets as systemd has already bound and passed them over. If the sslh
service is started on its own without the sockets being passed by systemd
then it will look to use those defined on the command line or config
file as usual. Any number of ListenStreams can be defined in the socket
file and systemd will pass them all over to sslh to use as usual.

To avoid inconsistency between starting via socket and starting directly
via the service Requires=sslh.socket can be added to the service unit to
mandate the use of the socket configuration.

Rather than overwriting the entire socket file drop in values can be placed
in /etc/systemd/system/sslh.socket.d/<name>.conf with additional ListenStream
values that will be merged.

In addition to the above with manual .socket file configuration there is an
optional systemd generator which can be compiled - systemd-sslh-generator 

This parses the /etc/sslh.cfg (or /etc/sslh/sslh.cfg file if that exists 
instead) configuration file and dynamically generates a socket file to use.

This will also merge with any sslh.socket.d drop in configuration but will be 
overridden by a /etc/systemd/system/sslh.socket file.

To use the generator place it in /usr/lib/systemd/system-generators and then
call systemctl daemon-reload after any changes to /etc/sslh.cfg to generate 
the new dynamic socket unit.

Fail2ban
--------

If using transparent proxying, just use the standard ssh
rules. If you can't or don't want to use transparent
proxying, you can set `fail2ban` rules to block repeated ssh
connections from an IP address (obviously this depends
on the site, there might be legitimate reasons you would get
many connections to ssh from the same IP address...)

See example files in scripts/fail2ban.

UDP
---

`sslh` can perform demultiplexing on UDP packets as well.
This does not work with `sslh-fork` (it is not possible to
support UDP with a forking model). Specify a listening
address and target protocols with `is_udp: true`. `sslh`
will wait for incoming UDP packets, run the probes in the
usual fashion, and forward packets to the appropriate
target. `sslh` will then remember the association between
remote host to target server for 60 seconds by default,
which can be overridden with `udp_timeout`. This allows to
process both single-datagram protocols such as DNS, and
connection-based protocols such as QUIC.

An example for supporting QUIC is shown in `example.cfg`.


Limiting file descriptor consumption
------------------------------------

There are various mechanisms to limit the number of
concurrent connections, which allows to limit the usage of
file descriptor. This is described in a separate
[guide](max_connections.md).
