diff options
| author | Viacheslav Hletenko <v.gletenko@vyos.io> | 2026-01-05 17:20:02 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-05 17:20:02 +0200 |
| commit | 06945f0a7079b72ab3844bec77288aea208ac266 (patch) | |
| tree | 2271fa220bfe6c90f7320ffdbc0d6bf8ebcf42af | |
| parent | 2e9c1ffd20a8149842a71acae062a8f0822f95dc (diff) | |
| parent | 381ae4a8ccddb524bca5951e27cc826eeef45453 (diff) | |
| download | vyos-1x-06945f0a7079b72ab3844bec77288aea208ac266.tar.gz vyos-1x-06945f0a7079b72ab3844bec77288aea208ac266.zip | |
Merge pull request #4618 from giga1699/T7635
T7635: OpenConnect Certificate Authentication
| -rw-r--r-- | data/templates/ocserv/ocserv_config.j2 | 9 | ||||
| -rw-r--r-- | interface-definitions/vpn_openconnect.xml.in | 31 | ||||
| -rwxr-xr-x | src/conf_mode/vpn_openconnect.py | 15 |
3 files changed, 52 insertions, 3 deletions
diff --git a/data/templates/ocserv/ocserv_config.j2 b/data/templates/ocserv/ocserv_config.j2 index 81f777031..76d3e6e4e 100644 --- a/data/templates/ocserv/ocserv_config.j2 +++ b/data/templates/ocserv/ocserv_config.j2 @@ -30,6 +30,15 @@ auth = "plain[otp=/run/ocserv/users.oath]" {% else %} auth = "plain[/run/ocserv/ocpasswd]" {% endif %} +{% elif "certificate" in authentication.mode %} +auth = "certificate" +{% if authentication.mode.certificate.user_identifier_field == "cn" %} +cert-user-oid = 2.5.4.3 +{% elif authentication.mode.certificate.user_identifier_field == "uid" %} +cert-user-oid = 0.9.2342.19200300.100.1.1 +{% else %} +cert-user-oid = {{ authentication.mode.certificate.user_identifier_field }} +{% endif %} {% else %} auth = "plain[/run/ocserv/ocpasswd]" {% endif %} diff --git a/interface-definitions/vpn_openconnect.xml.in b/interface-definitions/vpn_openconnect.xml.in index a2f040b2f..13e5142fd 100644 --- a/interface-definitions/vpn_openconnect.xml.in +++ b/interface-definitions/vpn_openconnect.xml.in @@ -69,6 +69,37 @@ <valueless/> </properties> </leafNode> + <node name="certificate"> + <properties> + <help>Use certificate-based authentication</help> + </properties> + <children> + <leafNode name="user-identifier-field"> + <properties> + <help>Certificate field to identify users by</help> + <valueHelp> + <format>cn</format> + <description>OID 2.5.4.3 - Common Name</description> + </valueHelp> + <valueHelp> + <format>uid</format> + <description>OID 0.9.2342.19200300.100.1.1 - UID</description> + </valueHelp> + <valueHelp> + <format>x.x.xx.xxx</format> + <description>Custom OID in dotted decimal format</description> + </valueHelp> + <constraint> + <regex>(^\d{1,5}(?:\.\d{1,5})*$|cn|uid)</regex> + </constraint> + <constraintErrorMessage>Invalid OID selection. Must be cn, uid, or a valid OID format.</constraintErrorMessage> + <completionHelp> + <list>cn uid x.x.xx.xxx</list> + </completionHelp> + </properties> + </leafNode> + </children> + </node> </children> </node> <node name="identity-based-config"> diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py index 68cd363f0..bfc1d5269 100755 --- a/src/conf_mode/vpn_openconnect.py +++ b/src/conf_mode/vpn_openconnect.py @@ -105,11 +105,17 @@ def verify(ocserv): if 'authentication' in ocserv: if 'mode' in ocserv['authentication']: if ( - 'local' in ocserv['authentication']['mode'] - and 'radius' in ocserv['authentication']['mode'] + ('local' in ocserv['authentication']['mode'] + and 'radius' in ocserv['authentication']['mode']) + or + ('local' in ocserv['authentication']['mode'] + and 'certificate' in ocserv['authentication']['mode']) + or + ('radius' in ocserv['authentication']['mode'] + and 'certificate' in ocserv['authentication']['mode']) ): raise ConfigError( - 'OpenConnect authentication modes are mutually-exclusive, remove either local or radius from your configuration' + 'OpenConnect authentication modes are mutually-exclusive. Use only one of local, radius, or certificate.' ) if 'radius' in ocserv['authentication']['mode']: if 'server' not in ocserv['authentication']['radius']: @@ -203,6 +209,9 @@ def verify(ocserv): raise ConfigError('SSL certificate missing on OpenConnect config!') verify_pki_certificate(ocserv, ocserv['ssl']['certificate']) + if 'ca_certificate' not in ocserv['ssl'] and 'certificiate' in ocserv['authentication']['mode']: + raise ConfigError('CA certificate must be provided in certificate authentication mode!') + if 'ca_certificate' in ocserv['ssl']: for ca_cert in ocserv['ssl']['ca_certificate']: verify_pki_ca_certificate(ocserv, ca_cert) |
