Implement --bindhost

This commit is contained in:
Robert Swiecki 2016-02-25 18:27:48 +01:00
parent 4ec7c12c99
commit 9852028522
5 changed files with 21 additions and 9 deletions

View File

@ -89,12 +89,12 @@ void cmdlineLogParams(struct nsjconf_t *nsjconf)
} }
LOG_I 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, " "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_newnet:%s, clone_newuser:%s, clone_newns:%s, clone_newpid:%s, "
"clone_newipc:%s, clonew_newuts:%s, apply_sandbox:%s, keep_caps:%s, " "clone_newipc:%s, clonew_newuts:%s, apply_sandbox:%s, keep_caps:%s, "
"tmpfs_size:%zu", "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->max_conns_per_ip, nsjconf->inside_uid, nsjconf->outside_uid,
nsjconf->inside_gid, nsjconf->outside_gid, nsjconf->tlimit, nsjconf->personality, nsjconf->inside_gid, nsjconf->outside_gid, nsjconf->tlimit, nsjconf->personality,
logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet), logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet),
@ -248,6 +248,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
.chroot = "/", .chroot = "/",
.argv = NULL, .argv = NULL,
.port = 31337, .port = 31337,
.bindhost = "::",
.daemonize = false, .daemonize = false,
.tlimit = 0, .tlimit = 0,
.apply_sandbox = true, .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]"}, "\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"}, {{"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: \"/\")"}, {{"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')"}, {{"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')"}, {{"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')"}, {{"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: '/')"}, {{"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)"}, {{"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))"}, {{"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)"}, {{"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)"}, {{"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': case 'p':
nsjconf->port = strtoul(optarg, NULL, 0); nsjconf->port = strtoul(optarg, NULL, 0);
break; break;
case 0x604:
nsjconf->bindhost = optarg;
break;
case 'i': case 'i':
nsjconf->max_conns_per_ip = strtoul(optarg, NULL, 0); nsjconf->max_conns_per_ip = strtoul(optarg, NULL, 0);
break; break;

View File

@ -65,6 +65,7 @@ struct nsjconf_t {
const char *cwd; const char *cwd;
char *const *argv; char *const *argv;
int port; int port;
const char *bindhost;
bool daemonize; bool daemonize;
time_t tlimit; time_t tlimit;
bool apply_sandbox; bool apply_sandbox;

14
net.c
View File

@ -141,12 +141,18 @@ bool netLimitConns(struct nsjconf_t * nsjconf, int connsock)
return true; return true;
} }
int netGetRecvSocket(int port) int netGetRecvSocket(const char *bindhost, int port)
{ {
if (port < 1 || port > 65535) { if (port < 1 || port > 65535) {
LOG_F("TCP port %d out of bounds (0 <= port <= 65535)", port); 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); int sockfd = socket(AF_INET6, SOCK_STREAM, 0);
if (sockfd == -1) { if (sockfd == -1) {
PLOG_E("socket(AF_INET6)"); PLOG_E("socket(AF_INET6)");
@ -161,11 +167,11 @@ int netGetRecvSocket(int port)
.sin6_family = AF_INET6, .sin6_family = AF_INET6,
.sin6_port = htons(port), .sin6_port = htons(port),
.sin6_flowinfo = 0, .sin6_flowinfo = 0,
.sin6_addr = in6addr_any, .sin6_addr = in6a,
.sin6_scope_id = 0, .sin6_scope_id = 0,
}; };
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 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; return -1;
} }
if (listen(sockfd, SOMAXCONN) == -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)); snprintf(buf, s, "[unknown]:%hu", ntohs(addr.sin6_port));
return; return;
} }
snprintf(buf, s, "%s:%hu", tmp, ntohs(addr.sin6_port)); snprintf(buf, s, "[%s]:%hu", tmp, ntohs(addr.sin6_port));
return; return;
} }

2
net.h
View File

@ -28,7 +28,7 @@
bool netCloneMacVtapAndNS(struct nsjconf_t *nsjconf, int pid); bool netCloneMacVtapAndNS(struct nsjconf_t *nsjconf, int pid);
bool netLimitConns(struct nsjconf_t *nsjconf, int connsock); bool netLimitConns(struct nsjconf_t *nsjconf, int connsock);
int netGetRecvSocket(int port); int netGetRecvSocket(const char *bindhost, int port);
int netAcceptConn(int listenfd); int netAcceptConn(int listenfd);
void netConnToText(int fd, bool remote, char *buf, size_t s, struct sockaddr_in6 *addr_or_null); void netConnToText(int fd, bool remote, char *buf, size_t s, struct sockaddr_in6 *addr_or_null);

View File

@ -111,7 +111,7 @@ static bool nsjailSetTimer(struct nsjconf_t *nsjconf)
static void nsjailListenMode(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) { if (listenfd == -1) {
return; return;
} }