From 985202852238b6a14eb9984374866b824797f2ce Mon Sep 17 00:00:00 2001 From: Robert Swiecki Date: Thu, 25 Feb 2016 18:27:48 +0100 Subject: [PATCH] Implement --bindhost --- cmdline.c | 11 ++++++++--- common.h | 1 + net.c | 14 ++++++++++---- net.h | 2 +- nsjail.c | 2 +- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cmdline.c b/cmdline.c index a046c0c..60465bb 100644 --- a/cmdline.c +++ b/cmdline.c @@ -89,12 +89,12 @@ void cmdlineLogParams(struct nsjconf_t *nsjconf) } LOG_I - ("Jail parameters: hostname:'%s', chroot:'%s', process:'%s', port:%d, " + ("Jail parameters: hostname:'%s', chroot:'%s', process:'%s', bind:[%s]:%d, " "max_conns_per_ip:%u, uid:(ns:%u, global:%u), gid:(ns:%u, global:%u), time_limit:%ld, personality:%#lx, daemonize:%s, " "clone_newnet:%s, clone_newuser:%s, clone_newns:%s, clone_newpid:%s, " "clone_newipc:%s, clonew_newuts:%s, apply_sandbox:%s, keep_caps:%s, " "tmpfs_size:%zu", - nsjconf->hostname, nsjconf->chroot, nsjconf->argv[0], nsjconf->port, + nsjconf->hostname, nsjconf->chroot, nsjconf->argv[0], nsjconf->bindhost, nsjconf->port, nsjconf->max_conns_per_ip, nsjconf->inside_uid, nsjconf->outside_uid, nsjconf->inside_gid, nsjconf->outside_gid, nsjconf->tlimit, nsjconf->personality, logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet), @@ -248,6 +248,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf) .chroot = "/", .argv = NULL, .port = 31337, + .bindhost = "::", .daemonize = false, .tlimit = 0, .apply_sandbox = true, @@ -301,12 +302,13 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf) "\tr: Immediately launch a single process on a console, keep doing it forever [MODE_STANDALONE_RERUN]"}, {{"cmd", no_argument, NULL, 0x500}, "Equivalent of -Mo (MODE_STANDALONE_ONCE), run command on a local console, once"}, {{"chroot", required_argument, NULL, 'c'}, "Directory containing / of the jail (default: \"/\")"}, - {{"rw", no_argument, NULL, 0x0601}, "Mount / as RW (default: RO)"}, + {{"rw", no_argument, NULL, 0x601}, "Mount / as RW (default: RO)"}, {{"user", required_argument, NULL, 'u'}, "Username/uid of processess inside the jail (default: 'nobody')"}, {{"group", required_argument, NULL, 'g'}, "Groupname/gid of processess inside the jail (default: 'nogroup')"}, {{"hostname", required_argument, NULL, 'H'}, "UTS name (hostname) of the jail (default: 'NSJAIL')"}, {{"cwd", required_argument, NULL, 'D'}, "Directory in the namespace the process will run (default: '/')"}, {{"port", required_argument, NULL, 'p'}, "TCP port to bind to (only in [MODE_LISTEN_TCP]) (default: 31337)"}, + {{"bindhost", required_argument, NULL, 0x604}, "IP address port to bind to (only in [MODE_LISTEN_TCP]) (default: '::')"}, {{"max_conns_per_ip", required_argument, NULL, 'i'}, "Maximum number of connections per one IP (default: 0 (unlimited))"}, {{"log", required_argument, NULL, 'l'}, "Log file (default: /proc/self/fd/2)"}, {{"time_limit", required_argument, NULL, 't'}, "Maximum time that a jail can exist, in seconds (default: 600)"}, @@ -371,6 +373,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf) case 'p': nsjconf->port = strtoul(optarg, NULL, 0); break; + case 0x604: + nsjconf->bindhost = optarg; + break; case 'i': nsjconf->max_conns_per_ip = strtoul(optarg, NULL, 0); break; diff --git a/common.h b/common.h index 1b42702..37d83eb 100644 --- a/common.h +++ b/common.h @@ -65,6 +65,7 @@ struct nsjconf_t { const char *cwd; char *const *argv; int port; + const char *bindhost; bool daemonize; time_t tlimit; bool apply_sandbox; diff --git a/net.c b/net.c index f37b1d6..b6d8a9c 100644 --- a/net.c +++ b/net.c @@ -141,12 +141,18 @@ bool netLimitConns(struct nsjconf_t * nsjconf, int connsock) return true; } -int netGetRecvSocket(int port) +int netGetRecvSocket(const char *bindhost, int port) { if (port < 1 || port > 65535) { LOG_F("TCP port %d out of bounds (0 <= port <= 65535)", port); } + struct in6_addr in6a; + if (inet_pton(AF_INET6, bindhost, &in6a) != 1) { + PLOG_E("Couldn't convert '%s' into AF_INET6 address", bindhost); + return -1; + } + int sockfd = socket(AF_INET6, SOCK_STREAM, 0); if (sockfd == -1) { PLOG_E("socket(AF_INET6)"); @@ -161,11 +167,11 @@ int netGetRecvSocket(int port) .sin6_family = AF_INET6, .sin6_port = htons(port), .sin6_flowinfo = 0, - .sin6_addr = in6addr_any, + .sin6_addr = in6a, .sin6_scope_id = 0, }; if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - PLOG_E("bind(port:%d)", port); + PLOG_E("bind(host:[%s], port:%d)", bindhost, port); return -1; } if (listen(sockfd, SOMAXCONN) == -1) { @@ -237,6 +243,6 @@ void netConnToText(int fd, bool remote, char *buf, size_t s, struct sockaddr_in6 snprintf(buf, s, "[unknown]:%hu", ntohs(addr.sin6_port)); return; } - snprintf(buf, s, "%s:%hu", tmp, ntohs(addr.sin6_port)); + snprintf(buf, s, "[%s]:%hu", tmp, ntohs(addr.sin6_port)); return; } diff --git a/net.h b/net.h index e2b45e7..198439a 100644 --- a/net.h +++ b/net.h @@ -28,7 +28,7 @@ bool netCloneMacVtapAndNS(struct nsjconf_t *nsjconf, int pid); bool netLimitConns(struct nsjconf_t *nsjconf, int connsock); -int netGetRecvSocket(int port); +int netGetRecvSocket(const char *bindhost, int port); int netAcceptConn(int listenfd); void netConnToText(int fd, bool remote, char *buf, size_t s, struct sockaddr_in6 *addr_or_null); diff --git a/nsjail.c b/nsjail.c index 1bf0371..5df2a0e 100644 --- a/nsjail.c +++ b/nsjail.c @@ -111,7 +111,7 @@ static bool nsjailSetTimer(struct nsjconf_t *nsjconf) static void nsjailListenMode(struct nsjconf_t *nsjconf) { - int listenfd = netGetRecvSocket(nsjconf->port); + int listenfd = netGetRecvSocket(nsjconf->bindhost, nsjconf->port); if (listenfd == -1) { return; }