diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/conf_mode/high-availability.py | 5 | ||||
| -rwxr-xr-x | src/conf_mode/protocols_bgp.py | 43 | ||||
| -rwxr-xr-x | src/etc/systemd/system-generators/vyos-generator | 94 | ||||
| -rw-r--r-- | src/etc/systemd/system/getty@.service.d/aftervyos.conf | 3 | ||||
| -rw-r--r-- | src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf | 3 | ||||
| -rwxr-xr-x | src/helpers/vyos_config_sync.py | 2 | ||||
| -rwxr-xr-x | src/init/vyos-config | 16 | ||||
| -rwxr-xr-x | src/init/vyos-router | 421 | ||||
| -rwxr-xr-x | src/migration-scripts/vrrp/3-to-4 | 51 | ||||
| -rwxr-xr-x | src/op_mode/pki.py | 29 | ||||
| -rw-r--r-- | src/systemd/vyos-router.service | 19 | ||||
| -rw-r--r-- | src/systemd/vyos.target | 3 | 
12 files changed, 682 insertions, 7 deletions
| diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py index e18b426b1..2b1cdbd23 100755 --- a/src/conf_mode/high-availability.py +++ b/src/conf_mode/high-availability.py @@ -175,6 +175,11 @@ def verify(ha):      # Virtual-server      if 'virtual_server' in ha:          for vs, vs_config in ha['virtual_server'].items(): + +            if 'address' not in vs_config and 'fwmark' not in vs_config: +                raise ConfigError('Either address or fwmark is required ' +                                  f'but not set for virtual-server "{vs}"') +              if 'port' not in vs_config and 'fwmark' not in vs_config:                  raise ConfigError(f'Port or fwmark is required but not set for virtual-server "{vs}"')              if 'port' in vs_config and 'fwmark' in vs_config: diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index b23584bdb..532970735 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2020-2022 VyOS maintainers and contributors +# Copyright (C) 2020-2023 VyOS maintainers and contributors  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as @@ -20,6 +20,7 @@ from sys import argv  from vyos.base import Warning  from vyos.config import Config  from vyos.configdict import dict_merge +from vyos.configdict import node_changed  from vyos.configverify import verify_prefix_list  from vyos.configverify import verify_route_map  from vyos.configverify import verify_vrf @@ -27,6 +28,7 @@ from vyos.template import is_ip  from vyos.template import is_interface  from vyos.template import render_to_string  from vyos.util import dict_search +from vyos.util import get_interface_config  from vyos.validate import is_addr_assigned  from vyos import ConfigError  from vyos import frr @@ -54,6 +56,20 @@ def get_config(config=None):                                                   key_mangling=('-', '_'),                                                   get_first_key=True,                                                   no_tag_node_value_mangle=True) +    # if config removed +    interfaces_removed = node_changed(conf, base + ['interface']) +    if interfaces_removed: +        bgp['interface_removed'] = list(interfaces_removed) +    # Add vrf mapping in <bgp interface ifname> +    if 'interface' in bgp: +        for interface in bgp['interface']: +            tmp = get_interface_config(interface) +            if dict_search('linkinfo.info_slave_kind', tmp) and \ +                    tmp['linkinfo']['info_slave_kind'] == 'vrf': +                if 'master' in tmp: +                    bgp['interface'][interface]['applied_vrf'] = tmp['master'] +            else: +                bgp['interface'][interface]['applied_vrf'] = 'default'      # Assign the name of our VRF context. This MUST be done before the return      # statement below, else on deletion we will delete the default instance @@ -231,6 +247,23 @@ def verify(bgp):      if 'system_as' not in bgp:          raise ConfigError('BGP system-as number must be defined!') +    # Verify vrf on interface and bgp section +    if 'interface' in bgp: +        for interface in dict_search('interface', bgp): +            if dict_search(f'interface.{interface}.mpls', bgp): +                if 'forwarding' in bgp['interface'][interface]['mpls']: +                    if 'vrf' in bgp: +                        if bgp['interface'][interface]['applied_vrf'] != bgp['vrf']: +                            raise ConfigError( +                                f'Can not set mpls forwarding. Interface {interface} in different vrf') +                    else: +                        if bgp['interface'][interface]['applied_vrf'] != 'default': +                            raise ConfigError( +                                f'Can not set mpls forwarding. Interface {interface} in different vrf') +            else: +                raise ConfigError( +                    f'<protocols bgp interface {interface}> command should have options') +      # Common verification for both peer-group and neighbor statements      for neighbor in ['neighbor', 'peer_group']:          # bail out early if there is no neighbor or peer-group statement @@ -520,6 +553,14 @@ def apply(bgp):          vrf = ' vrf ' + bgp['vrf']      frr_cfg.load_configuration(bgp_daemon) + +    #If bgp interface config removed +    for key in ['interface', 'interface_removed']: +        if key not in bgp: +            continue +        for interface in bgp[key]: +            frr_cfg.modify_section(f'^interface {interface}', stop_pattern='^exit', remove_stop_mark=True) +      frr_cfg.modify_section(f'^router bgp \d+{vrf}', stop_pattern='^exit', remove_stop_mark=True)      if 'frr_bgpd_config' in bgp:          frr_cfg.add_before(frr.default_add_before, bgp['frr_bgpd_config']) diff --git a/src/etc/systemd/system-generators/vyos-generator b/src/etc/systemd/system-generators/vyos-generator new file mode 100755 index 000000000..34faab6a2 --- /dev/null +++ b/src/etc/systemd/system-generators/vyos-generator @@ -0,0 +1,94 @@ +#!/bin/sh +set -f + +LOG="" +DEBUG_LEVEL=1 +LOG_D="/run/vyos-router" +ENABLE="enabled" +DISABLE="disabled" +FOUND="found" +NOTFOUND="notfound" +RUN_ENABLED_FILE="$LOG_D/$ENABLE" +VYOS_SYSTEM_TARGET="/lib/systemd/system/vyos.target" +VYOS_TARGET_NAME="vyos.target" + +debug() { +    local lvl="$1" +    shift +    [ "$lvl" -gt "$DEBUG_LEVEL" ] && return +    if [ -z "$LOG" ]; then +        local log="$LOG_D/${0##*/}.log" +        { [ -d "$LOG_D" ] || mkdir -p "$LOG_D"; } && +            { : > "$log"; } >/dev/null 2>&1 && LOG="$log" || +            LOG="/dev/kmsg" +    fi +    echo "$@" >> "$LOG" +} + +default() { +    _RET="$ENABLE" +} + +main() { +    local normal_d="$1" early_d="$2" late_d="$3" +    local target_name="multi-user.target" gen_d="$early_d" +    local link_path="$gen_d/${target_name}.wants/${VYOS_TARGET_NAME}" +    local ds="$NOTFOUND" + +    debug 1 "$0 normal=$normal_d early=$early_d late=$late_d" +    debug 2 "$0 $*" + +    local search result="error" ret="" +    for search in default; do +        if $search; then +            debug 1 "$search found $_RET" +            [ "$_RET" = "$ENABLE" -o "$_RET" = "$DISABLE" ] && +                result=$_RET && break +        else +            ret=$? +            debug 0 "search $search returned $ret" +        fi +    done + +    # enable AND ds=found == enable +    # enable AND ds=notfound == disable +    # disable || <any> == disabled +    if [ "$result" = "$ENABLE" ]; then +        if [ -e "$link_path" ]; then +                debug 1 "already enabled: no change needed" +        else +            [ -d "${link_path%/*}" ] || mkdir -p "${link_path%/*}" || +                debug 0 "failed to make dir $link_path" +            if ln -snf "$VYOS_SYSTEM_TARGET" "$link_path"; then +                debug 1 "enabled via $link_path -> $VYOS_SYSTEM_TARGET" +            else +                ret=$? +                debug 0 "[$ret] enable failed:" \ +                    "ln $VYOS_SYSTEM_TARGET $link_path" +            fi +        fi +        : > "$RUN_ENABLED_FILE" +    elif [ "$result" = "$DISABLE" ]; then +        if [ -f "$link_path" ]; then +            if rm -f "$link_path"; then +                debug 1 "disabled. removed existing $link_path" +            else +                ret=$? +                debug 0 "[$ret] disable failed, remove $link_path" +            fi +        else +            debug 1 "already disabled: no change needed [no $link_path]" +        fi +        if [ -e "$RUN_ENABLED_FILE" ]; then +            rm -f "$RUN_ENABLED_FILE" +        fi +    else +        debug 0 "unexpected result '$result' 'ds=$ds'" +        ret=3 +    fi +    return $ret +} + +main "$@" + +# vi: ts=4 expandtab diff --git a/src/etc/systemd/system/getty@.service.d/aftervyos.conf b/src/etc/systemd/system/getty@.service.d/aftervyos.conf new file mode 100644 index 000000000..c5753900e --- /dev/null +++ b/src/etc/systemd/system/getty@.service.d/aftervyos.conf @@ -0,0 +1,3 @@ +[Service] +ExecStartPre=-/usr/libexec/vyos/init/vyos-config +StandardOutput=journal+console diff --git a/src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf b/src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf new file mode 100644 index 000000000..8ba42778d --- /dev/null +++ b/src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf @@ -0,0 +1,3 @@ +[Service] +ExecStartPre=-/usr/libexec/vyos/init/vyos-config SERIAL +StandardOutput=journal+console diff --git a/src/helpers/vyos_config_sync.py b/src/helpers/vyos_config_sync.py index 6e66a6be0..7cfa8fe88 100755 --- a/src/helpers/vyos_config_sync.py +++ b/src/helpers/vyos_config_sync.py @@ -24,6 +24,7 @@ import logging  from typing import Optional, List, Union, Dict, Any  from vyos.config import Config +from vyos.template import bracketize_ipv6  CONFIG_FILE = '/run/config_sync_conf.conf' @@ -175,6 +176,7 @@ if __name__ == '__main__':      mode = config.get('mode')      secondary_address = config.get('secondary', {}).get('address') +    secondary_address = bracketize_ipv6(secondary_address)      secondary_key = config.get('secondary', {}).get('key')      sections = config.get('section')      timeout = int(config.get('secondary', {}).get('timeout')) diff --git a/src/init/vyos-config b/src/init/vyos-config new file mode 100755 index 000000000..356427024 --- /dev/null +++ b/src/init/vyos-config @@ -0,0 +1,16 @@ +#!/bin/bash + +while [ ! -f /tmp/vyos-config-status ] +do +  sleep 1 +done + +status=$(cat /tmp/vyos-config-status) + +if [ -z "$1" ]; then +  if [ $status -ne 0 ]; then +    echo "Configuration error" +  else +    echo "Configuration success" +  fi +fi diff --git a/src/init/vyos-router b/src/init/vyos-router new file mode 100755 index 000000000..7b752b84b --- /dev/null +++ b/src/init/vyos-router @@ -0,0 +1,421 @@ +#!/bin/bash +# Copyright (C) 2021 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +. /lib/lsb/init-functions + +: ${vyatta_env:=/etc/default/vyatta} +source $vyatta_env + +declare progname=${0##*/} +declare action=$1; shift + +declare -x BOOTFILE=$vyatta_sysconfdir/config/config.boot + +# If vyos-config= boot option is present, use that file instead +for x in $(cat /proc/cmdline); do +    [[ $x = vyos-config=* ]] || continue +    VYOS_CONFIG="${x#vyos-config=}" +done + +if [ ! -z "$VYOS_CONFIG" ]; then +    if [ -r "$VYOS_CONFIG" ]; then +        echo "Config selected manually: $VYOS_CONFIG" +        declare -x BOOTFILE="$VYOS_CONFIG" +    else +        echo "WARNING: Could not read selected config file, using default!" +    fi +fi + +declare -a subinit +declare -a all_subinits=( firewall ) + +if [ $# -gt 0 ] ; then +    for s in $@ ; do +        [ -x ${vyatta_sbindir}/${s}.init ] && subinit[${#subinit}]=$s +    done +else +    for s in ${all_subinits[@]} ; do +        [ -x ${vyatta_sbindir}/${s}.init ] && subinit[${#subinit}]=$s +    done +fi + +GROUP=vyattacfg + +# easy way to make empty file without any command +empty() +{ +    >$1 +} + +# check if bootup of this portion is disabled +disabled () { +    grep -q -w no-vyos-$1 /proc/cmdline +} + +# if necessary, provide initial config +init_bootfile () { +    if [ ! -r $BOOTFILE ] ; then +        if [ -f $vyatta_sysconfdir/config.boot.default ]; then +            cp $vyatta_sysconfdir/config.boot.default $BOOTFILE +        else +            $vyos_libexec_dir/system-versions-foot.py > $BOOTFILE +        fi +        chgrp ${GROUP} $BOOTFILE +        chmod 660 $BOOTFILE +    fi +} + +# if necessary, migrate initial config +migrate_bootfile () +{ +    if [ -x $vyos_libexec_dir/run-config-migration.py ]; then +        log_progress_msg migrate +        sg ${GROUP} -c "$vyos_libexec_dir/run-config-migration.py $BOOTFILE" +    fi +} + +# load the initial config +load_bootfile () +{ +    log_progress_msg configure +    ( +        if [ -f /etc/default/vyatta-load-boot ]; then +            # build-specific environment for boot-time config loading +            source /etc/default/vyatta-load-boot +        fi +        if [ -x $vyos_libexec_dir/vyos-boot-config-loader.py ]; then +            sg ${GROUP} -c "$vyos_libexec_dir/vyos-boot-config-loader.py $BOOTFILE" +        fi +    ) +} + +# execute the pre-config script +run_preconfig_script () +{ +    if [ -x $vyatta_sysconfdir/config/scripts/vyos-preconfig-bootup.script ]; then +        $vyatta_sysconfdir/config/scripts/vyos-preconfig-bootup.script +    fi +} + +# execute the post-config scripts +run_postconfig_scripts () +{ +    if [ -x $vyatta_sysconfdir/config/scripts/vyatta-postconfig-bootup.script ]; then +        $vyatta_sysconfdir/config/scripts/vyatta-postconfig-bootup.script +    fi +    if [ -x $vyatta_sysconfdir/config/scripts/vyos-postconfig-bootup.script ]; then +        $vyatta_sysconfdir/config/scripts/vyos-postconfig-bootup.script +    fi +} + +run_postupgrade_script () +{ +    if [ -f $vyatta_sysconfdir/config/.upgraded ]; then +        # Run the system script +        /usr/libexec/vyos/system/post-upgrade + +        # Run user scripts +        if [ -d $vyatta_sysconfdir/config/scripts/post-upgrade.d ]; then +            run-parts $vyatta_sysconfdir/config/scripts/post-upgrade.d +        fi +        rm -f $vyatta_sysconfdir/config/.upgraded +    fi +} + +# +# On image booted machines, we need to mount /boot from the image-specific +# boot directory so that kernel package installation will put the +# files in the right place.  We also have to mount /boot/grub from the +# system-wide grub directory so that tools that edit the grub.cfg +# file will find it in the expected location. +# +bind_mount_boot () +{ +    persist_path=$(/opt/vyatta/sbin/vyos-persistpath) +    if [ $? == 0 ]; then +        if [ -e $persist_path/boot ]; then +            image_name=$(cat /proc/cmdline | sed -e s+^.*vyos-union=/boot/++ | sed -e 's/ .*$//') + +            if [ -n "$image_name" ]; then +                mount --bind $persist_path/boot/$image_name /boot +                if [ $? -ne 0 ]; then +                    echo "Couldn't bind mount /boot" +                fi + +                if [ ! -d /boot/grub ]; then +                    mkdir /boot/grub +                fi + +                mount --bind $persist_path/boot/grub /boot/grub +                if [ $? -ne 0 ]; then +                    echo "Couldn't bind mount /boot/grub" +                fi +            fi +        fi +    fi +} + +clear_or_override_config_files () +{ +    for conf in snmp/snmpd.conf snmp/snmptrapd.conf snmp/snmp.conf \ +        keepalived/keepalived.conf cron.d/vyos-crontab \ +        ipvsadm.rules default/ipvsadm resolv.conf +    do +    if [ -s /etc/$conf ] ; then +        empty /etc/$conf +        chmod 0644 /etc/$conf +    fi +    done +} + +update_interface_config () +{ +    if [ -d /run/udev/vyos ]; then +        $vyos_libexec_dir/vyos-interface-rescan.py $BOOTFILE +    fi +} + +cleanup_post_commit_hooks () { +    # Remove links from the post-commit hooks directory. +    # note that this approach only supports hooks that are "configured", +    # i.e., it does not support hooks that need to always be present. +    cpostdir=$(cli-shell-api getPostCommitHookDir) +    # exclude commits hooks from vyatta-cfg +    excluded="10vyatta-log-commit.pl 99vyos-user-postcommit-hooks" +    if [ -d "$cpostdir" ]; then +	    for f in $cpostdir/*; do +	        if [[ ! $excluded =~ $(basename $f) ]]; then +		        rm -f $cpostdir/$(basename $f) +	        fi +	    done +    fi +} + +# These are all the default security setting which are later +# overridden when configuration is read. These are the values the +# system defaults. +security_reset () +{ +    # restore PAM back to virgin state (no radius/tacacs services) +    pam-auth-update --package --remove radius +    rm -f /etc/pam_radius_auth.conf +    pam-auth-update --package --remove tacplus +    rm -f /etc/tacplus_nss.conf /etc/tacplus_servers + +    # Certain configuration files are re-generated by the configuration +    # subsystem and must reside under /etc and can not easily be moved to /run. +    # So on every boot we simply delete any remaining files and let the CLI +    # regenearte them. + +    # PPPoE +    rm -f /etc/ppp/peers/pppoe* /etc/ppp/peers/wlm* + +    # IPSec +    rm -rf /etc/ipsec.conf /etc/ipsec.secrets +    find /etc/swanctl -type f | xargs rm -f + +    # limit cleanup +    rm -f /etc/security/limits.d/10-vyos.conf + +    # iproute2 cleanup +    rm -f /etc/iproute2/rt_tables.d/vyos-*.conf + +    # Container +    rm -f /etc/containers/storage.conf /etc/containers/registries.conf /etc/containers/containers.conf +    # Clean all networks and re-create them from our CLI +    rm -f /etc/containers/networks/* + +    # System Options (SSH/cURL) +    rm -f /etc/ssh/ssh_config.d/*vyos*.conf +    rm -f /etc/curlrc +} + +# XXX: T3885 - generate persistend DHCPv6 DUID (Type4 - UUID based) +gen_duid () +{ +    DUID_FILE="/var/lib/dhcpv6/dhcp6c_duid" +    UUID_FILE="/sys/class/dmi/id/product_uuid" +    UUID_FILE_ALT="/sys/class/dmi/id/product_serial" +    if [ ! -f ${UUID_FILE} ] && [ ! -f ${UUID_FILE_ALT} ]; then +        return 1 +    fi + +    # DUID is based on the BIOS/EFI UUID. We omit additional - characters +    if [ -f ${UUID_FILE} ]; then +        UUID=$(cat ${UUID_FILE} | tr -d -) +    fi +    if [ -z ${UUID} ]; then +        UUID=$(uuidgen --sha1 --namespace @dns --name $(cat ${UUID_FILE_ALT}) | tr -d -) +    fi +    # Add DUID type4 (UUID) information +    DUID_TYPE="0004" + +    # The length-information (as per RFC6355 UUID is 128 bits long) is in big-endian +    # format - beware when porting to ARM64. The length field consists out of the +    # UUID (128 bit + 16 bits DUID type) resulting in hex 12. +    DUID_LEN="0012" +    if [ "$(echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6 )" -eq 1 ]; then +        # true on little-endian (x86) systems +        DUID_LEN="1200" +    fi + +    for i in $(echo -n ${DUID_LEN}${DUID_TYPE}${UUID} | sed 's/../& /g'); do +        echo -ne "\x$i" +    done > ${DUID_FILE} +} + +start () +{ +    # reset and clean config files +    security_reset || log_failure_msg "security reset failed" + +    # some legacy directories migrated over from old rl-system.init +    mkdir -p /var/run/vyatta /var/log/vyatta +    chgrp vyattacfg /var/run/vyatta /var/log/vyatta +    chmod 775 /var/run/vyatta /var/log/vyatta + +    log_daemon_msg "Waiting for NICs to settle down" +    # On boot time udev migth take a long time to reorder nic's, this will ensure that +    # all udev activity is completed and all nics presented at boot-time will have their +    # final name before continuing with vyos-router initialization. +    SECONDS=0 +    udevadm settle +    STATUS=$? +    log_progress_msg "settled in ${SECONDS}sec." +    log_end_msg ${STATUS} + +    # mountpoint for bpf maps required by xdp +    mount -t bpf none /sys/fs/bpf + +    # Clear out Debian APT source config file +    empty /etc/apt/sources.list + +    # Generate DHCPv6 DUID +    gen_duid || log_failure_msg "could not generate DUID" + +    # Mount a temporary filesystem for container networks. +    # Configuration should be loaded from VyOS cli. +    cni_dir="/etc/cni/net.d" +    [ ! -d ${cni_dir} ] && mkdir -p ${cni_dir} +    mount -t tmpfs none ${cni_dir} + +    # Init firewall +    nfct helper add rpc inet tcp +    nfct helper add rpc inet udp +    nfct helper add tns inet tcp +    nft -f /usr/share/vyos/vyos-firewall-init.conf || log_failure_msg "could not initiate firewall rules" + +    rm -f /etc/hostname +    ${vyos_conf_scripts_dir}/host_name.py || log_failure_msg "could not reset host-name" +    systemctl start frr.service + +    # As VyOS does not execute commands that are not present in the CLI we call +    # the script by hand to have a single source for the login banner and MOTD +    ${vyos_conf_scripts_dir}/system_console.py || log_failure_msg "could not reset serial console" +    ${vyos_conf_scripts_dir}/system-login.py || log_failure_msg "could not reset system login" +    ${vyos_conf_scripts_dir}/system-login-banner.py || log_failure_msg "could not reset motd and issue files" +    ${vyos_conf_scripts_dir}/system-option.py || log_failure_msg "could not reset system option files" +    ${vyos_conf_scripts_dir}/conntrack.py || log_failure_msg "could not reset conntrack subsystem" +    ${vyos_conf_scripts_dir}/container.py || log_failure_msg "could not reset container subsystem" + +    clear_or_override_config_files || log_failure_msg "could not reset config files" + +    # enable some debugging before loading the configuration +    if grep -q vyos-debug /proc/cmdline; then +        log_action_begin_msg "Enable runtime debugging options" +        touch /tmp/vyos.container.debug +        touch /tmp/vyos.ifconfig.debug +        touch /tmp/vyos.frr.debug +        touch /tmp/vyos.container.debug +    fi + +    log_action_begin_msg "Mounting VyOS Config" +    # ensure the vyatta_configdir supports a large number of inodes since +    # the config hierarchy is often inode-bound (instead of size). +    # impose a minimum and then scale up dynamically with the actual size +    # of the system memory. +    local tmem=$(sed -n 's/^MemTotal: \+\([0-9]\+\) kB$/\1/p' /proc/meminfo) +    local tpages +    local tmpfs_opts="nosuid,nodev,mode=775,nr_inodes=0" #automatically allocate inodes +    mount -o $tmpfs_opts -t tmpfs none ${vyatta_configdir} \ +      && chgrp ${GROUP} ${vyatta_configdir} +    log_action_end_msg $? + +    disabled bootfile || init_bootfile + +    cleanup_post_commit_hooks + +    log_daemon_msg "Starting VyOS router" +    disabled migrate || migrate_bootfile + +    run_preconfig_script + +    run_postupgrade_script + +    update_interface_config + +    for s in ${subinit[@]} ; do +    if ! disabled $s; then +        log_progress_msg $s +        if ! ${vyatta_sbindir}/${s}.init start +        then log_failure_msg +         exit 1 +        fi +    fi +    done + +    bind_mount_boot + +    disabled configure || load_bootfile +    log_end_msg $? + +    telinit q +    chmod g-w,o-w / + +    run_postconfig_scripts +} + +stop() +{ +    local -i status=0 +    log_daemon_msg "Stopping VyOS router" +    for ((i=${#sub_inits[@]} - 1; i >= 0; i--)) ; do +    s=${subinit[$i]} +    log_progress_msg $s +    ${vyatta_sbindir}/${s}.init stop +    let status\|=$? +    done +    log_end_msg $status +    log_action_begin_msg "Un-mounting VyOS Config" +    umount ${vyatta_configdir} +    log_action_end_msg $? + +    systemctl stop frr.service +} + +case "$action" in +    start) start ;; +    stop)  stop ;; +    restart|force-reload) stop && start ;; +    *)  log_failure_msg "usage: $progname [ start|stop|restart ] [ subinit ... ]" ; +    false ;; +esac + +exit $? + +# Local Variables: +# mode: shell-script +# sh-indentation: 4 +# End: diff --git a/src/migration-scripts/vrrp/3-to-4 b/src/migration-scripts/vrrp/3-to-4 new file mode 100755 index 000000000..b0a6975c2 --- /dev/null +++ b/src/migration-scripts/vrrp/3-to-4 @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2023 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +from sys import argv +from vyos.configtree import ConfigTree + +if (len(argv) < 1): +    print('Must specify file name!') +    exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: +    config_file = f.read() + +base = ['high-availability', 'virtual-server'] +config = ConfigTree(config_file) + +if not config.exists(base): +    # Nothing to do +    exit(0) + +if config.exists(base): +    for vs in config.list_nodes(base): +        vs_base = base + [vs] + +        # If the fwmark is used, the address is not required +        if not config.exists(vs_base + ['fwmark']): +            # add option: 'virtual-server <tag> address x.x.x.x' +            config.set(vs_base + ['address'], value=vs) + + +try: +    with open(file_name, 'w') as f: +        f.write(config.to_string()) +except OSError as e: +    print(f'Failed to save the modified config: {e}') +    exit(1) diff --git a/src/op_mode/pki.py b/src/op_mode/pki.py index b054690b0..7ea295ff1 100755 --- a/src/op_mode/pki.py +++ b/src/op_mode/pki.py @@ -840,7 +840,7 @@ def import_openvpn_secret(name, path):      install_openvpn_key(name, key_data, key_version)  # Show functions -def show_certificate_authority(name=None): +def show_certificate_authority(name=None, pem=False):      headers = ['Name', 'Subject', 'Issuer CN', 'Issued', 'Expiry', 'Private Key', 'Parent']      data = []      certs = get_config_ca_certificate() @@ -852,6 +852,11 @@ def show_certificate_authority(name=None):                  continue              cert = load_certificate(cert_dict['certificate']) + +            if name and pem: +                print(encode_certificate(cert)) +                return +              parent_ca_name = get_certificate_ca(cert, certs)              cert_issuer_cn = cert.issuer.rfc4514_string().split(",")[0] @@ -867,7 +872,7 @@ def show_certificate_authority(name=None):      print("Certificate Authorities:")      print(tabulate.tabulate(data, headers)) -def show_certificate(name=None): +def show_certificate(name=None, pem=False):      headers = ['Name', 'Type', 'Subject CN', 'Issuer CN', 'Issued', 'Expiry', 'Revoked', 'Private Key', 'CA Present']      data = []      certs = get_config_certificate() @@ -885,6 +890,10 @@ def show_certificate(name=None):              if not cert:                  continue +            if name and pem: +                print(encode_certificate(cert)) +                return +              ca_name = get_certificate_ca(cert, ca_certs)              cert_subject_cn = cert.subject.rfc4514_string().split(",")[0]              cert_issuer_cn = cert.issuer.rfc4514_string().split(",")[0] @@ -906,7 +915,7 @@ def show_certificate(name=None):      print("Certificates:")      print(tabulate.tabulate(data, headers)) -def show_crl(name=None): +def show_crl(name=None, pem=False):      headers = ['CA Name', 'Updated', 'Revokes']      data = []      certs = get_config_ca_certificate() @@ -927,9 +936,16 @@ def show_crl(name=None):                  if not crl:                      continue +                if name and pem: +                    print(encode_certificate(crl)) +                    continue +                  certs = get_revoked_by_serial_numbers([revoked.serial_number for revoked in crl])                  data.append([cert_name, crl.last_update, ", ".join(certs)]) +    if name and pem: +        return +      print("Certificate Revocation Lists:")      print(tabulate.tabulate(data, headers)) @@ -943,6 +959,7 @@ if __name__ == '__main__':      parser.add_argument('--crl', help='Certificate Revocation List', required=False)      parser.add_argument('--sign', help='Sign certificate with specified CA', required=False)      parser.add_argument('--self-sign', help='Self-sign the certificate', action='store_true') +    parser.add_argument('--pem', help='Output using PEM encoding', action='store_true')      # SSH      parser.add_argument('--ssh', help='SSH Key', required=False) @@ -1032,16 +1049,16 @@ if __name__ == '__main__':                      if not conf.exists(['pki', 'ca', ca_name]):                          print(f'CA "{ca_name}" does not exist!')                          exit(1) -                show_certificate_authority(ca_name) +                show_certificate_authority(ca_name, args.pem)              elif args.certificate:                  cert_name = None if args.certificate == 'all' else args.certificate                  if cert_name:                      if not conf.exists(['pki', 'certificate', cert_name]):                          print(f'Certificate "{cert_name}" does not exist!')                          exit(1) -                show_certificate(None if args.certificate == 'all' else args.certificate) +                show_certificate(None if args.certificate == 'all' else args.certificate, args.pem)              elif args.crl: -                show_crl(None if args.crl == 'all' else args.crl) +                show_crl(None if args.crl == 'all' else args.crl, args.pem)              else:                  show_certificate_authority()                  show_certificate() diff --git a/src/systemd/vyos-router.service b/src/systemd/vyos-router.service new file mode 100644 index 000000000..6f683cebb --- /dev/null +++ b/src/systemd/vyos-router.service @@ -0,0 +1,19 @@ +[Unit] +Description=VyOS Router +After=systemd-journald-dev-log.socket time-sync.target local-fs.target cloud-config.service +Requires=frr.service +Conflicts=shutdown.target +Before=systemd-user-sessions.service + +[Service] +Type=simple +Restart=no +TimeoutSec=20min +KillMode=process +RemainAfterExit=yes +ExecStart=/usr/libexec/vyos/init/vyos-router start +ExecStop=/usr/libexec/vyos/init/vyos-router stop +StandardOutput=journal+console + +[Install] +WantedBy=vyos.target diff --git a/src/systemd/vyos.target b/src/systemd/vyos.target new file mode 100644 index 000000000..47c91c1cc --- /dev/null +++ b/src/systemd/vyos.target @@ -0,0 +1,3 @@ +[Unit] +Description=VyOS target +After=multi-user.target | 
