From e41ae4d952e276d8497d38f5761806c14ea542d2 Mon Sep 17 00:00:00 2001 From: DmitriyEshenko Date: Wed, 9 Sep 2020 06:45:40 +0000 Subject: openconnect: T2036: Move CLI commands under vpn openconnect --- src/conf_mode/vpn_anyconnect.py | 135 ------------------------------------- src/conf_mode/vpn_openconnect.py | 135 +++++++++++++++++++++++++++++++++++++ src/op_mode/anyconnect-control.py | 67 ------------------ src/op_mode/openconnect-control.py | 67 ++++++++++++++++++ 4 files changed, 202 insertions(+), 202 deletions(-) delete mode 100755 src/conf_mode/vpn_anyconnect.py create mode 100755 src/conf_mode/vpn_openconnect.py delete mode 100755 src/op_mode/anyconnect-control.py create mode 100755 src/op_mode/openconnect-control.py (limited to 'src') diff --git a/src/conf_mode/vpn_anyconnect.py b/src/conf_mode/vpn_anyconnect.py deleted file mode 100755 index 158e1a117..000000000 --- a/src/conf_mode/vpn_anyconnect.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2018-2020 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 . - -import os -from sys import exit - -from vyos.config import Config -from vyos.configdict import dict_merge -from vyos.xml import defaults -from vyos.template import render -from vyos.util import call -from vyos import ConfigError -from crypt import crypt, mksalt, METHOD_SHA512 - -from vyos import airbag -airbag.enable() - -cfg_dir = '/run/ocserv' -ocserv_conf = cfg_dir + '/ocserv.conf' -ocserv_passwd = cfg_dir + '/ocpasswd' -radius_cfg = cfg_dir + '/radiusclient.conf' -radius_servers = cfg_dir + '/radius_servers' - - -# Generate hash from user cleartext password -def get_hash(password): - return crypt(password, mksalt(METHOD_SHA512)) - - -def get_config(): - conf = Config() - base = ['vpn', 'anyconnect'] - if not conf.exists(base): - return None - - ocserv = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) - default_values = defaults(base) - ocserv = dict_merge(default_values, ocserv) - return ocserv - - -def verify(ocserv): - if ocserv is None: - return None - - # Check authentication - if "authentication" in ocserv: - if "mode" in ocserv["authentication"]: - if "local" in ocserv["authentication"]["mode"]: - if not ocserv["authentication"]["local_users"] or not ocserv["authentication"]["local_users"]["username"]: - raise ConfigError('Anyconect mode local required at leat one user') - else: - for user in ocserv["authentication"]["local_users"]["username"]: - if not "password" in ocserv["authentication"]["local_users"]["username"][user]: - raise ConfigError(f'password required for user {user}') - else: - raise ConfigError('anyconnect authentication mode required') - else: - raise ConfigError('anyconnect authentication credentials required') - - # Check ssl - if "ssl" in ocserv: - req_cert = ['ca_cert_file', 'cert_file', 'key_file'] - for cert in req_cert: - if not cert in ocserv["ssl"]: - raise ConfigError('anyconnect ssl {0} required'.format(cert.replace('_', '-'))) - else: - raise ConfigError('anyconnect ssl required') - - # Check network settings - if "network_settings" in ocserv: - if "push_route" in ocserv["network_settings"]: - # Replace default route - if "0.0.0.0/0" in ocserv["network_settings"]["push_route"]: - ocserv["network_settings"]["push_route"].remove("0.0.0.0/0") - ocserv["network_settings"]["push_route"].append("default") - else: - ocserv["network_settings"]["push_route"] = "default" - else: - raise ConfigError('anyconnect network settings required') - - -def generate(ocserv): - if not ocserv: - return None - - if "radius" in ocserv["authentication"]["mode"]: - # Render radius client configuration - render(radius_cfg, 'ocserv/radius_conf.tmpl', ocserv["authentication"]["radius"], trim_blocks=True) - # Render radius servers - render(radius_servers, 'ocserv/radius_servers.tmpl', ocserv["authentication"]["radius"], trim_blocks=True) - else: - if "local_users" in ocserv["authentication"]: - for user in ocserv["authentication"]["local_users"]["username"]: - ocserv["authentication"]["local_users"]["username"][user]["hash"] = get_hash(ocserv["authentication"]["local_users"]["username"][user]["password"]) - # Render local users - render(ocserv_passwd, 'ocserv/ocserv_passwd.tmpl', ocserv["authentication"]["local_users"], trim_blocks=True) - - # Render config - render(ocserv_conf, 'ocserv/ocserv_config.tmpl', ocserv, trim_blocks=True) - - - -def apply(ocserv): - if not ocserv: - call('systemctl stop ocserv.service') - for file in [ocserv_conf, ocserv_passwd]: - if os.path.exists(file): - os.unlink(file) - else: - call('systemctl restart ocserv.service') - - -if __name__ == '__main__': - try: - c = get_config() - verify(c) - generate(c) - apply(c) - except ConfigError as e: - print(e) - exit(1) diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py new file mode 100755 index 000000000..af8604972 --- /dev/null +++ b/src/conf_mode/vpn_openconnect.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018-2020 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 . + +import os +from sys import exit + +from vyos.config import Config +from vyos.configdict import dict_merge +from vyos.xml import defaults +from vyos.template import render +from vyos.util import call +from vyos import ConfigError +from crypt import crypt, mksalt, METHOD_SHA512 + +from vyos import airbag +airbag.enable() + +cfg_dir = '/run/ocserv' +ocserv_conf = cfg_dir + '/ocserv.conf' +ocserv_passwd = cfg_dir + '/ocpasswd' +radius_cfg = cfg_dir + '/radiusclient.conf' +radius_servers = cfg_dir + '/radius_servers' + + +# Generate hash from user cleartext password +def get_hash(password): + return crypt(password, mksalt(METHOD_SHA512)) + + +def get_config(): + conf = Config() + base = ['vpn', 'openconnect'] + if not conf.exists(base): + return None + + ocserv = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + default_values = defaults(base) + ocserv = dict_merge(default_values, ocserv) + return ocserv + + +def verify(ocserv): + if ocserv is None: + return None + + # Check authentication + if "authentication" in ocserv: + if "mode" in ocserv["authentication"]: + if "local" in ocserv["authentication"]["mode"]: + if not ocserv["authentication"]["local_users"] or not ocserv["authentication"]["local_users"]["username"]: + raise ConfigError('openconnect mode local required at leat one user') + else: + for user in ocserv["authentication"]["local_users"]["username"]: + if not "password" in ocserv["authentication"]["local_users"]["username"][user]: + raise ConfigError(f'password required for user {user}') + else: + raise ConfigError('openconnect authentication mode required') + else: + raise ConfigError('openconnect authentication credentials required') + + # Check ssl + if "ssl" in ocserv: + req_cert = ['ca_cert_file', 'cert_file', 'key_file'] + for cert in req_cert: + if not cert in ocserv["ssl"]: + raise ConfigError('openconnect ssl {0} required'.format(cert.replace('_', '-'))) + else: + raise ConfigError('openconnect ssl required') + + # Check network settings + if "network_settings" in ocserv: + if "push_route" in ocserv["network_settings"]: + # Replace default route + if "0.0.0.0/0" in ocserv["network_settings"]["push_route"]: + ocserv["network_settings"]["push_route"].remove("0.0.0.0/0") + ocserv["network_settings"]["push_route"].append("default") + else: + ocserv["network_settings"]["push_route"] = "default" + else: + raise ConfigError('openconnect network settings required') + + +def generate(ocserv): + if not ocserv: + return None + + if "radius" in ocserv["authentication"]["mode"]: + # Render radius client configuration + render(radius_cfg, 'ocserv/radius_conf.tmpl', ocserv["authentication"]["radius"], trim_blocks=True) + # Render radius servers + render(radius_servers, 'ocserv/radius_servers.tmpl', ocserv["authentication"]["radius"], trim_blocks=True) + else: + if "local_users" in ocserv["authentication"]: + for user in ocserv["authentication"]["local_users"]["username"]: + ocserv["authentication"]["local_users"]["username"][user]["hash"] = get_hash(ocserv["authentication"]["local_users"]["username"][user]["password"]) + # Render local users + render(ocserv_passwd, 'ocserv/ocserv_passwd.tmpl', ocserv["authentication"]["local_users"], trim_blocks=True) + + # Render config + render(ocserv_conf, 'ocserv/ocserv_config.tmpl', ocserv, trim_blocks=True) + + + +def apply(ocserv): + if not ocserv: + call('systemctl stop ocserv.service') + for file in [ocserv_conf, ocserv_passwd]: + if os.path.exists(file): + os.unlink(file) + else: + call('systemctl restart ocserv.service') + + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + exit(1) diff --git a/src/op_mode/anyconnect-control.py b/src/op_mode/anyconnect-control.py deleted file mode 100755 index 6382016b7..000000000 --- a/src/op_mode/anyconnect-control.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2020 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 . - -import sys -import argparse -import json - -from vyos.config import Config -from vyos.util import popen, run, DEVNULL -from tabulate import tabulate - -occtl = '/usr/bin/occtl' -occtl_socket = '/run/ocserv/occtl.socket' - -def show_sessions(): - out, code = popen("sudo {0} -j -s {1} show users".format(occtl, occtl_socket),stderr=DEVNULL) - if code: - sys.exit('Cannot get anyconnect users information') - else: - headers = ["interface", "username", "ip", "remote IP", "RX", "TX", "state", "uptime"] - sessions = json.loads(out) - ses_list = [] - for ses in sessions: - 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: - print(tabulate(ses_list, headers)) - else: - print("No active anyconnect sessions") - -def is_ocserv_configured(): - if not Config().exists_effective('vpn anyconnect'): - print("vpn anyconnect server is not configured") - sys.exit(1) - -def main(): - #parese args - parser = argparse.ArgumentParser() - parser.add_argument('--action', help='Control action', required=True) - parser.add_argument('--selector', help='Selector username|ifname|sid', required=False) - parser.add_argument('--target', help='Target must contain username|ifname|sid', required=False) - args = parser.parse_args() - - - # Check is IPoE configured - is_ocserv_configured() - - if args.action == "restart": - run("systemctl restart ocserv") - sys.exit(0) - elif args.action == "show_sessions": - show_sessions() - -if __name__ == '__main__': - main() diff --git a/src/op_mode/openconnect-control.py b/src/op_mode/openconnect-control.py new file mode 100755 index 000000000..ef9fe618c --- /dev/null +++ b/src/op_mode/openconnect-control.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2020 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 . + +import sys +import argparse +import json + +from vyos.config import Config +from vyos.util import popen, run, DEVNULL +from tabulate import tabulate + +occtl = '/usr/bin/occtl' +occtl_socket = '/run/ocserv/occtl.socket' + +def show_sessions(): + out, code = popen("sudo {0} -j -s {1} show users".format(occtl, occtl_socket),stderr=DEVNULL) + if code: + sys.exit('Cannot get openconnect users information') + else: + headers = ["interface", "username", "ip", "remote IP", "RX", "TX", "state", "uptime"] + sessions = json.loads(out) + ses_list = [] + for ses in sessions: + 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: + print(tabulate(ses_list, headers)) + else: + print("No active openconnect sessions") + +def is_ocserv_configured(): + if not Config().exists_effective('vpn openconnect'): + print("vpn openconnect server is not configured") + sys.exit(1) + +def main(): + #parese args + parser = argparse.ArgumentParser() + parser.add_argument('--action', help='Control action', required=True) + parser.add_argument('--selector', help='Selector username|ifname|sid', required=False) + parser.add_argument('--target', help='Target must contain username|ifname|sid', required=False) + args = parser.parse_args() + + + # Check is Openconnect server configured + is_ocserv_configured() + + if args.action == "restart": + run("systemctl restart ocserv") + sys.exit(0) + elif args.action == "show_sessions": + show_sessions() + +if __name__ == '__main__': + main() -- cgit v1.2.3