From e61f7abdb2136d8dfbf73729dbc14c3b5ab2ecba Mon Sep 17 00:00:00 2001 From: Jamie Austin Date: Fri, 27 Jan 2023 17:32:29 +1100 Subject: T4958: ocserv: openconnect: adds support for configuring RADIUS accounting Adds CLI configuration options to configure RADIUS accounting for OpenConnect VPN sessions. This functionality cannot be used outside of the RADIUS OpenConnect VPN authentication mode --- data/templates/ocserv/ocserv_config.j2 | 4 +++ data/templates/ocserv/radius_conf.j2 | 42 +++++++++++++++------- .../include/radius-acct-server-ipv4.xml.i | 26 ++++++++++++++ .../include/radius-auth-server-ipv4.xml.i | 27 ++++++++++++++ .../include/radius-server-acct-port.xml.i | 15 ++++++++ .../include/radius-server-auth-port.xml.i | 15 ++++++++ .../include/radius-server-ipv4-ipv6.xml.i | 2 +- .../include/radius-server-ipv4.xml.i | 27 -------------- .../include/radius-server-port.xml.i | 15 -------- interface-definitions/interfaces-wireless.xml.in | 2 +- interface-definitions/service-ipoe-server.xml.in | 2 +- interface-definitions/service-pppoe-server.xml.in | 2 +- interface-definitions/vpn-ipsec.xml.in | 2 +- interface-definitions/vpn-l2tp.xml.in | 2 +- interface-definitions/vpn-openconnect.xml.in | 23 +++++++++++- interface-definitions/vpn-pptp.xml.in | 2 +- interface-definitions/vpn-sstp.xml.in | 2 +- src/conf_mode/vpn_openconnect.py | 26 +++++++++++--- 18 files changed, 169 insertions(+), 67 deletions(-) create mode 100644 interface-definitions/include/radius-acct-server-ipv4.xml.i create mode 100644 interface-definitions/include/radius-auth-server-ipv4.xml.i create mode 100644 interface-definitions/include/radius-server-acct-port.xml.i create mode 100644 interface-definitions/include/radius-server-auth-port.xml.i delete mode 100644 interface-definitions/include/radius-server-ipv4.xml.i delete mode 100644 interface-definitions/include/radius-server-port.xml.i diff --git a/data/templates/ocserv/ocserv_config.j2 b/data/templates/ocserv/ocserv_config.j2 index 3194354e6..aa8897703 100644 --- a/data/templates/ocserv/ocserv_config.j2 +++ b/data/templates/ocserv/ocserv_config.j2 @@ -10,6 +10,10 @@ udp-port = {{ listen_ports.udp }} run-as-user = nobody run-as-group = daemon +{% if "radius" in accounting.mode %} +acct = "radius [config=/run/ocserv/radiusclient.conf]" +{% endif %} + {% if "radius" in authentication.mode %} auth = "radius [config=/run/ocserv/radiusclient.conf{{ ',groupconfig=true' if authentication.radius.groupconfig is vyos_defined else '' }}]" {% elif "local" in authentication.mode %} diff --git a/data/templates/ocserv/radius_conf.j2 b/data/templates/ocserv/radius_conf.j2 index b6612fee5..65548e3ad 100644 --- a/data/templates/ocserv/radius_conf.j2 +++ b/data/templates/ocserv/radius_conf.j2 @@ -1,20 +1,38 @@ ### generated by vpn_openconnect.py ### nas-identifier VyOS -{% for srv in server %} -{% if not "disable" in server[srv] %} -{% if "port" in server[srv] %} -authserver {{ srv }}:{{ server[srv]["port"] }} -{% else %} -authserver {{ srv }} + +#### Accounting +{% if "radius" in accounting['mode'] %} +{% for acctsrv in accounting['radius']['server'] %} +{% if not "disable" in accounting['radius']['server'][acctsrv] %} +{% if "port" in accounting['radius']['server'][acctsrv] %} +acctserver {{ acctsrv }}:{{ accounting['radius']['server'][acctsrv]['port'] }} +{% else %} +acctserver {{ acctsrv }} +{% endif %} {% endif %} -{% endif %} -{% endfor %} -radius_timeout {{ timeout }} -{% if source_address %} -bindaddr {{ source_address }} -{% else %} +{% endfor %} +{% endif %} + +#### Authentication +{% if "radius" in authentication['mode'] %} +{% for authsrv in authentication['radius']['server'] %} +{% if not "disable" in authentication['radius']['server'][authsrv] %} +{% if "port" in authentication['radius']['server'][authsrv] %} +authserver {{ authsrv }}:{{ authentication['radius']['server'][authsrv]['port'] }} +{% else %} +authserver {{ authsrv }} +{% endif %} +{% endif %} +{% endfor %} +radius_timeout {{ authentication['radius']['timeout'] }} +{% if source_address %} +bindaddr {{ authentication['radius']['source_address'] }} +{% else %} bindaddr * +{% endif %} {% endif %} + servers /run/ocserv/radius_servers dictionary /etc/radcli/dictionary default_realm diff --git a/interface-definitions/include/radius-acct-server-ipv4.xml.i b/interface-definitions/include/radius-acct-server-ipv4.xml.i new file mode 100644 index 000000000..9365aa8e9 --- /dev/null +++ b/interface-definitions/include/radius-acct-server-ipv4.xml.i @@ -0,0 +1,26 @@ + + + + RADIUS accounting for users OpenConnect VPN sessions OpenConnect authentication mode radius + + + + + RADIUS server configuration + + ipv4 + RADIUS server IPv4 address + + + + + + + #include + #include + #include + + + + + diff --git a/interface-definitions/include/radius-auth-server-ipv4.xml.i b/interface-definitions/include/radius-auth-server-ipv4.xml.i new file mode 100644 index 000000000..dc6f4d878 --- /dev/null +++ b/interface-definitions/include/radius-auth-server-ipv4.xml.i @@ -0,0 +1,27 @@ + + + + RADIUS based user authentication + + + #include + + + RADIUS server configuration + + ipv4 + RADIUS server IPv4 address + + + + + + + #include + #include + #include + + + + + diff --git a/interface-definitions/include/radius-server-acct-port.xml.i b/interface-definitions/include/radius-server-acct-port.xml.i new file mode 100644 index 000000000..0b356fa18 --- /dev/null +++ b/interface-definitions/include/radius-server-acct-port.xml.i @@ -0,0 +1,15 @@ + + + + Accounting port + + u32:1-65535 + Numeric IP port + + + + + + 1813 + + diff --git a/interface-definitions/include/radius-server-auth-port.xml.i b/interface-definitions/include/radius-server-auth-port.xml.i new file mode 100644 index 000000000..660fa540f --- /dev/null +++ b/interface-definitions/include/radius-server-auth-port.xml.i @@ -0,0 +1,15 @@ + + + + Authentication port + + u32:1-65535 + Numeric IP port + + + + + + 1812 + + diff --git a/interface-definitions/include/radius-server-ipv4-ipv6.xml.i b/interface-definitions/include/radius-server-ipv4-ipv6.xml.i index 5b12bec62..c593512b4 100644 --- a/interface-definitions/include/radius-server-ipv4-ipv6.xml.i +++ b/interface-definitions/include/radius-server-ipv4-ipv6.xml.i @@ -23,7 +23,7 @@ #include #include - #include + #include diff --git a/interface-definitions/include/radius-server-ipv4.xml.i b/interface-definitions/include/radius-server-ipv4.xml.i deleted file mode 100644 index ab4c8e10e..000000000 --- a/interface-definitions/include/radius-server-ipv4.xml.i +++ /dev/null @@ -1,27 +0,0 @@ - - - - RADIUS based user authentication - - - #include - - - RADIUS server configuration - - ipv4 - RADIUS server IPv4 address - - - - - - - #include - #include - #include - - - - - diff --git a/interface-definitions/include/radius-server-port.xml.i b/interface-definitions/include/radius-server-port.xml.i deleted file mode 100644 index c6b691a0f..000000000 --- a/interface-definitions/include/radius-server-port.xml.i +++ /dev/null @@ -1,15 +0,0 @@ - - - - Authentication port - - u32:1-65535 - Numeric IP port - - - - - - 1812 - - diff --git a/interface-definitions/interfaces-wireless.xml.in b/interface-definitions/interfaces-wireless.xml.in index aff5071b2..a9538d577 100644 --- a/interface-definitions/interfaces-wireless.xml.in +++ b/interface-definitions/interfaces-wireless.xml.in @@ -725,7 +725,7 @@ Invalid WPA pass phrase, must be 8 to 63 printable characters! - #include + #include diff --git a/interface-definitions/service-ipoe-server.xml.in b/interface-definitions/service-ipoe-server.xml.in index ef8569437..d778f9de0 100644 --- a/interface-definitions/service-ipoe-server.xml.in +++ b/interface-definitions/service-ipoe-server.xml.in @@ -220,7 +220,7 @@ #include - #include + #include #include diff --git a/interface-definitions/service-pppoe-server.xml.in b/interface-definitions/service-pppoe-server.xml.in index 47ad96582..68592b96b 100644 --- a/interface-definitions/service-pppoe-server.xml.in +++ b/interface-definitions/service-pppoe-server.xml.in @@ -20,7 +20,7 @@ #include #include #include - #include + #include #include diff --git a/interface-definitions/vpn-ipsec.xml.in b/interface-definitions/vpn-ipsec.xml.in index fa12d999c..4bb9ad145 100644 --- a/interface-definitions/vpn-ipsec.xml.in +++ b/interface-definitions/vpn-ipsec.xml.in @@ -923,7 +923,7 @@ #include - #include + #include #include diff --git a/interface-definitions/vpn-l2tp.xml.in b/interface-definitions/vpn-l2tp.xml.in index 86aeb324e..0a92017bd 100644 --- a/interface-definitions/vpn-l2tp.xml.in +++ b/interface-definitions/vpn-l2tp.xml.in @@ -178,7 +178,7 @@ #include #include #include - #include + #include diff --git a/interface-definitions/vpn-openconnect.xml.in b/interface-definitions/vpn-openconnect.xml.in index 82fe2bbc9..a426f604d 100644 --- a/interface-definitions/vpn-openconnect.xml.in +++ b/interface-definitions/vpn-openconnect.xml.in @@ -8,6 +8,27 @@ 901 + + + Accounting for users OpenConnect VPN Sessions + + + + + Accounting mode used by this server + + + + + Use RADIUS server for accounting + + + + + + #include + + Authentication for remote access SSL VPN Server @@ -137,7 +158,7 @@ - #include + #include #include diff --git a/interface-definitions/vpn-pptp.xml.in b/interface-definitions/vpn-pptp.xml.in index 5e52965fd..00ffd26f9 100644 --- a/interface-definitions/vpn-pptp.xml.in +++ b/interface-definitions/vpn-pptp.xml.in @@ -108,7 +108,7 @@ - #include + #include #include #include diff --git a/interface-definitions/vpn-sstp.xml.in b/interface-definitions/vpn-sstp.xml.in index 195d581df..9e912063f 100644 --- a/interface-definitions/vpn-sstp.xml.in +++ b/interface-definitions/vpn-sstp.xml.in @@ -16,7 +16,7 @@ #include #include #include - #include + #include #include diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py index 57eba17b0..12ddac23c 100755 --- a/src/conf_mode/vpn_openconnect.py +++ b/src/conf_mode/vpn_openconnect.py @@ -121,6 +121,14 @@ def verify(ocserv): not is_listen_port_bind_service(int(port), 'ocserv-main'): raise ConfigError(f'"{proto}" port "{port}" is used by another service') + # Check accounting + if "accounting" in ocserv: + if "mode" in ocserv["accounting"] and "radius" in ocserv["accounting"]["mode"]: + if "authentication" not in ocserv or "mode" not in ocserv["authentication"]: + raise ConfigError('Accounting depends on OpenConnect authentication configuration') + elif "radius" not in ocserv["authentication"]["mode"]: + raise ConfigError('RADIUS accounting must be used with RADIUS authentication') + # Check authentication if "authentication" in ocserv: if "mode" in ocserv["authentication"]: @@ -202,10 +210,20 @@ def generate(ocserv): return None if "radius" in ocserv["authentication"]["mode"]: - # Render radius client configuration - render(radius_cfg, 'ocserv/radius_conf.j2', ocserv["authentication"]["radius"]) - # Render radius servers - render(radius_servers, 'ocserv/radius_servers.j2', ocserv["authentication"]["radius"]) + if "accounting" in ocserv and "mode" in ocserv["accounting"] and "radius" in ocserv["accounting"]["mode"]: + acct_and_auth_config = {'accounting': ocserv["accounting"], 'authentication': ocserv["authentication"]} + # Render radius client configuration + render(radius_cfg, 'ocserv/radius_conf.j2', acct_and_auth_config) + merged_servers = ocserv["accounting"]["radius"]["server"] | ocserv["authentication"]["radius"]["server"] + # Render radius servers + # Merge the accounting and authentication servers into a single dictionary + render(radius_servers, 'ocserv/radius_servers.j2', {'server': merged_servers}) + else: + acct_and_auth_config = {'accounting': {'mode': ''}, 'authentication': ocserv['authentication']} + # Render radius client configuration + render(radius_cfg, 'ocserv/radius_conf.j2', acct_and_auth_config) + # Render radius servers + render(radius_servers, 'ocserv/radius_servers.j2', ocserv["authentication"]["radius"]) elif "local" in ocserv["authentication"]["mode"]: # if mode "OTP", generate OTP users file parameters if "otp" in ocserv["authentication"]["mode"]["local"]: -- cgit v1.2.3