From 9ab676206a5bfe94aad8d03345c8804d520b0488 Mon Sep 17 00:00:00 2001 From: Patrick Dube Date: Fri, 22 Jul 2016 15:32:20 -0400 Subject: [PATCH] Added missing rules on router config, fixed ordering of multiple rules, removed duplicate rules, added fix for network stats, added a check for b64 decoding (to pad incorrect b64). Also added a catch exception to be logged on the configure main. --- .../debian/config/opt/cloud/bin/configure.py | 201 +++++++++--------- .../config/opt/cloud/bin/cs/CsAddress.py | 17 +- .../config/opt/cloud/bin/cs/CsNetfilter.py | 14 +- 3 files changed, 126 insertions(+), 106 deletions(-) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index 59a8e9dcc78e..35ac3f28e7ed 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -313,6 +313,9 @@ def __createfile(self, ip, folder, file, data): # base64 decode userdata if folder == "userdata" or folder == "user-data": if data is not None: + # need to pad data if it is not valid base 64 + if len(data) % 4 != 0: + data += (4-(len(data) % 4)) * "=" data = base64.b64decode(data) fh = open(dest, "w") @@ -908,104 +911,106 @@ def main(argv): logging.basicConfig(filename=config.get_logger(), level=config.get_level(), format=config.get_format()) - - # Load stored ip adresses from disk to CsConfig() - config.set_address() - - logging.debug("Configuring ip addresses") - config.address().compare() - config.address().process() - - if process_file in ["cmd_line.json", "guest_network.json"]: - logging.debug("Configuring Guest Network") - iptables_change = True - - if process_file in ["cmd_line.json", "vm_password.json"]: - logging.debug("Configuring vmpassword") - password = CsPassword("vmpassword", config) - password.process() - - if process_file in ["cmd_line.json", "vm_metadata.json"]: - logging.debug("Configuring vmdata") - metadata = CsVmMetadata('vmdata', config) - metadata.process() - - if process_file in ["cmd_line.json", "network_acl.json"]: - logging.debug("Configuring networkacl") - iptables_change = True - - if process_file in ["cmd_line.json", "firewall_rules.json"]: - logging.debug("Configuring firewall rules") - iptables_change = True - - if process_file in ["cmd_line.json", "forwarding_rules.json", "staticnat_rules.json"]: - logging.debug("Configuring PF rules") - iptables_change = True - - if process_file in ["cmd_line.json", "site_2_site_vpn.json"]: - logging.debug("Configuring s2s vpn") - iptables_change = True - - if process_file in ["cmd_line.json", "remote_access_vpn.json"]: - logging.debug("Configuring remote access vpn") - iptables_change = True - - if process_file in ["cmd_line.json", "vpn_user_list.json"]: - logging.debug("Configuring vpn users list") - vpnuser = CsVpnUser("vpnuserlist", config) - vpnuser.process() - - if process_file in ["cmd_line.json", "vm_dhcp_entry.json", "dhcp.json"]: - logging.debug("Configuring dhcp entry") - dhcp = CsDhcp("dhcpentry", config) - dhcp.process() - - if process_file in ["cmd_line.json", "load_balancer.json"]: - logging.debug("Configuring load balancer") - iptables_change = True - - if process_file in ["cmd_line.json", "monitor_service.json"]: - logging.debug("Configuring monitor service") - mon = CsMonitor("monitorservice", config) - mon.process() - - # If iptable rules have changed, apply them. - if iptables_change: - acls = CsAcl('networkacl', config) - acls.process() - - acls = CsAcl('firewallrules', config) - acls.process() - - fwd = CsForwardingRules("forwardingrules", config) - fwd.process() - - vpns = CsSite2SiteVpn("site2sitevpn", config) - vpns.process() - - rvpn = CsRemoteAccessVpn("remoteaccessvpn", config) - rvpn.process() - - lb = CsLoadBalancer("loadbalancer", config) - lb.process() - - logging.debug("Configuring iptables rules") - nf = CsNetfilters() - nf.compare(config.get_fw()) - - logging.debug("Configuring iptables rules done ...saving rules") - - # Save iptables configuration - will be loaded on reboot by the iptables-restore that is configured on /etc/rc.local - CsHelper.save_iptables("iptables-save", "/etc/iptables/router_rules.v4") - CsHelper.save_iptables("ip6tables-save", "/etc/iptables/router_rules.v6") - - red = CsRedundant(config) - red.set() - - if process_file in ["cmd_line.json", "static_routes.json"]: - logging.debug("Configuring static routes") - static_routes = CsStaticRoutes("staticroutes", config) - static_routes.process() + try: + # Load stored ip adresses from disk to CsConfig() + config.set_address() + + logging.debug("Configuring ip addresses") + config.address().compare() + config.address().process() + + if process_file in ["cmd_line.json", "guest_network.json"]: + logging.debug("Configuring Guest Network") + iptables_change = True + + if process_file in ["cmd_line.json", "vm_password.json"]: + logging.debug("Configuring vmpassword") + password = CsPassword("vmpassword", config) + password.process() + + if process_file in ["cmd_line.json", "vm_metadata.json"]: + logging.debug("Configuring vmdata") + metadata = CsVmMetadata('vmdata', config) + metadata.process() + + if process_file in ["cmd_line.json", "network_acl.json"]: + logging.debug("Configuring networkacl") + iptables_change = True + + if process_file in ["cmd_line.json", "firewall_rules.json"]: + logging.debug("Configuring firewall rules") + iptables_change = True + + if process_file in ["cmd_line.json", "forwarding_rules.json", "staticnat_rules.json"]: + logging.debug("Configuring PF rules") + iptables_change = True + + if process_file in ["cmd_line.json", "site_2_site_vpn.json"]: + logging.debug("Configuring s2s vpn") + iptables_change = True + + if process_file in ["cmd_line.json", "remote_access_vpn.json"]: + logging.debug("Configuring remote access vpn") + iptables_change = True + + if process_file in ["cmd_line.json", "vpn_user_list.json"]: + logging.debug("Configuring vpn users list") + vpnuser = CsVpnUser("vpnuserlist", config) + vpnuser.process() + + if process_file in ["cmd_line.json", "vm_dhcp_entry.json", "dhcp.json"]: + logging.debug("Configuring dhcp entry") + dhcp = CsDhcp("dhcpentry", config) + dhcp.process() + + if process_file in ["cmd_line.json", "load_balancer.json"]: + logging.debug("Configuring load balancer") + iptables_change = True + + if process_file in ["cmd_line.json", "monitor_service.json"]: + logging.debug("Configuring monitor service") + mon = CsMonitor("monitorservice", config) + mon.process() + + # If iptable rules have changed, apply them. + if iptables_change: + acls = CsAcl('networkacl', config) + acls.process() + + acls = CsAcl('firewallrules', config) + acls.process() + + fwd = CsForwardingRules("forwardingrules", config) + fwd.process() + + vpns = CsSite2SiteVpn("site2sitevpn", config) + vpns.process() + + rvpn = CsRemoteAccessVpn("remoteaccessvpn", config) + rvpn.process() + + lb = CsLoadBalancer("loadbalancer", config) + lb.process() + + logging.debug("Configuring iptables rules") + nf = CsNetfilters() + nf.compare(config.get_fw()) + + logging.debug("Configuring iptables rules done ...saving rules") + + # Save iptables configuration - will be loaded on reboot by the iptables-restore that is configured on /etc/rc.local + CsHelper.save_iptables("iptables-save", "/etc/iptables/router_rules.v4") + CsHelper.save_iptables("ip6tables-save", "/etc/iptables/router_rules.v6") + + red = CsRedundant(config) + red.set() + + if process_file in ["cmd_line.json", "static_routes.json"]: + logging.debug("Configuring static routes") + static_routes = CsStaticRoutes("staticroutes", config) + static_routes.process() + except Exception: + logging.exception("Exception while configuring router") if __name__ == "__main__": main(sys.argv) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py index efcb94f6f818..f78ec4c371c5 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py @@ -432,6 +432,9 @@ def fw_vpcrouter(self): self.fw.append(["mangle", "front", "-A PREROUTING " + "-m state --state RELATED,ESTABLISHED " + "-j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff"]) + + self.fw.append(["filter", "", "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT"]) + if self.get_type() in ["guest"]: self.fw.append(["filter", "", "-A FORWARD -d %s -o %s -j ACL_INBOUND_%s" % (self.address['network'], self.dev, self.dev)]) @@ -439,6 +442,9 @@ def fw_vpcrouter(self): ["filter", "front", "-A ACL_INBOUND_%s -d 224.0.0.18/32 -j ACCEPT" % self.dev]) self.fw.append( ["filter", "front", "-A ACL_INBOUND_%s -d 225.0.0.50/32 -j ACCEPT" % self.dev]) + self.fw.append( + ["filter", "", "-A ACL_INBOUND_%s -j DROP" % self.dev]) + self.fw.append( ["mangle", "front", "-A ACL_OUTBOUND_%s -d 225.0.0.50/32 -j ACCEPT" % self.dev]) self.fw.append( @@ -459,10 +465,12 @@ def fw_vpcrouter(self): (self.dev, self.address[ 'network'], self.address['gateway'], self.dev) ]) - self.fw.append(["", "front", "-A NETWORK_STATS_%s -o %s -s %s" % + + self.fw.append(["", "front", "-A NETWORK_STATS_%s -i %s -d %s" % ("eth1", "eth1", self.address['network'])]) - self.fw.append(["", "front", "-A NETWORK_STATS_%s -o %s -d %s" % + self.fw.append(["", "front", "-A NETWORK_STATS_%s -o %s -s %s" % ("eth1", "eth1", self.address['network'])]) + self.fw.append(["nat", "front", "-A POSTROUTING -s %s -o %s -j SNAT --to-source %s" % (self.address['network'], self.dev, @@ -496,7 +504,10 @@ def fw_vpcrouter(self): self.fw.append(["filter", "", "-A INPUT -d 225.0.0.50/32 -j ACCEPT"]) self.fw.append(["filter", "", "-A INPUT -p icmp -j ACCEPT"]) + self.fw.append(["filter", "", "-A INPUT -i lo -j ACCEPT"]) + self.fw.append(["filter", "", "-A INPUT -i eth0 -p tcp -m tcp --dport 3922 -m state --state NEW,ESTABLISHED -j ACCEPT"]) + self.fw.append(["filter", "", "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT"]) self.fw.append(["filter", "", "-P INPUT DROP"]) self.fw.append(["filter", "", "-P FORWARD DROP"]) @@ -536,7 +547,7 @@ def post_config_change(self, method): if self.address["source_nat"]: vpccidr = cmdline.get_vpccidr() self.fw.append( - ["filter", "", "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr)]) + ["filter", 3, "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr)]) self.fw.append( ["nat", "", "-A POSTROUTING -j SNAT -o %s --to-source %s" % (self.dev, self.address['public_ip'])]) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsNetfilter.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsNetfilter.py index 39f184b39bd6..3ee5174459c2 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsNetfilter.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsNetfilter.py @@ -133,18 +133,21 @@ def get_unseen(self): def compare(self, list): """ Compare reality with what is needed """ - for c in self.chain.get("filter"): - # Ensure all inbound/outbound chains have a default drop rule - if c.startswith("ACL_INBOUND") or c.startswith("ACL_OUTBOUND"): - list.append(["filter", "", "-A %s -j DROP" % c]) # PASS 1: Ensure all chains are present for fw in list: new_rule = CsNetfilter() new_rule.parse(fw[2]) new_rule.set_table(fw[0]) self.add_chain(new_rule) + + ruleSet = set() # PASS 2: Create rules for fw in list: + tupledFw = tuple(fw) + if tupledFw in ruleSet : + logging.debug("Already processed : %s", tupledFw) + continue + new_rule = CsNetfilter() new_rule.parse(fw[2]) new_rule.set_table(fw[0]) @@ -165,12 +168,13 @@ def compare(self, list): cpy = cpy.replace('-A', '-I') if isinstance(fw[1], int): # if the rule is for ACLs, we want to insert them in order, right before the DROP all - if rule_chain.startswith("ACL_INBOUND") or rule_chain.startswith("ACL_OUTBOUND"): + if rule_chain.startswith("ACL_INBOUND"): rule_count = self.chain.get_count(rule_chain) cpy = cpy.replace("-A %s" % new_rule.get_chain(), '-I %s %s' % (new_rule.get_chain(), rule_count)) else: cpy = cpy.replace("-A %s" % new_rule.get_chain(), '-I %s %s' % (new_rule.get_chain(), fw[1])) CsHelper.execute("iptables -t %s %s" % (new_rule.get_table(), cpy)) + ruleSet.add(tupledFw) self.chain.add_rule(rule_chain) self.del_standard() self.get_unseen()