#!/bin/sh # Installe la Holleville Root CA sur un poste Linux : # - magasin système (Debian/Ubuntu/Mint, Fedora/RHEL, Arch, openSUSE) # - navigateurs NSS de l'utilisateur (Chrome/Chromium/Brave/Edge/Vivaldi, Firefox) # # Usage : curl -fsSL https://pki.holleville.eu/install-ca.sh | sudo sh # curl -fsSL https://pki.holleville.eu/install-ca.sh | sudo sh -s -- --uninstall set -eu CA_URL="https://pki.holleville.eu/root.pem" CA_NAME="Holleville Root CA" CA_FILE="holleville-root-ca" # Empreinte attendue : le script refuse tout certificat différent (protection contre un téléchargement altéré) CA_SHA256="46:29:38:11:02:E2:8B:BA:F5:C1:3E:AE:4F:D6:89:B4:47:4D:5C:5A:5B:DC:9A:6F:82:A4:17:76:5E:27:2A:C4" MODE=install [ "${1:-}" = "--uninstall" ] && MODE=uninstall info() { printf ' [i] %s\n' "$*"; } ok() { printf ' [✓] %s\n' "$*"; } warn() { printf ' [!] %s\n' "$*" >&2; } die() { printf ' [✗] %s\n' "$*" >&2; exit 1; } [ "$(id -u)" -eq 0 ] || die "à lancer en root : curl -fsSL https://pki.holleville.eu/install-ca.sh | sudo sh" # Utilisateur réel (pour ses navigateurs), même lancé via sudo TARGET_USER=${SUDO_USER:-root} TARGET_HOME=$(getent passwd "$TARGET_USER" | cut -d: -f6) # Distribution : répertoire d'ancres et commande de mise à jour du magasin système if command -v update-ca-certificates >/dev/null 2>&1 && [ -d /usr/local/share/ca-certificates ]; then ANCHOR=/usr/local/share/ca-certificates/$CA_FILE.crt; UPDATE="update-ca-certificates" [ "$MODE" = uninstall ] && UPDATE="update-ca-certificates --fresh" elif [ -d /etc/pki/ca-trust/source/anchors ]; then ANCHOR=/etc/pki/ca-trust/source/anchors/$CA_FILE.crt; UPDATE="update-ca-trust extract" elif [ -d /etc/ca-certificates/trust-source/anchors ]; then ANCHOR=/etc/ca-certificates/trust-source/anchors/$CA_FILE.crt; UPDATE="update-ca-trust extract" elif [ -d /etc/pki/trust/anchors ]; then ANCHOR=/etc/pki/trust/anchors/$CA_FILE.crt; UPDATE="update-ca-certificates" else die "distribution non reconnue : magasin de certificats introuvable" fi install_pkg() { if command -v apt-get >/dev/null 2>&1; then DEBIAN_FRONTEND=noninteractive apt-get install -y -q "$1" >/dev/null elif command -v dnf >/dev/null 2>&1; then dnf install -y -q "$2" >/dev/null elif command -v pacman >/dev/null 2>&1; then pacman -S --noconfirm --needed "$3" >/dev/null elif command -v zypper >/dev/null 2>&1; then zypper -q install -y "$4" >/dev/null else return 1; fi } # Bases NSS de l'utilisateur : Chromium & dérivés (~/.pki/nssdb) et profils Firefox nss_dbs() { [ -n "$TARGET_HOME" ] || return 0 for d in "$TARGET_HOME/.pki/nssdb" \ "$TARGET_HOME"/.mozilla/firefox/*/ \ "$TARGET_HOME"/snap/firefox/common/.mozilla/firefox/*/ \ "$TARGET_HOME"/.var/app/org.mozilla.firefox/.mozilla/firefox/*/; do [ -f "${d%/}/cert9.db" ] && echo "${d%/}" done return 0 } as_user() { if [ "$TARGET_USER" = root ]; then "$@"; else runuser -u "$TARGET_USER" -- "$@"; fi; } echo "== $CA_NAME : $MODE" if [ "$MODE" = uninstall ]; then rm -f "$ANCHOR"; $UPDATE >/dev/null 2>&1; ok "retirée du magasin système" if command -v certutil >/dev/null 2>&1; then for db in $(nss_dbs); do as_user certutil -d "sql:$db" -D -n "$CA_NAME" 2>/dev/null && ok "retirée de $db" done fi exit 0 fi # 1. Téléchargement et vérification command -v openssl >/dev/null 2>&1 || install_pkg openssl openssl openssl openssl || die "openssl requis" TMP=$(mktemp) trap 'rm -f "$TMP"' EXIT if command -v curl >/dev/null 2>&1; then curl -fsSL -o "$TMP" "$CA_URL" elif command -v wget >/dev/null 2>&1; then wget -qO "$TMP" "$CA_URL" else die "curl ou wget requis"; fi FP=$(openssl x509 -in "$TMP" -noout -fingerprint -sha256 2>/dev/null | cut -d= -f2) || true [ "$FP" = "$CA_SHA256" ] || die "empreinte inattendue ($FP) : certificat refusé" ok "certificat téléchargé, empreinte vérifiée" # 2. Magasin système install -m 644 "$TMP" "$ANCHOR" $UPDATE >/dev/null 2>&1 ok "ajoutée au magasin système ($ANCHOR)" # 3. Navigateurs (NSS) if ! command -v certutil >/dev/null 2>&1; then info "installation de certutil..." install_pkg libnss3-tools nss-tools nss mozilla-nss-tools || warn "certutil indisponible : navigateurs non configurés" fi if command -v certutil >/dev/null 2>&1; then # Chromium & dérivés : créer la base si absente pour que le navigateur la trouve if [ -n "$TARGET_HOME" ] && [ ! -f "$TARGET_HOME/.pki/nssdb/cert9.db" ]; then as_user mkdir -p "$TARGET_HOME/.pki/nssdb" as_user certutil -d "sql:$TARGET_HOME/.pki/nssdb" -N --empty-password fi chmod 644 "$TMP" found=0 for db in $(nss_dbs); do as_user certutil -d "sql:$db" -D -n "$CA_NAME" >/dev/null 2>&1 || true as_user certutil -d "sql:$db" -A -t "C,," -n "$CA_NAME" -i "$TMP" ok "ajoutée à $db"; found=1 done [ $found -eq 1 ] || info "aucun profil de navigateur NSS trouvé" fi echo "== Terminé. Redémarre tes navigateurs pour prendre en compte la nouvelle CA."