diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/http-api.py | 2 | ||||
-rwxr-xr-x | src/conf_mode/https.py | 27 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-pppoe.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/system-login.py | 10 | ||||
-rwxr-xr-x | src/helpers/vyos-load-config.py | 2 | ||||
-rw-r--r-- | src/op_mode/generate_interfaces_debug_archive.py | 115 | ||||
-rw-r--r-- | src/pam-configs/radius | 20 | ||||
-rw-r--r-- | src/pam-configs/radius-mandatory | 19 | ||||
-rw-r--r-- | src/pam-configs/radius-optional | 19 |
9 files changed, 194 insertions, 26 deletions
diff --git a/src/conf_mode/http-api.py b/src/conf_mode/http-api.py index 00f3d4f7f..2ade3476d 100755 --- a/src/conf_mode/http-api.py +++ b/src/conf_mode/http-api.py @@ -39,7 +39,7 @@ vyos_conf_scripts_dir=vyos.defaults.directories['conf_mode'] def get_config(config=None): http_api = deepcopy(vyos.defaults.api_data) x = http_api.get('api_keys') - if x is None: + if not x: default_key = None else: default_key = x[0] diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py index 1e58bb1e4..f02e32cd1 100755 --- a/src/conf_mode/https.py +++ b/src/conf_mode/https.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019-2020 VyOS maintainers and contributors +# Copyright (C) 2019-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 @@ -25,6 +25,7 @@ from vyos.config import Config from vyos.configverify import verify_vrf from vyos import ConfigError from vyos.util import call +from vyos.util import dict_search from vyos.template import render from vyos import airbag @@ -160,6 +161,30 @@ def verify(https): "matching the 'certbot domain-name' is required.") verify_vrf(https) + + # Verify API server settings, if present + if 'api' in https: + keys = dict_search('api.keys.id', https) + gql_auth_type = dict_search('api.graphql.authentication.type', https) + + # If "api graphql" is not defined and `gql_auth_type` is None, + # there's certainly no JWT auth option, and keys are required + jwt_auth = (gql_auth_type == "token") + + # Check for incomplete key configurations in every case + valid_keys_exist = False + if keys: + for k in keys: + if 'key' not in keys[k]: + raise ConfigError(f'Missing HTTPS API key string for key id "{k}"') + else: + valid_keys_exist = True + + # If only key-based methods are enabled, + # fail the commit if no valid key configurations are found + if (not valid_keys_exist) and (not jwt_auth): + raise ConfigError('At least one HTTPS API key is required unless GraphQL token authentication is enabled') + return None def generate(https): diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index 49714c558..7434c5b3b 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -44,6 +44,12 @@ def get_config(config=None): base = ['interfaces', 'pppoe'] pppoe = get_interface_dict(conf, base) + if 'deleted' not in pppoe: + # We always set the MRU value to the MTU size. This code path only re-creates + # the old behavior if MRU is not set on the CLI. + if 'mru' not in pppoe: + pppoe['mru'] = pppoe['mtu'] + return pppoe def verify(pppoe): diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index 7cfd5c940..4e61bd8ad 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -299,9 +299,15 @@ def apply(login): env = os.environ.copy() env['DEBIAN_FRONTEND'] = 'noninteractive' try: + # Disable PAM before enabling or modifying anything + cmd('pam-auth-update --disable radius-mandatory radius-optional', env=env) if 'radius' in login: # Enable RADIUS in PAM - cmd('pam-auth-update --package --enable radius', env=env) + if login['radius'].get('security_mode', '') == 'mandatory': + pam_profile = 'radius-mandatory' + else: + pam_profile = 'radius-optional' + cmd(f'pam-auth-update --enable {pam_profile}', env=env) # Make NSS system aware of RADIUS # This fancy snipped was copied from old Vyatta code command = "sed -i -e \'/\smapname/b\' \ @@ -312,8 +318,6 @@ def apply(login): -e \'/^group:[^#]*$/s/: */&mapname /\' \ /etc/nsswitch.conf" else: - # Disable RADIUS in PAM - cmd('pam-auth-update --package --remove radius', env=env) # Drop RADIUS from NSS NSS system # This fancy snipped was copied from old Vyatta code command = "sed -i -e \'/^passwd:.*mapuid[ \t]/s/mapuid[ \t]//\' \ diff --git a/src/helpers/vyos-load-config.py b/src/helpers/vyos-load-config.py index e579e81b2..4ec865454 100755 --- a/src/helpers/vyos-load-config.py +++ b/src/helpers/vyos-load-config.py @@ -66,7 +66,7 @@ def get_local_config(filename): return config_str -if any(x in file_name for x in protocols): +if any(file_name.startswith(f'{x}://') for x in protocols): config_string = vyos.remote.get_remote_config(file_name) if not config_string: sys.exit(f"No such config file at '{file_name}'") diff --git a/src/op_mode/generate_interfaces_debug_archive.py b/src/op_mode/generate_interfaces_debug_archive.py new file mode 100644 index 000000000..683484a65 --- /dev/null +++ b/src/op_mode/generate_interfaces_debug_archive.py @@ -0,0 +1,115 @@ +#!/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 datetime import datetime +from pathlib import Path +from shutil import rmtree +from socket import gethostname +from sys import exit +from tarfile import open as tar_open +from vyos.util import rc_cmd +import os + +# define a list of commands that needs to be executed + +CMD_LIST = [ + "journalctl -b -n 500", + "journalctl -b -k -n 500", + "ip -s l", + "cat /proc/interrupts", + "cat /proc/softirqs", + "top -b -d 1 -n 2 -1", + "netstat -l", + "cat /proc/net/dev", + "cat /proc/net/softnet_stat", + "cat /proc/net/icmp", + "cat /proc/net/udp", + "cat /proc/net/tcp", + "cat /proc/net/netstat", + "sysctl net", + "timeout 10 tcpdump -c 500 -eni any port not 22" +] + +CMD_INTERFACES_LIST = [ + "ethtool -i ", + "ethtool -S ", + "ethtool -g ", + "ethtool -c ", + "ethtool -a ", + "ethtool -k ", + "ethtool -i ", + "ethtool --phy-statistics " +] + +# get intefaces info +interfaces_list = os.popen('ls /sys/class/net/').read().split() + +# modify CMD_INTERFACES_LIST for all interfaces +CMD_INTERFACES_LIST_MOD=[] +for command_interface in interfaces_list: + for command_interfacev2 in CMD_INTERFACES_LIST: + CMD_INTERFACES_LIST_MOD.append (f'{command_interfacev2}{command_interface}') + +# execute a command and save the output to a file + +def save_stdout(command: str, file: Path) -> None: + rc, stdout = rc_cmd(command) + body: str = f'''### {command} ### +Command: {command} +Exit code: {rc} +Stdout: +{stdout} + +''' + with file.open(mode='a') as f: + f.write(body) + +# get local host name +hostname: str = gethostname() +# get current time +time_now: str = datetime.now().isoformat(timespec='seconds') + +# define a temporary directory for logs and collected data +tmp_dir: Path = Path(f'/tmp/drops-debug_{time_now}') +# set file paths +drops_file: Path = Path(f'{tmp_dir}/drops.txt') +interfaces_file: Path = Path(f'{tmp_dir}/interfaces.txt') +archive_file: str = f'/tmp/packet-drops-debug_{time_now}.tar.bz2' + +# create files +tmp_dir.mkdir() +drops_file.touch() +interfaces_file.touch() + +try: + # execute all commands + for command in CMD_LIST: + save_stdout(command, drops_file) + for command_interface in CMD_INTERFACES_LIST_MOD: + save_stdout(command_interface, interfaces_file) + + # create an archive + with tar_open(name=archive_file, mode='x:bz2') as tar_file: + tar_file.add(tmp_dir) + + # inform user about success + print(f'Debug file is generated and located in {archive_file}') +except Exception as err: + print(f'Error during generating a debug file: {err}') +finally: + # cleanup + rmtree(tmp_dir) + exit() diff --git a/src/pam-configs/radius b/src/pam-configs/radius deleted file mode 100644 index 0e2c71e38..000000000 --- a/src/pam-configs/radius +++ /dev/null @@ -1,20 +0,0 @@ -Name: RADIUS authentication -Default: yes -Priority: 257 -Auth-Type: Primary -Auth: - [default=ignore success=1] pam_succeed_if.so uid eq 1001 quiet - [default=ignore success=ignore] pam_succeed_if.so uid eq 1002 quiet - [authinfo_unavail=ignore success=end default=ignore] pam_radius_auth.so - -Account-Type: Primary -Account: - [default=ignore success=1] pam_succeed_if.so uid eq 1001 quiet - [default=ignore success=ignore] pam_succeed_if.so uid eq 1002 quiet - [authinfo_unavail=ignore success=end perm_denied=bad default=ignore] pam_radius_auth.so - -Session-Type: Additional -Session: - [default=ignore success=1] pam_succeed_if.so uid eq 1001 quiet - [default=ignore success=ignore] pam_succeed_if.so uid eq 1002 quiet - [authinfo_unavail=ignore success=ok default=ignore] pam_radius_auth.so diff --git a/src/pam-configs/radius-mandatory b/src/pam-configs/radius-mandatory new file mode 100644 index 000000000..3368fe7ff --- /dev/null +++ b/src/pam-configs/radius-mandatory @@ -0,0 +1,19 @@ +Name: RADIUS authentication (mandatory mode) +Default: no +Priority: 576 + +Auth-Type: Primary +Auth-Initial: + [default=ignore success=end auth_err=die perm_denied=die user_unknown=die] pam_radius_auth.so +Auth: + [default=ignore success=end auth_err=die perm_denied=die user_unknown=die] pam_radius_auth.so use_first_pass + +Account-Type: Primary +Account: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=ignore success=end] pam_radius_auth.so + +Session-Type: Additional +Session: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=bad success=ok] pam_radius_auth.so diff --git a/src/pam-configs/radius-optional b/src/pam-configs/radius-optional new file mode 100644 index 000000000..73085061d --- /dev/null +++ b/src/pam-configs/radius-optional @@ -0,0 +1,19 @@ +Name: RADIUS authentication (optional mode) +Default: no +Priority: 576 + +Auth-Type: Primary +Auth-Initial: + [default=ignore success=end] pam_radius_auth.so +Auth: + [default=ignore success=end] pam_radius_auth.so use_first_pass + +Account-Type: Primary +Account: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=ignore success=end] pam_radius_auth.so + +Session-Type: Additional +Session: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=ignore success=ok perm_denied=bad user_unknown=bad] pam_radius_auth.so |