diff options
-rwxr-xr-x | src/op_mode/show_ipsec_sa.py | 167 |
1 files changed, 90 insertions, 77 deletions
diff --git a/src/op_mode/show_ipsec_sa.py b/src/op_mode/show_ipsec_sa.py index 503366dd8..beb632fa8 100755 --- a/src/op_mode/show_ipsec_sa.py +++ b/src/op_mode/show_ipsec_sa.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019 VyOS maintainers and contributors +# Copyright (C) 2019-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 @@ -29,35 +29,22 @@ def convert(text): def alphanum_key(key): return [convert(c) for c in re.split('([0-9]+)', str(key))] -try: - session = vici.Session() - sas = session.list_sas() -except PermissionError: - print("You do not have a permission to connect to the IPsec daemon") - sys.exit(1) -except ConnectionRefusedError: - print("IPsec is not runing") - sys.exit(1) -except Exception as e: - print("An error occured: {0}".format(e)) - sys.exit(1) - -sa_data = [] - -for sa in sas: - # list_sas() returns a list of single-item dicts - for peer in sa: - parent_sa = sa[peer] - child_sas = parent_sa["child-sas"] - installed_sas = {k: v for k, v in child_sas.items() if v["state"] == b"INSTALLED"} - - # parent_sa["state"] = IKE state, child_sas["state"] = ESP state +def format_output(conns, sas): + sa_data = [] + + for peer, parent_conn in conns.items(): + if peer not in sas: + continue + + parent_sa = sas[peer] + child_sas = parent_sa['child-sas'] + installed_sas = {v['name'].decode(): v for k, v in child_sas.items() if v["state"] == b"INSTALLED"} + + state = 'down' + uptime = 'N/A' + if parent_sa["state"] == b"ESTABLISHED" and installed_sas: state = "up" - else: - state = "down" - - uptime = "N/A" remote_host = parent_sa["remote-host"].decode() remote_id = parent_sa["remote-id"].decode() @@ -66,53 +53,79 @@ for sa in sas: remote_id = "N/A" # The counters can only be obtained from the child SAs - if not installed_sas: - data = [peer, state, "N/A", "N/A", "N/A", "N/A", "N/A", "N/A"] - sa_data.append(data) - else: - for csa in installed_sas: - isa = installed_sas[csa] - csa_name = isa['name'] - csa_name = csa_name.decode() - - bytes_in = hurry.filesize.size(int(isa["bytes-in"].decode())) - bytes_out = hurry.filesize.size(int(isa["bytes-out"].decode())) - bytes_str = "{0}/{1}".format(bytes_in, bytes_out) - - pkts_in = hurry.filesize.size(int(isa["packets-in"].decode()), system=hurry.filesize.si) - pkts_out = hurry.filesize.size(int(isa["packets-out"].decode()), system=hurry.filesize.si) - pkts_str = "{0}/{1}".format(pkts_in, pkts_out) - # Remove B from <1K values - pkts_str = re.sub(r'B', r'', pkts_str) - - uptime = vyos.util.seconds_to_human(isa['install-time'].decode()) - - enc = isa["encr-alg"].decode() - if "encr-keysize" in isa: - key_size = isa["encr-keysize"].decode() - else: - key_size = "" - if "integ-alg" in isa: - hash = isa["integ-alg"].decode() - else: - hash = "" - if "dh-group" in isa: - dh_group = isa["dh-group"].decode() - else: - dh_group = "" - - proposal = enc - if key_size: - proposal = "{0}_{1}".format(proposal, key_size) - if hash: - proposal = "{0}/{1}".format(proposal, hash) - if dh_group: - proposal = "{0}/{1}".format(proposal, dh_group) - - data = [csa_name, state, uptime, bytes_str, pkts_str, remote_host, remote_id, proposal] + for child_conn in parent_conn['children']: + if child_conn not in installed_sas: + data = [child_conn, "down", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A"] sa_data.append(data) - -headers = ["Connection", "State", "Uptime", "Bytes In/Out", "Packets In/Out", "Remote address", "Remote ID", "Proposal"] -sa_data = sorted(sa_data, key=alphanum_key) -output = tabulate.tabulate(sa_data, headers) -print(output) + continue + + isa = installed_sas[child_conn] + csa_name = isa['name'] + csa_name = csa_name.decode() + + bytes_in = hurry.filesize.size(int(isa["bytes-in"].decode())) + bytes_out = hurry.filesize.size(int(isa["bytes-out"].decode())) + bytes_str = "{0}/{1}".format(bytes_in, bytes_out) + + pkts_in = hurry.filesize.size(int(isa["packets-in"].decode()), system=hurry.filesize.si) + pkts_out = hurry.filesize.size(int(isa["packets-out"].decode()), system=hurry.filesize.si) + pkts_str = "{0}/{1}".format(pkts_in, pkts_out) + # Remove B from <1K values + pkts_str = re.sub(r'B', r'', pkts_str) + + uptime = vyos.util.seconds_to_human(isa['install-time'].decode()) + + enc = isa["encr-alg"].decode() + if "encr-keysize" in isa: + key_size = isa["encr-keysize"].decode() + else: + key_size = "" + if "integ-alg" in isa: + hash = isa["integ-alg"].decode() + else: + hash = "" + if "dh-group" in isa: + dh_group = isa["dh-group"].decode() + else: + dh_group = "" + + proposal = enc + if key_size: + proposal = "{0}_{1}".format(proposal, key_size) + if hash: + proposal = "{0}/{1}".format(proposal, hash) + if dh_group: + proposal = "{0}/{1}".format(proposal, dh_group) + + data = [csa_name, state, uptime, bytes_str, pkts_str, remote_host, remote_id, proposal] + sa_data.append(data) + return sa_data + +if __name__ == '__main__': + try: + session = vici.Session() + conns = {} + sas = {} + + for conn in session.list_conns(): + for key in conn: + conns[key] = conn[key] + + for sa in session.list_sas(): + for key in sa: + sas[key] = sa[key] + + headers = ["Connection", "State", "Uptime", "Bytes In/Out", "Packets In/Out", "Remote address", "Remote ID", "Proposal"] + sa_data = format_output(conns, sas) + sa_data = sorted(sa_data, key=alphanum_key) + output = tabulate.tabulate(sa_data, headers) + print(output) + except PermissionError: + print("You do not have a permission to connect to the IPsec daemon") + sys.exit(1) + except ConnectionRefusedError: + print("IPsec is not runing") + sys.exit(1) + except Exception as e: + print("An error occured: {0}".format(e)) + sys.exit(1) |