# This file is provided as documentation to show what is
# possible. It should not be used as-is, and probably should
# not be used as a starting point for a working
# configuration. Instead use basic.cfg.

foreground: true;
inetd: false;
numeric: false;
transparent: false;
timeout: 2;
user: "nobody";
pidfile: "/var/run/sslh.pid";
chroot: "/var/empty";

# Logging configuration
# Value: 1: stdout; 2: syslog; 3: stdout+syslog; 4: logfile; ...; 7: all
# Defaults are indicated here, and should be sensible. Generally, you want *-error
# to be always enabled, to know if something is going wrong.
# Each option relates to a different set of messages.
verbose-config: 0; #  print configuration at startup
verbose-config-error: 3;  # print configuration errors
verbose-connections: 3; # trace established incoming address to forward address
verbose-connections-error: 3; # connection errors
verbose-connections-try: 0; # connection attempts towards targets
verbose-fd: 0; # file descriptor activity, open/close/whatnot
verbose-packets: 0; # hexdump packets on which probing is done
verbose-probe-info: 0; # what's happening during the probe process
verbose-probe-error: 3; # failures and problems during probing
verbose-system-error: 3; # system call problem, i.e.  malloc, fork, failing
verbose-int-error: 3; # internal errors, the kind that should never happen

# This one is special and overrides all previous options if
# set, as a quick way to get "as much as possible"
#verbose: 3;

# Specify a path to the logfile.
#logfile: "/var/log/sslh.log"

# Specify the number of concurrent UDP connection that can
# be managed (default 1024)
udp_max_connections: 16;

# Specify which syslog facility to use (names for your
# system are usually defined in /usr/include/*/sys/syslog.h
# or equivalent)
# Default is "auth"
# "none" disables use of syslog
syslog_facility: "auth"; 

# List of interfaces on which we should listen
# Options:
listen:
(
    { host: "thelonious"; port: "443"; },
    { host: "thelonious"; port: "8080"; keepalive: true; },
    { host: "thelonious"; is_udp: true; port: "443"; },
    { host: "/tmp/unix_socket"; is_unix: true; port: ""; }
);

# List of protocols
#
# Each protocol entry consists of:
#   name: name of the probe. These are listed on the command
#   line (ssh -?), plus 'regex' and 'timeout'.

#   service: (optional) libwrap service name (see hosts_access(5))
#   host, port: where to connect when this probe succeeds
#   log_level:  0 to turn off logging
#               1 to log each incoming connection
#   keepalive:  Should TCP keepalive be on or off for that
#               connection (default is off)
#   fork: Should a new process be forked for this protocol?
#         (only useful for sslh-select)
#   tfo_ok: Set to true if the server supports TCP FAST OPEN
#   resolve_on_forward: Set to true if server address should be resolved on
#         (every) newly incoming connection (again)
#   transparent: Set to true to proxy this protocol
#         transparently (server sees the remote client IP
#         address). Same as the global option, but per-protocol
#   is_unix: [true|false] connect to a UNIX socket. The host
#         field becomes the pathname to the socket, and the port
#         field is unused (but necessary).
#   proxyprotocol: <1|2>; When connecting to the backend
#         server, a proxyprotocol header of the specified
#         version will be added, containing the client's
#         connection information.
#
#  Probe-specific options:
# (sslh will try each probe in order they are declared, and
# connect to the first that matches.)
#
#       tls:
#               sni_hostnames:  list of FQDN for that target. Each name can
#               include wildcard following glob(7) rules.

#               alpn_protocols: list of ALPN protocols for that target, see:
#               https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
#
#               if both sni_hostnames AND alpn_protocols are specified, both must match
#
#               if neither are set, it is just checked whether this is the TLS protocol or not
#
#               Obviously set the most specific probes
#               first, and if you use TLS with no ALPN/SNI
#               set it as the last TLS probe
#       regex:
#               regex_patterns: list of patterns to match for
#               that target.
#   
# You can specify several of 'regex' and 'tls'.
#
# If you want to filter on incoming IP addresses, you can
# use libwrap which will use /etc/hosts.allow and
# /etc/hosts.deny.
 
protocols:
(
     { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; 
       keepalive: true; fork: true; tfo_ok: true },

# UNIX socket to a local NGINX. The socket name is in  'host'; 'port' is necessary but not used.
     { name: "http"; is_unix: true; host: "/tmp/nginx.sock"; port: ""; },

# match BOTH ALPN/SNI
     { name: "tls"; host: "localhost"; port: "5223"; alpn_protocols: [ "xmpp-client" ]; sni_hostnames: [ "im.somethingelse.net" ]; log_level: 0; tfo_ok: true },

# just match ALPN
     { name: "tls"; host: "localhost"; port: "443"; alpn_protocols: [ "h2", "http/1.1", "spdy/1", "spdy/2", "spdy/3" ]; log_level: 0;  tfo_ok: true },
     { name: "tls"; host: "localhost"; port: "xmpp-client"; alpn_protocols: [ "xmpp-client" ];  log_level: 0; tfo_ok: true },

# just match SNI
     { name: "tls"; host: "localhost"; port: "993"; sni_hostnames: [ "mail.rutschle.net", "mail.englishintoulouse.com" ]; log_level: 0;  tfo_ok: true },
     { name: "tls"; host: "localhost"; port: "xmpp-client"; sni_hostnames: [ "im.rutschle.net", "im.englishintoulouse.com" ];  log_level: 0; tfo_ok: true },

# Let's Encrypt (tls-alpn-* challenges)
     { name: "tls"; host: "localhost"; port: "letsencrypt-client"; alpn_protocols: [ "acme-tls/1" ]; log_level: 0;},

# catch anything else TLS
     { name: "tls"; host: "localhost"; port: "443";  tfo_ok: true },

# Forward UDP 
     { name: "regex"; host: "localhost"; is_udp: true; port: "123";
                      udp_timeout: 20;  # Time after which the "connection" is forgotten
                      regex_patterns: [ "hello" ]; },
# Forward Teamspeak3 (Voice only)
     { name: "teamspeak"; host: "localhost"; is_udp: true; port: "9987"; },
# Forward IETF QUIC-50 ("Q050" -> "\x51\x30\x35\x30")
# Remember that the regex needs to be adjusted for every supported QUIC version.
     { name: "regex"; host: "localhost"; is_udp: true; port: "4433"; regex_patterns: [ "\x51\x30\x35\x30" ]; },

# Regex examples -- better use the built-in probes for real-world use!
# OpenVPN
     { name: "regex"; host: "localhost"; port: "1194"; regex_patterns: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; },
# Jabber
     { name: "regex"; host: "localhost"; port: "5222"; regex_patterns: [ "jabber" ];
       minlength: 60;  # Won't even try to match the regex if we don't have that many bytes
     },
    
# Catch-all (but better use 'anyprot')
     { name: "regex"; host: "localhost"; port: "443"; regex_patterns: [ "" ]; },

# Where to connect in case of timeout (defaults to ssh)
     { name: "timeout"; service: "daytime"; host: "localhost"; port: "daytime"; }
);

# Optionally, specify to which protocol to connect in case
# of timeout (defaults to "ssh").
# You can timeout to any arbitrary address by setting an
# entry in 'protocols' named "timeout".
# This enables you to set a tcpd service name for this
# protocol too.
on-timeout: "timeout";

