diff options
Diffstat (limited to 'src/op_mode')
-rwxr-xr-x | src/op_mode/bridge.py | 2 | ||||
-rwxr-xr-x | src/op_mode/conntrack.py | 25 | ||||
-rwxr-xr-x | src/op_mode/container.py | 2 | ||||
-rwxr-xr-x | src/op_mode/cpu.py | 2 | ||||
-rwxr-xr-x | src/op_mode/dns.py | 2 | ||||
-rwxr-xr-x | src/op_mode/ipsec.py | 2 | ||||
-rwxr-xr-x | src/op_mode/memory.py | 2 | ||||
-rwxr-xr-x | src/op_mode/nat.py | 37 | ||||
-rwxr-xr-x | src/op_mode/neighbor.py | 2 | ||||
-rwxr-xr-x | src/op_mode/openconnect-control.py | 5 | ||||
-rwxr-xr-x | src/op_mode/openconnect.py | 81 | ||||
-rwxr-xr-x | src/op_mode/restart_dhcp_relay.py | 4 | ||||
-rw-r--r-- | src/op_mode/route.py | 2 | ||||
-rwxr-xr-x | src/op_mode/show_nat66_rules.py | 102 | ||||
-rwxr-xr-x | src/op_mode/version.py | 2 | ||||
-rwxr-xr-x | src/op_mode/vrf.py | 2 |
16 files changed, 138 insertions, 136 deletions
diff --git a/src/op_mode/bridge.py b/src/op_mode/bridge.py index 411aa06d1..fe8dadd70 100755 --- a/src/op_mode/bridge.py +++ b/src/op_mode/bridge.py @@ -197,6 +197,6 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/conntrack.py b/src/op_mode/conntrack.py index 1441d110f..b27aa6060 100755 --- a/src/op_mode/conntrack.py +++ b/src/op_mode/conntrack.py @@ -51,6 +51,21 @@ def _get_raw_data(family): return _xml_to_dict(xml) +def _get_raw_statistics(): + entries = [] + data = cmd('sudo conntrack -S') + data = data.replace(' \t', '').split('\n') + for entry in data: + entries.append(entry.split()) + return entries + + +def get_formatted_statistics(entries): + headers = ["CPU", "Found", "Invalid", "Insert", "Insert fail", "Drop", "Early drop", "Errors", "Search restart"] + output = tabulate(entries, headers, numalign="left") + return output + + def get_formatted_output(dict_data): """ :param xml: @@ -111,11 +126,19 @@ def show(raw: bool, family: str): return get_formatted_output(conntrack_data) +def show_statistics(raw: bool): + conntrack_statistics = _get_raw_statistics() + if raw: + return conntrack_statistics + else: + return get_formatted_statistics(conntrack_statistics) + + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/container.py b/src/op_mode/container.py index 78d42f800..ce466ffc1 100755 --- a/src/op_mode/container.py +++ b/src/op_mode/container.py @@ -80,6 +80,6 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/cpu.py b/src/op_mode/cpu.py index f9c425826..d53663c17 100755 --- a/src/op_mode/cpu.py +++ b/src/op_mode/cpu.py @@ -76,7 +76,7 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/dns.py b/src/op_mode/dns.py index 717652b9b..9e5b1040c 100755 --- a/src/op_mode/dns.py +++ b/src/op_mode/dns.py @@ -90,6 +90,6 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/ipsec.py b/src/op_mode/ipsec.py index caa1eef51..a4d1b4cb1 100755 --- a/src/op_mode/ipsec.py +++ b/src/op_mode/ipsec.py @@ -182,6 +182,6 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/memory.py b/src/op_mode/memory.py index a3870e498..178544be4 100755 --- a/src/op_mode/memory.py +++ b/src/op_mode/memory.py @@ -84,7 +84,7 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/nat.py b/src/op_mode/nat.py index a98fc4227..dec04aa48 100755 --- a/src/op_mode/nat.py +++ b/src/op_mode/nat.py @@ -27,7 +27,7 @@ from vyos.util import dict_search import vyos.opmode -def _get_json_data(direction): +def _get_json_data(direction, family): """ Get NAT format JSON """ @@ -35,14 +35,15 @@ def _get_json_data(direction): chain = 'POSTROUTING' if direction == 'destination': chain = 'PREROUTING' - return cmd(f'sudo nft --json list chain ip nat {chain}') + family = 'ip6' if family == 'inet6' else 'ip' + return cmd(f'sudo nft --json list chain {family} nat {chain}') -def _get_raw_data_rules(direction): +def _get_raw_data_rules(direction, family): """Get interested rules :returns dict """ - data = _get_json_data(direction) + data = _get_json_data(direction, family) data_dict = json.loads(data) rules = [] for rule in data_dict['nftables']: @@ -51,10 +52,12 @@ def _get_raw_data_rules(direction): return rules -def _get_formatted_output_rules(data, direction): +def _get_formatted_output_rules(data, direction, family): # Add default values before loop sport, dport, proto = 'any', 'any', 'any' - saddr, daddr = '0.0.0.0/0', '0.0.0.0/0' + saddr = '::/0' if family == 'inet6' else '0.0.0.0/0' + daddr = '::/0' if family == 'inet6' else '0.0.0.0/0' + data_entries = [] for rule in data: if 'comment' in rule['rule']: @@ -69,11 +72,13 @@ def _get_formatted_output_rules(data, direction): if 'prefix' in match['right'] or 'set' in match['right']: # Merge dict src/dst l3_l4 parameters my_dict = {**match['left']['payload'], **match['right']} + my_dict['op'] = match['op'] + op = '!' if my_dict.get('op') == '!=' else '' proto = my_dict.get('protocol').upper() if my_dict['field'] == 'saddr': - saddr = f'{my_dict["prefix"]["addr"]}/{my_dict["prefix"]["len"]}' + saddr = f'{op}{my_dict["prefix"]["addr"]}/{my_dict["prefix"]["len"]}' elif my_dict['field'] == 'daddr': - daddr = f'{my_dict["prefix"]["addr"]}/{my_dict["prefix"]["len"]}' + daddr = f'{op}{my_dict["prefix"]["addr"]}/{my_dict["prefix"]["len"]}' elif my_dict['field'] == 'sport': # Port range or single port if jmespath.search('set[*].range', my_dict): @@ -96,8 +101,8 @@ def _get_formatted_output_rules(data, direction): if jmespath.search('left.payload.field', match) == 'daddr': daddr = match.get('right') else: - saddr = '0.0.0.0/0' - daddr = '0.0.0.0/0' + saddr = '::/0' if family == 'inet6' else '0.0.0.0/0' + daddr = '::/0' if family == 'inet6' else '0.0.0.0/0' sport = 'any' dport = 'any' proto = 'any' @@ -175,16 +180,16 @@ def _get_formatted_output_statistics(data, direction): return output -def show_rules(raw: bool, direction: str): - nat_rules = _get_raw_data_rules(direction) +def show_rules(raw: bool, direction: str, family: str): + nat_rules = _get_raw_data_rules(direction, family) if raw: return nat_rules else: - return _get_formatted_output_rules(nat_rules, direction) + return _get_formatted_output_rules(nat_rules, direction, family) -def show_statistics(raw: bool, direction: str): - nat_statistics = _get_raw_data_rules(direction) +def show_statistics(raw: bool, direction: str, family: str): + nat_statistics = _get_raw_data_rules(direction, family) if raw: return nat_statistics else: @@ -196,6 +201,6 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/neighbor.py b/src/op_mode/neighbor.py index d86a372ac..264dbdc72 100755 --- a/src/op_mode/neighbor.py +++ b/src/op_mode/neighbor.py @@ -116,7 +116,7 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/openconnect-control.py b/src/op_mode/openconnect-control.py index a128cc011..20c50e779 100755 --- a/src/op_mode/openconnect-control.py +++ b/src/op_mode/openconnect-control.py @@ -19,7 +19,6 @@ import argparse import json from vyos.config import Config -from vyos.util import commit_in_progress from vyos.util import popen from vyos.util import run from vyos.util import DEVNULL @@ -60,10 +59,6 @@ def main(): # Check is Openconnect server configured is_ocserv_configured() - if commit_in_progress(): - print('Cannot restart openconnect while a commit is in progress') - exit(1) - if args.action == "restart": run("sudo systemctl restart ocserv.service") sys.exit(0) diff --git a/src/op_mode/openconnect.py b/src/op_mode/openconnect.py new file mode 100755 index 000000000..00992c66a --- /dev/null +++ b/src/op_mode/openconnect.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022 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/>. + +import sys +import json + +from tabulate import tabulate +from vyos.configquery import ConfigTreeQuery +from vyos.util import rc_cmd + +import vyos.opmode + + +occtl = '/usr/bin/occtl' +occtl_socket = '/run/ocserv/occtl.socket' + + +def _get_raw_data_sessions(): + rc, out = rc_cmd(f'sudo {occtl} --json --socket-file {occtl_socket} show users') + if rc != 0: + output = {'openconnect': + { + 'configured': False, + 'return_code': rc, + 'reason': out + } + } + return output + + sessions = json.loads(out) + return sessions + + +def _get_formatted_sessions(data): + headers = ["Interface", "Username", "IP", "Remote IP", "RX", "TX", "State", "Uptime"] + ses_list = [] + for ses in data: + ses_list.append([ + ses["Device"], ses["Username"], ses["IPv4"], ses["Remote IP"], + ses["_RX"], ses["_TX"], ses["State"], ses["_Connected at"] + ]) + if len(ses_list) > 0: + output = tabulate(ses_list, headers) + else: + output = 'No active openconnect sessions' + return output + + +def show_sessions(raw: bool): + config = ConfigTreeQuery() + if not config.exists('vpn openconnect') and not raw: + print('Openconnect is not configured') + exit(0) + + openconnect_data = _get_raw_data_sessions() + if raw: + return openconnect_data + return _get_formatted_sessions(openconnect_data) + + +if __name__ == '__main__': + try: + res = vyos.opmode.run(sys.modules[__name__]) + if res: + print(res) + except (ValueError, vyos.opmode.Error) as e: + print(e) + sys.exit(1) diff --git a/src/op_mode/restart_dhcp_relay.py b/src/op_mode/restart_dhcp_relay.py index db5a48970..9203c009f 100755 --- a/src/op_mode/restart_dhcp_relay.py +++ b/src/op_mode/restart_dhcp_relay.py @@ -43,7 +43,7 @@ if __name__ == '__main__': if commit_in_progress(): print('Cannot restart DHCP relay while a commit is in progress') exit(1) - call('systemctl restart isc-dhcp-server.service') + call('systemctl restart isc-dhcp-relay.service') sys.exit(0) elif args.ipv6: @@ -54,7 +54,7 @@ if __name__ == '__main__': if commit_in_progress(): print('Cannot restart DHCPv6 relay while commit is in progress') exit(1) - call('systemctl restart isc-dhcp-server6.service') + call('systemctl restart isc-dhcp-relay6.service') sys.exit(0) else: diff --git a/src/op_mode/route.py b/src/op_mode/route.py index 3bb06adac..e1eee5bbf 100644 --- a/src/op_mode/route.py +++ b/src/op_mode/route.py @@ -92,7 +92,7 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/show_nat66_rules.py b/src/op_mode/show_nat66_rules.py deleted file mode 100755 index 967ec9d37..000000000 --- a/src/op_mode/show_nat66_rules.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021 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/>. - -import jmespath -import json - -from argparse import ArgumentParser -from jinja2 import Template -from sys import exit -from vyos.util import cmd -from vyos.util import dict_search - -parser = ArgumentParser() -group = parser.add_mutually_exclusive_group() -group.add_argument("--source", help="Show statistics for configured source NAT rules", action="store_true") -group.add_argument("--destination", help="Show statistics for configured destination NAT rules", action="store_true") -args = parser.parse_args() - -if args.source or args.destination: - tmp = cmd('sudo nft -j list table ip6 nat') - tmp = json.loads(tmp) - - format_nat66_rule = '{0: <10} {1: <50} {2: <50} {3: <10}' - print(format_nat66_rule.format("Rule", "Source" if args.source else "Destination", "Translation", "Outbound Interface" if args.source else "Inbound Interface")) - print(format_nat66_rule.format("----", "------" if args.source else "-----------", "-----------", "------------------" if args.source else "-----------------")) - - data_json = jmespath.search('nftables[?rule].rule[?chain]', tmp) - for idx in range(0, len(data_json)): - data = data_json[idx] - - # The following key values must exist - # When the rule JSON does not have some keys, this is not a rule we can work with - continue_rule = False - for key in ['comment', 'chain', 'expr']: - if key not in data: - continue_rule = True - continue - if continue_rule: - continue - - comment = data['comment'] - - # Check the annotation to see if the annotation format is created by VYOS - continue_rule = True - for comment_prefix in ['SRC-NAT66-', 'DST-NAT66-']: - if comment_prefix in comment: - continue_rule = False - if continue_rule: - continue - - # When log is detected from the second index of expr, then this rule should be ignored - if 'log' in data['expr'][2]: - continue - - rule = comment.replace('SRC-NAT66-','') - rule = rule.replace('DST-NAT66-','') - chain = data['chain'] - if not ((args.source and chain == 'POSTROUTING') or (not args.source and chain == 'PREROUTING')): - continue - interface = dict_search('match.right', data['expr'][0]) - srcdest = dict_search('match.right.prefix.addr', data['expr'][2]) - if srcdest: - addr_tmp = dict_search('match.right.prefix.len', data['expr'][2]) - if addr_tmp: - srcdest = srcdest + '/' + str(addr_tmp) - else: - srcdest = dict_search('match.right', data['expr'][2]) - - tran_addr_json = dict_search('snat.addr' if args.source else 'dnat.addr', data['expr'][3]) - if tran_addr_json: - if isinstance(srcdest_json,str): - tran_addr = tran_addr_json - - if 'prefix' in tran_addr_json: - addr_tmp = dict_search('snat.addr.prefix.addr' if args.source else 'dnat.addr.prefix.addr', data['expr'][3]) - len_tmp = dict_search('snat.addr.prefix.len' if args.source else 'dnat.addr.prefix.len', data['expr'][3]) - if addr_tmp: - tran_addr = addr_tmp + '/' + str(len_tmp) - else: - if 'masquerade' in data['expr'][3]: - tran_addr = 'masquerade' - - print(format_nat66_rule.format(rule, srcdest, tran_addr, interface)) - - exit(0) -else: - parser.print_help() - exit(1) - diff --git a/src/op_mode/version.py b/src/op_mode/version.py index 06208c3e5..ad0293aca 100755 --- a/src/op_mode/version.py +++ b/src/op_mode/version.py @@ -78,7 +78,7 @@ if __name__ == '__main__': res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) diff --git a/src/op_mode/vrf.py b/src/op_mode/vrf.py index e3d944d90..aeb50fe6e 100755 --- a/src/op_mode/vrf.py +++ b/src/op_mode/vrf.py @@ -90,6 +90,6 @@ if __name__ == "__main__": res = vyos.opmode.run(sys.modules[__name__]) if res: print(res) - except ValueError as e: + except (ValueError, vyos.opmode.Error) as e: print(e) sys.exit(1) |