Eida.cz - Ještě víc enterprise

Ještě víc enterprise

Eida

Chápu, že Marek teď nemá už moc rád Apple, hlavně po tom, co ho poslední problémy natolik vypekly, že z toho byl ještě několik měsíců nešťastný. Kdybych mu ukázal, že mám nějaké potíže, asi by se to zvrhlo zase v hate, že nic nefunguje. Ale ono je potřeba pochopit, že jen nízké desetiny procent procent chyb jsou od výrobce a zbytek zkrátka leží a (ne)běží v samotném používání.

Je cool, pokud můžeme mít svépomocí v nějakých home-lab prostředích skutečně enterprise zabezpečení a zkoušet na tom všechno, co  je potřeba, ale prostě nikdy to nebude jako 1:1 v korporátu. Ze samotného RADIUS ověřování pomocí Samba řadičů se postupně stává evergreen jako tomu bylo dřív u Stroje času s kapsami, a to doslova. Mít více DC je výborný nápad pro zajištění funkcionality, pokud něco selže, a ve stejném duchu jsem tu chtěl mít postavený failover i pro samotný RADIUS. Myšlenka dobrá, ale zase nás tam vypekla poměrně komplikovaná PKI věc.

Až moc enterprise

Nuže. Před nějakou dobou jsem tu povídal o tom, jak je komplikovaná specifikace pro certifikáty, jejich platnost a důvěru v iOS – ono s iOS14 to začalo být ještě složitější a s iOS15+ se už teprve pohybujeme ve stratosférách vědomí, kde je jaksi až skoro nemožné hledat chyby související přímo s infrastrukturou v certifikátech. Hned na začátek by se slušelo říct, že PKI provozovatelů se opírá o spoustu lidí a spoustu specializovaných jednotek, kterým zkrátka jen pošlou svoje CSR a zbytek se nějak vytvoří sám. V domácím prostředí je tohle trochu pekelné a možná bude dávat smysl mít pro každou část sítě vlastní kořenovou CA bez superglobálního CA.

Jak to celé vlastně začalo? Síť fungovala krásně, pohoda jahoda, wifi frčí a všechny ty notifikace ukazují, co ani nechceme vědět. A pak, jednoho dne, bum – přišlo konečně přerušení. Připojení není k dispozici, začal vyprávět žlutě iOS u jména bezdrátové sítě. Když se to celé odpojilo, nebo dalo na letadýlko a připojilo znovu, zas to běželo. Asi bubák, jenže se to začalo nějak nehezky často opakovat. Uběhlo několik bezesných odpolední, protože většinou za tohle může DNS, kdy si iOS nemůže ověřit vlastnosti připojení a jestli je to captive portal, nebo jakýho čerta. Jenže nic nepomohlo. Nic. Ani kdy křičet. Natož ze zlata.

V dnešní době máme roboty, autonomní agenty... kdo má tu sílu dát jim SSH klíče a přístup na roota? Někdy se to musí prostě risknout. Trvalo to zas celé odpoledne, ale pak se ukázala konečně celá záhada. Protože Turris využíval failover a přehazoval klienty z jedné instance na druhou, jak mu to zrovna přišlo cool, provádělo se ověřování různými certifikáty (i když podepsanými stejnou CA), které neměly nic společného. Koho by to napadlo. Od iOS14+ je potřeba v rámci striktního RFC 2818 používat Subject Alternative Name pro sdílený logický název, docela stejně jako se to dělá v případě celé domény. A tam to už trochu naráží v domácím prostředí, pokud běží autorita na stejném stroji, resp. na jednom (nebo jako kopie na obou) NAS. Hmm.

V první řadě bylo teda potřeba udělat něco přímo s generováním certifikátů. Když se použije nějaké easyRSA, nebo jak tomu říkají, tak v té kostře stačí upravit základní konfiguraci tak, aby poskytovala SAN (ideálně jako DNS.1) pro logický hostname a hlavně aby se všechna tato rozšíření posílala do budoucích CSR.

server.cnf 1013 bajtů
[ CA_default ]
dir            = ./
certificate    = $dir/ca.pem
private_key    = $dir/ca.key
# ...standardní pole...
preserve       = no
copy_extensions = copy # bez toho SAN ze CSR do certifikátu nepřejde
policy         = policy_match

[ req ]
prompt             = no
distinguished_name = server
default_bits       = 2048
input_password     = heslo_ca_klice
output_password    = heslo_server_klice
req_extensions     = v3_req # extensions jdou do CSR

[server]
countryName            = CZ
stateOrProvinceName    = Czech Republic
organizationName       = Eida.cz EXAMPLE
commonName             = "Eida.cz RADIUS Server"
emailAddress           = example@eida.lan

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage         = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName   = @alt_names # SAN sekce

[alt_names]
# sdílený logický hostname — stejný text v TLSTrustedServerNames v mobileconfig
DNS.1 = radius.eida.lan
# volitelně – specifický hostname tohoto serveru
DNS.2 = dc1.eida.lan
Specifikace pro OpenSSL

Refresh skript pak sice může žít dál na serveru, ale v tuhle chvíli potřebujeme, aby už nikdy nesahal na CA. Ta má typickou životnost 10 let, na to stačí udělat nějaký číhač a zapomenout. Vytvoření pro první i druhý server se pak dá přenášet, nebo dělat na více místech, ale výsledek by měl být vždy stejný.

refresh.sh 2.23 KiB
#!/bin/bash
# /etc/freeradius/3.0/certs/refresh.sh
# obnova server certifikátu — CA se NIKDY neregeneruje
set -e
cd /etc/freeradius/3.0/certs/

# sanity check — ověř, že CA existuje a je platná
openssl x509 -in ca.pem -noout -fingerprint -sha1 || {
    echo "CHYBA: ca.pem chybí nebo je poškozená. Abort." >&2
    exit 1
}

# záloha stávajícího certifikátu
cp -f server.pem "server.pem.bak-$(date +%Y%m%d-%H%M%S)" 2>/dev/null || true

# smaž POUZE serverové soubory — ca.key a ca.pem se NEDOTÝKÁME
rm -f server.key server.csr server.crt server.pem server.p12
rm -f index.txt index.txt.attr index.txt.old serial serial.old [0-9]*.pem
echo "01" > serial
touch index.txt
echo "unique_subject = yes" > index.txt.attr

# 1) nový klíč + CSR (SAN pochází ze server.cnf [alt_names])
openssl req -new \
    -out server.csr \
    -keyout server.key \
    -config ./server.cnf \
    -passin  pass:heslo_ca_klice \
    -passout pass:heslo_server_klice
chmod 640 server.key

# 2) podpis CA (copy_extensions=copy zajistí přenos SAN z CSR)
openssl ca -batch \
    -keyfile ca.key \
    -cert    ca.pem \
    -in      server.csr \
    -key     heslo_ca_klice \
    -out     server.crt \
    -extensions xpserver_ext \
    -extfile    xpextensions \
    -config     ./server.cnf

# ověření SAN v podepsaném certifikátu
echo "=== SAN v novém certifikátu ==="
openssl x509 -in server.crt -noout -text | grep -A3 "Subject Alt" || true
openssl x509 -in server.crt -noout -fingerprint -sha256

# 3) konverze na PEM (formát, který FreeRADIUS čte)
openssl pkcs12 -export \
    -in server.crt -inkey server.key -out server.p12 \
    -passin pass:heslo_server_klice -passout pass:heslo_server_klice
openssl pkcs12 -in server.p12 -out server.pem \
    -passin pass:heslo_server_klice -passout pass:heslo_server_klice
chmod 640 server.pem server.p12

# ověření řetězce
openssl verify -CAfile ca.pem server.pem

# 4) deploy
cp server.key /etc/ssl/radius/server.key
cp server.pem /etc/ssl/radius/server.pem
chown -R root:freerad /etc/ssl/radius/

# 5) smaž TLS session cache (starý session reuse by nabídl certifikát před renewalem)
rm -rf /var/log/freeradius/tlscache/*

systemctl restart freeradius
systemctl is-active freeradius && echo "=== FreeRADIUS OK ==="
Periodická obnova certifikátů RADIUS serverů

Pak je vhodná ještě kosmetická úprava samotného EAP modulu pro FreeRADIUS, protože musíme jít trochu s dobou. To znamená konečně bumpnout TLS na 1.3 a udělat možná trochu hack, který souvisel s tím odpojováním – nechat cache třeba na týden, alespoň experimentálně. Pokud se pak objeví v síti nějaký pavouk, tak to bude pak snad dohledatelné v logu.

eap.conf 675 bajtů
# /etc/freeradius/3.0/mods-available/eap (sekce tls-common)

tls-config tls-common {
    private_key_password = heslo_server_klice
    private_key_file     = /etc/ssl/radius/server.key
    certificate_file     = /etc/ssl/radius/server.pem
    ca_file              = /etc/ssl/radius/ca.pem

    # iOS a Android vyžadují TLS 1.2+; TLS 1.3 funguje od iOS 15 / Android 10
    tls_min_version = "1.2"
    tls_max_version = "1.3"

    # Session cache: zkracuje dobu připojení při roamingu
    # Lifetime 24h místo defaultních 168h — kompromis výkon/bezpečnost
    cache {
        enable   = yes
        lifetime = 86400
        name     = "EAP-TLS-Session-Cache"
    }
}
EAP – konfigurace na jeden týden cache

Nezbytnou třešničkou na dortu je pak ještě nasazení nastavení co nejméně bolestivým způsobem. Bohužel tvorba profilů vyžaduje ve full-enterprise provisioning, což se doma dělá trochu složitě, možná až škodlivě. Ale je možné vytvořit profil, nebo možná dokonce dva profily – jeden pro naši CA s overtrust a pak profil, co zařídí WPA2/3-EAP autentizační flow. Tohle jde udělat buď ručně v Apple Configuratoru, nebo se to dá prostě naskriptovat, protože to vlastně jen XMLko.

eap.conf 675 bajtů
# /etc/freeradius/3.0/mods-available/eap (sekce tls-common)

tls-config tls-common {
    private_key_password = heslo_server_klice
    private_key_file     = /etc/ssl/radius/server.key
    certificate_file     = /etc/ssl/radius/server.pem
    ca_file              = /etc/ssl/radius/ca.pem

    # iOS a Android vyžadují TLS 1.2+; TLS 1.3 funguje od iOS 15 / Android 10
    tls_min_version = "1.2"
    tls_max_version = "1.3"

    # Session cache: zkracuje dobu připojení při roamingu
    # Lifetime 24h místo defaultních 168h — kompromis výkon/bezpečnost
    cache {
        enable   = yes
        lifetime = 86400
        name     = "EAP-TLS-Session-Cache"
    }
}
EAP – konfigurace na jeden týden cache

Takto vytvoření soubor by měl mít na sobě ozubené kolečko. Je možné ho pohodlně poslat AirDropem na dotčená zařízení, fungovat to bude na iOS i na macOS, ale je pak ještě nezbytně potřeba zapnout absolutní důvěru pro osobní CA, jinak se to bude pochopitelně každou chvíli ptát.

Při importu profilu tedy 1) uložime certifikát, 2) uložíme přihlašovací údaje pro EAP, 3) nastavíme plnou důvěru. Všechno by mělo jít hladce, i když je mi jasné, že to zní celé rozhodně jakkoliv, než hladce. Budu to tedy teď pár dnů zase pozorovat a jestli to zase selže, pak už teda nevím a bude tableflip. Všechno je v cronu, kontroly také... takže nás nespíš zase spíš vypečou updaty a doporučení, ale i to překonáme, musíme. Všechno bude ještě víc enterprise.

Tento článek přečetlo již 91 čtenářů (1 dnes).

Komentáře

Nový komentář