mirror of
https://github.com/moparisthebest/sslh
synced 2024-11-14 13:15:02 -05:00
v1.5: 10DEC2008
Fixed zombie generation. Added support scripts (), Makefile. Changed all 'connexions' to 'connections' to please pesky users. Damn users.
This commit is contained in:
parent
3386a64a4d
commit
b965d735b8
23
Makefile
Normal file
23
Makefile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Configuration
|
||||||
|
|
||||||
|
USELIBWRAP=1 # Use libwrap?
|
||||||
|
|
||||||
|
|
||||||
|
# End of configuration -- the rest should take care of
|
||||||
|
# itself
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
#LIBS=-lnet
|
||||||
|
LIBS=
|
||||||
|
|
||||||
|
ifneq ($(strip $(USELIBWRAP)),)
|
||||||
|
LIBS:=$(LIBS) -lwrap
|
||||||
|
CFLAGS=-DLIBWRAP
|
||||||
|
endif
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(CC) $(CFLAGS) -o sslh sslh.c $(LIBS)
|
||||||
|
strip sslh
|
||||||
|
|
||||||
|
|
83
README
Normal file
83
README
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
Compilation instructions:
|
||||||
|
|
||||||
|
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.init.d.sslh /etc/init.d/sslh
|
||||||
|
cp scripts/etc.default.sslh /etc/default/sslh
|
||||||
|
|
||||||
|
You can edit settings in /etc/default/sslh:
|
||||||
|
|
||||||
|
PIDFILE=/var/run/sslh.pid
|
||||||
|
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: 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Comments? questions? sslh@rutschle.net
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
4
scripts/etc.default.sslh
Executable file
4
scripts/etc.default.sslh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
PIDFILE=/var/run/sslh.pid
|
||||||
|
LISTEN=ifname:443
|
||||||
|
SSH=localhost:22
|
||||||
|
SSL=localhost:443
|
62
scripts/etc.init.d.sslh
Executable file
62
scripts/etc.init.d.sslh
Executable 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
|
||||||
|
PIDFILE=/var/run/sslh.pid
|
||||||
|
LISTEN=thelonious:443
|
||||||
|
SSH=localhost:22
|
||||||
|
SSL=localhost:443
|
||||||
|
|
||||||
|
if test -f /etc/default/sslh; then
|
||||||
|
. /etc/default/sslh
|
||||||
|
export PIDFILE=${PIDFILE}
|
||||||
|
fi
|
||||||
|
|
||||||
|
DAEMON=/usr/local/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
|
||||||
|
rm ${PIDFILE}
|
||||||
|
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
|
88
sslh.c
88
sslh.c
@ -18,44 +18,9 @@
|
|||||||
# The full text for the General Public License is here:
|
# The full text for the General Public License is here:
|
||||||
# http://www.gnu.org/licenses/gpl.html
|
# 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
|
|
||||||
|
|
||||||
Linux:
|
|
||||||
cc -o sslh sslh.c -lnet
|
|
||||||
|
|
||||||
HISTORY
|
|
||||||
|
|
||||||
v1.3: 14MAY2008
|
|
||||||
Added parsing for local interface to listen on
|
|
||||||
Changed default SSL connexion to port 442 (443 doesn't make
|
|
||||||
sense as a default as we're already listening on 443)
|
|
||||||
Syslog incoming connexions
|
|
||||||
|
|
||||||
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.3"
|
#define VERSION "1.5"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -72,6 +37,12 @@ v1.0:
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#ifdef LIBWRAP
|
||||||
|
#include <tcpd.h>
|
||||||
|
int allow_severity =0, deny_severity = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CHECK_RES_DIE(res, str) \
|
#define CHECK_RES_DIE(res, str) \
|
||||||
if (res == -1) { \
|
if (res == -1) { \
|
||||||
perror(str); \
|
perror(str); \
|
||||||
@ -86,8 +57,8 @@ if (res == -1) { \
|
|||||||
"\t\t-s [sshhost:]port -l [sslhost:]port [-v]\n\n" \
|
"\t\t-s [sshhost:]port -l [sslhost:]port [-v]\n\n" \
|
||||||
"-v: verbose\n" \
|
"-v: verbose\n" \
|
||||||
"-p: address and port to listen on. default: 0.0.0.0:443\n" \
|
"-p: address and port to listen on. default: 0.0.0.0:443\n" \
|
||||||
"-s: SSH address: where to connect an SSH connexion. default: localhost:22\n" \
|
"-s: SSH address: where to connect an SSH connection. default: localhost:22\n" \
|
||||||
"-l: SSL address: where to connect an SSL connexion.\n" \
|
"-l: SSL address: where to connect an SSL connection.\n" \
|
||||||
""
|
""
|
||||||
|
|
||||||
int verbose = 0; /* That's really quite global */
|
int verbose = 0; /* That's really quite global */
|
||||||
@ -227,7 +198,7 @@ void resolve_name(struct sockaddr *sock, char* fullname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* syslogs who connected to where */
|
/* syslogs who connected to where */
|
||||||
void log_connexion(int socket, char* target)
|
void log_connection(int socket, char* target)
|
||||||
{
|
{
|
||||||
struct sockaddr peeraddr;
|
struct sockaddr peeraddr;
|
||||||
socklen_t size = sizeof(peeraddr);
|
socklen_t size = sizeof(peeraddr);
|
||||||
@ -237,7 +208,7 @@ void log_connexion(int socket, char* target)
|
|||||||
res = getpeername(socket, &peeraddr, &size);
|
res = getpeername(socket, &peeraddr, &size);
|
||||||
CHECK_RES_DIE(res, "getpeername");
|
CHECK_RES_DIE(res, "getpeername");
|
||||||
|
|
||||||
syslog(LOG_INFO, "connexion from %s forwarded to %s\n",
|
syslog(LOG_INFO, "connection from %s forwarded to %s\n",
|
||||||
sprintaddr(buf, sizeof(buf), &peeraddr), target);
|
sprintaddr(buf, sizeof(buf), &peeraddr), target);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -251,6 +222,36 @@ int timeout = 2;
|
|||||||
struct sockaddr addr_listen;
|
struct sockaddr addr_listen;
|
||||||
struct sockaddr addr_ssl, addr_ssh;
|
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
|
/* Child process that finds out what to connect to and proxies
|
||||||
*/
|
*/
|
||||||
@ -280,9 +281,12 @@ void start_shoveler(int in_socket)
|
|||||||
/* The client hasn't written anything and we timed out: connect to SSH */
|
/* The client hasn't written anything and we timed out: connect to SSH */
|
||||||
saddr = &addr_ssh;
|
saddr = &addr_ssh;
|
||||||
target = "SSH";
|
target = "SSH";
|
||||||
|
|
||||||
|
/* do hosts_access check if built with libwrap support */
|
||||||
|
check_access_rights(in_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_connexion(in_socket, target);
|
log_connection(in_socket, target);
|
||||||
|
|
||||||
/* Connect the target socket */
|
/* Connect the target socket */
|
||||||
out_socket = socket(AF_INET, SOCK_STREAM, 0);
|
out_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
@ -442,7 +446,7 @@ int main(int argc, char *argv[])
|
|||||||
res = setsid();
|
res = setsid();
|
||||||
CHECK_RES_DIE(res, "setsid: already process leader");
|
CHECK_RES_DIE(res, "setsid: already process leader");
|
||||||
|
|
||||||
/* Open syslog connexion */
|
/* Open syslog connection */
|
||||||
openlog(argv[0], LOG_CONS, LOG_AUTH);
|
openlog(argv[0], LOG_CONS, LOG_AUTH);
|
||||||
|
|
||||||
/* Main server loop: accept connections, find what they are, fork shovelers */
|
/* Main server loop: accept connections, find what they are, fork shovelers */
|
||||||
|
Loading…
Reference in New Issue
Block a user