Accès à l’API interne¶
Présentation¶
Certaines opérations d’administration de la plateforme (par exemple la
réinitialisation de l’OTP d’un utilisateur) sont exposées par l’API sous le
préfixe /api/internal. Ces endpoints sont privilégiés : ils sont
destinés à être appelés par des systèmes d’automatisation de confiance
(scripts d’exploitation, orchestrateurs, outils internes), et non par les
navigateurs ou les clients finals qui utilisent le portail.
Le besoin couvert par cette fonctionnalité est donc le suivant : donner accès à
/api/internal sans l’exposer sur la surface publique habituelle (le
portail ou le host API standard), et en protégeant cet accès par une
authentification renforcée et indépendante de celle des utilisateurs normaux.
Pour cela, /api/internal est publié sur un nom d’hôte dédié
(API_INTERNAL_URL), distinct du portail et du host API standard, et peut
être protégé par trois couches complémentaires :
une liste d’IP autorisées (filtrage réseau) ;
un mTLS dédié (authentification mutuelle TLS avec sa propre PKI, séparée de la PKI interne classique) ;
une clé HMAC applicative, vérifiée par l’API elle-même.
Aucune de ces couches n’est obligatoire individuellement, mais elles se cumulent : on peut par exemple n’activer que le filtrage IP, ou ajouter le mTLS pour une authentification forte au niveau du transport.
Principe de fonctionnement¶
Lorsque la fonctionnalité est activée, une route Traefik dédiée est créée :
Host(`API_INTERNAL_URL`) && PathPrefix(`/api/internal`)
Cette route est posée :
sur le service portal lorsque le déploiement est de type
infra_manager(le portail relaie déjà/api/*vers l’API) ;sur le service api lorsque le déploiement sépare les rôles (
api_manager+portal_manager) ; la route est alors ouverte uniquement côtéapi_manager.
Le nom d’hôte API_INTERNAL_URL sert de point d’entrée isolé : c’est lui qui
porte l’authentification mTLS dédiée. Cette isolation par nom d’hôte est
nécessaire car le choix de la PKI cliente se fait au moment de la négociation
TLS (sur la base du nom d’hôte), avant que le chemin /api/internal ne soit
connu. Il n’est donc pas possible de réserver une PKI différente à un simple
chemin sur un hôte déjà utilisé.
Variables de configuration¶
API_INTERNAL_ENABLEDActive la fonctionnalité. Valeur booléenne (
true/false). Par défaut :false.API_INTERNAL_URLNom d’hôte dédié sur lequel
/api/internalest publié (par exempleapiinternal.example.com). Obligatoire dès lors que la route doit être ouverte. Doit être différent du nom d’hôte du portail (PORTAL_URL) et du host API standard reemo_api.API_INTERNAL_RESTRICT_IPListe d’adresses ou de plages IP autorisées à atteindre
/api/internal, au format CIDR séparé par des virgules (par exemple"10.0.0.0/8,192.168.10.20/32"). Une requête provenant d’une IP non listée reçoit un403. Laisser vide pour ne pas filtrer.API_INTERNAL_SSL_CERTChemin vers le certificat serveur que Traefik présente sur le nom d’hôte
API_INTERNAL_URL. Son SAN doit contenirAPI_INTERNAL_URL.API_INTERNAL_SSL_KEYChemin vers la clé privée associée au certificat serveur ci-dessus.
API_INTERNAL_SSL_CAChemin vers la CA utilisée pour valider le certificat client présenté par l’appelant (mTLS). C’est cette variable qui active réellement le mTLS dédié : si elle est renseignée, seuls les clients présentant un certificat signé par cette CA sont acceptés.
Note
Les trois variables API_INTERNAL_SSL_* sont optionnelles. Si elles ne
sont pas renseignées, la route reste ouverte mais sans la PKI dédiée. Pour
obtenir un mTLS avec une PKI séparée de la PKI interne classique, il
faut renseigner au minimum API_INTERNAL_SSL_CA (et fournir un
certificat serveur valide pour le nom d’hôte, voir
Certificats requis).
API_INTERNAL_HMACClé HMAC partagée, vérifiée par l’API au niveau applicatif sur les appels
/api/internal. Stockée comme secret. Cette couche est indépendante du mTLS : un appelant doit présenter le bon HMAC en plus de satisfaire les contrôles de transport.
Comportement selon la topologie¶
Déploiement mono-site (infra_manager)¶
La route /api/internal est ouverte sur le portail, sur le nom d’hôte
API_INTERNAL_URL. Le portail relaie ensuite la requête vers l’API.
Dans ce mode, PORTAL_URL doit être renseigné avec un nom d’hôte exact.
Si le portail est configuré en mode « wildcard » (sans PORTAL_URL), la
route dédiée n’est pas créée, car le routeur wildcard entrerait en conflit
avec l’authentification mTLS du nom d’hôte dédié.
Déploiement scindé (api_manager + portal_manager)¶
La route /api/internal est ouverte uniquement sur api_manager,
directement sur le service API. Le portal_manager n’ouvre pas la route.
Note
Sur api_manager, le host API standard impose déjà un mTLS avec la PKI
interne classique. La route dédiée API_INTERNAL_URL ajoute, sur son
propre nom d’hôte, un mTLS avec la PKI dédiée (API_INTERNAL_SSL_CA),
ce qui permet d’avoir deux PKI distinctes : l’une pour le trafic API
habituel, l’autre pour l’API interne.
Fermeture de l’accès par le canal public¶
Pour garantir que /api/internal ne soit joignable que par le nom
d’hôte dédié, l’accès au chemin /api/internal est refusé (403) sur le
nom d’hôte public (portail, ou host API standard selon la topologie).
Warning
Si un composant légitime appelle /api/internal par le host public (et
non par API_INTERNAL_URL ni en direct sur le conteneur), cette fermeture
le bloquera. Vérifiez le chemin emprunté par vos appelants avant d’activer
ce comportement.
Certificats requis¶
Deux éléments distincts interviennent dans le mTLS :
- Le certificat serveur (
API_INTERNAL_SSL_CERT/API_INTERNAL_SSL_KEY) C’est ce que Traefik présente au client. Son SAN doit contenir
API_INTERNAL_URL, et il doit être émis par une autorité que l’appelant fait confiance (le--cacertcôté client). Si aucun certificat correspondant au nom d’hôte n’est fourni, Traefik présente un certificat auto-signé, et le client ne pourra valider la connexion qu’en désactivant la vérification (à éviter).- La CA de validation client (
API_INTERNAL_SSL_CA) C’est l’autorité qui doit avoir signé le certificat client présenté par l’appelant. Un certificat client signé par une autre autorité (par exemple la PKI interne classique) sera rejeté sur ce nom d’hôte.
Exemple de configuration¶
api_manager:
vars:
API_INTERNAL_ENABLED: true
API_INTERNAL_URL: "apiinternal.example.com"
API_INTERNAL_RESTRICT_IP: "10.0.0.0/8,192.168.10.20/32"
API_INTERNAL_SSL_CERT: "/chemin/local/apiinternal.crt"
API_INTERNAL_SSL_KEY: "/chemin/local/apiinternal.key"
API_INTERNAL_SSL_CA: "/chemin/local/apiinternal_ca.crt"
API_INTERNAL_HMAC: "<clé HMAC partagée>"
Vérification¶
Une fois le déploiement effectué, un appel authentifié doit aboutir à l’API sans avoir à désactiver la vérification TLS :
curl -v \
--cacert /chemin/ca.pem \
--cert /chemin/client.crt \
--key /chemin/client.key \
https://apiinternal.example.com/api/internal/users/reset-otp
Points de contrôle pendant le handshake :
Request CERTcôté serveur : le serveur réclame bien le certificat client (mTLS actif) ;le certificat serveur présenté correspond à
API_INTERNAL_URLet est validé par votre--cacert(pas de messageself-signed certificate) ;la connexion aboutit ; un code applicatif (par exemple
401si le HMAC est absent ou invalide) confirme que la requête a bien atteint l’API.
Note
Un 401 Unauthorized provient de l’API (contrôle HMAC applicatif) et
non de Traefik : il indique que le transport (routage, mTLS, filtrage IP)
a réussi et que seul l’en-tête d’authentification applicatif fait défaut.
Points d’attention¶
API_INTERNAL_URLdoit être distinct dePORTAL_URLet deAPI_DOCKER_NAME. Réutiliser un nom d’hôte existant provoque un conflit d’options TLS sur ce nom et le mTLS dédié ne s’appliquerait pas de façon fiable.Le mTLS dédié et la PKI interne classique sont indépendants : un même certificat client n’est pas valable sur les deux. Distribuez aux appelants de l’API interne un certificat signé par
API_INTERNAL_SSL_CA.Le filtrage IP, le mTLS et le HMAC sont cumulatifs. Pour un endpoint d’administration, il est recommandé de combiner au minimum le mTLS dédié et le HMAC.
En mode
infra_manager,PORTAL_URLdoit être un nom d’hôte exact pour que l’isolation par nom d’hôte fonctionne.