From 366f63fb96609827b03b96ae798780093b8c7085 Mon Sep 17 00:00:00 2001 From: Jeff Ahrenholz Date: Tue, 9 Oct 2018 15:19:14 -0700 Subject: [PATCH 1/2] add a source NAT service using iptables masquerade --- daemon/core/services/security.py | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/daemon/core/services/security.py b/daemon/core/services/security.py index 926376f8..3576b837 100644 --- a/daemon/core/services/security.py +++ b/daemon/core/services/security.py @@ -110,3 +110,47 @@ class Firewall(CoreService): logger.exception("Error opening Firewall configuration template (%s)", fname) return cfg + +class Nat(CoreService): + ''' IPv4 source NAT service + ''' + name = "NAT" + group = "Security" + configs = ('nat.sh', ) + startup = ('sh nat.sh',) + custom_needed = False + + @classmethod + def generateifcnatrule(cls, ifc, line_prefix=""): + ''' Generate a NAT line for one interface. + ''' + cfg = line_prefix + "iptables -t nat -A POSTROUTING -o " + cfg +=ifc.name + " -j MASQUERADE\n" + + cfg += line_prefix + "iptables -A FORWARD -i " + ifc.name + cfg += " -m state --state RELATED,ESTABLISHED -j ACCEPT\n" + + cfg += line_prefix + "iptables -A FORWARD -i " + cfg += ifc.name + " -j DROP\n" + return cfg + + @classmethod + def generate_config(cls, node, filename): + ''' NAT out the first interface + ''' + cfg = "#!/bin/sh\n" + cfg += "# generated by security.py\n" + cfg += "# NAT out the first interface by default\n" + have_nat = False + for ifc in node.netifs(): + if hasattr(ifc, 'control') and ifc.control == True: + continue + if have_nat: + cfg += cls.generateifcnatrule(ifc, line_prefix='#') + else: + have_nat = True + cfg += "# NAT out the " + ifc.name + " interface\n" + cfg += cls.generateifcnatrule(ifc) + cfg += "\n" + return cfg + From ca107a32073a80607a382502a0ef3823d1baded2 Mon Sep 17 00:00:00 2001 From: bharnden Date: Wed, 10 Oct 2018 14:49:51 -0700 Subject: [PATCH 2/2] #199 small tweaks to be consistent with rest of code --- daemon/core/services/security.py | 39 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/daemon/core/services/security.py b/daemon/core/services/security.py index 3576b837..38d9d16e 100644 --- a/daemon/core/services/security.py +++ b/daemon/core/services/security.py @@ -11,8 +11,8 @@ from core.service import CoreService class VPNClient(CoreService): name = "VPNClient" group = "Security" - configs = ('vpnclient.sh',) - startup = ('sh vpnclient.sh',) + configs = ("vpnclient.sh",) + startup = ("sh vpnclient.sh",) shutdown = ("killall openvpn",) validate = ("pidof openvpn",) custom_needed = True @@ -37,8 +37,8 @@ class VPNClient(CoreService): class VPNServer(CoreService): name = "VPNServer" group = "Security" - configs = ('vpnserver.sh',) - startup = ('sh vpnserver.sh',) + configs = ("vpnserver.sh",) + startup = ("sh vpnserver.sh",) shutdown = ("killall openvpn",) validate = ("pidof openvpn",) custom_needed = True @@ -64,8 +64,8 @@ class VPNServer(CoreService): class IPsec(CoreService): name = "IPsec" group = "Security" - configs = ('ipsec.sh',) - startup = ('sh ipsec.sh',) + configs = ("ipsec.sh",) + startup = ("sh ipsec.sh",) shutdown = ("killall racoon",) custom_needed = True @@ -91,8 +91,8 @@ class IPsec(CoreService): class Firewall(CoreService): name = "Firewall" group = "Security" - configs = ('firewall.sh',) - startup = ('sh firewall.sh',) + configs = ("firewall.sh",) + startup = ("sh firewall.sh",) custom_needed = True @classmethod @@ -111,19 +111,23 @@ class Firewall(CoreService): return cfg + class Nat(CoreService): - ''' IPv4 source NAT service - ''' + """ + IPv4 source NAT service. + """ name = "NAT" + executables = ("iptables",) group = "Security" - configs = ('nat.sh', ) - startup = ('sh nat.sh',) + configs = ("nat.sh", ) + startup = ("sh nat.sh",) custom_needed = False @classmethod def generateifcnatrule(cls, ifc, line_prefix=""): - ''' Generate a NAT line for one interface. - ''' + """ + Generate a NAT line for one interface. + """ cfg = line_prefix + "iptables -t nat -A POSTROUTING -o " cfg +=ifc.name + " -j MASQUERADE\n" @@ -136,8 +140,9 @@ class Nat(CoreService): @classmethod def generate_config(cls, node, filename): - ''' NAT out the first interface - ''' + """ + NAT out the first interface + """ cfg = "#!/bin/sh\n" cfg += "# generated by security.py\n" cfg += "# NAT out the first interface by default\n" @@ -146,7 +151,7 @@ class Nat(CoreService): if hasattr(ifc, 'control') and ifc.control == True: continue if have_nat: - cfg += cls.generateifcnatrule(ifc, line_prefix='#') + cfg += cls.generateifcnatrule(ifc, line_prefix="#") else: have_nat = True cfg += "# NAT out the " + ifc.name + " interface\n"