diff options
Diffstat (limited to 'src/etc')
-rw-r--r-- | src/etc/bash_completion.d/vyatta-op | 685 | ||||
-rw-r--r-- | src/etc/default/vyatta | 217 | ||||
-rwxr-xr-x | src/etc/ipsec.d/vti-up-down | 53 | ||||
-rwxr-xr-x | src/etc/netplug/vyos-netplug-dhcp-client | 43 | ||||
-rwxr-xr-x | src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb | 61 | ||||
-rw-r--r-- | src/etc/rsyslog.conf | 67 | ||||
-rw-r--r-- | src/etc/skel/.bashrc | 3 | ||||
-rw-r--r-- | src/etc/sudoers.d/vyos | 9 | ||||
-rw-r--r-- | src/etc/sysctl.d/30-vyos-router.conf | 5 | ||||
-rw-r--r-- | src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf | 10 | ||||
-rw-r--r-- | src/etc/systemd/system/kea-dhcp4-server.service.d/override.conf | 7 | ||||
-rw-r--r-- | src/etc/systemd/system/kea-dhcp6-server.service.d/override.conf | 7 | ||||
-rw-r--r-- | src/etc/systemd/system/rsyslog.service.d/override.conf | 10 | ||||
-rw-r--r-- | src/etc/systemd/system/suricata.service.d/10-override.conf | 9 | ||||
-rw-r--r-- | src/etc/udev/rules.d/90-vyos-serial.rules | 2 |
15 files changed, 1069 insertions, 119 deletions
diff --git a/src/etc/bash_completion.d/vyatta-op b/src/etc/bash_completion.d/vyatta-op new file mode 100644 index 000000000..8ac2d9b20 --- /dev/null +++ b/src/etc/bash_completion.d/vyatta-op @@ -0,0 +1,685 @@ +# vyatta bash operational mode completion +# **** License **** +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 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. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Tom Grennan +# Date: 2007 +# Description: setup bash completion for Vyatta operational commands +# +# **** End License **** + +test -z "$_vyatta_less_options" && \ + declare -r _vyatta_less_options="\ + --QUIT-AT-EOF\ + --quit-if-one-screen\ + --RAW-CONTROL-CHARS\ + --squeeze-blank-lines\ + --no-init" +test -z "$_vyatta_default_pager" && \ + declare -r _vyatta_default_pager="less \ + --buffers=64\ + --auto-buffers\ + --no-lessopen\ + $_vyatta_less_options" +test -z "$VYATTA_PAGER" && \ + declare -x VYATTA_PAGER=$_vyatta_default_pager + +_vyatta_op_do_key_bindings () +{ + if [[ "$SHELL" != "/bin/vbash" && "$SHELL" != "/sbin/radius_shell" ]]; then + # only do bindings if vbash and radius_shell + return + fi + nullglob_save=$(shopt -p nullglob) + shopt -u nullglob + case "$-" in + *i*) + bind '"?": possible-completions' + bind 'set show-all-if-ambiguous on' + bind_cmds=$(grep '^bind .* # vyatta key binding$' $HOME/.bashrc) + eval $bind_cmds + ;; + esac + eval $nullglob_save +} + +_vyatta_op_do_key_bindings + +test -f /etc/default/vyatta && \ + source /etc/default/vyatta + +test ! -d "$vyatta_op_templates" && \ + return 0 + +case "$-" in + *i*) + declare -r _vyatta_op_last_comp_init='>>>>>>LASTCOMP<<<<<<' + ;; +esac +declare _vyatta_op_last_comp=${_vyatta_op_last_comp_init} +declare _vyatta_op_node_path +declare -a _vyatta_op_noncompletions _vyatta_op_completions +declare -x -a _vyatta_pipe_noncompletions _vyatta_pipe_completions +declare _vyatta_comptype +declare -x -a reply +declare -a _vyatta_operator_allowed + +if [[ "$VYATTA_USER_LEVEL_DIR" != "/opt/vyatta/etc/shell/level/admin" ]]; then + _vyatta_operator_allowed=( $(cat $VYATTA_USER_LEVEL_DIR/allowed-op) ) +fi + +declare -a functions +functions=( /opt/vyatta/share/vyatta-op/functions/interpreter/* ) + +for file in "${functions[@]}";do + source $file; +done + +# $1: label +# #2...: strings +_vyatta_op_debug () +{ + echo -ne \\n$1: + shift + for s ; do + echo -ne " \"$s\"" + done +} + +# this is needed to provide original "default completion" behavior. +# see "vyatta-cfg" completion script for details. +_vyatta_op_default_expand () +{ + local wc=${#COMP_WORDS[@]} + if [[ "${COMP_WORDS[0]}" =~ "/" ]]; then + # if we are looking for a directory on the first completion then do directory completions + _filedir_xspec_vyos + elif (( wc < 2 )) || + [[ $COMP_CWORD -eq 0 ]] || + [[ $1 == $2 ]]; then + _vyatta_op_expand "$@" + else + # after the first word => cannot be vyatta command so use original default + _filedir_xspec_vyos + fi +} + +# $1: label +# $2...: help +_vyatta_op_print_help () +{ + local label=$1 help=$2 + if [ ${#label} -eq 0 ] ; then + return + elif [ ${#help} -eq 0 ] ; then + echo -ne "\n $label" + elif [ ${#label} -lt 6 ] ; then + echo -ne "\n $label\t\t\t$help" + elif [ ${#label} -lt 14 ] ; then + echo -ne "\n $label\t\t$help" + elif [ ${#label} -lt 21 ] ; then + echo -ne "\n $label\t$help" + else + echo -ne "\n $label\n\t\t\t$help" + fi +} + +# $1: $cur +# $2...: possible completions +_vyatta_op_help () +{ + local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; ) + shopt -u nullglob + local cur=$1; shift + local ndef node_tag_help node_run help last_help + + ndef=${_vyatta_op_node_path}/node.tag/node.def + [ -f $ndef ] && \ + node_tag_help=$( _vyatta_op_get_node_def_field $ndef help ) + + ndef=${_vyatta_op_node_path}/node.def + [ -f $ndef ] && \ + node_run=$( _vyatta_op_get_node_def_field $ndef run ) + + if [[ "$1" == "<nocomps>" ]]; then + eval "$restore_shopts" + return + fi + echo -en "\nPossible completions:" + if [ -z "$cur" -a -n "$node_run" ]; then + _vyatta_op_print_help '<Enter>' "Execute the current command" + fi + if [ $# -eq 0 ];then + _vyatta_op_print_help '<text>' "$node_tag_help" + eval "$restore_shopts" + return + fi + for comp ; do + if [[ "$comp" == "<Enter>" ]]; then + continue + fi + if [ -z "$comp" ] ; then + if [ "X$node_tag_help" == "X$last_help" ] ; then + help="" + else + last_help=$node_tag_help + help=$node_tag_help + fi + _vyatta_op_print_help '*' "$help" + elif [[ -z "$cur" || $comp == ${cur}* ]] ; then + ndef=${_vyatta_op_node_path}/$comp/node.def + if [ -f $ndef ] ; then + help=$( _vyatta_op_get_node_def_field $ndef help ) + else + help=$node_tag_help + fi + if [ "X$help" == "X$last_help" ] ; then + help="" + else + last_help=$help + fi + _vyatta_op_print_help "$comp" "$help" + fi + done + eval "$restore_shopts" +} + +_vyatta_op_set_node_path () +{ + local node + _vyatta_op_node_path=$vyatta_op_templates + for (( i=0 ; i<COMP_CWORD ; i++ )) ; do + # expand the command so completion continues to work with short versions + if [[ "${COMP_WORDS[i]}" == "*" ]]; then + node="node.tag" # user defined wildcars are always tag nodes + else + node=$(_vyatta_op_conv_node_path $_vyatta_op_node_path ${COMP_WORDS[i]}) + fi + if [ -f "${_vyatta_op_node_path}/$node/node.def" ] ; then + _vyatta_op_node_path+=/$node + elif [ -f ${_vyatta_op_node_path}/node.tag/node.def ] ; then + _vyatta_op_node_path+=/node.tag + else + return 1 + fi + done +} + +_vyatta_op_set_completions () +{ + local -a allowed completions + local cur=$1 + local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; ) + for ndef in ${_vyatta_op_node_path}/*/node.def ; do + if [[ $ndef == */node.tag/node.def ]] ; then + local acmd=$( _vyatta_op_get_node_def_field $ndef allowed ) + shopt -u extglob nullglob + local -a a=($( eval "$acmd" )) + eval "$restore_shopts" + + if [ ${#a[@]} -ne 0 ] ; then + allowed+=( "${a[@]}" ) + else + allowed+=( "<text>" ) + fi + else + local sdir=${ndef%/*} + allowed+=( ${sdir##*/} ) + fi + done + + # donot complete entries like <HOSTNAME> or <A.B.C.D> + _vyatta_op_noncompletions=( ) + completions=( ) + + # make runable commands have a non-comp + ndef=${_vyatta_op_node_path}/node.def + [ -f $ndef ] && \ + node_run=$( _vyatta_op_get_node_def_field $ndef run ) + if [ -z "$cur" -a -n "$node_run" ]; then + _vyatta_op_noncompletions+=('<Enter>') + fi + + for (( i=0 ; i<${#allowed[@]} ; i++ )) ; do + if [[ "${allowed[i]}" == \<*\> ]] ; then + _vyatta_op_noncompletions+=( "${allowed[i]}" ) + else + if [[ "$VYATTA_USER_LEVEL_DIR" == "/opt/vyatta/etc/shell/level/admin" ]]; then + completions+=( ${allowed[i]} ) + elif is_elem_of ${allowed[i]} _vyatta_operator_allowed; then + completions+=( ${allowed[i]} ) + elif [[ $_vyatta_op_node_path == $vyatta_op_templates ]];then + continue + else + completions+=( ${allowed[i]} ) + fi + fi + done + + # Prefix filter the non empty completions + if [ -n "$cur" ]; then + _vyatta_op_completions=() + get_prefix_filtered_list "$cur" completions _vyatta_op_completions + _vyatta_op_completions=($( printf "%s\n" ${_vyatta_op_completions[@]} | sort -u )) + else + _vyatta_op_completions=($( printf "%s\n" ${completions[@]} | sort -u )) + fi + #shopt -s nullglob +} + +_vyatta_op_comprely_needs_ambiguity () +{ + local -a uniq + + [ ${#COMPREPLY[@]} -eq 1 ] && return + + uniq=( `printf "%s\n" ${COMPREPLY[@]} | cut -c1 | sort -u` ) + + [ ${#uniq[@]} -eq 1 ] && return + false +} + +_vyatta_op_invalid_completion () +{ + local tpath=$vyatta_op_templates + local -a args + local i=1 + for arg in "${COMP_WORDS[@]}"; do + arg=( $(_vyatta_op_conv_node_path $tpath $arg) ) # expand the arguments + # output proper error message based on the above expansion + if [[ "${arg[1]}" == "ambiguous" ]]; then + echo -ne "\n\n Ambiguous command: ${args[@]} [$arg]\n" + local -a cmds=( $(compgen -d $tpath/$arg) ) + _vyatta_op_node_path=$tpath + local comps=$(_vyatta_op_help $arg ${cmds[@]##*/}) + echo -ne "$comps" | sed -e 's/^P/ P/' + break + elif [[ "${arg[1]}" == "invalid" ]]; then + echo -ne "\n\n Invalid command: ${args[@]} [$arg]" + break + fi + + if [ -f "$tpath/$arg/node.def" ] ; then + tpath+=/$arg + elif [ -f $tpath/node.tag/node.def ] ; then + tpath+=/node.tag + else + echo -ne "\n\n Invalid command: ${args[@]} [$arg]" >&2 + break + fi + args[$i]=$arg + let "i+=1" + if [ $[${#COMP_WORDS[@]}+1] -eq $i ];then + _vyatta_op_help "" \ + "${_vyatta_op_noncompletions[@]}" \ + "${_vyatta_op_completions[@]}" \ + | ${VYATTA_PAGER:-cat} + fi + done +} + +_vyatta_op_expand () +{ + # We need nospace here and we have to append our own spaces + compopt -o nospace + + local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; ) + shopt -s extglob nullglob + local cur="" + local _has_comptype=0 + local current_prefix=$2 + local current_word=$3 + _vyatta_comptype="" + + if (( ${#COMP_WORDS[@]} > 0 )); then + cur=${COMP_WORDS[COMP_CWORD]} + else + (( COMP_CWORD = ${#COMP_WORDS[@]} )) + fi + + if _vyatta_pipe_completion "${COMP_WORDS[@]}"; then + if [ "${COMP_WORDS[*]}" == "$_vyatta_op_last_comp" ] || + [ ${#_vyatta_pipe_completions[@]} -eq 0 ]; then + _vyatta_do_pipe_help + COMPREPLY=( "" " " ) + _vyatta_op_last_comp=${_vyatta_op_last_comp_init} + else + COMPREPLY=( "${_vyatta_pipe_completions[@]}" ) + _vyatta_op_last_comp="${COMP_WORDS[*]}" + if [ ${#COMPREPLY[@]} -eq 1 ]; then + COMPREPLY=( "${COMPREPLY[0]} " ) + fi + fi + eval "$restore_shopts" + return + fi + + # this needs to be done on every completion even if it is the 'same' comp. + # The cursor can be at different places in the string. + # this will lead to unexpected cases if setting the node path isn't attempted + # each time. + if ! _vyatta_op_set_node_path ; then + echo -ne \\a + _vyatta_op_invalid_completion + COMPREPLY=( "" " " ) + eval "$restore_shopts" + return 1 + fi + + if [ "${COMP_WORDS[*]:0:$[$COMP_CWORD+1]}" != "$_vyatta_op_last_comp" ] ; then + _vyatta_set_comptype + case $_vyatta_comptype in + 'imagefiles') + _has_comptype=1 + _vyatta_image_file_complete + ;; + *) + _has_comptype=0 + if [[ -z "$current_word" ]]; then + _vyatta_op_set_completions $cur + else + _vyatta_op_set_completions $current_prefix + fi + ;; + esac + fi + if [[ $_has_comptype == 1 ]]; then + COMPREPLY=( "${_vyatta_op_completions[@]}" ) + else + COMPREPLY=($( compgen -W "${_vyatta_op_completions[*]}" -- $current_prefix )) + fi + + # if the last command line arg is empty and we have + # an empty completion option (meaning wild card), + # append a blank(s) to the completion array to force ambiguity + if [ -z "$current_prefix" -a -n "$current_word" ] || + [[ "${COMPREPLY[0]}" =~ "$cur" ]]; then + for comp ; do + if [ -z "$comp" ] ; then + if [ ${#COMPREPLY[@]} -eq 0 ] ; then + COMPREPLY=( " " "" ) + elif _vyatta_op_comprely_needs_ambiguity ; then + COMPREPLY+=( " " ) + fi + fi + done + fi + # Set this environment to enable and disable debugging on the fly + if [[ $DBG_OP_COMPS -eq 1 ]]; then + echo -e "\nCurrent: '$cur'" + echo -e "Current word: '$current_word'" + echo -e "Current prefix: '$current_prefix'" + echo "Number of comps: ${#_vyatta_op_completions[*]}" + echo "Number of non-comps: ${#_vyatta_op_noncompletions[*]}" + echo "_vyatta_op_completions: '${_vyatta_op_completions[*]}'" + echo "COMPREPLY: '${COMPREPLY[@]}'" + echo "CWORD: $COMP_CWORD" + echo "Last comp: '$_vyatta_op_last_comp'" + echo -e "Current comp: '${COMP_WORDS[*]:0:$[$COMP_CWORD+1]}'\n" + fi + + # This is non obvious... + # To have completion continue to work when working with words that aren't the last word, + # we have to set nospace at the beginning of this script and then append the spaces here. + if [ ${#COMPREPLY[@]} -eq 1 ] && + [[ $_has_comptype -ne 1 ]]; then + COMPREPLY=( "${COMPREPLY[0]} " ) + fi + # if there are no completions then handle invalid commands + if [ ${#_vyatta_op_noncompletions[@]} -eq 0 ] && + [ ${#_vyatta_op_completions[@]} -eq 0 ]; then + _vyatta_op_invalid_completion + COMPREPLY=( "" " " ) + _vyatta_op_last_comp=${_vyatta_op_last_comp_init} + elif [ ${#COMPREPLY[@]} -eq 0 ] && + [ -n "$current_prefix" ]; then + _vyatta_op_invalid_completion + COMPREPLY=( "" " " ) + _vyatta_op_last_comp=${_vyatta_op_last_comp_init} + # Stop completions from getting stuck + elif [ ${#_vyatta_op_completions[@]} -eq 1 ] && + [ -n "$cur" ] && + [[ "${COMPREPLY[0]}" =~ "$cur" ]]; then + _vyatta_op_last_comp=${_vyatta_op_last_comp_init} + elif [ ${#_vyatta_op_completions[@]} -eq 1 ] && + [ -n "$current_prefix" ] && + [[ "${COMPREPLY[0]}" =~ "$current_prefix" ]]; then + _vyatta_op_last_comp=${_vyatta_op_last_comp_init} + # if there are no completions then always show the non-comps + elif [ "${COMP_WORDS[*]:0:$[$COMP_CWORD+1]}" == "$_vyatta_op_last_comp" ] || + [ ${#_vyatta_op_completions[@]} -eq 0 ] || + [ -z "$cur" ]; then + _vyatta_op_help "$current_prefix" \ + "${_vyatta_op_noncompletions[@]}" \ + "${_vyatta_op_completions[@]}" \ + | ${VYATTA_PAGER:-cat} + COMPREPLY=( "" " " ) + _vyatta_op_last_comp=${_vyatta_op_last_comp_init} + else + _vyatta_op_last_comp="${COMP_WORDS[*]:0:$[$COMP_CWORD+1]}" + fi + + eval "$restore_shopts" +} + +# "pipe" functions +count () +{ + wc -l +} + +match () +{ + grep -E -e "$1" +} + +no-match () +{ + grep -E -v -e "$1" +} + +no-more () +{ + cat +} + +strip-private () +{ + ${vyos_libexec_dir}/strip-private.py +} + +commands () +{ + if [ "$_OFR_CONFIGURE" != "" ]; then + if $(cli-shell-api sessionChanged); then + echo "You have uncommited changes, please commit them before using the commands pipe" + else + vyos-config-to-commands + fi + else + echo "commands pipe is not supported in operational mode" + fi +} + +json () +{ + if [ "$_OFR_CONFIGURE" != "" ]; then + if $(cli-shell-api sessionChanged); then + echo "You have uncommited changes, please commit them before using the JSON pipe" + else + vyos-config-to-json + fi + else + echo "JSON pipe is not supported in operational mode" + fi +} + +# pipe command help +# $1: command +_vyatta_pipe_help () +{ + local help="No help text available" + case "$1" in + count) help="Count the number of lines in the output";; + match) help="Only output lines that match specified pattern";; + no-match) help="Only output lines that do not match specified pattern";; + more) help="Paginate the output";; + no-more) help="Do not paginate the output";; + strip-private) help="Remove private information from the config";; + commands) help="Convert config to set commands";; + json) help="Convert config to JSON";; + '<pattern>') help="Pattern for matching";; + esac + echo -n "$help" +} + +_vyatta_do_pipe_help () +{ + local help='' + if (( ${#_vyatta_pipe_completions[@]} + ${#_vyatta_pipe_noncompletions[@]} + == 0 )); then + return + fi + echo -en "\nPossible completions:" + for comp in "${_vyatta_pipe_completions[@]}" \ + "${_vyatta_pipe_noncompletions[@]}"; do + _vyatta_op_print_help "$comp" "$(_vyatta_pipe_help "$comp")" + done +} + +# pipe completion +# $@: words +_vyatta_pipe_completion () +{ + local -a pipe_cmd=() + local -a all_cmds=( 'count' 'match' 'no-match' 'more' 'no-more' 'strip-private' 'commands' 'json' ) + local found=0 + _vyatta_pipe_completions=() + _vyatta_pipe_noncompletions=() + + for word in "$@"; do + if [[ "$found" == "1" || "$word" == "|" ]]; then + pipe_cmd+=( "$word" ) + found=1 + fi + done + if (( found == 0 )); then + return 1 + fi + if (( ${#pipe_cmd[@]} == 1 )); then + # "|" only + _vyatta_pipe_completions=( "${all_cmds[@]}" ) + return 0 + fi + if (( ${#pipe_cmd[@]} == 2 )); then + # "|<space, chars, or space+chars>" + _vyatta_pipe_completions=($(compgen -W "${all_cmds[*]}" -- ${pipe_cmd[1]})) + return 0 + fi + if (( ${#pipe_cmd[@]} == 3 )); then + # "|<chars or space+chars><space or space+chars>" + case "${pipe_cmd[1]}" in + match|no-match) _vyatta_pipe_noncompletions=( '<pattern>' );; + esac + return 0 + fi + return 0 +} + +# comptype +_vyatta_set_comptype () +{ + local comptype + unset _vyatta_comptype + for ndef in ${_vyatta_op_node_path}/*/node.def ; do + if [[ $ndef == */node.tag/node.def ]] ; then + local comptype=$( _vyatta_op_get_node_def_field $ndef comptype ) + if [[ $comptype == "imagefiles" ]] ; then + _vyatta_comptype=$comptype + return 0 + else + _vyatta_comptype="" + return 1 + fi + else + _vyatta_comptype="" + return 1 + fi + done +} + +_filedir_xspec_vyos() +{ + local cur prev words cword + _init_completion || return + + _tilde "$cur" || return 0 + + local IFS=$'\n' xspec=${_xspec[${1##*/}]} tmp + local -a toks + + toks=( $( + compgen -d -- "$(quote_readline "$cur")" | { + while read -r tmp; do + printf '%s\n' $tmp + done + } + )) + + # Munge xspec to contain uppercase version too + # http://thread.gmane.org/gmane.comp.shells.bash.bugs/15294/focus=15306 + eval xspec="${xspec}" + local matchop=! + if [[ $xspec == !* ]]; then + xspec=${xspec#!} + matchop=@ + fi + xspec="$matchop($xspec|${xspec^^})" + + toks+=( $( + eval compgen -f -X "!$xspec" -- "\$(quote_readline "\$cur")" | { + while read -r tmp; do + [[ -n $tmp ]] && printf '%s\n' $tmp + done + } + )) + + if [[ ${#toks[@]} -ne 0 ]]; then + compopt -o filenames + COMPREPLY=( "${toks[@]}" ) + fi +} + +nullglob_save=$( shopt -p nullglob ) +shopt -s nullglob +for f in ${vyatta_datadir}/vyatta-op/functions/allowed/* ; do + source $f +done +eval $nullglob_save +unset nullglob_save + +# don't initialize if we are in configure mode +if [ "$_OFR_CONFIGURE" == "ok" ]; then + return 0 +fi + +if [[ "$VYATTA_USER_LEVEL_DIR" != "/opt/vyatta/etc/shell/level/admin" ]]; then + vyatta_unpriv_init $@ +else + _vyatta_op_init $@ +fi + +### Local Variables: +### mode: shell-script +### End: diff --git a/src/etc/default/vyatta b/src/etc/default/vyatta new file mode 100644 index 000000000..e5fa3bb30 --- /dev/null +++ b/src/etc/default/vyatta @@ -0,0 +1,217 @@ +# **** License **** +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 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. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc. +# All Rights Reserved. + +# declare configured Vyatta shell environment variables + +# first set vars per args of the "source /etc/default/vyatta VAR=FOO" +_vyatta_extglob=$(shopt -p extglob) +shopt -s extglob +for arg ; do + [[ $arg == *=* ]] && \ + eval declare -x $arg +done +eval $_vyatta_extglob +unset _vyatta_extglob + +{ + # These declarations must go within braces in order to be able to silence + # readonly variable errors. + + for var in prefix exec_prefix datarootdir ; do + eval test -n \"\$$var\" \&\& _vyatta_save_$var=\$$var + done + + prefix=/opt/vyatta + exec_prefix=${prefix} + datarootdir=${prefix}/share + + if test -z "$vyatta_prefix" ; then + if test -n "/opt/vyatta" ; then + declare -x -r vyatta_prefix=/opt/vyatta + declare -x -r vyos_prefix=/opt/vyatta + else + declare -x -r vyatta_prefix=/opt/vyatta + declare -x -r vyos_prefix=/opt/vyatta + fi + fi + if test -z "$vyatta_exec_prefix" ; then + if test -n "${prefix}" ; then + declare -x -r vyatta_prefix=${prefix} + declare -x -r vyos_prefix=${prefix} + else + declare -x -r vyatta_prefix=$vyatta_prefix + declare -x -r vyos_prefix=$vyatta_prefix + fi + fi + if test -z "$vyatta_datarootdir" ; then + if test -n "${prefix}/share" ; then + declare -x -r vyatta_datarootdir=${prefix}/share + declare -x -r vyos_datarootdir=${prefix}/share + else + declare -x -r vyatta_datarootdir=$vyatta_prefix/share + declare -x -r vyos_datarootdir=$vyatta_prefix/share + fi + fi + if test -z "$vyatta_bindir" ; then + if test -n "${exec_prefix}/bin" ; then + declare -x -r vyatta_bindir=${exec_prefix}/bin + else + declare -x -r vyatta_bindir=$vyatta_exec_prefix/bin + fi + fi + if test -z "$vyatta_sbindir" ; then + if test -n "${exec_prefix}/sbin" ; then + declare -x -r vyatta_sbindir=${exec_prefix}/sbin + else + declare -x -r vyatta_sbindir=$vyatta_exec_prefix/sbin + fi + fi + if test -z "$vyatta_libdir" ; then + if test -n "${exec_prefix}/lib" ; then + declare -x -r vyatta_libdir=${exec_prefix}/lib + declare -x -r vyos_libdir=${exec_prefix}/lib + else + declare -x -r vyatta_libdir=$vyatta_exec_prefix/lib + declare -x -r vyos_libdir=$vyatta_exec_prefix/lib + fi + fi + if test -z "$vyatta_libexecdir" ; then + if test -n "${exec_prefix}/libexec" ; then + declare -x -r vyatta_libexecdir=${exec_prefix}/libexec + else + declare -x -r vyatta_libexecdir=$vyatta_exec_prefix/libexec + fi + fi + if test -z "$vyatta_datadir" ; then + if test -n "${datarootdir}" ; then + declare -x -r vyatta_datadir=${datarootdir} + declare -x -r vyos_datadir=${datarootdir} + else + declare -x -r vyatta_datadir=$vyatta_datarootdir + declare -x -r vyos_datadir=$vyatta_datarootdir + fi + fi + if test -z "$vyatta_htmldir" ; then + if test -n "${docdir}" ; then + declare -x -r vyatta_htmldir=${docdir} + else + declare -x -r vyatta_htmldir=$vyatta_datarootdir/html + fi + fi + if test -z "$vyatta_infodir" ; then + if test -n "${prefix}/share/info" ; then + declare -x -r vyatta_infodir=${prefix}/share/info + else + declare -x -r vyatta_infodir=$vyatta_datarootdir/info + fi + fi + if test -z "$vyatta_mandir" ; then + if test -n "${prefix}/share/man" ; then + declare -x -r vyatta_htmldir=${prefix}/share/man + else + declare -x -r vyatta_htmldir=$vyatta_datarootdir/man + fi + fi + if test -z "$vyatta_localedir" ; then + if test -n "${datarootdir}/locale" ; then + declare -x -r vyatta_localedir=${datarootdir}/locale + else + declare -x -r vyatta_localedir=$vyatta_datarootdir/locale + fi + fi + if test -z "$vyatta_localstatedir" ; then + if test -n "${prefix}/var" ; then + declare -x -r vyatta_localstatedir=${prefix}/var + else + declare -x -r vyatta_localstatedir=$vyatta_prefix/var + fi + fi + if test -z "$vyatta_sharedstatedir" ; then + if test -n "${prefix}/com" ; then + declare -x -r vyatta_sharedstatedir=${prefix}/com + else + declare -x -r vyatta_sharedstatedir=$vyatta_prefix/com + fi + fi + if test -z "$vyatta_sysconfdir" ; then + if test -n "${prefix}/etc" ; then + declare -x -r vyatta_sysconfdir=${prefix}/etc + else + declare -x -r vyatta_sysconfdir=$vyatta_prefix/etc + fi + fi + if test -z "$vyatta_op_templates" ; then + declare -x -r vyatta_op_templates=$vyatta_datadir/vyatta-op/templates + declare -x -r vyos_op_templates=$vyatta_datadir/vyatta-op/templates + fi + if test -z "$vyatta_cfg_templates" ; then + declare -x -r vyatta_cfg_templates=$vyatta_datadir/vyatta-cfg/templates + declare -x -r vyos_cfg_templates=$vyatta_datadir/vyatta-cfg/templates + fi + if test -z "$vyatta_configdir" ; then + declare -x -r vyatta_configdir=$vyatta_prefix/config + declare -x -r vyos_configdir=$vyatta_prefix/config + fi + + for var in prefix exec_prefix datarootdir ; do + eval test -n \"\$_vyatta_save_$var\" \&\& $var=\$_vyatta_save_$var + done + + # It's not like we do, or should support installing VyOS at a different prefix + declare -x -r vyos_libexec_dir=/usr/libexec/vyos + declare -x -r vyos_bin_dir=/usr/bin + declare -x -r vyos_sbin_dir=/usr/sbin + declare -x -r vyos_share_dir=/usr/share + + if test -z "$vyos_conf_scripts_dir" ; then + declare -x -r vyos_conf_scripts_dir=$vyos_libexec_dir/conf_mode + fi + if test -z "$vyos_op_scripts_dir" ; then + declare -x -r vyos_op_scripts_dir=$vyos_libexec_dir/op_mode + fi + if test -z "$vyos_completion_dir" ; then + declare -x -r vyos_completion_dir=$vyos_libexec_dir/completion + fi + if test -z "$vyos_validators_dir" ; then + declare -x -r vyos_validators_dir=$vyos_libexec_dir/validators + fi + if test -z "$vyos_data_dir" ; then + declare -x -r vyos_data_dir=$vyos_share_dir/vyos + fi + if test -z "$vyos_persistence_dir" ; then + UNION_NAME=$(cat /proc/cmdline | sed -e s+^.*vyos-union=++ | sed -e 's/ .*$//') + declare -x -r vyos_persistence_dir="/usr/lib/live/mount/persistence/${UNION_NAME}" + fi + if test -z "$vyos_rootfs_dir" ; then + ROOTFS=$(mount -t squashfs | grep loop0 | cut -d' ' -f3) + declare -x -r vyos_rootfs_dir="${ROOTFS}" + fi + if test -z "$VRF" ; then + VRF=$(ip vrf identify) + [ -n "$VRF" ] && declare -x -r VRF="${VRF}" + fi + if test -z "$NETNS" ; then + NETNS=$(ip netns identify) + [ -n "$NETNS" ] && declare -x -r NETNS="${NETNS}" + fi + +} 2>/dev/null || : + +[ -r /etc/default/vyatta-cfg ] && source /etc/default/vyatta-cfg + +[ -r /etc/default/vyatta-local-env ] && source /etc/default/vyatta-local-env + +### Local Variables: +### mode: shell-script +### End: diff --git a/src/etc/ipsec.d/vti-up-down b/src/etc/ipsec.d/vti-up-down index 01e9543c9..e1765ae85 100755 --- a/src/etc/ipsec.d/vti-up-down +++ b/src/etc/ipsec.d/vti-up-down @@ -27,40 +27,41 @@ from syslog import LOG_INFO from vyos.configquery import ConfigTreeQuery from vyos.configdict import get_interface_dict -from vyos.ifconfig import VTIIf +from vyos.utils.commit import wait_for_commit_lock from vyos.utils.process import call -from vyos.utils.network import get_interface_config +from vyos.utils.vti_updown_db import open_vti_updown_db_for_update + +def supply_interface_dict(interface): + # Lazy-load the running config on first invocation + try: + conf = supply_interface_dict.cached_config + except AttributeError: + conf = ConfigTreeQuery() + supply_interface_dict.cached_config = conf + + _, vti = get_interface_dict(conf.config, ['interfaces', 'vti'], interface) + return vti if __name__ == '__main__': verb = os.getenv('PLUTO_VERB') connection = os.getenv('PLUTO_CONNECTION') interface = sys.argv[1] + if verb.endswith('-v6'): + protocol = 'v6' + else: + protocol = 'v4' + openlog(ident=f'vti-up-down', logoption=LOG_PID, facility=LOG_INFO) syslog(f'Interface {interface} {verb} {connection}') - if verb in ['up-client', 'up-host']: - call('sudo ip route delete default table 220') - - vti_link = get_interface_config(interface) - - if not vti_link: - syslog(f'Interface {interface} not found') - sys.exit(0) - - vti_link_up = (vti_link['operstate'] != 'DOWN' if 'operstate' in vti_link else False) + wait_for_commit_lock() - if verb in ['up-client', 'up-host']: - if not vti_link_up: - conf = ConfigTreeQuery() - _, vti = get_interface_dict(conf.config, ['interfaces', 'vti'], interface) - if 'disable' not in vti: - tmp = VTIIf(interface) - tmp.update(vti) - call(f'sudo ip link set {interface} up') - else: - call(f'sudo ip link set {interface} down') - syslog(f'Interface {interface} is admin down ...') - elif verb in ['down-client', 'down-host']: - if vti_link_up: - call(f'sudo ip link set {interface} down') + if verb in ['up-client', 'up-client-v6', 'up-host', 'up-host-v6']: + with open_vti_updown_db_for_update() as db: + db.add(interface, connection, protocol) + db.commit(supply_interface_dict) + elif verb in ['down-client', 'down-client-v6', 'down-host', 'down-host-v6']: + with open_vti_updown_db_for_update() as db: + db.remove(interface, connection, protocol) + db.commit(supply_interface_dict) diff --git a/src/etc/netplug/vyos-netplug-dhcp-client b/src/etc/netplug/vyos-netplug-dhcp-client index 55d15a163..4cc824afd 100755 --- a/src/etc/netplug/vyos-netplug-dhcp-client +++ b/src/etc/netplug/vyos-netplug-dhcp-client @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2023-2025 VyOS maintainers and contributors <maintainers@vyos.io> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -19,44 +19,39 @@ import sys from time import sleep -from vyos.configquery import ConfigTreeQuery +from vyos.config import Config +from vyos.configdict import get_interface_dict +from vyos.ifconfig import Interface from vyos.ifconfig import Section from vyos.utils.boot import boot_configuration_complete from vyos.utils.commit import commit_in_progress -from vyos.utils.process import call from vyos import airbag + airbag.enable() if len(sys.argv) < 3: - airbag.noteworthy("Must specify both interface and link status!") + airbag.noteworthy('Must specify both interface and link status!') sys.exit(1) if not boot_configuration_complete(): - airbag.noteworthy("System bootup not yet finished...") + airbag.noteworthy('System bootup not yet finished...') sys.exit(1) +interface = sys.argv[1] +# helper scripts should only work on physical interfaces not on individual +# sub-interfaces. Moving e.g. a VLAN interface in/out a VRF will also trigger +# this script which should be prohibited - bail out early +if '.' in interface: + sys.exit(0) + while commit_in_progress(): sleep(1) -interface = sys.argv[1] in_out = sys.argv[2] -config = ConfigTreeQuery() +config = Config() interface_path = ['interfaces'] + Section.get_config_path(interface).split() - -for _, interface_config in config.get_config_dict(interface_path).items(): - # Bail out early if we do not have an IP address configured - if 'address' not in interface_config: - continue - # Bail out early if interface ist administrative down - if 'disable' in interface_config: - continue - systemd_action = 'start' - if in_out == 'out': - systemd_action = 'stop' - # Start/Stop DHCP service - if 'dhcp' in interface_config['address']: - call(f'systemctl {systemd_action} dhclient@{interface}.service') - # Start/Stop DHCPv6 service - if 'dhcpv6' in interface_config['address']: - call(f'systemctl {systemd_action} dhcp6c@{interface}.service') +_, interface_config = get_interface_dict( + config, interface_path[:-1], ifname=interface, with_pki=True +) +Interface(interface).update(interface_config) diff --git a/src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb b/src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb new file mode 100755 index 000000000..fff258afa --- /dev/null +++ b/src/etc/ppp/ip-up.d/99-vyos-pppoe-wlb @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 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/>. + +# This is a Python hook script which is invoked whenever a PPPoE session goes +# "ip-up". It will call into our vyos.ifconfig library and will then execute +# common tasks for the PPPoE interface. The reason we have to "hook" this is +# that we can not create a pppoeX interface in advance in linux and then connect +# pppd to this already existing interface. + +import os +import signal + +from sys import argv +from sys import exit + +from vyos.defaults import directories + +# When the ppp link comes up, this script is called with the following +# parameters +# $1 the interface name used by pppd (e.g. ppp3) +# $2 the tty device name +# $3 the tty device speed +# $4 the local IP address for the interface +# $5 the remote IP address +# $6 the parameter specified by the 'ipparam' option to pppd + +if (len(argv) < 7): + exit(1) + +wlb_pid_file = '/run/wlb_daemon.pid' + +interface = argv[6] +nexthop = argv[5] + +if not os.path.exists(directories['ppp_nexthop_dir']): + os.mkdir(directories['ppp_nexthop_dir']) + +nexthop_file = os.path.join(directories['ppp_nexthop_dir'], interface) + +with open(nexthop_file, 'w') as f: + f.write(nexthop) + +# Trigger WLB daemon update +if os.path.exists(wlb_pid_file): + with open(wlb_pid_file, 'r') as f: + pid = int(f.read()) + + os.kill(pid, signal.SIGUSR2) diff --git a/src/etc/rsyslog.conf b/src/etc/rsyslog.conf deleted file mode 100644 index b3f41acb6..000000000 --- a/src/etc/rsyslog.conf +++ /dev/null @@ -1,67 +0,0 @@ -################# -#### MODULES #### -################# - -$ModLoad imuxsock # provides support for local system logging -$ModLoad imklog # provides kernel logging support (previously done by rklogd) -#$ModLoad immark # provides --MARK-- message capability - -$OmitLocalLogging off -$SystemLogSocketName /run/systemd/journal/syslog - -$KLogPath /proc/kmsg - -########################### -#### GLOBAL DIRECTIVES #### -########################### - -# Use traditional timestamp format. -# To enable high precision timestamps, comment out the following line. -# A modern-style logfile format similar to TraditionalFileFormat, buth with high-precision timestamps and timezone information -#$ActionFileDefaultTemplate RSYSLOG_FileFormat -# The "old style" default log file format with low-precision timestamps -$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat - -# Filter duplicated messages -$RepeatedMsgReduction on - -# -# Set the default permissions for all log files. -# -$FileOwner root -$FileGroup adm -$FileCreateMode 0640 -$DirCreateMode 0755 -$Umask 0022 - -# -# Stop excessive logging of sudo -# -:msg, contains, " pam_unix(sudo:session): session opened for user root(uid=0) by" stop -:msg, contains, "pam_unix(sudo:session): session closed for user root" stop - -# -# Include all config files in /etc/rsyslog.d/ -# -$IncludeConfig /etc/rsyslog.d/*.conf - -# The lines below cause all listed daemons/processes to be logged into -# /var/log/auth.log, then drops the message so it does not also go to the -# regular syslog so that messages are not duplicated - -$outchannel auth_log,/var/log/auth.log -if $programname == 'CRON' or - $programname == 'sudo' or - $programname == 'su' - then :omfile:$auth_log - -if $programname == 'CRON' or - $programname == 'sudo' or - $programname == 'su' - then stop - -############### -#### RULES #### -############### -# Emergencies are sent to everybody logged in. -*.emerg :omusrmsg:*
\ No newline at end of file diff --git a/src/etc/skel/.bashrc b/src/etc/skel/.bashrc index ba7d50003..f807f0c72 100644 --- a/src/etc/skel/.bashrc +++ b/src/etc/skel/.bashrc @@ -92,6 +92,9 @@ fi #alias la='ls -A' #alias l='ls -CF' +# Disable iproute2 auto color +alias ip="ip --color=never" + # Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. diff --git a/src/etc/sudoers.d/vyos b/src/etc/sudoers.d/vyos index c099446ba..198b9b9aa 100644 --- a/src/etc/sudoers.d/vyos +++ b/src/etc/sudoers.d/vyos @@ -1,7 +1,8 @@ # # VyOS modifications to sudo configuration # -Defaults syslog_goodpri=info +Defaults !syslog +Defaults !pam_session Defaults env_keep+=VYATTA_* # @@ -44,6 +45,8 @@ Cmnd_Alias DIAGNOSTICS = /bin/ip vrf exec * /bin/ping *, \ /bin/ip vrf exec * /bin/traceroute *, \ /bin/ip vrf exec * /usr/bin/mtr *, \ /usr/libexec/vyos/op_mode/* +Cmnd_Alias KEA_IP6_ROUTES = /sbin/ip -6 route replace *,\ + /sbin/ip -6 route del * %operator ALL=NOPASSWD: DATE, IPTABLES, ETHTOOL, IPFLUSH, HWINFO, \ PPPOE_CMDS, PCAPTURE, /usr/sbin/wanpipemon, \ DMIDECODE, DISK, CONNTRACK, IP6TABLES, \ @@ -55,3 +58,7 @@ Cmnd_Alias DIAGNOSTICS = /bin/ip vrf exec * /bin/ping *, \ # Allow members of group sudo to execute any command %sudo ALL=NOPASSWD: ALL +# Allow any user to query Machine Owner Key status +%sudo ALL=NOPASSWD: /usr/bin/mokutil + +_kea ALL=NOPASSWD: KEA_IP6_ROUTES diff --git a/src/etc/sysctl.d/30-vyos-router.conf b/src/etc/sysctl.d/30-vyos-router.conf index c9b8ef8fe..76be41ddc 100644 --- a/src/etc/sysctl.d/30-vyos-router.conf +++ b/src/etc/sysctl.d/30-vyos-router.conf @@ -110,3 +110,8 @@ net.ipv6.conf.all.seg6_enabled = 0 net.ipv6.conf.default.seg6_enabled = 0 net.vrf.strict_mode = 1 + +# https://vyos.dev/T6570 +# By default, do not forward traffic from bridge to IPvX layer +net.bridge.bridge-nf-call-iptables = 0 +net.bridge.bridge-nf-call-ip6tables = 0
\ No newline at end of file diff --git a/src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf b/src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf new file mode 100644 index 000000000..c74fafb42 --- /dev/null +++ b/src/etc/systemd/system/kea-ctrl-agent.service.d/override.conf @@ -0,0 +1,10 @@ +[Unit] +After= +After=vyos-router.service +ConditionFileNotEmpty= + +[Service] +ExecStart= +ExecStart=/usr/sbin/kea-ctrl-agent -c /run/kea/kea-ctrl-agent.conf +AmbientCapabilities=CAP_NET_BIND_SERVICE +CapabilityBoundingSet=CAP_NET_BIND_SERVICE diff --git a/src/etc/systemd/system/kea-dhcp4-server.service.d/override.conf b/src/etc/systemd/system/kea-dhcp4-server.service.d/override.conf new file mode 100644 index 000000000..682e5bbce --- /dev/null +++ b/src/etc/systemd/system/kea-dhcp4-server.service.d/override.conf @@ -0,0 +1,7 @@ +[Unit] +After= +After=vyos-router.service + +[Service] +ExecStart= +ExecStart=/usr/sbin/kea-dhcp4 -c /run/kea/kea-dhcp4.conf diff --git a/src/etc/systemd/system/kea-dhcp6-server.service.d/override.conf b/src/etc/systemd/system/kea-dhcp6-server.service.d/override.conf new file mode 100644 index 000000000..cb33fc057 --- /dev/null +++ b/src/etc/systemd/system/kea-dhcp6-server.service.d/override.conf @@ -0,0 +1,7 @@ +[Unit] +After= +After=vyos-router.service + +[Service] +ExecStart= +ExecStart=/usr/sbin/kea-dhcp6 -c /run/kea/kea-dhcp6.conf diff --git a/src/etc/systemd/system/rsyslog.service.d/override.conf b/src/etc/systemd/system/rsyslog.service.d/override.conf new file mode 100644 index 000000000..665b994d9 --- /dev/null +++ b/src/etc/systemd/system/rsyslog.service.d/override.conf @@ -0,0 +1,10 @@ +[Unit] +StartLimitIntervalSec=0 + +[Service] +ExecStart= +ExecStart=/usr/sbin/rsyslogd -n -iNONE -f /run/rsyslog/rsyslog.conf +Restart=always +RestartPreventExitStatus= +RestartSec=10 +RuntimeDirectoryPreserve=yes diff --git a/src/etc/systemd/system/suricata.service.d/10-override.conf b/src/etc/systemd/system/suricata.service.d/10-override.conf new file mode 100644 index 000000000..781256cf5 --- /dev/null +++ b/src/etc/systemd/system/suricata.service.d/10-override.conf @@ -0,0 +1,9 @@ +[Service] +ExecStart= +ExecStart=/usr/bin/suricata -D --af-packet -c /run/suricata/suricata.yaml --pidfile /run/suricata/suricata.pid +PIDFile= +PIDFile=/run/suricata/suricata.pid +ExecReload= +ExecReload=/usr/bin/suricatasc -c reload-rules /run/suricata/suricata.socket ; /bin/kill -HUP $MAINPID +ExecStop= +ExecStop=/usr/bin/suricatasc -c shutdown /run/suricata/suricata.socket diff --git a/src/etc/udev/rules.d/90-vyos-serial.rules b/src/etc/udev/rules.d/90-vyos-serial.rules index 30c1d3170..f86b2258f 100644 --- a/src/etc/udev/rules.d/90-vyos-serial.rules +++ b/src/etc/udev/rules.d/90-vyos-serial.rules @@ -8,7 +8,7 @@ SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci" SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" # /dev/serial/by-path/, /dev/serial/by-id/ for USB devices -KERNEL!="ttyUSB[0-9]*", GOTO="serial_end" +KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="serial_end" SUBSYSTEMS=="usb-serial", ENV{.ID_PORT}="$attr{port_number}" |