don't log to syslog when testing

This commit is contained in:
yrutschle 2022-03-18 18:02:32 +01:00
parent 91d148f66c
commit 1e0578c082
9 changed files with 86 additions and 66 deletions

View File

@ -8,7 +8,7 @@ RUN \
libconfig-dev \ libconfig-dev \
make \ make \
musl-dev \ musl-dev \
pcre2-dev \ pcre-dev \
perl && \ perl && \
cd /sslh && \ cd /sslh && \
make sslh-select && \ make sslh-select && \
@ -18,6 +18,6 @@ FROM alpine:latest
COPY --from=build /sslh/sslh-select /sslh COPY --from=build /sslh/sslh-select /sslh
RUN apk --no-cache add libconfig pcre2 RUN apk --no-cache add libconfig pcre
ENTRYPOINT [ "/sslh", "--foreground"] ENTRYPOINT [ "/sslh", "--foreground"]

View File

@ -27,13 +27,9 @@ CC ?= gcc
CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV) CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV)
LIBS=-lm -lpcre2-8 LIBS=-lm -lpcre2-8
# making sslh-conf.o also makes sslh-conf.h with
# conf2struct, which may be required by other headers: it
# should be kept first
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o collection.o gap.o OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o collection.o gap.o
FORK_OBJS=$(OBJS) sslh-fork.o FORK_OBJS=sslh-fork.o $(OBJS)
SELECT_OBJS=$(OBJS) sslh-select.o processes.o udp-listener.o SELECT_OBJS=sslh-select.o $(OBJS) processes.o udp-listener.o
EV_OBJS=sslh-ev.o $(OBJS) processes.o udp-listener.o EV_OBJS=sslh-ev.o $(OBJS) processes.o udp-listener.o
CONDITIONAL_TARGETS= CONDITIONAL_TARGETS=
@ -79,7 +75,7 @@ version.h:
sslh: sslh-fork sslh-select sslh-ev sslh: sslh-fork sslh-select sslh-ev
$(OBJS): version.h common.h collection.h sslh-conf.h gap.h processes.h $(OBJS): version.h common.h collection.h sslh-conf.h gap.h
sslh-conf.c sslh-conf.h: sslhconf.cfg sslh-conf.c sslh-conf.h: sslhconf.cfg
conf2struct sslhconf.cfg conf2struct sslhconf.cfg

View File

@ -554,6 +554,36 @@ int resolve_split_name(struct addrinfo **out, char* host, char* serv)
return res; return res;
} }
/* turns a "hostname:port" string into a list of struct addrinfo;
out: list of newly allocated addrinfo (see getaddrinfo(3)); freeaddrinfo(3) when done
fullname: input string -- it gets clobbered
*/
void resolve_name(struct addrinfo **out, char* fullname)
{
char *serv, *host;
int res;
/* Find port */
char *sep = strrchr(fullname, ':');
if (!sep) { /* No separator: parameter is just a port */
print_message(msg_config_error, "%s: names must be fully specified as hostname:port\n", fullname);
exit(1);
}
serv = sep+1;
*sep = 0;
host = fullname;
res = resolve_split_name(out, host, serv);
if (res) {
print_message(msg_config_error, "%s `%s'\n", gai_strerror(res), fullname);
if (res == EAI_SERVICE)
print_message(msg_config_error, "(Check you have specified all ports)\n");
exit(4);
}
}
/* Fills a connection description; returns 0 on failure */ /* Fills a connection description; returns 0 on failure */
int get_connection_desc(struct connection_desc* desc, const struct connection *cnx) int get_connection_desc(struct connection_desc* desc, const struct connection *cnx)
{ {

View File

@ -35,6 +35,30 @@
#include "version.h" #include "version.h"
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CHECK_RES_DIE(res, str) \
if (res == -1) { \
print_message(msg_system_error, "%s:%d:", __FILE__, __LINE__); \
perror(str); \
exit(1); \
}
#define CHECK_RES_RETURN(res, str, ret) \
if (res == -1) { \
print_message(msg_system_error, "%s:%d:%s:%d:%s\n", __FILE__, __LINE__, str, errno, strerror(errno)); \
return ret; \
}
#define CHECK_ALLOC(a, str) \
if (!a) { \
print_message(msg_system_error, "%s:%d:", __FILE__, __LINE__); \
perror(str); \
exit(1); \
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#if 1 #if 1
#define TRACE fprintf(stderr, "%s:%d\n", __FILE__, __LINE__); #define TRACE fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
@ -59,6 +83,9 @@ enum connection_state {
ST_SHOVELING /* Connexion is established */ ST_SHOVELING /* Connexion is established */
}; };
/* this is used to pass protocols through the command-line parameter parsing */
#define PROT_SHIFT 1000 /* protocol options will be 1000, 1001, etc */
/* A 'queue' is composed of a file descriptor (which can be read from or /* A 'queue' is composed of a file descriptor (which can be read from or
* written to), and a queue for deferred write data */ * written to), and a queue for deferred write data */
struct queue { struct queue {
@ -116,7 +143,6 @@ typedef enum {
BLOCKING = 1 BLOCKING = 1
} connect_blocking; } connect_blocking;
#include "log.h"
/* common.c */ /* common.c */
void init_cnx(struct connection *cnx); void init_cnx(struct connection *cnx);
@ -126,9 +152,11 @@ int fd2fd(struct queue *target, struct queue *from);
char* sprintaddr(char* buf, size_t size, struct addrinfo *a); char* sprintaddr(char* buf, size_t size, struct addrinfo *a);
void resolve_name(struct addrinfo **out, char* fullname); void resolve_name(struct addrinfo **out, char* fullname);
int get_connection_desc(struct connection_desc* desc, const struct connection *cnx); int get_connection_desc(struct connection_desc* desc, const struct connection *cnx);
void log_connection(struct connection_desc* desc, const struct connection *cnx);
void set_proctitle_shovel(struct connection_desc* desc, const struct connection *cnx); void set_proctitle_shovel(struct connection_desc* desc, const struct connection *cnx);
int check_access_rights(int in_socket, const char* service); int check_access_rights(int in_socket, const char* service);
void setup_signals(void); void setup_signals(void);
void setup_syslog(const char* bin_name);
void drop_privileges(const char* user_name, const char* chroot_path); void drop_privileges(const char* user_name, const char* chroot_path);
void set_capabilities(int cap_net_admin); void set_capabilities(int cap_net_admin);
void write_pid_file(const char* pidfile); void write_pid_file(const char* pidfile);
@ -149,29 +177,4 @@ void start_shoveler(int);
void main_loop(struct listen_endpoint *listen_sockets, int num_addr_listen); void main_loop(struct listen_endpoint *listen_sockets, int num_addr_listen);
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CHECK_RES_DIE(res, str) \
if (res == -1) { \
print_message(msg_system_error, "%s:%d:", __FILE__, __LINE__); \
perror(str); \
exit(1); \
}
#define CHECK_RES_RETURN(res, str, ret) \
if (res == -1) { \
print_message(msg_system_error, "%s:%d:%s:%d:%s\n", __FILE__, __LINE__, str, errno, strerror(errno)); \
return ret; \
}
#define CHECK_ALLOC(a, str) \
if (!a) { \
print_message(msg_system_error, "%s:%d:", __FILE__, __LINE__); \
perror(str); \
exit(1); \
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#endif #endif

View File

@ -23,8 +23,6 @@ Makefile.
* [libcap](http://packages.debian.org/source/unstable/libcap-dev), in package `libcap-dev`. You can compile with or without it using USELIBCAP in the Makefile * [libcap](http://packages.debian.org/source/unstable/libcap-dev), in package `libcap-dev`. You can compile with or without it using USELIBCAP in the Makefile
* [libev](http://software.schmorp.de/pkg/libev.html), in package `libev-dev`. It is only required to build `sslh-ev`, so you don't need if you only build `sslh-fork` and/or `sslh-select`.
* libbsd, to enable to change the process name (as shown in * libbsd, to enable to change the process name (as shown in
`ps`, so each forked process shows what protocol and what `ps`, so each forked process shows what protocol and what
connection it is serving), connection it is serving),
@ -73,8 +71,8 @@ of the Makefile:
Binaries Binaries
-------- --------
The Makefile produces three different executables: `sslh-fork`, The Makefile produces two different executables: `sslh-fork`
`sslh-select` and `sslh-ev`: and `sslh-select`:
* `sslh-fork` forks a new process for each incoming connection. * `sslh-fork` forks a new process for each incoming connection.
It is well-tested and very reliable, but incurs the overhead It is well-tested and very reliable, but incurs the overhead
@ -91,10 +89,10 @@ If you are going to use `sslh` on a "medium" setup (a few thousand ssh
connections, and another few thousand ssl connections), connections, and another few thousand ssl connections),
`sslh-select` will be better. `sslh-select` will be better.
* `sslh-ev` works very much like `sslh-select`, but uses If you have a very large site (tens of thousands of connections),
`libev` as a backend. `libev` provides more portability you'll need a vapourware version that would use libevent or
and alternative ways to support very large numbers of something like that.
connections.
Installation Installation
------------ ------------

View File

@ -22,7 +22,6 @@ PrivateDevices=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
MemoryDenyWriteExecute=true MemoryDenyWriteExecute=true
DynamicUser=true DynamicUser=true
Type=forking
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -2,13 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "common.h"
#define CHECK_ALLOC(a, str) \
if (!a) { \
fprintf(stderr, "%s:%d:", __FILE__, __LINE__); \
perror(str); \
exit(1); \
}
static char* resolve_listen(const char *hostname, const char *port) { static char* resolve_listen(const char *hostname, const char *port) {

View File

@ -14,17 +14,17 @@ syslog_facility: "auth";
# Value: 1: stdout; 2: syslog; 3: both # Value: 1: stdout; 2: syslog; 3: both
# Defaults should be sensible. Generally, you want *-error # Defaults should be sensible. Generally, you want *-error
# to be always enabled, to know if something is going wrong. # to be always enabled, to know if something is going wrong.
verbose-config: 3; # print configuration at startup verbose-config: 1; # print configuration at startup
verbose-config-error: 3; # print configuration errors verbose-config-error: 1; # print configuration errors
verbose-connections: 3; # trace established incoming address to forward address verbose-connections: 1; # trace established incoming address to forward address
verbose-connections-error: 3; # connection errors verbose-connections-error: 1; # connection errors
verbose-connections-try: 3; # connection attempts towards targets verbose-connections-try: 1; # connection attempts towards targets
verbose-fd: 3; # file descriptor activity, open/close/whatnot verbose-fd: 1; # file descriptor activity, open/close/whatnot
verbose-packets: 3; # hexdump packets on which probing is done verbose-packets: 1; # hexdump packets on which probing is done
verbose-probe-info: 3; # what's happening during the probe process verbose-probe-info: 1; # what's happening during the probe process
verbose-probe-error: 3; # failures and problems during probing verbose-probe-error: 1; # failures and problems during probing
verbose-system-error: 3; # system call problem, i.e. malloc, fork, failing verbose-system-error: 1; # system call problem, i.e. malloc, fork, failing
verbose-int-error: 3; # internal errors, the kind that should never happen verbose-int-error: 1; # internal errors, the kind that should never happen
# List of interfaces on which we should listen # List of interfaces on which we should listen
# Options: # Options:
@ -32,7 +32,7 @@ listen:
( (
{ host: "localhost"; port: "8080"; keepalive: true; }, { host: "localhost"; port: "8080"; keepalive: true; },
{ host: "localhost"; port: "8081"; keepalive: true; }, { host: "localhost"; port: "8081"; keepalive: true; },
{ host: "127.0.0.1"; is_udp: true; port: "8086"; } { host: "ip4-localhost"; is_udp: true; port: "8086"; }
); );
@ -46,7 +46,7 @@ protocols:
{ name: "xmpp"; host: "localhost"; port: "9009"; }, { name: "xmpp"; host: "localhost"; port: "9009"; },
{ name: "adb"; host: "localhost"; port: "9010"; }, { name: "adb"; host: "localhost"; port: "9010"; },
{ name: "syslog"; host: "localhost"; port: "9013"; }, { name: "syslog"; host: "localhost"; port: "9013"; },
{ name: "ssh"; host: "127.0.0.1"; is_udp: true; port: "9020"; { name: "regex"; host: "ip4-localhost"; is_udp: true; port: "9020";
udp_timeout: 30; udp_timeout: 30;
regex_patterns: [ "^foo" ]; regex_patterns: [ "^foo" ];
}, },

4
tls.c
View File

@ -255,7 +255,7 @@ parse_alpn_extension(const struct TLSProtocol *tls_data, const char *data, size_
if (len > 0 && has_match(tls_data->alpn_protocol_list, tls_data->alpn_list_len, data + pos + 1, len)) { if (len > 0 && has_match(tls_data->alpn_protocol_list, tls_data->alpn_list_len, data + pos + 1, len)) {
return len; return len;
} else if (len > 0) { } else if (len > 0) {
print_message(msg_probe_info, "Not in ALPN list: %.*s\n", (int)len, data + pos + 1); print_message(msg_probe_error, "Unknown ALPN name: %.*s\n", (int)len, data + pos + 1);
} }
pos += 1 + len; pos += 1 + len;
} }
@ -277,7 +277,7 @@ has_match(const char** list, size_t list_len, const char* name, size_t name_len)
for (i = 0; i < list_len; i++) { for (i = 0; i < list_len; i++) {
item = &list[i]; item = &list[i];
print_message(msg_probe_info, "matching [%.*s] with [%s]\n", (int)name_len, name, *item); print_message(msg_probe_error, "matching [%.*s] with [%s]\n", (int)name_len, name, *item);
if(!fnmatch(*item, name_nullterminated, 0)) { if(!fnmatch(*item, name_nullterminated, 0)) {
free(name_nullterminated); free(name_nullterminated);
return 1; return 1;