tlsgate

TLS reverse proxy
git clone git://git.akobets.xyz/tlsgate
Log | Files | Refs | README | LICENSE

commit 0b598fe4c85aa00dbaf247c4a111c3a8a05a4db2
parent 17f1bfed4b8bdf02467ca61f9e6cc78fb10f84aa
Author: Artem Kobets <artem@akobets.xyz>
Date:   Mon,  7 Sep 2020 12:50:19 +0300

limit number of connections with a custom counter

RLIMIT_NPROCS approach does not work if process has root privileges

Diffstat:
Mmain.c | 31++++++++++++++++++-------------
Mtlsgate.1 | 8++++----
2 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/main.c b/main.c @@ -3,7 +3,6 @@ #include <signal.h> #include <stdio.h> #include <stdlib.h> -#include <sys/resource.h> #include <sys/wait.h> #include <unistd.h> @@ -21,6 +20,7 @@ static void sigchld(int unused); static void usage(void); char *argv0; +static int conns = 0; void serve(struct tls *ctx, int cfd, const char *server_host, const char *server_port, const char *server_udsfile) @@ -182,7 +182,10 @@ cleanup: static void sigchld(int unused) { - while (wait(NULL) != -1); + // wait for children, remove connection counter when they exit + while (wait(NULL) != -1) { + conns--; + } } static void @@ -191,7 +194,7 @@ usage(void) errx( "usage: %s [-v] -c cert -k key [-C ca]\n" " [-h host] [-p port] [-H host] [-P port] [-U file]\n" - " [-n proc-num]", + " [-n conn-num]", argv0 ); } @@ -209,9 +212,8 @@ main(int argc, char **argv) char *server_host = NULL; char *server_port = NULL; char *server_udsfile = NULL; - int maxnprocs = 512; + int maxconns = 512; - struct rlimit rlim; struct tls *ctx; struct tls_config *config; int fd; @@ -247,7 +249,7 @@ main(int argc, char **argv) server_udsfile = optarg; break; case 'n': - maxnprocs = atol(optarg); + maxconns = atol(optarg); break; case 'v': errx("version %s", VERSION); @@ -271,11 +273,6 @@ main(int argc, char **argv) ) usage(); - // process limit - rlim.rlim_cur = rlim.rlim_max = maxnprocs; - if (setrlimit(RLIMIT_NPROC, &rlim) == -1) - err("setrlimit RLIMIT_NPROC"); - // setup tls if ((ctx = tls_server()) == NULL) err("tls_server"); @@ -305,6 +302,7 @@ main(int argc, char **argv) while (1) { pid_t pid; int cfd = -1; + printf("conns %i\n", conns); if ((cfd = accept(fd, NULL, NULL)) == -1) { // can be interrupted with SIGCHLD @@ -313,6 +311,12 @@ main(int argc, char **argv) continue; } + // connection limit + if (conns >= maxconns) { + warnx("Connection limit reached (%i)", maxconns); + continue; + } + switch (pid = fork()) { case 0: { close(fd); @@ -321,9 +325,10 @@ main(int argc, char **argv) } case -1: warn("fork"); - // fallthrough + close(cfd); + break; default: - // close connection in parent + conns++; close(cfd); break; } diff --git a/tlsgate.1 b/tlsgate.1 @@ -1,11 +1,11 @@ -.TH TLSGATE 1 2020-09-03 +.TH TLSGATE 1 2020-09-07 .SH NAME tlsgate \- TLS reverse proxy .SH SYNOPSIS .B tlsgate [-v] -c cert -k key [-C ca] [-h host] [-p port] [-H host] [-P port] [-U file] -[-n proc-num] +[-n conn-num] .SH DESCRIPTION .B tlsgate is a TLS reverse proxy which can be used to expose an unencrypted connection. @@ -39,8 +39,8 @@ Server port number. .B \-U file Server UNIX domain socket path. .TP -.B \-n proc-num -Maximum number of threads. Default is 512. +.B \-n conn-num +Maximum number of connections. Default is 512. .SH EXAMPLES Accept connections on port 443 and pass them to a local http server on port 80. .PP