From: Philip Papurt Date: Tue, 9 Feb 2021 22:13:35 +0000 (-0500) Subject: net: add support for max_conns X-Git-Tag: 3.0.20210707~13^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32f2287fbb7ab1a6b5cf68d888ed1b702e85df80;p=platform%2Fupstream%2Fnsjail.git net: add support for max_conns --- diff --git a/README.md b/README.md index 5901cb2..78fb8be 100644 --- a/README.md +++ b/README.md @@ -368,6 +368,8 @@ Options: TCP port to bind to (enables MODE_LISTEN_TCP) (default: 0) --bindhost VALUE IP address to bind the port to (only in [MODE_LISTEN_TCP]), (default: '::') + --max_conns VALUE + Maximum number of connections across all IPs (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited)) --max_conns_per_ip|-i VALUE Maximum number of connections per one IP (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited)) --log|-l VALUE diff --git a/cmdline.cc b/cmdline.cc index 88723ae..9a5b8f8 100644 --- a/cmdline.cc +++ b/cmdline.cc @@ -83,6 +83,7 @@ struct custom_option custom_opts[] = { { { "cwd", required_argument, NULL, 'D' }, "Directory in the namespace the process will run (default: '/')" }, { { "port", required_argument, NULL, 'p' }, "TCP port to bind to (enables MODE_LISTEN_TCP) (default: 0)" }, { { "bindhost", required_argument, NULL, 0x604 }, "IP address to bind the port to (only in [MODE_LISTEN_TCP]), (default: '::')" }, + { { "max_conns", required_argument, NULL, 0x608 }, "Maximum number of connections across all IPs (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited))" }, { { "max_conns_per_ip", required_argument, NULL, 'i' }, "Maximum number of connections per one IP (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited))" }, { { "log", required_argument, NULL, 'l' }, "Log file (default: use log_fd)" }, { { "log_fd", required_argument, NULL, 'L' }, "Log FD (default: 2)" }, @@ -226,19 +227,19 @@ void logParams(nsjconf_t* nsjconf) { LOG_I( "Jail parameters: hostname:'%s', chroot:'%s', process:'%s', bind:[%s]:%d, " - "max_conns_per_ip:%u, time_limit:%" PRId64 + "max_conns:%u, max_conns_per_ip:%u, time_limit:%" PRId64 ", personality:%#lx, daemonize:%s, clone_newnet:%s, " "clone_newuser:%s, clone_newns:%s, clone_newpid:%s, clone_newipc:%s, clone_newuts:%s, " "clone_newcgroup:%s, keep_caps:%s, disable_no_new_privs:%s, max_cpus:%zu", nsjconf->hostname.c_str(), nsjconf->chroot.c_str(), nsjconf->exec_file.empty() ? nsjconf->argv[0].c_str() : nsjconf->exec_file.c_str(), - nsjconf->bindhost.c_str(), nsjconf->port, nsjconf->max_conns_per_ip, nsjconf->tlimit, - nsjconf->personality, logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet), - logYesNo(nsjconf->clone_newuser), logYesNo(nsjconf->clone_newns), - logYesNo(nsjconf->clone_newpid), logYesNo(nsjconf->clone_newipc), - logYesNo(nsjconf->clone_newuts), logYesNo(nsjconf->clone_newcgroup), - logYesNo(nsjconf->keep_caps), logYesNo(nsjconf->disable_no_new_privs), - nsjconf->max_cpus); + nsjconf->bindhost.c_str(), nsjconf->port, nsjconf->max_conns, nsjconf->max_conns_per_ip, + nsjconf->tlimit, nsjconf->personality, logYesNo(nsjconf->daemonize), + logYesNo(nsjconf->clone_newnet), logYesNo(nsjconf->clone_newuser), + logYesNo(nsjconf->clone_newns), logYesNo(nsjconf->clone_newpid), + logYesNo(nsjconf->clone_newipc), logYesNo(nsjconf->clone_newuts), + logYesNo(nsjconf->clone_newcgroup), logYesNo(nsjconf->keep_caps), + logYesNo(nsjconf->disable_no_new_privs), nsjconf->max_cpus); for (const auto& p : nsjconf->mountpts) { LOG_I( @@ -423,6 +424,7 @@ std::unique_ptr parseArgs(int argc, char* argv[]) { nsjconf->is_silent = false; nsjconf->stderr_to_null = false; nsjconf->skip_setsid = false; + nsjconf->max_conns = 0; nsjconf->max_conns_per_ip = 0; nsjconf->proc_path = "/proc"; nsjconf->is_proc_rw = false; @@ -503,6 +505,9 @@ std::unique_ptr parseArgs(int argc, char* argv[]) { case 0x604: nsjconf->bindhost = optarg; break; + case 0x608: + nsjconf->max_conns = strtoul(optarg, NULL, 0); + break; case 'i': nsjconf->max_conns_per_ip = strtoul(optarg, NULL, 0); break; diff --git a/config.cc b/config.cc index f9ca867..bf8cee6 100644 --- a/config.cc +++ b/config.cc @@ -86,6 +86,7 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig& nsjconf->cwd = njc.cwd(); nsjconf->port = njc.port(); nsjconf->bindhost = njc.bindhost(); + nsjconf->max_conns = njc.max_conns(); nsjconf->max_conns_per_ip = njc.max_conns_per_ip(); nsjconf->tlimit = njc.time_limit(); nsjconf->max_cpus = njc.max_cpus(); diff --git a/config.proto b/config.proto index db1e6c7..6b03dcf 100644 --- a/config.proto +++ b/config.proto @@ -90,6 +90,8 @@ message NsJailConfig { optional uint32 port = 10 [default = 0]; /* Host to bind to for mode=LISTEN. Must be in IPv6 format */ optional string bindhost = 11 [default = "::"]; + /* For mode=LISTEN, maximum number of connections across all IPs */ + optional uint32 max_conns = 85 [default = 0]; /* For mode=LISTEN, maximum number of connections from a single IP */ optional uint32 max_conns_per_ip = 12 [default = 0]; diff --git a/net.cc b/net.cc index c17a24c..5259f9c 100644 --- a/net.cc +++ b/net.cc @@ -181,6 +181,12 @@ static bool isSocket(int fd) { } bool limitConns(nsjconf_t* nsjconf, int connsock) { + /* 0 means 'unlimited' */ + if (nsjconf->max_conns != 0 && nsjconf->pids.size() >= nsjconf->max_conns) { + LOG_W("Rejecting connection, max_conns limit reached: %u", nsjconf->max_conns); + return false; + } + /* 0 means 'unlimited' */ if (nsjconf->max_conns_per_ip == 0) { return true; diff --git a/nsjail.1 b/nsjail.1 index 7714de7..439f8e1 100644 --- a/nsjail.1 +++ b/nsjail.1 @@ -61,6 +61,9 @@ TCP port to bind to (enables MODE_LISTEN_TCP) (default: 0) \fB\-\-bindhost\fR VALUE IP address to bind the port to (only in [MODE_LISTEN_TCP]), (default: '::') .TP +\fB\-\-max_conns\fR VALUE +Maximum number of connections across all IPs (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited)) +.TP \fB\-\-max_conns_per_ip\fR|\fB\-i\fR VALUE Maximum number of connections per one IP (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited)) .TP diff --git a/nsjail.h b/nsjail.h index fda3392..038a62e 100644 --- a/nsjail.h +++ b/nsjail.h @@ -129,6 +129,7 @@ struct nsjconf_t { bool is_silent; bool stderr_to_null; bool skip_setsid; + unsigned int max_conns; unsigned int max_conns_per_ip; std::string proc_path; bool is_proc_rw;