2013-04-17 22:34:27 +02:00
|
|
|
/*
|
2022-01-31 22:02:06 +01:00
|
|
|
* Copyright (c) 2013-2022 Joris Vink <joris@coders.se>
|
2013-04-17 22:34:27 +02:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2015-05-20 16:36:13 +02:00
|
|
|
#include <sys/types.h>
|
2016-01-18 11:30:22 +01:00
|
|
|
#include <sys/stat.h>
|
2018-10-07 20:49:16 +02:00
|
|
|
#include <sys/un.h>
|
2016-01-18 11:30:22 +01:00
|
|
|
|
2013-04-17 22:34:27 +02:00
|
|
|
#include <sys/socket.h>
|
2015-05-20 16:36:13 +02:00
|
|
|
#include <sys/resource.h>
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2019-03-29 16:24:14 +01:00
|
|
|
#include <libgen.h>
|
2018-10-26 19:19:47 +02:00
|
|
|
#include <fcntl.h>
|
2016-01-22 12:08:13 +01:00
|
|
|
#include <stdio.h>
|
2013-07-27 20:56:15 +02:00
|
|
|
#include <netdb.h>
|
2013-05-03 00:04:06 +02:00
|
|
|
#include <signal.h>
|
2013-04-17 22:34:27 +02:00
|
|
|
|
|
|
|
#include "kore.h"
|
2021-01-11 23:58:26 +01:00
|
|
|
#include "hooks.h"
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2016-01-18 11:30:22 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
|
|
|
#include "http.h"
|
|
|
|
#endif
|
|
|
|
|
2019-04-24 00:10:47 +02:00
|
|
|
#if defined(KORE_USE_CURL)
|
|
|
|
#include "curl.h"
|
|
|
|
#endif
|
|
|
|
|
2019-09-04 19:57:28 +02:00
|
|
|
#if defined(KORE_USE_PGSQL)
|
|
|
|
#include "pgsql.h"
|
|
|
|
#endif
|
|
|
|
|
2017-01-12 23:38:51 +01:00
|
|
|
#if defined(KORE_USE_PYTHON)
|
|
|
|
#include "python_api.h"
|
|
|
|
#endif
|
|
|
|
|
2023-01-21 23:41:35 +01:00
|
|
|
#if defined(KORE_USE_LUA)
|
|
|
|
#include "lua_api.h"
|
|
|
|
#endif
|
|
|
|
|
2019-11-06 19:33:53 +01:00
|
|
|
#if defined(KORE_USE_ACME)
|
|
|
|
#include "acme.h"
|
|
|
|
#endif
|
|
|
|
|
2018-04-13 16:05:59 +02:00
|
|
|
volatile sig_atomic_t sig_recv;
|
2019-09-27 20:00:35 +02:00
|
|
|
struct kore_server_list kore_servers;
|
2013-07-27 20:56:15 +02:00
|
|
|
u_int8_t nlisteners;
|
2019-03-29 16:24:14 +01:00
|
|
|
int kore_argc = 0;
|
2013-06-26 11:18:32 +02:00
|
|
|
pid_t kore_pid = -1;
|
2013-06-17 23:39:17 +02:00
|
|
|
u_int16_t cpu_count = 1;
|
2018-11-15 16:01:37 +01:00
|
|
|
int kore_quiet = 0;
|
2015-05-18 21:34:39 +02:00
|
|
|
int skip_runas = 0;
|
2018-07-11 09:44:29 +02:00
|
|
|
int skip_chroot = 0;
|
|
|
|
u_int8_t worker_count = 0;
|
2019-03-29 16:24:14 +01:00
|
|
|
char **kore_argv = NULL;
|
2023-01-05 22:47:29 +01:00
|
|
|
int kore_mem_guard = 0;
|
2023-01-16 21:00:01 +01:00
|
|
|
int kore_foreground = 1;
|
2019-03-29 16:24:14 +01:00
|
|
|
char *kore_progname = NULL;
|
2015-04-09 15:29:44 +02:00
|
|
|
u_int32_t kore_socket_backlog = 5000;
|
2022-08-08 11:02:27 +02:00
|
|
|
int kore_quit = KORE_QUIT_NONE;
|
2013-06-04 16:53:30 +02:00
|
|
|
char *kore_pidfile = KORE_PIDFILE_DEFAULT;
|
2013-04-17 22:34:27 +02:00
|
|
|
|
Rework worker startup/privsep config.
Starting with the privsep config, this commit changes the following:
- Removes the root, runas, keymgr_root, keymgr_runas, acme_root and
acme_runas configuration options.
Instead these are now configured via a privsep configuration context:
privsep worker {
root /tmp
runas nobody
}
This is also configurable via Python using the new kore.privsep() method:
kore.privsep("worker", root="/tmp", runas="nobody", skip=["chroot"])
Tied into this we also better handle worker startup:
- Per worker process, wait until it signalled it is ready.
- If a worker fails at startup, display its last log lines more clearly.
- Don't start acme process if no domain requires acme.
- Remove each process its individual startup log message in favour
of a generalized one that displays its PID, root and user.
- At startup, log the kore version and built-ins in a nicer way.
- The worker processes now check things they need to start running
before signaling they are ready (such as access to CA certs for
TLS client authentication).
2021-09-07 21:59:22 +02:00
|
|
|
struct kore_privsep worker_privsep;
|
|
|
|
|
2019-03-29 16:24:14 +01:00
|
|
|
extern char **environ;
|
2016-07-06 16:16:15 +02:00
|
|
|
extern char *__progname;
|
2019-04-29 21:08:58 +02:00
|
|
|
static size_t proctitle_maxlen = 0;
|
2016-07-06 16:16:15 +02:00
|
|
|
|
2013-06-05 08:55:07 +02:00
|
|
|
static void usage(void);
|
2014-07-04 09:25:18 +02:00
|
|
|
static void version(void);
|
2020-09-08 22:38:06 +02:00
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
static void kore_write_kore_pid(void);
|
2019-04-29 21:08:58 +02:00
|
|
|
static void kore_proctitle_setup(void);
|
2021-11-03 17:23:05 +01:00
|
|
|
static void kore_server_shutdown(void);
|
2018-10-18 17:18:41 +02:00
|
|
|
static void kore_server_start(int, char *[]);
|
2019-09-26 20:38:02 +02:00
|
|
|
static void kore_call_parent_configure(int, char **);
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2023-01-16 21:00:01 +01:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
|
|
|
static const char *rarg0 = NULL;
|
|
|
|
#endif
|
|
|
|
|
2019-09-26 20:38:02 +02:00
|
|
|
static const char *parent_config_hook = KORE_CONFIG_HOOK;
|
|
|
|
static const char *parent_teardown_hook = KORE_TEARDOWN_HOOK;
|
2023-01-16 21:00:01 +01:00
|
|
|
|
2019-09-26 20:38:02 +02:00
|
|
|
#if defined(KORE_SINGLE_BINARY)
|
|
|
|
static const char *parent_daemonized_hook = KORE_DAEMONIZED_HOOK;
|
2019-09-26 15:49:00 +02:00
|
|
|
#endif
|
|
|
|
|
2013-06-05 08:55:07 +02:00
|
|
|
static void
|
|
|
|
usage(void)
|
|
|
|
{
|
2023-01-21 23:41:35 +01:00
|
|
|
if (kore_runtime_count() > 0) {
|
|
|
|
printf("Usage: %s [options] [app | script]\n", __progname);
|
|
|
|
} else {
|
|
|
|
printf("Usage: %s [options]\n", __progname);
|
|
|
|
}
|
2018-04-02 18:20:57 +02:00
|
|
|
|
2019-09-26 16:41:52 +02:00
|
|
|
printf("\n");
|
2023-01-05 22:47:29 +01:00
|
|
|
printf("Command-line options:\n");
|
2020-10-08 13:51:50 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2023-01-05 22:47:29 +01:00
|
|
|
printf("\t-c\tThe configuration file to load when starting.\n");
|
2020-10-08 13:51:50 +02:00
|
|
|
#endif
|
2023-01-05 22:47:29 +01:00
|
|
|
printf("\t-f\tDo not daemonize, everything runs in the foreground.\n");
|
|
|
|
printf("\t-h\tThis help text.\n");
|
|
|
|
printf("\t-n\tDo not do the chroot privsep step.\n");
|
|
|
|
printf("\t-q\tQuiet mode, only logs errors.\n");
|
|
|
|
printf("\t-r\tDo not do the privsep user swapping step.\n");
|
|
|
|
printf("\t-v\tDisplay %s build information.\n", __progname);
|
2014-08-01 13:59:47 +02:00
|
|
|
|
2023-01-05 22:47:29 +01:00
|
|
|
printf("\n");
|
|
|
|
printf("Environment options:\n");
|
|
|
|
printf(" env KORE_MEM_GUARD=1\n");
|
|
|
|
printf(" Enables memory pool guards and other protections.\n");
|
|
|
|
printf("\n");
|
|
|
|
printf(" Enabling this will include guard pages for each\n");
|
|
|
|
printf(" pool entry allocations and mark pool entries as\n");
|
|
|
|
printf(" PROT_NONE when unused.\n");
|
|
|
|
printf("\n");
|
|
|
|
printf(" This catches bugs and prevents memory vulnerabilities\n");
|
|
|
|
printf(" but with performance and memory pressure costs.\n");
|
|
|
|
|
|
|
|
printf("\n");
|
2018-04-02 18:20:57 +02:00
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
exit(1);
|
2013-06-05 08:55:07 +02:00
|
|
|
}
|
|
|
|
|
2014-07-04 09:25:18 +02:00
|
|
|
static void
|
|
|
|
version(void)
|
|
|
|
{
|
2018-06-19 19:05:55 +02:00
|
|
|
printf("%s ", kore_version);
|
2015-11-27 16:22:50 +01:00
|
|
|
#if defined(KORE_NO_HTTP)
|
|
|
|
printf("no-http ");
|
|
|
|
#endif
|
2019-04-24 00:10:47 +02:00
|
|
|
#if defined(KORE_USE_CURL)
|
2019-10-22 17:06:32 +02:00
|
|
|
printf("curl-%s ", LIBCURL_VERSION);
|
2019-04-24 00:10:47 +02:00
|
|
|
#endif
|
2014-07-04 09:25:18 +02:00
|
|
|
#if defined(KORE_USE_PGSQL)
|
|
|
|
printf("pgsql ");
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_TASKS)
|
|
|
|
printf("tasks ");
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
2017-01-25 22:21:30 +01:00
|
|
|
#if defined(KORE_USE_PYTHON)
|
2019-10-15 10:16:53 +02:00
|
|
|
printf("python-%s ", PY_VERSION);
|
2019-11-13 23:01:24 +01:00
|
|
|
#endif
|
2023-01-21 23:41:35 +01:00
|
|
|
#if defined(KORE_USE_LUA)
|
|
|
|
printf("lua-%s.%s.%s ",
|
|
|
|
LUA_VERSION_MAJOR, LUA_VERSION_MINOR, LUA_VERSION_RELEASE);
|
|
|
|
#endif
|
2019-11-13 23:01:24 +01:00
|
|
|
#if defined(KORE_USE_ACME)
|
|
|
|
printf("acme ");
|
2023-01-05 22:47:29 +01:00
|
|
|
#endif
|
|
|
|
#if defined(KORE_DEBUG)
|
|
|
|
printf("debug ");
|
2017-01-25 22:21:30 +01:00
|
|
|
#endif
|
2022-02-17 13:45:28 +01:00
|
|
|
if (!kore_tls_supported())
|
|
|
|
printf("notls ");
|
2023-01-05 22:47:29 +01:00
|
|
|
|
2014-07-04 09:25:18 +02:00
|
|
|
printf("\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2013-04-17 22:34:27 +02:00
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
2023-01-16 21:00:01 +01:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2019-06-12 23:35:43 +02:00
|
|
|
struct stat st;
|
|
|
|
#endif
|
2023-01-16 21:00:01 +01:00
|
|
|
struct kore_runtime_call *rcall;
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2019-03-29 16:24:14 +01:00
|
|
|
kore_argc = argc;
|
|
|
|
kore_argv = argv;
|
2014-08-01 13:59:47 +02:00
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2020-10-08 13:51:50 +02:00
|
|
|
kore_default_getopt(argc, argv);
|
2020-09-08 22:38:06 +02:00
|
|
|
#endif
|
2013-06-05 08:55:07 +02:00
|
|
|
|
2019-03-29 16:24:14 +01:00
|
|
|
kore_mem_init();
|
2021-09-13 15:33:42 +02:00
|
|
|
kore_msg_init();
|
|
|
|
kore_log_init();
|
2023-01-06 10:54:07 +01:00
|
|
|
kore_tls_init();
|
2021-09-13 15:33:42 +02:00
|
|
|
|
2019-03-29 16:24:14 +01:00
|
|
|
kore_progname = kore_strdup(argv[0]);
|
2019-04-29 21:08:58 +02:00
|
|
|
kore_proctitle_setup();
|
2019-03-29 16:24:14 +01:00
|
|
|
|
2020-09-08 22:38:06 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2013-06-05 08:55:07 +02:00
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
2020-09-08 22:38:06 +02:00
|
|
|
#endif
|
2013-06-05 08:55:07 +02:00
|
|
|
|
2023-01-16 21:00:01 +01:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
|
|
|
if (kore_runtime_count() > 0) {
|
|
|
|
if (argc > 0) {
|
|
|
|
rarg0 = argv[0];
|
|
|
|
argc--;
|
|
|
|
argv++;
|
2019-09-26 20:38:02 +02:00
|
|
|
}
|
|
|
|
|
2023-01-16 21:00:01 +01:00
|
|
|
if (rarg0) {
|
|
|
|
if (lstat(rarg0, &st) == -1) {
|
|
|
|
if (errno == ENOENT)
|
|
|
|
rarg0 = NULL;
|
|
|
|
else
|
|
|
|
fatal("stat(%s): %s", rarg0, errno_s);
|
|
|
|
}
|
|
|
|
}
|
2019-09-26 20:38:02 +02:00
|
|
|
}
|
2018-04-09 12:51:20 +02:00
|
|
|
#endif
|
2017-02-22 20:09:11 +01:00
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
kore_pid = getpid();
|
2013-07-27 20:56:15 +02:00
|
|
|
nlisteners = 0;
|
2019-09-27 20:00:35 +02:00
|
|
|
LIST_INIT(&kore_servers);
|
2013-07-27 20:56:15 +02:00
|
|
|
|
2019-09-25 14:25:49 +02:00
|
|
|
kore_platform_init();
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2018-06-28 13:27:44 +02:00
|
|
|
http_parent_init();
|
2019-04-24 00:10:47 +02:00
|
|
|
#if defined(KORE_USE_CURL)
|
|
|
|
kore_curl_sysinit();
|
2019-09-04 19:57:28 +02:00
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_PGSQL)
|
|
|
|
kore_pgsql_sys_init();
|
2019-04-24 00:10:47 +02:00
|
|
|
#endif
|
2014-01-22 22:55:10 +01:00
|
|
|
kore_auth_init();
|
2015-11-27 16:22:50 +01:00
|
|
|
kore_validator_init();
|
2018-06-28 13:27:44 +02:00
|
|
|
kore_filemap_init();
|
2019-11-06 19:33:53 +01:00
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_ACME)
|
|
|
|
kore_acme_init();
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
2013-06-24 11:32:45 +02:00
|
|
|
kore_domain_init();
|
2013-12-15 01:11:56 +01:00
|
|
|
kore_module_init();
|
2013-06-27 08:43:07 +02:00
|
|
|
|
2023-01-21 23:41:35 +01:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
|
|
|
if (kore_runtime_count() == 0 && config_file == NULL)
|
2014-07-31 17:15:51 +02:00
|
|
|
usage();
|
2018-06-28 13:27:44 +02:00
|
|
|
#endif
|
2017-01-12 23:38:51 +01:00
|
|
|
kore_module_load(NULL, NULL, KORE_MODULE_NATIVE);
|
2018-11-12 09:01:05 +01:00
|
|
|
|
|
|
|
#if defined(KORE_USE_PYTHON)
|
|
|
|
kore_python_init();
|
2019-06-12 23:35:43 +02:00
|
|
|
#endif
|
2023-01-16 21:00:01 +01:00
|
|
|
|
2023-01-21 23:41:35 +01:00
|
|
|
#if defined(KORE_USE_LUA)
|
|
|
|
kore_lua_init();
|
|
|
|
#endif
|
|
|
|
|
2023-01-16 21:00:01 +01:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
|
|
|
if (kore_runtime_count() > 0 && rarg0 != NULL)
|
|
|
|
kore_runtime_resolve(rarg0, &st);
|
2018-11-12 09:01:05 +01:00
|
|
|
#endif
|
2019-09-26 20:38:02 +02:00
|
|
|
|
|
|
|
#if defined(KORE_SINGLE_BINARY)
|
|
|
|
kore_call_parent_configure(argc, argv);
|
2023-01-16 21:00:01 +01:00
|
|
|
#else
|
|
|
|
if (kore_runtime_count() > 0 && rarg0 != NULL)
|
2019-09-26 20:38:02 +02:00
|
|
|
kore_call_parent_configure(argc, argv);
|
2018-10-18 17:18:41 +02:00
|
|
|
#endif
|
2014-07-31 17:15:51 +02:00
|
|
|
|
2019-09-26 15:49:00 +02:00
|
|
|
kore_parse_config();
|
2019-09-26 20:38:02 +02:00
|
|
|
|
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2019-09-26 19:58:13 +02:00
|
|
|
free(config_file);
|
2019-09-26 20:38:02 +02:00
|
|
|
#endif
|
2019-09-26 15:49:00 +02:00
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2016-01-18 11:30:22 +01:00
|
|
|
if (http_body_disk_offload > 0) {
|
|
|
|
if (mkdir(http_body_disk_path, 0700) == -1 && errno != EEXIST) {
|
|
|
|
printf("can't create http_body_disk_path '%s': %s\n",
|
|
|
|
http_body_disk_path, errno_s);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
}
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
2013-05-04 22:18:27 +02:00
|
|
|
|
2018-05-25 20:49:02 +02:00
|
|
|
kore_signal_setup();
|
2018-10-18 17:18:41 +02:00
|
|
|
kore_server_start(argc, argv);
|
2021-11-03 17:23:05 +01:00
|
|
|
kore_server_shutdown();
|
2018-10-23 21:46:34 +02:00
|
|
|
|
2019-09-26 20:38:02 +02:00
|
|
|
rcall = kore_runtime_getcall(parent_teardown_hook);
|
2018-10-23 21:46:34 +02:00
|
|
|
if (rcall != NULL) {
|
|
|
|
kore_runtime_execute(rcall);
|
|
|
|
kore_free(rcall);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlink(kore_pidfile) == -1 && errno != ENOENT)
|
|
|
|
kore_log(LOG_NOTICE, "failed to remove pidfile (%s)", errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_server_cleanup();
|
2018-11-15 16:01:37 +01:00
|
|
|
|
|
|
|
if (!kore_quiet)
|
Rework worker startup/privsep config.
Starting with the privsep config, this commit changes the following:
- Removes the root, runas, keymgr_root, keymgr_runas, acme_root and
acme_runas configuration options.
Instead these are now configured via a privsep configuration context:
privsep worker {
root /tmp
runas nobody
}
This is also configurable via Python using the new kore.privsep() method:
kore.privsep("worker", root="/tmp", runas="nobody", skip=["chroot"])
Tied into this we also better handle worker startup:
- Per worker process, wait until it signalled it is ready.
- If a worker fails at startup, display its last log lines more clearly.
- Don't start acme process if no domain requires acme.
- Remove each process its individual startup log message in favour
of a generalized one that displays its PID, root and user.
- At startup, log the kore version and built-ins in a nicer way.
- The worker processes now check things they need to start running
before signaling they are ready (such as access to CA certs for
TLS client authentication).
2021-09-07 21:59:22 +02:00
|
|
|
kore_log(LOG_INFO, "goodbye");
|
2016-06-08 13:55:14 +02:00
|
|
|
|
2017-02-06 11:42:53 +01:00
|
|
|
#if defined(KORE_USE_PYTHON)
|
|
|
|
kore_python_cleanup();
|
|
|
|
#endif
|
|
|
|
|
2023-01-21 23:41:35 +01:00
|
|
|
#if defined(KORE_USE_LUA)
|
|
|
|
kore_lua_cleanup();
|
|
|
|
#endif
|
|
|
|
|
2017-02-06 11:42:53 +01:00
|
|
|
kore_mem_cleanup();
|
|
|
|
|
2022-08-08 11:02:27 +02:00
|
|
|
return (kore_quit);
|
2013-04-17 22:34:27 +02:00
|
|
|
}
|
|
|
|
|
2020-10-08 13:51:50 +02:00
|
|
|
void
|
|
|
|
kore_default_getopt(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2023-01-16 21:00:01 +01:00
|
|
|
while ((ch = getopt(argc, argv, "c:dfhnqrv")) != -1) {
|
2020-10-08 13:51:50 +02:00
|
|
|
#else
|
2023-01-16 21:00:01 +01:00
|
|
|
while ((ch = getopt(argc, argv, "dfhnqrv")) != -1) {
|
2020-10-08 13:51:50 +02:00
|
|
|
#endif
|
|
|
|
switch (ch) {
|
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
|
|
|
case 'c':
|
|
|
|
free(config_file);
|
|
|
|
if ((config_file = strdup(optarg)) == NULL)
|
|
|
|
fatal("strdup");
|
|
|
|
break;
|
|
|
|
#endif
|
2023-01-16 21:00:01 +01:00
|
|
|
case 'd':
|
|
|
|
kore_foreground = 0;
|
|
|
|
break;
|
2020-10-08 13:51:50 +02:00
|
|
|
case 'f':
|
2023-01-16 21:00:01 +01:00
|
|
|
printf("note: -f is the default now, "
|
|
|
|
"use -d to daemonize\n");
|
2020-10-08 13:51:50 +02:00
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
usage();
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
skip_chroot = 1;
|
|
|
|
break;
|
|
|
|
case 'q':
|
|
|
|
kore_quiet = 1;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
skip_runas = 1;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
version();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-27 20:56:15 +02:00
|
|
|
int
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_server_bind(struct kore_server *srv, const char *ip, const char *port,
|
2019-09-27 12:22:35 +02:00
|
|
|
const char *ccb)
|
2013-07-27 20:56:15 +02:00
|
|
|
{
|
2017-02-22 22:23:30 +01:00
|
|
|
int r;
|
2019-09-27 20:00:35 +02:00
|
|
|
struct listener *l;
|
2015-06-14 16:54:44 +02:00
|
|
|
struct addrinfo hints, *results;
|
2013-07-27 20:56:15 +02:00
|
|
|
|
2015-06-14 16:54:44 +02:00
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
hints.ai_family = AF_UNSPEC;
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
hints.ai_protocol = IPPROTO_TCP;
|
|
|
|
hints.ai_flags = 0;
|
|
|
|
|
|
|
|
r = getaddrinfo(ip, port, &hints, &results);
|
2013-07-27 20:56:15 +02:00
|
|
|
if (r != 0)
|
|
|
|
fatal("getaddrinfo(%s): %s", ip, gai_strerror(r));
|
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
l = kore_listener_create(srv);
|
|
|
|
l->host = kore_strdup(ip);
|
|
|
|
l->port = kore_strdup(port);
|
|
|
|
|
2019-12-13 09:14:26 +01:00
|
|
|
if (!kore_listener_init(l, results->ai_family, ccb)) {
|
2013-07-27 20:56:15 +02:00
|
|
|
freeaddrinfo(results);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
if (bind(l->fd, results->ai_addr, results->ai_addrlen) == -1) {
|
|
|
|
kore_listener_free(l);
|
2013-07-27 20:56:15 +02:00
|
|
|
freeaddrinfo(results);
|
2018-10-07 20:49:16 +02:00
|
|
|
kore_log(LOG_ERR, "bind(): %s", errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
freeaddrinfo(results);
|
|
|
|
|
|
|
|
if (listen(l->fd, kore_socket_backlog) == -1) {
|
|
|
|
kore_listener_free(l);
|
|
|
|
kore_log(LOG_ERR, "listen(): %s", errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_server_bind_unix(struct kore_server *srv, const char *path,
|
|
|
|
const char *ccb)
|
2018-10-07 20:49:16 +02:00
|
|
|
{
|
2019-09-27 20:00:35 +02:00
|
|
|
struct listener *l;
|
2018-10-15 20:18:54 +02:00
|
|
|
int len;
|
2018-10-07 20:49:16 +02:00
|
|
|
struct sockaddr_un sun;
|
2018-10-15 20:18:54 +02:00
|
|
|
socklen_t socklen;
|
2018-10-07 20:49:16 +02:00
|
|
|
|
|
|
|
memset(&sun, 0, sizeof(sun));
|
|
|
|
sun.sun_family = AF_UNIX;
|
|
|
|
|
2018-10-15 20:18:54 +02:00
|
|
|
len = snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", path);
|
|
|
|
if (len == -1 || (size_t)len >= sizeof(sun.sun_path)) {
|
2018-10-07 20:49:16 +02:00
|
|
|
kore_log(LOG_ERR, "unix socket path '%s' too long", path);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2018-10-15 20:18:54 +02:00
|
|
|
#if defined(__linux__)
|
|
|
|
if (sun.sun_path[0] == '@')
|
|
|
|
sun.sun_path[0] = '\0';
|
|
|
|
socklen = sizeof(sun.sun_family) + len;
|
2019-05-28 21:44:46 +02:00
|
|
|
#else
|
|
|
|
socklen = sizeof(sun);
|
|
|
|
#endif
|
2018-10-15 20:18:54 +02:00
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
l = kore_listener_create(srv);
|
|
|
|
l->host = kore_strdup(path);
|
|
|
|
|
2019-12-13 09:14:26 +01:00
|
|
|
if (!kore_listener_init(l, AF_UNIX, ccb))
|
2018-10-07 20:49:16 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
|
2021-04-08 09:25:19 +02:00
|
|
|
if (sun.sun_path[0] != '\0') {
|
|
|
|
if (unlink(sun.sun_path) == -1 && errno != ENOENT) {
|
|
|
|
kore_log(LOG_ERR, "unlink: %s: %s",
|
|
|
|
sun.sun_path, errno_s);
|
|
|
|
kore_listener_free(l);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 20:18:54 +02:00
|
|
|
if (bind(l->fd, (struct sockaddr *)&sun, socklen) == -1) {
|
2018-10-07 20:49:16 +02:00
|
|
|
kore_log(LOG_ERR, "bind: %s", errno_s);
|
|
|
|
kore_listener_free(l);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
2013-07-27 20:56:15 +02:00
|
|
|
|
2015-04-09 15:29:44 +02:00
|
|
|
if (listen(l->fd, kore_socket_backlog) == -1) {
|
2017-02-01 17:12:11 +01:00
|
|
|
kore_log(LOG_ERR, "listen(): %s", errno_s);
|
2018-10-07 20:49:16 +02:00
|
|
|
kore_listener_free(l);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
}
|
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
struct kore_server *
|
|
|
|
kore_server_create(const char *name)
|
|
|
|
{
|
|
|
|
struct kore_server *srv;
|
|
|
|
|
|
|
|
srv = kore_calloc(1, sizeof(struct kore_server));
|
|
|
|
srv->name = kore_strdup(name);
|
2022-02-17 13:45:28 +01:00
|
|
|
|
|
|
|
if (kore_tls_supported())
|
|
|
|
srv->tls = 1;
|
|
|
|
else
|
|
|
|
srv->tls = 0;
|
2019-09-27 20:00:35 +02:00
|
|
|
|
|
|
|
TAILQ_INIT(&srv->domains);
|
|
|
|
LIST_INIT(&srv->listeners);
|
|
|
|
|
|
|
|
LIST_INSERT_HEAD(&kore_servers, srv, list);
|
|
|
|
|
|
|
|
return (srv);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_server_finalize(struct kore_server *srv)
|
|
|
|
{
|
|
|
|
struct listener *l;
|
|
|
|
const char *proto;
|
|
|
|
|
|
|
|
if (kore_quiet)
|
|
|
|
return;
|
|
|
|
|
|
|
|
LIST_FOREACH(l, &srv->listeners, list) {
|
|
|
|
if (srv->tls)
|
|
|
|
proto = "https";
|
|
|
|
else
|
|
|
|
proto = "http";
|
|
|
|
|
|
|
|
if (l->family == AF_UNIX) {
|
Rework worker startup/privsep config.
Starting with the privsep config, this commit changes the following:
- Removes the root, runas, keymgr_root, keymgr_runas, acme_root and
acme_runas configuration options.
Instead these are now configured via a privsep configuration context:
privsep worker {
root /tmp
runas nobody
}
This is also configurable via Python using the new kore.privsep() method:
kore.privsep("worker", root="/tmp", runas="nobody", skip=["chroot"])
Tied into this we also better handle worker startup:
- Per worker process, wait until it signalled it is ready.
- If a worker fails at startup, display its last log lines more clearly.
- Don't start acme process if no domain requires acme.
- Remove each process its individual startup log message in favour
of a generalized one that displays its PID, root and user.
- At startup, log the kore version and built-ins in a nicer way.
- The worker processes now check things they need to start running
before signaling they are ready (such as access to CA certs for
TLS client authentication).
2021-09-07 21:59:22 +02:00
|
|
|
kore_log(LOG_INFO, "%s serving %s on %s",
|
2019-09-27 20:00:35 +02:00
|
|
|
srv->name, proto, l->host);
|
|
|
|
} else {
|
Rework worker startup/privsep config.
Starting with the privsep config, this commit changes the following:
- Removes the root, runas, keymgr_root, keymgr_runas, acme_root and
acme_runas configuration options.
Instead these are now configured via a privsep configuration context:
privsep worker {
root /tmp
runas nobody
}
This is also configurable via Python using the new kore.privsep() method:
kore.privsep("worker", root="/tmp", runas="nobody", skip=["chroot"])
Tied into this we also better handle worker startup:
- Per worker process, wait until it signalled it is ready.
- If a worker fails at startup, display its last log lines more clearly.
- Don't start acme process if no domain requires acme.
- Remove each process its individual startup log message in favour
of a generalized one that displays its PID, root and user.
- At startup, log the kore version and built-ins in a nicer way.
- The worker processes now check things they need to start running
before signaling they are ready (such as access to CA certs for
TLS client authentication).
2021-09-07 21:59:22 +02:00
|
|
|
kore_log(LOG_INFO, "%s serving %s on %s:%s",
|
2019-09-27 20:00:35 +02:00
|
|
|
srv->name, proto, l->host, l->port);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
struct listener *
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_listener_create(struct kore_server *server)
|
2019-09-27 12:22:35 +02:00
|
|
|
{
|
|
|
|
struct listener *l;
|
|
|
|
|
|
|
|
l = kore_calloc(1, sizeof(struct listener));
|
|
|
|
|
|
|
|
nlisteners++;
|
2019-09-27 20:00:35 +02:00
|
|
|
LIST_INSERT_HEAD(&server->listeners, l, list);
|
2019-09-27 12:22:35 +02:00
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
l->server = server;
|
2019-09-27 12:22:35 +02:00
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
l->fd = -1;
|
2019-09-27 12:22:35 +02:00
|
|
|
l->evt.type = KORE_TYPE_LISTENER;
|
|
|
|
l->evt.handle = kore_listener_accept;
|
|
|
|
|
|
|
|
return (l);
|
|
|
|
}
|
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
struct kore_server *
|
|
|
|
kore_server_lookup(const char *name)
|
2018-10-07 20:49:16 +02:00
|
|
|
{
|
2019-09-27 20:00:35 +02:00
|
|
|
struct kore_server *srv;
|
2018-10-07 20:49:16 +02:00
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
LIST_FOREACH(srv, &kore_servers, list) {
|
|
|
|
if (!strcmp(srv->name, name))
|
|
|
|
return (srv);
|
2019-09-27 12:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
kore_listener_init(struct listener *l, int family, const char *ccb)
|
|
|
|
{
|
2018-10-07 20:49:16 +02:00
|
|
|
switch (family) {
|
|
|
|
case AF_INET:
|
|
|
|
case AF_INET6:
|
|
|
|
case AF_UNIX:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fatal("unknown address family %d", family);
|
|
|
|
}
|
|
|
|
|
|
|
|
l->family = family;
|
2018-10-09 19:34:40 +02:00
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
if ((l->fd = socket(family, SOCK_STREAM, 0)) == -1) {
|
|
|
|
kore_listener_free(l);
|
|
|
|
kore_log(LOG_ERR, "socket(): %s", errno_s);
|
2019-09-27 12:22:35 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
2018-10-07 20:49:16 +02:00
|
|
|
}
|
|
|
|
|
2018-10-26 19:19:47 +02:00
|
|
|
if (fcntl(l->fd, F_SETFD, FD_CLOEXEC) == -1) {
|
|
|
|
kore_listener_free(l);
|
|
|
|
kore_log(LOG_ERR, "fcntl(): %s", errno_s);
|
2019-09-27 12:22:35 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
2018-10-26 19:19:47 +02:00
|
|
|
}
|
|
|
|
|
2018-10-07 21:21:37 +02:00
|
|
|
if (!kore_connection_nonblock(l->fd, family != AF_UNIX)) {
|
2018-10-07 20:49:16 +02:00
|
|
|
kore_listener_free(l);
|
|
|
|
kore_log(LOG_ERR, "kore_connection_nonblock(): %s", errno_s);
|
2019-09-27 12:22:35 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
2018-10-07 20:49:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!kore_sockopt(l->fd, SOL_SOCKET, SO_REUSEADDR)) {
|
|
|
|
kore_listener_free(l);
|
2019-09-27 12:22:35 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
2018-10-07 20:49:16 +02:00
|
|
|
}
|
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
if (ccb != NULL) {
|
2017-01-12 23:38:51 +01:00
|
|
|
if ((l->connect = kore_runtime_getcall(ccb)) == NULL) {
|
2017-02-01 17:12:11 +01:00
|
|
|
kore_log(LOG_ERR, "no such callback: '%s'", ccb);
|
2018-10-07 20:49:16 +02:00
|
|
|
kore_listener_free(l);
|
2019-09-27 12:22:35 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
2015-11-27 16:22:50 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
l->connect = NULL;
|
|
|
|
}
|
|
|
|
|
2019-09-27 12:22:35 +02:00
|
|
|
return (KORE_RESULT_OK);
|
2018-10-07 20:49:16 +02:00
|
|
|
}
|
2014-08-01 20:00:09 +02:00
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
void
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_server_free(struct kore_server *srv)
|
2018-10-07 20:49:16 +02:00
|
|
|
{
|
2019-09-27 20:00:35 +02:00
|
|
|
struct listener *l;
|
2019-09-27 12:22:35 +02:00
|
|
|
struct kore_domain *dom;
|
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
LIST_REMOVE(srv, list);
|
|
|
|
|
|
|
|
while ((dom = TAILQ_FIRST(&srv->domains)) != NULL)
|
2019-09-27 12:22:35 +02:00
|
|
|
kore_domain_free(dom);
|
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
while ((l = LIST_FIRST(&srv->listeners)) != NULL)
|
|
|
|
kore_listener_free(l);
|
|
|
|
|
|
|
|
kore_free(srv->name);
|
|
|
|
kore_free(srv);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_listener_free(struct listener *l)
|
|
|
|
{
|
2021-04-08 09:25:19 +02:00
|
|
|
int rm;
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
LIST_REMOVE(l, list);
|
|
|
|
|
|
|
|
if (l->fd != -1)
|
|
|
|
close(l->fd);
|
|
|
|
|
2021-04-08 09:25:19 +02:00
|
|
|
rm = 0;
|
|
|
|
|
|
|
|
#if defined(__linux__)
|
|
|
|
if (worker == NULL && l->family == AF_UNIX && l->host[0] != '@')
|
|
|
|
rm++;
|
|
|
|
#else
|
|
|
|
if (worker == NULL && l->family == AF_UNIX)
|
|
|
|
rm++;
|
|
|
|
#endif
|
|
|
|
if (rm) {
|
|
|
|
if (unlink(l->host) == -1) {
|
|
|
|
kore_log(LOG_NOTICE,
|
|
|
|
"failed to remove unix socket %s (%s)", l->host,
|
|
|
|
errno_s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_free(l->host);
|
|
|
|
kore_free(l->port);
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
kore_free(l);
|
2013-07-27 20:56:15 +02:00
|
|
|
}
|
|
|
|
|
2018-10-09 19:34:40 +02:00
|
|
|
void
|
|
|
|
kore_listener_accept(void *arg, int error)
|
|
|
|
{
|
|
|
|
struct connection *c;
|
|
|
|
struct listener *l = arg;
|
|
|
|
u_int32_t accepted;
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
fatal("error on listening socket");
|
|
|
|
|
|
|
|
if (!(l->evt.flags & KORE_EVENT_READ))
|
|
|
|
return;
|
|
|
|
|
|
|
|
accepted = 0;
|
|
|
|
|
|
|
|
while (worker_active_connections < worker_max_connections) {
|
|
|
|
if (worker_accept_threshold != 0 &&
|
2018-10-22 09:01:05 +02:00
|
|
|
accepted >= worker_accept_threshold) {
|
|
|
|
kore_worker_make_busy();
|
2018-10-09 19:34:40 +02:00
|
|
|
break;
|
2018-10-22 09:01:05 +02:00
|
|
|
}
|
2018-10-09 19:34:40 +02:00
|
|
|
|
|
|
|
if (!kore_connection_accept(l, &c))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (c == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
accepted++;
|
|
|
|
kore_platform_event_all(c->fd, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-22 22:23:30 +01:00
|
|
|
int
|
|
|
|
kore_sockopt(int fd, int what, int opt)
|
|
|
|
{
|
|
|
|
int on;
|
|
|
|
|
|
|
|
on = 1;
|
|
|
|
if (setsockopt(fd, what, opt, (const char *)&on, sizeof(on)) == -1) {
|
|
|
|
kore_log(LOG_ERR, "setsockopt(): %s", errno_s);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
}
|
|
|
|
|
2018-05-25 20:49:02 +02:00
|
|
|
void
|
|
|
|
kore_signal_setup(void)
|
2021-12-22 09:50:26 +01:00
|
|
|
{
|
|
|
|
kore_signal_trap(SIGHUP);
|
|
|
|
kore_signal_trap(SIGQUIT);
|
|
|
|
kore_signal_trap(SIGTERM);
|
|
|
|
kore_signal_trap(SIGUSR1);
|
|
|
|
kore_signal_trap(SIGCHLD);
|
|
|
|
|
|
|
|
if (kore_foreground)
|
|
|
|
kore_signal_trap(SIGINT);
|
|
|
|
else
|
|
|
|
(void)signal(SIGINT, SIG_IGN);
|
|
|
|
|
|
|
|
(void)signal(SIGPIPE, SIG_IGN);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_signal_trap(int sig)
|
2018-05-25 20:49:02 +02:00
|
|
|
{
|
|
|
|
struct sigaction sa;
|
|
|
|
|
|
|
|
sig_recv = 0;
|
|
|
|
memset(&sa, 0, sizeof(sa));
|
|
|
|
sa.sa_handler = kore_signal;
|
|
|
|
|
|
|
|
if (sigfillset(&sa.sa_mask) == -1)
|
|
|
|
fatal("sigfillset: %s", errno_s);
|
|
|
|
|
2021-12-22 09:50:26 +01:00
|
|
|
if (sigaction(sig, &sa, NULL) == -1)
|
2018-05-25 20:49:02 +02:00
|
|
|
fatal("sigaction: %s", errno_s);
|
|
|
|
}
|
|
|
|
|
2019-09-27 12:22:35 +02:00
|
|
|
void
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_server_closeall(void)
|
2019-09-27 12:22:35 +02:00
|
|
|
{
|
|
|
|
struct listener *l;
|
2019-09-27 20:00:35 +02:00
|
|
|
struct kore_server *srv;
|
2019-09-27 12:22:35 +02:00
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
LIST_FOREACH(srv, &kore_servers, list) {
|
|
|
|
LIST_FOREACH(l, &srv->listeners, list)
|
|
|
|
l->fd = -1;
|
|
|
|
}
|
2019-09-27 12:22:35 +02:00
|
|
|
}
|
|
|
|
|
2016-06-08 13:55:14 +02:00
|
|
|
void
|
2019-09-27 20:00:35 +02:00
|
|
|
kore_server_cleanup(void)
|
2016-06-08 13:55:14 +02:00
|
|
|
{
|
2019-09-27 20:00:35 +02:00
|
|
|
struct kore_server *srv;
|
2016-06-08 13:55:14 +02:00
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
while ((srv = LIST_FIRST(&kore_servers)) != NULL)
|
|
|
|
kore_server_free(srv);
|
2016-06-08 13:55:14 +02:00
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
void
|
|
|
|
kore_signal(int sig)
|
|
|
|
{
|
|
|
|
sig_recv = sig;
|
|
|
|
}
|
|
|
|
|
2018-10-23 19:49:42 +02:00
|
|
|
void
|
|
|
|
kore_shutdown(void)
|
|
|
|
{
|
|
|
|
if (worker != NULL) {
|
|
|
|
kore_msg_send(KORE_MSG_PARENT, KORE_MSG_SHUTDOWN, NULL, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
fatal("kore_shutdown: called from parent");
|
|
|
|
}
|
|
|
|
|
2019-03-29 16:24:14 +01:00
|
|
|
void
|
|
|
|
kore_proctitle(const char *title)
|
|
|
|
{
|
2019-04-29 21:08:58 +02:00
|
|
|
int len;
|
|
|
|
|
|
|
|
kore_argv[1] = NULL;
|
|
|
|
|
|
|
|
len = snprintf(kore_argv[0], proctitle_maxlen, "%s %s",
|
|
|
|
basename(kore_progname), title);
|
|
|
|
if (len == -1 || (size_t)len >= proctitle_maxlen)
|
|
|
|
fatal("proctitle '%s' too large", title);
|
|
|
|
|
|
|
|
memset(kore_argv[0] + len, 0, proctitle_maxlen - len);
|
|
|
|
}
|
|
|
|
|
2023-01-16 21:00:01 +01:00
|
|
|
void
|
|
|
|
kore_hooks_set(const char *config, const char *teardown, const char *daemonized)
|
|
|
|
{
|
|
|
|
parent_config_hook = config;
|
|
|
|
parent_teardown_hook = teardown;
|
|
|
|
|
|
|
|
#if defined(KORE_SINGLE_BINARY)
|
|
|
|
parent_daemonized_hook = daemonized;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-04-29 21:08:58 +02:00
|
|
|
static void
|
|
|
|
kore_proctitle_setup(void)
|
|
|
|
{
|
|
|
|
int i;
|
2019-03-29 16:24:14 +01:00
|
|
|
char *p;
|
|
|
|
|
2019-04-29 21:08:58 +02:00
|
|
|
proctitle_maxlen = 0;
|
2019-03-29 16:24:14 +01:00
|
|
|
|
|
|
|
for (i = 0; environ[i] != NULL; i++) {
|
2019-08-27 13:12:44 +02:00
|
|
|
if ((p = strdup(environ[i])) == NULL)
|
|
|
|
fatal("strdup");
|
2019-04-29 21:08:58 +02:00
|
|
|
proctitle_maxlen += strlen(environ[i]) + 1;
|
2019-03-29 16:24:14 +01:00
|
|
|
environ[i] = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; kore_argv[i] != NULL; i++)
|
2019-04-29 21:08:58 +02:00
|
|
|
proctitle_maxlen += strlen(kore_argv[i]) + 1;
|
2019-03-29 16:24:14 +01:00
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
static void
|
2018-10-18 17:18:41 +02:00
|
|
|
kore_server_start(int argc, char *argv[])
|
2013-06-26 11:18:32 +02:00
|
|
|
{
|
2017-01-12 23:38:51 +01:00
|
|
|
u_int32_t tmp;
|
2019-10-07 10:31:35 +02:00
|
|
|
struct kore_server *srv;
|
2019-03-21 10:17:08 +01:00
|
|
|
u_int64_t netwait;
|
2021-11-03 17:23:05 +01:00
|
|
|
int last_sig;
|
2022-01-28 14:29:58 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
|
|
|
int alog;
|
|
|
|
struct kore_domain *dom;
|
|
|
|
#endif
|
2019-09-26 20:38:02 +02:00
|
|
|
#if defined(KORE_SINGLE_BINARY)
|
2019-09-26 16:05:01 +02:00
|
|
|
struct kore_runtime_call *rcall;
|
|
|
|
#endif
|
2019-09-26 15:49:00 +02:00
|
|
|
|
2021-09-07 23:26:36 +02:00
|
|
|
if (!kore_quiet) {
|
|
|
|
kore_log(LOG_INFO, "%s %s starting, built=%s",
|
|
|
|
__progname, kore_version, kore_build_date);
|
2023-01-05 22:47:29 +01:00
|
|
|
kore_log(LOG_INFO, "memory pool protections: %s",
|
|
|
|
kore_mem_guard ? "enabled" : "disabled");
|
2021-09-07 23:26:36 +02:00
|
|
|
kore_log(LOG_INFO, "built-ins: "
|
|
|
|
#if defined(__linux__)
|
|
|
|
"seccomp "
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_PGSQL)
|
|
|
|
"pgsql "
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_TASKS)
|
|
|
|
"tasks "
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_JSONRPC)
|
|
|
|
"jsonrpc "
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_PYTHON)
|
|
|
|
"python "
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_ACME)
|
|
|
|
"acme "
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_CURL)
|
|
|
|
"curl "
|
2023-01-23 21:56:49 +01:00
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_LUA)
|
|
|
|
"lua "
|
2021-09-07 23:26:36 +02:00
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-01-16 21:00:01 +01:00
|
|
|
kore_tls_log_version();
|
|
|
|
|
2021-01-11 23:35:16 +01:00
|
|
|
if (kore_foreground == 0) {
|
2018-10-18 17:18:41 +02:00
|
|
|
if (daemon(1, 0) == -1)
|
|
|
|
fatal("cannot daemon(): %s", errno_s);
|
|
|
|
#if defined(KORE_SINGLE_BINARY)
|
2019-09-26 20:38:02 +02:00
|
|
|
rcall = kore_runtime_getcall(parent_daemonized_hook);
|
2018-10-18 17:18:41 +02:00
|
|
|
if (rcall != NULL) {
|
|
|
|
kore_runtime_execute(rcall);
|
|
|
|
kore_free(rcall);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2013-06-26 11:18:32 +02:00
|
|
|
|
|
|
|
kore_pid = getpid();
|
2017-02-22 20:38:07 +01:00
|
|
|
kore_write_kore_pid();
|
2013-06-26 11:18:32 +02:00
|
|
|
|
2023-01-16 21:00:01 +01:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
|
|
|
if (kore_runtime_count() == 0 || rarg0 == NULL)
|
2019-09-26 20:38:02 +02:00
|
|
|
kore_call_parent_configure(argc, argv);
|
2017-02-09 13:36:08 +01:00
|
|
|
#endif
|
|
|
|
|
2021-05-02 00:23:11 +02:00
|
|
|
#if defined(KORE_USE_PYTHON)
|
|
|
|
kore_python_routes_resolve();
|
|
|
|
#endif
|
|
|
|
|
2019-10-07 10:31:35 +02:00
|
|
|
/* Check if keymgr will be active. */
|
2022-02-17 13:45:28 +01:00
|
|
|
if (kore_tls_supported()) {
|
|
|
|
LIST_FOREACH(srv, &kore_servers, list) {
|
|
|
|
if (srv->tls) {
|
|
|
|
kore_keymgr_active = 1;
|
|
|
|
break;
|
|
|
|
}
|
2019-10-07 10:31:35 +02:00
|
|
|
}
|
2022-02-17 13:45:28 +01:00
|
|
|
} else {
|
|
|
|
kore_keymgr_active = 0;
|
2019-10-07 10:31:35 +02:00
|
|
|
}
|
|
|
|
|
2019-03-29 16:24:14 +01:00
|
|
|
kore_platform_proctitle("[parent]");
|
Rework worker startup/privsep config.
Starting with the privsep config, this commit changes the following:
- Removes the root, runas, keymgr_root, keymgr_runas, acme_root and
acme_runas configuration options.
Instead these are now configured via a privsep configuration context:
privsep worker {
root /tmp
runas nobody
}
This is also configurable via Python using the new kore.privsep() method:
kore.privsep("worker", root="/tmp", runas="nobody", skip=["chroot"])
Tied into this we also better handle worker startup:
- Per worker process, wait until it signalled it is ready.
- If a worker fails at startup, display its last log lines more clearly.
- Don't start acme process if no domain requires acme.
- Remove each process its individual startup log message in favour
of a generalized one that displays its PID, root and user.
- At startup, log the kore version and built-ins in a nicer way.
- The worker processes now check things they need to start running
before signaling they are ready (such as access to CA certs for
TLS client authentication).
2021-09-07 21:59:22 +02:00
|
|
|
|
|
|
|
if (!kore_worker_init()) {
|
|
|
|
kore_log(LOG_ERR, "last worker log lines:");
|
|
|
|
kore_log(LOG_ERR, "=====================================");
|
|
|
|
net_init();
|
|
|
|
kore_connection_init();
|
|
|
|
kore_platform_event_init();
|
|
|
|
kore_msg_parent_init();
|
|
|
|
kore_platform_event_wait(10);
|
|
|
|
kore_worker_dispatch_signal(SIGQUIT);
|
|
|
|
kore_log(LOG_ERR, "=====================================");
|
|
|
|
return;
|
|
|
|
}
|
2013-06-26 11:18:32 +02:00
|
|
|
|
2015-06-22 21:13:32 +02:00
|
|
|
/* Set worker_max_connections for kore_connection_init(). */
|
|
|
|
tmp = worker_max_connections;
|
|
|
|
worker_max_connections = worker_count;
|
|
|
|
|
|
|
|
net_init();
|
|
|
|
kore_connection_init();
|
|
|
|
kore_platform_event_init();
|
|
|
|
kore_msg_parent_init();
|
|
|
|
|
|
|
|
worker_max_connections = tmp;
|
2018-07-11 09:44:29 +02:00
|
|
|
|
2018-12-22 09:25:00 +01:00
|
|
|
kore_timer_init();
|
2022-01-28 14:29:58 +01:00
|
|
|
|
2018-12-22 09:41:55 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2022-01-28 14:29:58 +01:00
|
|
|
alog = 0;
|
|
|
|
|
|
|
|
LIST_FOREACH(srv, &kore_servers, list) {
|
|
|
|
TAILQ_FOREACH(dom, &srv->domains, list) {
|
|
|
|
if (dom->accesslog != -1)
|
|
|
|
alog = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (alog) {
|
|
|
|
kore_timer_add(kore_accesslog_run, 100, NULL, 0);
|
|
|
|
kore_log(LOG_INFO, "accesslog vacuum is enabled");
|
|
|
|
}
|
2018-12-22 09:41:55 +01:00
|
|
|
#endif
|
2018-12-22 09:25:00 +01:00
|
|
|
|
2019-10-16 12:05:27 +02:00
|
|
|
#if defined(KORE_USE_PYTHON)
|
|
|
|
kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
|
|
|
|
#endif
|
|
|
|
|
2022-08-08 11:02:27 +02:00
|
|
|
while (kore_quit == KORE_QUIT_NONE) {
|
2021-12-22 09:50:26 +01:00
|
|
|
last_sig = sig_recv;
|
2019-03-22 09:49:50 +01:00
|
|
|
|
2021-12-22 09:50:26 +01:00
|
|
|
if (last_sig != 0) {
|
|
|
|
switch (last_sig) {
|
2014-07-31 13:27:04 +02:00
|
|
|
case SIGHUP:
|
2021-12-22 09:50:26 +01:00
|
|
|
kore_worker_dispatch_signal(last_sig);
|
2014-07-31 13:27:04 +02:00
|
|
|
kore_module_reload(0);
|
|
|
|
break;
|
|
|
|
case SIGINT:
|
|
|
|
case SIGQUIT:
|
2016-01-31 16:48:17 +01:00
|
|
|
case SIGTERM:
|
2022-08-08 11:02:27 +02:00
|
|
|
kore_quit = KORE_QUIT_NORMAL;
|
2021-12-22 09:50:26 +01:00
|
|
|
kore_worker_dispatch_signal(last_sig);
|
2014-07-31 13:27:04 +02:00
|
|
|
continue;
|
2018-07-11 09:44:29 +02:00
|
|
|
case SIGUSR1:
|
2021-12-22 09:50:26 +01:00
|
|
|
kore_worker_dispatch_signal(last_sig);
|
2018-07-11 09:44:29 +02:00
|
|
|
break;
|
2018-10-26 19:19:47 +02:00
|
|
|
case SIGCHLD:
|
2019-03-22 09:49:50 +01:00
|
|
|
kore_worker_reap();
|
2018-10-26 19:19:47 +02:00
|
|
|
break;
|
2014-07-31 13:27:04 +02:00
|
|
|
default:
|
|
|
|
break;
|
2013-06-26 16:37:22 +02:00
|
|
|
}
|
2014-07-31 13:27:04 +02:00
|
|
|
|
2019-03-22 09:49:50 +01:00
|
|
|
if (sig_recv == last_sig)
|
|
|
|
sig_recv = 0;
|
|
|
|
else
|
|
|
|
continue;
|
2013-06-26 16:37:22 +02:00
|
|
|
}
|
|
|
|
|
2019-03-21 10:17:08 +01:00
|
|
|
netwait = kore_timer_next_run(kore_time_ms());
|
2018-12-22 09:25:00 +01:00
|
|
|
kore_platform_event_wait(netwait);
|
2015-06-22 21:13:32 +02:00
|
|
|
kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
|
2019-03-21 10:17:08 +01:00
|
|
|
kore_timer_run(kore_time_ms());
|
2021-11-03 17:23:05 +01:00
|
|
|
kore_worker_reap();
|
2013-06-26 16:37:22 +02:00
|
|
|
}
|
2015-12-29 20:39:39 +01:00
|
|
|
|
2021-11-03 17:23:05 +01:00
|
|
|
kore_worker_dispatch_signal(SIGQUIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
kore_server_shutdown(void)
|
|
|
|
{
|
|
|
|
if (!kore_quiet)
|
|
|
|
kore_log(LOG_INFO, "server shutting down");
|
|
|
|
|
|
|
|
kore_worker_shutdown();
|
|
|
|
|
2018-12-22 09:41:55 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2019-03-21 10:17:08 +01:00
|
|
|
kore_accesslog_gather(NULL, kore_time_ms(), 1);
|
2018-12-22 09:41:55 +01:00
|
|
|
#endif
|
2018-12-22 09:25:00 +01:00
|
|
|
|
2016-01-04 22:40:14 +01:00
|
|
|
kore_platform_event_cleanup();
|
|
|
|
kore_connection_cleanup();
|
2016-02-01 20:02:02 +01:00
|
|
|
kore_domain_cleanup();
|
2022-02-17 13:45:28 +01:00
|
|
|
kore_tls_cleanup();
|
2016-01-04 22:40:14 +01:00
|
|
|
net_cleanup();
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
|
2013-06-17 23:39:17 +02:00
|
|
|
static void
|
2013-06-26 11:18:32 +02:00
|
|
|
kore_write_kore_pid(void)
|
2013-06-04 16:53:30 +02:00
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
|
|
|
|
if ((fp = fopen(kore_pidfile, "w+")) == NULL) {
|
2014-07-31 17:15:51 +02:00
|
|
|
printf("warning: couldn't write pid to %s (%s)\n",
|
|
|
|
kore_pidfile, errno_s);
|
2013-06-04 16:53:30 +02:00
|
|
|
} else {
|
2013-06-26 11:18:32 +02:00
|
|
|
fprintf(fp, "%d\n", kore_pid);
|
2013-06-04 16:53:30 +02:00
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
}
|
2019-09-26 20:38:02 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
kore_call_parent_configure(int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct kore_runtime_call *rcall;
|
|
|
|
|
|
|
|
rcall = kore_runtime_getcall(parent_config_hook);
|
|
|
|
if (rcall != NULL) {
|
|
|
|
kore_runtime_configure(rcall, argc, argv);
|
|
|
|
kore_free(rcall);
|
|
|
|
}
|
|
|
|
}
|