diff --git a/doc/sample.config b/doc/sample.config index 592c7e44..fdeb42de 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -33,7 +33,7 @@ auth = "plain[./sample.passwd]" # Whether to enable seccomp worker isolation. That restricts the number of # system calls allowed to a worker process, in order to reduce damage from a # bug in the worker process. It is available on Linux systems at a performance cost. -#use-seccomp = true +isolate-workers = true # A banner to be displayed on clients #banner = "Welcome" diff --git a/src/config.c b/src/config.c index a70c91ba..b33b7138 100644 --- a/src/config.c +++ b/src/config.c @@ -90,6 +90,7 @@ static struct cfg_options available_options[] = { { .name = "occtl-socket-file", .type = OPTION_STRING, .mandatory = 0 }, { .name = "banner", .type = OPTION_STRING, .mandatory = 0 }, { .name = "use-seccomp", .type = OPTION_BOOLEAN, .mandatory = 0 }, + { .name = "isolate-worker", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "predictable-ips", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "session-control", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "auto-select-group", .type = OPTION_BOOLEAN, .mandatory = 0 }, @@ -569,10 +570,16 @@ unsigned force_cert_auth; config->cisco_client_compat = 1; } - READ_TF("use-seccomp", config->seccomp, 0); -#ifndef HAVE_LIBSECCOMP - if (config->seccomp != 0) { - fprintf(stderr, "error: 'use-seccomp' is set to true, but not compiled with seccomp support\n"); + READ_TF("use-seccomp", config->isolate, 0); + if (config->isolate) { + fprintf(stderr, "note that 'use-seccomp' was replaced by 'isolate-workers'\n"); + config->cisco_client_compat = 1; + } else { + READ_TF("isolate-workers", config->isolate, 0); + } +#if !defined(HAVE_LIBSECCOMP) && !defined(ENABLE_LINUX_NS) + if (config->isolate != 0) { + fprintf(stderr, "error: 'isolate-workers' is set to true, but not compiled with seccomp or Linux namespaces support\n"); exit(1); } #endif diff --git a/src/main.c b/src/main.c index b5238f63..d1616349 100644 --- a/src/main.c +++ b/src/main.c @@ -882,6 +882,8 @@ static int check_tcp_wrapper(int fd) # define check_tcp_wrapper(x) 0 #endif +typedef pid_t (*fork_func)(void); + int main(int argc, char** argv) { int fd, pid, e; @@ -903,6 +905,7 @@ int main(int argc, char** argv) sigset_t emptyset, blockset; /* tls credentials */ struct tls_st creds; + fork_func our_fork = fork; #ifdef DEBUG_LEAKS talloc_enable_leak_report_full(); @@ -1000,6 +1003,10 @@ int main(int argc, char** argv) } } + /* override the default fork function */ + if (s->config->isolate) + our_fork = safe_fork; + write_pid_file(); run_sec_mod(s); @@ -1122,7 +1129,7 @@ int main(int argc, char** argv) break; } - pid = safe_fork(); + pid = our_fork(); if (pid == 0) { /* child */ /* close any open descriptors, and erase * sensitive data before running the worker diff --git a/src/ocserv-args.def b/src/ocserv-args.def index dc422fc7..489e8cd4 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -104,10 +104,12 @@ An example configuration file follows. # Framed-IP-Address, Framed-IP-Netmask, MS-Primary-DNS-Server, MS-Secondary-DNS-Server #auth = "radius[/etc/radiusclient/radiusclient.conf,groupconfig]" -# Whether to enable seccomp worker isolation. That restricts the number of +# Whether to enable seccomp/Linux namespaces worker isolation. That restricts the number of # system calls allowed to a worker process, in order to reduce damage from a # bug in the worker process. It is available on Linux systems at a performance cost. -#use-seccomp = true +# The performance cost is roughly double the time needed for fork() per client, and +# 2% overhead at transfer time (tested on a Linux 3.17.8). +#isolate-workers = true # A banner to be displayed on clients #banner = "Welcome" diff --git a/src/vpn.h b/src/vpn.h index 3dc8c660..5e696034 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -240,7 +240,7 @@ struct cfg_st { time_t min_reauth_time; /* after a failed auth, how soon one can reauthenticate -> in seconds */ - unsigned seccomp; /* whether seccomp should be enabled or not */ + unsigned isolate; /* whether seccomp should be enabled or not */ unsigned auth_timeout; /* timeout of HTTP auth */ unsigned idle_timeout; /* timeout when idle */ diff --git a/src/worker-vpn.c b/src/worker-vpn.c index a5301af8..64244267 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -782,7 +782,7 @@ void vpn_server(struct worker_st *ws) /* do not allow this process to be traced. That * prevents worker processes tracing each other. */ pr_set_undumpable("worker"); - if (ws->config->seccomp != 0) { + if (ws->config->isolate != 0) { ret = disable_system_calls(ws); if (ret < 0) { oclog(ws, LOG_INFO,