Use init/openvpn method by default for now

This commit is contained in:
Lauri Võsandi 2021-04-14 00:17:17 +03:00
parent 3332c36629
commit 5d798cfec9
3 changed files with 200 additions and 189 deletions

View File

@ -9,12 +9,15 @@ RUN echo "Dpkg::Use-Pty=0;" > /etc/apt/apt.conf.d/99quieter
RUN apt-get update -qq RUN apt-get update -qq
RUN apt-get install -y -qq \ RUN apt-get install -y -qq \
python3-pip python3-pip \
openvpn
COPY entrypoint.sh /entrypoint.sh
COPY pinecrypt/client/. /src/pinecrypt/client COPY pinecrypt/client/. /src/pinecrypt/client
COPY setup.py /src/ COPY setup.py /src/
COPY README.md /src/ COPY README.md /src/
COPY misc/ /src/misc/ COPY misc/ /src/misc/
WORKDIR /src WORKDIR /src
RUN pip3 install . RUN pip3 install .
RUN echo "#!/bin/sh" > /usr/bin/chcon
RUN chmod +x /usr/bin/chcon

5
entrypoint.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
$@
AUTHORITY=$3
cat /etc/openvpn/$AUTHORITY.conf
openvpn --config /etc/openvpn/$AUTHORITY.conf

View File

@ -3,6 +3,7 @@
import click import click
import hashlib import hashlib
import logging import logging
import json
import os import os
import random import random
import re import re
@ -78,22 +79,18 @@ def certidude_provision(authority):
@click.command("enroll", help="Run processes for requesting certificates and configuring services") @click.command("enroll", help="Run processes for requesting certificates and configuring services")
@click.option("-k", "--kerberos", default=False, is_flag=True, help="Offer system keytab for auth") @click.option("-k", "--kerberos", default=False, is_flag=True, help="Offer system keytab for auth")
@click.option("-f", "--fork", default=False, is_flag=True, help="Fork to background") @click.option("-f", "--fork", default=False, is_flag=True, help="Fork to background")
@click.option("-nw", "--no-wait", default=False, is_flag=True, help="Return immideately if server doesn't autosign") @click.option("-nw", "--no-wait", default=False, is_flag=True, help="Return immediately if server doesn't autosign")
def certidude_enroll(fork, no_wait, kerberos): def certidude_enroll(fork, no_wait, kerberos):
try: try:
os.makedirs(const.RUN_DIR) os.makedirs(const.RUN_DIR)
except FileExistsError: except FileExistsError:
pass pass
context = globals()
context.update(locals())
if not os.path.exists(const.CLIENT_CONFIG_PATH): if not os.path.exists(const.CLIENT_CONFIG_PATH):
click.echo("Client not configured, so not going to enroll") click.echo("Client not configured, so not going to enroll")
return return
clients = ConfigTreeParser(const.CLIENT_CONFIG_PATH) clients = ConfigTreeParser(const.CLIENT_CONFIG_PATH)
service_config = ConfigTreeParser(const.SERVICES_CONFIG_PATH)
for authority_name in clients.sections(): for authority_name in clients.sections():
try: try:
@ -172,34 +169,28 @@ def certidude_enroll(fork, no_wait, kerberos):
authority_public_key = asymmetric.load_public_key( authority_public_key = asymmetric.load_public_key(
authority_certificate["tbs_certificate"]["subject_public_key_info"]) authority_certificate["tbs_certificate"]["subject_public_key_info"])
# Attempt to install CA certificates system wide
try: try:
authority_system_wide = clients.getboolean(authority_name, "system wide") config_path = clients.get(authority_name, "config path")
except NoOptionError: except NoOptionError:
authority_system_wide = False config_path = "/etc/certidude/authority/%s/config.json" % authority_name
finally: finally:
if authority_system_wide: if os.path.exists(config_path):
# Firefox, Chromium, wget, curl on Fedora click.echo("Found config in: %s" % config_path)
# Note that if ~/.pki/nssdb has been customized before, curl breaks with open(config_path) as fh:
if os.path.exists("/usr/bin/update-ca-trust"): bootstrap = json.loads(fh.read())
link_path = "/etc/pki/ca-trust/source/anchors/%s" % authority_name else:
if not os.path.lexists(link_path): bootstrap_url = "http://%s/api/bootstrap/" % authority_name
os.symlink(authority_path, link_path) click.echo("Attempting to bootstrap connection from %s" % bootstrap_url)
os.system("update-ca-trust") r = requests.get(bootstrap_url)
if r.status_code != 200:
raise ValueError("Bootstrap API endpoint returned %s" % r.content)
bootstrap = r.json()
# curl on Fedora ? config_partial = config_path + ".part"
# pip with open(config_partial, "wb") as oh:
oh.write(r.content)
# Firefox (?) on Debian, Ubuntu click.echo("Writing configuration to: %s" % config_path)
if os.path.exists("/usr/bin/update-ca-certificates") or os.path.exists("/usr/sbin/update-ca-certificates"): os.rename(config_partial, config_path)
link_path = "/usr/local/share/ca-certificates/%s" % authority_name
if not os.path.lexists(link_path):
os.symlink(authority_path, link_path)
os.system("update-ca-certificates")
# TODO: test for curl, wget
try: try:
common_name = clients.get(authority_name, "common name") common_name = clients.get(authority_name, "common name")
@ -326,7 +317,7 @@ def certidude_enroll(fork, no_wait, kerberos):
if submission.status_code == requests.codes.ok: if submission.status_code == requests.codes.ok:
pass pass
if submission.status_code == requests.codes.accepted: if submission.status_code == requests.codes.accepted:
click.echo("Server accepted the request, but refused to sign immideately (%s). Waiting was not requested, hence quitting for now" % submission.text) click.echo("Server accepted the request, but refused to sign immediately (%s). Waiting was not requested, hence quitting for now" % submission.text)
os.unlink(pid_path) os.unlink(pid_path)
continue continue
if submission.status_code == requests.codes.conflict: if submission.status_code == requests.codes.conflict:
@ -367,9 +358,8 @@ def certidude_enroll(fork, no_wait, kerberos):
### Configure related services ### ### Configure related services ###
################################## ##################################
for endpoint in service_config.sections(): endpoint = authority_name
if service_config.get(endpoint, "authority") != authority_name: method = "init/openvpn"
continue
click.echo("Configuring '%s'" % endpoint) click.echo("Configuring '%s'" % endpoint)
csummer = hashlib.sha1() csummer = hashlib.sha1()
@ -377,28 +367,42 @@ def certidude_enroll(fork, no_wait, kerberos):
csum = csummer.hexdigest() csum = csummer.hexdigest()
uuid = csum[:8] + "-" + csum[8:12] + "-" + csum[12:16] + "-" + csum[16:20] + "-" + csum[20:32] uuid = csum[:8] + "-" + csum[8:12] + "-" + csum[12:16] + "-" + csum[16:20] + "-" + csum[20:32]
# Intranet HTTPS handled by PKCS#12 bundle generation,
# so it will not be implemented here
# OpenVPN set up with initscripts # OpenVPN set up with initscripts
if service_config.get(endpoint, "service") == "init/openvpn": if method == "init/openvpn":
if os.path.exists("/etc/openvpn/%s.disabled" % endpoint) and not os.path.exists("/etc/openvpn/%s.conf" % endpoint): openvpn_config_path = "/etc/openvpn/%s.conf" % endpoint
os.rename("/etc/openvpn/%s.disabled" % endpoint, "/etc/openvpn/%s.conf" % endpoint) print(bootstrap)
with open(openvpn_config_path + ".part", "w") as fh:
fh.write("client\n")
fh.write("nobind\n")
fh.write("remote %s 1194 udp\n" % endpoint)
fh.write("tls-version-min 1.2\n")
fh.write("tls-cipher %s\n" % bootstrap["openvpn"]["tls_cipher"])
fh.write("cipher %s\n" % bootstrap["openvpn"]["cipher"])
fh.write("auth %s\n" % bootstrap["openvpn"]["auth"])
fh.write("mute-replay-warnings\n")
fh.write("reneg-sec 0\n")
fh.write("remote-cert-tls server\n")
fh.write("dev tun\n")
fh.write("persist-tun\n")
fh.write("persist-key\n")
fh.write("ca %s\n" % authority_path)
fh.write("key %s\n" % key_path)
fh.write("cert %s\n" % certificate_path)
os.rename(openvpn_config_path + ".part", openvpn_config_path)
if os.path.exists("/bin/systemctl"): if os.path.exists("/bin/systemctl"):
click.echo("Re-running systemd generators for OpenVPN...") click.echo("Re-running systemd generators for OpenVPN...")
os.system("systemctl daemon-reload") os.system("systemctl daemon-reload")
if not os.path.exists("/etc/systemd/system/openvpn-reconnect.service"): # if not os.path.exists("/etc/systemd/system/openvpn-reconnect.service"):
with open("/etc/systemd/system/openvpn-reconnect.service.part", "w") as fh: # with open("/etc/systemd/system/openvpn-reconnect.service.part", "w") as fh:
fh.write(env.get_template("client/openvpn-reconnect.service").render(context)) # fh.write(env.get_template("client/openvpn-reconnect.service").render(context))
os.rename("/etc/systemd/system/openvpn-reconnect.service.part", # os.rename("/etc/systemd/system/openvpn-reconnect.service.part",
"/etc/systemd/system/openvpn-reconnect.service") # "/etc/systemd/system/openvpn-reconnect.service")
click.echo("Created /etc/systemd/system/openvpn-reconnect.service") # click.echo("Created /etc/systemd/system/openvpn-reconnect.service")
click.echo("Starting OpenVPN...") os.system("systemctl restart openvpn")
os.system("service openvpn start")
continue continue
# IPSec set up with initscripts # IPSec set up with initscripts
if service_config.get(endpoint, "service") == "init/strongswan": if method == "init/strongswan":
config = loads(open("%s/ipsec.conf" % const.STRONGSWAN_PREFIX).read()) config = loads(open("%s/ipsec.conf" % const.STRONGSWAN_PREFIX).read())
for section_type, section_name in config: for section_type, section_name in config:
# Identify correct ipsec.conf section by leftcert # Identify correct ipsec.conf section by leftcert
@ -439,7 +443,7 @@ def certidude_enroll(fork, no_wait, kerberos):
continue continue
# OpenVPN set up with NetworkManager # OpenVPN set up with NetworkManager
if service_config.get(endpoint, "service") == "network-manager/openvpn": if method == "network-manager/openvpn":
# NetworkManager-strongswan-gnome # NetworkManager-strongswan-gnome
nm_config_path = os.path.join("/etc/NetworkManager/system-connections", endpoint) nm_config_path = os.path.join("/etc/NetworkManager/system-connections", endpoint)
if os.path.exists(nm_config_path): if os.path.exists(nm_config_path):
@ -496,7 +500,7 @@ def certidude_enroll(fork, no_wait, kerberos):
# IPSec set up with NetworkManager # IPSec set up with NetworkManager
if service_config.get(endpoint, "service") == "network-manager/strongswan": if method == "network-manager/strongswan":
client_config = ConfigParser() client_config = ConfigParser()
nm_config = ConfigParser() nm_config = ConfigParser()
nm_config.add_section("connection") nm_config.add_section("connection")
@ -538,7 +542,6 @@ def certidude_enroll(fork, no_wait, kerberos):
os.system("nmcli con reload") os.system("nmcli con reload")
continue continue
# TODO: Puppet, OpenLDAP, <insert awesomeness here>
click.echo("Unknown service: %s" % service_config.get(endpoint, "service")) click.echo("Unknown service: %s" % service_config.get(endpoint, "service"))
os.unlink(pid_path) os.unlink(pid_path)