Implement --bindhost
authorRobert Swiecki <swiecki@google.com>
Thu, 25 Feb 2016 17:27:48 +0000 (18:27 +0100)
committerRobert Swiecki <swiecki@google.com>
Thu, 25 Feb 2016 17:27:48 +0000 (18:27 +0100)
cmdline.c
common.h
net.c
net.h
nsjail.c

index a046c0ca9b66fc76dc607186df88100a133d7f80..60465bbd97cef2239a98231ade9d6324306a9cc2 100644 (file)
--- 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;
index 1b4270222dc68fd96db1785600f21ec3f5efcfcd..37d83eb1622bc61e4bd3106484ac421c14647250 100644 (file)
--- 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 f37b1d62a585e780aedda32e49bb877440cd9c59..b6d8a9cfce671c8fb669870c061a0be7a10f444d 100644 (file)
--- 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 e2b45e7be1cd0a7308e7b7a31245df9b1cb5b7f7..198439a67c6f0814305b358f029eeabbdee4ea61 100644 (file)
--- 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);
 
index 1bf0371ec8a2672d3940bd3184ee4b55f5d653bb..5df2a0e8d93dfb8caccbac286572db99dddb5b31 100644 (file)
--- 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;
        }