summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/container.py7
-rwxr-xr-xsrc/conf_mode/interfaces_vxlan.py2
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py11
-rwxr-xr-xsrc/conf_mode/service_console-server.py8
-rwxr-xr-xsrc/conf_mode/system_login.py21
-rwxr-xr-xsrc/conf_mode/vpn_ipsec.py27
6 files changed, 72 insertions, 4 deletions
diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py
index 3636b0871..18d660a4e 100755
--- a/src/conf_mode/container.py
+++ b/src/conf_mode/container.py
@@ -289,6 +289,13 @@ def verify(container):
if 'registry' in container:
for registry, registry_config in container['registry'].items():
+ if 'mirror' in registry_config:
+ if 'host_name' in registry_config['mirror'] and 'address' in registry_config['mirror']:
+ raise ConfigError(f'Container registry mirror address/host-name are mutually exclusive!')
+
+ if 'path' in registry_config['mirror'] and not registry_config['mirror']['path'].startswith('/'):
+ raise ConfigError('Container registry mirror path must start with "/"!')
+
if 'authentication' not in registry_config:
continue
if not {'username', 'password'} <= set(registry_config['authentication']):
diff --git a/src/conf_mode/interfaces_vxlan.py b/src/conf_mode/interfaces_vxlan.py
index 68646e8ff..256b65708 100755
--- a/src/conf_mode/interfaces_vxlan.py
+++ b/src/conf_mode/interfaces_vxlan.py
@@ -95,6 +95,8 @@ def verify(vxlan):
if 'group' in vxlan:
if 'source_interface' not in vxlan:
raise ConfigError('Multicast VXLAN requires an underlaying interface')
+ if 'remote' in vxlan:
+ raise ConfigError('Both group and remote cannot be specified')
verify_source_interface(vxlan)
if not any(tmp in ['group', 'remote', 'source_address', 'source_interface'] for tmp in vxlan):
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index c4af717af..53e83c3b4 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -523,12 +523,21 @@ def verify(config_dict):
raise ConfigError(
'Please unconfigure import vrf commands before using vpn commands in dependent VRFs!')
+ if (dict_search('route_map.vrf.import', afi_config) is not None
+ or dict_search('import.vrf', afi_config) is not None):
# FRR error: please unconfigure vpn to vrf commands before
# using import vrf commands
- if 'vpn' in afi_config['import'] or dict_search('export.vpn', afi_config) != None:
+ if ('vpn' in afi_config['import']
+ or dict_search('export.vpn', afi_config) is not None):
raise ConfigError('Please unconfigure VPN to VRF commands before '\
'using "import vrf" commands!')
+ if (dict_search('route_map.vpn.import', afi_config) is not None
+ or dict_search('route_map.vpn.export', afi_config) is not None) :
+ raise ConfigError('Please unconfigure route-map VPN to VRF commands before '\
+ 'using "import vrf" commands!')
+
+
# Verify that the export/import route-maps do exist
for export_import in ['export', 'import']:
tmp = dict_search(f'route_map.vpn.{export_import}', afi_config)
diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py
index b112add3f..b83c6dfb1 100755
--- a/src/conf_mode/service_console-server.py
+++ b/src/conf_mode/service_console-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2025 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
@@ -98,6 +98,12 @@ def generate(proxy):
return None
def apply(proxy):
+ if not os.path.exists('/etc/dropbear/dropbear_rsa_host_key'):
+ call('dropbearkey -t rsa -s 4096 -f /etc/dropbear/dropbear_rsa_host_key')
+
+ if not os.path.exists('/etc/dropbear/dropbear_ecdsa_host_key'):
+ call('dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key')
+
call('systemctl daemon-reload')
call('systemctl stop dropbear@*.service conserver-server.service')
diff --git a/src/conf_mode/system_login.py b/src/conf_mode/system_login.py
index d3a969d9b..1e6061ecf 100755
--- a/src/conf_mode/system_login.py
+++ b/src/conf_mode/system_login.py
@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import warnings
from passlib.hosts import linux_context
from psutil import users
@@ -24,11 +25,17 @@ from pwd import getpwuid
from sys import exit
from time import sleep
+from vyos.base import Warning
from vyos.config import Config
from vyos.configverify import verify_vrf
from vyos.template import render
from vyos.template import is_ipv4
-from vyos.utils.auth import get_current_user
+from vyos.utils.auth import (
+ DEFAULT_PASSWORD,
+ EPasswdStrength,
+ evaluate_strength,
+ get_current_user
+)
from vyos.utils.configfs import delete_cli_node
from vyos.utils.configfs import add_cli_node
from vyos.utils.dict import dict_search
@@ -146,6 +153,18 @@ def verify(login):
if s_user.pw_name == user and s_user.pw_uid < MIN_USER_UID:
raise ConfigError(f'User "{user}" can not be created, conflict with local system account!')
+ # T6353: Check password for complexity using cracklib.
+ # A user password should be sufficiently complex
+ plaintext_password = dict_search(
+ path='authentication.plaintext_password',
+ dict_object=user_config
+ ) or None
+
+ if plaintext_password is not None:
+ result = evaluate_strength(plaintext_password)
+ if result['strength'] == EPasswdStrength.WEAK:
+ Warning(result['error'])
+
for pubkey, pubkey_options in (dict_search('authentication.public_keys', user_config) or {}).items():
if 'type' not in pubkey_options:
raise ConfigError(f'Missing type for public-key "{pubkey}"!')
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py
index 25604d2a2..71a503e61 100755
--- a/src/conf_mode/vpn_ipsec.py
+++ b/src/conf_mode/vpn_ipsec.py
@@ -156,6 +156,8 @@ def get_config(config=None):
_, vti = get_interface_dict(conf, ['interfaces', 'vti'], vti_interface)
ipsec['vti_interface_dicts'][vti_interface] = vti
+ ipsec['vpp_ipsec_exists'] = conf.exists(['vpp', 'settings', 'ipsec'])
+
return ipsec
def get_dhcp_address(iface):
@@ -484,6 +486,17 @@ def verify(ipsec):
else:
raise ConfigError(f"Missing ike-group on site-to-site peer {peer}")
+ # verify encryption algorithm compatibility for IKE with VPP
+ if ipsec['vpp_ipsec_exists']:
+ ike_group = ipsec['ike_group'][peer_conf['ike_group']]
+ for proposal, proposal_config in ike_group.get('proposal', {}).items():
+ algs = ['gmac', 'serpent', 'twofish']
+ if any(alg in proposal_config['encryption'] for alg in algs):
+ raise ConfigError(
+ f'Encryption algorithm {proposal_config["encryption"]} cannot be used '
+ f'for IKE proposal {proposal} for site-to-site peer {peer} with VPP'
+ )
+
if 'authentication' not in peer_conf or 'mode' not in peer_conf['authentication']:
raise ConfigError(f"Missing authentication on site-to-site peer {peer}")
@@ -562,7 +575,7 @@ def verify(ipsec):
esp_group_name = tunnel_conf['esp_group'] if 'esp_group' in tunnel_conf else peer_conf['default_esp_group']
- if esp_group_name not in ipsec['esp_group']:
+ if esp_group_name not in ipsec.get('esp_group'):
raise ConfigError(f"Invalid esp-group on tunnel {tunnel} for site-to-site peer {peer}")
esp_group = ipsec['esp_group'][esp_group_name]
@@ -574,6 +587,18 @@ def verify(ipsec):
if ('local' in tunnel_conf and 'prefix' in tunnel_conf['local']) or ('remote' in tunnel_conf and 'prefix' in tunnel_conf['remote']):
raise ConfigError(f"Local/remote prefix cannot be used with ESP transport mode on tunnel {tunnel} for site-to-site peer {peer}")
+ # verify ESP encryption algorithm compatibility with VPP
+ # because Marvel plugin for VPP doesn't support all algorithms that Strongswan does
+ if ipsec['vpp_ipsec_exists']:
+ for proposal, proposal_config in esp_group.get('proposal', {}).items():
+ algs = ['aes128', 'aes192', 'aes256', 'aes128gcm128', 'aes192gcm128', 'aes256gcm128']
+ if proposal_config['encryption'] not in algs:
+ raise ConfigError(
+ f'Encryption algorithm {proposal_config["encryption"]} cannot be used '
+ f'for ESP proposal {proposal} on tunnel {tunnel} for site-to-site peer {peer} with VPP'
+ )
+
+
def cleanup_pki_files():
for path in [CERT_PATH, CA_PATH, CRL_PATH, KEY_PATH, PUBKEY_PATH]:
if not os.path.exists(path):