diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2025-06-10 01:39:15 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska@appnovation.com> | 2025-06-10 01:39:15 +0000 |
| commit | 5db792ba17ce1c372ece1a9d4b152290d4f1b867 (patch) | |
| tree | 7a2e186b483cc82ca509ff5033d90ce2015352a1 | |
| parent | 992508c00caddc5576968bad88b6e6f01344e472 (diff) | |
| download | s6-networking-5db792ba17ce1c372ece1a9d4b152290d4f1b867.tar.gz | |
proxy-server: support in s6-tlsserver
Signed-off-by: Laurent Bercot <ska@appnovation.com>
| -rw-r--r-- | doc/s6-tlsserver.html | 14 | ||||
| -rw-r--r-- | src/conn-tools/proxy-server.c | 75 | ||||
| -rw-r--r-- | src/tls/s6-tlsserver.c | 22 |
3 files changed, 85 insertions, 26 deletions
diff --git a/doc/s6-tlsserver.html b/doc/s6-tlsserver.html index 6f199e7..27bcc66 100644 --- a/doc/s6-tlsserver.html +++ b/doc/s6-tlsserver.html @@ -139,13 +139,25 @@ variables will not appear in <em>prog</em>'s environment. <h2> Options </h2> <p> - <tt>s6-tlsserver</tt> accepts a myriad of options, all of which are + <tt>s6-tlsserver</tt> accepts a myriad of options, most of which are passed as is to the correct executable. Not giving any options will generally work, but unless you're running a very public server (such as a Web server) or base your access control on client certificates, you probably still want TCP access rules. </p> +<h3> Options informing s6-tlsserver behaviour </h3> + +<ul> + <li> <tt>-L</tt> : if this option is given, s6-tlsserver will +add an invocation of <a href="proxy-server.html">proxy-server</a> so that +a PROXY line or binary block is read <em>in cleartext</em> before the +TLS tunnel is established. If the proxy uses the v2 version of the PROXY +protocol and transmits SSL information from the client connection, this +information will be reflected in the SSL environment variables transmitted +to <em>prog</em>. </li> +</ul> + <h3> Options passed as is to s6-tcpserver </h3> <ul> diff --git a/src/conn-tools/proxy-server.c b/src/conn-tools/proxy-server.c index 0d15cea..129955b 100644 --- a/src/conn-tools/proxy-server.c +++ b/src/conn-tools/proxy-server.c @@ -3,6 +3,7 @@ #include <stdint.h> #include <string.h> #include <unistd.h> +#include <stdlib.h> #include <errno.h> #include <skalibs/gccattributes.h> @@ -23,8 +24,25 @@ #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_diefu1sys(111, "stralloc_catb") +enum main_golb_e +{ + MAIN_GOLB_V1, + MAIN_GOLB_V2, + MAIN_GOLB_BEFORE, + MAIN_GOLB_AFTER, + MAIN_GOLB_N +} ; + +enum main_gola_e +{ + MAIN_GOLA_TIMEOUT, + MAIN_GOLA_VERBOSITY, + MAIN_GOLA_N +} ; + static unsigned int verbosity = 1 ; static tain deadline ; +static uint64_t golb = 1 << MAIN_GOLB_V1 | 1 << MAIN_GOLB_V2 ; /* v2 */ @@ -79,7 +97,7 @@ static void process_v2_extensions (char const *s, uint16_t len, int sub) char tmp[n+1] ; if (sub) strerr_dief1x(1, "invalid sub-extension type") ; memcpy(tmp, s, n) ; tmp[n] = 0 ; - if (!env_mexec("SSL_TLS_SNI_SERVERNAME", tmp)) dienomem() ; + if (!env_mexec(golb & 1 << MAIN_GOLB_BEFORE ? "tlsbak_SSL_TLS_SNI_SERVERNAME" : "SSL_TLS_SNI_SERVERNAME", tmp)) dienomem() ; break ; } case 0x20 : /* PP2_TYPE_SSL */ @@ -92,7 +110,7 @@ static void process_v2_extensions (char const *s, uint16_t len, int sub) char tmp[n+1] ; if (!sub) strerr_dief1x(1, "invalid main extension type") ; memcpy(tmp, s, n) ; tmp[n] = 0 ; - if (!env_mexec("SSL_PROTOCOL", tmp)) dienomem() ; + if (!env_mexec(golb & 1 << MAIN_GOLB_BEFORE ? "tlsbak_SSL_PROTOCOL" : "SSL_PROTOCOL", tmp)) dienomem() ; break ; } case 0x22 : /* PP2_SUBTYPE_SSL_CN */ @@ -100,7 +118,7 @@ static void process_v2_extensions (char const *s, uint16_t len, int sub) char tmp[n+1] ; if (!sub) strerr_dief1x(1, "invalid main extension type") ; memcpy(tmp, s, n) ; tmp[n] = 0 ; - if (!env_mexec("SSL_PEER_CERT_CN", tmp)) dienomem() ; + if (!env_mexec(golb & 1 << MAIN_GOLB_BEFORE ? "tlsbak_SSL_PEER_CERT_CN" : "SSL_PEER_CERT_CN", tmp)) dienomem() ; break ; } case 0x23 : /* PP2_SUBTYPE_SSL_CIPHER */ @@ -108,7 +126,7 @@ static void process_v2_extensions (char const *s, uint16_t len, int sub) char tmp[n+1] ; if (!sub) strerr_dief1x(1, "invalid main extension type") ; memcpy(tmp, s, n) ; tmp[n] = 0 ; - if (!env_mexec("SSL_CIPHER", tmp)) dienomem() ; + if (!env_mexec(golb & 1 << MAIN_GOLB_BEFORE ? "tlsbak_SSL_CIPHER" : "SSL_CIPHER", tmp)) dienomem() ; break ; } default : break ; @@ -299,19 +317,28 @@ static void both (void) else maybe_v2(buf) ; } -enum main_golb_e +static void after (void) { - MAIN_GOLB_V1, - MAIN_GOLB_V2, - MAIN_GOLB_N -} ; - -enum main_gola_e -{ - MAIN_GOLA_TIMEOUT, - MAIN_GOLA_VERBOSITY, - MAIN_GOLA_N -} ; + static char const *const vars[] = + { + "SSL_TLS_SNI_SERVERNAME", + "SSL_PROTOCOL", + "SSL_PEER_CERT_CN", + "SSL_CIPHER", + 0 + } ; + for (char const *const *var = vars ; *var ; var++) + { + size_t len = strlen(*var) ; + char const *x ; + char bakvar[8 + len] ; + memcpy(bakvar, "tlsbak_", 7) ; + memcpy(bakvar + 7, *var, len+1) ; + x = getenv(bakvar) ; + if (!x) strerr_dief1x(100, "--after-tlsd can only be used after an invocation with --before-tlsd") ; + if (!env_mexec(bakvar, 0) || !env_mexec(*var, x)) dienomem() ; + } +} int main (int argc, char const *const *argv) { @@ -319,6 +346,8 @@ int main (int argc, char const *const *argv) { { .so = '1', .lo = "disable-v2", .set = 0, .mask = 1 << MAIN_GOLB_V2 }, { .so = '2', .lo = "disable-v1", .set = 0, .mask = 1 << MAIN_GOLB_V1 }, + { .so = 0, .lo = "before-tlsd", .set = 1, .mask = 1 << MAIN_GOLB_BEFORE }, + { .so = 0, .lo = "after-tlsd", .set = 1, .mask = 1 << MAIN_GOLB_AFTER }, } ; static gol_arg const main_gola[MAIN_GOLA_N] = { @@ -326,7 +355,6 @@ int main (int argc, char const *const *argv) { .so = 'v', .lo = "verbosity", .i = MAIN_GOLA_VERBOSITY } } ; - uint64_t golb = 1 << MAIN_GOLB_V1 | 1 << MAIN_GOLB_V2 ; PROG = NAME ; { @@ -350,10 +378,13 @@ int main (int argc, char const *const *argv) PROG_pid_fill(prog_storage, NAME) ; PROG = prog_storage ; - uint64_t ver = golb & (1 << MAIN_GOLB_V1 | 1 << MAIN_GOLB_V2) ; - if (ver == (1 << MAIN_GOLB_V1 | 1 << MAIN_GOLB_V2)) both() ; - else if (ver == 1 << MAIN_GOLB_V2) v2() ; - else if (ver == 1 << MAIN_GOLB_V1) v1() ; - else if (verbosity) strerr_warnw1x("both versions disabled, no proxy protocol expected") ; + if (golb & 1 << MAIN_GOLB_AFTER) after() ; + else switch (golb & (1 << MAIN_GOLB_V1 | 1 << MAIN_GOLB_V2)) + { + case 1 << MAIN_GOLB_V1 | 1 << MAIN_GOLB_V2 : both() ; break ; + case 1 << MAIN_GOLB_V2 : v2() ; break ; + case 1 << MAIN_GOLB_V1 : v1() ; break ; + default : if (verbosity) strerr_warnw1x("both versions disabled, no proxy protocol expected") ; + } xmexec(argv) ; } diff --git a/src/tls/s6-tlsserver.c b/src/tls/s6-tlsserver.c index 5f9c7dd..ee9516c 100644 --- a/src/tls/s6-tlsserver.c +++ b/src/tls/s6-tlsserver.c @@ -13,6 +13,7 @@ #include <s6-networking/config.h> #define USAGE "s6-tlsserver [ options ] ip port prog...\n" \ +"proxy-server options: [ -L ]" \ "s6-tcpserver options: [ -q | -Q | -v ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] [ -b backlog ] [ -G gidlist ] [ -g gid ] [ -u uid ] [ -U ]\n" \ "s6-tcpserver-access options: [ -W | -w ] [ -D | -d ] [ -H ] [ -h ] [ -R | -r ] [ -P | -p ] [ -l localname ] [ -B banner ] [ -t timeout ] [ -i rulesdir | -x rulesfile ]\n" \ "s6-tlsd options: [ -S | -s ] [ -J | -j ] [ -Y | -y ] [ -K timeout ] [ -Z | -z ] [ -k snilevel ]" @@ -36,6 +37,7 @@ struct options_s unsigned int kimeout ; unsigned int snilevel ; unsigned int verbosity : 2 ; + unsigned int flagL : 1 ; unsigned int flag1 : 1 ; unsigned int flagU : 1 ; unsigned int flagw : 1 ; @@ -66,8 +68,9 @@ struct options_s .localmaxconn = 0, \ .timeout = 0, \ .kimeout = 0, \ - .verbosity = 1, \ .snilevel = 0, \ + .verbosity = 1, \ + .flagL = 0, \ .flag1 = 0, \ .flagU = 0, \ .flagw = 0, \ @@ -93,7 +96,7 @@ int main (int argc, char const *const *argv) subgetopt l = SUBGETOPT_ZERO ; for (;;) { - int opt = subgetopt_r(argc, argv, "qQv1c:C:b:G:g:u:UWwDdHhRrPpl:B:t:i:x:SsJjYyK:Zzk:", &l) ; + int opt = subgetopt_r(argc, argv, "qQv1c:C:b:G:g:u:LUWwDdHhRrPpl:B:t:i:x:SsJjYyK:Zzk:", &l) ; if (opt == -1) break ; switch (opt) { @@ -101,6 +104,7 @@ int main (int argc, char const *const *argv) case 'Q' : o.verbosity = 1 ; break ; case 'v' : o.verbosity = 2 ; break ; case '1' : o.flag1 = 1 ; break ; + case 'L' : o.flagL = 1 ; break ; case 'c' : if (!uint0_scan(l.arg, &o.maxconn)) dieusage() ; if (!o.maxconn) o.maxconn = 1 ; break ; case 'C' : if (!uint0_scan(l.arg, &o.localmaxconn)) dieusage() ; if (!o.localmaxconn) o.localmaxconn = 1 ; break ; case 'b' : if (!uint0_scan(l.arg, &o.backlog)) dieusage() ; break ; @@ -144,7 +148,7 @@ int main (int argc, char const *const *argv) size_t pos = 0 ; unsigned int m = 0 ; char fmt[UINT_FMT * 6 + UID_FMT + GID_FMT * (NGROUPS_MAX + 1)] ; - char const *newargv[51 + argc] ; + char const *newargv[57 + argc] ; int doaccess = o.flagw || o.flagD || !o.flagH || o.flagr || o.flagp || o.localname || o.banner || o.timeout || o.rules ; newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver" ; if (o.verbosity != 1) @@ -216,6 +220,12 @@ int main (int argc, char const *const *argv) } newargv[m++] = "--" ; } + if (o.flagL) + { + newargv[m++] = S6_NETWORKING_BINPREFIX "proxy-server" ; + newargv[m++] = "--before-tlsd" ; + newargv[m++] = "--" ; + } newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tlsd" ; if (o.verbosity != 1) { @@ -264,6 +274,12 @@ int main (int argc, char const *const *argv) if (o.flagU) newargv[m++] = "-Uz" ; newargv[m++] = "--" ; } + if (o.flagL) + { + newargv[m++] = S6_NETWORKING_BINPREFIX "proxy-server" ; + newargv[m++] = "--after-tlsd" ; + newargv[m++] = "--" ; + } while (*argv) newargv[m++] = *argv++ ; newargv[m++] = 0 ; xexec(newargv) ; |
