diff options
-rw-r--r-- | eurephiafw.c | 6 | ||||
-rw-r--r-- | firewall/iptables/efw_iptables.c | 62 |
2 files changed, 53 insertions, 15 deletions
diff --git a/eurephiafw.c b/eurephiafw.c index ee4949b..bf60ad1 100644 --- a/eurephiafw.c +++ b/eurephiafw.c @@ -197,11 +197,11 @@ void eFW_StartFirewall(eurephiaCTX *ctx) { sem_wait(ctx->fwcfg->thrdata.semp_worker); eurephia_log(ctx, LOG_INFO, 2, "eFW interface initialised."); - // Flushing the firewall chain for our clients, to make sure it is empty + // Initialise the chain memset(&buf, 0, 1026); - snprintf(buf, 1024, "F %s", fwdest); + snprintf(buf, 1024, "I %s", fwdest); if( mq_send((*ctx->fwcfg).thrdata.msgq, buf, strlen(buf)+1, 1) == -1 ) { - eurephia_log(ctx, LOG_ERROR, 0, "Could not request firewall flushing of the %s chain: %s", + eurephia_log(ctx, LOG_ERROR, 0, "Could not request firewall initialisation of the %s chain: %s", fwdest, strerror(errno)); }; } diff --git a/firewall/iptables/efw_iptables.c b/firewall/iptables/efw_iptables.c index 3bd9cce..d63a161 100644 --- a/firewall/iptables/efw_iptables.c +++ b/firewall/iptables/efw_iptables.c @@ -46,6 +46,7 @@ int eFWinterfaceAPIversion() { int process_input(eurephiaCTX *ctx, const char *fwcmd, const char *msg); +int call_iptables(eurephiaCTX *ctx, const char *fwcmd, char **ipt_args); void eFW_RunFirewall(void *fwargs) { efw_threaddata *cfg = (efw_threaddata *) fwargs; @@ -99,9 +100,8 @@ void eFW_RunFirewall(void *fwargs) { int process_input(eurephiaCTX *ctx, const char *fwcmd, const char *input) { char mode[3], *macaddr = NULL, *destchain = NULL, *jump = NULL; char *msg = NULL, *orig_msg = NULL; - char *iptables_args[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - pid_t pid; - int cmdret = -1; + char *iptables_args[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + int ret = 0; orig_msg = strdup_nullsafe(input); msg = orig_msg; @@ -116,11 +116,11 @@ int process_input(eurephiaCTX *ctx, const char *fwcmd, const char *input) { msg += 2; iptables_args[0] = (char *)fwcmd; - iptables_args[1] = mode; switch( mode[1] ) { case 'A': case 'D': + iptables_args[1] = mode; macaddr = msg; // start of string for macaddr // Search for end of macaddr and NULL terminate it @@ -147,27 +147,67 @@ int process_input(eurephiaCTX *ctx, const char *fwcmd, const char *input) { iptables_args[4] = "mac\0"; iptables_args[5] = "--mac-source\0"; iptables_args[6] = macaddr; - iptables_args[7] = "-j\0"; - iptables_args[8] = jump; - iptables_args[9] = NULL; + iptables_args[7] = "-m\0"; + iptables_args[8] = "state\0"; + iptables_args[9] = "--state\0"; + iptables_args[10] = "NEW\0"; + iptables_args[11] = "-j\0"; + iptables_args[12] = jump; + iptables_args[13] = NULL; eurephia_log(ctx, LOG_INFO, 3, "eFW_RunFirewall - updating iptables rules " "==> mode: %s macaddr: '%s' destchain: '%s' jump: '%s'", (mode[1] == 'A' ? "ADD":"DELETE"), macaddr, destchain, jump); + ret = call_iptables(ctx, fwcmd, iptables_args); break; case 'F': + iptables_args[1] = mode; destchain = msg; iptables_args[2] = destchain; - + iptables_args[3] = NULL; eurephia_log(ctx, LOG_INFO, 3, "eFW_RunFirewall - updating iptables rules " "==> mode: FLUSH destchain: '%s'", destchain); + ret = call_iptables(ctx, fwcmd, iptables_args); break; + case 'I': + // Init chain - flush it and then add needed rule for stateful inspection + destchain = msg; + + eurephia_log(ctx, LOG_INFO, 3, "eFW_RunFirewall - Initialising iptables chain '%s'", + destchain); + + // Flush phase + iptables_args[1] = "-F"; + destchain = msg; + iptables_args[2] = destchain; + iptables_args[3] = NULL; + ret = call_iptables(ctx, fwcmd, iptables_args); + + // Add stateful inspection + iptables_args[1] = "-I\0"; + iptables_args[2] = destchain; + iptables_args[3] = "-m\0"; + iptables_args[4] = "state\0"; + iptables_args[5] = "--state\0"; + iptables_args[6] = "ESTABLISHED,RELATED\0"; + iptables_args[7] = "-j\0"; + iptables_args[8] = "ACCEPT\0"; + ret &= call_iptables(ctx, fwcmd, iptables_args); + break; + default: eurephia_log(ctx, LOG_CRITICAL, 0, "eFW_RunFirewall::process_input: Malformed update request"); - return 1; + ret = 1; } + free_nullsafe(orig_msg); + return ret; +} + +int call_iptables(eurephiaCTX *ctx, const char *fwcmd, char **ipt_args) { + pid_t pid; + int cmdret = -1; // Fork out a child process which will run the iptables command. Since the execve replaces // the current process, we need to do the forking first. @@ -179,12 +219,10 @@ int process_input(eurephiaCTX *ctx, const char *fwcmd, const char *input) { switch( pid ) { case 0: // child process - execute the program and exit - execve(fwcmd, iptables_args, NULL); + execve(fwcmd, ipt_args, NULL); exit(1); // execve should replace the process, but if it fails to do so, make sure we exit default: // parent process - free_nullsafe(orig_msg); - if( waitpid(pid, &cmdret, 0) != pid ) { eurephia_log(ctx, LOG_WARNING, 0, "eFW_RunFirewall::process_input: Failed to wait for process for %s" |