[ https://issues.apache.org/jira/browse/CLOUDSTACK-10379?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sean Lair updated CLOUDSTACK-10379: ----------------------------------- Description: There is a bug in the Private Gateway functionality, when Source NAT is enabled for the Private Gateway. When the SNAT is added to iptables, it has the source CIDR of the private gateway subnet. Since no VMs live in that private gateway subnet, the SNAT doesn’t work. Below is an example: * VMs have IP addresses in the 10.0.0.0/24 subnet. * The Private Gateway address is 10.101.141.2/30 See the outputs below, see how the SOURCE field for the new SNAT (eth3) only matches if the source is 10.101.141.0/30? Since the VM has an IP address in 10.0.0.0/24, the VMs don’t get SNAT’d as they should when talking across the private gateway. The SOURCE should be set to ANYWHERE. BEFORE ADDING PRIVATE GATEWAY ----------------------------------------------- {code:java} Chain POSTROUTING (policy ACCEPT 1 packets, 52 bytes) pkts bytes target prot opt in out source destination 2 736 SNAT all -- any eth2 10.0.0.0/24 anywhere to:10.0.0.1 16 1039 SNAT all -- any eth1 anywhere anywhere to:46.99.52.18{code} AFTER ADDING PRIVATE GATEWAY W/ SNAT ----------------------------------------------- {code:java} Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- any eth3 10.101.141.0/30 anywhere to:10.101.141.2 2 736 SNAT all -- any eth2 10.0.0.0/24 anywhere to:10.0.0.1 23 1515 SNAT all -- any eth1 anywhere anywhere to:46.99.52.18 {code} It looks like CsAddress.py treats the creation of the Private Gateway SNAT as if it is a GUEST network, which works fine, except for the SNAT problem shown above. Here is the code from MASTER (line 479 is SNAT rule): {code:java} if self.get_type() in ["guest"]: ... ... self.fw.append(["nat", "front", "-A POSTROUTING -s %s -o %s -j SNAT --to-source %s" % (guestNetworkCidr, self.dev, self.address['public_ip'])]) {code} I am thinking we just change that to the following. I can’t think of any reason we need the source/guest CIDR specified: {code:java} if self.get_type() in ["guest"]: ... ... self.fw.append(["nat", "front", "-A POSTROUTING -o %s -j SNAT --to-source %s" % (self.dev, self.address['public_ip'])]) {code} THE NAT TABLE IF THE ABOVE CODE CHANGE IS MADE ----------------------------------------------- {code:java} Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- any eth3 anywhere anywhere to:10.101.141.2 2 736 SNAT all -- any eth2 anywhere anywhere to:10.0.0.1 23 1515 SNAT all -- any eth1 anywhere {code} was: There is a bug in the Private Gateway functionality, when Source NAT is enabled for the Private Gateway. When the SNAT is added to iptables, it has the source CIDR of the private gateway subnet. Since no VMs live in that private gateway subnet, the SNAT doesn’t work. Below is an example: * VMs have IP addresses in the 10.0.0.0/24 subnet. * The Private Gateway address is 10.101.141.2/30 See the outputs below, see how the SOURCE field for the new SNAT (eth3) only matches if the source is 10.101.141.0/30? Since the VM has an IP address in 10.0.0.0/24, the VMs don’t get SNAT’d as they should when talking across the private gateway. The SOURCE should be set to ANYWHERE. BEFORE ADDING PRIVATE GATEWAY ----------------------------------------------- {code:java} Chain POSTROUTING (policy ACCEPT 1 packets, 52 bytes)pkts bytes target prot opt in out source destination 2 736 SNAT all -- any eth2 10.0.0.0/24 anywhere to:10.0.0.1 16 1039 SNAT all -- any eth1 anywhere anywhere to:46.99.52.18{code} {{}}{{ }} AFTER ADDING PRIVATE GATEWAY W/ SNAT ----------------------------------------------- {code:java} Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- any eth3 10.101.141.0/30 anywhere to:10.101.141.2 2 736 SNAT all -- any eth2 10.0.0.0/24 anywhere to:10.0.0.1 23 1515 SNAT all -- any eth1 anywhere anywhere to:46.99.52.18 {code} It looks like CsAddress.py treats the creation of the Private Gateway SNAT as if it is a GUEST network, which works fine, except for the SNAT problem shown above. Here is the code from MASTER (line 479 is SNAT rule): {code:java} if self.get_type() in ["guest"]: ... ... self.fw.append(["nat", "front", "-A POSTROUTING -s %s -o %s -j SNAT --to-source %s" % (guestNetworkCidr, self.dev, self.address['public_ip'])]) {code} I am thinking we just change that to the following. I can’t think of any reason we need the source/guest CIDR specified: {code:java} if self.get_type() in ["guest"]: ... ... self.fw.append(["nat", "front", "-A POSTROUTING -o %s -j SNAT --to-source %s" % (self.dev, self.address['public_ip'])]) {code} THE NAT TABLE IF THE ABOVE CODE CHANGE IS MADE ----------------------------------------------- {code:java} Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- any eth3 anywhere anywhere to:10.101.141.2 2 736 SNAT all -- any eth2 anywhere anywhere to:10.0.0.1 23 1515 SNAT all -- any eth1 anywhere {code} > Using Source NAT option on Private Gateway does not work > -------------------------------------------------------- > > Key: CLOUDSTACK-10379 > URL: https://issues.apache.org/jira/browse/CLOUDSTACK-10379 > Project: CloudStack > Issue Type: Improvement > Security Level: Public(Anyone can view this level - this is the > default.) > Components: VPC > Affects Versions: 4.9.0, 4.10.0.0 > Environment: KVM > Reporter: Sean Lair > Priority: Minor > Labels: patch > Original Estimate: 24h > Remaining Estimate: 24h > > There is a bug in the Private Gateway functionality, when Source NAT is > enabled for the Private Gateway. When the SNAT is added to iptables, it has > the source CIDR of the private gateway subnet. Since no VMs live in that > private gateway subnet, the SNAT doesn’t work. Below is an example: > > * VMs have IP addresses in the 10.0.0.0/24 subnet. > * The Private Gateway address is 10.101.141.2/30 > > See the outputs below, see how the SOURCE field for the new SNAT (eth3) only > matches if the source is 10.101.141.0/30? Since the VM has an IP address in > 10.0.0.0/24, the VMs don’t get SNAT’d as they should when talking across the > private gateway. The SOURCE should be set to ANYWHERE. > > BEFORE ADDING PRIVATE GATEWAY > ----------------------------------------------- > {code:java} > Chain POSTROUTING (policy ACCEPT 1 packets, 52 bytes) > pkts bytes target prot opt in out source destination > 2 736 SNAT all -- any eth2 10.0.0.0/24 anywhere > to:10.0.0.1 > 16 1039 SNAT all -- any eth1 anywhere anywhere > to:46.99.52.18{code} > > AFTER ADDING PRIVATE GATEWAY W/ SNAT > ----------------------------------------------- > {code:java} > Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) > pkts bytes target prot opt in out source destination > 0 0 SNAT all -- any eth3 10.101.141.0/30 anywhere > to:10.101.141.2 > 2 736 SNAT all -- any eth2 10.0.0.0/24 anywhere > to:10.0.0.1 > 23 1515 SNAT all -- any eth1 anywhere anywhere > to:46.99.52.18 > {code} > > It looks like CsAddress.py treats the creation of the Private Gateway SNAT > as if it is a GUEST network, which works fine, except for the SNAT problem > shown above. Here is the code from MASTER (line 479 is SNAT rule): > > {code:java} > if self.get_type() in ["guest"]: > ... > ... > self.fw.append(["nat", "front", > "-A POSTROUTING -s %s -o %s -j SNAT --to-source %s" % > (guestNetworkCidr, self.dev, self.address['public_ip'])]) > {code} > > I am thinking we just change that to the following. I can’t think of any > reason we need the source/guest CIDR specified: > > {code:java} > if self.get_type() in ["guest"]: > ... > ... > self.fw.append(["nat", "front", > "-A POSTROUTING -o %s -j SNAT --to-source %s" % > (self.dev, self.address['public_ip'])]) > {code} > > THE NAT TABLE IF THE ABOVE CODE CHANGE IS MADE > ----------------------------------------------- > {code:java} > Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) > pkts bytes target prot opt in out source destination > 0 0 SNAT all -- any eth3 anywhere anywhere > to:10.101.141.2 > 2 736 SNAT all -- any eth2 anywhere anywhere > to:10.0.0.1 > 23 1515 SNAT all -- any eth1 anywhere > {code} > -- This message was sent by Atlassian JIRA (v7.6.3#76005)