git ssb

0+

cel / sslh



Commit 0658982705270b6f79c5387db43e95e7c1f67465

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!)
Yves Rutschle committed on 7/10/2013, 9:10:43 PM
Parent: b965d735b8cede5dfc93947da5c59e562aceb559

Files changed

Makefilechanged
READMEchanged
scripts/etc.default.sslhchanged
scripts/etc.init.d.sslhchanged
sslh.cchanged
sslh.podadded
MakefileView
@@ -1,23 +1,49 @@
11 # Configuration
22
3+VERSION="v1.6i"
34 USELIBWRAP=1 # Use libwrap?
5+PREFIX=/usr/local
46
7+MAN=sslh.8.gz # man page name
58
69 # End of configuration -- the rest should take care of
710 # itself
811
912 CC = gcc
13+CFLAGS=-Wall
1014
1115 #LIBS=-lnet
1216 LIBS=
1317
1418 ifneq ($(strip $(USELIBWRAP)),)
1519 LIBS:=$(LIBS) -lwrap
16- CFLAGS=-DLIBWRAP
20+ CFLAGS:=$(CFLAGS) -DLIBWRAP
1721 endif
1822
19-all:
20- $(CC) $(CFLAGS) -o sslh sslh.c $(LIBS)
23+all: sslh $(MAN)
24+
25+sslh: sslh.c Makefile
26+ $(CC) $(CFLAGS) -D'VERSION=$(VERSION)' -o sslh sslh.c $(LIBS)
2127 strip sslh
2228
29+$(MAN): sslh.pod Makefile
30+ pod2man --section=8 --release=$(VERSION) --center=" " sslh.pod | gzip -9 - > $(MAN)
2331
32+# generic install: install binary and man page
33+install: sslh $(MAN)
34+ install -D sslh $(PREFIX)/sbin/sslh
35+ install -D -m 0644 $(MAN) $(PREFIX)/share/man/man8/$(MAN)
36+
37+# "extended" install for Debian: install startup script
38+install-debian: install sslh $(MAN)
39+ sed -e "s+^PREFIX=+PREFIX=$(PREFIX)+" scripts/etc.init.d.sslh > /etc/init.d/sslh
40+ chmod 755 /etc/init.d/sslh
41+ cp scripts/etc.default.sslh /etc/default/sslh
42+ update-rc.d sslh defaults
43+
44+uninstall:
45+ rm -f $(PREFIX)/sbin/sslh $(PREFIX)/share/man/man8/$(MAN) /etc/init.d/sslh /etc/default/sslh
46+ update-rc.d sslh remove
47+
48+clean:
49+ rm -f sslh $(MAN)
READMEView
@@ -1,12 +1,22 @@
1-sslh -- A ssl/ssh multiplexer.
1+===== sslh -- A ssl/ssh multiplexer. =====
22
33 sslh lets one accept both HTTPS and SSH connections on the
44 same port. It makes it possible to connect to an SSH server
55 on port 443 (e.g. from inside a corporate firewall) while
66 still serving HTTPS on that port.
77
8+==== Compile and install ====
89
10+If you're lucky, the Makefile will work for you:
11+
12+make install
13+
14+(see below for configuration hints)
15+
16+
17+Otherwise:
18+
919 Compilation instructions:
1020
1121 Solaris:
1222 cc -o sslh sslh.c -lresolv -lsocket -lnsl
@@ -28,21 +38,32 @@
2838 cp sslh /usr/local/sbin
2939 cp scripts/etc.init.d.sslh /etc/init.d/sslh
3040 cp scripts/etc.default.sslh /etc/default/sslh
3141
42+and probably create links in /etc/rc<x>.d so that the server
43+start automatically at boot-up, e.g. under Debian:
44+update-rc.d sslh defaults
45+
46+
47+
48+==== Configuration ====
49+
3250 You can edit settings in /etc/default/sslh:
3351
34-PIDFILE=/var/run/sslh.pid
3552 LISTEN=ifname:443
3653 SSH=localhost:22
3754 SSL=localhost:443
3855
3956 A good scheme is to use the external name of the machine in
40-$LISTEN, and bind httpd to localhost:443: that way, https
41-connections coming from inside your network don't need to go
42-through sslh, and sslh is only there as a frontal for
43-connections coming from the internet.
57+$LISTEN, and bind httpd to localhost:443 (instead of all
58+binding to all interfaces): that way, https connections
59+coming from inside your network don't need to go through
60+sslh, and sslh is only there as a frontal for connections
61+coming from the internet.
4462
63+
64+==== Libwrap support ====
65+
4566 Sslh can optionnaly perform libwrap checks for the sshd
4667 service: because the connection to sshd will be coming
4768 locally from sslh, sshd cannot determine the IP of the
4869 client.
@@ -50,8 +71,19 @@
5071 Comments? questions? sslh@rutschle.net
5172
5273 HISTORY
5374
75+v1.6: 25APR2009
76+ Added -V, version option.
77+ Install target directory configurable in Makefile
78+ Changed syslog prefix in auth.log to "sslh[%pid]"
79+ Man page
80+ new 'make install' and 'make install-debian' targets
81+ PID file now specified using -P command line option
82+ Actually fixed zombie generation (the v1.5 patch got
83+ lost, doh!)
84+
85+
5486 v1.5: 10DEC2008
5587 Fixed zombie generation.
5688 Added support scripts (), Makefile.
5789 Changed all 'connexions' to 'connections' to please
scripts/etc.default.sslhView
@@ -1,4 +1,3 @@
1-PIDFILE=/var/run/sslh.pid
21 LISTEN=ifname:443
32 SSH=localhost:22
43 SSL=localhost:443
scripts/etc.init.d.sslhView
@@ -13,19 +13,20 @@
1313
1414 # /etc/init.d/sslh: start and stop the sslh proxy daemon
1515
1616 # Defaults -- can be overridden in /etc/default/sslh
17-PIDFILE=/var/run/sslh.pid
1817 LISTEN=thelonious:443
1918 SSH=localhost:22
2019 SSL=localhost:443
2120
2221 if test -f /etc/default/sslh; then
2322 . /etc/default/sslh
24- export PIDFILE=${PIDFILE}
2523 fi
2624
27-DAEMON=/usr/local/sbin/sslh
25+# The prefix is normally filled by make install. If
26+# installing by hand, fill it in yourself!
27+PREFIX=
28+DAEMON=$PREFIX/sbin/sslh
2829
2930 start()
3031 {
3132 echo "Start services: sslh"
sslh.cView
@@ -19,10 +19,9 @@
1919 # http://www.gnu.org/licenses/gpl.html
2020
2121 */
2222
23-#define VERSION "1.5"
24-
23+#define _GNU_SOURCE
2524 #include <sys/types.h>
2625 #include <fcntl.h>
2726 #include <string.h>
2827 #include <unistd.h>
@@ -35,8 +34,9 @@
3534 #include <arpa/inet.h>
3635 #include <netdb.h>
3736 #include <pwd.h>
3837 #include <syslog.h>
38+#include <libgen.h>
3939
4040 #ifdef LIBWRAP
4141 #include <tcpd.h>
4242 int allow_severity =0, deny_severity = 0;
@@ -49,17 +49,18 @@
4949 exit(1); \
5050 }
5151
5252 #define USAGE_STRING \
53-"sslh v" VERSION "\n" \
53+"sslh " VERSION "\n" \
5454 "usage:\n" \
55-"\texport PIDFILE=/var/run/sslhc.pid\n" \
5655 "\tsslh [-t <timeout>] -u <username> -p [listenaddr:]<listenport> \n" \
57-"\t\t-s [sshhost:]port -l [sslhost:]port [-v]\n\n" \
56+"\t\t-s [sshhost:]port -l [sslhost:]port [-P pidfile] [-v] [-V]\n\n" \
5857 "-v: verbose\n" \
58+"-V: version\n" \
5959 "-p: address and port to listen on. default: 0.0.0.0:443\n" \
6060 "-s: SSH address: where to connect an SSH connection. default: localhost:22\n" \
6161 "-l: SSL address: where to connect an SSL connection.\n" \
62+"-P: PID file. Default: /var/run/sslh.pid\n" \
6263 ""
6364
6465 int verbose = 0; /* That's really quite global */
6566
@@ -187,9 +188,9 @@
187188 hint.ai_socktype = SOCK_STREAM;
188189
189190 res = getaddrinfo(host, serv, &hint, &addr);
190191 if (res) {
191- fprintf(stderr, "%s\n", gai_strerror(res));
192+ fprintf(stderr, "%s `%s'\n", gai_strerror(res), fullname);
192193 if (res == EAI_SERVICE)
193194 fprintf(stderr, "(Check you have specified all ports)\n");
194195 exit(1);
195196 }
@@ -305,28 +306,34 @@
305306
306307 exit(0);
307308 }
308309
309-/* SIGCHLD handling:
310- * we need to reap our children
311- */
312-void child_handler(int signo)
313-{
314- signal(SIGCHLD, &child_handler);
315- wait(NULL);
316-}
317310 void setup_signals(void)
318311 {
319- void* res;
312+ int res;
313+ struct sigaction action;
320314
321- res = signal(SIGCHLD, &child_handler);
322- if (res == SIG_ERR) {
323- perror("signal");
324- exit(1);
325- }
315+ /* Request no SIGCHLD is sent upon termination of
316+ * the children */
317+ memset(&action, 0, sizeof(action));
318+ action.sa_handler = NULL;
319+ action.sa_flags = SA_NOCLDWAIT;
320+ res = sigaction(SIGCHLD, &action, NULL);
321+ CHECK_RES_DIE(res, "sigaction");
326322 }
327323
324+/* Open syslog connection with appropriate banner;
325+ * banner is made up of basename(bin_name)+"[pid]" */
326+void setup_syslog(char* bin_name) {
327+ char *name1, *name2;
328328
329+ name1 = strdup(bin_name);
330+ asprintf(&name2, "%s[%d]", basename(name1), getpid());
331+ openlog(name2, LOG_CONS, LOG_AUTH);
332+ free(name1);
333+ /* Don't free name2, as openlog(3) uses it (at least in glibc) */
334+}
335+
329336 /* We don't want to run as root -- drop priviledges if required */
330337 void drop_privileges(char* user_name)
331338 {
332339 int res;
@@ -344,16 +351,12 @@
344351 CHECK_RES_DIE(res, "setuid");
345352 }
346353
347354 /* Writes my PID if $PIDFILE is defined */
348-void write_pid_file(void)
355+void write_pid_file(char* pidfile)
349356 {
350- char *pidfile = getenv("PIDFILE");
351357 FILE *f;
352358
353- if (!pidfile)
354- return;
355-
356359 f = fopen(pidfile, "w");
357360 if (!f) {
358361 perror(pidfile);
359362 exit(1);
@@ -390,14 +393,15 @@
390393 char *user_name = "nobody";
391394 char listen_str[] = "0.0.0.0:443";
392395 char ssl_str[] = "localhost:442";
393396 char ssh_str[] = "localhost:22";
397+ char *pid_file = "/var/run/sslh.pid";
394398
395399 resolve_name(&addr_listen, listen_str);
396400 resolve_name(&addr_ssl, ssl_str);
397401 resolve_name(&addr_ssh, ssh_str);
398402
399- while ((c = getopt(argc, argv, "t:l:s:p:vu:")) != EOF) {
403+ while ((c = getopt(argc, argv, "t:l:s:p:P:vVu:")) != EOF) {
400404 switch (c) {
401405
402406 case 't':
403407 timeout = atoi(optarg);
@@ -418,12 +422,20 @@
418422 case 'v':
419423 verbose += 1;
420424 break;
421425
426+ case 'V':
427+ printf("sslh %s\n", VERSION);
428+ exit(0);
429+
422430 case 'u':
423431 user_name = optarg;
424432 break;
425433
434+ case 'P':
435+ pid_file = optarg;
436+ break;
437+
426438 default:
427439 fprintf(stderr, USAGE_STRING);
428440 exit(2);
429441 }
@@ -437,18 +449,18 @@
437449 listen_socket = start_listen_socket(&addr_listen);
438450
439451 if (fork() > 0) exit(0); /* Detach */
440452
441- write_pid_file();
453+ write_pid_file(pid_file);
442454
443455 drop_privileges(user_name);
444456
445457 /* New session -- become group leader */
446458 res = setsid();
447459 CHECK_RES_DIE(res, "setsid: already process leader");
448460
449461 /* Open syslog connection */
450- openlog(argv[0], LOG_CONS, LOG_AUTH);
462+ setup_syslog(argv[0]);
451463
452464 /* Main server loop: accept connections, find what they are, fork shovelers */
453465 while (1)
454466 {
sslh.podView
@@ -1,0 +1,128 @@
1+# I'm just not gonna write troff :-)
2+
3+=head1 NAME
4+
5+ sslh - ssl/ssh multiplexer
6+
7+=head1 SYNOPSIS
8+
9+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] [-V]
10+
11+=head1 DESCRIPTION
12+
13+B<sslh> lets one accept both HTTPS and SSH connections on
14+the same port. It makes it possible to connect to an SSH
15+server on port 443 (e.g. from inside a corporate firewall,
16+which almost never block port 443) while still serving HTTPS
17+on that port.
18+
19+The idea is to have B<sslh> listen to the external 443 port,
20+accept the incoming connections, work out what type of
21+connection it is, and then fordward to the appropriate
22+server.
23+
24+=head2 Protocol detection
25+
26+The protocol detection is made based on a small difference
27+between SSL and SSH: an SSL client connecting to a server
28+speaks first, whereas an SSH client expects the SSH server
29+to speak first (announcing itself with a banner). B<sslh>
30+waits for some time for the incoming connection to send data.
31+If it does before the timeout occurs, it is supposed to be
32+an SSL connection. Otherwise, it is supposed to be an SSH
33+connection.
34+
35+=head2 Libwrap support
36+
37+One drawback of B<sslh> is that the B<ssh> and B<httpd>
38+servers do not see the original IP address of the client
39+anymore, as the connection is forwarded through B<sslh>.
40+B<sslh> provides enough logging to circumvent that problem.
41+However it is common to limit access to B<ssh> using
42+B<libwrap> or B<tcpd>. For this reason, B<sslh> can be
43+compiled to check SSH accesses against SSH access lists as
44+defined in F</etc/hosts.allow> and F</etc/hosts.deny>.
45+
46+=head1 OPTIONS
47+
48+=over 4
49+
50+=item B<-t> I<num>
51+
52+Timeout before a connection is considered to be SSH. Default
53+is 2s.
54+
55+=item B<-p> I<listening address>
56+
57+Interface and port on which to listen, e.g. I<foobar:443>,
58+where I<foobar> is the name of an interface (typically the
59+IP address on which the Internet connection ends up).
60+
61+Defaults to I<0.0.0.0:443> (listen to port 443 on all
62+available interfaces).
63+
64+=item B<-l> I<target address for SSL>
65+
66+Interface and port on which to forward SSL connection,
67+typically I<localhost:443>.
68+
69+Defaults to I<localhost:442> (this assumes you would
70+configure your B<httpd> process to listen to port 443).
71+
72+Note that you can set B<sslh> to listen on I<ext_ip:443> and
73+B<httpd> to listen on I<localhost:443>: this allows clients
74+inside your network to just connect directly to B<httpd>.
75+
76+=item B<-s> I<target address for SSH>
77+
78+Interface and port on which to forward SSH connection,
79+defaults to I<localhost:22>.
80+
81+=item B<-v>
82+
83+Increase verboseness.
84+
85+=item B<-V>
86+
87+Prints B<sslh> version.
88+
89+=item B<-u> I<username>
90+
91+Requires to run under the specified username. Defaults to
92+I<nobody> (which is not perfect -- ideally B<sslh> should
93+run under its own UID).
94+
95+=item B<-P> I<pidfile>
96+
97+Specifies the file in which to write the PID of the main
98+server. Defaults to I</var/run/sslh.pid>.
99+
100+=back
101+
102+=head1 FILES
103+
104+=over 4
105+
106+=item F</etc/init.d/sslh>
107+
108+Start-up script. The standard actions B<start>, B<stop> and
109+B<restart> are supported.
110+
111+=item F</etc/default/sslh>
112+
113+Server configuration. These are environement variables
114+loaded by the start-up script and passed to B<sslh> as
115+command-line arguments. Refer to the OPTIONS section for a
116+detailed explanation of the variables used by B<sslh>.
117+
118+=back
119+
120+=head1 SEE ALSO
121+
122+Last version available from
123+L<http://www.rutschle.net/tech/sslh>, and can be tracked
124+from L<http://freshmeat.net/projects/sslh/>.
125+
126+=head1 AUTHOR
127+
128+Written by Yves Rutschle

Built with git-ssb-web