diff options
25 files changed, 198 insertions, 99 deletions
diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2 index 194dbcb07..8df1e9513 100644 --- a/data/templates/frr/isisd.frr.j2 +++ b/data/templates/frr/isisd.frr.j2 @@ -121,22 +121,12 @@ router isis VyOS {{ 'vrf ' + vrf if vrf is vyos_defined }} {% for prefix, prefix_config in segment_routing.prefix.items() %} {% if prefix_config.absolute is vyos_defined %} {% if prefix_config.absolute.value is vyos_defined %} - segment-routing prefix {{ prefix }} absolute {{ prefix_config.absolute.value }} -{% if prefix_config.absolute.explicit_null is vyos_defined %} - segment-routing prefix {{ prefix }} absolute {{ prefix_config.absolute.value }} explicit-null -{% elif prefix_config.absolute.no_php_flag is vyos_defined %} - segment-routing prefix {{ prefix }} absolute {{ prefix_config.absolute.value }} no-php-flag -{% endif %} + segment-routing prefix {{ prefix }} absolute {{ prefix_config.absolute.value }} {{ 'explicit-null' if prefix_config.absolute.explicit_null is vyos_defined }} {{ 'no-php-flag' if prefix_config.absolute.no_php_flag is vyos_defined }} {% endif %} {% endif %} {% if prefix_config.index is vyos_defined %} {% if prefix_config.index.value is vyos_defined %} - segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} -{% if prefix_config.index.explicit_null is vyos_defined %} - segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} explicit-null -{% elif prefix_config.index.no_php_flag is vyos_defined %} - segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} no-php-flag -{% endif %} + segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} {{ 'explicit-null' if prefix_config.index.explicit_null is vyos_defined }} {{ 'no-php-flag' if prefix_config.index.no_php_flag is vyos_defined }} {% endif %} {% endif %} {% endfor %} diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2 index 9cd9b03dc..2a8afefbc 100644 --- a/data/templates/frr/ospfd.frr.j2 +++ b/data/templates/frr/ospfd.frr.j2 @@ -196,12 +196,7 @@ router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% for prefix, prefix_config in segment_routing.prefix.items() %} {% if prefix_config.index is vyos_defined %} {% if prefix_config.index.value is vyos_defined %} - segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} -{% if prefix_config.index.explicit_null is vyos_defined %} - segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} explicit-null -{% elif prefix_config.index.no_php_flag is vyos_defined %} - segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} no-php-flag -{% endif %} + segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} {{ 'explicit-null' if prefix_config.index.explicit_null is vyos_defined }} {{ 'no-php-flag' if prefix_config.index.no_php_flag is vyos_defined }} {% endif %} {% endif %} {% endfor %} diff --git a/data/templates/login/pam_otp_ga.conf.j2 b/data/templates/login/pam_otp_ga.conf.j2 new file mode 100644 index 000000000..cf51ce089 --- /dev/null +++ b/data/templates/login/pam_otp_ga.conf.j2 @@ -0,0 +1,7 @@ +{% if authentication.otp.key is vyos_defined %} +{{ authentication.otp.key | upper }} +" RATE_LIMIT {{ authentication.otp.rate_limit }} {{ authentication.otp.rate_time }} +" WINDOW_SIZE {{ authentication.otp.window_size }} +" DISALLOW_REUSE +" TOTP_AUTH +{% endif %} diff --git a/data/templates/ssh/sshd_config.j2 b/data/templates/ssh/sshd_config.j2 index 79b07478b..5bbfdeb88 100644 --- a/data/templates/ssh/sshd_config.j2 +++ b/data/templates/ssh/sshd_config.j2 @@ -17,7 +17,6 @@ PubkeyAuthentication yes IgnoreRhosts yes HostbasedAuthentication no PermitEmptyPasswords no -ChallengeResponseAuthentication no X11Forwarding yes X11DisplayOffset 10 PrintMotd no @@ -30,6 +29,7 @@ PermitRootLogin no PidFile /run/sshd/sshd.pid AddressFamily any DebianBanner no +PasswordAuthentication no # # User configurable section @@ -48,7 +48,7 @@ Port {{ value }} LogLevel {{ loglevel | upper }} # Specifies whether password authentication is allowed -PasswordAuthentication {{ "no" if disable_password_authentication is vyos_defined else "yes" }} +ChallengeResponseAuthentication {{ "no" if disable_password_authentication is vyos_defined else "yes" }} {% if listen_address is vyos_defined %} # Specifies the local addresses sshd should listen on diff --git a/data/templates/telegraf/telegraf.j2 b/data/templates/telegraf/telegraf.j2 index 2d14230ae..36571ce98 100644 --- a/data/templates/telegraf/telegraf.j2 +++ b/data/templates/telegraf/telegraf.j2 @@ -110,7 +110,7 @@ server = "unixgram:///run/telegraf/telegraf_syslog.sock" best_effort = true syslog_standard = "RFC3164" -{% if influxdb_configured is vyos_defined %} +{% if influxdb is vyos_defined %} [[inputs.exec]] commands = [ "{{ custom_scripts_dir }}/show_firewall_input_filter.py", diff --git a/debian/vyos-1x.postinst b/debian/vyos-1x.postinst index 6879b6e4f..031e91595 100644 --- a/debian/vyos-1x.postinst +++ b/debian/vyos-1x.postinst @@ -21,6 +21,14 @@ if ! grep -q '^openvpn' /etc/passwd; then adduser --quiet --firstuid 100 --system --group --shell /usr/sbin/nologin openvpn fi +# Add 2FA support for SSH +sudo grep -qF -- "auth required pam_google_authenticator.so nullok" "/etc/pam.d/sshd" || \ +sudo sed -i '/^@include common-auth/a # Check OTP 2FA, if configured for the user\nauth required pam_google_authenticator.so nullok' /etc/pam.d/sshd + +# Add 2FA support for local authentication +sudo grep -qF -- "auth required pam_google_authenticator.so nullok" "/etc/pam.d/login" || \ +sudo sed -i '/^@include common-auth/a # Check OTP 2FA, if configured for the user\nauth required pam_google_authenticator.so nullok' /etc/pam.d/login + # Add RADIUS operator user for RADIUS authenticated users to map to if ! grep -q '^radius_user' /etc/passwd; then adduser --quiet --firstuid 1000 --disabled-login --ingroup vyattaop \ diff --git a/interface-definitions/include/isis/protocol-common-config.xml.i b/interface-definitions/include/isis/protocol-common-config.xml.i index 57ee19300..42bda7a80 100644 --- a/interface-definitions/include/isis/protocol-common-config.xml.i +++ b/interface-definitions/include/isis/protocol-common-config.xml.i @@ -238,7 +238,7 @@ <help>Segment Routing Global Block label range</help> </properties> <children> - #include <include/isis/high-low-label-value.xml.i> + #include <include/segment-routing-label-value.xml.i> </children> </node> <node name="local-block"> @@ -246,7 +246,7 @@ <help>Segment Routing Local Block label range</help> </properties> <children> - #include <include/isis/high-low-label-value.xml.i> + #include <include/segment-routing-label-value.xml.i> </children> </node> <leafNode name="maximum-label-depth"> diff --git a/interface-definitions/include/monitoring/url.xml.i b/interface-definitions/include/monitoring/url.xml.i deleted file mode 100644 index fd61c38ea..000000000 --- a/interface-definitions/include/monitoring/url.xml.i +++ /dev/null @@ -1,15 +0,0 @@ -<!-- include start from monitoring/url.xml.i --> -<leafNode name="url"> - <properties> - <help>Remote URL</help> - <valueHelp> - <format>url</format> - <description>Remote URL</description> - </valueHelp> - <constraint> - <regex>(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}?(\/.*)?</regex> - </constraint> - <constraintErrorMessage>Incorrect URL format</constraintErrorMessage> - </properties> -</leafNode> -<!-- include end --> diff --git a/interface-definitions/include/ospf/protocol-common-config.xml.i b/interface-definitions/include/ospf/protocol-common-config.xml.i index 28e3b473b..0615063af 100644 --- a/interface-definitions/include/ospf/protocol-common-config.xml.i +++ b/interface-definitions/include/ospf/protocol-common-config.xml.i @@ -631,7 +631,7 @@ <help>Segment Routing Global Block label range</help> </properties> <children> - #include <include/isis/high-low-label-value.xml.i> + #include <include/segment-routing-label-value.xml.i> </children> </node> <node name="local-block"> @@ -639,7 +639,7 @@ <help>Segment Routing Local Block label range</help> </properties> <children> - #include <include/isis/high-low-label-value.xml.i> + #include <include/segment-routing-label-value.xml.i> </children> </node> <leafNode name="maximum-label-depth"> diff --git a/interface-definitions/include/isis/high-low-label-value.xml.i b/interface-definitions/include/segment-routing-label-value.xml.i index f30b5af3a..05e1edd78 100644 --- a/interface-definitions/include/isis/high-low-label-value.xml.i +++ b/interface-definitions/include/segment-routing-label-value.xml.i @@ -1,10 +1,10 @@ -<!-- include start from isis/high-low-label-value.xml.i --> +<!-- include start from segment-routing-label-value.xml.i --> <leafNode name="low-label-value"> <properties> <help>MPLS label lower bound</help> <valueHelp> <format>u32:16-1048575</format> - <description>Label value (recommended minimum value: 100)</description> + <description>Label value (recommended minimum value: 300)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 16-1048575"/> diff --git a/interface-definitions/service-monitoring-telegraf.xml.in b/interface-definitions/service-monitoring-telegraf.xml.in index 47f943d83..f50e5e334 100644 --- a/interface-definitions/service-monitoring-telegraf.xml.in +++ b/interface-definitions/service-monitoring-telegraf.xml.in @@ -53,7 +53,7 @@ </properties> <defaultValue>main</defaultValue> </leafNode> - #include <include/monitoring/url.xml.i> + #include <include/url.xml.i> #include <include/port-number.xml.i> <leafNode name="port"> <defaultValue>8086</defaultValue> @@ -145,7 +145,7 @@ <constraintErrorMessage>Table is limited to alphanumerical characters and can contain hyphen and underscores</constraintErrorMessage> </properties> </leafNode> - #include <include/monitoring/url.xml.i> + #include <include/url.xml.i> </children> </node> <leafNode name="source"> @@ -271,7 +271,7 @@ </leafNode> </children> </node> - #include <include/monitoring/url.xml.i> + #include <include/url.xml.i> </children> </node> #include <include/interface/vrf.xml.i> diff --git a/interface-definitions/system-login.xml.in b/interface-definitions/system-login.xml.in index d189be3f8..def42544a 100644 --- a/interface-definitions/system-login.xml.in +++ b/interface-definitions/system-login.xml.in @@ -19,7 +19,7 @@ <children> <node name="authentication"> <properties> - <help>Password authentication</help> + <help>Authentication settings</help> </properties> <children> <leafNode name="encrypted-password"> @@ -36,6 +36,68 @@ </properties> <defaultValue>!</defaultValue> </leafNode> + <node name="otp"> + <properties> + <help>One-Time-Pad (two-factor) authentication parameters</help> + </properties> + <children> + <leafNode name="rate-limit"> + <properties> + <help>Limit number of logins (rate-limit) per rate-time</help> + <valueHelp> + <format>u32:1-10</format> + <description>Number of attempts</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-10"/> + </constraint> + <constraintErrorMessage>Number of login attempts must me between 1 and 10</constraintErrorMessage> + </properties> + <defaultValue>3</defaultValue> + </leafNode> + <leafNode name="rate-time"> + <properties> + <help>Limit number of logins (rate-limit) per rate-time</help> + <valueHelp> + <format>u32:15-600</format> + <description>Time interval</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 15-600"/> + </constraint> + <constraintErrorMessage>Rate limit time interval must be between 15 and 600 seconds</constraintErrorMessage> + </properties> + <defaultValue>30</defaultValue> + </leafNode> + <leafNode name="window-size"> + <properties> + <help>Set window of concurrently valid codes</help> + <valueHelp> + <format>u32:1-21</format> + <description>Window size</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-21"/> + </constraint> + <constraintErrorMessage>Window of concurrently valid codes must be between 1 and 21</constraintErrorMessage> + </properties> + <defaultValue>3</defaultValue> + </leafNode> + <leafNode name="key"> + <properties> + <help>Key/secret the token algorithm (see RFC4226)</help> + <valueHelp> + <format>txt</format> + <description>Base32 encoded key/token</description> + </valueHelp> + <constraint> + <regex>[a-zA-Z2-7]{26,10000}</regex> + </constraint> + <constraintErrorMessage>Key must only include base32 characters and be at least 26 characters long</constraintErrorMessage> + </properties> + </leafNode> + </children> + </node> <leafNode name="plaintext-password"> <properties> <help>Plaintext password used for encryption</help> diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py index 6894fc4da..7de458960 100644 --- a/python/vyos/defaults.py +++ b/python/vyos/defaults.py @@ -49,8 +49,6 @@ api_data = { 'port' : '8080', 'socket' : False, 'strict' : False, - 'gql' : False, - 'introspection' : False, 'debug' : False, 'api_keys' : [ {"id": "testapp", "key": "qwerty"} ] } diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py index c26028253..d11d80a1f 100755 --- a/smoketest/scripts/cli/test_protocols_isis.py +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -263,10 +263,10 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): self.assertIn(f' isis bfd profile {bfd_profile}', tmp) def test_isis_07_segment_routing_configuration(self): - global_block_low = "100" - global_block_high = "199" - local_block_low = "200" - local_block_high = "299" + global_block_low = "300" + global_block_high = "399" + local_block_low = "400" + local_block_high = "499" interface = 'lo' maximum_stack_size = '5' prefix_one = '192.168.0.1/32' diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py index 93bb761c1..51c947537 100755 --- a/smoketest/scripts/cli/test_protocols_ospf.py +++ b/smoketest/scripts/cli/test_protocols_ospf.py @@ -382,10 +382,10 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): def test_ospf_14_segment_routing_configuration(self): - global_block_low = "100" - global_block_high = "199" - local_block_low = "200" - local_block_high = "299" + global_block_low = "300" + global_block_high = "399" + local_block_low = "400" + local_block_high = "499" interface = 'lo' maximum_stack_size = '5' prefix_one = '192.168.0.1/32' @@ -408,16 +408,13 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Verify all changes - frrconfig = self.getFRRconfig('router ospf') + self.assertIn(f' segment-routing on', frrconfig) self.assertIn(f' segment-routing global-block {global_block_low} {global_block_high} local-block {local_block_low} {local_block_high}', frrconfig) self.assertIn(f' segment-routing node-msd {maximum_stack_size}', frrconfig) self.assertIn(f' segment-routing prefix {prefix_one} index {prefix_one_value} explicit-null', frrconfig) self.assertIn(f' segment-routing prefix {prefix_two} index {prefix_two_value} no-php-flag', frrconfig) - self.skipTest('https://github.com/FRRouting/frr/issues/12007') - self.assertIn(f' segment-routing on', frrconfig) - if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_service_monitoring_telegraf.py b/smoketest/scripts/cli/test_service_monitoring_telegraf.py index c1c4044e6..ed486c3b9 100755 --- a/smoketest/scripts/cli/test_service_monitoring_telegraf.py +++ b/smoketest/scripts/cli/test_service_monitoring_telegraf.py @@ -60,6 +60,7 @@ class TestMonitoringTelegraf(VyOSUnitTestSHIM.TestCase): self.assertIn(f' token = "$INFLUX_TOKEN"', config) self.assertIn(f'urls = ["{url}:{port}"]', config) self.assertIn(f'bucket = "{bucket}"', config) + self.assertIn(f'[[inputs.exec]]', config) for input in inputs: self.assertIn(input, config) diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py index 1131b6f93..6006fe0f6 100755 --- a/smoketest/scripts/cli/test_system_login.py +++ b/smoketest/scripts/cli/test_system_login.py @@ -46,6 +46,14 @@ TTSb0X1zPGxPIRFy5GoGtO9Mm5h4OZk= """ class TestSystemLogin(VyOSUnitTestSHIM.TestCase): + @classmethod + def setUpClass(cls): + super(TestSystemLogin, cls).setUpClass() + + # ensure we can also run this test on a live system - so lets clean + # out the current configuration which will break this test + cls.cli_delete(cls, base_path + ['radius']) + def tearDown(self): # Delete individual users from configuration for user in users: @@ -97,6 +105,22 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase): # b'Linux LR1.wue3 5.10.61-amd64-vyos #1 SMP Fri Aug 27 08:55:46 UTC 2021 x86_64 GNU/Linux\n' self.assertTrue(len(stdout) > 40) + def test_system_login_otp(self): + otp_user = 'otp-test_user' + otp_password = 'SuperTestPassword' + otp_key = '76A3ZS6HFHBTOK2H4NDHTIVFPQ' + + self.cli_set(base_path + ['user', otp_user, 'authentication', 'plaintext-password', otp_password]) + self.cli_set(base_path + ['user', otp_user, 'authentication', 'otp', 'key', otp_key]) + + self.cli_commit() + + # Check if OTP key was written properly + tmp = cmd(f'sudo head -1 /home/{otp_user}/.google_authenticator') + self.assertIn(otp_key, tmp) + + self.cli_delete(base_path + ['user', otp_user]) + def test_system_user_ssh_key(self): ssh_user = 'ssh-test_user' public_keys = 'vyos_test@domain-foo.com' diff --git a/src/conf_mode/http-api.py b/src/conf_mode/http-api.py index 04113fc09..c196e272b 100755 --- a/src/conf_mode/http-api.py +++ b/src/conf_mode/http-api.py @@ -24,9 +24,11 @@ from copy import deepcopy import vyos.defaults from vyos.config import Config +from vyos.configdict import dict_merge from vyos.template import render from vyos.util import cmd from vyos.util import call +from vyos.xml import defaults from vyos import ConfigError from vyos import airbag airbag.enable() @@ -36,6 +38,15 @@ systemd_service = '/run/systemd/system/vyos-http-api.service' vyos_conf_scripts_dir=vyos.defaults.directories['conf_mode'] +def _translate_values_to_boolean(d: dict) -> dict: + for k in list(d): + if d[k] == {}: + d[k] = True + elif isinstance(d[k], dict): + _translate_values_to_boolean(d[k]) + else: + pass + def get_config(config=None): http_api = deepcopy(vyos.defaults.api_data) x = http_api.get('api_keys') @@ -54,48 +65,40 @@ def get_config(config=None): if not conf.exists(base): return None + api_dict = conf.get_config_dict(base, key_mangling=('-', '_'), + no_tag_node_value_mangle=True, + get_first_key=True) + + # One needs to 'flatten' the keys dict from the config into the + # http-api.conf format for api_keys: + if 'keys' in api_dict: + api_dict['api_keys'] = [] + for el in list(api_dict['keys']['id']): + key = api_dict['keys']['id'][el]['key'] + api_dict['api_keys'].append({'id': el, 'key': key}) + del api_dict['keys'] + # Do we run inside a VRF context? vrf_path = ['service', 'https', 'vrf'] if conf.exists(vrf_path): http_api['vrf'] = conf.return_value(vrf_path) - conf.set_level('service https api') - if conf.exists('strict'): - http_api['strict'] = True - - if conf.exists('debug'): - http_api['debug'] = True + if 'api_keys' in api_dict: + keys_added = True - if conf.exists('gql'): - http_api['gql'] = True - if conf.exists('gql introspection'): - http_api['introspection'] = True + if 'gql' in api_dict: + api_dict = dict_merge(defaults(base), api_dict) - if conf.exists('socket'): - http_api['socket'] = True - - if conf.exists('port'): - port = conf.return_value('port') - http_api['port'] = port - - if conf.exists('cors'): - http_api['cors'] = {} - if conf.exists('cors allow-origin'): - origins = conf.return_values('cors allow-origin') - http_api['cors']['origins'] = origins[:] - - if conf.exists('keys'): - for name in conf.list_nodes('keys id'): - if conf.exists('keys id {0} key'.format(name)): - key = conf.return_value('keys id {0} key'.format(name)) - new_key = { 'id': name, 'key': key } - http_api['api_keys'].append(new_key) - keys_added = True + http_api.update(api_dict) if keys_added and default_key: if default_key in http_api['api_keys']: http_api['api_keys'].remove(default_key) + # Finally, translate entries in http_api into boolean settings for + # backwards compatability of JSON http-api.conf file + _translate_values_to_boolean(http_api) + return http_api def verify(http_api): diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index 87456f00b..ff568d470 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -159,6 +159,11 @@ def verify(bgp): if 'ebgp_multihop' in peer_config and 'ttl_security' in peer_config: raise ConfigError('You can not set both ebgp-multihop and ttl-security hops') + # interface and ebgp-multihop can't be used in the same configration + if 'ebgp_multihop' in peer_config and 'interface' in peer_config: + raise ConfigError(f'Ebgp-multihop can not be used with directly connected '\ + f'neighbor "{peer}"') + # Check if neighbor has both override capability and strict capability match # configured at the same time. if 'override_capability' in peer_config and 'strict_capability_match' in peer_config: diff --git a/src/conf_mode/service_monitoring_telegraf.py b/src/conf_mode/service_monitoring_telegraf.py index 427cb6911..aafece47a 100755 --- a/src/conf_mode/service_monitoring_telegraf.py +++ b/src/conf_mode/service_monitoring_telegraf.py @@ -42,7 +42,11 @@ systemd_override = '/etc/systemd/system/telegraf.service.d/10-override.conf' def get_nft_filter_chains(): """ Get nft chains for table filter """ - nft = cmd('nft --json list table ip vyos_filter') + try: + nft = cmd('nft --json list table ip vyos_filter') + except Exception: + print('nft table ip vyos_filter not found') + return [] nft = json.loads(nft) chain_list = [] diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index dbd346fe4..e26b81e3d 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -257,6 +257,15 @@ def apply(login): except Exception as e: raise ConfigError(f'Adding user "{user}" raised exception: "{e}"') + # Generate 2FA/MFA One-Time-Pad configuration + if dict_search('authentication.otp.key', user_config): + render(f'{home_dir}/.google_authenticator', 'login/pam_otp_ga.conf.j2', + user_config, permission=0o400, user=user, group='users') + else: + # delete configuration as it's not enabled for the user + if os.path.exists(f'{home_dir}/.google_authenticator'): + os.remove(f'{home_dir}/.google_authenticator') + if 'rm_users' in login: for user in login['rm_users']: try: diff --git a/src/etc/sudoers.d/vyos b/src/etc/sudoers.d/vyos index f760b417f..e0fd8cb0b 100644 --- a/src/etc/sudoers.d/vyos +++ b/src/etc/sudoers.d/vyos @@ -40,10 +40,13 @@ Cmnd_Alias PCAPTURE = /usr/bin/tcpdump Cmnd_Alias HWINFO = /usr/bin/lspci Cmnd_Alias FORCE_CLUSTER = /usr/share/heartbeat/hb_takeover, \ /usr/share/heartbeat/hb_standby +Cmnd_Alias DIAGNOSTICS = /bin/ip vrf exec * /bin/ping *, \ + /bin/ip vrf exec * /bin/traceroute *, \ + /usr/libexec/vyos/op_mode/* %operator ALL=NOPASSWD: DATE, IPTABLES, ETHTOOL, IPFLUSH, HWINFO, \ PPPOE_CMDS, PCAPTURE, /usr/sbin/wanpipemon, \ DMIDECODE, DISK, CONNTRACK, IP6TABLES, \ - FORCE_CLUSTER + FORCE_CLUSTER, DIAGNOSTICS # Allow any user to run files in sudo-users %users ALL=NOPASSWD: /opt/vyatta/bin/sudo-users/ diff --git a/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py b/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py index cbc2bfe6b..d7eca5894 100755 --- a/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py +++ b/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py @@ -11,7 +11,10 @@ def get_nft_filter_chains(): """ Get list of nft chains for table filter """ - nft = cmd('/usr/sbin/nft --json list table ip vyos_filter') + try: + nft = cmd('/usr/sbin/nft --json list table ip vyos_filter') + except Exception: + return [] nft = json.loads(nft) chain_list = [] diff --git a/src/op_mode/ipsec.py b/src/op_mode/ipsec.py index a4d1b4cb1..7ec35d7bd 100755 --- a/src/op_mode/ipsec.py +++ b/src/op_mode/ipsec.py @@ -133,14 +133,13 @@ def _get_formatted_output_sas(sas): def get_peer_connections(peer, tunnel, return_all = False): - peer = peer.replace(':', '-') - search = rf'^[\s]*(peer_{peer}_(tunnel_[\d]+|vti)).*' + search = rf'^[\s]*({peer}-(tunnel-[\d]+|vti)).*' matches = [] with open(SWANCTL_CONF, 'r') as f: for line in f.readlines(): result = re.match(search, line) if result: - suffix = f'tunnel_{tunnel}' if tunnel.isnumeric() else tunnel + suffix = f'tunnel-{tunnel}' if tunnel.isnumeric() else tunnel if return_all or (result[2] == suffix): matches.append(result[1]) return matches diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server index 190f3409d..4ace981ca 100755 --- a/src/services/vyos-http-api-server +++ b/src/services/vyos-http-api-server @@ -686,10 +686,16 @@ if __name__ == '__main__': app.state.vyos_keys = server_config['api_keys'] app.state.vyos_debug = server_config['debug'] - app.state.vyos_gql = server_config['gql'] - app.state.vyos_introspection = server_config['introspection'] app.state.vyos_strict = server_config['strict'] - app.state.vyos_origins = server_config.get('cors', {}).get('origins', []) + app.state.vyos_origins = server_config.get('cors', {}).get('allow_origin', []) + if 'gql' in server_config: + app.state.vyos_gql = True + if isinstance(server_config['gql'], dict) and 'introspection' in server_config['gql']: + app.state.vyos_introspection = True + else: + app.state.vyos_introspection = False + else: + app.state.vyos_gql = False if app.state.vyos_gql: graphql_init(app) |