Commit 8fdaf6eb08555e01c9993ffbf52f7e4ac40c3d15
changed configuration file to accomodate SNI in a cleaner way
Yves Rutschle committed on 7/17/2015, 1:04:04 PMParent: 77ef29358d7cfb5962cab175995e9e48399a991d
Files changed
ChangeLog | changed |
basic.cfg | changed |
example.cfg | changed |
probe.c | changed |
sslh-main.c | changed |
sslh.pod | changed |
ChangeLog | ||
---|---|---|
@@ -4,8 +4,13 @@ | ||
4 | 4 | |
5 | 5 | Added support for RFC4366 SNI |
6 | 6 | (Travis Burtrum) |
7 | 7 | |
8 | + Changed configuration file format: 'probe' field is | |
9 | + no longer required, 'name' field can now contain | |
10 | + 'sni' or 'regex', with corresponding options (see | |
11 | + example.org) | |
12 | + | |
8 | 13 | v1.17: 09MAR2015 |
9 | 14 | Support RFC5952-style IPv6 addresses, e.g. [::]:443. |
10 | 15 | |
11 | 16 | Transparant proxy support for FreeBSD. |
basic.cfg | ||
---|---|---|
@@ -18,12 +18,12 @@ | ||
18 | 18 | ); |
19 | 19 | |
20 | 20 | protocols: |
21 | 21 | ( |
22 | - { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; probe: "builtin"; }, | |
23 | - { name: "openvpn"; host: "localhost"; port: "1194"; probe: "builtin"; }, | |
24 | - { name: "xmpp"; host: "localhost"; port: "5222"; probe: "builtin"; }, | |
25 | - { name: "http"; host: "localhost"; port: "80"; probe: "builtin"; }, | |
26 | - { name: "ssl"; host: "localhost"; port: "443"; probe: "builtin"; }, | |
27 | - { name: "anyprot"; host: "localhost"; port: "443"; probe: "builtin"; } | |
22 | + { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; }, | |
23 | + { name: "openvpn"; host: "localhost"; port: "1194"; }, | |
24 | + { name: "xmpp"; host: "localhost"; port: "5222"; }, | |
25 | + { name: "http"; host: "localhost"; port: "80"; }, | |
26 | + { name: "ssl"; host: "localhost"; port: "443"; }, | |
27 | + { name: "anyprot"; host: "localhost"; port: "443"; } | |
28 | 28 | ); |
29 | 29 |
example.cfg | ||
---|---|---|
@@ -22,33 +22,50 @@ | ||
22 | 22 | |
23 | 23 | # List of protocols |
24 | 24 | # |
25 | 25 | # Each protocol entry consists of: |
26 | -# name: name of the protocol | |
26 | +# name: name of the probe. These are listed on the command | |
27 | +# line (ssh -?), plus 'regex', 'sni' and 'timeout'. | |
28 | + | |
27 | 29 | # service: (optional) libwrap service name (see hosts_access(5)) |
28 | -# host: host name to connect that protocol | |
29 | -# port: port number to connect that protocol | |
30 | -# probe: "builtin" or a list of regular expressions | |
31 | -# (can be left out, e.g. to use with on-timeout) | |
30 | +# host, port: where to connect when this probe succeeds | |
31 | +# | |
32 | +# Probe-specific options: | |
33 | +# sni: | |
34 | +# sni_hotnames: list of FQDN for that target | |
35 | +# regex: | |
36 | +# regex_patterns: list of patterns to match for | |
37 | +# that target. | |
32 | 38 | # |
33 | 39 | # sslh will try each probe in order they are declared, and |
34 | 40 | # connect to the first that matches. |
35 | - | |
41 | +# | |
42 | +# You can specify several of 'regex' and 'sni'. | |
43 | + | |
36 | 44 | protocols: |
37 | 45 | ( |
38 | - { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; probe: "builtin"; }, | |
39 | - { name: "sni"; host: "localhost"; port: "993"; probe: "builtin"; sni_hostnames: [ "imap.example.org", "imap.example.com" ]; }, | |
40 | - { name: "openvpn"; host: "localhost"; port: "1194"; probe: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; }, | |
41 | - { name: "xmpp"; host: "localhost"; port: "5222"; probe: [ "jabber" ]; }, | |
42 | - { name: "http"; host: "localhost"; port: "80"; probe: "builtin"; }, | |
43 | - { name: "ssl"; host: "localhost"; port: "443"; probe: [ "" ]; }, | |
46 | + { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; }, | |
47 | + { name: "http"; host: "localhost"; port: "80"; }, | |
48 | + | |
49 | + { name: "sni"; host: "localhost"; port: "993"; sni_hostnames: [ "mail.rutschle.net", "mail.englishintoulouse.com" ]; }, | |
50 | + { name: "sni"; host: "localhost"; port: "xmpp-client"; sni_hostnames: [ "im.rutschle.net", "im.englishintoulouse.com" ]; }, | |
51 | + | |
52 | +# OpenVPN | |
53 | + { name: "regex"; host: "localhost"; port: "1194"; regex_patterns: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; }, | |
54 | +# Jabber | |
55 | + { name: "regex"; host: "localhost"; port: "5222"; regex_patterns: [ "jabber" ]; }, | |
56 | + | |
57 | +# Catch-all | |
58 | + { name: "regex"; host: "localhost"; port: "443"; regex_patterns: [ "" ]; }, | |
59 | + | |
60 | +# Where to connect in case of timeout (defaults to ssh) | |
44 | 61 | { name: "timeout"; service: "daytime"; host: "localhost"; port: "daytime"; } |
45 | 62 | ); |
46 | 63 | |
47 | 64 | # Optionally, specify to which protocol to connect in case |
48 | 65 | # of timeout (defaults to "ssh"). |
49 | -# You can timeout to any arbitrary address by setting a | |
50 | -# protocol with no probe, as is the case with this example. | |
66 | +# You can timeout to any arbitrary address by setting an | |
67 | +# entry in 'protocols' named "timeout". | |
51 | 68 | # This enables you to set a tcpd service name for this |
52 | 69 | # protocol too. |
53 | 70 | on-timeout: "timeout"; |
54 | 71 |
probe.c | ||
---|---|---|
@@ -232,13 +232,15 @@ | ||
232 | 232 | |
233 | 233 | /* Assume does not match */ |
234 | 234 | valid_tls = PROBE_NEXT; |
235 | 235 | |
236 | - for (sni_hostname = proto->data; *sni_hostname; sni_hostname++) | |
236 | + for (sni_hostname = proto->data; *sni_hostname; sni_hostname++) { | |
237 | + fprintf(stderr, "matching [%s] with [%s]\n", hostname, *sni_hostname); | |
237 | 238 | if(!strcmp(hostname, *sni_hostname)) { |
238 | 239 | valid_tls = PROBE_MATCH; |
239 | 240 | break; |
240 | 241 | } |
242 | + } | |
241 | 243 | |
242 | 244 | free(hostname); |
243 | 245 | return valid_tls; |
244 | 246 | } |
@@ -364,8 +366,13 @@ | ||
364 | 366 | /* Special case of "sni" probe for same reason as above*/ |
365 | 367 | if (!strcmp(description, "sni")) |
366 | 368 | return is_sni_protocol; |
367 | 369 | |
370 | + /* Special case of "timeout" is allowed as a probe name in the | |
371 | + * configuration file even though it's not really a probe */ | |
372 | + if (!strcmp(description, "timeout")) | |
373 | + return is_true; | |
374 | + | |
368 | 375 | return NULL; |
369 | 376 | } |
370 | 377 | |
371 | 378 |
sslh-main.c | ||
---|---|---|
@@ -248,9 +248,9 @@ | ||
248 | 248 | */ |
249 | 249 | |
250 | 250 | static int config_protocols(config_t *config, struct proto **prots) |
251 | 251 | { |
252 | - config_setting_t *setting, *prot, *probes, *sni_hostnames; | |
252 | + config_setting_t *setting, *prot, *patterns, *sni_hostnames; | |
253 | 253 | const char *hostname, *port, *name; |
254 | 254 | int i, num_prots; |
255 | 255 | struct proto *p, *prev = NULL; |
256 | 256 | |
@@ -272,36 +272,28 @@ | ||
272 | 272 | config_setting_lookup_string(prot, "service", &(p->service)); |
273 | 273 | |
274 | 274 | resolve_split_name(&(p->saddr), hostname, port); |
275 | 275 | |
276 | + p->probe = get_probe(name); | |
277 | + if (!p->probe) { | |
278 | + fprintf(stderr, "line %d: %s: probe unknown\n", config_setting_source_line(prot), name); | |
279 | + exit(1); | |
280 | + } | |
276 | 281 | |
277 | - probes = config_setting_get_member(prot, "probe"); | |
278 | - if (probes) { | |
279 | - if (config_setting_is_array(probes)) { | |
280 | - /* If 'probe' is an array, setup a regex probe using the | |
281 | - * array of strings as pattern */ | |
282 | - | |
283 | - setup_regex_probe(p, probes); | |
284 | - | |
285 | - } else { | |
286 | - /* if 'probe' is 'builtin', set the probe to the | |
287 | - * appropriate builtin protocol */ | |
288 | - if (!strcmp(config_setting_get_string(probes), "builtin")) { | |
289 | - p->probe = get_probe(name); | |
290 | - if (!p->probe) { | |
291 | - fprintf(stderr, "%s: no builtin probe for this protocol\n", name); | |
292 | - exit(1); | |
293 | - } | |
294 | - } else { | |
295 | - fprintf(stderr, "%s: illegal probe name\n", name); | |
296 | - exit(1); | |
297 | - } | |
282 | + /* Probe-specific options: regex patterns */ | |
283 | + if (!strcmp(name, "regex")) { | |
284 | + patterns = config_setting_get_member(prot, "regex_patterns"); | |
285 | + if (patterns && config_setting_is_array(patterns)) { | |
286 | + setup_regex_probe(p, patterns); | |
298 | 287 | } |
299 | 288 | } |
300 | 289 | |
301 | - sni_hostnames = config_setting_get_member(prot, "sni_hostnames"); | |
302 | - if (sni_hostnames && config_setting_is_array(sni_hostnames)) { | |
303 | - setup_sni_hostnames(p, sni_hostnames); | |
290 | + /* Probe-specific options: SNI hostnames */ | |
291 | + if (!strcmp(name, "sni")) { | |
292 | + sni_hostnames = config_setting_get_member(prot, "sni_hostnames"); | |
293 | + if (sni_hostnames && config_setting_is_array(sni_hostnames)) { | |
294 | + setup_sni_hostnames(p, sni_hostnames); | |
295 | + } | |
304 | 296 | } |
305 | 297 | } |
306 | 298 | } |
307 | 299 | } |
sslh.pod | ||
---|---|---|
@@ -50,16 +50,12 @@ | ||
50 | 50 | and the list of protocols). |
51 | 51 | |
52 | 52 | The configuration file makes it possible to specify |
53 | 53 | protocols using regular expressions: a list of regular |
54 | -expressions is given as the I<probe> parameter, and if the | |
54 | +expressions is given as the I<regex_patterns> parameter, and if the | |
55 | 55 | first packet received from the client matches any of these |
56 | 56 | expressions, B<sslh> connects to that protocol. |
57 | 57 | |
58 | -Alternatively, the I<probe> parameter can be set to | |
59 | -"builtin", to use the compiled probes which are much faster | |
60 | -than regular expressions. | |
61 | - | |
62 | 58 | =head2 Probing protocols |
63 | 59 | |
64 | 60 | When receiving an incoming connection, B<sslh> will read the |
65 | 61 | first bytes sent be the connecting client. It will then |
Built with git-ssb-web