Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions data/templates/ocserv/ocserv_config.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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 == "cn" %}
cert-user-oid = 2.5.4.3
{% elif authentication.mode.certificate == "uid" %}
cert-user-oid = 0.9.2342.19200300.100.1.1
{% else %}
cert-user-oid = {{ authentication.mode.certificate }}
{% endif %}
{% else %}
auth = "plain[/run/ocserv/ocpasswd]"
{% endif %}
Expand Down
24 changes: 24 additions & 0 deletions interface-definitions/vpn_openconnect.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@
<valueless/>
</properties>
</leafNode>
<leafNode name="certificate">
<properties>
<help>Use certificate based authentication</help>
<valueHelp>
<format>cn</format>
<description>OID 2.5.4.3 - Common Name</description>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My feeling is that these should be sub-nodes like cert cn oc.example.com. That way it would be more obvious to config readers what field of the cert it's supposed to match, and it will be possible to add separate constraints for CNs and UIDs.

I also don't know if help strings should mention OIDs. End users normally talk about symbolic names like CN, I can't see how OIDs could be important or useful here in help strings.

Copy link
Member

@sever-sever sever-sever Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using certificate instead of cert ?
And common-name instead of cn

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual config is the OID, not a name. I don't think you can have more than one selection. I was referencing the OIDs because that's how the example config references that config item. So I don't think putting a domain name in there would be useful, and might lead to confusion by the user.

The OID definition is what openconnect should list as the username in the output of the show commands, and be used for any user specific configurations. The server will validate the user's certificate against the CA that's defined in the configuration to make sure the certificate is valid.

I suppose I figured seeing OIDs in the help might key in a more advanced user that they can certainly specify a specific OID for the configuration to match on. I think CN is going to be the most common use case, but the two listed in the openconnect example configs were CN and UID.

I don't see any issue using certificate instead of cert. I will make that change at a minimum.

I don't have any issue taking out the OID references from the help text if you'd rather them not be in there.

Here's the section from the example config taken from https://github.com/openconnect/ocserv/blob/master/doc/sample.config

# The object identifier that will be used to read the user ID in the client 
# certificate. The object identifier should be part of the certificate's DN
# Useful OIDs are: 
#  CN = 2.5.4.3, UID = 0.9.2342.19200300.100.1.1, SAN(rfc822name)
cert-user-oid = 0.9.2342.19200300.100.1.1

</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>
<node name="identity-based-config">
Expand Down
15 changes: 12 additions & 3 deletions src/conf_mode/vpn_openconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,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. Only one of local, radius, or certificate.'
)
if 'radius' in ocserv['authentication']['mode']:
if 'server' not in ocserv['authentication']['radius']:
Expand Down Expand Up @@ -202,6 +208,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)
Expand Down
Loading