Ejemplo n.º 1
0
def generate(data):
    render(charon_conf_file, 'ipsec/charon.tmpl', data, trim_blocks=True)

    if data["ipsec_l2tp"]:
        remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_secrets_file)
        # old_umask = os.umask(0o077)
        # render(ipsec_secrets_file, 'ipsec/ipsec.secrets.tmpl', data, trim_blocks=True)
        # os.umask(old_umask)
        ## Use this method while IPSec CLI handler won't be overwritten to python
        write_ipsec_secrets(data)

        old_umask = os.umask(0o077)

        # Create tunnels directory if does not exist
        if not os.path.exists(ipsec_ra_conn_dir):
            os.makedirs(ipsec_ra_conn_dir)

        render(ipsec_ra_conn_file, 'ipsec/remote-access.tmpl', data, trim_blocks=True)
        os.umask(old_umask)

        remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_conf_file)
        # old_umask = os.umask(0o077)
        # render(ipsec_conf_file, 'ipsec/ipsec.conf.tmpl', data, trim_blocks=True)
        # os.umask(old_umask)
        ## Use this method while IPSec CLI handler won't be overwritten to python
        write_ipsec_conf(data)

    else:
        if os.path.exists(ipsec_ra_conn_file):
            remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_ra_conn_file)
        remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_secrets_file)
        remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_conf_file)
Ejemplo n.º 2
0
def generate(ntp):
    # bail out early - looks like removal from running config
    if ntp is None:
        return None

    render(config_file, 'ntp/ntp.conf.tmpl', ntp)
    return None
Ejemplo n.º 3
0
def generate(relay):
    # bail out early - looks like removal from running config
    if relay is None:
        return None

    render(config_file, 'dhcpv6-relay/config.tmpl', relay)
    return None
Ejemplo n.º 4
0
def generate(bgp):
    # bail out early - looks like removal from running config
    if not bgp:
        return None

    render(config_file, 'frr/bgp.frr.tmpl', bgp)
    return None
Ejemplo n.º 5
0
    def set(self):
        """
        Configure interface as DHCPv6 client. The dhclient binary is automatically
        started in background!

        Example:

        >>> from vyos.ifconfig import Interface
        >>> j = Interface('eth0')
        >>> j.dhcp.v6.set()
        """

        # better save then sorry .. should be checked in interface script
        # but if you missed it we are safe!
        if self.options['dhcpv6_prm_only'] and self.options['dhcpv6_temporary']:
            raise Exception(
                'DHCPv6 temporary and parameters-only options are mutually exclusive!'
            )

        render(self._conf_file,
               'dhcp-client/ipv6.tmpl',
               self.options,
               trim_blocks=True)
        return self._cmd(
            'systemctl restart dhcp6c@{ifname}.service'.format(**self.options))
Ejemplo n.º 6
0
def generate(config):
    # skip all checks if flow-accounting was removed
    if not config['flow-accounting-configured']:
        return True

    # Calculate all necessary values
    if config['buffer-size']:
        # circular queue size
        config['plugin_pipe_size'] = int(config['buffer-size']) * 1024**2
    else:
        config['plugin_pipe_size'] = default_plugin_pipe_size * 1024**2
    # transfer buffer size
    # recommended value from pmacct developers 1/1000 of pipe size
    config['plugin_buffer_size'] = int(config['plugin_pipe_size'] / 1000)

    # Prepare a timeouts string
    timeout_string = ''
    for timeout_type, timeout_value in config['netflow']['timeout'].items():
        if timeout_value:
            if timeout_string == '':
                timeout_string = "{}{}={}".format(timeout_string, timeout_type, timeout_value)
            else:
                timeout_string = "{}:{}={}".format(timeout_string, timeout_type, timeout_value)
    config['netflow']['timeout_string'] = timeout_string

    render(uacctd_conf_path, 'netflow/uacctd.conf.tmpl', {
        'templatecfg': config,
        'snaplen': default_captured_packet_size,
    })
Ejemplo n.º 7
0
def generate(openvpn):
    interface = openvpn['intf']
    directory = os.path.dirname(get_config_name(interface))

    # we can't know in advance which clients have been removed,
    # thus all client configs will be removed and re-added on demand
    ccd_dir = os.path.join(directory, 'ccd', interface)
    if os.path.isdir(ccd_dir):
        rmtree(ccd_dir, ignore_errors=True)

    if openvpn['deleted'] or openvpn['disable']:
        return None

    # create config directory on demand
    directories = []
    directories.append(f'{directory}/status')
    directories.append(f'{directory}/ccd/{interface}')
    for onedir in directories:
        if not os.path.exists(onedir):
            os.makedirs(onedir, 0o755)
        chown(onedir, user, group)

    # Fix file permissons for keys
    fix_permissions = []
    fix_permissions.append(openvpn['shared_secret_file'])
    fix_permissions.append(openvpn['tls_key'])

    # Generate User/Password authentication file
    if openvpn['auth']:
        with open(openvpn['auth_user_pass_file'], 'w') as f:
            f.write('{}\n{}'.format(openvpn['auth_user'],
                                    openvpn['auth_pass']))
        # also change permission on auth file
        fix_permissions.append(openvpn['auth_user_pass_file'])

    else:
        # delete old auth file if present
        if os.path.isfile(openvpn['auth_user_pass_file']):
            os.remove(openvpn['auth_user_pass_file'])

    # Generate client specific configuration
    for client in openvpn['client']:
        client_file = os.path.join(ccd_dir, client['name'])
        render(client_file, 'openvpn/client.conf.tmpl', client)
        chown(client_file, user, group)

    # we need to support quoting of raw parameters from OpenVPN CLI
    # see https://phabricator.vyos.net/T1632
    render(get_config_name(interface),
           'openvpn/server.conf.tmpl',
           openvpn,
           formater=lambda _: _.replace(""", '"'))
    chown(get_config_name(interface), user, group)

    # Fixup file permissions
    for file in fix_permissions:
        chmod_600(file)

    return None
Ejemplo n.º 8
0
def generate(nat):
    render(iptables_nat_config,
           'firewall/nftables-nat.tmpl',
           nat,
           trim_blocks=True,
           permission=0o755)

    return None
Ejemplo n.º 9
0
def generate(mdns):
    if mdns is None:
        return None

    if mdns['disabled']:
        print('Warning: mDNS repeater will be deactivated because it is disabled')
        return None

    render(config_file, 'mdns-repeater/mdns-repeater.tmpl', mdns)
    return None
Ejemplo n.º 10
0
def generate(https):
    if https is None:
        return None

    if 'server_block_list' not in https or not https['server_block_list']:
        https['server_block_list'] = [default_server_block]

    render(config_file, 'https/nginx.default.tmpl', https, trim_blocks=True)

    return None
Ejemplo n.º 11
0
def generate(dhcp):
    if not dhcp or dhcp['disabled']:
        return None

    # Please see: https://phabricator.vyos.net/T1129 for quoting of the raw parameters
    # we can pass to ISC DHCPd
    render(config_file,
           'dhcp-server/dhcpd.conf.tmpl',
           dhcp,
           formater=lambda _: _.replace(""", '"'))
    return None
Ejemplo n.º 12
0
def generate(rtradv):
    if not rtradv['interfaces']:
        return None

    render(config_file, 'router-advert/radvd.conf.tmpl', rtradv, trim_blocks=True)

    # adjust file permissions of new configuration file
    if os.path.exists(config_file):
        os.chmod(config_file, S_IRUSR | S_IWUSR | S_IRGRP)

    return None
Ejemplo n.º 13
0
def generate(c):
    if c == None:
        return None

    conf = '/etc/rsyslog.d/vyos-rsyslog.conf'
    render(conf, 'syslog/rsyslog.conf.tmpl', c, trim_blocks=True)

    # eventually write for each file its own logrotate file, since size is
    # defined it shouldn't matter
    conf = '/etc/logrotate.d/vyos-rsyslog'
    render(conf, 'syslog/logrotate.tmpl', c, trim_blocks=True)
Ejemplo n.º 14
0
def generate(dyndns):
    # bail out early - looks like removal from running config
    if dyndns['deleted']:
        return None

    render(config_file, 'dynamic-dns/ddclient.conf.tmpl', dyndns)

    # Config file must be accessible only by its owner
    os.chmod(config_file, S_IRUSR | S_IWUSR)

    return None
Ejemplo n.º 15
0
def generate(dns):
    # bail out early - looks like removal from running config
    if dns is None:
        return None

    render(config_file,
           'dns-forwarding/recursor.conf.tmpl',
           dns,
           trim_blocks=True,
           user='******',
           group='pdns')
    return None
Ejemplo n.º 16
0
def generate(igmp_proxy):
    # bail out early - looks like removal from running config
    if igmp_proxy is None:
        return None

    # bail out early - service is disabled, but inform user
    if igmp_proxy['disable']:
        print('Warning: IGMP Proxy will be deactivated because it is disabled')
        return None

    render(config_file, 'igmp-proxy/igmpproxy.conf.tmpl', igmp_proxy)
    return None
Ejemplo n.º 17
0
def generate(login):
    # calculate users encrypted password
    for user in login['add_users']:
        if user['password_plaintext']:
            user['password_encrypted'] = crypt(user['password_plaintext'],
                                               METHOD_SHA512)
            user['password_plaintext'] = ''

            # remove old plaintext password and set new encrypted password
            env = os.environ.copy()
            env['vyos_libexec_dir'] = '/usr/libexec/vyos'

            call("/opt/vyatta/sbin/my_set system login user '{name}' "
                 "authentication plaintext-password '{password_plaintext}'".
                 format(**user),
                 env=env)

            call("/opt/vyatta/sbin/my_set system login user '{name}' "
                 "authentication encrypted-password '{password_encrypted}'".
                 format(**user),
                 env=env)

        else:
            try:
                if getspnam(
                        user['name']).sp_pwdp == user['password_encrypted']:
                    # If the current encrypted bassword matches the encrypted password
                    # from the config - do not update it. This will remove the encrypted
                    # value from the system logs.
                    #
                    # The encrypted password will be set only once during the first boot
                    # after an image upgrade.
                    user['password_encrypted'] = ''
            except:
                pass

    if len(login['radius_server']) > 0:
        render(radius_config_file,
               'system-login/pam_radius_auth.conf.tmpl',
               login,
               trim_blocks=True)

        uid = getpwnam('root').pw_uid
        gid = getpwnam('root').pw_gid
        os.chown(radius_config_file, uid, gid)
        chmod_600(radius_config_file)
    else:
        if os.path.isfile(radius_config_file):
            os.unlink(radius_config_file)

    return None
Ejemplo n.º 18
0
def generate(snmp):
    #
    # As we are manipulating the snmpd user database we have to stop it first!
    # This is even save if service is going to be removed
    call('systemctl stop snmpd.service')
    config_files = [
        config_file_client, config_file_daemon, config_file_access,
        config_file_user
    ]
    for file in config_files:
        rmfile(file)

    if snmp is None:
        return None

    # Write client config file
    render(config_file_client, 'snmp/etc.snmp.conf.tmpl', snmp)
    # Write server config file
    render(config_file_daemon, 'snmp/etc.snmpd.conf.tmpl', snmp)
    # Write access rights config file
    render(config_file_access, 'snmp/usr.snmpd.conf.tmpl', snmp)
    # Write access rights config file
    render(config_file_user, 'snmp/var.snmpd.conf.tmpl', snmp)

    return None
Ejemplo n.º 19
0
def generate(wifi):
    interface = wifi['intf']

    # always stop hostapd service first before reconfiguring it
    call(f'systemctl stop hostapd@{interface}.service')
    # always stop wpa_supplicant service first before reconfiguring it
    call(f'systemctl stop wpa_supplicant@{interface}.service')

    # Delete config files if interface is removed
    if wifi['deleted']:
        if os.path.isfile(hostapd_conf.format(**wifi)):
            os.unlink(hostapd_conf.format(**wifi))

        if os.path.isfile(wpa_suppl_conf.format(**wifi)):
            os.unlink(wpa_suppl_conf.format(**wifi))

        return None

    if not wifi['mac']:
        # http://wiki.stocksy.co.uk/wiki/Multiple_SSIDs_with_hostapd
        # generate locally administered MAC address from used phy interface
        with open('/sys/class/ieee80211/{}/addresses'.format(wifi['phy']),
                  'r') as f:
            # some PHYs tend to have multiple interfaces and thus supply multiple MAC
            # addresses - we only need the first one for our calculation
            tmp = f.readline().rstrip()
            tmp = EUI(tmp).value
            # mask last nibble from the MAC address
            tmp &= 0xfffffffffff0
            # set locally administered bit in MAC address
            tmp |= 0x020000000000
            # we now need to add an offset to our MAC address indicating this
            # subinterfaces index
            tmp += int(findall(r'\d+', interface)[0])

            # convert integer to "real" MAC address representation
            mac = EUI(hex(tmp).split('x')[-1])
            # change dialect to use : as delimiter instead of -
            mac.dialect = mac_unix_expanded
            wifi['mac'] = str(mac)

    # render appropriate new config files depending on access-point or station mode
    if wifi['op_mode'] == 'ap':
        render(hostapd_conf.format(**wifi), 'wifi/hostapd.conf.tmpl', wifi)

    elif wifi['op_mode'] == 'station':
        render(wpa_suppl_conf.format(**wifi), 'wifi/wpa_supplicant.conf.tmpl',
               wifi)

    return None
Ejemplo n.º 20
0
def generate(pptp):
    if not pptp:
        return None

    render(pptp_conf, 'accel-ppp/pptp.config.tmpl', pptp, trim_blocks=True)

    if pptp['local_users']:
        render(pptp_chap_secrets,
               'accel-ppp/chap-secrets.tmpl',
               pptp,
               trim_blocks=True)
        os.chmod(pptp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
    else:
        if os.path.exists(pptp_chap_secrets):
            os.unlink(pptp_chap_secrets)
Ejemplo n.º 21
0
def generate(ipoe):
    if not ipoe:
        return None

    render(ipoe_conf, 'accel-ppp/ipoe.config.tmpl', ipoe, trim_blocks=True)

    if ipoe['auth_mode'] == 'local':
        render(ipoe_chap_secrets, 'accel-ppp/chap-secrets.ipoe.tmpl', ipoe)
        os.chmod(ipoe_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)

    else:
        if os.path.exists(ipoe_chap_secrets):
            os.unlink(ipoe_chap_secrets)

    return None
Ejemplo n.º 22
0
def generate(regdom):
    print("Changing the wireless regulatory domain requires a system reboot.")

    if regdom['deleted']:
        if os.path.isfile(config_80211_file):
            os.unlink(config_80211_file)

        if os.path.isfile(config_crda_file):
            os.unlink(config_crda_file)

        return None

    render(config_80211_file, 'wifi/cfg80211.conf.tmpl', regdom)
    render(config_crda_file, 'wifi/crda.tmpl', regdom)
    return None
Ejemplo n.º 23
0
def generate(l2tp):
    if not l2tp:
        return None

    render(l2tp_conf, 'accel-ppp/l2tp.config.tmpl', l2tp, trim_blocks=True)

    if l2tp['auth_mode'] == 'local':
        render(l2tp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', l2tp)
        os.chmod(l2tp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)

    else:
        if os.path.exists(l2tp_chap_secrets):
            os.unlink(l2tp_chap_secrets)

    return None
Ejemplo n.º 24
0
def generate(data):
    vrrp_groups, sync_groups = data

    # Remove disabled groups from the sync group member lists
    for sync_group in sync_groups:
        for member in sync_group["members"]:
            g = list(filter(lambda x: x["name"] == member, vrrp_groups))[0]
            if g["disable"]:
                print("Warning: ignoring disabled VRRP group {0} in sync-group {1}".format(g["name"], sync_group["name"]))
    # Filter out disabled groups
    vrrp_groups = list(filter(lambda x: x["disable"] is not True, vrrp_groups))

    render(VRRP.location['config'], 'vrrp/keepalived.conf.tmpl',
            {"groups": vrrp_groups, "sync_groups": sync_groups})
    render(VRRP.location['daemon'], 'vrrp/daemon.tmpl', {})
    return None
Ejemplo n.º 25
0
def generate(sstp):
    if not sstp:
        return None

    # accel-cmd reload doesn't work so any change results in a restart of the daemon
    render(sstp_conf, 'accel-ppp/sstp.config.tmpl', sstp, trim_blocks=True)

    if sstp['local_users']:
        render(sstp_chap_secrets,
               'accel-ppp/chap-secrets.tmpl',
               sstp,
               trim_blocks=True)
        os.chmod(sstp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
    else:
        if os.path.exists(sstp_chap_secrets):
            os.unlink(sstp_chap_secrets)

    return sstp
Ejemplo n.º 26
0
def generate(lldp):
    # bail out early - looks like removal from running config
    if lldp is None:
        return

    # generate listen on interfaces
    for intf in lldp['interface_list']:
        tmp = ''
        # add exclamation mark if interface is disabled
        if intf['disable']:
            tmp = '!'

        tmp += intf['name']
        lldp['options']['listen_on'].append(tmp)

    # generate /etc/default/lldpd
    render(config_file, 'lldp/lldpd.tmpl', lldp)
    # generate /etc/lldpd.d/01-vyos.conf
    render(vyos_config_file, 'lldp/vyos.conf.tmpl', lldp)
Ejemplo n.º 27
0
def generate(wwan):
    # set up configuration file path variables where our templates will be
    # rendered into
    intf = wwan['intf']
    config_wwan = f'/etc/ppp/peers/{intf}'
    config_wwan_chat = wwan['chat_script']
    script_wwan_pre_up = f'/etc/ppp/ip-pre-up.d/1010-vyos-wwan-{intf}'
    script_wwan_ip_up = f'/etc/ppp/ip-up.d/1010-vyos-wwan-{intf}'
    script_wwan_ip_down = f'/etc/ppp/ip-down.d/1010-vyos-wwan-{intf}'

    config_files = [config_wwan, config_wwan_chat, script_wwan_pre_up,
                    script_wwan_ip_up, script_wwan_ip_down]

    # Always hang-up WWAN connection prior generating new configuration file
    call(f'systemctl stop ppp@{intf}.service')

    if wwan['deleted']:
        # Delete PPP configuration files
        for file in config_files:
            if os.path.exists(file):
                os.unlink(file)

    else:
        # Create PPP configuration files
        render(config_wwan, 'wwan/peer.tmpl', wwan)
        # Create PPP chat script
        render(config_wwan_chat, 'wwan/chat.tmpl', wwan)

        # generated script file must be executable

        # Create script for ip-pre-up.d
        render(script_wwan_pre_up, 'wwan/ip-pre-up.script.tmpl',
               wwan, permission=0o755)
        # Create script for ip-up.d
        render(script_wwan_ip_up, 'wwan/ip-up.script.tmpl',
               wwan, permission=0o755)
        # Create script for ip-down.d
        render(script_wwan_ip_down, 'wwan/ip-down.script.tmpl',
               wwan, permission=0o755)

    return None
Ejemplo n.º 28
0
def generate(salt):
    if not salt:
        return None

    render(config_file, 'salt-minion/minion.tmpl', salt,
           user=salt['user'], group=salt['group'])

    if not os.path.exists(master_keyfile):
        if salt['master_key']:
            req = PoolManager().request('GET', salt['master_key'], preload_content=False)

            with open(master_keyfile, 'wb') as f:
                while True:
                    data = req.read(1024)
                    if not data:
                        break
                    f.write(data)

            req.release_conn()
            chown(master_keyfile, salt['user'], salt['group'])

    return None
Ejemplo n.º 29
0
def generate(relay):
    if relay is None:
        return None

    config_dir = os.path.dirname(config_file)
    config_filename = os.path.basename(config_file)
    active_configs = []

    for config in fnmatch.filter(os.listdir(config_dir),
                                 config_filename + '*'):
        # determine prefix length to identify service instance
        prefix_len = len(config_filename)
        active_configs.append(config[prefix_len:])

    # sort our list
    active_configs.sort()

    # delete old configuration files
    for id in active_configs[:]:
        if os.path.exists(config_file + id):
            os.unlink(config_file + id)

    # If the service is disabled, we can bail out here
    if relay['disabled']:
        print(
            'Warning: UDP broadcast relay service will be deactivated because it is disabled'
        )
        return None

    for r in relay['instances']:
        # Skip writing instance config when it's disabled
        if r['disabled']:
            continue

        # configuration filename contains instance id
        file = config_file + str(r['id'])
        render(file, 'bcast-relay/udp-broadcast-relay.tmpl', r)

    return None
Ejemplo n.º 30
0
    def set(self):
        """
        Configure interface as DHCP client. The dhclient binary is automatically
        started in background!

        Example:

        >>> from vyos.ifconfig import Interface
        >>> j = Interface('eth0')
        >>> j.dhcp.v4.set()
        """
        if not self.options['hostname']:
            # read configured system hostname.
            # maybe change to vyos hostd client ???
            with open('/etc/hostname', 'r') as f:
                self.options['hostname'] = f.read().rstrip('\n')

        render(self.options['options_file'], 'dhcp-client/daemon-options.tmpl',
               self.options)
        render(self.options['conf_file'], 'dhcp-client/ipv4.tmpl',
               self.options)

        return self._cmd('systemctl restart dhclient@{ifname}.service'.format(
            **self.options))