FreeRDP et le kerberos coté serveur
Ces derniers temps, j'ai pas mal exploré des sujets de FreeRDP avec remote credential guard, Kerberos et NLA, je fais donc
un petit billet sur comment kerberossiser sa partie serveur de FreeRDP.
NLA, SPNego et Kerberos

Toute la kerberosserie commence avec le NLA: si on se connecte sur un serveur RDP
avec mstsc et que la configuration est à peu près standard.
Quand on exécute mstsc /v:dc.hardening2.com, mstsc va:
- se connecter au serveur et négocier du NLA;
- établir la couche TLS;
- commencer NLA en envoyant dedans un paquet SPNego, et ce paquet SPNego contiendra un début de négociation Kerberos en mode user2user dans le champs du optimistic token. En gros, mstsc (via CredSSP) considère qu'évidement on supporte tout ce qui va bien et qu'en plus de donner la liste ordonnée des modes d'authentification qu'on supporte, on peut gagner un aller-retour en donnant directement un token pour celui qu'on préfère, car à coup sûr c'est celui-là que le serveur va utiliser;
- donc dans le cas standard, ce premier token va être une demande de tgt dans le cadre d'un négociation en mode user2user. Ceci suppose que le serveur ai d'une manière ou d'une autre un "compte machine" qui lui permette de récupérer un TGT. Le serveur acquière le TGT et le renvoie au client;
- dans l'étape suivante, le client envoie un Service Ticket (souvent appelé TGS) pour validation au serveur,
ce ticket est pour
TERMSRV/<nom serveur>@<REALM>. On est en user2user, le serveur valide donc ce ticket "à travers" le client.
Notes: dans certain cas, on peut se passer de la couche SPNego et envoyer directement le message qui va bien. C'est ce que fait tout le temps le vénérable rdesktop, mais aussi FreeRDP quand on ne peut faire que du NTLM ou un type de kerberos (à ce moment là pas besoin de rajouter la couche de négociation de SPNego)
Configuration
Très bien pour la théorie, mais en pratique ? Alors évidement on peut passer des commandes sous windows et jouer avec les clicodrômes du serveur sous windows, mais ce n'est pas ce qui nous plait non ?
On va donc plutôt utiliser msktutil sous Linux pour créer le keytab qui va bien. On commence par se logguer en kerberos avec un compte avec les bons privilèges, par exemple, dans mon cas:
$ kinit Administrateur@HARDENING2.COM Password for Administrateur@HARDENING2.COM: $ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: Administrateur@HARDENING2.COM Valid starting Expires Service principal 08/12/2025 14:11:09 09/12/2025 00:11:09 krbtgt/HARDENING2.COM@HARDENING2.COM renew until 09/12/2025 14:10:49
Ensuite on va créer le host djinn65, lui attacher le service TERMSRV, et récupérer le keytab correspondant. Dans mon exemple, le controlleur de domaine s'appelle dc.hardening2.com:
$ msktutil --server dc.hardening2.com --precreate --host djinn65 -b cn=computers --service TERMSRV --description "host account for djinn65" --enctypes 24 -N $ msktutil --server dc.hardening2.com --auto-update --keytab djinn65-termsrv.keytab --host djinn65 -N $ klist -kt djinn65-termsrv.keytab Keytab name: FILE:djinn65-termsrv.keytab KVNO Timestamp Principal ---- ------------------- ------------------------------------------------------ 15 05/12/2025 22:51:04 djinn65$@HARDENING2.COM 15 05/12/2025 22:51:04 djinn65$@HARDENING2.COM 15 05/12/2025 22:51:04 djinn65$@HARDENING2.COM 15 05/12/2025 22:51:04 DJINN65$@HARDENING2.COM 15 05/12/2025 22:51:04 DJINN65$@HARDENING2.COM 15 05/12/2025 22:51:04 DJINN65$@HARDENING2.COM 15 05/12/2025 22:51:04 TERMSRV/djinn65@HARDENING2.COM 15 05/12/2025 22:51:05 TERMSRV/djinn65@HARDENING2.COM 15 05/12/2025 22:51:05 TERMSRV/djinn65@HARDENING2.COM 15 05/12/2025 22:51:05 host/djinn65@HARDENING2.COM 15 05/12/2025 22:51:05 host/djinn65@HARDENING2.COM 15 05/12/2025 22:51:05 host/djinn65@HARDENING2.COM
On notera l'entrée associée à la machine avec le dollar à la fin (DJINN65$@HARDENING2.COM).
Il y a plusieurs manières d'avoir un SPN, soit on créé un "compte de service" et on lui associe le SPN, c'est donc les droits du compte de service qui sont appliqués.
Soit comme dans mon exemple, c'est le compte de la machine qui porte le SPN plutôt qu'un compte additionnel.
On peut voir ça en utilisant l'outils Utilisateurs et ordinateurs activeDirectory, en allant sur l'entrée correspondant à la machine, puis l'onglet Éditeur d'attributs, là on trouve une entrée servicePrincipalName:

Dans le cas d'un compte de service, on aura la même chose mais sur l'entrée du compte de service plutôt que sur celle du host.
La différence entre les deux modes, c'est que quand le SPN est associé à l'host, le serveur va se "logguer" (récupérer un TGT) avec le SPN djinn65$@HARDENING2.COM.
On peut simuler ça en faisant:
$ kinit -kt djinn65-termsrv.keytab 'djinn65$@HARDENING2.COM'
Si on utilisait plutôt un compte de service, ce serait plutôt (msktutil permet aussi de gérer les comptes de service):
$ kinit -kt djinn65-termsrv.keytab TERMSRV/djinn65@HARDENING2.COM
Conclusion
Après tout ça la kerberossisation n'a plus de secrets pour vous, à vous les proxys ou les shadow servers en NLA+Kerberos !