automatic update of authorized_keys from LDAP

master
vuko 2020-11-07 18:39:34 +01:00
parent eb7734033d
commit a82c44f3cc
2 changed files with 97 additions and 9 deletions

View File

@ -38,8 +38,13 @@ let
ipv4 = "10.9.1.1";
};
};
hostname = "customs";
openvpn-auth = import ./openvpn-auth { inherit pkgs; };
secrets-path = "/etc/nixos/secrets/";
update_authorized_keys = pkgs.writeShellScriptBin "update_authorized_keys" ''
${pkgs.python3.withPackages (pp: [ pp.ldap3 ])}/bin/python ${./update_authorized_keys.py} ${hostname} ${secrets-path}/ldap-password.txt
'';
in {
imports =
[
@ -77,7 +82,7 @@ in {
options = [ "rw" "mode=755" "size=200M" "nosuid" "nodev" "relatime" "noexec" ];
};
networking.hostName = "customs";
networking.hostName = hostname;
networking.useDHCP = false;
networking.vlans = {
laser = {
@ -92,8 +97,8 @@ in {
script = ''
${pkgs.coreutils}/bin/install --owner=root --mode=700 --directory /mnt/secrets/nginx/
${pkgs.coreutils}/bin/install --owner=root --mode=400 -t /mnt/secrets/nginx/ \
/etc/nixos/secrets/nginx/at.hackerspace.pl.key \
/etc/nixos/secrets/nginx/at.hackerspace.pl.crt
${secrets-path}/nginx/at.hackerspace.pl.key \
${secrets-path}/nginx/at.hackerspace.pl.crt
${pkgs.acl}/bin/setfacl -m "u:nginx:rx" /mnt/secrets/nginx
${pkgs.acl}/bin/setfacl -m "u:nginx:r" /mnt/secrets/nginx/*
'';
@ -351,6 +356,7 @@ in {
enable = true;
systemCronJobs = [
"*/5 * * * * root ${log-neigh}"
"0 3 * * * root ${update_authorized_keys}"
];
};
@ -472,10 +478,10 @@ in {
proto udp6
dev vpn
dev-type tun
ca /etc/nixos/secrets/openvpn-public/ca.crt
cert /etc/nixos/secrets/openvpn-public/server.crt
key /etc/nixos/secrets/openvpn-public/server.key
dh /etc/nixos/secrets/openvpn-public/dh.pem
ca ${secrets-path}/openvpn-public/ca.crt
cert ${secrets-path}/openvpn-public/server.crt
key ${secrets-path}/openvpn-public/server.key
dh ${secrets-path}/openvpn-public/dh.pem
server 10.9.1.0 255.255.255.0
push "route 10.0.0.0 255.0.0.0"
@ -493,7 +499,7 @@ in {
environment.systemPackages = with pkgs; [
vim tcpdump htop nmon tmux git file procps parted dmidecode ack utillinux nmap mosh ncdu tree lz4 bind
rxvt_unicode.terminfo
rxvt_unicode.terminfo update_authorized_keys
];
programs.mtr.enable = true;

82
update_authorized_keys.py Executable file
View File

@ -0,0 +1,82 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p python3Packages.ldap3
from ldap3 import Server, Connection, LEVEL
from ldap3.utils.dn import escape_rdn
import getpass
import logging
from pathlib import Path
import filecmp
import os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("hostname", help="hostname")
parser.add_argument("ldap_pass_file", type=Path, help="file containing lap password")
header_warning = """
################################### WARNING ####################################
# This file was created automatically from LDAP database and *WILL* be
# overwritten. If you need to add / remove keys make changes to
# {}-admin group / members sshPublicKey attributes in LDAP and rerun
# update_authorized_keys script
################################################################################
""".lstrip()
def get_keys(connection: Connection, group: str):
c = connection
c.search(
search_base="ou=People,dc=hackerspace,dc=pl",
search_filter=(
"(&"
"(objectClass=hsMember)"
f"(memberOf=cn={escape_rdn(group)},ou=Group,dc=hackerspace,dc=pl)"
")"
),
search_scope=LEVEL,
attributes=["sshPublicKey"],
)
admin_keys = []
for entry in c.response:
attributes = entry["attributes"]
for key in entry["attributes"]["sshPublicKey"]:
yield key.strip()
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
args = parser.parse_args()
user = f"cn={escape_rdn(args.hostname)},ou=Boxen,dc=hackerspace,dc=pl"
password = args.ldap_pass_file.read_text().strip()
s = Server("ldap.hackerspace.pl", use_ssl=True)
with Connection(s, user=user, password=password, raise_exceptions=True) as c:
keys = list(get_keys(c, f"{args.hostname}-admin"))
if len(keys) < 2:
raise Exception("Less then two keys found - aborting")
ssh_dir = Path("/", "root", ".ssh")
ssh_dir.mkdir(mode=700, exist_ok=True)
ssh_dir.chmod(0o700)
new_file = ssh_dir.joinpath("authorized_keys_new")
old_file = ssh_dir.joinpath("authorized_keys")
try:
new_file.unlink()
except FileNotFoundError:
pass
new_file.write_bytes(
header_warning.format(args.hostname).encode() + b"\n".join(keys)
)
if not old_file.exists():
logging.info('Creating new "authorized_keys" file')
os.rename(new_file, old_file)
elif filecmp.cmp(new_file, old_file, shallow=False):
logging.info('Nothing changed - "authorized_keys" file is up to date')
new_file.unlink()
else:
logging.info('Keys changed - overwriting "authorized_keys" file')
os.rename(new_file, old_file)