You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cloudstack.apache.org by rhtyd <gi...@git.apache.org> on 2016/08/26 10:37:18 UTC

[GitHub] cloudstack pull request #1663: CLOUDSTACK-6432: Prevent DNS reflection attac...

GitHub user rhtyd opened a pull request:

    https://github.com/apache/cloudstack/pull/1663

    CLOUDSTACK-6432: Prevent DNS reflection attacks

    At least in SG zones DNS on the VR is publicly accessible and as such
    susceptible to DNS amplification/reflection attacks. This fixes it as per
    https://issues.apache.org/jira/browse/CLOUDSTACK-6432 to only allow IPs
    from the guest cidr to send DNS requests on port 53.
    
    Due to repository commit issues I've created this PR, based on #1653 .

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/shapeblue/cloudstack 4.9-dnsreflection-attack

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/cloudstack/pull/1663.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #1663
    
----
commit 5adacc9b6f1b7b9ae53d35aa78fc8f7cd0d2273e
Author: NuxRo <nu...@li.nux.ro>
Date:   2016-08-22T09:31:41Z

    CLOUDSTACK-6432: Prevent DNS reflection attacks
    
    At least in SG zones DNS on the VR is publicly accessible and as such
    susceptible to DNS amplification/reflection attacks. This fixes it as per
    https://issues.apache.org/jira/browse/CLOUDSTACK-6432 to only allow IPs
    from the guest cidr to send DNS requests on port 53.
    
    Signed-off-by: Rohit Yadav <ro...@shapeblue.com>

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by jburwell <gi...@git.apache.org>.
Github user jburwell commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76546255
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +
    +        self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm.id)
    +        FireWallRule.create(
    +            self.apiclient,
    +            ipaddressid=public_ip.id,
    +            protocol=self.services["natrule1"]["protocol"],
    +            cidrlist=['0.0.0.0/0'],
    +            startport=self.services["natrule1"]["publicport"],
    +            endport=self.services["natrule1"]["publicport"]
    +        )
    +
    +        self.logger.debug("Creating NAT rule for VM ID: %s" % self.vm.id)
    +        nat_rule1 = NATRule.create(
    +            self.apiclient,
    +            self.vm,
    +            self.services["natrule1"],
    +            public_ip.id
    +        )
    +        nat_rules = list_nat_rules(
    +            self.apiclient,
    +            id=nat_rule1.id
    +        )
    +        self.assertEqual(
    +            isinstance(nat_rules, list),
    +            True,
    +            "Check for list NAT rules response return valid data"
    +        )
    --- End diff --
    
    Should there be an assertiong that ``nat_rules`` has a length of 1?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by jburwell <gi...@git.apache.org>.
Github user jburwell commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76546205
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    --- End diff --
    
    Should there be an ``assert`` that ``public_ips`` has a length of 1?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by jburwell <gi...@git.apache.org>.
Github user jburwell commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76546145
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +
    +        self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm.id)
    +        FireWallRule.create(
    +            self.apiclient,
    +            ipaddressid=public_ip.id,
    +            protocol=self.services["natrule1"]["protocol"],
    +            cidrlist=['0.0.0.0/0'],
    +            startport=self.services["natrule1"]["publicport"],
    +            endport=self.services["natrule1"]["publicport"]
    +        )
    --- End diff --
    
    Should we check that the results of the ``FireWallRule.create`` call to ensure that it created as expected?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
GitHub user rhtyd reopened a pull request:

    https://github.com/apache/cloudstack/pull/1663

    [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflection attacks

    CLOUDSTACK-6432: Prevent DNS reflection attacks
        
        DNS on VR should not be publically accessible as it may be prone to DNS
        amplification/reflection attacks. This fixes the issue by only allowing VR
        DNS (port 53) to be accessible from guest network cidr, as per the fix in:
        https://issues.apache.org/jira/browse/CLOUDSTACK-6432
        
        - Only allows guest network cidrs to query VR DNS on port 53.
        - Includes marvin smoke test that checks the VR DNS accessibility checks from
          guest and non-guest network.
        - Fixes Marvin sshClient to avoid using ssh agent when password is provided,
          previous some environments may have seen 'No existing session' exception without
          this fix.
        - Adds a new dnspython dependency that is used to perform dns resolutions in the
          tests.
    
    Due to repository commit issues I've created this PR, based on #1653 .
    
    /cc @jburwell @karuturi @NuxRo @ustcweizhou @wido  and others

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/shapeblue/cloudstack 4.9-dnsreflection-attack

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/cloudstack/pull/1663.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #1663
    
----
commit 56ad2c83ae2fb8f3cb74df15ed57a35c795ebced
Author: Rohit Yadav <ro...@shapeblue.com>
Date:   2016-08-22T09:31:41Z

    CLOUDSTACK-6432: Prevent DNS reflection attacks
    
    DNS on VR should not be publically accessible as it may be prone to DNS
    amplification/reflection attacks. This fixes the issue by only allowing VR
    DNS (port 53) to be accessible from guest network cidr, as per the fix in:
    https://issues.apache.org/jira/browse/CLOUDSTACK-6432
    
    - Only allows guest network cidrs to query VR DNS on port 53.
    - Includes marvin smoke test that checks the VR DNS accessibility checks from
      guest and non-guest network.
    - Fixes Marvin sshClient to avoid using ssh agent when password is provided,
      previous some environments may have seen 'No existing session' exception without
      this fix.
    - Adds a new dnspython dependency that is used to perform dns resolutions in the
      tests.
    
    Signed-off-by: Rohit Yadav <ro...@shapeblue.com>

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    Thanks all, based on the test results and reviews from this PR with the marvin test and the original PR #1653 from where the main changes were taken, I'll go ahead and merge this now.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    @s-seitz the fix should work for newly deployed VRs, for existing VR there may be existing rules or chains blocking the intended fix. Are you getting issues or seeing the same behaviour with new VRs? If yes, can you send a fix. Thanks.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd closed the pull request at:

    https://github.com/apache/cloudstack/pull/1663


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by jburwell <gi...@git.apache.org>.
Github user jburwell commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76546049
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +
    +        self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm.id)
    +        FireWallRule.create(
    +            self.apiclient,
    +            ipaddressid=public_ip.id,
    +            protocol=self.services["natrule1"]["protocol"],
    +            cidrlist=['0.0.0.0/0'],
    +            startport=self.services["natrule1"]["publicport"],
    +            endport=self.services["natrule1"]["publicport"]
    +        )
    +
    +        self.logger.debug("Creating NAT rule for VM ID: %s" % self.vm.id)
    +        nat_rule1 = NATRule.create(
    +            self.apiclient,
    +            self.vm,
    +            self.services["natrule1"],
    +            public_ip.id
    +        )
    +        nat_rules = list_nat_rules(
    +            self.apiclient,
    +            id=nat_rule1.id
    +        )
    +        self.assertEqual(
    +            isinstance(nat_rules, list),
    +            True,
    +            "Check for list NAT rules response return valid data"
    +        )
    +        self.assertEqual(
    +            nat_rules[0].state,
    +            'Active',
    +            "Check list port forwarding rules"
    +        )
    +
    +        result = None
    +        try:
    +            self.logger.debug("SSH into guest VM with IP: %s" % nat_rule1.ipaddress)
    +            ssh = self.vm.get_ssh_client(ipaddress=nat_rule1.ipaddress, port=self.services['natrule1']["publicport"], retries=8)
    +            result = str(ssh.execute("nslookup google.com"))
    +        except Exception as e:
    +            self.fail("Failed to SSH into VM - %s due to exception: %s" % (nat_rule1.ipaddress, e))
    +
    +        self.assertTrue(result is not None and "google.com" in result and "#53" in result,
    --- End diff --
    
    Minor nit: Consider breaking up into three asserts with more detailed messages to improve the isolation of a failure


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by jburwell <gi...@git.apache.org>.
Github user jburwell commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76546182
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    --- End diff --
    
    The setup of this test method and ``test_router_dns_externalipquery`` seem very similar.  Would it make sense to factor it out to the ``setup`` method or some other internal utility method?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76561209
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    --- End diff --
    
    Fixed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76561440
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +
    +        self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm.id)
    +        FireWallRule.create(
    +            self.apiclient,
    +            ipaddressid=public_ip.id,
    +            protocol=self.services["natrule1"]["protocol"],
    +            cidrlist=['0.0.0.0/0'],
    +            startport=self.services["natrule1"]["publicport"],
    +            endport=self.services["natrule1"]["publicport"]
    +        )
    +
    +        self.logger.debug("Creating NAT rule for VM ID: %s" % self.vm.id)
    +        nat_rule1 = NATRule.create(
    +            self.apiclient,
    +            self.vm,
    +            self.services["natrule1"],
    +            public_ip.id
    +        )
    +        nat_rules = list_nat_rules(
    +            self.apiclient,
    +            id=nat_rule1.id
    +        )
    +        self.assertEqual(
    +            isinstance(nat_rules, list),
    +            True,
    +            "Check for list NAT rules response return valid data"
    +        )
    --- End diff --
    
    Fixed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76561383
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    --- End diff --
    
    Fixed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by borisstoyanov <gi...@git.apache.org>.
Github user borisstoyanov commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    LGTM, I was able to build and test the PR. Found a little issue with the tests and fixed it. 
    Here are the tests results: 
    
    
    ```
    $ nosetests --with-xunit --xunit-file=integration-test-results.xml --with-marvin --marvin-config=advanced_ccs.cfg -s -a tags=advanced,required_hardware=true --zone=zone1 --hypervisor=kvm cloudstack/test/integration/smoke/test_router_dns.py -vv
    nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$']
    
    ==== Marvin Init Started ====
    
    === Marvin Parse Config Successful ===
    
    === Marvin Setting TestData Successful===
    
    ==== Log Folder Path: /tmp//MarvinLogs//Aug_30_2016_15_44_51_LNKTQ1. All logs will be available here ====
    
    === Marvin Init Logging Successful===
    
    ==== Marvin Init Successful ====
    Creating Admin Account for domain b1376fae-6e2a-11e6-bca7-000c290e77f6 on zone 7060c2b9-7ea2-475f-9b74-56ce80444feb
    Creating Service Offering on zone 7060c2b9-7ea2-475f-9b74-56ce80444feb
    Creating Network Offering on zone 7060c2b9-7ea2-475f-9b74-56ce80444feb
    Creating Network for Account test-a-TestRouterDns-CF5DZ4 using offering 8c206825-65e7-4aaa-9850-b8e804f523ef
    Creating guest VM for Account test-a-TestRouterDns-CF5DZ4 using offering 6fd51c75-fe0f-4673-8b1a-a312fe5605c4
    Starting test_router_dns_externalips...
    Querying VR DNS IP: 192.168.1.103
    VR DNS query failed from non-guest network IP as expected
    === TestName: test_router_dns_externalipquery | Status : SUCCESS ===
    
    Starting test_router_dns_guestipquery...
    Creating Firewall rule for VM ID: cf929b5d-4ce1-4c86-b389-5baba0a5d8e7
    Creating NAT rule for VM ID: cf929b5d-4ce1-4c86-b389-5baba0a5d8e7
    SSH into guest VM with IP: 192.168.1.103
    ====Trying SSH Connection: Host:192.168.1.103 User:root                                   Port:22 RetryCnt:8===
    SshClient: Exception under createConnection: ['Traceback (most recent call last):\n', '  File "/usr/local/lib/python2.7/site-packages/marvin/sshClient.py", line 122, in createConnection\n    allow_agent=False)\n', '  File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in connect\n    retry_on_signal(lambda: sock.connect(addr))\n', '  File "/usr/local/lib/python2.7/site-packages/paramiko/util.py", line 269, in retry_on_signal\n    return function()\n', '  File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in <lambda>\n    retry_on_signal(lambda: sock.connect(addr))\n', '  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth\n    return getattr(self._sock,name)(*args)\n', 'error: [Errno 51] Network is unreachable\n']
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/site-packages/marvin/sshClient.py", line 122, in createConnection
        allow_agent=False)
      File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in connect
        retry_on_signal(lambda: sock.connect(addr))
      File "/usr/local/lib/python2.7/site-packages/paramiko/util.py", line 269, in retry_on_signal
        return function()
      File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in <lambda>
        retry_on_signal(lambda: sock.connect(addr))
      File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
        return getattr(self._sock,name)(*args)
    error: [Errno 51] Network is unreachable
    ====Trying SSH Connection: Host:192.168.1.103 User:root                                   Port:22 RetryCnt:7===
    SshClient: Exception under createConnection: ['Traceback (most recent call last):\n', '  File "/usr/local/lib/python2.7/site-packages/marvin/sshClient.py", line 122, in createConnection\n    allow_agent=False)\n', '  File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in connect\n    retry_on_signal(lambda: sock.connect(addr))\n', '  File "/usr/local/lib/python2.7/site-packages/paramiko/util.py", line 269, in retry_on_signal\n    return function()\n', '  File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in <lambda>\n    retry_on_signal(lambda: sock.connect(addr))\n', '  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth\n    return getattr(self._sock,name)(*args)\n', 'error: [Errno 51] Network is unreachable\n']
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/site-packages/marvin/sshClient.py", line 122, in createConnection
        allow_agent=False)
      File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in connect
        retry_on_signal(lambda: sock.connect(addr))
      File "/usr/local/lib/python2.7/site-packages/paramiko/util.py", line 269, in retry_on_signal
        return function()
      File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 305, in <lambda>
        retry_on_signal(lambda: sock.connect(addr))
      File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
        return getattr(self._sock,name)(*args)
    error: [Errno 51] Network is unreachable
    ====Trying SSH Connection: Host:192.168.1.103 User:root                                   Port:22 RetryCnt:6===
    ===SSH to Host 192.168.1.103 port : 22 SUCCESSFUL===
    {Cmd: nslookup google.com via Host: 192.168.1.103} {returns: [u'Server:\t\t10.1.1.1', u'Address:\t10.1.1.1#53', u'', u'Non-authoritative answer:', u'Name:\tgoogle.com', u'Address: 212.39.82.187', u'Name:\tgoogle.com', u'Address: 212.39.82.174', u'Name:\tgoogle.com', u'Address: 212.39.82.152', u'Name:\tgoogle.com', u'Address: 212.39.82.180', u'Name:\tgoogle.com', u'Address: 212.39.82.167', u'Name:\tgoogle.com', u'Address: 212.39.82.181', u'Name:\tgoogle.com', u'Address: 212.39.82.159', u'Name:\tgoogle.com', u'Address: 212.39.82.153', u'Name:\tgoogle.com', u'Address: 212.39.82.146', u'Name:\tgoogle.com', u'Address: 212.39.82.173', u'Name:\tgoogle.com', u'Address: 212.39.82.166', u'Name:\tgoogle.com', u'Address: 212.39.82.160', u'']}
    === TestName: test_router_dns_guestipquery | Status : SUCCESS ===
    
    ===final results are now copied to: /tmp//MarvinLogs/test_router_dns_IG8LQP===
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by jburwell <gi...@git.apache.org>.
Github user jburwell commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76546110
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    --- End diff --
    
    Should there be an ``assert`` that ``public_ips`` has a length of 1?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: CLOUDSTACK-6432: Prevent DNS reflection attac...

Posted by rhtyd <gi...@git.apache.org>.
GitHub user rhtyd reopened a pull request:

    https://github.com/apache/cloudstack/pull/1663

    CLOUDSTACK-6432: Prevent DNS reflection attacks

    CLOUDSTACK-6432: Prevent DNS reflection attacks
        
        DNS on VR should not be publically accessible as it may be prone to DNS
        amplification/reflection attacks. This fixes the issue by only allowing VR
        DNS (port 53) to be accessible from guest network cidr, as per the fix in:
        https://issues.apache.org/jira/browse/CLOUDSTACK-6432
        
        - Only allows guest network cidrs to query VR DNS on port 53.
        - Includes marvin smoke test that checks the VR DNS accessibility checks from
          guest and non-guest network.
        - Fixes Marvin sshClient to avoid using ssh agent when password is provided,
          previous some environments may have seen 'No existing session' exception without
          this fix.
        - Adds a new dnspython dependency that is used to perform dns resolutions in the
          tests.
    
    Due to repository commit issues I've created this PR, based on #1653 .
    
    /cc @jburwell @karuturi @NuxRo @ustcweizhou @wido  and others

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/shapeblue/cloudstack 4.9-dnsreflection-attack

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/cloudstack/pull/1663.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #1663
    
----
commit 3f588c3f85c64d89cd3e071854655ae475826ad5
Author: Rohit Yadav <ro...@shapeblue.com>
Date:   2016-08-22T09:31:41Z

    CLOUDSTACK-6432: Prevent DNS reflection attacks
    
    DNS on VR should not be publically accessible as it may be prone to DNS
    amplification/reflection attacks. This fixes the issue by only allowing VR
    DNS (port 53) to be accessible from guest network cidr, as per the fix in:
    https://issues.apache.org/jira/browse/CLOUDSTACK-6432
    
    - Only allows guest network cidrs to query VR DNS on port 53.
    - Includes marvin smoke test that checks the VR DNS accessibility checks from
      guest and non-guest network.
    - Fixes Marvin sshClient to avoid using ssh agent when password is provided,
      previous some environments may have seen 'No existing session' exception without
      this fix.
    - Adds a new dnspython dependency that is used to perform dns resolutions in the
      tests.
    
    Signed-off-by: Rohit Yadav <ro...@shapeblue.com>

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by jburwell <gi...@git.apache.org>.
Github user jburwell commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    @NuxRo Any thoughts to add?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/cloudstack/pull/1663


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by s-seitz <gi...@git.apache.org>.
Github user s-seitz commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    After patching our systemvm.iso and the respective routers, I've noticed the iptables rules changed as given in CsAddress.py. These rules don't get any packets since two identical (but unpatched) rules apply before. I found these in CsApp.py.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: CLOUDSTACK-6432: Prevent DNS reflection attacks

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    New smoke test result:
    
    $ nosetests --with-xunit --xunit-file=integration-test-results.xml --with-marvin --marvin-config=/home/bhaisaab/Lab/apache/marvin-cfgs/adv-kvm.cfg -s -a tags=advanced,required_hardware=true --zone=KVM-advzone --hypervisor=KVM  test_router_dns.py
    
    ==== Marvin Init Started ====
    
    === Marvin Parse Config Successful ===
    
    === Marvin Setting TestData Successful===
    
    ==== Log Folder Path: /tmp//MarvinLogs//Aug_26_2016_19_25_30_U977TH. All logs will be available here ====
    
    === Marvin Init Logging Successful===
    
    ==== Marvin Init Successful ====
    Creating Admin Account for domain db10a868-6b7a-11e6-863f-a434d91cd37e on zone d7eb01c3-f5e4-4643-ae8a-14372778ffb4
    Creating Service Offering on zone d7eb01c3-f5e4-4643-ae8a-14372778ffb4
    Creating Network Offering on zone d7eb01c3-f5e4-4643-ae8a-14372778ffb4
    Creating Network for Account test-a-TestRouterDns-64PRTV using offering 4a0b3e7e-c585-4b96-8040-736161597b62
    Creating guest VM for Account test-a-TestRouterDns-64PRTV using offering 1e1db335-c2e0-48b2-a288-9adf88a10adb
    Starting test_router_dns_externalips...
    Querying VR DNS IP: 192.168.20.18
    VR DNS query failed from non-guest network IP as expected
    === TestName: test_router_dns_externalipquery | Status : SUCCESS ===
    
    Starting test_router_dns_guestipquery...
    Creating Firewall rule for VM ID: b00b68b8-9445-4925-a631-f4bbd54bc6b9
    Creating NAT rule for VM ID: b00b68b8-9445-4925-a631-f4bbd54bc6b9
    SSH into guest VM with IP: 192.168.20.18
    ====Trying SSH Connection: Host:192.168.20.18 User:root                                   Port:22 RetryCnt:8===
    SshClient: Exception under createConnection: ['Traceback (most recent call last):\n', '  File "/usr/local/lib/python2.7/dist-packages/marvin/sshClient.py", line 122, in createConnection\n    allow_agent=False)\n', '  File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 324, in connect\n    raise NoValidConnectionsError(errors)\n', 'NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 192.168.20.18\n']
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/marvin/sshClient.py", line 122, in createConnection
        allow_agent=False)
      File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 324, in connect
        raise NoValidConnectionsError(errors)
    NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 192.168.20.18
    ====Trying SSH Connection: Host:192.168.20.18 User:root                                   Port:22 RetryCnt:7===
    SshClient: Exception under createConnection: ['Traceback (most recent call last):\n', '  File "/usr/local/lib/python2.7/dist-packages/marvin/sshClient.py", line 122, in createConnection\n    allow_agent=False)\n', '  File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 324, in connect\n    raise NoValidConnectionsError(errors)\n', 'NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 192.168.20.18\n']
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/marvin/sshClient.py", line 122, in createConnection
        allow_agent=False)
      File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 324, in connect
        raise NoValidConnectionsError(errors)
    NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 192.168.20.18
    ====Trying SSH Connection: Host:192.168.20.18 User:root                                   Port:22 RetryCnt:6===
    SshClient: Exception under createConnection: ['Traceback (most recent call last):\n', '  File "/usr/local/lib/python2.7/dist-packages/marvin/sshClient.py", line 122, in createConnection\n    allow_agent=False)\n', '  File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 324, in connect\n    raise NoValidConnectionsError(errors)\n', 'NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 192.168.20.18\n']
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/marvin/sshClient.py", line 122, in createConnection
        allow_agent=False)
      File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 324, in connect
        raise NoValidConnectionsError(errors)
    NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 192.168.20.18
    
    ====Trying SSH Connection: Host:192.168.20.18 User:root                                   Port:22 RetryCnt:5===
    ===SSH to Host 192.168.20.18 port : 22 SUCCESSFUL===
    {Cmd: nslookup google.com via Host: 192.168.20.18} {returns: [u'Server:\t\t10.1.1.1', u'Address:\t10.1.1.1#53', u'', u'Non-authoritative answer:', u'Name:\tgoogle.com', u'Address: 216.58.199.142', u'']}
    SSH nslookup result: [u'Server:\t\t10.1.1.1', u'Address:\t10.1.1.1#53', u'', u'Non-authoritative answer:', u'Name:\tgoogle.com', u'Address: 216.58.199.142', u'']
    === TestName: test_router_dns_guestipquery | Status : SUCCESS ===


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    Thanks @borisstoyanov 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by NuxRo <gi...@git.apache.org>.
Github user NuxRo commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    Thanks a lot for implementing this properly :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76560808
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    --- End diff --
    
    We know that public_ips should at least have length of 1, I can add a check to say `>= 1`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76560781
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +
    +        self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm.id)
    +        FireWallRule.create(
    +            self.apiclient,
    +            ipaddressid=public_ip.id,
    +            protocol=self.services["natrule1"]["protocol"],
    +            cidrlist=['0.0.0.0/0'],
    +            startport=self.services["natrule1"]["publicport"],
    +            endport=self.services["natrule1"]["publicport"]
    +        )
    +
    +        self.logger.debug("Creating NAT rule for VM ID: %s" % self.vm.id)
    +        nat_rule1 = NATRule.create(
    +            self.apiclient,
    +            self.vm,
    +            self.services["natrule1"],
    +            public_ip.id
    +        )
    +        nat_rules = list_nat_rules(
    +            self.apiclient,
    +            id=nat_rule1.id
    +        )
    +        self.assertEqual(
    +            isinstance(nat_rules, list),
    +            True,
    +            "Check for list NAT rules response return valid data"
    +        )
    +        self.assertEqual(
    +            nat_rules[0].state,
    +            'Active',
    +            "Check list port forwarding rules"
    +        )
    +
    +        result = None
    +        try:
    +            self.logger.debug("SSH into guest VM with IP: %s" % nat_rule1.ipaddress)
    +            ssh = self.vm.get_ssh_client(ipaddress=nat_rule1.ipaddress, port=self.services['natrule1']["publicport"], retries=8)
    +            result = str(ssh.execute("nslookup google.com"))
    +        except Exception as e:
    +            self.fail("Failed to SSH into VM - %s due to exception: %s" % (nat_rule1.ipaddress, e))
    +
    +        self.assertTrue(result is not None and "google.com" in result and "#53" in result,
    --- End diff --
    
    Fixed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: CLOUDSTACK-6432: Prevent DNS reflection attac...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd closed the pull request at:

    https://github.com/apache/cloudstack/pull/1663


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76561273
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    +        """Checks that guest VM can query VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_guestipquery...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +
    +        self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm.id)
    +        FireWallRule.create(
    +            self.apiclient,
    +            ipaddressid=public_ip.id,
    +            protocol=self.services["natrule1"]["protocol"],
    +            cidrlist=['0.0.0.0/0'],
    +            startport=self.services["natrule1"]["publicport"],
    +            endport=self.services["natrule1"]["publicport"]
    +        )
    --- End diff --
    
    We'll need to do a list call to verify, but that's not necessary because if there is an issue with fw-rules, SSH into VM will fail.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack issue #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS reflectio...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on the issue:

    https://github.com/apache/cloudstack/pull/1663
  
    @jburwell @NuxRo  thanks for the reviews, I've fixed the outstanding issues. Please re-review.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] cloudstack pull request #1663: [LTS/blocker] CLOUDSTACK-6432: Prevent DNS re...

Posted by rhtyd <gi...@git.apache.org>.
Github user rhtyd commented on a diff in the pull request:

    https://github.com/apache/cloudstack/pull/1663#discussion_r76561300
  
    --- Diff: test/integration/smoke/test_router_dns.py ---
    @@ -0,0 +1,286 @@
    +# 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.
    +
    +import logging
    +import dns.resolver
    +
    +from nose.plugins.attrib import attr
    +from marvin.cloudstackTestCase import cloudstackTestCase
    +from marvin.lib.utils import cleanup_resources
    +from marvin.lib.base import (ServiceOffering,
    +                             VirtualMachine,
    +                             Account,
    +                             NATRule,
    +                             FireWallRule,
    +                             NetworkOffering,
    +                             Network)
    +from marvin.lib.common import (get_zone,
    +                               get_template,
    +                               get_domain,
    +                               list_routers,
    +                               list_nat_rules,
    +                               list_publicIP)
    +
    +
    +class TestRouterDns(cloudstackTestCase):
    +
    +    @classmethod
    +    def setUpClass(cls):
    +        cls.logger = logging.getLogger('TestRouterDns')
    +        cls.stream_handler = logging.StreamHandler()
    +        cls.logger.setLevel(logging.DEBUG)
    +        cls.logger.addHandler(cls.stream_handler)
    +
    +        cls.testClient = super(TestRouterDns, cls).getClsTestClient()
    +        cls.api_client = cls.testClient.getApiClient()
    +        cls.services = cls.testClient.getParsedTestDataConfig()
    +
    +        cls.domain = get_domain(cls.api_client)
    +        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
    +        cls.services['mode'] = cls.zone.networktype
    +        cls.template = get_template(
    +            cls.api_client,
    +            cls.zone.id,
    +            cls.services["ostype"]
    +        )
    +        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
    +
    +        cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
    +        cls.account = Account.create(
    +            cls.api_client,
    +            cls.services["account"],
    +            admin=True,
    +            domainid=cls.domain.id
    +        )
    +
    +        cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id))
    +        cls.service_offering = ServiceOffering.create(
    +            cls.api_client,
    +            cls.services["service_offering"]
    +        )
    +
    +        cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id))
    +        cls.services["isolated_network_offering"]["egress_policy"] = "true"
    +        cls.network_offering = NetworkOffering.create(cls.api_client,
    +                                                       cls.services["isolated_network_offering"],
    +                                                       conservemode=True)
    +        cls.network_offering.update(cls.api_client, state='Enabled')
    +
    +        cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id))
    +        cls.network = Network.create(cls.api_client,
    +                                      cls.services["network"],
    +                                      accountid=cls.account.name,
    +                                      domainid=cls.account.domainid,
    +                                      networkofferingid=cls.network_offering.id,
    +                                      zoneid=cls.zone.id)
    +
    +        cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id))
    +        cls.vm = VirtualMachine.create(cls.api_client,
    +                                         cls.services["virtual_machine"],
    +                                         templateid=cls.template.id,
    +                                         accountid=cls.account.name,
    +                                         domainid=cls.domain.id,
    +                                         serviceofferingid=cls.service_offering.id,
    +                                         networkids=[str(cls.network.id)])
    +        cls.vm.password = "password"
    +
    +        cls.services["natrule1"] = {
    +            "privateport": 22,
    +            "publicport": 22,
    +            "protocol": "TCP"
    +        }
    +
    +        cls.services["configurableData"] = {
    +            "host": {
    +                "password": "password",
    +                "username": "root",
    +                "port": 22
    +            },
    +            "input": "INPUT",
    +            "forward": "FORWARD"
    +        }
    +
    +        cls._cleanup = [
    +            cls.vm,
    +            cls.network,
    +            cls.network_offering,
    +            cls.service_offering,
    +            cls.account
    +        ]
    +
    +    @classmethod
    +    def tearDownClass(cls):
    +        try:
    +            cleanup_resources(cls.api_client, cls._cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +    def setUp(self):
    +        self.apiclient = self.testClient.getApiClient()
    +        self.cleanup = []
    +
    +    def tearDown(self):
    +        try:
    +            cleanup_resources(self.apiclient, self.cleanup)
    +        except Exception as e:
    +            raise Exception("Warning: Exception during cleanup : %s" % e)
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_externalipquery(self):
    +        """Checks that non-guest network IPs cannot access VR DNS"""
    +
    +        self.logger.debug("Starting test_router_dns_externalips...")
    +        routers = list_routers(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid
    +        )
    +
    +        self.assertEqual(
    +            isinstance(routers, list),
    +            True,
    +            "Check for list routers response return valid data"
    +        )
    +
    +        self.assertNotEqual(
    +            len(routers),
    +            0,
    +            "Check list router response"
    +        )
    +
    +        router = routers[0]
    +
    +        self.assertEqual(
    +            router.state,
    +            'Running',
    +            "Check list router response for router state"
    +        )
    +
    +        public_ips = list_publicIP(
    +            self.apiclient,
    +            account=self.account.name,
    +            domainid=self.account.domainid,
    +            zoneid=self.zone.id
    +        )
    +
    +        self.assertEqual(
    +            isinstance(public_ips, list),
    +            True,
    +            "Check for list public IPs response return valid data"
    +        )
    +
    +        public_ip = public_ips[0]
    +        self.logger.debug("Querying VR DNS IP: " + public_ip.ipaddress)
    +        resolver = dns.resolver.Resolver()
    +        resolver.namerservers = [public_ip.ipaddress]
    +        try:
    +            resolver.query('google.com', 'A')
    +            self.fail("Non-guest network IPs are able to access VR DNS, failing.")
    +        except:
    +            self.logger.debug("VR DNS query failed from non-guest network IP as expected")
    +
    +
    +    @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
    +    def test_router_dns_guestipquery(self):
    --- End diff --
    
    Refactored common tests code.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---