Commit b965d735b8cede5dfc93947da5c59e562aceb559
v1.5: 10DEC2008
Fixed zombie generation. Added support scripts (), Makefile. Changed all 'connexions' to 'connections' to please pesky users. Damn users.Yves Rutschle committed on 7/10/2013, 9:09:40 PM
Parent: 3386a64a4d817d03da64318fb028c49c699cee85
Files changed
sslh.c | changed |
Makefile | added |
README | added |
scripts/etc.default.sslh | added |
scripts/etc.init.d.sslh | added |
sslh.c | ||
---|---|---|
@@ -17,46 +17,11 @@ | ||
17 | 17 | # |
18 | 18 | # The full text for the General Public License is here: |
19 | 19 | |
20 | 20 | |
21 | -Comments? questions? sslh@rutschle.net | |
22 | - | |
23 | -Compilation instructions: | |
24 | - | |
25 | -Solaris: | |
26 | - cc -o sslh sslh.c -lresolv -lsocket -lnsl | |
27 | - | |
28 | -LynxOS: | |
29 | - gcc -o tcproxy tcproxy.c -lnetinet | |
30 | - | |
31 | -Linux: | |
32 | - cc -o sslh sslh.c -lnet | |
33 | - | |
34 | -HISTORY | |
35 | - | |
36 | -v1.3: 14MAY2008 | |
37 | - Added parsing for local interface to listen on | |
38 | - Changed default SSL connexion to port 442 (443 doesn't make | |
39 | - sense as a default as we're already listening on 443) | |
40 | - Syslog incoming connexions | |
41 | - | |
42 | -v1.2: 12MAY2008 | |
43 | - Fixed compilation warning for AMD64 (Thx Daniel Lange) | |
44 | - | |
45 | -v1.1: 21MAY2007 | |
46 | - Making sslhc more like a real daemon: | |
47 | - * If $PIDFILE is defined, write first PID to it upon startup | |
48 | - * Fork at startup (detach from terminal) | |
49 | - (thanks to http://www.enderunix.org/docs/eng/daemon.php -- good checklist) | |
50 | - * Less memory usage (?) | |
51 | - | |
52 | -v1.0: | |
53 | - * Basic functionality: privilege dropping, target hostnames and ports | |
54 | - configurable. | |
55 | - | |
56 | 21 | */ |
57 | 22 | |
58 | - | |
23 | + | |
59 | 24 | |
60 | 25 | |
61 | 26 | |
62 | 27 | |
@@ -71,8 +36,14 @@ | ||
71 | 36 | |
72 | 37 | |
73 | 38 | |
74 | 39 | |
40 | + | |
41 | + | |
42 | +int allow_severity =0, deny_severity = 0; | |
43 | + | |
44 | + | |
45 | + | |
75 | 46 | |
76 | 47 | if (res == -1) { \ |
77 | 48 | perror(str); \ |
78 | 49 | exit(1); \ |
@@ -85,10 +56,10 @@ | ||
85 | 56 | "\tsslh [-t <timeout>] -u <username> -p [listenaddr:]<listenport> \n" \ |
86 | 57 | "\t\t-s [sshhost:]port -l [sslhost:]port [-v]\n\n" \ |
87 | 58 | "-v: verbose\n" \ |
88 | 59 | "-p: address and port to listen on. default: 0.0.0.0:443\n" \ |
89 | -"-s: SSH address: where to connect an SSH connexion. default: localhost:22\n" \ | |
90 | -"-l: SSL address: where to connect an SSL connexion.\n" \ | |
60 | +"-s: SSH address: where to connect an SSH connection. default: localhost:22\n" \ | |
61 | +"-l: SSL address: where to connect an SSL connection.\n" \ | |
91 | 62 | "" |
92 | 63 | |
93 | 64 | int verbose = 0; /* That's really quite global */ |
94 | 65 | |
@@ -226,9 +197,9 @@ | ||
226 | 197 | memcpy(sock, addr->ai_addr, sizeof(*sock)); |
227 | 198 | } |
228 | 199 | |
229 | 200 | /* syslogs who connected to where */ |
230 | -void log_connexion(int socket, char* target) | |
201 | +void log_connection(int socket, char* target) | |
231 | 202 | { |
232 | 203 | struct sockaddr peeraddr; |
233 | 204 | socklen_t size = sizeof(peeraddr); |
234 | 205 | char buf[64]; |
@@ -236,9 +207,9 @@ | ||
236 | 207 | |
237 | 208 | res = getpeername(socket, &peeraddr, &size); |
238 | 209 | CHECK_RES_DIE(res, "getpeername"); |
239 | 210 | |
240 | - syslog(LOG_INFO, "connexion from %s forwarded to %s\n", | |
211 | + syslog(LOG_INFO, "connection from %s forwarded to %s\n", | |
241 | 212 | sprintaddr(buf, sizeof(buf), &peeraddr), target); |
242 | 213 | |
243 | 214 | } |
244 | 215 | |
@@ -250,9 +221,39 @@ | ||
250 | 221 | int timeout = 2; |
251 | 222 | struct sockaddr addr_listen; |
252 | 223 | struct sockaddr addr_ssl, addr_ssh; |
253 | 224 | |
225 | +/* libwrap (tcpd): check the ssh connection is legal. This is necessary because | |
226 | + * the actual sshd will only see a connection coming from localhost and can't | |
227 | + * apply the rules itself. | |
228 | + */ | |
229 | +void check_access_rights(int in_socket) | |
230 | +{ | |
231 | + | |
232 | + struct sockaddr peeraddr; | |
233 | + socklen_t size = sizeof(peeraddr); | |
234 | + char addr_str[1024]; | |
235 | + struct hostent *host; | |
236 | + struct in_addr addr; | |
237 | + int res; | |
254 | 238 | |
239 | + res = getpeername(in_socket, &peeraddr, &size); | |
240 | + CHECK_RES_DIE(res, "getpeername"); | |
241 | + inet_ntop(AF_INET, &((struct sockaddr_in*)&peeraddr)->sin_addr, addr_str, sizeof(addr_str)); | |
242 | + | |
243 | + addr.s_addr = inet_addr(addr_str); | |
244 | + host = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); | |
245 | + | |
246 | + if (!hosts_ctl("sshd", (host ? host->h_name : STRING_UNKNOWN), addr_str, STRING_UNKNOWN)) { | |
247 | + if (verbose) | |
248 | + fprintf(stderr, "access denied\n"); | |
249 | + log_connection(in_socket, "access denied"); | |
250 | + close(in_socket); | |
251 | + exit(0); | |
252 | + } | |
253 | + | |
254 | +} | |
255 | + | |
255 | 256 | /* Child process that finds out what to connect to and proxies |
256 | 257 | */ |
257 | 258 | void start_shoveler(int in_socket) |
258 | 259 | { |
@@ -279,11 +280,14 @@ | ||
279 | 280 | } else { |
280 | 281 | /* The client hasn't written anything and we timed out: connect to SSH */ |
281 | 282 | saddr = &addr_ssh; |
282 | 283 | target = "SSH"; |
284 | + | |
285 | + /* do hosts_access check if built with libwrap support */ | |
286 | + check_access_rights(in_socket); | |
283 | 287 | } |
284 | 288 | |
285 | - log_connexion(in_socket, target); | |
289 | + log_connection(in_socket, target); | |
286 | 290 | |
287 | 291 | /* Connect the target socket */ |
288 | 292 | out_socket = socket(AF_INET, SOCK_STREAM, 0); |
289 | 293 | res = connect(out_socket, saddr, sizeof(addr_ssl)); |
@@ -441,9 +445,9 @@ | ||
441 | 445 | /* New session -- become group leader */ |
442 | 446 | res = setsid(); |
443 | 447 | CHECK_RES_DIE(res, "setsid: already process leader"); |
444 | 448 | |
445 | - /* Open syslog connexion */ | |
449 | + /* Open syslog connection */ | |
446 | 450 | openlog(argv[0], LOG_CONS, LOG_AUTH); |
447 | 451 | |
448 | 452 | /* Main server loop: accept connections, find what they are, fork shovelers */ |
449 | 453 | while (1) |
Makefile | ||
---|---|---|
@@ -1,0 +1,23 @@ | ||
1 | +# Configuration | |
2 | + | |
3 | +USELIBWRAP=1 # Use libwrap? | |
4 | + | |
5 | + | |
6 | +# End of configuration -- the rest should take care of | |
7 | +# itself | |
8 | + | |
9 | +CC = gcc | |
10 | + | |
11 | +#LIBS=-lnet | |
12 | +LIBS= | |
13 | + | |
14 | +ifneq ($(strip $(USELIBWRAP)),) | |
15 | + LIBS:=$(LIBS) -lwrap | |
16 | + CFLAGS=-DLIBWRAP | |
17 | +endif | |
18 | + | |
19 | +all: | |
20 | + $(CC) $(CFLAGS) -o sslh sslh.c $(LIBS) | |
21 | + strip sslh | |
22 | + | |
23 | + |
README | ||
---|---|---|
@@ -1,0 +1,83 @@ | ||
1 | +sslh -- A ssl/ssh multiplexer. | |
2 | + | |
3 | +sslh lets one accept both HTTPS and SSH connections on the | |
4 | +same port. It makes it possible to connect to an SSH server | |
5 | +on port 443 (e.g. from inside a corporate firewall) while | |
6 | +still serving HTTPS on that port. | |
7 | + | |
8 | + | |
9 | +Compilation instructions: | |
10 | + | |
11 | +Solaris: | |
12 | + cc -o sslh sslh.c -lresolv -lsocket -lnsl | |
13 | + | |
14 | +LynxOS: | |
15 | + gcc -o tcproxy tcproxy.c -lnetinet | |
16 | + | |
17 | +Linux: | |
18 | + cc -o sslh sslh.c -lnet | |
19 | +or: | |
20 | + cc -o sslh sslh.c | |
21 | + | |
22 | +To compile with libwrap support: | |
23 | + cc -o sslh -DLIBWRAP sslh.c -lwrap | |
24 | + | |
25 | +To install: | |
26 | + | |
27 | +make | |
28 | +cp sslh /usr/local/sbin | |
29 | +cp scripts/etc.init.d.sslh /etc/init.d/sslh | |
30 | +cp scripts/etc.default.sslh /etc/default/sslh | |
31 | + | |
32 | +You can edit settings in /etc/default/sslh: | |
33 | + | |
34 | +PIDFILE=/var/run/sslh.pid | |
35 | +LISTEN=ifname:443 | |
36 | +SSH=localhost:22 | |
37 | +SSL=localhost:443 | |
38 | + | |
39 | +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. | |
44 | + | |
45 | +Sslh can optionnaly perform libwrap checks for the sshd | |
46 | +service: because the connection to sshd will be coming | |
47 | +locally from sslh, sshd cannot determine the IP of the | |
48 | +client. | |
49 | + | |
50 | +Comments? questions? sslh@rutschle.net | |
51 | + | |
52 | +HISTORY | |
53 | + | |
54 | +v1.5: 10DEC2008 | |
55 | + Fixed zombie generation. | |
56 | + Added support scripts (), Makefile. | |
57 | + Changed all 'connexions' to 'connections' to please | |
58 | + pesky users. Damn users. | |
59 | + | |
60 | +v1.4: 13JUL2008 | |
61 | + Added libwrap support for ssh service (Christian Weinberger) | |
62 | + Only SSH is libwraped, not SSL. | |
63 | + | |
64 | +v1.3: 14MAY2008 | |
65 | + Added parsing for local interface to listen on | |
66 | + Changed default SSL connection to port 442 (443 doesn't make | |
67 | + sense as a default as we're already listening on 443) | |
68 | + Syslog incoming connections | |
69 | + | |
70 | +v1.2: 12MAY2008 | |
71 | + Fixed compilation warning for AMD64 (Thx Daniel Lange) | |
72 | + | |
73 | +v1.1: 21MAY2007 | |
74 | + Making sslhc more like a real daemon: | |
75 | + * If $PIDFILE is defined, write first PID to it upon startup | |
76 | + * Fork at startup (detach from terminal) | |
77 | + (thanks to http://www.enderunix.org/docs/eng/daemon.php -- good checklist) | |
78 | + * Less memory usage (?) | |
79 | + | |
80 | +v1.0: | |
81 | + * Basic functionality: privilege dropping, target hostnames and ports | |
82 | + configurable. | |
83 | + |
scripts/etc.default.sslh | ||
---|---|---|
@@ -1,0 +1,4 @@ | ||
1 | +PIDFILE=/var/run/sslh.pid | |
2 | +LISTEN=ifname:443 | |
3 | +SSH=localhost:22 | |
4 | +SSL=localhost:443 |
scripts/etc.init.d.sslh | ||
---|---|---|
@@ -1,0 +1,62 @@ | ||
1 | +#! /bin/sh | |
2 | + | |
3 | +### BEGIN INIT INFO | |
4 | +# Provides: sslh | |
5 | +# Default-Start: 2 3 4 5 | |
6 | +# Default-Stop: 1 | |
7 | +# Short-Description: sslh proxy ssl & ssh connections | |
8 | +### END INIT INFO | |
9 | + | |
10 | +set -e | |
11 | +tag=sslh | |
12 | +facility=user.info | |
13 | + | |
14 | +# /etc/init.d/sslh: start and stop the sslh proxy daemon | |
15 | + | |
16 | +# Defaults -- can be overridden in /etc/default/sslh | |
17 | +PIDFILE=/var/run/sslh.pid | |
18 | +LISTEN=thelonious:443 | |
19 | +SSH=localhost:22 | |
20 | +SSL=localhost:443 | |
21 | + | |
22 | +if test -f /etc/default/sslh; then | |
23 | + . /etc/default/sslh | |
24 | + export PIDFILE=${PIDFILE} | |
25 | +fi | |
26 | + | |
27 | +DAEMON=/usr/local/sbin/sslh | |
28 | + | |
29 | +start() | |
30 | +{ | |
31 | + echo "Start services: sslh" | |
32 | + $DAEMON -u nobody -p ${LISTEN} -s ${SSH} -l ${SSL} | |
33 | + logger -t ${tag} -p ${facility} -i 'Started sslh' | |
34 | +} | |
35 | + | |
36 | +stop() | |
37 | +{ | |
38 | + echo "Stop services: sslh" | |
39 | + killall $DAEMON | |
40 | + rm ${PIDFILE} | |
41 | + logger -t ${tag} -p ${facility} -i 'Stopped sslh' | |
42 | +} | |
43 | + | |
44 | + | |
45 | +case "$1" in | |
46 | + start) | |
47 | + start | |
48 | + ;; | |
49 | + stop) | |
50 | + stop | |
51 | + ;; | |
52 | + restart) | |
53 | + stop | |
54 | + sleep 5 | |
55 | + start | |
56 | + ;; | |
57 | + *) | |
58 | + echo "Usage: /etc/init.d/sslh {start|stop|restart}" >&2 | |
59 | + ;; | |
60 | +esac | |
61 | + | |
62 | +exit 0 |
Built with git-ssb-web