Introductie
Na heel wat doorgelezen te hebben op de verschillende fora op het internet was ik zelf ook wel op zoek naar een goede oplossing voor het gebruik van certificaten op de ingebouwde RADIUS server van de USG (3P). Standaard wordt er gebruik gemaakt van een self-signed certificaat met de naam 'ubnt', wat ervoor zorgt dat je eigenlijk alle apparaten zo in moet stellen dat zij het certificaat niet gaan valideren, of je moet iedereen dat certificaat los laten importeren zodat er geen foutmelding komt. Al met al geen prettige situatie.
Tijdens deze zoektocht kwam ik veel informatie tegen, maar niemand die het nu echt goed had opgelost. Voornamelijk mensen die maar blijven hameren op UI dat het belachelijk is dat dit niet goed geïntegreerd zit in het product. Soit, dat gaat me niet helpen, dus het dan maar zelf uitvogelen.
Standaard configuratie
Als eerste ben ik ingelogd via SSH op mijn USG 3P om eens rond te snuffelen en te kijken wat ik kan vinden. Ik wist al dat freeradius gebruikt werd als product, dus het was een kwestie van even de standaard paden afzoeken. Het configuratiebestand wat gebruikt wordt door freeradius voor zijn EAP configuratie is te vinden op:
In deze configuratie wordt een verwijzing gemaakt naar een
server.key en een
server.pem die opgeslagen worden in de directory:
Aldaar vinden we de twee 'bestanden', die onder de motorkap eigenlijk gewoon een symbolic link zijn naar het self-signed certificaat op een andere lokatie, te weten:
server.key -> /etc/ssl/private/ssl-cert-snakeoil.key
server.pem -> /etc/ssl/certs/ssl-cert-snakeoil.pem
Het idee
Om zo min mogelijk aanpassingen te hoeven maken aan de configuratie van de USG is het idee om de twee symoblic links te redirecten naar een eigen certificaat, in mijn geval dus van Let's Encrypt.
In eerste instantie was het idee zelfs om het nieuwe certificaat en de sleutel hier gewoon in de directory te plaatsen, maar deze zit aardig weggestopt in de configuratie van de USG. Ook heb ik begrepen dat deze configuratie bij elke firmware upgrade weer wordt overschreven. Aangezien we wel een oplossing willen hebben die uiteindelijk stand houdt, was een slimmere plek nodig om die bestanden te gaan plaatsen.
In mijn geval heb ik er dan ook voor gekozen om een directory '
radius' aan te maken op de volgende lokatie:
Zelf heb ik nooit hoeven werken met custom scripts op mijn USG, maar naar wat ik begrijp wordt alles op deze plek wel gewoon met rust gelaten tijdens een firmware upgrade. Ik heb mijn eigen bestanden hier dan ook geplaatst en daarna even een chmod gegeven naar de juiste waardes, zodat freeradius er ook netjes bij kan.
mkdir /config/scripts/radius/
chown freerad:freerad /config/scripts/radius/certificate.pem
chown freerad:freerad /config/scripts/radius/privkey.pem
chmod 400 /config/scripts/radius/certificate.pem
chmod 400 /config/scripts/radius/privkey.pem
Daarna was het alleen nog een kwestie van het omgooien van die symoblic links om ze naar deze lokatie te laten wijzen.
ln -sfn /config/scripts/radius/certificate.pem /etc/freeradius/certs/server.pem
ln -sfn /config/scripts/radius/privkey.pem /etc/freeradius/certs/server.key
chown -h freerad:freerad /etc/freeradius/certs/server.pem
chown -h freerad:freerad /etc/freeradius/certs/server.key
service freeradius restart
De service moet echt herstart worden kwam ik achter. Het was niet voldoende om alleen een reload van de freeradius configuratie uit te voeren.
Automatiseren van de symbolic links
Nu werkt dit wel voor nu, maar het idee was iets te maken wat ook in de toekomst nog gewoon blijft werken. Om dit te bewerkstelligen kwam ik een directory tegen met wat extra waarde.
/config/scripts/post-config.d/
Alles scripts in die directory worden automatisch uitgevoerd na een firmware upgrade of een reboot, zover ik begrijp. Een ideale plek om iets neer te zetten om die symbolic links weer opnieuw te maken.
Bash: /config/scripts/post-config.d/update-radius-symlink.sh
1
2
3
4
5
6
7
8
9
10
11
12
| #!/bin/bash
# This script is responsible for re-creating the symbolic links which are accessed by FreeRADIUS for the USG
# built-in RADIUS services.
ln -sfn /config/scripts/radius/certificate.pem /etc/freeradius/certs/server.pem;
ln -sfn /config/scripts/radius/privkey.pem /etc/freeradius/certs/server.key;
chown -h freerad:freerad /etc/freeradius/certs/server.pem;
chown -h freerad:freerad /etc/freeradius/certs/server.key;
service freeradius restart; |
Daarna nog even de verplichte chmod om hem executable te maken.
chmod 755 /config/scripts/post-config.d/update-radius-symlink.sh
Als het goed is heeft de USG dan nu dus zijn certificaat en worden de symbolic links netjes ververst bij de reboot en/of een upgrade. Dat is dus al een heel stuk beter dan de out-of-the-box situatie.
Automatiseren installatie certificaat
De volgende stap die ik wilde bereiken is het vernieuwen van het Let's Encrypt certificaat, maar dan specifiek de installatie op de USG. Ik wil het lean & mean houden, dus geen installaties van de ACME client op de USG of ander spul om het te automatiseren. In mijn geval maak ik gebruik van mijn Synology NAS om het certificaat aan te vragen. Deze moet uiteindelijk op de USG terecht komen (kom ik nog op terug), maar dat kan natuurlijk niet direct als root. Dus ik heb ervoor gekozen om er maar vanuit te gaan dat het certificaat klaar wordt gezet in de
/tmp directory, specifiek onder de volgende paden:
/tmp/radius_certificate.pem
/tmp/radius_privkey.pem
Deze bestanden moeten dus verplaatst worden naar de aangemaakte radius directory, dus daar heb ik wederom een script voor in het leven geroepen.
Bash: /config/scripts/upate-radius-certificate.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| #!/bin/bash
# This script is responsible for checking if there is a new certificate and private key available for the USG
# RADIUS service. If this is the case, the script will move the files and replace the symlinks which are
# currently in place for either the default self-signed certificate, or for the certificate which needs to be
# renewed. The files and symlinks are all assigned to the freeradius user.
if [ -f /tmp/radius_certificate.pem ] && [ -f /tmp/radius_privkey.pem ]; then
echo "A new certificate & key was found in /tmp for RADIUS services.";
mkdir -p /config/scripts/radius;
mv -f /tmp/radius_certificate.pem /config/scripts/radius/certificate.pem;
mv -f /tmp/radius_privkey.pem /config/scripts/radius/privkey.pem;
chown freerad:freerad /config/scripts/radius/certificate.pem;
chown freerad:freerad /config/scripts/radius/privkey.pem;
chmod 400 /config/scripts/radius/certificate.pem;
chmod 400 /config/scripts/radius/privkey.pem;
/bin/bash /config/scripts/post-config.d/update-radius-symlink.sh
fi |
Wanneer het script wordt uitgevoerd gaat hij dus controleren of er een nieuw certificaat en sleutel klaar staat. Wanneer dit het geval is verplaatst hij die bestanden, past eigenaarschap en rechten aan en roept daarna het eerder aangemaakte script aan om de service te herstarten. Dat is nodig om het nieuwe certificaat in te laden, zoals eerder aangegeven. Natuurlijk moet het script nog wel even executable gemaakt worden.
chmod 755 /config/scripts/update-radius-certificate.sh
Het uitvoeren van dit script dient te gebeuren als root, maar ik kan niet zomaar als root inloggen en extern het signaal afgeven. Het idee is dus om het script te schedulen, en laten ze daar nu een mooie functionaliteit voor hebben ingebouwd met behulp van de custom JSON.
JSON: config.gateway.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| {
"system": {
"task-scheduler": {
"task": {
"radius-certificate-update": {
"executable": {
"path": "/config/scripts/update-radius-certificate.sh"
},
"interval": "15m"
}
}
}
}
} |
Deze dient dan op je controller geplaatst te worden in de
correcte directory voor de site waar de USG voor actief is. Daarna is het een kwestie van een Force Provision van de USG in de controller en vanaf nu gaat hij netjes elke 15 minuten kijken of er werk te doen is.
Automatiseren vernieuwing certificaat (via Synology NAS)
Ik maak al veelvuldig gebruik van Let's Encrypt certificaten op mijn NAS voor zowel hosted websites (hobby projectjes) als voor mijn reverse proxy. Na eerdere pogingen hier op Tweakers om wat zaken uit te vinden wist ik al dat alle certificaten op een Synology primair onder één directory worden opgeslagen:
/usr/syno/etc/certificate/_archive/
Of een certificaat nu gebruikt wordt voor iets of niet, daar staat hij. Hij wordt door de NAS ook netjes vernieuwd, dus dat is dan ook direct geregeld. Er zit bij elk certificaat een '
renew.json' bestand en dat is maar goed ook, want elk certificaat staat in een directory met een naam opgebouwd uit random karakters. Maar in dit json bestand staat de naam zoals ik hem zelf kan herkennen.
Om het certificaat over te zetten vond ik het voor de hand liggen om de NAS toe te voegen aan de trusted keys van de USG. Standaard heeft de root user geen key, dus die heb ik even aangemaakt als root via:
Na het beantwoorden van elke vraag met een Enter (en niets anders dan die Enter) heb ik de inhoud van de public key, zonder het commentaar aan het einde, geïmporteerd als sleutel in de controller via de GUI. Deze public key staat standaard dus opgeslagen onder:
Om het certificaat over te zetten heb ik gebruik gemaakt van de Task Scheduler in Synology DSM, te bereiken via de Control Panel in de GUI van de Synology NAS. Ik heb daar een Scheduled Task > User-defined script taak toegevoegd. Als naam iets leuks gegeven en eenmaal per week gescheduled met het volgende Run command (User-defined script):
scp /usr/syno/etc/certificate/_archive/XXXXXX/fullchain.pem youruser@192.168.1.1:/tmp/radius_certificate.pem;
scp /usr/syno/etc/certificate/_archive/XXXXXX/privkey.pem youruser@192.168.1.1:/tmp/radius_privkey.pem
Vanzelfsprekend nog even de youruser vervangen door de gebruiker die in de controller is gekozen voor SSH toegang, alsmede het IP adres van de USG zelf. De XXXXXX moet natuurlijk ook even vervangen worden zodat het pad wijst naar het goede certificaat op de Synology NAS.
Eindresultaat
Met dit allemaal ingericht op de bovenstaande wijze heb ik volgens mij iets wat niet alleen werkt, maar ook blijft werken in de toekomst bij een upgrade. De NAS vernieuwt het certificaat en pompt het eens per week naar de USG. Die draait elke 15 minuten een snelle controle of er een certificaat & key klaar staat, waarna hij die installeert en de freeradius dienst herstart.
Na het aanmaken van het draadloze netwerk met WPA2 Enterprise, gebruik makende van de RADIUS van de USG, konden alle clients verbinden met de volgende instellingen:
code:
1
2
3
4
5
6
| EAP Method: PEAP
Phase-2 authentication: MSCHAPv2
CA certificate: Use system certificates
Domain: <overgenomen uit Let's Encrypt certificaat>
Identity: <Radius User: Username>
Password: <Radius User: Password> |
Het maakte voor mij niet uit of ik een certificaat had aangevraagd voor radius.example.com en in Domain dan gewoon example.com configureerde, dat werkte gewoon. Een ander domain werkte natuurlijk dan weer niet (gelukkig maar). Het instellen van het CA certificate naar Use system certificates is natuurlijk het hele idee, zodat je niet zelf hoeft te importeren op apparaten, noch dat mensen het self-signed certificaat moeten vertrouwen.
Naast EAP-PEAP werkt EAP-TTLS overigens ook met deze set-up, maar zelf heb ik daar geen behoefte aan om dat te gebruiken. Maar als jij dat prettiger vindt, dan werkt het wel.
Ps. Als je gebruik maakt van de USG RADIUS voor het toewijzen van een VLAN op basis van de gebruiker die dus inlogt via 802.1x (WPA2 Enterprise), dan mag het VLAN waar die gebruiker op uitkomt geen dedicated SSID toegewezen hebben. Je zult dus een Dummy/Default VLAN moeten toewijzen aan je WPA2 Enterprise SSID wat niet overeen komt met één van de VLANs die je wilt toewijzen aan gebruikers. Als het VLAN wel in gebruik is door een dedicated SSID dan blijft het proces van verbinden netjes hangen...
Mocht iemand hier nog aanvullingen en/of opmerkingen over hebben, gooi het dan vooral in het topic. Ik ben erg benieuwd naar de inzichten van mensen en de manieren waarop het misschien nog beter kan, want dit was mijn eerste poging voor 'customisation' van de USG.