summaryrefslogtreecommitdiff
path: root/src/op_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/op_mode')
-rwxr-xr-xsrc/op_mode/dhcp.py10
-rwxr-xr-xsrc/op_mode/firewall.py223
-rwxr-xr-xsrc/op_mode/pki.py23
-rwxr-xr-xsrc/op_mode/show_openconnect_otp.py38
-rw-r--r--src/op_mode/show_techsupport_report.py3
5 files changed, 154 insertions, 143 deletions
diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py
index 20ef698bd..f558c18b7 100755
--- a/src/op_mode/dhcp.py
+++ b/src/op_mode/dhcp.py
@@ -295,8 +295,10 @@ def show_server_leases(raw: bool, family: ArgFamily, pool: typing.Optional[str],
def _get_raw_client_leases(family='inet', interface=None):
from time import mktime
from datetime import datetime
+ from vyos.defaults import directories
+ from vyos.utils.network import get_interface_vrf
- lease_dir = '/var/lib/dhcp'
+ lease_dir = directories['isc_dhclient_dir']
lease_files = []
lease_data = []
@@ -324,6 +326,10 @@ def _get_raw_client_leases(family='inet', interface=None):
k, v = line.split('=')
tmp.update({k : v.replace("'", "")})
+ if 'interface' in tmp:
+ vrf = get_interface_vrf(tmp['interface'])
+ if vrf: tmp.update({'vrf' : vrf})
+
lease_data.append(tmp)
return lease_data
@@ -352,6 +358,8 @@ def _get_formatted_client_leases(lease_data, family):
data_entries.append(["DHCP Server", lease['new_dhcp_server_identifier']])
if 'new_dhcp_lease_time' in lease:
data_entries.append(["DHCP Server", lease['new_dhcp_lease_time']])
+ if 'vrf' in lease:
+ data_entries.append(["VRF", lease['vrf']])
if 'last_update' in lease:
tmp = strftime(time_string, localtime(int(lease['last_update'])))
data_entries.append(["Last Update", tmp])
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index 8260bbb77..852a7248a 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -24,62 +24,27 @@ from vyos.config import Config
from vyos.utils.process import cmd
from vyos.utils.dict import dict_search_args
-def get_firewall_interfaces(firewall, name=None, ipv6=False):
- directions = ['in', 'out', 'local']
-
- if 'interface' in firewall:
- for ifname, if_conf in firewall['interface'].items():
- for direction in directions:
- if direction not in if_conf:
- continue
-
- fw_conf = if_conf[direction]
- name_str = f'({ifname},{direction})'
-
- if 'name' in fw_conf:
- fw_name = fw_conf['name']
-
- if not name:
- firewall['name'][fw_name]['interface'].append(name_str)
- elif not ipv6 and name == fw_name:
- firewall['interface'].append(name_str)
-
- if 'ipv6_name' in fw_conf:
- fw_name = fw_conf['ipv6_name']
-
- if not name:
- firewall['ipv6_name'][fw_name]['interface'].append(name_str)
- elif ipv6 and name == fw_name:
- firewall['interface'].append(name_str)
-
- return firewall
-
-def get_config_firewall(conf, name=None, ipv6=False, interfaces=True):
+def get_config_firewall(conf, hook=None, priority=None, ipv6=False, interfaces=True):
config_path = ['firewall']
- if name:
- config_path += ['ipv6-name' if ipv6 else 'name', name]
+ if hook:
+ config_path += ['ipv6' if ipv6 else 'ipv4', hook]
+ if priority:
+ config_path += [priority]
firewall = conf.get_config_dict(config_path, key_mangling=('-', '_'),
get_first_key=True, no_tag_node_value_mangle=True)
- if firewall and interfaces:
- if name:
- firewall['interface'] = {}
- else:
- if 'name' in firewall:
- for fw_name, name_conf in firewall['name'].items():
- name_conf['interface'] = []
- if 'ipv6_name' in firewall:
- for fw_name, name_conf in firewall['ipv6_name'].items():
- name_conf['interface'] = []
-
- get_firewall_interfaces(firewall, name, ipv6)
return firewall
-def get_nftables_details(name, ipv6=False):
+def get_nftables_details(hook, priority, ipv6=False):
suffix = '6' if ipv6 else ''
name_prefix = 'NAME6_' if ipv6 else 'NAME_'
- command = f'sudo nft list chain ip{suffix} vyos_filter {name_prefix}{name}'
+ if hook == 'name' or hook == 'ipv6-name':
+ command = f'sudo nft list chain ip{suffix} vyos_filter {name_prefix}{priority}'
+ else:
+ up_hook = hook.upper()
+ command = f'sudo nft list chain ip{suffix} vyos_filter VYOS_{up_hook}_{priority}'
+
try:
results = cmd(command)
except:
@@ -87,7 +52,7 @@ def get_nftables_details(name, ipv6=False):
out = {}
for line in results.split('\n'):
- comment_search = re.search(rf'{name}[\- ](\d+|default-action)', line)
+ comment_search = re.search(rf'{priority}[\- ](\d+|default-action)', line)
if not comment_search:
continue
@@ -102,18 +67,15 @@ def get_nftables_details(name, ipv6=False):
out[rule_id] = rule
return out
-def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None):
+def output_firewall_name(hook, priority, firewall_conf, ipv6=False, single_rule_id=None):
ip_str = 'IPv6' if ipv6 else 'IPv4'
- print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n')
-
- if name_conf['interface']:
- print('Active on: {0}\n'.format(" ".join(name_conf['interface'])))
+ print(f'\n---------------------------------\n{ip_str} Firewall "{hook} {priority}"\n')
- details = get_nftables_details(name, ipv6)
+ details = get_nftables_details(hook, priority, ipv6)
rows = []
- if 'rule' in name_conf:
- for rule_id, rule_conf in name_conf['rule'].items():
+ if 'rule' in firewall_conf:
+ for rule_id, rule_conf in firewall_conf['rule'].items():
if single_rule_id and rule_id != single_rule_id:
continue
@@ -128,8 +90,8 @@ def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None):
row.append(rule_details['conditions'])
rows.append(row)
- if 'default_action' in name_conf and not single_rule_id:
- row = ['default', name_conf['default_action'], 'all']
+ if 'default_action' in firewall_conf and not single_rule_id:
+ row = ['default', firewall_conf['default_action'], 'all']
if 'default-action' in details:
rule_details = details['default-action']
row.append(rule_details.get('packets', 0))
@@ -140,18 +102,15 @@ def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None):
header = ['Rule', 'Action', 'Protocol', 'Packets', 'Bytes', 'Conditions']
print(tabulate.tabulate(rows, header) + '\n')
-def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id=None):
+def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_rule_id=None):
ip_str = 'IPv6' if ipv6 else 'IPv4'
- print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n')
+ print(f'\n---------------------------------\n{ip_str} Firewall "{hook} {prior}"\n')
- if name_conf['interface']:
- print('Active on: {0}\n'.format(" ".join(name_conf['interface'])))
-
- details = get_nftables_details(name, ipv6)
+ details = get_nftables_details(prior, ipv6)
rows = []
- if 'rule' in name_conf:
- for rule_id, rule_conf in name_conf['rule'].items():
+ if 'rule' in prior_conf:
+ for rule_id, rule_conf in prior_conf['rule'].items():
if single_rule_id and rule_id != single_rule_id:
continue
@@ -174,7 +133,7 @@ def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id=
row.append(dest_addr)
rows.append(row)
- if 'default_action' in name_conf and not single_rule_id:
+ if 'default_action' in prior_conf and not single_rule_id:
row = ['default']
if 'default-action' in details:
rule_details = details['default-action']
@@ -183,7 +142,7 @@ def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id=
else:
row.append('0')
row.append('0')
- row.append(name_conf['default_action'])
+ row.append(prior_conf['default_action'])
row.append('0.0.0.0/0') # Source
row.append('0.0.0.0/0') # Dest
rows.append(row)
@@ -201,29 +160,47 @@ def show_firewall():
if not firewall:
return
- if 'name' in firewall:
- for name, name_conf in firewall['name'].items():
- output_firewall_name(name, name_conf, ipv6=False)
+ if 'ipv4' in firewall:
+ for hook, hook_conf in firewall['ipv4'].items():
+ for prior, prior_conf in firewall['ipv4'][hook].items():
+ output_firewall_name(hook, prior, prior_conf, ipv6=False)
+
+ if 'ipv6' in firewall:
+ for hook, hook_conf in firewall['ipv6'].items():
+ for prior, prior_conf in firewall['ipv6'][hook].items():
+ output_firewall_name(hook, prior, prior_conf, ipv6=True)
- if 'ipv6_name' in firewall:
- for name, name_conf in firewall['ipv6_name'].items():
- output_firewall_name(name, name_conf, ipv6=True)
+def show_firewall_family(family):
+ print(f'Rulesets {family} Information')
-def show_firewall_name(name, ipv6=False):
+ conf = Config()
+ firewall = get_config_firewall(conf)
+
+ if not firewall:
+ return
+
+ for hook, hook_conf in firewall[family].items():
+ for prior, prior_conf in firewall[family][hook].items():
+ if family == 'ipv6':
+ output_firewall_name(hook, prior, prior_conf, ipv6=True)
+ else:
+ output_firewall_name(hook, prior, prior_conf, ipv6=False)
+
+def show_firewall_name(hook, priority, ipv6=False):
print('Ruleset Information')
conf = Config()
- firewall = get_config_firewall(conf, name, ipv6)
+ firewall = get_config_firewall(conf, hook, priority, ipv6)
if firewall:
- output_firewall_name(name, firewall, ipv6)
+ output_firewall_name(hook, priority, firewall, ipv6)
-def show_firewall_rule(name, rule_id, ipv6=False):
+def show_firewall_rule(hook, priority, rule_id, ipv6=False):
print('Rule Information')
conf = Config()
- firewall = get_config_firewall(conf, name, ipv6)
+ firewall = get_config_firewall(conf, hook, priority, ipv6)
if firewall:
- output_firewall_name(name, firewall, ipv6, rule_id)
+ output_firewall_name(hook, priority, firewall, ipv6, rule_id)
def show_firewall_group(name=None):
conf = Config()
@@ -234,19 +211,32 @@ def show_firewall_group(name=None):
def find_references(group_type, group_name):
out = []
- for name_type in ['name', 'ipv6_name']:
- if name_type not in firewall:
- continue
- for name, name_conf in firewall[name_type].items():
- if 'rule' not in name_conf:
+ family = []
+ if group_type in ['address_group', 'network_group']:
+ family = ['ipv4']
+ elif group_type == 'ipv6_address_group':
+ family = ['ipv6']
+ group_type = 'address_group'
+ elif group_type == 'ipv6_network_group':
+ family = ['ipv6']
+ group_type = 'network_group'
+ else:
+ family = ['ipv4', 'ipv6']
+
+ for item in family:
+ for name_type in ['name', 'ipv6_name', 'forward', 'input', 'output']:
+ if name_type not in firewall[item]:
continue
- for rule_id, rule_conf in name_conf['rule'].items():
- source_group = dict_search_args(rule_conf, 'source', 'group', group_type)
- dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type)
- if source_group and group_name == source_group:
- out.append(f'{name}-{rule_id}')
- elif dest_group and group_name == dest_group:
- out.append(f'{name}-{rule_id}')
+ for name, name_conf in firewall[item][name_type].items():
+ if 'rule' not in name_conf:
+ continue
+ for rule_id, rule_conf in name_conf['rule'].items():
+ source_group = dict_search_args(rule_conf, 'source', 'group', group_type)
+ dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type)
+ if source_group and group_name == source_group:
+ out.append(f'{name}-{rule_id}')
+ elif dest_group and group_name == dest_group:
+ out.append(f'{name}-{rule_id}')
return out
header = ['Name', 'Type', 'References', 'Members']
@@ -284,28 +274,28 @@ def show_summary():
if not firewall:
return
- header = ['Ruleset Name', 'Description', 'References']
+ header = ['Ruleset Hook', 'Ruleset Priority', 'Description', 'References']
v4_out = []
v6_out = []
- if 'name' in firewall:
- for name, name_conf in firewall['name'].items():
- description = name_conf.get('description', '')
- interfaces = ", ".join(name_conf['interface'])
- v4_out.append([name, description, interfaces])
+ if 'ipv4' in firewall:
+ for hook, hook_conf in firewall['ipv4'].items():
+ for prior, prior_conf in firewall['ipv4'][hook].items():
+ description = prior_conf.get('description', '')
+ v4_out.append([hook, prior, description])
- if 'ipv6_name' in firewall:
- for name, name_conf in firewall['ipv6_name'].items():
- description = name_conf.get('description', '')
- interfaces = ", ".join(name_conf['interface'])
- v6_out.append([name, description, interfaces or 'N/A'])
+ if 'ipv6' in firewall:
+ for hook, hook_conf in firewall['ipv6'].items():
+ for prior, prior_conf in firewall['ipv6'][hook].items():
+ description = prior_conf.get('description', '')
+ v6_out.append([hook, prior, description])
if v6_out:
- print('\nIPv6 name:\n')
+ print('\nIPv6 Ruleset:\n')
print(tabulate.tabulate(v6_out, header) + '\n')
if v4_out:
- print('\nIPv4 name:\n')
+ print('\nIPv4 Ruleset:\n')
print(tabulate.tabulate(v4_out, header) + '\n')
show_firewall_group()
@@ -319,18 +309,23 @@ def show_statistics():
if not firewall:
return
- if 'name' in firewall:
- for name, name_conf in firewall['name'].items():
- output_firewall_name_statistics(name, name_conf, ipv6=False)
+ if 'ipv4' in firewall:
+ for hook, hook_conf in firewall['ipv4'].items():
+ for prior, prior_conf in firewall['ipv4'][hook].items():
+ output_firewall_name_statistics(hook,prior, prior_conf, ipv6=False)
- if 'ipv6_name' in firewall:
- for name, name_conf in firewall['ipv6_name'].items():
- output_firewall_name_statistics(name, name_conf, ipv6=True)
+ if 'ipv6' in firewall:
+ for hook, hook_conf in firewall['ipv6'].items():
+ for prior, prior_conf in firewall['ipv6'][hook].items():
+ output_firewall_name_statistics(hook,prior, prior_conf, ipv6=True)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--action', help='Action', required=False)
parser.add_argument('--name', help='Firewall name', required=False, action='store', nargs='?', default='')
+ parser.add_argument('--family', help='IP family', required=False, action='store', nargs='?', default='')
+ parser.add_argument('--hook', help='Firewall hook', required=False, action='store', nargs='?', default='')
+ parser.add_argument('--priority', help='Firewall priority', required=False, action='store', nargs='?', default='')
parser.add_argument('--rule', help='Firewall Rule ID', required=False)
parser.add_argument('--ipv6', help='IPv6 toggle', action='store_true')
@@ -338,11 +333,13 @@ if __name__ == '__main__':
if args.action == 'show':
if not args.rule:
- show_firewall_name(args.name, args.ipv6)
+ show_firewall_name(args.hook, args.priority, args.ipv6)
else:
- show_firewall_rule(args.name, args.rule, args.ipv6)
+ show_firewall_rule(args.hook, args.priority, args.rule, args.ipv6)
elif args.action == 'show_all':
show_firewall()
+ elif args.action == 'show_family':
+ show_firewall_family(args.family)
elif args.action == 'show_group':
show_firewall_group(args.name)
elif args.action == 'show_statistics':
diff --git a/src/op_mode/pki.py b/src/op_mode/pki.py
index 4c31291ad..35c7ce0e2 100755
--- a/src/op_mode/pki.py
+++ b/src/op_mode/pki.py
@@ -25,9 +25,8 @@ from cryptography import x509
from cryptography.x509.oid import ExtendedKeyUsageOID
from vyos.config import Config
-from vyos.configquery import ConfigTreeQuery
-from vyos.configdict import dict_merge
from vyos.pki import encode_certificate, encode_public_key, encode_private_key, encode_dh_parameters
+from vyos.pki import get_certificate_fingerprint
from vyos.pki import create_certificate, create_certificate_request, create_certificate_revocation_list
from vyos.pki import create_private_key
from vyos.pki import create_dh_parameters
@@ -38,21 +37,19 @@ from vyos.utils.io import ask_input
from vyos.utils.io import ask_yes_no
from vyos.utils.misc import install_into_config
from vyos.utils.process import cmd
-from vyos.xml import defaults
CERT_REQ_END = '-----END CERTIFICATE REQUEST-----'
auth_dir = '/config/auth'
# Helper Functions
-conf = ConfigTreeQuery()
+conf = Config()
def get_default_values():
# Fetch default x509 values
base = ['pki', 'x509', 'default']
x509_defaults = conf.get_config_dict(base, key_mangling=('-', '_'),
+ no_tag_node_value_mangle=True,
get_first_key=True,
- no_tag_node_value_mangle=True)
- default_values = defaults(base)
- x509_defaults = dict_merge(default_values, x509_defaults)
+ with_recursive_defaults=True)
return x509_defaults
@@ -916,6 +913,12 @@ def show_certificate(name=None, pem=False):
print("Certificates:")
print(tabulate.tabulate(data, headers))
+def show_certificate_fingerprint(name, hash):
+ cert = get_config_certificate(name=name)
+ cert = load_certificate(cert['certificate'])
+
+ print(get_certificate_fingerprint(cert, hash))
+
def show_crl(name=None, pem=False):
headers = ['CA Name', 'Updated', 'Revokes']
data = []
@@ -961,6 +964,7 @@ if __name__ == '__main__':
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')
+ parser.add_argument('--fingerprint', help='Show fingerprint and exit', action='store')
# SSH
parser.add_argument('--ssh', help='SSH Key', required=False)
@@ -1057,7 +1061,10 @@ if __name__ == '__main__':
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, args.pem)
+ if args.fingerprint is None:
+ show_certificate(None if args.certificate == 'all' else args.certificate, args.pem)
+ else:
+ show_certificate_fingerprint(args.certificate, args.fingerprint)
elif args.crl:
show_crl(None if args.crl == 'all' else args.crl, args.pem)
else:
diff --git a/src/op_mode/show_openconnect_otp.py b/src/op_mode/show_openconnect_otp.py
index 415a5f72c..3771fb385 100755
--- a/src/op_mode/show_openconnect_otp.py
+++ b/src/op_mode/show_openconnect_otp.py
@@ -17,12 +17,11 @@
import argparse
import os
+from base64 import b32encode
from vyos.config import Config
-from vyos.xml import defaults
-from vyos.configdict import dict_merge
+from vyos.utils.dict import dict_search_args
from vyos.utils.process import popen
-from base64 import b32encode
otp_file = '/run/ocserv/users.oath'
@@ -33,7 +32,7 @@ def check_uname_otp(username):
config = Config()
base_key = ['vpn', 'openconnect', 'authentication', 'local-users', 'username', username, 'otp', 'key']
if not config.exists(base_key):
- return None
+ return False
return True
def get_otp_ocserv(username):
@@ -41,21 +40,21 @@ def get_otp_ocserv(username):
base = ['vpn', 'openconnect']
if not config.exists(base):
return None
- ocserv = config.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
- # We have gathered the dict representation of the CLI, but there are default
- # options which we need to update into the dictionary retrived.
- default_values = defaults(base)
- ocserv = dict_merge(default_values, ocserv)
- # workaround a "know limitation" - https://vyos.dev/T2665
- del ocserv['authentication']['local_users']['username']['otp']
- if not ocserv["authentication"]["local_users"]["username"]:
+
+ ocserv = config.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True,
+ with_recursive_defaults=True)
+
+ user_path = ['authentication', 'local_users', 'username']
+ users = dict_search_args(ocserv, *user_path)
+
+ if users is None:
return None
- default_ocserv_usr_values = default_values['authentication']['local_users']['username']['otp']
- for user, params in ocserv['authentication']['local_users']['username'].items():
- # Not every configuration requires OTP settings
- if ocserv['authentication']['local_users']['username'][user].get('otp'):
- ocserv['authentication']['local_users']['username'][user]['otp'] = dict_merge(default_ocserv_usr_values, ocserv['authentication']['local_users']['username'][user]['otp'])
- result = ocserv['authentication']['local_users']['username'][username]
+
+ # function is called conditionally, if check_uname_otp true, so username
+ # exists
+ result = users[username]
+
return result
def display_otp_ocserv(username, params, info):
@@ -101,8 +100,7 @@ if __name__ == '__main__':
parser.add_argument('--info', action="store", type=str, default='full', help='Wich information to display')
args = parser.parse_args()
- check_otp = check_uname_otp(args.user)
- if check_otp:
+ if check_uname_otp(args.user):
user_otp_params = get_otp_ocserv(args.user)
display_otp_ocserv(args.user, user_otp_params, args.info)
else:
diff --git a/src/op_mode/show_techsupport_report.py b/src/op_mode/show_techsupport_report.py
index d27221e54..53144fd52 100644
--- a/src/op_mode/show_techsupport_report.py
+++ b/src/op_mode/show_techsupport_report.py
@@ -91,7 +91,8 @@ def show_package_repository_config() -> None:
def show_user_startup_scripts() -> None:
"""Prints the user startup scripts."""
- execute_command('cat /config/scripts/vyos-postconfig-bootup.script', 'User Startup Scripts')
+ execute_command('cat /config/scripts/vyos-preconfig-bootup.script', 'User Startup Scripts (Preconfig)')
+ execute_command('cat /config/scripts/vyos-postconfig-bootup.script', 'User Startup Scripts (Postconfig)')
def show_frr_config() -> None: