Exemple #1
0
def terminate_sessions(username='', interface='', protocol=''):

    # Reset vpn connections by username
    if protocol in cmd_dict['vpn_types']:
        if username == "all_users":
            run(cmd_dict['cmd_base'].format(cmd_dict['vpn_types'][protocol],
                                            'all', ''))
        else:
            run(cmd_dict['cmd_base'].format(cmd_dict['vpn_types'][protocol],
                                            'username', username))

    # Reset vpn connections by ifname
    elif interface:
        for proto in cmd_dict['vpn_types']:
            run(cmd_dict['cmd_base'].format(cmd_dict['vpn_types'][proto], 'if',
                                            interface))

    elif username:
        # Reset all vpn connections
        if username == "all_users":
            for proto in cmd_dict['vpn_types']:
                run(cmd_dict['cmd_base'].format(cmd_dict['vpn_types'][proto],
                                                'all', ''))
        else:
            for proto in cmd_dict['vpn_types']:
                run(cmd_dict['cmd_base'].format(cmd_dict['vpn_types'][proto],
                                                'username', username))
Exemple #2
0
def main():
    #parese args
    parser = argparse.ArgumentParser()
    parser.add_argument('--action', help='Control action', required=True)
    parser.add_argument('--selector', help='Selector username|ifname|sid', required=False)
    parser.add_argument('--target', help='Target must contain username|ifname|sid', required=False)
    args = parser.parse_args()


    # Check is IPoE configured
    is_ipoe_configured()

    if args.action == "restart":
        run(cmd_dict['cmd_base'] + "restart")
        sys.exit(0)

    if args.action in cmd_dict['actions']:
        if args.selector in cmd_dict['selector'] and args.target:
            run(cmd_dict['cmd_base'] + "{0} {1} {2}".format(args.action, args.selector, args.target))
        else:
            output, err = popen(cmd_dict['cmd_base'] + cmd_dict['actions'][args.action], decode='utf-8')
            if not err:
                print(output)
            else:
                print("IPoE server is not running")
def apply(opt):
    # Beep action
    if opt['beep_if_fully_booted']:
        run('systemctl enable vyos-beep.service')
    else:
        run('systemctl disable vyos-beep.service')

    # Ctrl-Alt-Delete action
    if opt['ctrl_alt_del'] == 'ignore':
        if os.path.exists(systemd_ctrl_alt_del):
            os.unlink('/lib/systemd/system/ctrl-alt-del.target')

    elif opt['ctrl_alt_del'] == 'reboot':
        if os.path.exists(systemd_ctrl_alt_del):
            os.unlink(systemd_ctrl_alt_del)
        os.symlink('/lib/systemd/system/reboot.target', systemd_ctrl_alt_del)

    elif opt['ctrl_alt_del'] == 'poweroff':
        if os.path.exists(systemd_ctrl_alt_del):
            os.unlink(systemd_ctrl_alt_del)
        os.symlink('/lib/systemd/system/poweroff.target', systemd_ctrl_alt_del)

    # Reboot system on kernel panic
    with open('/proc/sys/kernel/panic', 'w') as f:
        if opt['reboot_on_panic']:
            f.write('60')
        else:
            f.write('0')
Exemple #4
0
def apply(config):
    if config is None:
        return None

    ## Send the updated data to vyos-hostsd

    # vyos-hostsd uses "tags" to identify data sources
    tag = "static"

    try:
        client = vyos.hostsd_client.Client()

        # Check if disable-dhcp-nameservers is configured, and if yes - delete DNS servers added by DHCP
        if config['no_dhcp_ns']:
            client.delete_name_servers('dhcp-.+')

        client.set_host_name(config['hostname'], config['domain_name'],
                             config['domain_search'])

        client.delete_name_servers(tag)
        client.add_name_servers(tag, config['nameserver'])

        client.delete_hosts(tag)
        client.add_hosts(tag, config['static_host_mapping'])
    except vyos.hostsd_client.VyOSHostsdError as e:
        raise ConfigError(str(e))

    ## Actually update the hostname -- vyos-hostsd doesn't do that

    # No domain name -- the Debian way.
    hostname_new = config['hostname']

    # rsyslog runs into a race condition at boot time with systemd
    # restart rsyslog only if the hostname changed.
    hostname_old = cmd('hostnamectl --static')
    call(f'hostnamectl set-hostname --static {hostname_new}')

    # Restart services that use the hostname
    if hostname_new != hostname_old:
        call("systemctl restart rsyslog.service")

    # If SNMP is running, restart it too
    ret = run("pgrep snmpd")
    if ret == 0:
        call("systemctl restart snmpd.service")

    # restart pdns if it is used
    ret = run('/usr/bin/rec_control ping')
    if ret == 0:
        call('/etc/init.d/pdns-recursor restart >/dev/null')

    return None
Exemple #5
0
def cancel_shutdown():
    output = get_shutdown_status()
    if output and 'MODE' in output:
        timenow = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        try:
            cmd('/sbin/shutdown -c --no-wall')
        except OSError as e:
            sys.exit("Could not cancel a reboot or poweroff: %s" % e)
        message = "Scheduled %s has been cancelled %s" % (output['MODE'],
                                                          timenow)
        run(f'wall {message}')
    else:
        print("Reboot or poweroff is not scheduled")
def apply(config):
    for intf, addresses in config.items():
        # bring the interface up
        cmd = ["ip", "link", "set", "dev", intf, "up"]
        sl.syslog(sl.LOG_NOTICE, " ".join(cmd))
        run(cmd)

        # add configured addresses to interface
        for addr in addresses:
            if addr == "dhcp":
                cmd = ["dhclient", intf]
            else:
                cmd = ["ip", "address", "add", addr, "dev", intf]
            sl.syslog(sl.LOG_NOTICE, " ".join(cmd))
            run(cmd)
Exemple #7
0
def check_kmod():
    """ check if kmod is loaded, if not load it """
    if not os.path.exists('/sys/module/wireguard'):
        sl.syslog(sl.LOG_NOTICE, "loading wirguard kmod")
        if run('sudo modprobe wireguard') != 0:
            sl.syslog(sl.LOG_ERR, "modprobe wireguard failed")
            raise ConfigError("modprobe wireguard failed")
Exemple #8
0
def apply(c):
  if c['ipsec_conf']:
    # Shutdown VPN service which can use QAT
    vpn_control('stop')

  # Disable QAT service
  if c['qat_conf'] == None:
    run('sudo /etc/init.d/qat_service stop')
    if c['ipsec_conf']:
      vpn_control('start')
    return

  # Run qat init.d script
  run('sudo /etc/init.d/qat_service start')
  if c['ipsec_conf']:
    # Recovery VPN service
    vpn_control('start')
Exemple #9
0
def apply(config):
    if config is None:
        return None

    ## Send the updated data to vyos-hostsd

    # vyos-hostsd uses "tags" to identify data sources
    tag = "static"

    try:
        client = vyos.hostsd_client.Client()

        # Check if disable-dhcp-nameservers is configured, and if yes - delete DNS servers added by DHCP
        if config['no_dhcp_ns']:
            client.delete_name_servers('dhcp-.+')

        client.set_host_name(config['hostname'], config['domain_name'], config['domain_search'])

        client.delete_name_servers(tag)
        client.add_name_servers(tag, config['nameserver'])

        client.delete_hosts(tag)
        client.add_hosts(tag, config['static_host_mapping'])
    except vyos.hostsd_client.VyOSHostsdError as e:
        raise ConfigError(str(e))

    ## Actually update the hostname -- vyos-hostsd doesn't do that

    # No domain name -- the Debian way.
    hostname_new = config['hostname']

    # rsyslog runs into a race condition at boot time with systemd
    # restart rsyslog only if the hostname changed.
    hostname_old = cmd('hostnamectl --static')
    call(f'hostnamectl set-hostname --static {hostname_new}')

    # Restart services that use the hostname
    if hostname_new != hostname_old:
        call("systemctl restart rsyslog.service")

    # If SNMP is running, restart it too
    if process_named_running('snmpd'):
        call('systemctl restart snmpd.service')

    # restart pdns if it is used - we check for the control dir to not raise
    # an exception on system startup
    #
    #   File "/usr/lib/python3/dist-packages/vyos/configsession.py", line 128, in __run_command
    #     raise ConfigSessionError(output)
    # vyos.configsession.ConfigSessionError: [ system domain-name vyos.io ]
    # Fatal: Unable to generate local temporary file in directory '/run/powerdns': No such file or directory
    if os.path.isdir('/run/powerdns'):
        ret = run('/usr/bin/rec_control --socket-dir=/run/powerdns ping')
        if ret == 0:
            call('systemctl restart pdns-recursor.service')

    return None
Exemple #10
0
def generate_keypair(pk, pub):
    """ generates a keypair which is stored in /config/auth/wireguard """
    old_umask = os.umask(0o027)
    if run(f'wg genkey | tee {pk} | wg pubkey > {pub}') != 0:
        raise ConfigError("wireguard key-pair generation failed")
    else:
        sl.syslog(sl.LOG_NOTICE,
                  "new keypair wireguard key generated in " + dir)
    os.umask(old_umask)
Exemple #11
0
def get_full_version_data(fname=version_file):
    version_data = get_version_data(fname)

    # Get system architecture (well, kernel architecture rather)
    version_data['system_arch'], _ = popen('uname -m', stderr=DEVNULL)

    hypervisor, code = popen('hvinfo', stderr=DEVNULL)
    if code == 1:
        # hvinfo returns 1 if it cannot detect any hypervisor
        version_data['system_type'] = 'bare metal'
    else:
        version_data['system_type'] = f"{hypervisor} guest"

    # Get boot type, it can be livecd, installed image, or, possible, a system installed
    # via legacy "install system" mechanism
    # In installed images, the squashfs image file is named after its image version,
    # while on livecd it's just "filesystem.squashfs", that's how we tell a livecd boot
    # from an installed image
    boot_via = "installed image"
    if run(""" grep -e '^overlay.*/filesystem.squashfs' /proc/mounts >/dev/null"""
           ) == 0:
        boot_via = "livecd"
    elif run(""" grep '^overlay /' /proc/mounts >/dev/null """) != 0:
        boot_via = "legacy non-image installation"
    version_data['boot_via'] = boot_via

    # Get hardware details from DMI
    dmi = '/sys/class/dmi/id'
    version_data['hardware_vendor'] = read_file(dmi + '/sys_vendor', 'Unknown')
    version_data['hardware_model'] = read_file(dmi + '/product_name',
                                               'Unknown')

    # These two assume script is run as root, normal users can't access those files
    subsystem = '/sys/class/dmi/id/subsystem/id'
    version_data['hardware_serial'] = read_file(subsystem + '/product_serial',
                                                'Unknown')
    version_data['hardware_uuid'] = read_file(subsystem + '/product_uuid',
                                              'Unknown')

    return version_data
Exemple #12
0
def apply(c):
    if c == None:
        if os.path.exists(pidfile):
            _accel_cmd('shutdown hard')
            if os.path.exists(pidfile):
                os.remove(pidfile)
        return None

    if not os.path.exists(pidfile):
        ret = run(f'/usr/sbin/accel-pppd -c {pppoe_conf} -p {pidfile} -d')
        _chk_con()
        if ret != 0 and os.path.exists(pidfile):
            os.remove(pidfile)
            raise ConfigError('accel-pppd failed to start')
    else:
        _accel_cmd('restart')
Exemple #13
0
def genkey(location):
    """ helper function to check, regenerate the keypair """
    pk = "{}/private.key".format(location)
    pub = "{}/public.key".format(location)
    old_umask = os.umask(0o027)
    if os.path.exists(pk) and os.path.exists(pub):
        try:
            choice = input(
                "You already have a wireguard key-pair, do you want to re-generate? [y/n] "
            )
            if choice == 'y' or choice == 'Y':
                generate_keypair(pk, pub)
        except KeyboardInterrupt:
            sys.exit(0)
    else:
        """ if keypair is bing executed from a running iso """
        if not os.path.exists(location):
            run(f'sudo mkdir -p {location}')
            run(f'sudo chgrp vyattacfg {location}')
            run(f'sudo chmod 750 {location}')
        generate_keypair(pk, pub)
    os.umask(old_umask)
Exemple #14
0
def _uacctd_running():
    command = 'systemctl status uacctd.service > /dev/null'
    return run(command) == 0
Exemple #15
0
def vpn_control(action):
  # XXX: Should these commands report failure
  if action == 'restore' and gl_ipsec_conf:
    return run('sudo ipsec start')
  return run(f'sudo ipsec {action}')
Exemple #16
0
 def feature(ifname, option, value):
     run(f'/sbin/ethtool -K {ifname} {option} {value}', 'ifconfig')
     return False
Exemple #17
0
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-i',
        '--interface',
        action='store',
        help=
        'Interface name which should be added to bridge it is configured for',
        required=True)
    args, unknownargs = parser.parse_known_args()

    conf = Config()
    if not conf.list_nodes('interfaces bridge'):
        #  no bridge interfaces exist .. bail out early
        exit(0)
    else:
        for bridge in conf.list_nodes('interfaces bridge'):
            for member_if in conf.list_nodes(
                    'interfaces bridge {} member interface'.format(bridge)):
                if args.interface == member_if:
                    command = 'brctl addif "{}" "{}"'.format(
                        bridge, args.interface)
                    # let interfaces etc. settle - especially required for OpenVPN bridged interfaces
                    sleep(4)
                    # XXX: This is ignoring any issue, should be cmd but kept as it
                    # XXX: during the migration to not cause any regression
                    run(command)

    exit(0)
Exemple #18
0
def _accel_cmd(command):
    return run(f'/usr/bin/accel-cmd {command}')
Exemple #19
0
def _accel_cmd(command):
    return run('/usr/bin/accel-cmd -p 2003 {command}')
def apply(wifi):
    if wifi['deleted']:
        w = WiFiIf(wifi['intf'])
        # delete interface
        w.remove()
    else:
        # WiFi interface needs to be created on-block (e.g. mode or physical
        # interface) instead of passing a ton of arguments, I just use a dict
        # that is managed by vyos.ifconfig
        conf = deepcopy(WiFiIf.get_config())

        # Assign WiFi instance configuration parameters to config dict
        conf['phy'] = wifi['phy']

        # Finally create the new interface
        w = WiFiIf(wifi['intf'], **conf)

        # assign/remove VRF
        w.set_vrf(wifi['vrf'])

        # update interface description used e.g. within SNMP
        w.set_alias(wifi['description'])

        if wifi['dhcp_client_id']:
            w.dhcp.v4.options['client_id'] = wifi['dhcp_client_id']

        if wifi['dhcp_hostname']:
            w.dhcp.v4.options['hostname'] = wifi['dhcp_hostname']

        if wifi['dhcp_vendor_class_id']:
            w.dhcp.v4.options['vendor_class_id'] = wifi['dhcp_vendor_class_id']

        if wifi['dhcpv6_prm_only']:
            w.dhcp.v6.options['dhcpv6_prm_only'] = True

        if wifi['dhcpv6_temporary']:
            w.dhcp.v6.options['dhcpv6_temporary'] = True

        # ignore link state changes
        w.set_link_detect(wifi['disable_link_detect'])

        # Change interface MAC address - re-set to real hardware address (hw-id)
        # if custom mac is removed
        if wifi['mac']:
            w.set_mac(wifi['mac'])
        elif wifi['hw_id']:
            w.set_mac(wifi['hw_id'])

        # configure ARP filter configuration
        w.set_arp_filter(wifi['ip_disable_arp_filter'])
        # configure ARP accept
        w.set_arp_accept(wifi['ip_enable_arp_accept'])
        # configure ARP announce
        w.set_arp_announce(wifi['ip_enable_arp_announce'])
        # configure ARP ignore
        w.set_arp_ignore(wifi['ip_enable_arp_ignore'])
        # IPv6 address autoconfiguration
        w.set_ipv6_autoconf(wifi['ipv6_autoconf'])
        # IPv6 EUI-based address
        w.set_ipv6_eui64_address(wifi['ipv6_eui64_prefix'])
        # IPv6 forwarding
        w.set_ipv6_forwarding(wifi['ipv6_forwarding'])
        # IPv6 Duplicate Address Detection (DAD) tries
        w.set_ipv6_dad_messages(wifi['ipv6_dup_addr_detect'])

        # Configure interface address(es)
        # - not longer required addresses get removed first
        # - newly addresses will be added second
        for addr in wifi['address_remove']:
            w.del_addr(addr)
        for addr in wifi['address']:
            w.add_addr(addr)

        # remove no longer required VLAN interfaces (vif)
        for vif in wifi['vif_remove']:
            e.del_vlan(vif)

        # create VLAN interfaces (vif)
        for vif in wifi['vif']:
            # QoS priority mapping can only be set during interface creation
            # so we delete the interface first if required.
            if vif['egress_qos_changed'] or vif['ingress_qos_changed']:
                try:
                    # on system bootup the above condition is true but the interface
                    # does not exists, which throws an exception, but that's legal
                    e.del_vlan(vif['id'])
                except:
                    pass

            vlan = e.add_vlan(vif['id'])
            apply_vlan_config(vlan, vif)

        # Enable/Disable interface - interface is always placed in
        # administrative down state in WiFiIf class
        if not wifi['disable']:
            w.set_admin_state('up')

            # Physical interface is now configured. Proceed by starting hostapd or
            # wpa_supplicant daemon. When type is monitor we can just skip this.
            if wifi['op_mode'] == 'ap':
                command = 'start-stop-daemon'
                command += ' --start '
                command += ' --quiet'
                command += ' --oknodo'
                command += ' --pidfile ' + get_pid('hostapd', wifi['intf'])
                command += ' --exec /usr/sbin/hostapd'
                # now pass arguments to hostapd binary
                command += ' -- '
                command += ' -B'
                command += ' -P ' + get_pid('hostapd', wifi['intf'])
                command += ' ' + get_conf_file('hostapd', wifi['intf'])

                # execute assembled command
                run(command)

            elif wifi['op_mode'] == 'station':
                command = 'start-stop-daemon'
                command += ' --start '
                command += ' --quiet'
                command += ' --oknodo'
                command += ' --pidfile ' + get_pid('hostapd', wifi['intf'])
                command += ' --exec /sbin/wpa_supplicant'
                # now pass arguments to hostapd binary
                command += ' -- '
                command += ' -s -B -D nl80211'
                command += ' -P ' + get_pid('wpa_supplicant', wifi['intf'])
                command += ' -i ' + wifi['intf']
                command += ' -c ' + \
                    get_conf_file('wpa_supplicant', wifi['intf'])

                # execute assembled command
                run(command)

    return None
Exemple #21
0
def apply(c):
    if not c:
        return run('systemctl stop syslog')
    return run('systemctl restart syslog')
Exemple #22
0
    system_type = "bare metal"
    try:
        hypervisor = cmd('hvinfo', stderr=DEVNULL)
        system_type = "{0} guest".format(hypervisor)
    except OSError:
        # hvinfo returns 1 if it cannot detect any hypervisor
        pass
    version_data['system_type'] = system_type

    # Get boot type, it can be livecd, installed image, or, possible, a system installed
    # via legacy "install system" mechanism
    # In installed images, the squashfs image file is named after its image version,
    # while on livecd it's just "filesystem.squashfs", that's how we tell a livecd boot
    # from an installed image
    boot_via = "installed image"
    if run(""" grep -e '^overlay.*/filesystem.squashfs' /proc/mounts >/dev/null"""
           ) == 0:
        boot_via = "livecd"
    elif run(""" grep '^overlay /' /proc/mounts >/dev/null """) != 0:
        boot_via = "legacy non-image installation"
    version_data['boot_via'] = boot_via

    # Get hardware details from DMI
    version_data['hardware_vendor'] = read_file('/sys/class/dmi/id/sys_vendor')
    version_data['hardware_model'] = read_file(
        '/sys/class/dmi/id/product_name')

    # These two assume script is run as root, normal users can't access those files
    version_data['hardware_serial'] = read_file(
        '/sys/class/dmi/id/subsystem/id/product_serial')
    version_data['hardware_uuid'] = read_file(
        '/sys/class/dmi/id/subsystem/id/product_uuid')
def _accel_cmd(command):
    return run('/usr/bin/accel-cmd -p {cmd_port} {command}')
def _uacctd_running():
    command = '/usr/bin/sudo /bin/systemctl status uacctd > /dev/null'
    return run(command) == 0
def generate(wifi):
    # Prepare Jinja2 template loader from files
    tmpl_path = os.path.join(vyos_data_dir["data"], "templates", "wifi")
    fs_loader = FileSystemLoader(tmpl_path)
    env = Environment(loader=fs_loader)

    # always stop hostapd service first before reconfiguring it
    pidfile = get_pid('hostapd', wifi['intf'])
    if process_running(pidfile):
        command = 'start-stop-daemon'
        command += ' --stop '
        command += ' --quiet'
        command += ' --oknodo'
        command += ' --pidfile ' + pidfile
        run(command)

    # always stop wpa_supplicant service first before reconfiguring it
    pidfile = get_pid('wpa_supplicant', wifi['intf'])
    if process_running(pidfile):
        command = 'start-stop-daemon'
        command += ' --stop '
        command += ' --quiet'
        command += ' --oknodo'
        command += ' --pidfile ' + pidfile
        run(command)

    # Delete config files if interface is removed
    if wifi['deleted']:
        if os.path.isfile(get_conf_file('hostapd', wifi['intf'])):
            os.unlink(get_conf_file('hostapd', wifi['intf']))

        if os.path.isfile(get_conf_file('wpa_supplicant', wifi['intf'])):
            os.unlink(get_conf_file('wpa_supplicant', wifi['intf']))

        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+', wifi['intf'])[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':
        tmpl = env.get_template('hostapd.conf.tmpl')
        config_text = tmpl.render(wifi)
        with open(get_conf_file('hostapd', wifi['intf']), 'w') as f:
            f.write(config_text)

    elif wifi['op_mode'] == 'station':
        tmpl = env.get_template('wpa_supplicant.conf.tmpl')
        config_text = tmpl.render(wifi)
        with open(get_conf_file('wpa_supplicant', wifi['intf']), 'w') as f:
            f.write(config_text)

    return None