diff --git a/src/Makefile.am b/src/Makefile.am index 42acaef..08e6844 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,3 @@ AM_CFLAGS = -Wall bin_PROGRAMS=init -init_SOURCES=init.c jsmn.c net.c util.c parse.c container.c exec.c event.c +init_SOURCES=init.c jsmn.c net.c util.c parse.c container.c exec.c event.c portmapping.c diff --git a/src/container.h b/src/container.h index 13f94d0..86cf459 100644 --- a/src/container.h +++ b/src/container.h @@ -28,7 +28,7 @@ struct port { int host_port; int container_port; char *protocol; -} +}; struct hyper_container { char *id; diff --git a/src/init.c b/src/init.c index f2cc4f6..6fb6e8c 100644 --- a/src/init.c +++ b/src/init.c @@ -1293,6 +1293,10 @@ int main(int argc, char *argv[]) symlink("/busybox", "/sh"); symlink("/busybox", "/tar"); symlink("/busybox", "/sbin/modprobe"); + symlink("/busybox", "/sbin/depmod"); + symlink("/iptables", "/sbin/iptables"); + symlink("/iptables", "/sbin/iptables-restore"); + symlink("/iptables", "/sbin/iptables-save"); cmdline = read_cmdline(); diff --git a/src/parse.c b/src/parse.c index fcf604a..401e7f6 100644 --- a/src/parse.c +++ b/src/parse.c @@ -540,8 +540,12 @@ static int container_parse_ports(struct hyper_container *c, char *json, jsmntok_ { int i = 0, j; + if (toks[i].size == 0) { + return 0; + } + if (toks[i].type != JSMN_ARRAY) { - fprintf(stdout, "ports need array\n"); + fprintf(stdout, "ports format error\n"); return -1; } @@ -1003,13 +1007,17 @@ static int hyper_parse_white_cidrs(struct hyper_pod *pod, char *json, jsmntok_t { int i = 0, j; + if (toks[i].size == 0) { + return 0; + } + if (toks[i].type != JSMN_ARRAY) { - fprintf(stdout, "Dns format incorrect\n"); + fprintf(stdout, "white CIDRs format incorrect\n"); return -1; } pod->w_num = toks[i].size; - fprintf(stdout, "white cidr count %d\n", pod->w_num); + fprintf(stdout, "white CIDRs count %d\n", pod->w_num); pod->white_cidrs = calloc(pod->w_num, sizeof(*pod->white_cidrs)); if (pod->white_cidrs == NULL) { diff --git a/src/portmapping.c b/src/portmapping.c index 7096585..f70ffa7 100644 --- a/src/portmapping.c +++ b/src/portmapping.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include @@ -12,69 +14,70 @@ #include "util.h" #include "../config.h" -int hyper_init_iptables() +int hyper_init_modules() { - const char *cmd = "/sbin/modprobe iptable_filter iptable_nat xt_multiport xt_REDIRECT"; - fprintf(stdout, "command for init iptables is %s\n", cmd); - - int status = hyper_cmd(cmd); - if (status < 0) { - fprintf(stderr, "modprobe iptables exit unexpectedly, status %d\n", status); + int status = hyper_cmd("/sbin/depmod"); + if (status != 0) { + fprintf(stderr, "depmod failed, status: %d\n", status); + return -1; } - return status + return 0; } -int hyper_insert_rule(struct ipt_rule rule) +int hyper_setup_iptables_rule(struct ipt_rule rule) { char check_cmd[512] = {0}; char cmd[512] = {0}; int check = -1; - if rule.rule != NULL { - sprintf(check_cmd, "/iptables -t %s -C %s %s", rule.table, rule.chain, rule.rule); - sprintf(cmd, "/iptables -t %s %s %s %s", rule.table, rule.op, rule.chain, rule.rule); + if (rule.rule != NULL) { + sprintf(check_cmd, "/sbin/iptables -t %s -C %s %s", rule.table, rule.chain, rule.rule); + sprintf(cmd, "/sbin/iptables -t %s %s %s %s", rule.table, rule.op, rule.chain, rule.rule); } else { - sprintf(cmd, "/iptables -t %s %s %s", rule.table, rule.op, rule.chain); + sprintf(cmd, "/sbin/iptables -t %s %s %s", rule.table, rule.op, rule.chain); } if (strlen(check_cmd) > 0) { - check = hyper_cmd(check_cmd); - fprintf(stdout, "check iptables '%s' status %d\n", check_cmd, status); + check = hyper_cmd(check_cmd); + fprintf(stdout, "check iptables '%s', ret: %d\n", check_cmd, check); } - - if check == 0 { - fprintf(stdout, "iptables rule '%s' already exist\n", rule.rule); - return 0; + + if (check == 0) { + // iptables rule already exist, do not insert it again + if (rule.op == "-A" || rule.op == "-I" || rule.op == "-N") { + fprintf(stdout, "iptables rule '%s' already exist\n", rule.rule); + return 0; + } } int status = hyper_cmd(cmd); - fprintf(stdout, "insert iptables '%s' status %d\n", cmd, status); - if (status < 0) { - fprintf(stderr, "insert iptables rule failed, status %d\n", status); - } - - return status -} - -// load iptables modules and initialize iptables chain -int hyper_setup_portmapping(struct hyper_pod *pod) -{ - if pod->w_num == 0 { - return 0; - } - - if (hyper_init_iptables() < 0) { - fprintf(stderr, "modprobe iptables modules failed\n"); + fprintf(stdout, "insert iptables '%s', ret: %d\n", cmd, status); + if (status != 0) { + fprintf(stderr, "insert iptables rule failed, ret: %d\n", status); return -1; } - // "/iptables -t filter -N hyperstart-INPUT", - // "/iptables -t nat -N hyperstart-PREROUTING", - // "/iptables -t filter -I INPUT -j hyperstart-INPUT", - // "/iptables -t nat -I PREROUTING -j hyperstart-PREROUTING", - // "/iptables -t filter -A hyperstart-INPUT -j DROP ", - // "/iptables -t nat -A hyperstart-PREROUTING -j RETURN"}; + return 0; +} + +// initialize modules and iptables chains +int hyper_setup_portmapping(struct hyper_pod *pod) +{ + if (pod->w_num == 0) { + return 0; + } + + if (hyper_init_modules() < 0) { + return -1; + } + + // iptables -t filter -N hyperstart-INPUT + // iptables -t nat -N hyperstart-PREROUTING + // iptables -t filter -I INPUT -j hyperstart-INPUT + // iptables -t nat -I PREROUTING -j hyperstart-PREROUTING + // iptables -t filter -A hyperstart-INPUT -j DROP + // iptables -t nat -A hyperstart-PREROUTING -j RETURN const struct ipt_rule rules[] = { { .table = "filter", @@ -112,11 +115,11 @@ int hyper_setup_portmapping(struct hyper_pod *pod) .chain = "hyperstart-PREROUTING", .rule = "-j RETURN", }, - } + }; - for(int i=0; i< sizeof(rules)/sizeof(struct ipt_rule); i++) { - if (hyper_insert_rule(rules[i])<0) { - fprintf(stderr, "insert iptables rule '%s' failed\n", rules[i].rule); + int i = 0; + for(i=0; i< sizeof(rules)/sizeof(struct ipt_rule); i++) { + if (hyper_setup_iptables_rule(rules[i])<0) { return -1; } } @@ -126,47 +129,160 @@ int hyper_setup_portmapping(struct hyper_pod *pod) void hyper_cleanup_portmapping(struct hyper_pod *pod) { - int status = 0; - - if pod->w_num == 0 { - return 0; + if (pod->w_num == 0) { + return; } - // const char* rules[] = {"/iptables -t filter -D hyperstart-INPUT -j DROP ", - // "/iptables -t nat -D hyperstart-PREROUTING -j RETURN", - // "/iptables -t filter -D INPUT -j hyperstart-DNPUT", - // "/iptables -t nat -D PREROUTING -j hyperstart-PREROUTING", - // "/iptables -t filter -F hyperstart-INPUT", - // "/iptables -t nat -F hyperstart-PREROUTING", - // "/iptables -t filter -X hyperstart-INPUT", - // "/iptables -t nat -X hyperstart-PREROUTING",}; + // iptables -t filter -D hyperstart-INPUT -j DROP + // iptables -t nat -D hyperstart-PREROUTING -j RETURN + // iptables -t filter -D INPUT -j hyperstart-DNPUT + // iptables -t nat -D PREROUTING -j hyperstart-PREROUTING + // iptables -t filter -F hyperstart-INPUT + // iptables -t nat -F hyperstart-PREROUTING + // iptables -t filter -X hyperstart-INPUT + // iptables -t nat -X hyperstart-PREROUTING + const struct ipt_rule rules[] = { + { + .table = "nat", + .op = "-D", + .chain = "hyperstart-PREROUTING", + .rule = "-j RETURN", + }, + { + .table = "filter", + .op = "-D", + .chain = "hyperstart-INPUT", + .rule = "-j DROP", + }, + { + .table = "nat", + .op = "-D", + .chain = "PREROUTING", + .rule = "-j hyperstart-PREROUTING", + }, + { + .table = "filter", + .op = "-D", + .chain = "INPUT", + .rule = "-j hyperstart-INPUT", + }, + { + .table = "nat", + .op = "-F", + .chain = "hyperstart-PREROUTING", + .rule = NULL, + }, + { + .table = "nat", + .op = "-X", + .chain = "hyperstart-PREROUTING", + .rule = NULL, + }, + { + .table = "filter", + .op = "-F", + .chain = "hyperstart-INPUT", + .rule = NULL, + }, + { + .table = "filter", + .op = "-X", + .chain = "hyperstart-INPUT", + .rule = NULL, + }, + }; + int i = 0; + for(i=0; i< sizeof(rules)/sizeof(struct ipt_rule); i++) { + if (hyper_setup_iptables_rule(rules[i])<0) { + return -1; + } + } } -// iptables -t filter -I hyperstart-INPUT -s 0.0.0.0/0 -p tcp -m multiport --dports 80 -j ACCEPT -// iptables -t nat -I hyperstart-PREROUTING -p tcp -m tcp --dport 8080 -j REDIRECT --to-ports 80 int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod) { - if pod->w_num == 0 { + if (pod->w_num == 0) { return 0; } - if c->ports_num == 0 { + if (c->ports_num == 0) { return 0; } + int i = 0, j = 0; + char rule[128] = {0}; + + for (i=0; iports_num; i++) { + sprintf(rule, "-p tcp -m tcp --dport %d -j REDIRECT --to-ports %d", c->ports[i].host_port, c->ports[i].container_port); + struct ipt_rule rediect_rule = { + .table = "nat", + .op = "-I", + .chain = "hyperstart-PREROUTING", + .rule = rule, + }; + if (hyper_setup_iptables_rule(rediect_rule)<0) { + fprintf(stderr, "setup rediect_rule '%s' failed\n", rule); + return -1; + } + + for (j=0; jw_num; j++) { + sprintf(rule, "-s %s -p %s -m multiport --dports %d -j ACCEPT", pod->white_cidrs[j], c->ports[i].protocol, c->ports[i].container_port); + struct ipt_rule accept_rule = { + .table = "filter", + .op = "-I", + .chain = "hyperstart-INPUT", + .rule = rule, + }; + if (hyper_setup_iptables_rule(accept_rule)<0) { + fprintf(stderr, "setup accept_rule '%s' failed\n", rule); + return -1; + } + } + + } + return 0; } -int hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod) +void hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod) { - if pod->w_num == 0 { - return 0; + if (pod->w_num == 0) { + return; } - if c->ports_num == 0 { - return 0; + if (c->ports_num == 0) { + return; } - return 0; + + int i = 0, j = 0; + char rule[128] = {0}; + + for (i=0; iports_num; i++) { + sprintf(rule, "-p tcp -m tcp --dport %d -j REDIRECT --to-ports %d", c->ports[i].host_port, c->ports[i].container_port); + struct ipt_rule rediect_rule = { + .table = "nat", + .op = "-D", + .chain = "hyperstart-PREROUTING", + .rule = rule, + }; + if (hyper_setup_iptables_rule(rediect_rule)<0) { + fprintf(stderr, "setup rediect_rule '%s' failed\n", rule); + } + + for (j=0; jw_num; j++) { + sprintf(rule, "-s %s -p %s -m multiport --dports %d -j ACCEPT", pod->white_cidrs[j], c->ports[i].protocol, c->ports[i].container_port); + struct ipt_rule accept_rule = { + .table = "filter", + .op = "-D", + .chain = "hyperstart-INPUT", + .rule = rule, + }; + if (hyper_setup_iptables_rule(accept_rule)<0) { + fprintf(stderr, "setup accept_rule '%s' failed\n", rule); + } + } + + } } diff --git a/src/portmapping.h b/src/portmapping.h index 2a860a4..453605a 100644 --- a/src/portmapping.h +++ b/src/portmapping.h @@ -18,6 +18,6 @@ struct hyper_container; int hyper_setup_portmapping(struct hyper_pod *pod); void hyper_cleanup_portmapping(struct hyper_pod *pod); int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod); -int hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod); +void hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod); #endif diff --git a/src/util.c b/src/util.c index 1ce1941..90acf03 100644 --- a/src/util.c +++ b/src/util.c @@ -628,6 +628,30 @@ void hyper_shutdown() int hyper_cmd(char *cmd) { - int status = system(cmd); - return ((WIFEXITED(status)) ? ((char)WEXITSTATUS(status)) : -1); + int pid, status; + + pid = fork(); + if (pid < 0) { + perror("fail to fork"); + return -1; + } else if (pid > 0) { + if (waitpid(pid, &status, 0) <= 0) { + perror("waiting fork cmd failed"); + return -1; + } + if (WIFEXITED(status)) { + int ret = WEXITSTATUS(status); + fprintf(stdout, "%s cmd exit normally, status %" PRIu8 "\n", cmd, ret); + if (ret == 0) + return 0; + } + + fprintf(stdout, "cmd %s exit unexpectedly, status %" PRIu8 "\n", cmd, status); + return -1; + } else { + fprintf(stdout, "executing cmd %s\n", cmd); + execlp("/busybox", "sh", "-c", cmd, NULL); + } + + return -1; } diff --git a/src/util.h b/src/util.h index bcbdcc9..ed72a88 100644 --- a/src/util.h +++ b/src/util.h @@ -24,6 +24,7 @@ int hyper_copy_dir(char *src, char *dst); void hyper_sync_time_hctosys(); void online_cpu(void); void online_memory(void); +int hyper_cmd(char *cmd); int hyper_mkdir(char *path); int hyper_open_channel(char *channel, int mode); int hyper_open_serial_dev(char *tty); @@ -33,7 +34,6 @@ int hyper_setfd_nonblock(int fd); int hyper_socketpair(int domain, int type, int protocol, int sv[2]); void hyper_shutdown(void); int hyper_insmod(char *module); -int hyper_cmd(char* cmd); struct passwd *hyper_getpwnam(const char *name); struct group *hyper_getgrnam(const char *name); int hyper_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);