mirror of
https://github.com/moparisthebest/sslh
synced 2024-11-27 19:42:21 -05:00
changed configuration file to accomodate SNI in a cleaner way
This commit is contained in:
parent
77ef29358d
commit
8fdaf6eb08
@ -5,6 +5,11 @@ vNEXT:
|
|||||||
Added support for RFC4366 SNI
|
Added support for RFC4366 SNI
|
||||||
(Travis Burtrum)
|
(Travis Burtrum)
|
||||||
|
|
||||||
|
Changed configuration file format: 'probe' field is
|
||||||
|
no longer required, 'name' field can now contain
|
||||||
|
'sni' or 'regex', with corresponding options (see
|
||||||
|
example.org)
|
||||||
|
|
||||||
v1.17: 09MAR2015
|
v1.17: 09MAR2015
|
||||||
Support RFC5952-style IPv6 addresses, e.g. [::]:443.
|
Support RFC5952-style IPv6 addresses, e.g. [::]:443.
|
||||||
|
|
||||||
|
12
basic.cfg
12
basic.cfg
@ -19,11 +19,11 @@ listen:
|
|||||||
|
|
||||||
protocols:
|
protocols:
|
||||||
(
|
(
|
||||||
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; probe: "builtin"; },
|
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; },
|
||||||
{ name: "openvpn"; host: "localhost"; port: "1194"; probe: "builtin"; },
|
{ name: "openvpn"; host: "localhost"; port: "1194"; },
|
||||||
{ name: "xmpp"; host: "localhost"; port: "5222"; probe: "builtin"; },
|
{ name: "xmpp"; host: "localhost"; port: "5222"; },
|
||||||
{ name: "http"; host: "localhost"; port: "80"; probe: "builtin"; },
|
{ name: "http"; host: "localhost"; port: "80"; },
|
||||||
{ name: "ssl"; host: "localhost"; port: "443"; probe: "builtin"; },
|
{ name: "ssl"; host: "localhost"; port: "443"; },
|
||||||
{ name: "anyprot"; host: "localhost"; port: "443"; probe: "builtin"; }
|
{ name: "anyprot"; host: "localhost"; port: "443"; }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
43
example.cfg
43
example.cfg
@ -23,31 +23,48 @@ listen:
|
|||||||
# List of protocols
|
# List of protocols
|
||||||
#
|
#
|
||||||
# Each protocol entry consists of:
|
# Each protocol entry consists of:
|
||||||
# name: name of the protocol
|
# name: name of the probe. These are listed on the command
|
||||||
|
# line (ssh -?), plus 'regex', 'sni' and 'timeout'.
|
||||||
|
|
||||||
# service: (optional) libwrap service name (see hosts_access(5))
|
# service: (optional) libwrap service name (see hosts_access(5))
|
||||||
# host: host name to connect that protocol
|
# host, port: where to connect when this probe succeeds
|
||||||
# port: port number to connect that protocol
|
#
|
||||||
# probe: "builtin" or a list of regular expressions
|
# Probe-specific options:
|
||||||
# (can be left out, e.g. to use with on-timeout)
|
# sni:
|
||||||
|
# sni_hotnames: list of FQDN for that target
|
||||||
|
# regex:
|
||||||
|
# regex_patterns: list of patterns to match for
|
||||||
|
# that target.
|
||||||
#
|
#
|
||||||
# sslh will try each probe in order they are declared, and
|
# sslh will try each probe in order they are declared, and
|
||||||
# connect to the first that matches.
|
# connect to the first that matches.
|
||||||
|
#
|
||||||
|
# You can specify several of 'regex' and 'sni'.
|
||||||
|
|
||||||
protocols:
|
protocols:
|
||||||
(
|
(
|
||||||
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; probe: "builtin"; },
|
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; },
|
||||||
{ name: "sni"; host: "localhost"; port: "993"; probe: "builtin"; sni_hostnames: [ "imap.example.org", "imap.example.com" ]; },
|
{ name: "http"; host: "localhost"; port: "80"; },
|
||||||
{ name: "openvpn"; host: "localhost"; port: "1194"; probe: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; },
|
|
||||||
{ name: "xmpp"; host: "localhost"; port: "5222"; probe: [ "jabber" ]; },
|
{ name: "sni"; host: "localhost"; port: "993"; sni_hostnames: [ "mail.rutschle.net", "mail.englishintoulouse.com" ]; },
|
||||||
{ name: "http"; host: "localhost"; port: "80"; probe: "builtin"; },
|
{ name: "sni"; host: "localhost"; port: "xmpp-client"; sni_hostnames: [ "im.rutschle.net", "im.englishintoulouse.com" ]; },
|
||||||
{ name: "ssl"; host: "localhost"; port: "443"; probe: [ "" ]; },
|
|
||||||
|
# OpenVPN
|
||||||
|
{ name: "regex"; host: "localhost"; port: "1194"; regex_patterns: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; },
|
||||||
|
# Jabber
|
||||||
|
{ name: "regex"; host: "localhost"; port: "5222"; regex_patterns: [ "jabber" ]; },
|
||||||
|
|
||||||
|
# Catch-all
|
||||||
|
{ name: "regex"; host: "localhost"; port: "443"; regex_patterns: [ "" ]; },
|
||||||
|
|
||||||
|
# Where to connect in case of timeout (defaults to ssh)
|
||||||
{ name: "timeout"; service: "daytime"; host: "localhost"; port: "daytime"; }
|
{ name: "timeout"; service: "daytime"; host: "localhost"; port: "daytime"; }
|
||||||
);
|
);
|
||||||
|
|
||||||
# Optionally, specify to which protocol to connect in case
|
# Optionally, specify to which protocol to connect in case
|
||||||
# of timeout (defaults to "ssh").
|
# of timeout (defaults to "ssh").
|
||||||
# You can timeout to any arbitrary address by setting a
|
# You can timeout to any arbitrary address by setting an
|
||||||
# protocol with no probe, as is the case with this example.
|
# entry in 'protocols' named "timeout".
|
||||||
# This enables you to set a tcpd service name for this
|
# This enables you to set a tcpd service name for this
|
||||||
# protocol too.
|
# protocol too.
|
||||||
on-timeout: "timeout";
|
on-timeout: "timeout";
|
||||||
|
9
probe.c
9
probe.c
@ -233,11 +233,13 @@ static int is_sni_protocol(const char *p, int len, struct proto *proto)
|
|||||||
/* Assume does not match */
|
/* Assume does not match */
|
||||||
valid_tls = PROBE_NEXT;
|
valid_tls = PROBE_NEXT;
|
||||||
|
|
||||||
for (sni_hostname = proto->data; *sni_hostname; sni_hostname++)
|
for (sni_hostname = proto->data; *sni_hostname; sni_hostname++) {
|
||||||
|
fprintf(stderr, "matching [%s] with [%s]\n", hostname, *sni_hostname);
|
||||||
if(!strcmp(hostname, *sni_hostname)) {
|
if(!strcmp(hostname, *sni_hostname)) {
|
||||||
valid_tls = PROBE_MATCH;
|
valid_tls = PROBE_MATCH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(hostname);
|
free(hostname);
|
||||||
return valid_tls;
|
return valid_tls;
|
||||||
@ -365,6 +367,11 @@ T_PROBE* get_probe(const char* description) {
|
|||||||
if (!strcmp(description, "sni"))
|
if (!strcmp(description, "sni"))
|
||||||
return is_sni_protocol;
|
return is_sni_protocol;
|
||||||
|
|
||||||
|
/* Special case of "timeout" is allowed as a probe name in the
|
||||||
|
* configuration file even though it's not really a probe */
|
||||||
|
if (!strcmp(description, "timeout"))
|
||||||
|
return is_true;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
sslh-main.c
30
sslh-main.c
@ -249,7 +249,7 @@ static void setup_sni_hostnames(struct proto *p, config_setting_t* sni_hostnames
|
|||||||
#ifdef LIBCONFIG
|
#ifdef LIBCONFIG
|
||||||
static int config_protocols(config_t *config, struct proto **prots)
|
static int config_protocols(config_t *config, struct proto **prots)
|
||||||
{
|
{
|
||||||
config_setting_t *setting, *prot, *probes, *sni_hostnames;
|
config_setting_t *setting, *prot, *patterns, *sni_hostnames;
|
||||||
const char *hostname, *port, *name;
|
const char *hostname, *port, *name;
|
||||||
int i, num_prots;
|
int i, num_prots;
|
||||||
struct proto *p, *prev = NULL;
|
struct proto *p, *prev = NULL;
|
||||||
@ -273,31 +273,22 @@ static int config_protocols(config_t *config, struct proto **prots)
|
|||||||
|
|
||||||
resolve_split_name(&(p->saddr), hostname, port);
|
resolve_split_name(&(p->saddr), hostname, port);
|
||||||
|
|
||||||
|
|
||||||
probes = config_setting_get_member(prot, "probe");
|
|
||||||
if (probes) {
|
|
||||||
if (config_setting_is_array(probes)) {
|
|
||||||
/* If 'probe' is an array, setup a regex probe using the
|
|
||||||
* array of strings as pattern */
|
|
||||||
|
|
||||||
setup_regex_probe(p, probes);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* if 'probe' is 'builtin', set the probe to the
|
|
||||||
* appropriate builtin protocol */
|
|
||||||
if (!strcmp(config_setting_get_string(probes), "builtin")) {
|
|
||||||
p->probe = get_probe(name);
|
p->probe = get_probe(name);
|
||||||
if (!p->probe) {
|
if (!p->probe) {
|
||||||
fprintf(stderr, "%s: no builtin probe for this protocol\n", name);
|
fprintf(stderr, "line %d: %s: probe unknown\n", config_setting_source_line(prot), name);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s: illegal probe name\n", name);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Probe-specific options: regex patterns */
|
||||||
|
if (!strcmp(name, "regex")) {
|
||||||
|
patterns = config_setting_get_member(prot, "regex_patterns");
|
||||||
|
if (patterns && config_setting_is_array(patterns)) {
|
||||||
|
setup_regex_probe(p, patterns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Probe-specific options: SNI hostnames */
|
||||||
|
if (!strcmp(name, "sni")) {
|
||||||
sni_hostnames = config_setting_get_member(prot, "sni_hostnames");
|
sni_hostnames = config_setting_get_member(prot, "sni_hostnames");
|
||||||
if (sni_hostnames && config_setting_is_array(sni_hostnames)) {
|
if (sni_hostnames && config_setting_is_array(sni_hostnames)) {
|
||||||
setup_sni_hostnames(p, sni_hostnames);
|
setup_sni_hostnames(p, sni_hostnames);
|
||||||
@ -305,6 +296,7 @@ static int config_protocols(config_t *config, struct proto **prots)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
6
sslh.pod
6
sslh.pod
@ -51,14 +51,10 @@ and the list of protocols).
|
|||||||
|
|
||||||
The configuration file makes it possible to specify
|
The configuration file makes it possible to specify
|
||||||
protocols using regular expressions: a list of regular
|
protocols using regular expressions: a list of regular
|
||||||
expressions is given as the I<probe> parameter, and if the
|
expressions is given as the I<regex_patterns> parameter, and if the
|
||||||
first packet received from the client matches any of these
|
first packet received from the client matches any of these
|
||||||
expressions, B<sslh> connects to that protocol.
|
expressions, B<sslh> connects to that protocol.
|
||||||
|
|
||||||
Alternatively, the I<probe> parameter can be set to
|
|
||||||
"builtin", to use the compiled probes which are much faster
|
|
||||||
than regular expressions.
|
|
||||||
|
|
||||||
=head2 Probing protocols
|
=head2 Probing protocols
|
||||||
|
|
||||||
When receiving an incoming connection, B<sslh> will read the
|
When receiving an incoming connection, B<sslh> will read the
|
||||||
|
Loading…
Reference in New Issue
Block a user