Use MHD_OPTION_SOCK_ADDR to bind the http listen socket to a single address. The address should be an IPv4 or IPv6 address configured on the system: --listen-address=127.0.0.1 --listen-address=::1 --listen-address='LOCAL_IPv4|IPv6_ADDRESS' As debuginfod does not include any security features, a listen on the localhost address is sufficient for a HTTP/HTTPS reverse-proxy setup. --- debuginfod/debuginfod.cxx | 115 ++++++++++++++++++++++++++------------ doc/debuginfod.8 | 5 ++ 2 files changed, 84 insertions(+), 36 deletions(-)
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx index 0edd57cb..8fc9426e 100644 --- a/debuginfod/debuginfod.cxx +++ b/debuginfod/debuginfod.cxx @@ -81,6 +81,7 @@ extern "C" { #include <math.h> #include <float.h> #include <fnmatch.h> +#include <arpa/inet.h> /* If fts.h is included before config.h, its indirect inclusions may not @@ -481,6 +482,8 @@ static const struct argp_option options[] = #define ARGP_KEY_METADATA_MAXTIME 0x100C { "metadata-maxtime", ARGP_KEY_METADATA_MAXTIME, "SECONDS", 0, "Number of seconds to limit metadata query run time, 0=unlimited.", 0 }, +#define ARGP_KEY_HTTP_ADDR 0x100D + { "listen-address", ARGP_KEY_HTTP_ADDR, "ADDR", 0, "HTTP address to listen on.", 0 }, { NULL, 0, NULL, 0, NULL, 0 }, }; @@ -512,6 +515,8 @@ static volatile sig_atomic_t sigusr1 = 0; static volatile sig_atomic_t forced_groom_count = 0; static volatile sig_atomic_t sigusr2 = 0; static unsigned http_port = 8002; +static struct sockaddr_in6 http_sockaddr; +static string addr_info = ""; static bool webapi_cors = false; static unsigned rescan_s = 300; static unsigned groom_s = 86400; @@ -753,6 +758,16 @@ parse_opt (int key, char *arg, requires_koji_sigcache_mapping = true; break; #endif + case ARGP_KEY_HTTP_ADDR: + if (inet_pton(AF_INET, arg, &(((sockaddr_in*)&http_sockaddr)->sin_addr)) == 1) + http_sockaddr.sin6_family = AF_INET; + else + if (inet_pton(AF_INET6, arg, &http_sockaddr.sin6_addr) == 1) + http_sockaddr.sin6_family = AF_INET6; + else + argp_failure(state, 1, EINVAL, "listen-address"); + addr_info = arg; + break; // case 'h': argp_state_help (state, stderr, ARGP_HELP_LONG|ARGP_HELP_EXIT_OK); default: return ARGP_ERR_UNKNOWN; } @@ -5596,6 +5611,8 @@ main (int argc, char *argv[]) fdcache_prefetch = 64; // guesstimate storage is this much less costly than re-decompression /* Parse and process arguments. */ + memset(&http_sockaddr, 0, sizeof(http_sockaddr)); + http_sockaddr.sin6_family = AF_UNSPEC; int remaining; (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL); if (remaining != argc) @@ -5702,50 +5719,75 @@ main (int argc, char *argv[]) #endif | MHD_USE_DEBUG); /* report errors to stderr */ - // Start httpd server threads. Use a single dual-homed pool. - MHD_Daemon *d46 = MHD_start_daemon (mhd_flags, http_port, - NULL, NULL, /* default accept policy */ - handler_cb, NULL, /* handler callback */ - MHD_OPTION_EXTERNAL_LOGGER, - error_cb, NULL, - MHD_OPTION_THREAD_POOL_SIZE, - (int)connection_pool, - MHD_OPTION_END); - - MHD_Daemon *d4 = NULL; - if (d46 == NULL) + MHD_Daemon *dsa = NULL, + *d4 = NULL, + *d46 = NULL; + + if (http_sockaddr.sin6_family != AF_UNSPEC) { - // Cannot use dual_stack, use ipv4 only - mhd_flags &= ~(MHD_USE_DUAL_STACK); - d4 = MHD_start_daemon (mhd_flags, http_port, - NULL, NULL, /* default accept policy */ + if (http_sockaddr.sin6_family == AF_INET) + ((sockaddr_in*)&http_sockaddr)->sin_port = htons(http_port); + if (http_sockaddr.sin6_family == AF_INET6) + http_sockaddr.sin6_port = htons(http_port); + // Start httpd server threads on socket addr:port. + dsa = MHD_start_daemon (mhd_flags & ~MHD_USE_DUAL_STACK, http_port, + NULL, NULL, /* default accept policy */ handler_cb, NULL, /* handler callback */ MHD_OPTION_EXTERNAL_LOGGER, error_cb, NULL, - (connection_pool - ? MHD_OPTION_THREAD_POOL_SIZE - : MHD_OPTION_END), - (connection_pool - ? (int)connection_pool - : MHD_OPTION_END), + MHD_OPTION_SOCK_ADDR, + (struct sockaddr *) &http_sockaddr, + MHD_OPTION_THREAD_POOL_SIZE, + (int)connection_pool, MHD_OPTION_END); - if (d4 == NULL) + } + else + { + // Start httpd server threads. Use a single dual-homed pool. + d46 = MHD_start_daemon (mhd_flags, http_port, + NULL, NULL, /* default accept policy */ + handler_cb, NULL, /* handler callback */ + MHD_OPTION_EXTERNAL_LOGGER, + error_cb, NULL, + MHD_OPTION_THREAD_POOL_SIZE, + (int)connection_pool, + MHD_OPTION_END); + addr_info = "IPv4 IPv6"; + if (d46 == NULL) { - sqlite3 *database = db; - sqlite3 *databaseq = dbq; - db = dbq = 0; // for signal_handler not to freak - sqlite3_close (databaseq); - sqlite3_close (database); - error (EXIT_FAILURE, 0, "cannot start http server at port %d", - http_port); + // Cannot use dual_stack, use ipv4 only + mhd_flags &= ~(MHD_USE_DUAL_STACK); + d4 = MHD_start_daemon (mhd_flags, http_port, + NULL, NULL, /* default accept policy */ + handler_cb, NULL, /* handler callback */ + MHD_OPTION_EXTERNAL_LOGGER, + error_cb, NULL, + (connection_pool + ? MHD_OPTION_THREAD_POOL_SIZE + : MHD_OPTION_END), + (connection_pool + ? (int)connection_pool + : MHD_OPTION_END), + MHD_OPTION_END); + addr_info = "IPv4"; } - } - obatched(clog) << "started http server on" - << (d4 != NULL ? " IPv4 " : " IPv4 IPv6 ") - << "port=" << http_port - << (webapi_cors ? " with cors" : "") - << endl; + if (d4 == NULL && d46 == NULL && dsa == NULL) + { + sqlite3 *database = db; + sqlite3 *databaseq = dbq; + db = dbq = 0; // for signal_handler not to freak + sqlite3_close (databaseq); + sqlite3_close (database); + error (EXIT_FAILURE, 0, "cannot start http server on %s port %d", + addr_info.c_str(), http_port); + } + + obatched(clog) << "started http server on " + << addr_info + << " port=" << http_port + << (webapi_cors ? " with cors" : "") + << endl; // add maxigroom sql if -G given if (maxigroom) @@ -5869,6 +5911,7 @@ main (int argc, char *argv[]) pthread_join (it, NULL); /* Stop all the web service threads. */ + if (dsa) MHD_stop_daemon (dsa); if (d46) MHD_stop_daemon (d46); if (d4) MHD_stop_daemon (d4); diff --git a/doc/debuginfod.8 b/doc/debuginfod.8 index 1cf9a18f..d7744db1 100644 --- a/doc/debuginfod.8 +++ b/doc/debuginfod.8 @@ -154,6 +154,11 @@ listen, to service HTTP requests. Both IPv4 and IPV6 sockets are opened, if possible. The webapi is documented below. The default port number is 8002. +.TP +.B "\-\-listen\-address=ADDR" +Set the IP address (IPv4/IPv6 address of the system) on which +debuginfod should listen, to service HTTP requests. + .TP .B "\-\-cors" Add CORS-related response headers and OPTIONS method processing. -- 2.39.5 (Apple Git-154)