def write_nat_rule(self, nat_rule): if 'enabled' in nat_rule and not nat_rule['enabled']: return if 'conditions' not in nat_rule: return if 'ruleId' not in nat_rule: return if 'auto' in nat_rule and nat_rule['auto']: target = " -j MASQUERADE " elif 'newSource' in nat_rule: target = " -j SNAT --to-source %s " % str(nat_rule['newSource']) else: print("ERROR: invalid nat target: %s" + str(nat_rule)) return description = "NAT Rule #%i" % int(nat_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands( nat_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string( nat_rule['conditions'], description) commands += [ "${IPTABLES} -t nat -A nat-rules " + ipt + target for ipt in iptables_conditions ] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_port_forward_rule(self, port_forward_rule): if 'enabled' in port_forward_rule and not port_forward_rule['enabled']: return if 'conditions' not in port_forward_rule: return if 'ruleId' not in port_forward_rule: return if 'newDestination' in port_forward_rule and 'newPort' in port_forward_rule: target = " -j DNAT --to-destination %s:%s " % (str(port_forward_rule['newDestination']), str(port_forward_rule['newPort'])) elif 'newDestination' in port_forward_rule: target = " -j DNAT --to-destination %s " % str(port_forward_rule['newDestination']) else: print("ERROR: invalid port forward target: %s" + str(port_forward_rule)) return description = "Port Forward Rule #%i" % int(port_forward_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands(port_forward_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string(port_forward_rule['conditions'], description) commands += ["${IPTABLES} -t nat -A port-forward-rules " + ipt + target for ipt in iptables_conditions] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_qos_rule(self, qos_rule): if 'enabled' in qos_rule and not qos_rule['enabled']: return if 'conditions' not in qos_rule: return if 'ruleId' not in qos_rule: return if 'priority' in qos_rule: target = " -g qos-class%i " % qos_rule['priority'] else: print("ERROR: invalid qos priority: %s" + str(qos_rule)) return description = "QoS Custom Rule #%i" % int(qos_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands(qos_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string(qos_rule['conditions'], description) commands += ["${IPTABLES} -t mangle -A qos-rules -m mark --mark 0x%X/0x%X " % (self.bypass_mark_mask, self.bypass_mark_mask) + ipt + target for ipt in iptables_conditions] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_qos_rule(self, qos_rule, verbosity=0): if 'enabled' in qos_rule and not qos_rule['enabled']: return if 'conditions' not in qos_rule or 'list' not in qos_rule['conditions']: return if 'ruleId' not in qos_rule: return if 'priority' in qos_rule: target = " -g qos-class%i " % qos_rule['priority'] else: print("ERROR: invalid qos priority: %s" + str(qos_rule)) return description = "QoS Custom Rule #%i" % int(qos_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands( qos_rule['conditions']['list'], description, verbosity) iptables_conditions = IptablesUtil.conditions_to_iptables_string( qos_rule['conditions']['list'], description, verbosity) commands += [ "${IPTABLES} -t mangle -A qos-rules -m mark --mark 0x%X/0x%X " % (self.bypass_mark_mask, self.bypass_mark_mask) + ipt + target for ipt in iptables_conditions ] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_bypass_rule(self, bypass_rule, verbosity=0): if 'enabled' in bypass_rule and not bypass_rule['enabled']: return if 'conditions' not in bypass_rule or 'list' not in bypass_rule[ 'conditions']: return if 'ruleId' not in bypass_rule: return bypass = None if 'bypass' in bypass_rule and bypass_rule['bypass']: target = " --goto set-bypass-mark " elif 'bypass' in bypass_rule and not bypass_rule['bypass']: target = " -j RETURN " else: print("ERROR: invalid bypass target: %s" + str(bypass_rule)) return description = "Bypass Rule #%i" % int(bypass_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands( bypass_rule['conditions']['list'], description, verbosity) iptables_conditions = IptablesUtil.conditions_to_iptables_string( bypass_rule['conditions']['list'], description, verbosity) commands += [ "${IPTABLES} -t filter -A bypass-rules " + ipt + target for ipt in iptables_conditions ] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_nat_rule(self, nat_rule): if 'enabled' in nat_rule and not nat_rule['enabled']: return if 'conditions' not in nat_rule: return if 'ruleId' not in nat_rule: return if 'auto' in nat_rule and nat_rule['auto']: target = " -j MASQUERADE " elif 'newSource' in nat_rule: target = " -j SNAT --to-source %s " % str(nat_rule['newSource']) else: print("ERROR: invalid nat target: %s" + str(nat_rule)) return description = "NAT Rule #%i" % int(nat_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands(nat_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string(nat_rule['conditions'], description) commands += ["${IPTABLES} -t nat -A nat-rules " + ipt + target for ipt in iptables_conditions] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_bypass_rule(self, bypass_rule, table, chain, comment_prefix): """ Convert the bypass rule to iptables notation (possibly expanding to multiple commands for multiple protocols) """ if 'enabled' in bypass_rule and not bypass_rule['enabled']: return if 'conditions' not in bypass_rule: return if 'ruleId' not in bypass_rule: return target = None if 'bypass' in bypass_rule and bypass_rule['bypass']: target = " -j RETURN " elif 'bypass' in bypass_rule and not bypass_rule['bypass']: # bypass is not enabled; do nothing to let it be processed return else: print("ERROR: invalid bypass target: %s" + str(bypass_rule)) return description = comment_prefix + " Bypass Rule #%i" % int(bypass_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands(bypass_rule['conditions'], description) conditions = IptablesUtil.conditions_to_iptables_string(bypass_rule['conditions'], description) for condition in conditions: commands += ["${{IPTABLES}} -t {table} -A {chain} {conditions}{target}".format(table=table, chain=chain, conditions=condition, target=target)] for cmd in commands: self.out_file.write( cmd + "\n") return
def write_bypass_rule(self, bypass_rule): if 'enabled' in bypass_rule and not bypass_rule['enabled']: return if 'conditions' not in bypass_rule: return if 'ruleId' not in bypass_rule: return bypass = None if 'bypass' in bypass_rule and bypass_rule['bypass']: target = " --goto set-bypass-mark " elif 'bypass' in bypass_rule and not bypass_rule['bypass']: target = " -j RETURN " else: print("ERROR: invalid bypass target: %s" + str(bypass_rule)) return description = "Bypass Rule #%i" % int(bypass_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands(bypass_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string(bypass_rule['conditions'], description) commands += ["${IPTABLES} -t filter -A bypass-rules " + ipt + target for ipt in iptables_conditions] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_filter_rule(self, table_name, filter_rule, drop_target): if filter_rule.get('enabled') == None or filter_rule.get('enabled') == False: return if filter_rule.get('ruleId') == None: return if filter_rule.get('blocked') == None: return if filter_rule.get('blocked'): target = ' -j %s ' % drop_target else: target = ' -j RETURN ' description = "Rule #%i" % int(filter_rule['ruleId']) prep_commands = IptablesUtil.conditions_to_prep_commands(filter_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string(filter_rule['conditions'], description) iptables_log_commands = [("${IPTABLES} -t filter -A %s " % table_name) + ipt + " -j NFLOG --nflog-prefix 'filter_blocked' " for ipt in iptables_conditions] iptables_commands = [("${IPTABLES} -t filter -A %s " % table_name) + ipt + target for ipt in iptables_conditions] self.file.write("# %s\n" % description) i = 0 for cmd in prep_commands: self.file.write(cmd + "\n") for cmd in iptables_commands: # write a log rule before each block rule so we log every drop if filter_rule.get('blocked'): self.file.write(iptables_log_commands[i] + "\n") i = i+1 self.file.write(cmd + "\n") if filter_rule.get('ipv6Enabled') == None or filter_rule.get('ipv6Enabled') == False: return ip6tables_commands = [("${IP6TABLES} -t filter -A %s " % table_name) + ipt + target for ipt in iptables_conditions] for cmd in ip6tables_commands: if cmd.find("--protocol ah"): cmd = cmd.replace("--protocol ah", "-m ah ! --ahspi 0") if cmd.find("--protocol icmp"): cmd = cmd.replace("--protocol icmp", "--protocol icmpv6") self.file.write(cmd + "\n") self.file.write("\n") return
def write_nat_rule(self, nat_rule, prefix=""): if 'enabled' in nat_rule and not nat_rule['enabled']: return if 'conditions' not in nat_rule: return if 'ruleId' not in nat_rule: return if 'auto' in nat_rule and nat_rule['auto']: target = " -j MASQUERADE " elif 'newSource' in nat_rule: target = " -j SNAT --to-source %s " % str(nat_rule['newSource']) else: print("ERROR: invalid nat target: %s" + str(nat_rule)) return description = "NAT Rule #%i" % int(nat_rule['ruleId']) wireguard_commands = [] commands = IptablesUtil.conditions_to_prep_commands( nat_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string( nat_rule['conditions'], description, is_nat_rules=True) commands += [ "${IPTABLES} -t nat -A nat-rules " + ipt + target for ipt in iptables_conditions ] if not self.added_wireguard: wireguard_commands = IptablesUtil.commands_for_wireguard( nat_rule['conditions']) self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") # write out any wireguard nat rules to own file if len(wireguard_commands) > 0: for cmd in wireguard_commands: self.wireguard_file.write(cmd + "\n") self.added_wireguard = True return
def write_port_forward_rule(self, port_forward_rule, verbosity=0): if 'enabled' in port_forward_rule and not port_forward_rule['enabled']: return if 'conditions' not in port_forward_rule or 'list' not in port_forward_rule[ 'conditions']: return if 'ruleId' not in port_forward_rule: return if 'newDestination' in port_forward_rule and 'newPort' in port_forward_rule: target = " -j DNAT --to-destination %s:%s " % ( str(port_forward_rule['newDestination']), str(port_forward_rule['newPort'])) elif 'newDestination' in port_forward_rule: target = " -j DNAT --to-destination %s " % str( port_forward_rule['newDestination']) else: print("ERROR: invalid port forward target: %s" + str(port_forward_rule)) return description = "Port Forward Rule #%i" % int( port_forward_rule['ruleId']) commands = IptablesUtil.conditions_to_prep_commands( port_forward_rule['conditions']['list'], description, verbosity) iptables_conditions = IptablesUtil.conditions_to_iptables_string( port_forward_rule['conditions']['list'], description, verbosity) commands += [ "${IPTABLES} -t nat -A port-forward-rules " + ipt + target for ipt in iptables_conditions ] self.file.write("# %s\n" % description) for cmd in commands: self.file.write(cmd + "\n") self.file.write("\n") return
def write_wireguard_iptables_script(self, settings_file, prefix): """ Write wireguard configuration for wg-quick """ if bool(NetworkUtil.settings) is False: # Network settings must be specified raise Exception("Network settings not specified") delete_rules, new_rules = IptablesUtil.write_wireguard_iptables_rules( self.iptables_table_chain_rules) self.out_file_name = prefix + self.wireguard_iptables_script self.out_file_dir = os.path.dirname(self.out_file_name) if not os.path.exists(self.out_file_dir): os.makedirs(self.out_file_dir) self.out_file = open(self.out_file_name, "w+") self.out_file.write("#!/bin/dash\n") self.out_file.write("## DO NOT EDIT. Changes will be overwritten.\n\n") self.out_file.write( 'if [ -z "$IPTABLES" ] ; then IPTABLES=/sbin/iptables ; fi' + "\n\n") self.out_file.write( 'WG_INTERFACE=$(ip link show | grep "wg[[:digit:]]\+:" | cut -d\' \' -f2 | cut -d: -f1 | head -1)' + "\n\n") self.out_file.write('##' "\n") self.out_file.write('## Delete current rules' "\n") self.out_file.write('##' "\n") for rule in delete_rules: self.out_file.write(rule + "\n") self.out_file.write("\n" '##' "\n") self.out_file.write('## Add new rules' "\n") self.out_file.write('##' "\n") self.out_file.write('if [ "$WG_INTERFACE" != "" ] ; then ' + "\n") for rule in new_rules: self.out_file.write(' ' + rule + "\n") self.out_file.write('fi' + "\n") self.out_file.flush() self.out_file.close() os.chmod(self.out_file_name, os.stat(self.out_file_name).st_mode | stat.S_IEXEC) print("WireguardManager: Wrote %s" % self.out_file_name)
def write_filter_rule(self, table_name, filter_rule, drop_target): if filter_rule.get('enabled') == None or filter_rule.get( 'enabled') == False: return if filter_rule.get('ruleId') == None: return if filter_rule.get('blocked') == None: return if filter_rule.get('blocked'): target = ' -j %s ' % drop_target else: target = ' -j RETURN ' description = "Rule #%i" % int(filter_rule['ruleId']) prep_commands = IptablesUtil.conditions_to_prep_commands( filter_rule['conditions'], description) iptables_conditions = IptablesUtil.conditions_to_iptables_string( filter_rule['conditions'], description) iptables_log_commands = [ ("${IPTABLES} -t filter -A %s " % table_name) + ipt + " -j NFLOG --nflog-prefix 'filter_blocked' " for ipt in iptables_conditions ] iptables_commands = [ ("${IPTABLES} -t filter -A %s " % table_name) + ipt + target for ipt in iptables_conditions ] self.file.write("# %s\n" % description) i = 0 for cmd in prep_commands: self.file.write(cmd + "\n") for cmd in iptables_commands: # write a log rule before each block rule so we log every drop if filter_rule.get('blocked'): self.file.write(iptables_log_commands[i] + "\n") i = i + 1 self.file.write(cmd + "\n") if filter_rule.get('ipv6Enabled') == None or filter_rule.get( 'ipv6Enabled') == False: return ip6tables_commands = [ ("${IP6TABLES} -t filter -A %s " % table_name) + ipt + target for ipt in iptables_conditions ] for cmd in ip6tables_commands: if cmd.find("--protocol ah"): cmd = cmd.replace("--protocol ah", "-m ah ! --ahspi 0") if cmd.find("--protocol icmp"): cmd = cmd.replace("--protocol icmp", "--protocol icmpv6") self.file.write(cmd + "\n") self.file.write("\n") return