- Blog Xebia France - http://blog.xebia.fr -
Java en Production – L’audit
Posted By Cyrille Le Clerc On Mercredi 25 août 2010 @ 12:40 In Exploitation,Java / JEE | 16 Comments
Après avoir abordé la gestion des fichiers de logs, nous continuons aujourd’hui la série « Applications Java prêtes pour la Production » avec l’audit.
Par audit, nous entendons l’audit des actions importantes réalisées sur une application.
Est-il vraiment utile de générer des informations d’audit dans nos applications ? Sans explications de juriste, quelques exemples suffiront à nous en convaincre :
Pour revenir à des explications plus théoriques, les logs d’audit nous apportent :
Nous nous placerons dans le cas le plus fréquent où nous ne développons pas d’outil pour consulter ces informations d’audit et où un accès direct au média de stockage (grep sur fichier texte, sql sur base de données, etc) suffit.
Dans un monde idéal, le contenu des messages serait défini avec les équipes de sécurité. En pratique, nous sommes assez seuls pour les choisir et il ne faut pas dramatiser. Si l’on ne prend pas le sujet à la légère, après quelques itérations, notre bon sens est le plus souvent suffisant.
Les éléments clefs à tracer sont :
id ou le toString() des paramètres d’appel.La première idée serait de se contenter des logs d’accès des serveurs web et des firewalls pour auditer les accès à nos applications ; nous n’aurions alors plus rien à faire.
Hélas, cela n’est pas suffisant car il manque dans les logs http des informations clefs :
Dans un monde idéal, le framework d’audit ne devrait pas dépendre de la configuration des logs pour ne pas risquer qu’une mauvaise manipulation de ces configurations de logs ne le désactive.
En pratique, les frameworks de logs sont les briques les plus performantes et les plus matures pour traiter les besoins d’écriture d’audit et la probabilité de désactiver l’audit en faisant une mauvaise manipulation sur la configuration des logs est négligeable. Ces raisons nous amènent à utiliser SLF4J avec logback ou log4j pour gérer l’audit.
Nous encapsulerons tout de même le logger avec une couche légère packagée dans la librairie Xebia Spring Security Extras qui ajoutera au message l’identité de l’internaute et son adresse IP (via Spring Security). Cette librairie offre une gestion déclarative de l’audit avec une annotation @Audited, son aspect associé AuditAspect et une classe utilitaire Auditor. Nous ne rentrerons pas dans le débat annotations vs. code ; dans la majeure partie des projets, nous avons pu traiter la plupart de l’audit avec une annotation et seuls quelques cas ont nécessité de passer par du code.
Exemple de gestion de l’audit avec l’annotation @Audited :
@Audited(message = "transferMoney(#{args[0].accountNumber}, #{args[1].accountNumber}, #{args[3]})")
public void transferMoney(Account from, Account to, Amount amount) throws BusinessException { ... }
L’attribut message est un pattern supportant Spring Expression Language définissant l’entrée insérée dans le fichier d’audit ; la date, le nom de l’utilisateur, l’adresse ip et l’exception s’il y en a une sont ajoutés au message.
Fragment de configuration Spring Framework pour utiliser l’annotation @Audited :
<beans ...
xmlns:security-extras="http://www.xebia.fr/schema/xebia-spring-security-extras"
xsi:schemaLocation="...
http://www.xebia.fr/schema/xebia-spring-security-extras http://www.xebia.fr/schema/security/xebia-spring-security-extras.xsd">
<!-- enable Spring AOP -->
<aop:aspectj-autoproxy/>
<!-- activate the AutitAspect -->
<security-extras:audit-aspect />
...
</beans>
Message d’audit généré :
... transferMoney(000652584515, 0000684651684, 187.53) by bdupont coming from 192.168.0.14 ... transferMoney(000652584515, 0000684651684, 666666.00) threw '...BusinessException: debit amount greater than account balance' by bdupont coming from 192.168.0.14
Exemple de gestion de l’audit avec l’utilitaire Auditor :
public void transferMoney(...) throws BusinessException {
...
Auditor.audit("Tranfer '" + amount + "' from " + fromAccount + " to " + toAccount);
}
Message d’audit généré :
... Transfer '187.53 euros' from Account[000652584515] to Account[0000684651684] by bdupont coming from 192.168.0.14
L’entrée d’audit est ajoutée dans un fichier d’audit géré par le logger spécifique "fr.xebia.audit" (voir cet article pour la configuration du logger).
Tous les détails sur l’annotation @Audited sont sur @Audited Annotation.
Ce framework peut être intégré de différentes façons dans une application :
<project ...>
<dependencies>
<dependency>
<groupId>fr.xebia.springframework</groupId>
<artifactId>xebia-spring-security-extras</artifactId>
<version>1.1.6</version>
</dependency>
...
</dependencies>
...
</project>
Cet artifact est déployé sur le Maven Central Repository.
Le stockage des entrées d’audit en base de données permet sûrement une recherche plus fine des données que sur des fichiers mais cela ajoute de la complexité (déploiement, exploitation, backup) ainsi que des risques de pannes et impacte les performances. Les approches JMS présentent des contraintes similaires et l’utilisation de systèmes de logs distants comme rsyslog présentent un défi de fiabilité. Ces difficultés sont accentuées lorsqu’une application génère de gros volumes de logs (plusieurs Go/jour).
Pour ces raisons, nous préférons stocker les messages d’audit dans un simple fichier. Les risques de saturation du système de fichiers sont assez facilement gérables par les équipes d’exploitation, les procédures d’archivage et de consultation très simples (gzip, scp, grep, etc) et il n’y a quasiment jamais de problème de performance, même avec des fichiers de quelques Go par jour.
Y-a-t-il un plus grand risque de perdre les données par de mauvaises manipulations ? Si une application est critique, les exploitants doivent déjà ne pas perdre les fichiers de log du système d’exploitation, des serveurs web et autres firewalls.
Pour la gestion des messages d’audit sous forme de fichier texte, nous aimons logback comme nous l’avons expliqué dans Java en Production – Les fichiers de logs mais il est aussi possible d’utiliser Log4j.
Exemple de configuration Logback pour gérer les messages d’audit émis sur le logger fr.xebia.audit :
<appender name="audit-file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS_FOLDER}/my-application-audit.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rotate every day -->
<fileNamePattern>/my-application-audit.%d{yyyyMMdd-HHmm}.log.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<!-- don't output the date or the logger name because the auditing framework handles this -->
<pattern>%m %throwable{0}%n</pattern>
</encoder>
</appender>
<!-- route the 'fr.xebia.audit' log messages to the audit-file -->
<logger name="fr.xebia.audit" additivity="false" level="TRACE">
<appender-ref ref="audit-file" />
</logger>
Exemple équivalent avec log4j (le EnhancedPatternLayout requiert log4j 1.2.16) :
log4j.appender.auditfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.auditfile.datePattern='-'yyyyMMdd
log4j.appender.auditfile.file=${catalina.base}/logs/my-application-audit.log
log4j.appender.auditfile.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.auditfile.layout.conversionPattern=%m %throwable{short}n
log4j.logger.fr.xebia.audit=INFO, auditfile
Nous ne rentrerons pas plus dans les détails de la gestion des logs d’audit après leur génération par nos applications.
Ce sujet complexe présente aussi bien des aspects juridiques que de confidentialité ou encore de fiabilité. Schématiquement, on n’a pas le droit de garder indéfiniment des données personnelles, il faut restreindre leur consultation et empêcher leur modification et leur destruction par accident comme par malveillance.
Des professionnels de l’exploitation et de la sécurité sont beaucoup plus compétents que nous sur ce sujet
.
Si le traitement de l’audit dans les applications vous a intéressé, nous avons aimé lire :
Nous avons vu aujourd’hui une façon simple de gérer l’audit d’applications java en reposant sur le framework de log de l’application (Logback voire Log4j) pour écrire les messages dans de simples fichiers texte avec une surcouche très légère composée d’une annotation @Audited et d’un utilitaire Auditor.
Historique
25/11/2010 : passage à la version 1.1.5 de la librarie xebia-spring-security-extras avec utilisation du namespace de configuration.
20/12/2011 : xebia-spring-security-extras : passage à la version 1.1.6 et aux URLs GitHub
Article printed from Blog Xebia France: http://blog.xebia.fr
URL to article: http://blog.xebia.fr/2010/08/25/java-en-production-laudit/
Click here to print.