feature: users and their certificates no longer need a P2S system enabled.
Release / release (push) Successful in 21s
Release / release (push) Successful in 21s
This commit is contained in:
1 parent
0ff74cc8c9
commit
0bf78b16b1
7 files changed
+67
-40
No files matched your search
@@ -347,13 +347,8 @@ def manage_wireguard(ctx, changed):
|
||||
run(['systemctl', 'restart', unit], check=False)
|
||||
|
||||
|
||||
def manage_directory(ctx):
|
||||
"""Provision the user directory in slapd while a P2S system that has users is configured.
|
||||
|
||||
The directory is left in place when they are switched off, so the users are kept.
|
||||
"""
|
||||
if not (vpnrouter.p2s_ready(ctx) or vpnrouter.openvpn_ready(ctx)):
|
||||
return
|
||||
def manage_directory():
|
||||
"""Provision the user directory in slapd, whether or not a P2S system is configured."""
|
||||
if vpnrouter_ldap.ensure_services() or not unit_is_active('slapd'):
|
||||
run(['systemctl', 'restart', 'slapd'])
|
||||
try:
|
||||
@@ -422,7 +417,6 @@ def refresh_web(cfg, ctx):
|
||||
'p2s': bool(vpnrouter.p2s_ready(ctx)),
|
||||
'wireguard': bool(vpnrouter.wg_ready(ctx)),
|
||||
'openvpn': bool(vpnrouter.openvpn_ready(ctx)),
|
||||
'users': bool(vpnrouter.p2s_ready(ctx) or vpnrouter.openvpn_ready(ctx)),
|
||||
'configuration': public,
|
||||
'network': {
|
||||
'external_interface': ctx['wan_iface'],
|
||||
@@ -469,7 +463,7 @@ def main():
|
||||
elif rules_changed:
|
||||
run(['ufw', 'reload'], check=False)
|
||||
|
||||
manage_directory(ctx)
|
||||
manage_directory()
|
||||
manage_strongswan(ctx, changed)
|
||||
manage_wireguard(ctx, changed)
|
||||
manage_openvpn(ctx, changed)
|
||||
|
||||
@@ -565,24 +565,28 @@ def _simple_ca(*args):
|
||||
|
||||
|
||||
def provision_pki(ctx):
|
||||
"""Create the CA, server certificate and CRL when the PKI directory is empty; a CA without a CRL gets one."""
|
||||
"""Create the CA and CRL when the PKI directory is empty, and the server certificate once wan.local_fqdn is set.
|
||||
|
||||
A CA of the router's own (ca_key.pem present) without a CRL gets one, and without a
|
||||
certificate for wan.local_fqdn gets one too; nothing present is overwritten.
|
||||
"""
|
||||
PKI_DIR.mkdir(parents=True, exist_ok=True)
|
||||
os.chmod(PKI_DIR, 0o700)
|
||||
|
||||
if any(PKI_DIR.iterdir()):
|
||||
if (PKI_DIR / 'ca_key.pem').is_file() and not (PKI_DIR / 'crl.pem').is_file():
|
||||
_simple_ca('make-crl', '--ca-dir', str(PKI_DIR), '--days', str(CRL_DAYS))
|
||||
return
|
||||
if not ctx['p2s_ca_name']:
|
||||
warn('p2s.ca_name is empty, not creating a local CA')
|
||||
return
|
||||
if not SIMPLE_CA.is_file():
|
||||
fail(f'{SIMPLE_CA} is missing')
|
||||
|
||||
_simple_ca('make-ca', '--ca-dir', str(PKI_DIR), ctx['p2s_ca_name'])
|
||||
_simple_ca('make-cert', '--ca-dir', str(PKI_DIR),
|
||||
ctx['local_fqdn'], ctx['local_fqdn'])
|
||||
_simple_ca('make-crl', '--ca-dir', str(PKI_DIR), '--days', str(CRL_DAYS))
|
||||
if not any(PKI_DIR.iterdir()):
|
||||
if not ctx['p2s_ca_name']:
|
||||
warn('p2s.ca_name is empty, not creating a local CA')
|
||||
return
|
||||
_simple_ca('make-ca', '--ca-dir', str(PKI_DIR), ctx['p2s_ca_name'])
|
||||
if not (PKI_DIR / 'ca_key.pem').is_file():
|
||||
return
|
||||
if not (PKI_DIR / 'crl.pem').is_file():
|
||||
_simple_ca('make-crl', '--ca-dir', str(PKI_DIR), '--days', str(CRL_DAYS))
|
||||
label = ctx['local_fqdn'].split('.', 1)[0] if ctx['local_fqdn'] else ''
|
||||
if label and not (PKI_DIR / f'{label}_cert.pem').is_file():
|
||||
_simple_ca('make-cert', '--ca-dir', str(PKI_DIR), ctx['local_fqdn'], ctx['local_fqdn'])
|
||||
|
||||
|
||||
def distribute_pki(ctx):
|
||||
@@ -628,8 +632,7 @@ def configure(cfg=None, local_id_override=None):
|
||||
|
||||
changed = set()
|
||||
|
||||
if p2s_ready(ctx) or openvpn_ready(ctx):
|
||||
provision_pki(ctx)
|
||||
provision_pki(ctx)
|
||||
if distribute_pki(ctx):
|
||||
changed.add('swanctl')
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Pages:
|
||||
/status the status as JSON
|
||||
/config the configuration without its secrets, and what the router resolved and
|
||||
runs, as JSON
|
||||
/users the users of the P2S systems: list, add, set the password, disable, enable,
|
||||
/users the users in the router's directory, whether or not a P2S system is enabled: list, add, set the password, disable, enable,
|
||||
remove, and the OpenVPN client profile (see users())
|
||||
|
||||
/config and /users need an HS256 JWT in an Authorization: Bearer header that is signed
|
||||
@@ -433,8 +433,6 @@ def users(state, method, path, body):
|
||||
DELETE /users/<name> remove the user and revoke the certificate
|
||||
GET /users/<name>/profile the OpenVPN client profile
|
||||
"""
|
||||
if not state.get('users'):
|
||||
return 404, {'error': 'no P2S system with users is configured'}
|
||||
if body == 'invalid' or (body is not None and not isinstance(body, dict)):
|
||||
return 400, {'error': 'the body must be a JSON object'}
|
||||
body = body or {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/python3
|
||||
"""Manage the users of the router's P2S systems.
|
||||
"""Manage the users of the router's directory, whether or not a P2S system is enabled.
|
||||
|
||||
A user is an entry in the router's directory, whose password OpenVPN checks, and a client
|
||||
certificate of the router CA with the user name as its common name, which OpenVPN and
|
||||
@@ -103,7 +103,7 @@ def list_users(connection):
|
||||
def add(connection, name):
|
||||
secret = password()
|
||||
if not (vpnrouter.PKI_DIR / 'ca_key.pem').is_file():
|
||||
raise Failure('the router CA does not exist; enable OpenVPN or IKEv2 road-warrior access first')
|
||||
raise Failure('the router CA does not exist; vpn-router-setup creates it once a platform is chosen')
|
||||
try:
|
||||
connection.add_s(dn_of(name), ldap.modlist.addModlist({
|
||||
'objectClass': [b'inetOrgPerson'], 'uid': [name.encode()], 'cn': [name.encode()], 'sn': [name.encode()],
|
||||
|
||||
Reference in new issue
Block a user