git ssb

0+

cel / sslh



Commit 26b4bcd089f6c3a3c43d1380969c939e600b3ef2

v1.11: 21APR2012

	WARNING: defaults have been removed for --user and
	--pidfile options, update your start-up scripts!

	No longer stop sslh when reverse DNS requests fail
	for logging.

	Added HTTP probe.

	No longer create new session if running in
	foreground.

	No longer default to changing user to 'nobody'. If
	--user isn't specified, just run as current user.

	No longer create PID file by default, it should be
	explicitely set with --pidfile.

	No longer log to syslog if in foreground. Logs are
	instead output to stderr.

	The four changes above make it straightforward to
	integrate sslh with systemd, and should help with
	launchd.
Yves Rutschle committed on 7/10/2013, 9:14:48 PM
Parent: ae008179f033c8409c69b13787a539351bace626

Files changed

ChangeLogchanged
Makefilechanged
READMEchanged
common.cchanged
scripts/etc.default.sslhchanged
scripts/etc.init.d.sslhchanged
scripts/etc.rc.d.init.d.sslh.centoschanged
sslh-fork.cchanged
sslh-main.cchanged
sslh.podchanged
ChangeLogView
@@ -1,5 +1,30 @@
1-v1.10:
1+v1.11: 21APR2012
2+ WARNING: defaults have been removed for --user and
3+ --pidfile options, update your start-up scripts!
4+
5+ No longer stop sslh when reverse DNS requests fail
6+ for logging.
7+
8+ Added HTTP probe.
9+
10+ No longer create new session if running in
11+ foreground.
12+
13+ No longer default to changing user to 'nobody'. If
14+ --user isn't specified, just run as current user.
15+
16+ No longer create PID file by default, it should be
17+ explicitely set with --pidfile.
18+
19+ No longer log to syslog if in foreground. Logs are
20+ instead output to stderr.
21+
22+ The four changes above make it straightforward to
23+ integrate sslh with systemd, and should help with
24+ launchd.
25+
26+v1.10: 27NOV2011
227 Fixed calls referring to sockaddr length so they work
328 with FreeBSD.
429
530 Try target addresses in turn until one works if
MakefileView
@@ -1,7 +1,7 @@
11 # Configuration
22
3-VERSION="v1.10"
3+VERSION="v1.11"
44 USELIBWRAP= # Use libwrap?
55 COV_TEST= # Perform test coverage?
66 PREFIX=/usr/local
77
READMEView
@@ -1,11 +1,11 @@
11 ===== sslh -- A ssl/ssh multiplexer. =====
22
3-sslh accepts HTTPS, SSH, OpenVPN, tinc and XMPP connections
4-on the same port. This makes it possible to connect to any
5-of these servers on port 443 (e.g. from inside a corporate
6-firewall, which almost never block port 443) while still
7-serving HTTPS on that port.
3+sslh accepts HTTP, HTTPS, SSH, OpenVPN, tinc and XMPP
4+connections on the same port. This makes it possible to
5+connect to any of these servers on port 443 (e.g. from
6+inside a corporate firewall, which almost never block port
7+443) while still serving HTTPS on that port.
88
99 ==== Compile and install ====
1010
1111 If you're lucky, the Makefile will work for you:
common.cView
@@ -34,8 +34,9 @@
3434 int is_ssh_protocol(const char *p, int len);
3535 int is_openvpn_protocol(const char *p, int len);
3636 int is_tinc_protocol(const char *p, int len);
3737 int is_xmpp_protocol(const char *p, int len);
38+int is_http_protocol(const char *p, int len);
3839 int is_true(const char *p, int len) { return 1; }
3940
4041 /* Table of all the protocols we know how to connect to.
4142 *
@@ -50,8 +51,9 @@
5051 { 0, "ssh", "sshd", {0}, is_ssh_protocol },
5152 { 0, "openvpn", NULL, {0}, is_openvpn_protocol },
5253 { 0, "tinc", NULL, {0}, is_tinc_protocol },
5354 { 0, "xmpp", NULL, {0}, is_xmpp_protocol },
55+ { 0, "http", NULL, {0}, is_http_protocol },
5456 /* probe for SSL always successes: it's the default, and must be tried last
5557 **/
5658 { 0, "ssl", NULL, {0}, is_true }
5759 };
@@ -337,9 +339,35 @@
337339 {
338340 return strstr(p, "jabber") ? 1 : 0;
339341 }
340342
343+int probe_http_method(const char *p, const char *opt)
344+{
345+ return !strncmp(p, opt, strlen(opt)-1);
346+}
341347
348+/* Is the buffer the beginnin of an HTTP connection? */
349+int is_http_protocol(const char *p, int len)
350+{
351+ /* If it's got HTTP in the request (HTTP/1.1) then it's HTTP */
352+ if (strstr(p, "HTTP"))
353+ return 1;
354+
355+ /* Otherwise it could be HTTP/1.0 without version: check if it's got an
356+ * HTTP method (RFC2616 5.1.1) */
357+ probe_http_method(p, "OPTIONS");
358+ probe_http_method(p, "GET");
359+ probe_http_method(p, "HEAD");
360+ probe_http_method(p, "POST");
361+ probe_http_method(p, "PUT");
362+ probe_http_method(p, "DELETE");
363+ probe_http_method(p, "TRACE");
364+ probe_http_method(p, "CONNECT");
365+
366+ return 0;
367+}
368+
369+
342370 /*
343371 * Read the beginning of data coming from the client connection and check if
344372 * it's a known protocol. Then leave the data on the defered
345373 * write buffer of the connection and returns the protocol index in the
@@ -391,10 +419,20 @@
391419 serv, sizeof(serv),
392420 numeric ? NI_NUMERICHOST | NI_NUMERICSERV : 0 );
393421
394422 if (res) {
395- fprintf(stderr, "sprintaddr:getnameinfo: %s\n", gai_strerror(res));
396- exit(1);
423+ log_message(LOG_ERR, "sprintaddr:getnameinfo: %s\n", gai_strerror(res));
424+ /* Name resolution failed: do it numerically instead */
425+ res = getnameinfo(a->ai_addr, a->ai_addrlen,
426+ host, sizeof(host),
427+ serv, sizeof(serv),
428+ NI_NUMERICHOST | NI_NUMERICSERV);
429+ /* should not fail but... */
430+ if (res) {
431+ log_message(LOG_ERR, "sprintaddr:getnameinfo(NUM): %s\n", gai_strerror(res));
432+ strcpy(host, "?");
433+ strcpy(serv, "?");
434+ }
397435 }
398436
399437 snprintf(buf, size, "%s:%s", host, serv);
400438
@@ -435,20 +473,18 @@
435473 exit(4);
436474 }
437475 }
438476
439-/* Log to syslog, and to stderr if foreground */
477+/* Log to syslog or stderr if foreground */
440478 void log_message(int type, char* msg, ...)
441479 {
442480 va_list ap;
443481
444482 va_start(ap, msg);
445- vsyslog(type, msg, ap);
446- va_end(ap);
447-
448- va_start(ap, msg);
449483 if (foreground)
450484 vfprintf(stderr, msg, ap);
485+ else
486+ vsyslog(type, msg, ap);
451487 va_end(ap);
452488 }
453489
454490 /* syslogs who connected to where */
scripts/etc.default.sslhView
@@ -1,3 +1,5 @@
11 LISTEN=ifname:443
22 SSH=localhost:22
33 SSL=localhost:443
4+USER=nobody
5+PID=/var/run/sslh.pid
scripts/etc.init.d.sslhView
@@ -12,13 +12,8 @@
1212 facility=user.info
1313
1414 # /etc/init.d/sslh: start and stop the sslh proxy daemon
1515
16-# Defaults -- can be overridden in /etc/default/sslh
17-LISTEN=thelonious:443
18-SSH=localhost:22
19-SSL=localhost:443
20-
2116 if test -f /etc/default/sslh; then
2217 . /etc/default/sslh
2318 fi
2419
@@ -29,9 +24,9 @@
2924
3025 start()
3126 {
3227 echo "Start services: sslh"
33- $DAEMON --user nobody --listen ${LISTEN} --ssh ${SSH} --ssl ${SSL}
28+ $DAEMON --user ${USER} --pidfile ${PID} --listen ${LISTEN} --ssh ${SSH} --ssl ${SSL}
3429 logger -t ${tag} -p ${facility} -i 'Started sslh'
3530 }
3631
3732 stop()
scripts/etc.rc.d.init.d.sslh.centosView
@@ -19,9 +19,9 @@
1919
2020 SSLH="/usr/local/sbin/sslh"
2121 PIDFILE="/var/run/sslh"
2222
23-OPTIONS="-p 0.0.0.0:8443 --ssl 127.0.0.1:443 --ssh 127.0.0.1:22"
23+OPTIONS="--user nobody --pidfile $PIDFILE -p 0.0.0.0:8443 --ssl 127.0.0.1:443 --ssh 127.0.0.1:22"
2424
2525 if [ -f /etc/sysconfig/sslh ]; then
2626 . /etc/sysconfig/sslh
2727 fi
sslh-fork.cView
@@ -137,8 +137,9 @@
137137 {
138138 int in_socket, i, res;
139139 struct sigaction action;
140140
141+ listener_pid_number = num_addr_listen;
141142 listener_pid = malloc(listener_pid_number * sizeof(listener_pid[0]));
142143
143144 /* Start one process for each listening address */
144145 for (i = 0; i < num_addr_listen; i++) {
@@ -169,9 +170,8 @@
169170 action.sa_handler = stop_listeners;
170171 res = sigaction(SIGTERM, &action, NULL);
171172 CHECK_RES_DIE(res, "sigaction");
172173
173- listener_pid_number = num_addr_listen;
174174 wait(NULL);
175175 }
176176
177177 /* The actual main is in common.c: it's the same for both version of
sslh-main.cView
@@ -153,10 +153,10 @@
153153
154154 int *listen_sockets;
155155
156156 /* Init defaults */
157- pid_file = "/var/run/sslh.pid";
158- user_name = "nobody";
157+ pid_file = NULL;
158+ user_name = NULL;
159159 foreground = 0;
160160
161161 parse_cmdline(argc, argv);
162162
@@ -171,23 +171,26 @@
171171 printsettings();
172172
173173 num_addr_listen = start_listen_sockets(&listen_sockets, addr_listen);
174174
175- if (!foreground)
175+ if (!foreground) {
176176 if (fork() > 0) exit(0); /* Detach */
177177
178+ /* New session -- become group leader */
179+ if (getuid() == 0) {
180+ res = setsid();
181+ CHECK_RES_DIE(res, "setsid: already process leader");
182+ }
183+ }
184+
178185 setup_signals();
179186
180- drop_privileges(user_name);
187+ if (user_name)
188+ drop_privileges(user_name);
181189
182- /* New session -- become group leader */
183- if (getuid() == 0) {
184- res = setsid();
185- CHECK_RES_DIE(res, "setsid: already process leader");
186- }
190+ if (pid_file)
191+ write_pid_file(pid_file);
187192
188- write_pid_file(pid_file);
189-
190193 /* Open syslog connection */
191194 setup_syslog(argv[0]);
192195
193196 main_loop(listen_sockets, num_addr_listen);
sslh.podView
@@ -5,17 +5,17 @@
55 sslh - ssl/ssh multiplexer
66
77 =head1 SYNOPSIS
88
9-sslh [ B<-t> I<num> ] [B<-p> I<listening address> [B<-p> I<listening address> ...] [B<--ssl> I<target address for SSL>] [B<--ssh> I<target address for SSH>] [B<--openvpn> I<target address for OpenVPN>] [B<-u> I<username>] [B<-P> I<pidfile>] [-v] [-i] [-V] [-f] [-n]
9+sslh [ B<-t> I<num> ] [B<-p> I<listening address> [B<-p> I<listening address> ...] [B<--ssl> I<target address for SSL>] [B<--ssh> I<target address for SSH>] [B<--openvpn> I<target address for OpenVPN>] [B<--http> I<target address for HTTP>] [B<-u> I<username>] [B<-P> I<pidfile>] [-v] [-i] [-V] [-f] [-n]
1010
1111 =head1 DESCRIPTION
1212
13-B<sslh> accepts HTTPS, SSH, OpenVPN, tinc and XMPP connections
14-on the same port. This makes it possible to connect to any
15-of these servers on port 443 (e.g. from inside a corporate
16-firewall, which almost never block port 443) while still
17-serving HTTPS on that port.
13+B<sslh> accepts HTTP, HTTPS, SSH, OpenVPN, tinc and XMPP
14+connections on the same port. This makes it possible to
15+connect to any of these servers on port 443 (e.g. from
16+inside a corporate firewall, which almost never block port
17+443) while still serving HTTPS on that port.
1818
1919
2020 The idea is to have B<sslh> listen to the external 443 port,
2121 accept the incoming connections, work out what type of
@@ -122,16 +122,14 @@
122122 Prints B<sslh> version.
123123
124124 =item B<-u> I<username>, B<--user> I<username>
125125
126-Requires to run under the specified username. Defaults to
127-I<nobody> (which is not perfect -- ideally B<sslh> should
128-run under its own UID).
126+Requires to run under the specified username.
129127
130128 =item B<-P> I<pidfile>, B<--pid-file> I<pidfile>
131129
132-Specifies the file in which to write the PID of the main
133-server. Defaults to I</var/run/sslh.pid>.
130+Specifies a file in which to write the PID of the main
131+server.
134132
135133 =item B<-i>, B<--inetd>
136134
137135 Runs as an I<inetd> server. Options B<-P> (PID file), B<-p>

Built with git-ssb-web