Compare commits

...
4 Commits
Author SHA1 Message Date
Yves Rutschle 44f02ddf39 v1.7: 01FEB2010
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).
2013-07-10 23:11:40 +02:00
Yves Rutschle 0658982705 v1.6: 25APR2009
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!)
2013-07-10 23:10:43 +02:00
Yves Rutschle b965d735b8 v1.5: 10DEC2008
Fixed zombie generation.
        Added support scripts (), Makefile.
        Changed all 'connexions' to 'connections' to please
        pesky users. Damn users.
2013-07-10 23:09:40 +02:00
Yves Rutschle 3386a64a4d v1.3 2013-07-10 23:07:49 +02:00
8 changed files with 647 additions and 77 deletions

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
v1.7: 01FEB2010
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).
v1.6: 25APR2009
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!)
v1.5: 10DEC2008
Fixed zombie generation.
Added support scripts (), Makefile.
Changed all 'connexions' to 'connections' to please
pesky users. Damn users.
v1.4: 13JUL2008
Added libwrap support for ssh service (Christian Weinberger)
Only SSH is libwraped, not SSL.
v1.3: 14MAY2008
Added parsing for local interface to listen on
Changed default SSL connection to port 442 (443 doesn't make
sense as a default as we're already listening on 443)
Syslog incoming connections
v1.2: 12MAY2008
Fixed compilation warning for AMD64 (Thx Daniel Lange)
v1.1: 21MAY2007
Making sslhc more like a real daemon:
* If $PIDFILE is defined, write first PID to it upon startup
* Fork at startup (detach from terminal)
(thanks to http://www.enderunix.org/docs/eng/daemon.php -- good checklist)
* Less memory usage (?)
v1.0:
Basic functionality: privilege dropping, target hostnames and ports
configurable.
+49
View File
@@ -0,0 +1,49 @@
# Configuration
VERSION="v1.7a"
USELIBWRAP=1 # Use libwrap?
PREFIX=/usr/local
MAN=sslh.8.gz # man page name
# End of configuration -- the rest should take care of
# itself
CC = gcc
CFLAGS=-Wall
#LIBS=-lnet
LIBS=
ifneq ($(strip $(USELIBWRAP)),)
LIBS:=$(LIBS) -lwrap
CFLAGS:=$(CFLAGS) -DLIBWRAP
endif
all: sslh $(MAN)
sslh: sslh.c Makefile
$(CC) $(CFLAGS) -D'VERSION=$(VERSION)' -o sslh sslh.c $(LIBS)
strip sslh
$(MAN): sslh.pod Makefile
pod2man --section=8 --release=$(VERSION) --center=" " sslh.pod | gzip -9 - > $(MAN)
# generic install: install binary and man page
install: sslh $(MAN)
install -D sslh $(PREFIX)/sbin/sslh
install -D -m 0644 $(MAN) $(PREFIX)/share/man/man8/$(MAN)
# "extended" install for Debian: install startup script
install-debian: install sslh $(MAN)
sed -e "s+^PREFIX=+PREFIX=$(PREFIX)+" scripts/etc.init.d.sslh > /etc/init.d/sslh
chmod 755 /etc/init.d/sslh
cp scripts/etc.default.sslh /etc/default/sslh
update-rc.d sslh defaults
uninstall:
rm -f $(PREFIX)/sbin/sslh $(PREFIX)/share/man/man8/$(MAN) /etc/init.d/sslh /etc/default/sslh
update-rc.d sslh remove
clean:
rm -f sslh $(MAN)
+115
View File
@@ -0,0 +1,115 @@
===== sslh -- A ssl/ssh multiplexer. =====
sslh lets one accept both HTTPS and SSH connections on the
same port. It makes it possible to connect to an SSH server
on port 443 (e.g. from inside a corporate firewall) while
still serving HTTPS on that port.
==== Compile and install ====
If you're lucky, the Makefile will work for you:
make install
(see below for configuration hints)
Otherwise:
Compilation instructions (the binary produced won't contain
the version number, which is stored only in the Makefile)
Solaris:
cc -o sslh sslh.c -lresolv -lsocket -lnsl
LynxOS:
gcc -o tcproxy tcproxy.c -lnetinet
Linux:
cc -o sslh sslh.c -lnet
or:
cc -o sslh sslh.c
To compile with libwrap support:
cc -o sslh -DLIBWRAP sslh.c -lwrap
To install:
make
cp sslh /usr/local/sbin
cp scripts/etc.default.sslh /etc/default/sslh
For Debian:
cp scripts/etc.init.d.sslh /etc/init.d/sslh
For CentOS:
cp scripts/etc.rc.d.init.d.sslh /etc/rc.d/init.d/sslh
and probably create links in /etc/rc<x>.d so that the server
start automatically at boot-up, e.g. under Debian:
update-rc.d sslh defaults
==== Configuration ====
You can edit settings in /etc/default/sslh:
LISTEN=ifname:443
SSH=localhost:22
SSL=localhost:443
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 optionnaly 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 reportedly take more than one second between
the time the TCP connexion is established and the time they
send the first data packet. This results in sslh with
default settings timing out and assuming an SSH connexion.
To support OpenVPN connexions reliably, it is necessary to
increase sslh's timeout to 5 seconds.
==== IP_TPROXY support ====
There is a netfilter patch that adds an option to the Linux
TCP/IP stack to allow a program to set the source address
of an IP packet that it sends. This could let sslh set the
address of packets to that of the actual client, so that
sshd would see and log the IP address of the client, making
sslh transparent.
This is not, and won't be, implemented in sslh for the
following reasons (in increasing order of importance):
* It's not vital: the real connecting IP address can be
found in logs. Little gain.
* It's Linux only: it means increased complexity for no
gain to some users.
* It's a patch: it means it'd only be useful to Linux
users who compile their own kernel.
* Only root can use the feature: that's a definite no-no.
Sslh should not, must not, will never run as root.
This isn't to mean that it won't eventually get implemented,
when/if the feature finds its way into the main kernel and
it becomes usuable by non-root processes.
Comments? questions? sslh@rutschle.net
+3
View File
@@ -0,0 +1,3 @@
LISTEN=ifname:443
SSH=localhost:22
SSL=localhost:443
+62
View File
@@ -0,0 +1,62 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: sslh
# Default-Start: 2 3 4 5
# Default-Stop: 1
# Short-Description: sslh proxy ssl & ssh connections
### END INIT INFO
set -e
tag=sslh
facility=user.info
# /etc/init.d/sslh: start and stop the sslh proxy daemon
# Defaults -- can be overridden in /etc/default/sslh
LISTEN=thelonious:443
SSH=localhost:22
SSL=localhost:443
if test -f /etc/default/sslh; then
. /etc/default/sslh
fi
# The prefix is normally filled by make install. If
# installing by hand, fill it in yourself!
PREFIX=
DAEMON=$PREFIX/sbin/sslh
start()
{
echo "Start services: sslh"
$DAEMON -u nobody -p ${LISTEN} -s ${SSH} -l ${SSL}
logger -t ${tag} -p ${facility} -i 'Started sslh'
}
stop()
{
echo "Stop services: sslh"
killall $DAEMON
logger -t ${tag} -p ${facility} -i 'Stopped sslh'
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 5
start
;;
*)
echo "Usage: /etc/init.d/sslh {start|stop|restart}" >&2
;;
esac
exit 0
+77
View File
@@ -0,0 +1,77 @@
#!/bin/bash
#
# /etc/rc.d/init.d/sslh
# sslh This shell script takes care of starting and stopping
# sslh - a daemon switching incoming connection between SSH and SSL/HTTPS servers
#
# Author: Andre Krajnik akrajnik@gmail.com
#
# chkconfig: 2345 13 87
# description: sslh - a daemon switching incoming connection between SSH and SSL/HTTPS servers
# Source function library.
. /etc/init.d/functions
# ./sslh -p 0.0.0.0:8443 -l 127.0.0.1:443 -s 127.0.0.1:22
SSLH='/usr/local/sbin/sslh'
PIDFILE='/var/run/sslh'
OPTIONS='-p 0.0.0.0:8443 -l 127.0.0.1:443 -s 127.0.0.1:22 -P $PIDFILE'
if [ -f /etc/sysconfig/sslh ]; then
. /etc/sysconfig/sslh
fi
start() {
echo -n "Starting SSL-SSH-Switch: "
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
echo sslh already running: $PID
exit 2;
elif [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
echo sslh already running: $PID
exit 2;
else
cd $SLAPD_DIR
daemon $SSLH $OPTIONS
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch $PIDFILE
return $RETVAL
fi
}
stop() {
echo -n "Shutting down SSL-SSH-Switch: "
echo
killproc sslh
echo
rm -f $PIDFILE
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status sslh
;;
restart)
stop
start
;;
*)
echo "Usage: {start|stop|status|restart}"
exit 1
;;
esac
exit $?
+143 -77
View File
@@ -18,36 +18,9 @@
# The full text for the General Public License is here:
# http://www.gnu.org/licenses/gpl.html
Comments? questions? sslh@rutschle.net
Compilation instructions:
Solaris:
cc -o sslh sslh.c -lresolv -lsocket -lnsl
LynxOS:
gcc -o tcproxy tcproxy.c -lnetinet
HISTORY
v1.2: 12MAY2008
Fixed compilation warning for AMD64 (Thx Daniel Lange)
v1.1: 21MAY2007
Making sslhc more like a real daemon:
* If $PIDFILE is defined, write first PID to it upon startup
* Fork at startup (detach from terminal)
(thanks to http://www.enderunix.org/docs/eng/daemon.php -- good checklist)
* Less memory usage (?)
v1.0:
* Basic functionality: privilege dropping, target hostnames and ports
configurable.
*/
#define VERSION "1.2"
#define _GNU_SOURCE
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
@@ -61,6 +34,17 @@ v1.0:
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
#include <syslog.h>
#include <libgen.h>
#ifdef LIBWRAP
#include <tcpd.h>
int allow_severity =0, deny_severity = 0;
#endif
#ifndef VERSION
#define VERSION "v?"
#endif
#define CHECK_RES_DIE(res, str) \
if (res == -1) { \
@@ -69,19 +53,27 @@ if (res == -1) { \
}
#define USAGE_STRING \
"sslh v" VERSION "\n" \
"sslh " VERSION "\n" \
"usage:\n" \
"\texport PIDFILE=/var/run/sslhc.pid\n" \
"\tsslh [-t <timeout>] -u <username> -p <listenport> -s [sshhost:]port -l [sslhost:]port [-v]\n"
"\tsslh [-t <timeout>] -u <username> -p [listenaddr:]<listenport> \n" \
"\t\t-s [sshhost:]port -l [sslhost:]port [-P pidfile] [-v] [-i] [-V]\n\n" \
"-v: verbose\n" \
"-V: version\n" \
"-p: address and port to listen on. default: 0.0.0.0:443\n" \
"-s: SSH address: where to connect an SSH connection. default: localhost:22\n" \
"-l: SSL address: where to connect an SSL connection.\n" \
"-P: PID file. Default: /var/run/sslh.pid.\n" \
"-i: Run as a inetd service.\n" \
""
int verbose = 0; /* That's really quite global */
/* Starts a listening socket on specified port.
/* Starts a listening socket on specified address.
Returns file descriptor
*/
int start_listen_socket(int port)
int start_listen_socket(struct sockaddr *addr)
{
struct sockaddr_in saddr;
struct sockaddr_in *saddr = (struct sockaddr_in*)addr;
int sockfd, res, reuse;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
@@ -91,10 +83,7 @@ int start_listen_socket(int port)
res = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
CHECK_RES_DIE(res, "setsockopt");
memset(&saddr, 0, sizeof(saddr));
saddr.sin_port = htons(port);
res = bind (sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
res = bind (sockfd, (struct sockaddr*)saddr, sizeof(*saddr));
CHECK_RES_DIE(res, "bind");
res = listen (sockfd, 5);
@@ -178,10 +167,8 @@ char* sprintaddr(char* buf, size_t size, struct sockaddr* s)
/* turns a "hostname:port" string into a struct sockaddr;
sock: socket address to which to copy the addr
fullname: input string -- it gets clobbered
serv: default service/port
(defaults don't work yet)
*/
void resolve_name(struct sockaddr *sock, char* fullname, int port) {
void resolve_name(struct sockaddr *sock, char* fullname) {
struct addrinfo *addr, hint;
char *serv, *host;
int res;
@@ -191,7 +178,7 @@ void resolve_name(struct sockaddr *sock, char* fullname, int port) {
if (!sep) /* No separator: parameter is just a port */
{
serv = fullname;
fprintf(stderr, "names must be fully specified as hostname:port for the moment\n");
fprintf(stderr, "names must be fully specified as hostname:port\n");
exit(1);
}
else {
@@ -206,7 +193,7 @@ void resolve_name(struct sockaddr *sock, char* fullname, int port) {
res = getaddrinfo(host, serv, &hint, &addr);
if (res) {
fprintf(stderr, "%s\n", gai_strerror(res));
fprintf(stderr, "%s `%s'\n", gai_strerror(res), fullname);
if (res == EAI_SERVICE)
fprintf(stderr, "(Check you have specified all ports)\n");
exit(1);
@@ -215,15 +202,61 @@ void resolve_name(struct sockaddr *sock, char* fullname, int port) {
memcpy(sock, addr->ai_addr, sizeof(*sock));
}
/* syslogs who connected to where */
void log_connection(int socket, char* target)
{
struct sockaddr peeraddr;
socklen_t size = sizeof(peeraddr);
char buf[64];
int res;
res = getpeername(socket, &peeraddr, &size);
CHECK_RES_DIE(res, "getpeername");
syslog(LOG_INFO, "connection from %s forwarded to %s\n",
sprintaddr(buf, sizeof(buf), &peeraddr), target);
}
/*
* Settings that depend on the command line. That's less global than verbose * :-)
* They're set in main(), but also used in start_shoveler(), and it'd be heavy-handed
* to pass it all as parameters
*/
int timeout = 2;
int listen_port = 443;
struct sockaddr addr_listen;
struct sockaddr addr_ssl, addr_ssh;
/* libwrap (tcpd): check the ssh connection is legal. This is necessary because
* the actual sshd will only see a connection coming from localhost and can't
* apply the rules itself.
*/
void check_access_rights(int in_socket)
{
#ifdef LIBWRAP
struct sockaddr peeraddr;
socklen_t size = sizeof(peeraddr);
char addr_str[1024];
struct hostent *host;
struct in_addr addr;
int res;
res = getpeername(in_socket, &peeraddr, &size);
CHECK_RES_DIE(res, "getpeername");
inet_ntop(AF_INET, &((struct sockaddr_in*)&peeraddr)->sin_addr, addr_str, sizeof(addr_str));
addr.s_addr = inet_addr(addr_str);
host = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
if (!hosts_ctl("sshd", (host ? host->h_name : STRING_UNKNOWN), addr_str, STRING_UNKNOWN)) {
if (verbose)
fprintf(stderr, "access denied\n");
log_connection(in_socket, "access denied");
close(in_socket);
exit(0);
}
#endif
}
/* Child process that finds out what to connect to and proxies
*/
@@ -234,6 +267,7 @@ void start_shoveler(int in_socket)
struct sockaddr *saddr;
int res;
int out_socket;
char *target;
FD_ZERO(&fds);
FD_SET(in_socket, &fds);
@@ -247,15 +281,18 @@ void start_shoveler(int in_socket)
if (FD_ISSET(in_socket, &fds)) {
/* The client wrote something to the socket: it's an SSL connection */
saddr = &addr_ssl;
if (verbose)
fprintf(stderr, "Forwarding to SSL\n");
target = "SSL";
} else {
/* The client hasn't written anything and we timed out: connect to SSH */
saddr = &addr_ssh;
if (verbose)
fprintf(stderr, "Forwarding to SSH\n");
target = "SSH";
/* do hosts_access check if built with libwrap support */
check_access_rights(in_socket);
}
log_connection(in_socket, target);
/* Connect the target socket */
out_socket = socket(AF_INET, SOCK_STREAM, 0);
res = connect(out_socket, saddr, sizeof(addr_ssl));
@@ -274,25 +311,31 @@ void start_shoveler(int in_socket)
exit(0);
}
/* SIGCHLD handling:
* we need to reap our children
*/
void child_handler(int signo)
{
signal(SIGCHLD, &child_handler);
wait(NULL);
}
void setup_signals(void)
{
void* res;
int res;
struct sigaction action;
res = signal(SIGCHLD, &child_handler);
if (res == SIG_ERR) {
perror("signal");
exit(1);
}
/* Request no SIGCHLD is sent upon termination of
* the children */
memset(&action, 0, sizeof(action));
action.sa_handler = NULL;
action.sa_flags = SA_NOCLDWAIT;
res = sigaction(SIGCHLD, &action, NULL);
CHECK_RES_DIE(res, "sigaction");
}
/* Open syslog connection with appropriate banner;
* banner is made up of basename(bin_name)+"[pid]" */
void setup_syslog(char* bin_name) {
char *name1, *name2;
name1 = strdup(bin_name);
asprintf(&name2, "%s[%d]", basename(name1), getpid());
openlog(name2, LOG_CONS, LOG_AUTH);
free(name1);
/* Don't free name2, as openlog(3) uses it (at least in glibc) */
}
/* We don't want to run as root -- drop priviledges if required */
void drop_privileges(char* user_name)
@@ -312,15 +355,11 @@ void drop_privileges(char* user_name)
CHECK_RES_DIE(res, "setuid");
}
/* Writes my PID if $PIDFILE is defined */
void write_pid_file(void)
/* Writes my PID */
void write_pid_file(char* pidfile)
{
char *pidfile = getenv("PIDFILE");
FILE *f;
if (!pidfile)
return;
f = fopen(pidfile, "w");
if (!f) {
perror(pidfile);
@@ -342,7 +381,7 @@ void printsettings(void)
timeout
);
fprintf(stderr, "SSH addr: %s\n", sprintaddr(buf, sizeof(buf), &addr_ssh));
fprintf(stderr, "listening on port %d\n", listen_port);
fprintf(stderr, "listening on %s\n", sprintaddr(buf, sizeof(buf), &addr_listen));
}
int main(int argc, char *argv[])
@@ -356,13 +395,17 @@ int main(int argc, char *argv[])
/* Init defaults */
char *user_name = "nobody";
char listen_str[] = "0.0.0.0:443";
char ssl_str[] = "localhost:443";
char ssh_str[] = "localhost:22";
char *pid_file = "/var/run/sslh.pid";
char inetd = 0;
resolve_name(&addr_ssl, ssl_str, 443);
resolve_name(&addr_ssh, ssh_str, 22);
resolve_name(&addr_listen, listen_str);
resolve_name(&addr_ssl, ssl_str);
resolve_name(&addr_ssh, ssh_str);
while ((c = getopt(argc, argv, "t:l:s:p:vu:")) != EOF) {
while ((c = getopt(argc, argv, "t:l:s:p:P:ivVu:")) != EOF) {
switch (c) {
case 't':
@@ -370,41 +413,60 @@ int main(int argc, char *argv[])
break;
case 'p':
listen_port = atoi(optarg);
resolve_name(&addr_listen, optarg);
break;
case 'l':
resolve_name(&addr_ssl, optarg, 443);
resolve_name(&addr_ssl, optarg);
break;
case 's':
resolve_name(&addr_ssh, optarg, 22);
resolve_name(&addr_ssh, optarg);
break;
case 'i':
inetd = 1;
break;
case 'v':
verbose += 1;
break;
case 'V':
printf("sslh %s\n", VERSION);
exit(0);
case 'u':
user_name = optarg;
break;
case 'P':
pid_file = optarg;
break;
default:
fprintf(stderr, USAGE_STRING);
exit(2);
}
}
if(inetd)
{
verbose = 0;
start_shoveler(0);
exit(0);
}
if (verbose)
printsettings();
setup_signals();
listen_socket = start_listen_socket(listen_port);
listen_socket = start_listen_socket(&addr_listen);
if (fork() > 0) exit(0); /* Detach */
write_pid_file();
write_pid_file(pid_file);
drop_privileges(user_name);
@@ -412,6 +474,9 @@ int main(int argc, char *argv[])
res = setsid();
CHECK_RES_DIE(res, "setsid: already process leader");
/* Open syslog connection */
setup_syslog(argv[0]);
/* Main server loop: accept connections, find what they are, fork shovelers */
while (1)
{
@@ -420,6 +485,7 @@ int main(int argc, char *argv[])
if (!fork())
{
close(listen_socket);
start_shoveler(in_socket);
exit(0);
}
+133
View File
@@ -0,0 +1,133 @@
# I'm just not gonna write troff :-)
=head1 NAME
sslh - ssl/ssh multiplexer
=head1 SYNOPSIS
sslh [ B<-t> I<num> ] [B<-p> I<listening address>] [B<-l> I<target address for SSL>] [B<-s> I<target address for SSH>] [B<-u> I<username>] [B<-P> I<pidfile>] [-v] [-i] [-V]
=head1 DESCRIPTION
B<sslh> lets one accept both HTTPS and SSH connections on
the same port. It makes it possible to connect to an SSH
server on port 443 (e.g. from inside a corporate firewall,
which almost never block port 443) while still serving HTTPS
on that port.
The idea is to have B<sslh> listen to the external 443 port,
accept the incoming connections, work out what type of
connection it is, and then fordward to the appropriate
server.
=head2 Protocol detection
The protocol detection is made based on a small difference
between SSL and SSH: an SSL client connecting to a server
speaks first, whereas an SSH client expects the SSH server
to speak first (announcing itself with a banner). B<sslh>
waits for some time for the incoming connection to send data.
If it does before the timeout occurs, it is supposed to be
an SSL connection. Otherwise, it is supposed to be an SSH
connection.
=head2 Libwrap support
One drawback of B<sslh> is that the B<ssh> and B<httpd>
servers do not see the original IP address of the client
anymore, as the connection is forwarded through B<sslh>.
B<sslh> provides enough logging to circumvent that problem.
However it is common to limit access to B<ssh> using
B<libwrap> or B<tcpd>. For this reason, B<sslh> can be
compiled to check SSH accesses against SSH access lists as
defined in F</etc/hosts.allow> and F</etc/hosts.deny>.
=head1 OPTIONS
=over 4
=item B<-t> I<num>
Timeout before a connection is considered to be SSH. Default
is 2s.
=item B<-p> I<listening address>
Interface and port on which to listen, e.g. I<foobar:443>,
where I<foobar> is the name of an interface (typically the
IP address on which the Internet connection ends up).
Defaults to I<0.0.0.0:443> (listen to port 443 on all
available interfaces).
=item B<-l> I<target address for SSL>
Interface and port on which to forward SSL connection,
typically I<localhost:443>.
Defaults to I<localhost:443> (this assumes you would
configure your B<httpd> process to listen to port 443).
Note that you can set B<sslh> to listen on I<ext_ip:443> and
B<httpd> to listen on I<localhost:443>: this allows clients
inside your network to just connect directly to B<httpd>.
=item B<-s> I<target address for SSH>
Interface and port on which to forward SSH connection,
defaults to I<localhost:22>.
=item B<-v>
Increase verboseness.
=item B<-V>
Prints B<sslh> version.
=item B<-u> I<username>
Requires to run under the specified username. Defaults to
I<nobody> (which is not perfect -- ideally B<sslh> should
run under its own UID).
=item B<-P> I<pidfile>
Specifies the file in which to write the PID of the main
server. Defaults to I</var/run/sslh.pid>.
=item B<-i>
Runs as an I<inetd> server. Options B<-P> (PID file), B<-p>
(listen address), B<-U> (user) are ignored.
=back
=head1 FILES
=over 4
=item F</etc/init.d/sslh>
Start-up script. The standard actions B<start>, B<stop> and
B<restart> are supported.
=item F</etc/default/sslh>
Server configuration. These are environment variables
loaded by the start-up script and passed to B<sslh> as
command-line arguments. Refer to the OPTIONS section for a
detailed explanation of the variables used by B<sslh>.
=back
=head1 SEE ALSO
Last version available from
L<http://www.rutschle.net/tech/sslh>, and can be tracked
from L<http://freshmeat.net/projects/sslh/>.
=head1 AUTHOR
Written by Yves Rutschle