Esempio n. 1
0
 def _validate_policy_lifetime(self, policy_info, policy_type):
     """NSX supports only units=seconds"""
     lifetime = policy_info.get('lifetime')
     if not lifetime:
         return
     if lifetime.get('units') != 'seconds':
         msg = _("Unsupported policy lifetime %(val)s in %(pol)s policy. "
                 "Only seconds lifetime is supported.") % {
                     'val': lifetime,
                     'pol': policy_type
                 }
         raise nsx_exc.NsxVpnValidationError(details=msg)
     value = lifetime.get('value')
     if policy_type == 'IKE':
         limits = vpn_ipsec.IkeSALifetimeLimits
     else:
         limits = vpn_ipsec.IPsecSALifetimeLimits
     if (value and (value < limits.SA_LIFETIME_MIN
                    or value > limits.SA_LIFETIME_MAX)):
         msg = _("Unsupported policy lifetime %(value)s in %(pol)s policy. "
                 "Value range is [%(min)s-%(max)s].") % {
                     'value': value,
                     'pol': policy_type,
                     'min': limits.SA_LIFETIME_MIN,
                     'max': limits.SA_LIFETIME_MAX
                 }
         raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 2
0
    def _check_advertisment_overlap(self, context, ipsec_site_conn):
        """Validate there is no overlapping advertisement of networks

        The plugin advertise all no-snat routers networks + vpn local
        networks.
        The NSX does not allow different Tier1 router to advertise the
        same subnets
        """
        admin_con = context.elevated()
        srv_id = ipsec_site_conn.get('vpnservice_id')
        srv = self.vpn_plugin._get_vpnservice(admin_con, srv_id)
        this_router = srv['router_id']
        this_cidr = srv['subnet']['cidr']

        # get all subnets of no-snat routers
        all_routers = self._core_plugin.get_routers(admin_con)
        nosnat_routers = [
            rtr for rtr in all_routers
            if (rtr['id'] != this_router and rtr.get('external_gateway_info')
                and not rtr['external_gateway_info'].get(
                    'enable_snat', cfg.CONF.enable_snat_by_default))
        ]
        for rtr in nosnat_routers:
            if rtr['id'] == this_router:
                continue
            # go over the subnets of this router
            subnets = self._core_plugin._find_router_subnets_cidrs(
                admin_con, rtr['id'])
            if subnets and netaddr.IPSet(subnets) & netaddr.IPSet([this_cidr]):
                msg = (_("Cannot create connection with overlapping local "
                         "cidrs %(local)s which was already advertised by "
                         "no-snat router %(rtr)s") % {
                             'local': subnets,
                             'rtr': rtr['id']
                         })
                raise nsx_exc.NsxVpnValidationError(details=msg)

        # add all vpn local subnets
        connections = self.vpn_plugin.get_ipsec_site_connections(admin_con)
        for conn in connections:
            # skip this connection and connections in non active state
            if (conn['id'] == ipsec_site_conn.get('id')
                    or conn['status'] != constants.ACTIVE):
                continue
            # check the service local address
            conn_srv_id = conn.get('vpnservice_id')
            conn_srv = self.vpn_plugin._get_vpnservice(admin_con, conn_srv_id)
            if conn_srv['router_id'] == this_router:
                continue
            conn_cidr = conn_srv['subnet']['cidr']
            if netaddr.IPSet([conn_cidr]) & netaddr.IPSet([this_cidr]):
                msg = (_("Cannot create connection with overlapping local "
                         "cidr %(local)s which was already advertised by "
                         "router %(rtr)s and connection %(conn)s") % {
                             'local': conn_cidr,
                             'rtr': conn_srv['router_id'],
                             'conn': conn['id']
                         })
                raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 3
0
    def _check_unique_addresses(self, context, ipsec_site_conn):
        """Validate no repeating local & peer addresses (of all tenants)

        The nsx does not support it cross all tenants, and tier0 routers
        """
        vpnservice_id = ipsec_site_conn.get('vpnservice_id')
        local_addr = self._get_service_local_address(context, vpnservice_id)
        peer_address = ipsec_site_conn.get('peer_address')
        filters = {'peer_address': [peer_address]}
        connections = self.vpn_plugin.get_ipsec_site_connections(
            context.elevated(), filters=filters)
        for conn in connections:
            # skip this connection and connections in non active state
            if (conn['id'] == ipsec_site_conn.get('id')
                    or conn['status'] != constants.ACTIVE):
                continue
            # this connection has the same peer addr as ours.
            # check the service local address
            srv_id = conn.get('vpnservice_id')
            srv_local = self._get_service_local_address(
                context.elevated(), srv_id)
            if srv_local == local_addr:
                msg = (_("Cannot create another connection with the same "
                         "local address %(local)s and peer address %(peer)s "
                         "as connection %(id)s") % {
                             'local': local_addr,
                             'peer': peer_address,
                             'id': conn['id']
                         })
                raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 4
0
 def _validate_router(self, context, router_id):
     # Only support distributed and exclusive router type
     router = self.core_plugin.get_router(context, router_id)
     if self._is_shared_router(router):
         msg = _("Router type is not supported for VPN service, only "
                 "support distributed and exclusive router")
         raise nsxv_exc.NsxVpnValidationError(details=msg)
Esempio n. 5
0
 def validate_ipsec_policy(self, context, policy_info):
     """Ensure IPSec policy encap mode is tunnel for current REST API."""
     mode = policy_info['encapsulation_mode']
     if mode not in nsxv_constants.ENCAPSULATION_MODE_ALLOWED:
         msg = _("Unsupported encapsulation mode: %s! currently only"
                 "'tunnel' mode is supported.") % mode
         raise nsxv_exc.NsxVpnValidationError(details=msg)
Esempio n. 6
0
 def validate_ikepolicy_version(self, policy_info):
     """NSX Edge provides IKEv1"""
     version = policy_info.get('ike_version')
     if version != 'v1':
         msg = _("Unsupported ike policy %s! only v1 "
                 "is supported right now.") % version
         raise nsxv_exc.NsxVpnValidationError(details=msg)
Esempio n. 7
0
 def validate_ikepolicy_pfs(self, policy_info):
     # Check whether pfs is allowed.
     if not nsxv_constants.PFS_MAP.get(policy_info['pfs']):
         msg = _("Unsupported pfs: %(pfs)s! currently only "
                 "the following pfs are supported on VSE: %s") % {
                     'pfs': policy_info['pfs'],
                     'supported': nsxv_constants.PFS_MAP
                 }
         raise nsxv_exc.NsxVpnValidationError(details=msg)
Esempio n. 8
0
    def _validate_router(self, context, router_id):
        # Verify that the router gw network is connected to an active-standby
        # Tier0 router
        router_db = self._core_plugin._get_router(context, router_id)
        tier0_uuid = self._core_plugin._get_tier0_uuid_by_router(
            context, router_db)
        # TODO(asarfaty): cache this result
        tier0_router = self.nsxlib.logical_router.get(tier0_uuid)
        if (not tier0_router or tier0_router.get('high_availability_mode') !=
                'ACTIVE_STANDBY'):
            msg = _("The router GW should be connected to a TIER-0 router "
                    "with ACTIVE_STANDBY HA mode")
            raise nsx_exc.NsxVpnValidationError(details=msg)

        # Verify that this is a no-snat router
        if router_db.enable_snat:
            msg = _("VPN is supported only for routers with disabled SNAT")
            raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 9
0
 def validate_encryption_algorithm(self, policy_info):
     encryption = policy_info['encryption_algorithm']
     if encryption not in nsxv_constants.ENCRYPTION_ALGORITHM_MAP:
         msg = _("Unsupported encryption_algorithm: %(algo)s! please "
                 "select one of the following supported algorithms: "
                 "%(supported_algos)s") % {
                     'algo': encryption,
                     'supported_algos':
                     nsxv_constants.ENCRYPTION_ALGORITHM_MAP
                 }
         raise nsxv_exc.NsxVpnValidationError(details=msg)
Esempio n. 10
0
 def _validate_policy_pfs(self, policy_info, policy_type):
     pfs = policy_info.get('pfs')
     if pfs and pfs not in ipsec_utils.PFS_MAP:
         msg = _("Unsupported pfs: %(pfs)s in %(pol)s policy. Please "
                 "select one of the following pfs: "
                 "%(supported_pfs)s") % {
                     'pfs': pfs,
                     'pol': policy_type,
                     'supported_pfs': ipsec_utils.PFS_MAP.keys()
                 }
         raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 11
0
 def _validate_policy_auth_algorithm(self, policy_info, policy_type):
     """NSX supports only SHA1 and SHA256"""
     auth = policy_info.get('auth_algorithm')
     if auth and auth not in ipsec_utils.AUTH_ALGORITHM_MAP:
         msg = _("Unsupported auth_algorithm: %(algo)s in %(pol)s policy. "
                 "Please select one of the following supported algorithms: "
                 "%(supported_algos)s") % {
                     'pol': policy_type,
                     'algo': auth,
                     'supported_algos':
                     ipsec_utils.AUTH_ALGORITHM_MAP.keys()
                 }
         raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 12
0
 def _validate_policy_encryption_algorithm(self, policy_info, policy_type):
     encryption = policy_info.get('encryption_algorithm')
     if (encryption
             and encryption not in ipsec_utils.ENCRYPTION_ALGORITHM_MAP):
         msg = _("Unsupported encryption_algorithm: %(algo)s in %(pol)s "
                 "policy. Please select one of the following supported "
                 "algorithms: %(supported_algos)s") % {
                     'algo': encryption,
                     'pol': policy_type,
                     'supported_algos':
                     ipsec_utils.ENCRYPTION_ALGORITHM_MAP.keys()
                 }
         raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 13
0
 def _validate_dpd(self, connection):
     dpd_info = connection.get('dpd')
     if not dpd_info:
         return
     action = dpd_info.get('action')
     if action not in ipsec_utils.DPD_ACTION_MAP.keys():
         msg = _("Unsupported DPD action: %(action)s! Currently only "
                 "%(supported)s is supported.") % {
                     'action': action,
                     'supported': ipsec_utils.DPD_ACTION_MAP.keys()
                 }
         raise nsx_exc.NsxVpnValidationError(details=msg)
     timeout = dpd_info.get('timeout')
     if (timeout < vpn_ipsec.DpdProfileTimeoutLimits.DPD_TIMEOUT_MIN or
             timeout > vpn_ipsec.DpdProfileTimeoutLimits.DPD_TIMEOUT_MAX):
         msg = _(
             "Unsupported DPD timeout: %(timeout)s. Value range is "
             "[%(min)s-%(max)s].") % {
                 'timeout': timeout,
                 'min': vpn_ipsec.DpdProfileTimeoutLimits.DPD_TIMEOUT_MIN,
                 'max': vpn_ipsec.DpdProfileTimeoutLimits.DPD_TIMEOUT_MAX
             }
         raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 14
0
    def validate_vpnservice(self, context, vpnservice):
        """Called upon create/update of a service"""

        # Call general validations
        super(IPsecValidator, self).validate_vpnservice(context, vpnservice)

        # Call specific NSX validations
        self._validate_router(context, vpnservice['router_id'])

        if not vpnservice['subnet_id']:
            # we currently do not support multiple subnets so a subnet must
            # be defined
            msg = _("Subnet must be defined in a service")
            raise nsxv_exc.NsxVpnValidationError(details=msg)
Esempio n. 15
0
    def validate_ike_policy(self, context, ike_policy):
        # Call general validations
        super(IPsecV3Validator, self).validate_ike_policy(context, ike_policy)

        # Call specific NSX validations
        self._validate_policy_lifetime(ike_policy, "IKE")
        self._validate_policy_auth_algorithm(ike_policy, "IKE")
        self._validate_policy_encryption_algorithm(ike_policy, "IKE")
        self._validate_policy_pfs(ike_policy, "IKE")

        # 'aggressive' phase1-negotiation-mode is not supported
        if ike_policy.get('phase1-negotiation-mode', 'main') != 'main':
            msg = _("Unsupported phase1-negotiation-mode: %s! Only 'main' is "
                    "supported.") % ike_policy['phase1-negotiation-mode']
            raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 16
0
    def validate_ipsec_policy(self, context, ipsec_policy):
        # Call general validations
        super(IPsecV3Validator,
              self).validate_ipsec_policy(context, ipsec_policy)

        # Call specific NSX validations
        self._validate_policy_lifetime(ipsec_policy, "IPSec")
        self._validate_policy_auth_algorithm(ipsec_policy, "IPSec")
        self._validate_policy_encryption_algorithm(ipsec_policy, "IPSec")
        self._validate_policy_pfs(ipsec_policy, "IPSec")

        # Ensure IPSec policy encap mode is tunnel
        mode = ipsec_policy.get('encapsulation_mode')
        if mode and mode not in ipsec_utils.ENCAPSULATION_MODE_MAP.keys():
            msg = _("Unsupported encapsulation mode: %s. Only 'tunnel' mode "
                    "is supported.") % mode
            raise nsx_exc.NsxVpnValidationError(details=msg)

        # Ensure IPSec policy transform protocol is esp
        prot = ipsec_policy.get('transform_protocol')
        if prot and prot not in ipsec_utils.TRANSFORM_PROTOCOL_MAP.keys():
            msg = _("Unsupported transform protocol: %s. Only 'esp' protocol "
                    "is supported.") % prot
            raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 17
0
    def validate_ipsec_site_connection(self, context, ipsec_site_conn):
        if not ipsec_site_conn.get('tenant_id'):
            # nothing we can do here.
            return

        v = self._get_validator_for_project(ipsec_site_conn['tenant_id'])

        # first make sure the plugin is the same as the one of the vpnservice
        srv_id = ipsec_site_conn.get('vpnservice_id')
        srv = self.vpn_plugin._get_vpnservice(context, srv_id)
        srv_validator = self._get_validator_for_project(srv['tenant_id'])
        if v != srv_validator:
            err_msg = _('VPN service should belong to the same plugin '
                        'as the connection')
            raise nsx_exc.NsxVpnValidationError(details=err_msg)

        return v.validate_ipsec_site_connection(context, ipsec_site_conn)
Esempio n. 18
0
    def validate_vpnservice(self, context, vpnservice):
        if not vpnservice.get('tenant_id'):
            # This will happen during update.
            # nothing significant like router or subnet can be changes
            # so we can skip it.
            return

        v = self._get_validator_for_project(vpnservice['tenant_id'])

        # first make sure the router&subnet plugin matches the vpnservice
        router_id = vpnservice['router_id']
        p = self.core_plugin._get_plugin_from_router_id(context, router_id)
        if self.validators.get(p.plugin_type()) != v:
            err_msg = _('Router & subnet should belong to the same plugin '
                        'as the VPN service')
            raise nsx_exc.NsxVpnValidationError(details=err_msg)
        return v.validate_vpnservice(context, vpnservice)
Esempio n. 19
0
    def _check_policy_rules_overlap(self, context, ipsec_site_conn):
        """validate no overlapping policy rules

        The nsx does not support overlapping policy rules cross
        all tenants, and tier0 routers
        """
        connections = self.vpn_plugin.get_ipsec_site_connections(
            context.elevated())
        if not connections:
            return
        vpnservice_id = ipsec_site_conn.get('vpnservice_id')
        vpnservice = self.vpn_plugin._get_vpnservice(context, vpnservice_id)
        local_cidrs = [vpnservice['subnet']['cidr']]
        peer_cidrs = ipsec_site_conn['peer_cidrs']
        for conn in connections:
            # skip this connection and connections in non active state
            if (conn['id'] == ipsec_site_conn.get('id')
                    or conn['status'] != constants.ACTIVE):
                continue
            # TODO(asarfaty): support peer groups too
            # check if it overlaps with the peer cidrs
            conn_peer_cidrs = conn['peer_cidrs']
            if netaddr.IPSet(conn_peer_cidrs) & netaddr.IPSet(peer_cidrs):
                # check if the local cidr also overlaps
                con_service_id = conn.get('vpnservice_id')
                con_service = self.vpn_plugin._get_vpnservice(
                    context.elevated(), con_service_id)
                conn_local_cidr = [con_service['subnet']['cidr']]
                if netaddr.IPSet(conn_local_cidr) & netaddr.IPSet(local_cidrs):
                    msg = (_("Cannot create a connection with overlapping "
                             "local and peer cidrs (%(local)s and %(peer)s) "
                             "as connection %(id)s") % {
                                 'local': local_cidrs,
                                 'peer': peer_cidrs,
                                 'id': conn['id']
                             })
                    raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 20
0
 def _validate_psk(self, connection):
     if 'psk' in connection and not connection['psk']:
         msg = _("'psk' cannot be empty or null when authentication "
                 "mode is psk")
         raise nsx_exc.NsxVpnValidationError(details=msg)
Esempio n. 21
0
 def _validate_backend_version(self):
     if not self.backend_support:
         msg = (_("VPNaaS is not supported by the NSX backend "
                  "(version %s)") % self.nsxlib.get_version())
         raise nsx_exc.NsxVpnValidationError(details=msg)