2. Éléments du modèle
Cette section contient les définitions requises pour réaliser le modèle de sécurité défini par ce mémo.
2.1. Utilisateurs du modèle de sécurité basé sur l'utilisateur
Les opérations de gestion utilisant ce modèle de sécurité utilisent un ensemble défini d'identités d'utilisateur. Pour tout utilisateur au nom duquel des opérations de gestion sont autorisées sur un moteur SNMP particulier, ce moteur SNMP doit avoir connaissance de cet utilisateur. Un moteur SNMP qui souhaite communiquer avec un autre moteur SNMP doit également avoir connaissance d'un utilisateur connu de ce moteur, y compris la connaissance des attributs applicables de cet utilisateur.
Un utilisateur et ses attributs sont définis comme suit :
-
userName Une chaîne représentant le nom de l'utilisateur.
-
securityName Une chaîne lisible par l'homme représentant l'utilisateur dans un format indépendant du modèle de sécurité. Il existe une relation un-à-un entre userName et securityName.
-
authProtocol Une indication si les messages envoyés au nom de cet utilisateur peuvent être authentifiés, et si oui, le type de protocole d'authentification utilisé. Deux de ces protocoles sont définis dans ce mémo :
- le protocole d'authentification HMAC-MD5-96.
- le protocole d'authentification HMAC-SHA-96.
-
authKey Si les messages envoyés au nom de cet utilisateur peuvent être authentifiés, la clé d'authentification (privée) à utiliser avec le protocole d'authentification. Notez que la clé d'authentification d'un utilisateur sera normalement différente sur différents moteurs SNMP autoritatifs. L'authKey n'est pas accessible via SNMP. Les exigences de longueur de l'authKey sont définies par l'authProtocol en cours d'utilisation.
-
authKeyChange et authOwnKeyChange Le seul moyen de mettre à jour à distance la clé d'authentification. Cela se fait de manière sécurisée, de sorte que la mise à jour puisse être effectuée sans avoir besoin d'employer une protection de confidentialité.
-
privProtocol Une indication si les messages envoyés au nom de cet utilisateur peuvent être protégés contre la divulgation, et si oui, le type de protocole de confidentialité utilisé. Un tel protocole est défini dans ce mémo : le protocole de chiffrement symétrique CBC-DES.
-
privKey Si les messages envoyés au nom de cet utilisateur peuvent être chiffrés/déchiffrés, la clé de confidentialité (privée) à utiliser avec le protocole de confidentialité. Notez que la clé de confidentialité d'un utilisateur sera normalement différente sur différents moteurs SNMP autoritatifs. La privKey n'est pas accessible via SNMP. Les exigences de longueur de la privKey sont définies par le privProtocol en cours d'utilisation.
-
privKeyChange et privOwnKeyChange Le seul moyen de mettre à jour à distance la clé de chiffrement. Cela se fait de manière sécurisée, de sorte que la mise à jour puisse être effectuée sans avoir besoin d'employer une protection de confidentialité.
2.2. Protection contre le rejeu
Chaque moteur SNMP maintient trois objets :
-
snmpEngineID, qui (au moins au sein d'un domaine administratif) identifie de manière unique et non ambiguë un moteur SNMP.
-
snmpEngineBoots, qui est un compteur du nombre de fois que le moteur SNMP a redémarré/réinitialisé depuis la dernière configuration de snmpEngineID ; et,
-
snmpEngineTime, qui est le nombre de secondes depuis la dernière incrémentation du compteur snmpEngineBoots.
Chaque moteur SNMP est toujours autoritatif en ce qui concerne ces objets dans sa propre entité SNMP. Il incombe à un moteur SNMP non autoritatif de se synchroniser avec le moteur SNMP autoritatif, selon le cas.
Un moteur SNMP autoritatif est tenu de maintenir les valeurs de son snmpEngineID et snmpEngineBoots dans un stockage non volatile.
2.2.1. msgAuthoritativeEngineID
La valeur msgAuthoritativeEngineID contenue dans un message authentifié est utilisée pour contrer les attaques dans lesquelles des messages d'un moteur SNMP à un autre moteur SNMP sont rejoués vers un moteur SNMP différent. Elle représente le snmpEngineID du moteur SNMP autoritatif impliqué dans l'échange du message.
Lorsqu'un moteur SNMP autoritatif est installé pour la première fois, il définit sa valeur locale de snmpEngineID selon un algorithme spécifique à l'entreprise (voir la définition de la convention textuelle pour SnmpEngineID dans le document Architecture SNMP [RFC3411]).
2.2.2. msgAuthoritativeEngineBoots et msgAuthoritativeEngineTime
Les valeurs msgAuthoritativeEngineBoots et msgAuthoritativeEngineTime contenues dans un message authentifié sont utilisées pour contrer les attaques dans lesquelles les messages sont rejoués alors qu'ils ne sont plus valides. Elles représentent les valeurs snmpEngineBoots et snmpEngineTime du moteur SNMP autoritatif impliqué dans l'échange du message.
Grâce à l'utilisation de snmpEngineBoots et snmpEngineTime, il n'y a aucune exigence pour qu'un moteur SNMP ait une horloge non volatile qui tourne (c'est-à-dire, augmente avec le passage du temps) même lorsque le moteur SNMP est éteint. Au contraire, chaque fois qu'un moteur SNMP redémarre, il récupère, incrémente puis stocke snmpEngineBoots dans un stockage non volatile, et remet snmpEngineTime à zéro.
Lorsqu'un moteur SNMP est installé pour la première fois, il définit ses valeurs locales de snmpEngineBoots et snmpEngineTime à zéro. Si snmpEngineTime atteint sa valeur maximale (2147483647), alors snmpEngineBoots est incrémenté comme si le moteur SNMP avait redémarré et snmpEngineTime est remis à zéro et recommence à s'incrémenter.
Chaque fois qu'un moteur SNMP autoritatif redémarre, tous les moteurs SNMP détenant les valeurs snmpEngineBoots et snmpEngineTime de ce moteur SNMP autoritatif doivent se resynchroniser avant d'envoyer des messages correctement authentifiés à ce moteur SNMP autoritatif (voir la section 2.3 pour les procédures de (re-)synchronisation). Notez cependant que les procédures prévoient qu'une notification soit acceptée comme authentique par un moteur SNMP récepteur, lorsqu'elle est envoyée par un moteur SNMP autoritatif qui a redémarré depuis la dernière (re-)synchronisation du moteur SNMP récepteur.
Si un moteur SNMP autoritatif n'est jamais en mesure de déterminer sa dernière valeur snmpEngineBoots, alors il doit définir sa valeur snmpEngineBoots à 2147483647.
Chaque fois que la valeur locale de snmpEngineBoots a la valeur 2147483647, elle se verrouille à cette valeur et un message authentifié provoque toujours un échec d'authentification notInTimeWindow.
Pour réinitialiser un moteur SNMP dont la valeur snmpEngineBoots a atteint la valeur 2147483647, une intervention manuelle est requise. Le moteur doit être physiquement visité et reconfiguré, soit avec une nouvelle valeur snmpEngineID, soit avec de nouvelles valeurs secrètes pour les protocoles d'authentification et de confidentialité de tous les utilisateurs connus de ce moteur SNMP. Notez que même si un moteur SNMP redémarre une fois par seconde, il faudrait encore environ 68 ans avant que la valeur maximale de 2147483647 ne soit atteinte.
2.2.3. Fenêtre temporelle
La fenêtre temporelle est une valeur qui spécifie la fenêtre de temps pendant laquelle un message généré au nom de n'importe quel utilisateur est valide. Ce mémo spécifie que la même valeur de la fenêtre temporelle, 150 secondes, est utilisée pour tous les utilisateurs.
2.3. Synchronisation temporelle
La synchronisation temporelle, requise par un moteur SNMP non autoritatif afin de procéder à des communications authentiques, s'est produite lorsque le moteur SNMP non autoritatif a obtenu une notion locale des valeurs snmpEngineBoots et snmpEngineTime du moteur SNMP autoritatif auprès du moteur SNMP autoritatif. Ces valeurs doivent être (et rester) dans la fenêtre temporelle du moteur SNMP autoritatif. Ainsi, la notion locale des valeurs du moteur SNMP autoritatif doit être maintenue approximativement synchronisée avec les valeurs stockées sur le moteur SNMP autoritatif. En plus de conserver une copie locale de snmpEngineBoots et snmpEngineTime du moteur SNMP autoritatif, un moteur SNMP non autoritatif doit également conserver une variable locale, latestReceivedEngineTime. Cette valeur enregistre la valeur la plus élevée de snmpEngineTime qui a été reçue par le moteur SNMP non autoritatif du moteur SNMP autoritatif et est utilisée pour éliminer la possibilité de rejouer des messages qui empêcheraient la notion du moteur SNMP non autoritatif du snmpEngineTime d'avancer.
Un moteur SNMP non autoritatif doit conserver des notions locales de ces valeurs (snmpEngineBoots, snmpEngineTime et latestReceivedEngineTime) pour chaque moteur SNMP autoritatif avec lequel il souhaite communiquer. Étant donné que chaque moteur SNMP autoritatif est identifié de manière unique et non ambiguë par sa valeur snmpEngineID, le moteur SNMP non autoritatif peut utiliser cette valeur comme clé afin de mettre en cache ses notions locales de ces valeurs.
La synchronisation temporelle se produit dans le cadre des procédures de réception d'un message SNMP (section 3.2, étape 7b). En tant que telle, aucune procédure explicite de synchronisation temporelle n'est requise par un moteur SNMP non autoritatif. Notez que chaque fois que la valeur locale de snmpEngineID est modifiée (par exemple, par découverte) ou lorsque des communications sécurisées sont établies pour la première fois avec un moteur SNMP autoritatif, les valeurs locales de snmpEngineBoots et latestReceivedEngineTime doivent être définies à zéro. Cela entraînera la synchronisation temporelle lors de la réception du prochain message authentique.
2.4. Messages SNMP utilisant ce modèle de sécurité
La syntaxe d'un message SNMP utilisant ce modèle de sécurité adhère au format de message défini dans le document de modèle de traitement de message spécifique à la version (par exemple [RFC3412]).
Le champ msgSecurityParameters dans les messages SNMPv3 a un type de données OCTET STRING. Sa valeur est la sérialisation BER de la séquence ASN.1 suivante :
USMSecurityParametersSyntax DEFINITIONS IMPLICIT TAGS ::= BEGIN
UsmSecurityParameters ::=
SEQUENCE {
-- global User-based security parameters
msgAuthoritativeEngineID OCTET STRING,
msgAuthoritativeEngineBoots INTEGER (0..2147483647),
msgAuthoritativeEngineTime INTEGER (0..2147483647),
msgUserName OCTET STRING (SIZE(0..32)),
-- authentication protocol specific parameters
msgAuthenticationParameters OCTET STRING,
-- privacy protocol specific parameters
msgPrivacyParameters OCTET STRING
}
END
Les champs de cette séquence sont :
-
Le msgAuthoritativeEngineID spécifie le snmpEngineID du moteur SNMP autoritatif impliqué dans l'échange du message.
-
Le msgAuthoritativeEngineBoots spécifie la valeur snmpEngineBoots du moteur SNMP autoritatif impliqué dans l'échange du message.
-
Le msgAuthoritativeEngineTime spécifie la valeur snmpEngineTime du moteur SNMP autoritatif impliqué dans l'échange du message.
-
Le msgUserName spécifie l'utilisateur (principal) au nom duquel le message est échangé. Notez qu'un userName de longueur nulle ne correspondra à aucun utilisateur, mais il peut être utilisé pour la découverte de snmpEngineID.
-
Les msgAuthenticationParameters sont définis par le protocole d'authentification utilisé pour le message, tel que défini par la colonne usmUserAuthProtocol dans l'entrée de l'utilisateur dans la usmUserTable.
-
Les msgPrivacyParameters sont définis par le protocole de confidentialité utilisé pour le message, tel que défini par la colonne usmUserPrivProtocol dans l'entrée de l'utilisateur dans la usmUserTable).
Voir l'annexe A.4 pour un exemple de codage BER du champ msgSecurityParameters.
2.5. Services fournis par le modèle de sécurité basé sur l'utilisateur
Cette section décrit les services fournis par le modèle de sécurité basé sur l'utilisateur avec leurs entrées et sorties.
Les services sont décrits comme des primitives d'une interface de service abstraite et les entrées et sorties sont décrites comme des éléments de données abstraits tels qu'ils sont transmis dans ces primitives de service abstraites.
2.5.1. Services pour générer un message SNMP sortant
Lorsque le sous-système de traitement des messages (MP) invoque le module de sécurité basé sur l'utilisateur pour sécuriser un message SNMP sortant, il doit utiliser le service approprié fourni par le module de sécurité. Ces deux services sont fournis :
- Un service pour générer un message de requête. La primitive de service abstraite est :
statusInformation = -- success or errorIndication
generateRequestMsg(
IN messageProcessingModel -- typically, SNMP version
IN globalData -- message header, admin data
IN maxMessageSize -- of the sending SNMP entity
IN securityModel -- for the outgoing message
IN securityEngineID -- authoritative SNMP entity
IN securityName -- on behalf of this principal
IN securityLevel -- Level of Security requested
IN scopedPDU -- message (plaintext) payload
OUT securityParameters -- filled in by Security Module
OUT wholeMsg -- complete generated message
OUT wholeMsgLength -- length of generated message
)
- Un service pour générer un message de réponse. La primitive de service abstraite est :
statusInformation = -- success or errorIndication
generateResponseMsg(
IN messageProcessingModel -- typically, SNMP version
IN globalData -- message header, admin data
IN maxMessageSize -- of the sending SNMP entity
IN securityModel -- for the outgoing message
IN securityEngineID -- authoritative SNMP entity
IN securityName -- on behalf of this principal
IN securityLevel -- Level of Security requested
IN scopedPDU -- message (plaintext) payload
IN securityStateReference -- reference to security state
-- information from original
-- request
OUT securityParameters -- filled in by Security Module
OUT wholeMsg -- complete generated message
OUT wholeMsgLength -- length of generated message
)
Les éléments de données abstraits transmis en tant que paramètres dans les primitives de service abstraites sont les suivants :
-
statusInformation Une indication si l'encodage et la sécurisation du message ont réussi. Sinon, c'est une indication du problème.
-
messageProcessingModel Le numéro de version SNMP pour le message à générer. Ces données ne sont pas utilisées par le module de sécurité basé sur l'utilisateur.
-
globalData L'en-tête du message (c'est-à-dire ses informations administratives). Ces données ne sont pas utilisées par le module de sécurité basé sur l'utilisateur.
-
maxMessageSize La taille maximale du message telle qu'incluse dans le message. Ces données ne sont pas utilisées par le module de sécurité basé sur l'utilisateur.
-
securityParameters Ce sont les paramètres de sécurité. Ils seront remplis par le module de sécurité basé sur l'utilisateur.
-
securityModel Le modèle de sécurité utilisé. Devrait être le modèle de sécurité basé sur l'utilisateur. Ces données ne sont pas utilisées par le module de sécurité basé sur l'utilisateur.
-
securityName Avec le snmpEngineID, il identifie une ligne dans la usmUserTable qui doit être utilisée pour sécuriser le message. Le securityName a un format indépendant du modèle de sécurité. Dans le cas d'une réponse, ce paramètre est ignoré et la valeur du cache est utilisée.
-
securityLevel Le niveau de sécurité à partir duquel le module de sécurité basé sur l'utilisateur détermine si le message doit être protégé contre la divulgation et si le message doit être authentifié.
-
securityEngineID Le snmpEngineID du moteur SNMP autoritatif auquel un message de requête de données doit être envoyé. Dans le cas d'une réponse, il est implicite d'être le snmpEngineID du moteur SNMP de traitement et donc s'il est spécifié, il est ignoré.
-
scopedPDU La charge utile du message. Les données sont opaques pour le modèle de sécurité basé sur l'utilisateur.
-
securityStateReference Un handle/référence aux cachedSecurityData à utiliser lors de la sécurisation d'un message de réponse sortant. C'est exactement le même handle/référence tel qu'il a été généré par le module de sécurité basé sur l'utilisateur lors du traitement du message de requête entrant auquel il s'agit du message de réponse.
-
wholeMsg Le message entièrement encodé et sécurisé prêt à être envoyé sur le fil.
-
wholeMsgLength La longueur du message encodé et sécurisé (wholeMsg).
À la fin du processus, le module de sécurité basé sur l'utilisateur renvoie statusInformation. Si le processus a réussi, le message complet avec confidentialité et authentification appliquées si cela a été demandé par le securityLevel spécifié est renvoyé. Si le processus n'a pas réussi, alors une errorIndication est renvoyée.
2.5.2. Services pour traiter un message SNMP entrant
Lorsque le sous-système de traitement des messages (MP) invoque le module de sécurité basé sur l'utilisateur pour vérifier la sécurité appropriée d'un message entrant, il doit utiliser le service fourni pour un message entrant. La primitive de service abstraite est :
statusInformation = -- errorIndication or success
-- error counter OID/value if error
processIncomingMsg(
IN messageProcessingModel -- typically, SNMP version
IN maxMessageSize -- of the sending SNMP entity
IN securityParameters -- for the received message
IN securityModel -- for the received message
IN securityLevel -- Level of Security
IN wholeMsg -- as received on the wire
IN wholeMsgLength -- length as received on the wire
OUT securityEngineID -- authoritative SNMP entity
OUT securityName -- identification of the principal
OUT scopedPDU, -- message (plaintext) payload
OUT maxSizeResponseScopedPDU -- maximum size of the Response PDU
OUT securityStateReference -- reference to security state
) -- information, needed for response
Les éléments de données abstraits transmis en tant que paramètres dans les primitives de service abstraites sont les suivants :
-
statusInformation Une indication si le processus a réussi ou non. Sinon, les statusInformation incluent l'OID et la valeur du compteur d'erreurs qui a été incrémenté.
-
messageProcessingModel Le numéro de version SNMP tel que reçu dans le message. Ces données ne sont pas utilisées par le module de sécurité basé sur l'utilisateur.
-
maxMessageSize La taille maximale du message telle qu'incluse dans le message. Le module de sécurité basé sur l'utilisateur utilise cette valeur pour calculer le maxSizeResponseScopedPDU.
-
securityParameters Ce sont les paramètres de sécurité tels que reçus dans le message.
-
securityModel Le modèle de sécurité utilisé. Devrait être le modèle de sécurité basé sur l'utilisateur. Ces données ne sont pas utilisées par le module de sécurité basé sur l'utilisateur.
-
securityLevel Le niveau de sécurité à partir duquel le module de sécurité basé sur l'utilisateur détermine si le message doit être protégé contre la divulgation et si le message doit être authentifié.
-
wholeMsg Le message complet tel qu'il a été reçu.
-
wholeMsgLength La longueur du message tel qu'il a été reçu (wholeMsg).
-
securityEngineID Le snmpEngineID qui a été extrait du champ msgAuthoritativeEngineID et qui a été utilisé pour rechercher les secrets dans la usmUserTable.
-
securityName Le nom de sécurité représentant l'utilisateur au nom duquel le message a été reçu. Le securityName a un format indépendant du modèle de sécurité.
-
scopedPDU La charge utile du message. Les données sont opaques pour le modèle de sécurité basé sur l'utilisateur.
-
maxSizeResponseScopedPDU La taille maximale d'un scopedPDU à inclure dans un éventuel message de réponse. Le module de sécurité basé sur l'utilisateur calcule cette taille en fonction du msgMaxSize (tel que reçu dans le message) et de l'espace requis pour l'en-tête du message (y compris les securityParameters) pour un tel message de réponse.
-
securityStateReference Un handle/référence aux cachedSecurityData à utiliser lors de la sécurisation d'un message de réponse sortant. Lorsque le sous-système de traitement des messages appelle le module de sécurité basé sur l'utilisateur pour générer une réponse à ce message entrant, il doit transmettre ce handle/référence.
À la fin du processus, le module de sécurité basé sur l'utilisateur renvoie statusInformation et, si le processus a réussi, les éléments de données supplémentaires pour un traitement ultérieur du message. Si le processus n'a pas réussi, alors une errorIndication, éventuellement avec une paire OID et valeur d'un compteur d'erreurs qui a été incrémenté.
2.6. Algorithme de localisation de clé
Une clé localisée est une clé secrète partagée entre un utilisateur U et un moteur SNMP autoritatif E. Même si un utilisateur peut n'avoir qu'un seul mot de passe et donc une seule clé pour l'ensemble du réseau, les secrets réels partagés entre l'utilisateur et chaque moteur SNMP autoritatif seront différents. Ceci est réalisé par la localisation de clé [Localized-key].
Tout d'abord, si un utilisateur utilise un mot de passe, alors le mot de passe de l'utilisateur est converti en une clé Ku en utilisant l'un des deux algorithmes décrits dans les annexes A.2.1 et A.2.2.
Pour convertir la clé Ku en une clé localisée Kul de l'utilisateur U au moteur SNMP autoritatif E, on ajoute le snmpEngineID du moteur SNMP autoritatif à la clé Ku puis on ajoute la clé Ku au résultat, enveloppant ainsi le snmpEngineID dans les deux copies de la clé Ku de l'utilisateur. Ensuite, on exécute une fonction de hachage sécurisée (laquelle dépend du protocole d'authentification défini pour cet utilisateur U au moteur SNMP autoritatif E ; ce document définit deux protocoles d'authentification avec leurs algorithmes associés basés sur MD5 et SHA). La sortie de la fonction de hachage est la clé localisée Kul pour l'utilisateur U au moteur SNMP autoritatif E.