Skip to content

Commit

Permalink
v1.14: 21DEC2012
Browse files Browse the repository at this point in the history
	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
	(Thomas Varis).
  • Loading branch information
yrutschle committed Jul 10, 2013
1 parent 5cd1fa1 commit f842e2e
Show file tree
Hide file tree
Showing 15 changed files with 358 additions and 161 deletions.
25 changes: 25 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
v1.14: 21DEC2012
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
(Thomas Varis).

v1.13: 18MAY2012
Write PID file before dropping privileges.

Expand Down
17 changes: 12 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Configuration

VERSION="v1.13b"
VERSION="1.14"
USELIBCONFIG=1 # Use libconfig? (necessary to use configuration files)
USELIBWRAP= # Use libwrap?
COV_TEST= # Perform test coverage?
Expand All @@ -15,10 +15,10 @@ ifneq ($(strip $(COV_TEST)),)
CFLAGS_COV=-fprofile-arcs -ftest-coverage
endif

CC = gcc
CFLAGS=-Wall -g $(CFLAGS_COV)
CC ?= gcc
CFLAGS ?=-Wall -g $(CFLAGS_COV)

LIBS=
LIBS=$(LDFLAGS)
OBJS=common.o sslh-main.o probe.o

ifneq ($(strip $(USELIBWRAP)),)
Expand Down Expand Up @@ -48,11 +48,18 @@ sslh-select: $(OBJS) sslh-select.o Makefile common.h
#strip sslh-select

echosrv: $(OBJS) echosrv.o
$(CC) $(CFLAGS) -o echosrv echosrv.o common.o $(LIBS)
$(CC) $(CFLAGS) -o echosrv echosrv.o probe.o common.o $(LIBS)

$(MAN): sslh.pod Makefile
pod2man --section=8 --release=$(VERSION) --center=" " sslh.pod | gzip -9 - > $(MAN)

# Create release: export clean tree and tag current
# configuration
release:
svn export . /tmp/sslh-$(VERSION)
( cd /tmp; tar zcvf /tmp/sslh-$(VERSION).tar.gz sslh-$(VERSION) )
( cd .. ; svn copy trunk tags/sslh-$(VERSION) ; cd tags/sslh-$(VERSION) ; make clean )

# generic install: install binary and man page
install: sslh $(MAN)
install -D sslh-fork $(PREFIX)/sbin/sslh
Expand Down
32 changes: 19 additions & 13 deletions README
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
===== sslh -- A ssl/ssh multiplexer. =====

sslh accepts connections in HTTP, HTTPS, SSH, OpenVPN,
tinc, XMPP, or any other protocol that can be tested using a
regular expression, on the same port. This makes it possible
to connect to any of these servers on port 443 (e.g. from
inside a corporate firewall, which almost never block port
443) while still serving HTTPS on that port.

Sslh accepts connections on specified ports, and forwards
them further based on tests performed on the first data
packet sent by the remote client.

Probes for HTTP, SSL, SSH, OpenVPN, tinc, XMPP are
implemented, and any other protocol that can be tested using
a regular expression, can be recognised. A typical use case
is to allow serving several services on port 443 (e.g. to
connect to ssh from inside a corporate firewall, which
almost never block port 443) while still serving HTTPS on
that port.

Hence sslh acts as a protocol demultiplexer, or a
switchboard. Its name comes from its original function to
serve SSH and HTTPS on the same port.

==== Compile and install ====

Expand Down Expand Up @@ -57,7 +65,7 @@ If you are going to use sslh for a "small" setup (less than
a dozen ssh connections and a low-traffic https server) then
sslh-fork is probably more suited for you. If you are going
to use sslh on a "medium" setup (a few thousand ssh
connections, and another few thousand sslh connections),
connections, and another few thousand ssl connections),
sslh-select will be better. If you have a very large site
(tens of thousands of connections), you'll need a vapourware
version that would use libevent or something like that.
Expand Down Expand Up @@ -139,17 +147,15 @@ Web browser --------http/ssl------> stunnel ---http---> sslh --> http:80
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 --ssl localhost:80 --ssh localhost:22
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 specifies
the key + certificate, -d specifies which interface and port
we're listening to for incoming connexions, -l summons sslh
in inetd mode.

sslh options: -i for inetd mode, --ssl to forward SSL
connexions (in fact normal HTTP at that stage) to port 80,
and SSH connexions to port 22. This works because sslh
considers that any protocol it doesn't recognise is SSL.
sslh options: -i for inetd mode, --http to forward http
connexions to port 80, and SSH connexions to port 22.

==== IP_TPROXY support ====

Expand Down
28 changes: 28 additions & 0 deletions basic.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This is a basic configuration file that should provide
# sensible values for "standard" setup.

verbose: false;
foreground: false;
inetd: false;
numeric: false;
timeout: 2;
user: "nobody";
pidfile: "/var/run/sslh.pid";


# Change hostname with your external address name.
listen:
(
{ host: "thelonious"; port: "443"; }
);

protocols:
(
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; probe: "builtin"; },
{ name: "openvpn"; host: "localhost"; port: "1194"; probe: "builtin"; },
{ name: "xmpp"; host: "localhost"; port: "5222"; probe: "builtin"; },
{ name: "http"; host: "localhost"; port: "80"; probe: "builtin"; },
{ name: "ssl"; host: "localhost"; port: "443"; probe: "builtin"; },
{ name: "anyprot"; host: "localhost"; port: "443"; probe: "builtin"; }
);

5 changes: 1 addition & 4 deletions common.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int inetd = 0;
int foreground = 0;
int background = 0;
int numeric = 0;
const char *user_name, *pid_file, *rule_filename;
const char *user_name, *pid_file;

struct addrinfo *addr_listen = NULL; /* what addresses do we listen to? */

Expand Down Expand Up @@ -165,7 +165,6 @@ int flush_defered(struct queue *q)
q->defered_data_size -= n;
}


return n;
}

Expand Down Expand Up @@ -193,8 +192,6 @@ void dump_connection(struct connection *cnx)
* returns FD_NODATA if no data was available
* returns FD_STALLED if data was read, could not be written, and has been
* stored in temporary buffer.
*
* slot for debug only and may go away at some point
*/
int fd2fd(struct queue *target_q, struct queue *from_q)
{
Expand Down
2 changes: 1 addition & 1 deletion common.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ extern int probing_timeout, verbose, inetd, foreground, background, numeric;
extern struct sockaddr_storage addr_ssl, addr_ssh, addr_openvpn;
extern struct addrinfo *addr_listen;
extern const char* USAGE_STRING;
extern const char* user_name, *pid_file, *rule_filename;
extern const char* user_name, *pid_file;
extern const char* server_type;

/* sslh-fork.c */
Expand Down
24 changes: 9 additions & 15 deletions echosrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,32 +94,26 @@ void parse_cmdline(int argc, char* argv[])

void start_echo(int fd)
{
fd_set fds;
int res;
char buffer[1 << 20];
char* ret;
FILE *socket;
int ret, prefix_len;

FD_ZERO(&fds);
prefix_len = strlen(prefix);

socket = fdopen(fd, "r+");
if (!socket) {
CHECK_RES_DIE(-1, "fdopen");
}
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, prefix);

while (1) {
ret = fgets(buffer, sizeof(buffer), socket);
if (!ret) {
fprintf(stderr, "%s", strerror(ferror(socket)));
ret = read(fd, buffer + prefix_len, sizeof(buffer));
if (ret == -1) {
fprintf(stderr, "%s", strerror(errno));
return;
}
res = fprintf(socket, "%s%s", prefix, buffer);
res = write(fd, buffer, ret + prefix_len);
if (res < 0) {
fprintf(stderr, "%s", strerror(ferror(socket)));
fprintf(stderr, "%s", strerror(errno));
return;
}

fflush(socket);
}
}

Expand Down
26 changes: 19 additions & 7 deletions example.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
verbose: false;
# 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.

verbose: true;
foreground: true;
inetd: false;
numeric: false;
Expand All @@ -10,8 +15,8 @@ pidfile: "/var/run/sslh.pid";
# List of interfaces on which we should listen
listen:
(
{ host: "thelonious"; port: "443"; }
# , { host: "thelonious"; port: "8080"; }
{ host: "thelonious"; port: "443"; },
{ host: "thelonious"; port: "8080"; }
);

# List of protocols
Expand All @@ -22,10 +27,8 @@ listen:
# host: host name to connect that protocol
# port: port number to connect that protocol
# probe: "builtin" or a list of regular expressions
# (can be left out, e.g. to use with on-timeout)
#
# In case of timeout sslh will connect to the first
# protocol: this should be SSH.
# SSL should have a "always true" probe, and come last.
# sslh will try each probe in order they are declared, and
# connect to the first that matches.

Expand All @@ -35,6 +38,15 @@ protocols:
{ name: "openvpn"; host: "localhost"; port: "1194"; probe: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; },
{ name: "xmpp"; host: "localhost"; port: "5222"; probe: [ "jabber" ]; },
{ name: "http"; host: "localhost"; port: "80"; probe: "builtin"; },
{ name: "ssl"; host: "localhost"; port: "443"; probe: [ "" ]; }
{ name: "ssl"; host: "localhost"; port: "443"; probe: [ "" ]; },
{ 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 a
# protocol with no probe, as is the case with this example.
# This enables you to set a tcpd service name for this
# protocol too.
on-timeout: "timeout";

Loading

0 comments on commit f842e2e

Please sign in to comment.