mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-08-26 18:17:25 +00:00
Merge pull request #114 from feiskyer/pm
Add external network white list for port mapping
This commit is contained in:
+8
-2
@@ -49,8 +49,8 @@ struct hyper_pod {
|
||||
struct hyper_container *c;
|
||||
struct hyper_interface *iface;
|
||||
struct hyper_route *rt;
|
||||
struct portmapping_white_list *portmap_white_lists;
|
||||
char **dns;
|
||||
char **white_cidrs;
|
||||
struct list_head containers;
|
||||
struct list_head exec_head;
|
||||
char *hostname;
|
||||
@@ -60,7 +60,6 @@ struct hyper_pod {
|
||||
uint32_t r_num;
|
||||
uint32_t e_num;
|
||||
uint32_t d_num;
|
||||
uint32_t w_num;
|
||||
uint32_t type;
|
||||
/* how many containers are running */
|
||||
uint32_t remains;
|
||||
@@ -68,6 +67,13 @@ struct hyper_pod {
|
||||
int efd;
|
||||
};
|
||||
|
||||
struct portmapping_white_list {
|
||||
char **internal_networks;
|
||||
char **external_networks;
|
||||
uint32_t i_num;
|
||||
uint32_t e_num;
|
||||
};
|
||||
|
||||
struct hyper_win_size {
|
||||
char *tty;
|
||||
int row;
|
||||
|
||||
+99
-13
@@ -997,14 +997,14 @@ static int hyper_parse_dns(struct hyper_pod *pod, char *json, jsmntok_t *toks)
|
||||
|
||||
i++;
|
||||
for (j = 0; j < pod->d_num; j++, i++) {
|
||||
pod->dns[j] = (json_token_str(json, &toks[i]));
|
||||
pod->dns[j] = json_token_str(json, &toks[i]);
|
||||
fprintf(stdout, "pod dns %d: %s\n", j, pod->dns[j]);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int hyper_parse_white_cidrs(struct hyper_pod *pod, char *json, jsmntok_t *toks)
|
||||
static int hyper_parse_portmapping_internal_networks(struct portmapping_white_list *podmapping, char *json, jsmntok_t *toks)
|
||||
{
|
||||
int i = 0, j;
|
||||
|
||||
@@ -1013,28 +1013,114 @@ static int hyper_parse_white_cidrs(struct hyper_pod *pod, char *json, jsmntok_t
|
||||
}
|
||||
|
||||
if (toks[i].type != JSMN_ARRAY) {
|
||||
fprintf(stdout, "white CIDRs format incorrect\n");
|
||||
fprintf(stdout, "internal networks format incorrect\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pod->w_num = toks[i].size;
|
||||
fprintf(stdout, "white CIDRs count %d\n", pod->w_num);
|
||||
podmapping->i_num = toks[i].size;
|
||||
fprintf(stdout, "internal networks count %d\n", podmapping->i_num);
|
||||
|
||||
pod->white_cidrs = calloc(pod->w_num, sizeof(*pod->white_cidrs));
|
||||
if (pod->white_cidrs == NULL) {
|
||||
fprintf(stdout, "alloc memory for white_cidrs failed\n");
|
||||
podmapping->internal_networks = calloc(podmapping->i_num, sizeof(*podmapping->internal_networks));
|
||||
if (podmapping->internal_networks == NULL) {
|
||||
fprintf(stdout, "alloc memory for internal_networks failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
i++;
|
||||
for (j = 0; j < pod->w_num; j++, i++) {
|
||||
pod->white_cidrs[j] = (json_token_str(json, &toks[i]));
|
||||
fprintf(stdout, "pod white_cidr %d: %s\n", j, pod->white_cidrs[j]);
|
||||
for (j = 0; j < podmapping->i_num; j++, i++) {
|
||||
podmapping->internal_networks[j] = json_token_str(json, &toks[i]);
|
||||
fprintf(stdout, "podmapping internal_networks %d: %s\n", j, podmapping->internal_networks[j]);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int hyper_parse_portmapping_external_networks(struct portmapping_white_list *podmapping, char *json, jsmntok_t *toks)
|
||||
{
|
||||
int i = 0, j;
|
||||
|
||||
if (toks[i].size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (toks[i].type != JSMN_ARRAY) {
|
||||
fprintf(stdout, "external networks format incorrect\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
podmapping->e_num = toks[i].size;
|
||||
fprintf(stdout, "external networks count %d\n", podmapping->e_num);
|
||||
|
||||
podmapping->external_networks = calloc(podmapping->e_num, sizeof(*podmapping->external_networks));
|
||||
if (podmapping->external_networks == NULL) {
|
||||
fprintf(stdout, "alloc memory for external_networks failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
i++;
|
||||
for (j = 0; j < podmapping->e_num; j++, i++) {
|
||||
podmapping->external_networks[j] = json_token_str(json, &toks[i]);
|
||||
fprintf(stdout, "podmapping external_networks %d: %s\n", j, podmapping->external_networks[j]);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int hyper_parse_portmapping_whitelist(struct hyper_pod *pod, char *json, jsmntok_t *toks)
|
||||
{
|
||||
int i = 0, j, toks_size, next;
|
||||
|
||||
if (toks[i].type != JSMN_OBJECT) {
|
||||
fprintf(stdout, "PortmappingWhiteLists format incorrect\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pod->portmap_white_lists = calloc(1, sizeof(*pod->portmap_white_lists));
|
||||
if (pod->portmap_white_lists == NULL) {
|
||||
fprintf(stdout, "alloc memory for portmap_white_lists failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
toks_size = toks[i].size;
|
||||
i++;
|
||||
for (j = 0; j < toks_size; j++) {
|
||||
jsmntok_t *t = &toks[i];
|
||||
|
||||
fprintf(stdout, "token %d, type is %d, size is %d\n", i, t->type, t->size);
|
||||
if (t->type != JSMN_STRING) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (json_token_streq(json, t, "internalNetworks") && t->size == 1) {
|
||||
next = hyper_parse_portmapping_internal_networks(pod->portmap_white_lists, json, &toks[++i]);
|
||||
if (next < -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
i += next;
|
||||
} else if (json_token_streq(json, t, "externalNetworks") && t->size == 1) {
|
||||
next = hyper_parse_portmapping_external_networks(pod->portmap_white_lists, json, &toks[++i]);
|
||||
if (next < -1) {
|
||||
goto out;
|
||||
}
|
||||
i += next;
|
||||
} else {
|
||||
fprintf(stdout, "get unknown section %s in portmap_white_lists\n", json_token_str(json, t));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
|
||||
out:
|
||||
free(pod->portmap_white_lists->internal_networks);
|
||||
free(pod->portmap_white_lists->external_networks);
|
||||
free(pod->portmap_white_lists);
|
||||
pod->portmap_white_lists = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int hyper_parse_pod(struct hyper_pod *pod, char *json, int length)
|
||||
{
|
||||
int i, n, next = -1;
|
||||
@@ -1116,8 +1202,8 @@ realloc:
|
||||
pod->policy = POLICY_ONFAILURE;
|
||||
fprintf(stdout, "restartPolicy is %" PRIu8 "\n", pod->policy);
|
||||
i++;
|
||||
} else if (json_token_streq(json, t, "whiteCIDRs") && t->size == 1) {
|
||||
next = hyper_parse_white_cidrs(pod, json, &toks[++i]);
|
||||
} else if (json_token_streq(json, t, "portmappingWhiteLists") && t->size == 1) {
|
||||
next = hyper_parse_portmapping_whitelist(pod, json, &toks[++i]);
|
||||
if (next < 0)
|
||||
goto out;
|
||||
|
||||
|
||||
+99
-41
@@ -66,7 +66,8 @@ int hyper_setup_iptables_rule(struct ipt_rule rule)
|
||||
// initialize modules and iptables chains
|
||||
int hyper_setup_portmapping(struct hyper_pod *pod)
|
||||
{
|
||||
if (pod->w_num == 0) {
|
||||
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||
pod->portmap_white_lists->e_num == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -152,7 +153,8 @@ int hyper_setup_portmapping(struct hyper_pod *pod)
|
||||
|
||||
void hyper_cleanup_portmapping(struct hyper_pod *pod)
|
||||
{
|
||||
if (pod->w_num == 0) {
|
||||
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||
pod->portmap_white_lists->e_num == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -242,11 +244,17 @@ void hyper_cleanup_portmapping(struct hyper_pod *pod)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
free(pod->portmap_white_lists->internal_networks);
|
||||
free(pod->portmap_white_lists->external_networks);
|
||||
free(pod->portmap_white_lists);
|
||||
pod->portmap_white_lists = NULL;
|
||||
}
|
||||
|
||||
int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod)
|
||||
{
|
||||
if (pod->w_num == 0) {
|
||||
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||
pod->portmap_white_lists->e_num == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -256,27 +264,54 @@ int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_po
|
||||
|
||||
int i = 0, j = 0;
|
||||
char rule[128] = {0};
|
||||
|
||||
char *network = NULL;
|
||||
for (i=0; i<c->ports_num; i++) {
|
||||
sprintf(rule, "-p %s -m %s --dport %d -j REDIRECT --to-ports %d",
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].protocol,
|
||||
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;
|
||||
// setup port mapping only if host_port is set
|
||||
if (c->ports[i].host_port > 0) {
|
||||
for (j=0; j<pod->portmap_white_lists->e_num; j++) {
|
||||
network = pod->portmap_white_lists->external_networks[j];
|
||||
|
||||
// redirect host_port to container_port
|
||||
sprintf(rule, "-s %s -p %s -m %s --dport %d -j REDIRECT --to-ports %d",
|
||||
network,
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].host_port,
|
||||
c->ports[i].container_port);
|
||||
struct ipt_rule redirect_rule = {
|
||||
.table = "nat",
|
||||
.op = "-I",
|
||||
.chain = "hyperstart-PREROUTING",
|
||||
.rule = rule,
|
||||
};
|
||||
if (hyper_setup_iptables_rule(redirect_rule)<0) {
|
||||
fprintf(stderr, "setup redirect_rule '%s' failed\n", rule);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// open container_port to external network
|
||||
sprintf(rule, "-s %s -p %s -m %s --dport %d -j ACCEPT",
|
||||
network,
|
||||
c->ports[i].protocol,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0; j<pod->w_num; j++) {
|
||||
// only allow network request from white list
|
||||
for (j=0; j<pod->portmap_white_lists->i_num; j++) {
|
||||
sprintf(rule, "-s %s -p %s -m %s --dport %d -j ACCEPT",
|
||||
pod->white_cidrs[j],
|
||||
pod->portmap_white_lists->internal_networks[j],
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].container_port);
|
||||
@@ -291,7 +326,6 @@ int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_po
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -299,7 +333,8 @@ int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_po
|
||||
|
||||
void hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod)
|
||||
{
|
||||
if (pod->w_num == 0) {
|
||||
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||
pod->portmap_white_lists->e_num == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -307,29 +342,53 @@ void hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int i = 0, j = 0;
|
||||
char rule[128] = {0};
|
||||
|
||||
char *network = NULL;
|
||||
for (i=0; i<c->ports_num; i++) {
|
||||
sprintf(rule, "-p %s -m %s --dport %d -j REDIRECT --to-ports %d",
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].protocol,
|
||||
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);
|
||||
// clean up port mapping only if host_port is set
|
||||
if (c->ports[i].host_port > 0) {
|
||||
for (j=0; j<pod->portmap_white_lists->e_num; j++) {
|
||||
network = pod->portmap_white_lists->external_networks[j];
|
||||
|
||||
// redirect host_port to container_port
|
||||
sprintf(rule, "-s %s -p %s -m %s --dport %d -j REDIRECT --to-ports %d",
|
||||
network,
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].host_port,
|
||||
c->ports[i].container_port);
|
||||
struct ipt_rule redirect_rule = {
|
||||
.table = "nat",
|
||||
.op = "-D",
|
||||
.chain = "hyperstart-PREROUTING",
|
||||
.rule = rule,
|
||||
};
|
||||
if (hyper_setup_iptables_rule(redirect_rule)<0) {
|
||||
fprintf(stderr, "cleanup redirect '%s' failed\n", rule);
|
||||
}
|
||||
|
||||
// open container_port to external network
|
||||
sprintf(rule, "-s %s -p %s -m %s --dport %d -j ACCEPT",
|
||||
network,
|
||||
c->ports[i].protocol,
|
||||
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, "cleanup accept_rule '%s' failed\n", rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0; j<pod->w_num; j++) {
|
||||
for (j=0; j<pod->portmap_white_lists->i_num; j++) {
|
||||
sprintf(rule, "-s %s -p %s -m %s --dport %d -j ACCEPT",
|
||||
pod->white_cidrs[j],
|
||||
pod->portmap_white_lists->internal_networks[j],
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].protocol,
|
||||
c->ports[i].container_port);
|
||||
@@ -340,9 +399,8 @@ void hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper
|
||||
.rule = rule,
|
||||
};
|
||||
if (hyper_setup_iptables_rule(accept_rule)<0) {
|
||||
fprintf(stderr, "setup accept_rule '%s' failed\n", rule);
|
||||
fprintf(stderr, "cleanup accept_rule '%s' failed\n", rule);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user