[ https://issues.apache.org/jira/browse/CLOUDSTACK-9339?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15439785#comment-15439785 ]
ASF GitHub Bot commented on CLOUDSTACK-9339: -------------------------------------------- Github user jburwell commented on a diff in the pull request: https://github.com/apache/cloudstack/pull/1659#discussion_r76484431 --- Diff: test/integration/smoke/test_multiple_public_ip_ranges.py --- @@ -0,0 +1,887 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +""" BVT tests for network services on public IP's from different public IP + range than that of associated source NAT IP of the network. Each IP associated + with network from a different public IP range results in a new public + interface on VR (eth3, eth4 etc) and iptable +""" +# Import Local Modules +from marvin.codes import (FAILED, STATIC_NAT_RULE, LB_RULE, + NAT_RULE, PASS) +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackException import CloudstackAPIException +from marvin.cloudstackAPI import rebootRouter +from marvin.sshClient import SshClient +from marvin.lib.utils import cleanup_resources, get_process_status +from marvin.lib.base import (Account, + VirtualMachine, + ServiceOffering, + NATRule, + PublicIPAddress, + StaticNATRule, + FireWallRule, + Network, + NetworkOffering, + LoadBalancerRule, + PublicIpRange, + Router, + VpcOffering, + VPC, + NetworkACL) +from marvin.lib.common import (get_domain, + get_zone, + get_template, + list_hosts, + list_publicIP, + list_nat_rules, + list_routers, + list_virtual_machines, + list_lb_rules, + list_configurations, + verifyGuestTrafficPortGroups) +from nose.plugins.attrib import attr +from ddt import ddt, data +# Import System modules +import socket +import time +import logging + +_multiprocess_shared_ = True + +logger = logging.getLogger('TestNetworkOps') +stream_handler = logging.StreamHandler() +logger.setLevel(logging.DEBUG) +logger.addHandler(stream_handler) + +class TestPortForwarding(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + testClient = super(TestPortForwarding, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + cls.hypervisor = testClient.getHypervisorInfo() + # Get Zone, Domain and templates + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["zoneid"] = cls.zone.id + template = get_template( + cls.apiclient, + cls.zone.id, + cls.services["ostype"] + ) + if template == FAILED: + assert False, "get_template() failed to return template with description %s" % cls.services[ + "ostype"] + + # Create an account, network, VM and IP addresses + cls.account = Account.create( + cls.apiclient, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + cls.services["publiciprange"]["zoneid"] = cls.zone.id + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.services["service_offerings"]["tiny"] + ) + cls.virtual_machine = VirtualMachine.create( + cls.apiclient, + cls.services["virtual_machine"], + templateid=template.id, + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id + ) + cls._cleanup = [ + cls.virtual_machine, + cls.account, + cls.service_offering + ] + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.cleanup = [] + return + + @classmethod + def tearDownClass(cls): + try: + cls.apiclient = super( + TestPortForwarding, + cls).getClsTestClient().getApiClient() + cleanup_resources(cls.apiclient, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def tearDown(self): + cleanup_resources(self.apiclient, self.cleanup) + return + + @attr(tags=["advanced", "smoke"], required_hardware="true") + def test_port_forwarding_on_ip_from_non_src_nat_ip_range(self): + """Test for port forwarding on a IP which is in pubic IP range different + from public IP range that has source NAT IP associated with network + """ + + # Validate the following: + # 1. Create a new public IP range and dedicate to a account + # 2. Acquire a IP from new public range + # 3. create a port forwarding on acquired IP from new range + # 4. Create a firewall rule to open up the port + # 5. Test SSH works to the VM + + self.public_ip_range = PublicIpRange.create( + self.apiclient, + self.services["publiciprange"] + ) + --- End diff -- Add an assertion to validate the ``this.public_ip_range`` is not ``None`` or has an error. > Virtual Routers don't handle Multiple Public Interfaces > ------------------------------------------------------- > > Key: CLOUDSTACK-9339 > URL: https://issues.apache.org/jira/browse/CLOUDSTACK-9339 > Project: CloudStack > Issue Type: Bug > Security Level: Public(Anyone can view this level - this is the > default.) > Components: Virtual Router > Affects Versions: 4.8.0 > Reporter: dsclose > Labels: firewall, nat, router > > There are a series of issues with the way Virtual Routers manage multiple > public interfaces. These are more pronounced on redundant virtual router > setups. I have not attempted to examine these issues in a VPC context. > Outside of a VPC context, however, the following is expected behaviour: > * eth0 connects the router to the guest network. > * In RvR setups, keepalived manages the guests' gateway IP as a virtual IP on > eth0. > * eth1 provides a local link to the hypervisor, allowing Cloudstack to issue > commands to the router. > * eth2 is the routers public interface. By default, a single public IP will > be setup on eth2 along with the necessary iptables and ip rules to source-NAT > guest traffic to that public IP. > * When a public IP address is assigned to the router that is on a separate > subnet to the source-NAT IP, a new interface is configured, such as eth3, and > the IP is assigned to that interface. > * This can result in eth3, eth4, eth5, etc. being created depending upon how > many public subnets the router has to work with. > The above all works. The following, however, is currently not working: > * Public interfaces should be set to DOWN on backup redundant routers. The > master.py script is responsible for setting public interfaces to UP during a > keepalived transition. Currently the check_is_up method of the CsIP class > brings all interfaces UP on both RvR. A proposed fix for this has been > discussed on the mailing list. That fix will leave public interfaces DOWN on > RvR allowing the keepalived transition to control the state of public > interfaces. Issue #1413 includes a commit that contradicts the proposed fix > so it is unclear what the current state of the code should be. > * Newly created interfaces should be set to UP on master redundant routers. > Assuming public interfaces should be default be DOWN on an RvR we need to > accommodate the fact that, as interfaces are created, no keepalived > transition occurs. This means that assigning an IP from a new public subnet > will have no effect (as the interface will be down) until the network is > restarted with a "clean up." > * Public interfaces other than eth2 do not forward traffic. There are two > iptables rules in the FORWARD chain of the filter table created for eth2 that > allow forwarding between eth2 and eth0. Equivalent rules are not created for > other public interfaces so forwarded traffic is dropped. > * Outbound traffic from guest VMs does not honour static-NAT rules. Instead, > outbound traffic is source-NAT'd to the networks default source-NAT IP. New > connections from guests that are destined for public networks are processed > like so: > 1. Traffic is matched against the following rule in the mangle table that > marks the connection with a 0x0: > *mangle > -A PREROUTING -i eth0 -m state --state NEW -j CONNMARK --set-xmark > 0x0/0xffffffff > 2. There are no "ip rule" statements that match a connection marked 0x0, so > the kernel routes the connection via the default gateway. That gateway is on > source-NAT subnet, so the connection is routed out of eth2. > 3. The following iptables rules are then matched in the filter table: > *filter > -A FORWARD -i eth0 -o eth2 -j FW_OUTBOUND > -A FW_OUTBOUND -j FW_EGRESS_RULES > -A FW_EGRESS_RULES -j ACCEPT > 4. Finally, the following rule is matched from the nat table, where the IP > address is the source-NAT IP: > *nat > -A POSTROUTING -o eth2 -j SNAT --to-source 123.4.5.67 > -- This message was sent by Atlassian JIRA (v6.3.4#6332)