From 08eb92273d18ebf5d76ded6428496e878c88b3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Weing=C3=A4rtner?= Date: Mon, 2 Apr 2018 08:30:34 -0300 Subject: [PATCH] [CLOUDSTACK-10346] VPC-NAT configuration, access via public IPs does not work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When users create a VPC, and configure a NAT from a public IP to application in a VM. This VM(applications) are not accessible via public IP for other VMs in the same VPC. The problem is in the NAT table. If you take a closer look at rules, you will see something like: -A PREROUTING -d publicIP/32 -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination internalIp:80 The problem is that according to this rule only packets coming via eth1(public interface), will be “redirected” to the internal IP. We need an extra entry to each one of the NAT configurations. For the presented rule, we would need something like: -A PREROUTING -d publicIP/32 -i eth2 -p tcp -m tcp --dport 80 -j DNAT --to-destination internalIp:80 --- systemvm/debian/opt/cloud/bin/configure.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/systemvm/debian/opt/cloud/bin/configure.py b/systemvm/debian/opt/cloud/bin/configure.py index a3b7674926c4..c83d832b2022 100755 --- a/systemvm/debian/opt/cloud/bin/configure.py +++ b/systemvm/debian/opt/cloud/bin/configure.py @@ -801,6 +801,7 @@ def portsToString(self, ports, delimiter): return "%s%s%s" % (ports_parts[0], delimiter, ports_parts[1]) def processForwardRule(self, rule): + logging.info("Is going to process VPC forwarding: %s", self.config.is_vpc()) if self.config.is_vpc(): self.forward_vpc(rule) else: @@ -894,6 +895,15 @@ def forward_vpc(self, rule): if not rule["internal_ports"] == "any": fw_prerout_rule += ":" + self.portsToString(rule["internal_ports"], "-") + fw_prerout_rule2 = "-A PREROUTING -d %s/32 -i %s" % (rule["public_ip"], self.getDeviceByIp(rule['internal_ip'])) + if not rule["protocol"] == "any": + fw_prerout_rule2 += " -m %s -p %s" % (rule["protocol"], rule["protocol"]) + if not rule["public_ports"] == "any": + fw_prerout_rule2 += " --dport %s" % self.portsToString(rule["public_ports"], ":") + fw_prerout_rule2 += " -j DNAT --to-destination %s" % rule["internal_ip"] + if not rule["internal_ports"] == "any": + fw_prerout_rule2 += ":" + self.portsToString(rule["internal_ports"], "-") + fw_postrout_rule = "-A POSTROUTING -d %s/32 " % rule["public_ip"] if not rule["protocol"] == "any": fw_postrout_rule += " -m %s -p %s" % (rule["protocol"], rule["protocol"]) @@ -913,6 +923,7 @@ def forward_vpc(self, rule): fw_output_rule += ":" + self.portsToString(rule["internal_ports"], "-") self.fw.append(["nat", "", fw_prerout_rule]) + self.fw.append(["nat", "", fw_prerout_rule2]) self.fw.append(["nat", "", fw_postrout_rule]) self.fw.append(["nat", "", fw_output_rule])