openvpn: Use config file instead of env vars for easy-rsa

- A configuration file seems to be the preferred approach for invoke easy-rsa
since version 3.

- Drop unused configuration keys KEY_CONFIG, KEY_DIR and EASYRSA_REQ_NAME. These
are no longer referred to in the easy-rsa script.

- Remove configuration key EASYRSA_OPENSSL as the value 'openssl' is already the
default.

- Use pathlib.Path to simplify some code.

Tests:

- Re-run setup and notice the ca.cert file has not changed.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2023-08-24 16:53:41 -07:00 committed by James Valleroy
parent 95f65b5c4b
commit 0176d706b9
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808

View File

@ -2,6 +2,7 @@
"""Configure OpenVPN server."""
import os
import pathlib
import shutil
import subprocess
@ -10,23 +11,16 @@ import augeas
from plinth import action_utils
from plinth.actions import privileged
KEYS_DIRECTORY = '/etc/openvpn/freedombox-keys'
DH_PARAMS = f'{KEYS_DIRECTORY}/pki/dh.pem'
EC_PARAMS_DIR = f'{KEYS_DIRECTORY}/pki/ecparams'
KEYS_DIRECTORY = pathlib.Path('/etc/openvpn/freedombox-keys')
CA_CERTIFICATE_PATH = KEYS_DIRECTORY / 'pki' / 'ca.crt'
USER_CERTIFICATE_PATH = KEYS_DIRECTORY / 'pki' / 'issued' / '{username}.crt'
USER_KEY_PATH = KEYS_DIRECTORY / 'pki' / 'private' / '{username}.key'
ATTR_FILE = KEYS_DIRECTORY / 'pki' / 'index.txt.attr'
SERVER_CONFIGURATION_PATH = '/etc/openvpn/server/freedombox.conf'
SERVICE_NAME = 'openvpn-server@freedombox'
CA_CERTIFICATE_PATH = os.path.join(KEYS_DIRECTORY, 'pki', 'ca.crt')
USER_CERTIFICATE_PATH = os.path.join(KEYS_DIRECTORY, 'pki', 'issued',
'{username}.crt')
USER_KEY_PATH = os.path.join(KEYS_DIRECTORY, 'pki', 'private',
'{username}.key')
ATTR_FILE = os.path.join(KEYS_DIRECTORY, 'pki', 'index.txt.attr')
SERVER_CONFIGURATION = '''
port 1194
proto udp
@ -69,13 +63,10 @@ verb 3
<key>
{key}</key>'''
CERTIFICATE_CONFIGURATION = {
_EASY_RSA_CONFIGURATION = {
'EASYRSA_ALGO': 'ec',
'EASYRSA_BATCH': '1',
'EASYRSA_DIGEST': 'sha512',
'KEY_CONFIG': '/usr/share/easy-rsa/openssl-easyrsa.cnf',
'KEY_DIR': KEYS_DIRECTORY,
'EASYRSA_OPENSSL': 'openssl',
'EASYRSA_CA_EXPIRE': '3650',
'EASYRSA_CERT_EXPIRE': '3650',
'EASYRSA_REQ_COUNTRY': 'US',
@ -84,11 +75,8 @@ CERTIFICATE_CONFIGURATION = {
'EASYRSA_REQ_ORG': 'FreedomBox',
'EASYRSA_REQ_EMAIL': 'me@freedombox',
'EASYRSA_REQ_OU': 'Home',
'EASYRSA_REQ_NAME': 'FreedomBox'
}
COMMON_ARGS = {'env': CERTIFICATE_CONFIGURATION, 'cwd': KEYS_DIRECTORY}
@privileged
def setup():
@ -150,14 +138,19 @@ def _run_easy_rsa(args):
cwd=KEYS_DIRECTORY, check=True)
def _write_easy_rsa_config():
"""Write easy-rsa 'vars' file."""
with (KEYS_DIRECTORY / 'pki' / 'vars').open('w') as file_handle:
for key, value in _EASY_RSA_CONFIGURATION.items():
file_handle.write(f'set_var {key} "{value}"\n')
def _create_certificates():
"""Generate CA and server certificates."""
try:
os.mkdir(KEYS_DIRECTORY, 0o700)
except FileExistsError:
pass
KEYS_DIRECTORY.mkdir(mode=0o700, exist_ok=True)
_run_easy_rsa(['init-pki'])
_write_easy_rsa_config()
_run_easy_rsa(['build-ca', 'nopass'])
_run_easy_rsa(['build-server-full', 'server', 'nopass'])
@ -168,8 +161,8 @@ def get_profile(username: str, remote_server: str) -> str:
if username == 'ca' or username == 'server':
raise Exception('Invalid username')
user_certificate = USER_CERTIFICATE_PATH.format(username=username)
user_key = USER_KEY_PATH.format(username=username)
user_certificate = str(USER_CERTIFICATE_PATH).format(username=username)
user_key = str(USER_KEY_PATH).format(username=username)
if not _is_non_empty_file(user_certificate) or \
not _is_non_empty_file(user_key):
@ -189,7 +182,7 @@ def get_profile(username: str, remote_server: str) -> str:
def set_unique_subject(value):
"""Set the unique_subject value to a particular value."""
aug = load_augeas()
aug.set('/files' + ATTR_FILE + '/unique_subject', value)
aug.set('/files' + str(ATTR_FILE) + '/unique_subject', value)
aug.save()
@ -211,7 +204,7 @@ def load_augeas():
# shell-script config file lens
aug.set('/augeas/load/Simplevars/lens', 'Simplevars.lns')
aug.set('/augeas/load/Simplevars/incl[last() + 1]', ATTR_FILE)
aug.set('/augeas/load/Simplevars/incl[last() + 1]', str(ATTR_FILE))
aug.load()
return aug