[ https://issues.apache.org/jira/browse/CLOUDSTACK-6432?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15444548#comment-15444548 ]
ASF GitHub Bot commented on CLOUDSTACK-6432: -------------------------------------------- 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? > Prevent VR from response to DNS request from outside of network > --------------------------------------------------------------- > > Key: CLOUDSTACK-6432 > URL: https://issues.apache.org/jira/browse/CLOUDSTACK-6432 > Project: CloudStack > Issue Type: Bug > Security Level: Public(Anyone can view this level - this is the > default.) > Affects Versions: 4.4.0, 4.5.0 > Reporter: Sheng Yang > Assignee: Sheng Yang > Fix For: 4.4.0, 4.5.0 > > > In basic and shared network, VR use private network nic for dhcp/dns > services. But if private network is on the internet as well, it would make VR > facing outside network. > We would restrain the VR DNS service inside CloudStack managed network. -- This message was sent by Atlassian JIRA (v6.3.4#6332)