# Tomcat embarqué, synthèse
## Contexte & cible
### Objectif
:::info
- Les équipes de maintenance livreront un paquet contenant l'application ainsi que les **binaires du conteneur** de servlet. Les applications concernées: les applications en Java, que ce soit une IHM ou un backend.
> je trouve ça bizarrement formulé, avec une différence sur l'application et la partie serveur http alors que ca ne devrait pas etre séparé.
> "Proposition : on livre une application java sous forme de *fatjar* ecoutant du http sur un port modifiable"
> [name=Cédric Couralet]
- L'hôte nécessaire pour exécuter le service incluera **uniquement une machine virtuelle** java (Jre). Plus de serveur web.
- C'est l'ocasion de **faire évoluer le mode de livraison** et d'exploitation
- simplifier le livrable: y a t il besoin de relivivrer à chaque fois les properties dans un zip ? C'est indispensable à la première livraison ou lors d'un ajout de properties mais cela ne sert à rien en mode 'livraison courante'
- l'équipe de **maintenance à la main sur le serveur web**, celui-ci étant embarqué avec son application. Elle doit le paramétrer. Toutefois il faut veiller à ce que le paramétage soit maîtrisé
- toutes les équipes ne savent pas paramétrer un tomcat. Il faudra constituer progressivement un guide pour les développeurs.
- plus de liberté ==> besoin d'avoir du feedback sur son paramétrage. Il faut mettre en place de la **supervision** serveur et la rendre disponibles au Dev. Solution technique par défaut =
pile
- Spring boot actuator sur l'application avec activation endpoint prometheus
- `+` Prometheus Gepex
- `+` Grafana Gepex
- certains **paramètres sont plus sensibles** (exposition des endpoints, entetes http, accesslog etc.) Dans un premier temps on peut proposer une approche `Convention over configuration` et offrir un service `opiniated` qui donne une trame limitative par défaut, éventuellement surchargeable ou à rediscuter entre dev et exploitants au cas par cas.
:::
<br><br>
:::warning
## Feuille de route
:::
> **3 Lots**
> L'objectif est de produire rapidement (Lot1) une offre minimale qui permette à certaines applications de livrer en mode serveur embarqué.
1.**Elaboration d'une offre minimale: lot 1**
Constituer une offre de plateforme permettant de livrer et run une application
- spring boot embedded,
- sur solution Tomcat
L'étude, les tests, la sécurisation, la documentation, la contractualisation de l'offre se limiteront à la solution conteneur = Tomcat
Cette offre est une reprise de l'existant pour les applications qui sont actuellement sous Spring
Elle constitue le premier lot, extensible par la suite.
**Livrable**:
- un contrat d'installation de plateforme permettant de lancer une application Spring boot java à base de Tomcat. Toute version de Tomcat acceptée
- le contrat ne devra pas etre ahérent à Tomcat: il faudra sur cette première base pouvoir élargir l'offre à d'autres serveurs.
- une offre de supervision applicative plus compléte que Centreon.
**Exigences**:
- paramétrage du serveur laissé au maximum à l'équipe de maintenance
- sécurisation a minima par l'exploitation. Celle-ci ne garde la main (à discuter) que sur
- le reglage mémoire Jvm
- le trustore
- la fermeture par défaut mais modifiables des endpoints de management
- l'application n'a pas à connaître la structure du serveur. L'exploitation fournit dans son environnement de run les informations utiles au jar pour se "brancher" sur les ressources existantes (emplacement des properties, chemin des logs etc.). Dans un monde docker, cela revient à ce que le dev constitue son image, la livre et que la prod lance la commande docker avec les variables d'environnement qui concernent l'hôte (points de montage). Les variables d'environnement applicatives sont laissées à l'appréciation de l'équipe de maintenance. Quand l'institut aura la maturité suffisante il sera envisageable de mettre à disposition du développeur une VM avec Java dessus et de laisser l'équipe de maintenance prendre connaissance/maîtrise de l'hote (VM) et élaborer le contrat d'installation de son service comme il l'entend.
-
:::danger
La plupart des éléments techniques de la présente documentation portent sur le **Lot 1**.
:::
2. **Compléter l'offre avec la possibilté de lancer d'autres types de conteneurs (_ex. Jetty_)**. **Lot 2**
- Préalable: instruction technique des autres solutions (Jetty/Undertow) pour les qualifier en terme de sécurité.
Livrable:
- une évolution du contrat du Lot 1, acceptant de lancer d'autres serveurs que Tomcat
- de préférence le contrat noeud sera identique, pour Tomcat, pour Jetty ou pour toute autre implémentation de conteneur de servlets. Dans l'idéal léquipe de maintenance exprimera sa demande de conteneur embarqué et l'offre consistera à avoir une plateforme Java identique quelle que soit la solution technique (Tomcat/Jetty/Autre) envisagée
3. **Etude de la meilleure solution pour élargir l'offre à l'ensemble des applications Java**. **Lot 3**, dont il conviendra de discuter l'opportunité.
A l'étape 2, seules les applications sous Spring boot peuvent livrer facilement sur le mode conteneur embarqué.
- l'offre de service est adhérente à Spring boot
- exemple: ligne de commande spécifie
- l'emplacement des properties (spring.config.additional.location)
- le trustore
- une config minimale des endpoints de management (pour des raisons de sécurité)
- ces parametres sont dans la syntaxe Spring Boot et ne sont pas utilisables en l'état et nativement par une autre solution que Spring Boot
**Néanmoins, ces parametres ne "gènent" pas**: avec Struts + librairies Tomcat par exemple, c'est juste qu'ils ne signifient rien, mais ils n'empecheraient pas l'application de tourner.
**Donc**: **si une application en Struts veut faire tourner son livrable en mode serveur embarqué**, il faudra
- qu'elle implémente elle-même l'embarquement des jar du conteneur (tomcat-embed-core)
- qu'elle ajoute une classe main
- qu'elle livre son application sous forme de jar
- qu'elle connaisse les paramètres utilisés pour les applications spring boot et qu'elle les réutilise: par exemple, elle peut récuperer la valeur de `spring.config.additional.location` et charger ces properties sur la base de cette information. De manière générale un ensemble d'informations est fourni par l'environnement de lancement à l'application (fichier de properties, fichier de conf log éventuellement, trustore etc.) et ces informations sont récupérables par l'application, quelle que soit la technologie choisie.
- si les applications conteneur embarqué "non spring boot" ont besoin d'autres informations, alors
--> l'environnement d'exécution devra s'enrichir de ces informations. Celles-ci de leur coté ne gèneront pas les applications Spring boot (exemple, on rajoute un param `Struts.application.properties.path`, Spring boot l'ignore mais les applis Struts la récupèrent)
--> si un unique service (une meme ligne de commande, une meme structure de répertoires) ne suffisait pas à lancer à la fois du Spring Boot et du "non spring boot", alors il faudra le paramétrer pour avoir 2 services différents et au pire faire un deuximeme contrat "legacy" qui permette de lancer par exemple les applications Struts + serveur embarqué
En tous le cas:
- embarquer un conteneur dans une solution java autre que Spring Boot peut être fastidueux: Spring Boot fait plein de choses qui ne sont pas facilement reproductibles (exemple constituer le classpath et son arborescence, désigner une classe main etc.)
- **pour les applications non Spring**: **il faudra, application par application, comparer le coût de 2 scénarios**: passer en mode serveur embarqué, ou passer sous Spring. Passer à Spring permettrait de réduire le legacy, là où le passage en mode embarqué est plus coûteux que pour les applications en Spring (moins que de passer de Struts à Spring certes), mais accumule le retard.
Le temps que l'offre Serveur Embarqué soit généralisée, il est tout à fait possible que le cluster ait vu le jour en production. Il sera beaucoup plus aisé de faire tourner le legacy (Struts, autre) dans du conteneur (Tomcat) que de les passer au chausse-pied dans du conteneur embarqué.
- pour les application Spring mais non Spring Boot: facile de passer à Spring Boot.
:::success
En l'**état d'avancement des développements** il est faisable de livrer des applications Sring boot (quel que soit le serveur) et certainement ( à vérifier) des applications hors Spring Boot (exemple une appli Struts ou Spring). Simplement, l'offre est "orientée" (lancement facilité) Spring Boot
:::
----
:::info
## En PROD
:::
### :one: Livrable PROD
- un **jar** exécutable, sans les properties externalisées, juste un ou des fichiers de properties dans le classpath
- **_Exemple_** en Spring Boot:
- :file_folder: BOOT-INF
- :file_folder: classes
- :file_folder: fr/insee/monAppli
- :page_facing_up: monAppli.class
- :page_facing_up: **application.properties** ou **monAppli.properties** (ou n'importe quel autre nom)
- :file_folder: config (*optionnel*)
- :page_facing_up: **application.properties** (ou **monAppli.properties** ou n'importe quel autre nom). <br>*Optionnel*, uniquement si 2 fichiers de properties internes. N'est que du ressort du Dev, ne concerne pas l'exploitation.
- :file_folder: lib
- :file_folder: META-INF
- :file_folder: org
### :two: Définition du service
#### L'arborescence au CEI sera de la forme
- :file_folder: `java-app` (*nommage "java-app" arbitraire pour l'exemple*, il faut un répertoire dans lequel mettre le jar et les properties. pourrait être `tomcat_embedded`, `server_embedded` etc.)
- :file_folder: config
- :page_facing_up: **application.properties** ==> le fichier de properties de production, tiré par puppet
- :gift: **monAppli.jar** ==> le jar livré par le développeur
On pourra, à titre d'exemple, placer ce répertoire sous `/var/opt/`
:question: quel nommage entre
- tomcatemb
- tomcat_embedded
- embedded_server
- java_app
#### Le Service
- 1. Créer un `service` systemd (nommé "java-app" par exemple)
```
[Unit]
Description= Java embedded Spring Boot application
After=syslog.target
[Service]
User=insee
Group= [...]
ExecStart=/var/opt/lancement.sh
ExecStop=[...]
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
```
#### Commande lancée par le service
:::warning
dans le script (`lancement.sh` par exemple) appelé par le service on pourrait lancer:
<br>
```
java -jar -Xms256m -Xmx1024m opt/insee/tomcat-embeded/application.jar (nommage générique du jar)
--server.port=8080 #(optionnel, mis pour info)
--server.servlet.context-path=/monAppli (optionnel, mis pour info)
--spring.config.additional-location=opt/insee/tomcat-embeded/config/application.properties # Obligatoire
--server.ssl.trustore-store=/chemin/versLeTrustore
--server.ssl.trust-store-type=xx # ?
--server.server-header=unknown
--trace=false # optionnel
--server.tomcat.accesslog.enabled=true
--server.tomcat.accesslog.directory=/chemin/vers/logs
--server.tomcat.accesslog.rotate=false # (géré par ailleurs - logrotate?)
--management.endpoints.enabled-by-default=false # #(optionnel) On désactive les endpoints par défaut si on veut sécuriser, sinon on ne met rien
-Dmanagement.server.port=<un autre port que les ports http classique>. # Optionnel, plutot du ressort de l'application si elle veut mettre un autreport
-Dmanagement.endpoint.prometheus.enabled=true #(optionnel, ssi management.endpoints.enabled-by-default=false)
-Dmanagement.endpoints.web.base-path=<autre chose que la valeur par défaut ("/actuator"). # Optionnel, du ressort de l'application si elle veut sécuriser ses endpoints.
--management.endpoint.shutdown.enabled=false # Optionnel, si les endpoint ne sont pas fermés par défaut
-Dmanagement.endpoints.web.exposure.exclude=[liste des endpoints à exclure de l'exposition] # voir plus bas. Modifiable par le Dev
-Dmanagement.endpoints.jmx.exposure.exclude=* # Modifiable par le Dev
```
:::
- Il conviendra de **compléter** la liste des paramètres de sécurité par les éléments listés sur le wiki PILAS --> **https://gitlab.insee.fr/pilas/documentation-pilas/-/wikis/2%20Logiciels%20applicatifs%20et%20progiciels/Tomcat/tomcat9-securisation**
Ces éléments pourront en partie être trouvés parmi les `Server properties` de https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties-server
:::info
:heavy_check_mark: **Proposition**:
on part sur une **commande minimale** et on voit ensuite quels élements de sécurité intégrer et comment. Cette commande minimale
- gère le chemin du jar, le chemin des properties externalisées, les accesslog et le trustore
- désactive par défaut les endpoints (par défaut ils sont activés, notre politique sera d'activer sciemment les endpoints dont on a besoin), active le endoint prometheus puisque par défaut les endpoints ont été désactivés, et expose en http le endoint prometheus (par défaut il n'est pas exposé, seul "health" et "info" sont activés)
:::
Les arguments que l'on veut verouiller seront en `--`. Ceux sur lesquels on veut mettre une valeur par défaut tout en laisser la possibilité aux développeurs de le modifier au lancement (via `System.setProperty`) seront en `-D`. L'odre de priorité Spring est en effet:
- 1. command line arguments (`--`)
- 2. Java System properties (`-D`)
- 3. OS Environment variables (`export MA_VARIABLE ...`)
- 4. application.properties (fichiers de properties)
```
java -jar -Xms256m -Xmx1024m /opt/insee/tomcat-embeded/application.jar
--spring.config.additional-location=opt/insee/tomcat-embeded/config/application.properties
--server.ssl.trustore-store=/chemin/versLeTrustore
--server.ssl.trust-store-type=xx # ?
--server.tomcat.accesslog.enabled=true
--server.tomcat.accesslog.directory=/chemin/vers/logs
--server.tomcat.accesslog.rotate=false # (géré par ailleurs - logrotate?)
--server.jetty.accesslog.enabled=true #(idem que Tomcat)
--server.jetty.accesslog.filename=/chemin/vers/logs/fichier_log #
--server.jetty.accesslog.file-date-format='yyyy-mm-dd' # sinon rien, géré par logrotate
-Dmanagement.endpoints.enabled-by-default=false
-Dmanagement.endpoint.prometheus.enabled=true
-Dmanagement.endpoints.web.exposure.include=prometheus
```
Explications: :arrow_forward:
- 1) `/opt/insee/tomcat-embeded/application.jar` : le jar livré par les dev sera nommé lors de la livraison selon les conventions habituelles (nomAppli-module-version). Il sera renommé dans un nom générique (exemple 'application.jar') pour que le service de lancement du jar soit le plus générique possible: qu'il n'y ait pas à paramétrer le contrat noeud par le nom d'application ou qu'il n'y ait pas à modifier à la volée le nom du jar lancé par le service: le service doit juste savoir qu'il faut qu'il lance un jar nommé 'application.jar'. Pareillement, Majiba n'aura pas à savoir comment renommer le jar livré, il faudra juste qu'il s'assure qu'il livre sur la bonne plateforme et il renommerait le jar en 'application.jar' quelle que soit la plaforme.
- **Sinon on fait comme d'habitude**: contrat noeud et on met un parametre <%= @application %> qui servira entre autre à renommer le jar avec le nom de l'application.
- l'action de renommage sera faite par l'automate de déploiement:
- rundeck en prod
- scrute_vsftp.sh en Hprod. Actuellement le script `scrute_vsftp.sh` fait un `application=$(echo $filename|cut -d. -f1)` pour repérer le nom de l'application et faire le ménage sous /var/lib/tomcat/webapps/${application} (pour nettoyer le contexte avant de le recréer)
- A la cible, le sript prendra le zip (avec le jar + properties + log4j.xml), le dézippera pareil que maintenant, fera le ménage sous /opt/insee/tomcat-embeded et mettra tous les fichiers (le jar, les fichiers de properties, le log4j2.xml) sous le répertoire /opt/insee/tomcat-embeded/
- 2) `--spring.config.additional-location`
Uniquement en PROD. En prod cela **sert à être certain d'intégrer les properties** indiquées dans cette additional-location, quel que soit le nom des fichiers de properties indiqués par l'application dans sa classe main.jar. En gros on veut etre sûr que les properties de production sont prises en compte, sans avoir à interférer dans le code applicatif: le developpeur peut mettre le nom (`spring.config.name=toto`) qu'il veut, les répertoires externes et internes (`spring.config.location=classpath:/,classpath:/config_toto/,file:./un_repertoire_qui_n_existe_pas,file:./config_toto/`) qu'il veut, les properties indiquées par la prod seront **toujours chargées**).
La ligne de commande de lancement du service sera légérement différente en hprod qu'en prod car c'est le développeur qui ajoute son fichier de properties externe
- :-1: soit on le contraint à livrer en DV/QF un fichier de properties nommé 'application.properties'. Le srcipt de déploiement `scrute_vsftp` récupère ce fichier et le copie de `depot` vers `/opt/insee/tomcat-embeded/application.properties`. La ligne de commande peut alors etre identique à celle en prod.
Mais très contraignant, et il y a de nombreuses applications qui nomment leur fichier selon le profil de déploiement (monAppli-dev.properties, monAppli-qf1.properties etc.) Ce serait contraignant pour elles de devoir renommer ces fichiers.
- :+1: soit, préférentiellement, on laisse le développeur libre de nommer en DV/QF le fichier de properties comme il l'entend.
Dans le cas num°2,
- le service lancera `java -jar application.jar`
sans ajouter `spring.config.additional-location=/var/opt/java-app/config/application.properties`.
- la commande sera lancée depuis le répertoire /opt/insee/tomcat-embeded/ (spring boot parle de "répertoire courant" pour l'emplacement par défaut des properties. C'est quoi exactement le répertoire courant, c'est celui depuis lequel est lancée la commande ou celui dans lequel se trouve le jar ?)
(avec un `cd /opt/insee/tomcat-embedded/` avant de faire java -jar), comme cela le fichier de properties qui sera sous ce répertoire pourra être pris en compte par défaut, sans que le développeur n'ait à connaitre l'arboresence CEI, et le développeur pourra le nommer comme il veut (toucan.properties, web4g-bo.properties etc.)
Si le développeur veut ajouter un deuxième fichier de properties:
* soit il le met dans un répertoire 'config' dans son livrable. Ceci donnerait pour la dev/qf
:file_folder: monAppli.zip
- :file_folder: config
- monAppli.properties (si 2 fichiers de properties)
- monAppli.properties
- log4j.xml
- monAppli.jar
* soit il se sert de la nouvelle fonctionnalité de spring boot 2.4 `spring.config.import`, à mettre dans le premier fichier de properties (voir https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4)
- 3) `server.ssl.trustore-store`
- 4) `server.[tomcat|jetty].accesslog`: indiquer le repertoire de sortie des accesslog. Le dev n'a pas à le connaitre a priori
:arrow_down:
**Tableau**: *Liste des éléments de sécurité à migrer*
|Wiki PILAS | Adaptation |
| -| -|
| Privilèges du service tomcat| Créer un `user` et groupe ad-hoc pour lancer le service|
| Anonymisation du serveur| --server.server-header=unknown|
|Anonymisation du serveur <br> http TRACE | --trace=false|
|Anonymisation du serveur <br> xpoweredBy=false dans le web.xml |<br>server.servlet.jsp.init-parameters.xpoweredBy <br> dans le groupe de paramétrage de JSP `server.servlet.jsp.init-parameters.*` (voir la [doc° officielle](https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#server.servlet.jsp.init-parameters)|
|Anonymisation du serveur <br> /etc/tomcat9/conf/web.xml, placer le paramètre « listings » à false| :question: |
| Droits d’accès sur les répertoires| Idem que privilège du service. <br> Créer un user ad-hoc|
| Gestion des logs| --server.tomcat.accesslog.enabled=true|
| Annuler le déploiement de l’interface d’administration| Il n'y a plus d'interface d'administration avec spring boot 2 <br> Remplacé par la martie manager de l'actuator, sécurisé|
|Appliquer un timeout sur les sessions | -Dserver.tomcat.connection-timeout=30|
|Empêcher la lecture de l’identifiant de session | <br> Contexte applicatif, du ressort du Dev désormais <br>:question:|
|Ouverture/Fermeture des ports d’écoute | Faut-il fermer des ports ? <br>Sous Spring Boot il n'y a plus d'interface d'administration et plus de port spécifique pour le shutdown. <br> Pas certain qu'il y ait des ports à fermer. |
|Interfaces d'écoute |server.port=8080 |
|Sécurisation des connexions | Pris en charge par F5|
| Modification du paramétrage du port d’extinction| N'existe plus dans Spring boot 2 <br> --management.endpoint.shutdown.enabled=false|
|Déploiement automatique des applications | Sans objet dans Spring boot jar|
|Remoteipvalve, X-Forwarded-Proto » et « X-Forwarded-For | <br>server.tomcat.remoteip.protocol-header=x-forwarded-proto <br> server.tomcat.remoteip.protocol-header-https-value=https (default)|
|`InseeAddHeaderValve` headerName='X-Frame-Options' | :question: <br> Deprecated tres certainement (était pour la fédé Id ?) |
#### Sécurisation des endpoints actuator
- L'acces est nativement sécurisé par Spring security et par la configuration qui en est faite (Basic, OIDC etc.). A l'insee elle s'appuie sur OIDC de KC. Le Dev s'appuierait sur un rôle à pouvoir existant (ex. Admin) qui donnerait acces aux endpoints actuator. C'est la première sécurité, elle est du meme type que la sécurité applicative (n'autoriser l'acces aux ressources protégées qu'à des comptes à pouvoir). Le reste de la sécurité joue sur:
- ce que l'on active (on peut ou pas activer des javaagents par exemple)
- ce que l'on expose parmi les services activés. Empecher d'exposer un service que l'on a désactivé constitue une sécurité supplémentaire: si le service est activé par erreur, il ne sera pas exposé sur un endpoint.
- la manière dont on les expose (port, path). On peut vouloir changer les valeur par défaut de ces parametres pour augmenter la sécurité
Côté code, l'application devra sécuriser son actuator
Exemple de sécurisation des endpoint de l'actutor, avec ici pour role "ENDPOINT_ADMIN" (pourra être autre rôle, rattaché à des comptes à pouvoir comme "ADMIN")
```java
@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
.anyRequest().hasRole("ENDPOINT_ADMIN")
.and()
.httpBasic();
}
}
```
*Exemple*: http://dvgensuivilht01.ad.insee.intra/toucan/actu (admin:admin)
- C'est l'application qui fait les choix en matière de personnalisation des acces aux différents endpoints (sécuriser /info /health ou non etc.). Elle peut laisser une autorisation globale pour les endpoints ou faire plus finement, endpoint par endpoint.
- Le prometheus de la supervision devra obtenir un jeton qui lui permette de s'authentifier sur les endpoints de l'actuator. Ce jeton sera demandé par l'équipe de dev au DOT, puis transmis à l'équipe supervision pour qu'elle le mette dans la config du Prometheus de supervision. Si le port d'écoute de l'actuator est différent du port standard (management.server.port<> 8080) alors la supervision devra en être informée
- Liste des enpoints à exclure de l'exposition (à mettre dans la property`management.endpoints.web.exposure.exclude`) parmi:
|prop spring | Exclure ? |
| --| --|
|`auditevents` | |
| `beans`| |
| `conditions`| |
| `configprops`| |
| `env`|Peut être. puissant et potentiellement dangeureux |
| `flyway`| |
| `health`| |
| `heapdump`| |
| `httptrace`| |
| `info`| |
| `integrationgraph`| |
| `jolokia`| Peut être. puissant et potentiellement dangeureux |
| `liquibase`| |
| `logfile`| |
| `loggers`| |
| `mappings`| |
| `metrics`| |
| `prometheus`|NON, ne pas l'exclure, on en a besoin pour la supervision|
| `scheduledtasks`| |
| `sessions`| |
| `startup`| |
| `threaddump`| |
L'idée est
- d'offrir une sécurisation supplémentaire par rapport à celle par défaut (acces authentifié aux ressources de l'actuator)
- de n'exclure que les endpoints que l'on considère comme 'dangereux' (ie ceux qui fournissent de l'information utilisable par un utilsateur malveillant ou maladroit)
Avec ces restrictions, une équipe de développement qui veut accéder en http au endpoint Jolokia devra:
- activer le endpoint (qui sont désactivés par défaut, voir param `management.endpoints.enabled-by-default=false`)
- exposer le endpoint (qui par défaut sont ne sont pas exposés, voir param ` management.endpoints.web.exposure.exclude`)
#### Sécurisation du Tomcat par le code
> Bonnes pratiques à implémenter coté code
qui ne sont pas transcriptibles via des parametres en ligne de commande
- Realm `org.apache.catalina.realm.LockOutRealm`
C'est une implémenentation de l'interfact Tomcat Realm qui permet de bloquer un utilisateur en cas de trop nombreuses tentatives de connexion erronées sur une certaine période de temps (attaque brute force). Voir https://www.baeldung.com/spring-security-block-brute-force-authentication-attempts
### Traces applicatives :page_with_curl:
Elles sont gérées par 2 éléments
- **fichier de configuration des logs**, log4j2.xml ou log4j.xml, ou autre fichier
- assure le paramétrage des LOGGER (format de la log selon la classe java)
- assure le paramétrage de l'Appender Sysout (`<Console name="Console" target="SYSTEM_OUT">`)
- **ce fichier reste dans le classpath (dans le jar). Il n'est pas touché/surchargé par la prod**. Plus simple à gérer que des conf de log externalisées, les dev sont responsables de bout en bout la conf des logs.
- **fichier de properties externalisé** (application.properties), surchargé par la prod. Permettra à la prod d'indiquer
1. ::heavy_check_mark: le chemin du fichier de sortie de log
2. ~~le chemin vers le fichier de configuration des logs~~ : pas besoin, par défaut le fichier de conf des logs est pris dans le classpath.
- 1. Le chemin du fichier de sortie de logs
Dans le fichier application.properties, il y aura une property, que la prod surchargera
- ~~logging.file.name~~ : pas la peine, les applications/devs décident du nom de fichier
- property: **`logging.file.path`**: pour que le fichier soit produit dans le répertoire voulu par la prod. _Exemple_ : `logging.file.path=/var/log`
Avec Spring boot, cette variable logging.file.path sera disponible depuis le fichier log4j, sous la forme d'une variable System
- logging.file.path ==> `LOG_PATH`
Cette variable `LOG_PATH` peut être récupérée comme suit dans le fichier log4j2.xml:
- `<file>${LOG_PATH}/spring-boot-logger.log</file>`
- `<fileNamePattern>${LOG_PATH}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>`
- 2. ~~Le chemin vers le fichier de configuration (chemin vers log4j2.xml)~~
- ~~property: **`logging.config`**, dans le fichier application.properties externe~~
- ~~cette property sera surchargée par la Prod, qui la valorisera avec le chemin vers le fichier log4j.xml externalisé~~
---
**Avancement**
|Quoi | Etat |Observation |
|-- | --|-- |
| **Livrable** de test sous forme de **jar** <br> Plateforme de test | :heavy_check_mark: | - Plusieurs jar fournis <br> rio, toucan-api, nautile, citrus-web <br> - dvdaapemblas01.ad.insee.intra |
|**Contrat puppet** |:construction: :recycle: |Première version en cours éléboration.<br> Fonctionne, ajouts et refactor à faire <br> https://gitlab.insee.fr/pilas/modules-puppet/tomcat_embedded-puppet-module |
| **Gestion des properties** | :heavy_check_mark: | Properties externalisées <br> Pour l'instant mises sous `opt/tomemb/conf/` (renommage probable de "tomemb" vers un nom plus parlant|
| **Gestion des logs**| | Se fait dans fichier `log4j2.xml`, `Appenders` <br> ou dans les properties (`server.tomcat.accesslog.*`) |
| Gestion des logs applicatives| :heavy_check_mark:|- catalina.out produit sous `/var/log/tomcat-embedded` <br> - <nom_application>.log produit + logrotate. Log supplémentaire (Appender) demandée par l'application |
| Gestion des `accesslogs` | :heavy_check_mark: :recycle:|- acces.log produit sous `/var/log/tomcat-embedded` <br> :question:Exigences particulière du CEI ou des DEVS en la matière (rotation des acceslog, paramétrage PatternLayout etc.) |
| **Gestion des `management endpoints`** | :heavy_check_mark: :recycle:|- page d'accès http disponible, endpoint prometheus exposé.<br> :question:Exigences particulière des DEVS en la matière ? (*exemple*: activer d'autres endpoints par défaut, laisser tous les endpoints activés par défaut ?<br> :dart: <br> - Tester l'acces d'un Prometheus à ce endpoint <br> - Véfifier la possibilité de sécuriser ce endpoint sous Actuator (auth Basic admin:admin ou OIDC) |
| **Sécurisation complémentaire du conteneur** (pour les applications exposées en DMZ par exemple) | :dart: |- Quelles configurations complémentaires? <br> :question: <br> Suggestion des DEVS|
| | |
|**Généralisation** à d'autres conteneurs |:dart: |- Tester avec un Jetty :heavy_check_mark:<br> - Voir quels params adapter pour Jetty|
| |
|**Généralisation** à d'autres processus java |:dart::question: | Voir l'opportunité de tester avec un jar qui embarque autre chose que conteneur de servlet <br> - Dans ce cas voir quels params adapter ou comment laisser la main au Dev sur le lancement de son processus.|
|**Différenciation /environnement** | | |
|Environnement= Hprod | :dart: |- Quels livraison jar, properties, log4j) en DV/QF ? <br> - Script .sh de déploiement à adapter
|
|Environnement= Prod | :dart: |- Quels livraison properties) en PD ? <br> - Comment relivrer jar ?
|
|:factory: **Industrialiser** | :dart: |- Permettre la publication officielle de l'offre <br> - Documentation de la plateforme <br> -->Technique <br> -->Utilisateur: comment livrer concretement, et bonnes pratiques <br> Tester de bout en bout du workflow complet: <br> 1. Demande de pf de DEV, attribution d'une pf de DEV. <br> <br> 1.bis Tester la livraison en DEV <br> - 2. Demande d'une pf de Prod et création d'un project Prometheus par Gepex, demande de modification du service (augmentation de la mémoire jvm par exemple, params additionnels)
|
Annexes
- la plateforme de test
`http://dvdaapemblas01/<application>`
![Uploading file..._tvsad8bz1]()