Beispiel #1
0
def verify(dummy):
    if dummy['deleted']:
        interface = dummy['intf']
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None

    vrf_name = dummy['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    return None
Beispiel #2
0
def verify(geneve):
    if geneve['deleted']:
        interface = geneve['intf']
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None

    if not geneve['remote']:
        raise ConfigError('GENEVE remote must be configured')

    if not geneve['vni']:
        raise ConfigError('GENEVE VNI must be configured')

    return None
def verify(vxlan):
    if vxlan['deleted']:
        interface = vxlan['intf']
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None

    if vxlan['mtu'] < 1500:
        print(
            'WARNING: RFC7348 recommends VXLAN tunnels preserve a 1500 byte MTU'
        )

    if vxlan['group']:
        if not vxlan['source_interface']:
            raise ConfigError(
                'Multicast VXLAN requires an underlaying interface ')

        if not vxlan['source_interface'] in interfaces():
            raise ConfigError('VXLAN source interface does not exist')

    if not (vxlan['group'] or vxlan['remote'] or vxlan['source_address']):
        raise ConfigError('Group, remote or source-address must be configured')

    if not vxlan['vni']:
        raise ConfigError('Must configure VNI for VXLAN')

    if vxlan['source_interface']:
        # VXLAN adds a 50 byte overhead - we need to check the underlaying MTU
        # if our configured MTU is at least 50 bytes less
        underlay_mtu = int(Interface(vxlan['source_interface']).get_mtu())
        if underlay_mtu < (vxlan['mtu'] + 50):
            raise ConfigError('VXLAN has a 50 byte overhead, underlaying device ' \
                              'MTU is to small ({})'.format(underlay_mtu))

    return None
def verify(l2tpv3):
    interface = l2tpv3['intf']

    if l2tpv3['deleted']:
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None

    if not l2tpv3['local_address']:
        raise ConfigError(
            f'Must configure the l2tpv3 local-ip for {interface}')

    if not l2tpv3['remote_address']:
        raise ConfigError(
            f'Must configure the l2tpv3 remote-ip for {interface}')

    if not l2tpv3['tunnel_id']:
        raise ConfigError(
            f'Must configure the l2tpv3 tunnel-id for {interface}')

    if not l2tpv3['peer_tunnel_id']:
        raise ConfigError(
            f'Must configure the l2tpv3 peer-tunnel-id for {interface}')

    if not l2tpv3['session_id']:
        raise ConfigError(
            f'Must configure the l2tpv3 session-id for {interface}')

    if not l2tpv3['peer_session_id']:
        raise ConfigError(
            f'Must configure the l2tpv3 peer-session-id for {interface}')

    return None
def verify(peth):
    if peth['deleted']:
        interface = peth['intf']
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None

    if not peth['source_interface']:
        raise ConfigError('Link device must be set for virtual ethernet {}'.format(peth['intf']))

    if not peth['source_interface'] in interfaces():
        raise ConfigError('Pseudo-ethernet source interface does not exist')

    vrf_name = peth['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    # use common function to verify VLAN configuration
    verify_vlan_config(peth)
    return None
Beispiel #6
0
def verify(wg):
    interface = wg['intf']

    if wg['deleted']:
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None

    vrf_name = wg['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    if not os.path.exists(wg['pk']):
        raise ConfigError('No keys found, generate them by executing:\n' \
                          '"run generate wireguard [keypair|named-keypairs]"')

    if not wg['address']:
        raise ConfigError(f'IP address required for interface "{interface}"!')

    if not wg['peer']:
        raise ConfigError(f'Peer required for interface "{interface}"!')

    # run checks on individual configured WireGuard peer
    for peer in wg['peer']:
        peer_name = peer['name']
        if not peer['allowed-ips']:
            raise ConfigError(
                f'Peer allowed-ips required for peer "{peer_name}"!')

        if not peer['pubkey']:
            raise ConfigError(
                f'Peer public-key required for peer "{peer_name}"!')
def verify(openvpn):
    if openvpn['deleted']:
        interface = openvpn['intf']
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None

    if not openvpn['mode']:
        raise ConfigError('Must specify OpenVPN operation mode')

    # Checks which need to be performed on interface rmeoval
    if openvpn['deleted']:
        # OpenVPN interface can not be deleted if it's still member of a bridge
        if openvpn['bridge_member']:
            raise ConfigError(
                'Can not delete {} as it is a member interface of bridge {}!'.
                format(openvpn['intf'], bridge))

    # Check if we have disabled ncp and at the same time specified ncp-ciphers
    if openvpn['disable_ncp'] and openvpn['ncp_ciphers']:
        raise ConfigError(
            'Cannot specify both "encryption disable-ncp" and "encryption ncp-ciphers"'
        )
    #
    # OpenVPN client mode - VERIFY
    #
    if openvpn['mode'] == 'client':
        if openvpn['local_port']:
            raise ConfigError('Cannot specify "local-port" in client mode')

        if openvpn['local_host']:
            raise ConfigError('Cannot specify "local-host" in client mode')

        if openvpn['protocol'] == 'tcp-passive':
            raise ConfigError(
                'Protocol "tcp-passive" is not valid in client mode')

        if not openvpn['remote_host']:
            raise ConfigError('Must specify "remote-host" in client mode')

        if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none':
            raise ConfigError('Cannot specify "tls dh-file" in client mode')

    #
    # OpenVPN site-to-site - VERIFY
    #
    if openvpn['mode'] == 'site-to-site':
        if openvpn['ncp_ciphers']:
            raise ConfigError(
                'encryption ncp-ciphers cannot be specified in site-to-site mode, only server or client'
            )

    if openvpn['mode'] == 'site-to-site' and not openvpn['bridge_member']:
        if not openvpn['local_address']:
            raise ConfigError(
                'Must specify "local-address" or "bridge member interface"')

        for host in openvpn['remote_host']:
            if host == openvpn['remote_address']:
                raise ConfigError(
                    '"remote-address" cannot be the same as "remote-host"')

        if openvpn['type'] == 'tun':
            if not openvpn['remote_address']:
                raise ConfigError('Must specify "remote-address"')

            if openvpn['local_address'] == openvpn['remote_address']:
                raise ConfigError(
                    '"local-address" and "remote-address" cannot be the same')

            if openvpn['local_address'] == openvpn['local_host']:
                raise ConfigError(
                    '"local-address" cannot be the same as "local-host"')

    else:
        # checks for client-server or site-to-site bridged
        if openvpn['local_address'] or openvpn['remote_address']:
            raise ConfigError(
                'Cannot specify "local-address" or "remote-address" in client-server or bridge mode'
            )

    #
    # OpenVPN server mode - VERIFY
    #
    if openvpn['mode'] == 'server':
        if openvpn['protocol'] == 'tcp-active':
            raise ConfigError(
                'Protocol "tcp-active" is not valid in server mode')

        if openvpn['remote_port']:
            raise ConfigError('Cannot specify "remote-port" in server mode')

        if openvpn['remote_host']:
            raise ConfigError('Cannot specify "remote-host" in server mode')

        if openvpn['protocol'] == 'tcp-passive' and len(
                openvpn['remote_host']) > 1:
            raise ConfigError(
                'Cannot specify more than 1 "remote-host" with "tcp-passive"')

        if not openvpn['tls_dh'] and not checkCertHeader(
                '-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']):
            raise ConfigError(
                'Must specify "tls dh-file" when not using EC keys in server mode'
            )

        if not openvpn['server_subnet']:
            if not openvpn['bridge_member']:
                raise ConfigError(
                    'Must specify "server subnet" or "bridge member interface" in server mode'
                )

    else:
        # checks for both client and site-to-site go here
        if openvpn['server_reject_unconfigured']:
            raise ConfigError(
                'reject-unconfigured-clients is only supported in OpenVPN server mode'
            )

        if openvpn['server_topology']:
            raise ConfigError(
                'The "topology" option is only valid in server mode')

        if (not openvpn['remote_host']) and openvpn['redirect_gateway']:
            raise ConfigError(
                'Cannot set "replace-default-route" without "remote-host"')

    #
    # OpenVPN common verification section
    # not depending on any operation mode
    #

    # verify specified IP address is present on any interface on this system
    if openvpn['local_host']:
        if not is_addr_assigned(openvpn['local_host']):
            raise ConfigError(
                'No interface on system with specified local-host IP address: {}'
                .format(openvpn['local_host']))

    # TCP active
    if openvpn['protocol'] == 'tcp-active':
        if openvpn['local_port']:
            raise ConfigError('Cannot specify "local-port" with "tcp-active"')

        if not openvpn['remote_host']:
            raise ConfigError('Must specify "remote-host" with "tcp-active"')

    # shared secret and TLS
    if not (openvpn['shared_secret_file'] or openvpn['tls']):
        raise ConfigError(
            'Must specify one of "shared-secret-key-file" and "tls"')

    if openvpn['shared_secret_file'] and openvpn['tls']:
        raise ConfigError(
            'Can only specify one of "shared-secret-key-file" and "tls"')

    if openvpn['mode'] in ['client', 'server']:
        if not openvpn['tls']:
            raise ConfigError('Must specify "tls" in client-server mode')

    #
    # TLS/encryption
    #
    if openvpn['shared_secret_file']:
        if openvpn['encryption'] in ['aes128gcm', 'aes192gcm', 'aes256gcm']:
            raise ConfigError(
                'GCM encryption with shared-secret-key-file is not supported')

        if not checkCertHeader('-----BEGIN OpenVPN Static key V1-----',
                               openvpn['shared_secret_file']):
            raise ConfigError(
                'Specified shared-secret-key-file "{}" is not valid'.format(
                    openvpn['shared_secret_file']))

    if openvpn['tls']:
        if not openvpn['tls_ca_cert']:
            raise ConfigError('Must specify "tls ca-cert-file"')

        if not (openvpn['mode'] == 'client' and openvpn['auth']):
            if not openvpn['tls_cert']:
                raise ConfigError('Must specify "tls cert-file"')

            if not openvpn['tls_key']:
                raise ConfigError('Must specify "tls key-file"')

        if openvpn['tls_auth'] and openvpn['tls_crypt']:
            raise ConfigError('TLS auth and crypt are mutually exclusive')

        if not checkCertHeader('-----BEGIN CERTIFICATE-----',
                               openvpn['tls_ca_cert']):
            raise ConfigError('Specified ca-cert-file "{}" is invalid'.format(
                openvpn['tls_ca_cert']))

        if openvpn['tls_auth']:
            if not checkCertHeader('-----BEGIN OpenVPN Static key V1-----',
                                   openvpn['tls_auth']):
                raise ConfigError('Specified auth-file "{}" is invalid'.format(
                    openvpn['tls_auth']))

        if openvpn['tls_cert']:
            if not checkCertHeader('-----BEGIN CERTIFICATE-----',
                                   openvpn['tls_cert']):
                raise ConfigError('Specified cert-file "{}" is invalid'.format(
                    openvpn['tls_cert']))

        if openvpn['tls_key']:
            if not checkCertHeader('-----BEGIN (?:RSA |EC )?PRIVATE KEY-----',
                                   openvpn['tls_key']):
                raise ConfigError(
                    'Specified key-file "{}" is not valid'.format(
                        openvpn['tls_key']))

        if openvpn['tls_crypt']:
            if not checkCertHeader('-----BEGIN OpenVPN Static key V1-----',
                                   openvpn['tls_crypt']):
                raise ConfigError(
                    'Specified TLS crypt-file "{}" is invalid'.format(
                        openvpn['tls_crypt']))

        if openvpn['tls_crl']:
            if not checkCertHeader('-----BEGIN X509 CRL-----',
                                   openvpn['tls_crl']):
                raise ConfigError('Specified crl-file "{} not valid'.format(
                    openvpn['tls_crl']))

        if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none':
            if not checkCertHeader('-----BEGIN DH PARAMETERS-----',
                                   openvpn['tls_dh']):
                raise ConfigError('Specified dh-file "{}" is not valid'.format(
                    openvpn['tls_dh']))

        if openvpn['tls_role']:
            if openvpn['mode'] in ['client', 'server']:
                if not openvpn['tls_auth']:
                    raise ConfigError(
                        'Cannot specify "tls role" in client-server mode')

            if openvpn['tls_role'] == 'active':
                if openvpn['protocol'] == 'tcp-passive':
                    raise ConfigError(
                        'Cannot specify "tcp-passive" when "tls role" is "active"'
                    )

                if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none':
                    raise ConfigError(
                        'Cannot specify "tls dh-file" when "tls role" is "active"'
                    )

            elif openvpn['tls_role'] == 'passive':
                if openvpn['protocol'] == 'tcp-active':
                    raise ConfigError(
                        'Cannot specify "tcp-active" when "tls role" is "passive"'
                    )

                if not openvpn['tls_dh']:
                    raise ConfigError(
                        'Must specify "tls dh-file" when "tls role" is "passive"'
                    )

        if openvpn['tls_key'] and checkCertHeader(
                '-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']):
            if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none':
                print(
                    'Warning: using dh-file and EC keys simultaneously will lead to DH ciphers being used instead of ECDH'
                )
            else:
                print(
                    'Diffie-Hellman prime file is unspecified, assuming ECDH')

    #
    # Auth user/pass
    #
    if openvpn['auth']:
        if not openvpn['auth_user']:
            raise ConfigError('Username for authentication is missing')

        if not openvpn['auth_pass']:
            raise ConfigError('Password for authentication is missing')

    #
    # Client
    #
    subnet = openvpn['server_subnet'].replace(' ', '/')
    for client in openvpn['client']:
        if client['ip'] and not ip_address(client['ip']) in ip_network(subnet):
            raise ConfigError('Client IP "{}" not in server subnet "{}'.format(
                client['ip'], subnet))

    return None
def verify(wifi):
    if wifi['deleted']:
        interface = wifi['intf']
        is_member, bridge = is_bridge_member(interface)
        if is_member:
            # can not use a f'' formatted-string here as bridge would not get
            # expanded in the print statement
            raise ConfigError('Can not delete interface "{0}" as it ' \
                              'is a member of bridge "{1}"!'.format(interface, bridge))
        return None


    if wifi['op_mode'] != 'monitor' and not wifi['ssid']:
        raise ConfigError('SSID must be set for {}'.format(wifi['intf']))

    if not wifi['phy']:
        raise ConfigError('You must specify physical-device')

    if not wifi['mode']:
        raise ConfigError('You must specify a WiFi mode')

    if wifi['op_mode'] == 'ap':
        c = Config()
        if not c.exists('system wifi-regulatory-domain'):
            raise ConfigError('Wireless regulatory domain is mandatory,\n' \
                              'use "set system wifi-regulatory-domain".')

        if not wifi['channel']:
            raise ConfigError('Channel must be set for {}'.format(wifi['intf']))

    if len(wifi['sec_wep_key']) > 4:
        raise ConfigError('No more then 4 WEP keys configurable')

    if wifi['cap_vht'] and not wifi['cap_ht']:
        raise ConfigError('Specify HT flags if you want to use VHT!')

    if wifi['cap_vht_beamform'] and wifi['cap_vht_antenna_cnt'] == 1:
        raise ConfigError('Cannot use beam forming with just one antenna!')

    if wifi['cap_vht_beamform'] == 'single-user-beamformer' and wifi['cap_vht_antenna_cnt'] < 3:
        # Nasty Gotcha: see https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf lines 692-705
        raise ConfigError('Single-user beam former requires at least 3 antennas!')

    if wifi['sec_wep'] and (len(wifi['sec_wep_key']) == 0):
        raise ConfigError('Missing WEP keys')

    if wifi['sec_wpa'] and not (wifi['sec_wpa_passphrase'] or wifi['sec_wpa_radius']):
        raise ConfigError('Misssing WPA key or RADIUS server')

    for radius in wifi['sec_wpa_radius']:
        if not radius['key']:
            raise ConfigError('Misssing RADIUS shared secret key for server: {}'.format(radius['server']))

    vrf_name = wifi['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    # use common function to verify VLAN configuration
    verify_vlan_config(wifi)

    conf = Config()
    # Only one wireless interface per phy can be in station mode
    base = ['interfaces', 'wireless']
    for phy in os.listdir('/sys/class/ieee80211'):
        stations = []
        for wlan in conf.list_nodes(base):
            # the following node is mandatory
            if conf.exists(base + [wlan, 'physical-device', phy]):
                tmp = conf.return_value(base + [wlan, 'type'])
                if tmp == 'station':
                    stations.append(wlan)

        if len(stations) > 1:
            raise ConfigError('Only one station per wireless physical interface possible!')

    return None