36 views
# Installation d'AREN sous Debian GNU/Linux 10 (Buster) ## Notes Ceci n'est pas forcément la meilleure manière d'installer l'application AREN. C'est juste une documentation de comment j'ai procédé sur mon serveur que j'ai écrite pour m'en souvenir plus tard et que je partage avec vous. L'installation décrite dans ce document à été réalisée en étant logué en tant qu'utilisateur root Si on est logué sous un compte utilisateur normal il faut utiliser la commande `sudo su -` pour devenir root puis utiliser la commande `exit` a la fin pour revenir à la session utilisateur normal Une autre manière de procéder est de précéder chaque commandes qui nécessites les privilèges d'administration de `sudo ` ## Installation des dépendances Mettre à jour le système `apt-get update && apt-get dist-upgrade` Installer postgresql, java, maven, tomcat et git si ils ne sont pas dejà installés sur le serveur : ``` apt install -y postgresql default-jdk maven tomcat9 git ``` ## Installation d'AREN Récupérer le code source d'AREN depuis github ``` cd ~ git clone https://github.com/ArenMg/aren.git aren ``` Créer un utilisateur postgresql et une base de donnée pour AREN ``` su - postgres createuser -P aren createdb -O aren -E UTF8 -T template0 aren_prod exit ``` Note : La commande createuser demande de saisir un mot de passe pour le nouvel utilisateur. Notez bien le mot de passe que vous choisirez pour le reporter dans la configuration d'AREN Copier les exemples de fichier de configuration et remplir les paramètres comme indiqué dans les commentaire contenus dans ces fichiers ``` cd ~/aren/ cp config/application.properties src/main/resources/ nano src/main/resources/application.properties cp config/persistence.xml src/main/resources/META-INF/ nano src/main/resources/META-INF/persistence.xml ``` Compiler l'application AREN ``` cd ~/aren/ mvn clean install ``` Arréter le service tomcat et supprimer l'application installée par défaut ``` systemctl stop tomcat9 rm -rf /var/lib/tomcat9/webapps/ROOT ``` Deployer AREN à la place (note: tuto pour déployer une webapp sous tomcat : https://www.baeldung.com/tomcat-deploy-war) ``` cd ~/aren/ cp target/aren.war /var/lib/tomcat9/webapps/ROOT.war chown tomcat:tomcat /var/lib/tomcat9/webapps/ROOT.war systemctl start tomcat9 systemctl status tomcat9 journalctl -feu tomcat9 # attendre que le war soit déployé (tomcat va créer une version décompressée du .war) systemctl stop tomcat9 ``` Comme indiqué dans le fichier readme, avant le premier démarrage il faut décommenter deux lignes dans le fichier persistence.xml déployé et les re-commenter après. ``` nano /var/lib/tomcat9/webapps/ROOT/WEB-INF/classes/META-INF/persistence.xml ``` Remplacer ces deux lignes : ``` <!--property name="hibernate.hbm2ddl.auto" value="drop-and-create"/--> <!--property name="hibernate.hbm2ddl.import_files" value="META-INF/init.sql"/--> ``` Par celles là : ``` <property name="hibernate.hbm2ddl.auto" value="drop-and-create"/> <property name="hibernate.hbm2ddl.import_files" value="META-INF/init.sql"/> ``` (En fait il suffit de supprimer `!--` au début des lignes après le `<` et de supprimer `--` à la fin des lignes avant le `>`) Redémarer le service tomcat et vérifier si tout se passe bien ``` systemctl start tomcat9 systemctl status tomcat9 ``` L'application aren doit être accessible sur le port 8080 : `http://nom-du-serveur:8080/` **`/!\/!\/!\`** Penser à modifier à nouveau le fichier `/var/lib/tomcat9/webapps/ROOT/WEB-INF/classes/META-INF/persistence.xml` pour recommenter les lignes comme elle l'étaient à l'origine Sinon la base de données sera supprimée et re-crée à chaque démarrage de l'application ce qui causera une perte de toutes les données. Par contre pour un système de test il peut être utile de garder ces paramètres pour repartir d'une base de données vierge à chaque test. **`/!\/!\/!\`** **Note du 05 Mai 2021** : Sur la dernière version du code source d'AREN ces paramètre de création de la DB ont été modifié et il semble qu'il faut procéder différement (update au lieu de drop/create). Je mettrais a jour ce document lorsque le README.md d'AREN sera modifié pour expliquer la manière officielle de procéder. ## Sécurisation du serveur Si le serveur doit être accéssible via l'internet public il est préférable de sécuriser les communication web en mettant en place un chiffrement SSL De plus si le serveur à une adresse IP publique il faut le sécuriser un minimum en mettant en place un firewall pour bloquer tous les ports sauf ceux strictement nécessaires, mettre en place fail2ban, sécuriser les connection ssh avec une authentification par clé publique, etc... Voir, par exemple, cette documentation réalisée par FramaSoft pour la sécuriation générale d'un serveur : https://framacloud.org/fr/auto-hebergement/securite.html Je ne détaillerais ici que l'aspect chiffrement SSL de tomcat. Mais il est vivement recommendé d'installer au minimum un firewall (ufw par exemple) pour ne laisser ouvert vers l'extérieur que les ports réseaux strictement nécessaires (SSH, HTTP et HTTPS), de sécuriser l'accès SSH au serveur avec des clés privé/publiques et de suivre les autres recommendation du document ci-dessus. Sur mon infrastructure de test je dispose, sur un autre serveur, d'un reverse proxy par lequel passe toutes les requetes http/https venant de l'extérieur et qui gère automatiquement le chiffrement SSL et la génération de certificats via LetsEncrypt. En fonction de votre infrastructure la démarche à suivre pourrait être différente de ce que j'ai réalisé chez moi. ### Mettre en place un certificat auto-signé au niveau de tomcat Note : Cette étape n'est pas strictement nécéssaire puisque c'est le reverse proxy qui fera le chiffrage SSL de tout ce qui transite sur internet avec un certificat généré par LetsEncrypt et automatiquement mis a jour. Cela permet juste, sur mon infrastructure, de chiffrer les communications entre le serveur AREN et le serveur du reverse proxy dans le cas où quelqu'un espionerait ce qui se passe sur mon réseau local. En effet, comme sur cette infrastructure ces deux composants sont sur deux machines distinctes, les communication entre le reverse proxy et le serveur tomcat peuvent être interceptée en écoutant le traffic réseau. Cette étape est superflue dans le cas ou le reverse proxy est sur le même serveur qu'AREN. Et la sécurité est d'ailleurs meilleure en mettant les deux composants sur la même machine. En effet dans une configuration sur deux serveur avec un certificat auto-signé du coté de tomcat, nginx ne vérifie pas forcément la validité du certificat SSL utilisé par tomcat s'il n'est pas correctement configuré. Ce qui laisse la porte ouverte à des attaques de type "man in the middle". Si le proxy nginx est installé sur le même serveur que tomcat, cette étape étant totalement inutile, aller directement à l'étape `Procédure simplifiée pour installer un reverse proxy avec nginx sur le même serveur qu'AREN` Pour générer un certificat SLL auto signé pour tomcat : ``` mkdir -p /opt/tomcat keytool -genkey -alias tomcat -keyalg RSA -keystore /opt/tomcat/keystore chown tomcat:tomcat /opt/tomcat/keystore ``` Configurer SSL avec le certificat auto-signé dans le fichier server.xml de tomcat. Ouvrir ce fichier dans un éditeur : ``` nano /etc/tomcat9/server.xml ``` Et y ajouter un connecteur SSL comme suit : ``` <Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="150" scheme="https" secure="true" SSLEnabled="true" keystoreFile="/opt/tomcat/keystore" keystorePass="******" clientAuth="false" sslProtocol="TLS"/> ``` Remplacer également le connecteur non SLL qui écoute sur le port 8080 par celui-ci qui fais une redirection sur le connecteur SSL: ``` <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ``` Note : `keystorePass` est le mot de passe qui a été saisi à la génération du certificat SSL avec keytool Redémarer le service tomcat et vérifier que tout se passe bien ``` systemctl restart tomcat9 systemctl status tomcat9 ``` L'application AREN doit maintenant être accessible en SSL sur le port 8443 : `https://nom-du-serveur:8443/` ### Configurer une redirection et générer un certificat SSL signé par LetsEncrypt au niveau du reverse proxy. Sur mon suystème de tests j'utilise Nginx Proxy Manager qui s'occupe de ca tout seul et qui se configure simplement au traver d'une interface web : https://nginxproxymanager.com/ Mais il est aussi possible d'utiliser nginx tout seul en réalisant la configuration à la main et de générer des certificats SLL avec l'utilitaire certbot de Lets Encrypt. Voici un exemple de tutoriel qui explique les principes de base : https://openclassrooms.com/fr/courses/1733551-gerez-votre-serveur-linux-et-ses-services/5236081-mettez-en-place-un-reverse-proxy-avec-nginx A noter qu'on est pas obligé d'installer le reverse proxy nginx sur un serveur séparé du serveur AREN comme c'est fait dans le tutoriel. Il est tout à fait possible d'installer le reverse proxy nginx sur le même serveur que l'application AREN. Et comme indiqué au chapitre précédent c'est même plus sur de faire comme ça d'un point de vue sécurité. C'est ce que j'ai fais pour sur serveur de production pour Terre De Convergence, comme décrit dans le chapitre suivant. ### Procédure simplifiée pour installer un reverse proxy avec nginx sur le même serveur qu'AREN (sous Debian GNU/Linux) : Installation nginx et certbot ``` # apt update && apt upgrade # apt install nginx certbot python3-certbot-nginx -y ``` Ouverture des port HTTP et HTTPS au niveau du firewall ``` # ufw allow 'Nginx HTTP' # ufw allow 'Nginx HTTPS' # ufw status verbose ``` Configuration nginx ``` # nano /etc/nginx/sites-available/prog.terre-de-convergence.org # ln -s /etc/nginx/sites-available/prog.terre-de-convergence.org /etc/nginx/sites-enabled/ # nginx -t # systemctl reload nginx ``` Génération du certificat SSL via LetsEncrypt avec CertBot ``` # certbot --nginx ``` Voir un exemple de contenu du fichier `/etc/nginx/sites-available/prog.terre-de-convergence.org` en annexes [ci-dessous](https://md.lab12.le-led.me/s/r1iNlubKD#Un-exemple-de-fichier-de-configuration-nginx-pour-le-reverse-proxy-). ## Configuration de la mémoire utilisable par tomcat Ajouter les options `-Xms`, `-Xmx`, `-XX:PermSize` et `-XX:MaxPermSize` sur la ligne `JAVA_OPTS` dansles fichiers `/etc/default/tomcat9` et `/etc/systemd/system/multi-user.target.wants/tomcat9.service` Par exemple, pour le fichier `/etc/default/tomcat9` : ``` JAVA_OPTS="-Djava.awt.headless=true -Xms128m -Xmx2048m -XX:PermSize=265m -XX:MaxPermSize=1024m" ``` Et pourle fichier `/etc/systemd/system/multi-user.target.wants/tomcat9.service` : ``` Environment="JAVA_OPTS=-Djava.awt.headless=true -Xms128m -Xmx2048m -XX:PermSize=265m -XX:MaxPermSize=1024m" ``` ## License Cet article est publié sous license Creative Commons [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.fr) Copyleft ![Copyleft](https://stratus.lab12.le-led.me/s/cxSa57Exp62ESH6/preview =18x) Douze Bé 2020/11/05 ## Annexes ### Versions Au 04/05/2021 les versions des dépendances qui étaient utilisées sur le serveur étaient : - OS : Debian 10 (Buster) kernel linux 5.4.65 - DB : PostgreSQL 11.11 - Java : OpenJDK 11.0.11 - Build : Maven 3.6.0 - Serveur d'applications : Tomcat 9.0.31 ### Mon fichier application.properties Note : j'ai remplacé les informations personelle par des étoiles ``` # Change the production mode to alter some logging in the application # On the client side, if set as true, the javascript and css loaded will be the minified ones production = false # If you are behind a reverse proxy, write here the end user root url # Example : http://aren.my_company.fr/app reverse-proxy = https://debats.terre-de-convergence.org # A unique identification of you web server. Used for remote requets # Example : My_Institution plateform.id = terre-de-convergence # Secret use for the creation of JWT token authentication.jwt.secret = ******** # Issuer for the JWT token # Example : my_domain.name authentication.jwt.issuer = debats.terre-de-convergence.org # Audience for the JWT token # Example : my_domain.name authentication.jwt.audience = debats.terre-de-convergence.org # Validation time for the JWT tokens, in seconds # Default is one year authentication.jwt.validFor = 31536000 # Other configuration for JWT token, don't change if you don't know what you do authentication.jwt.clockSkew = 10 authentication.jwt.claimNames.authorities = authorities authentication.jwt.claimNames.refreshCount = refreshCount authentication.jwt.claimNames.refreshLimit = refreshLimit # SMTP configuration # String smtp.server = ****.********.*** # Boolean smtp.auth = true # Int smtp.port = 587 # Boolean smtp.tls = false # String smtp.username = ********@******.*** # String smtp.password = ******** # ENT conexion configuration # Example : https://cas.mon-ent-occitanie.fr/login cas.url = # AREN tools # The Python scalar server scalar.url = https://portail-aren.lirmm.fr/aren-vectors/scalar # The python theme server theme.url = https://portail-aren.lirmm.fr/aren-vectors/theme # Remote tool configuration idefix.url = http://www.jeuxdemots.org/intern_extract.php ``` ### Mon fichier persistence.xml ``` <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="default" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <!-- Connection information --> <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/> <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/aren_prod"/> <property name="hibernate.connection.username" value="aren"/> <property name="hibernate.connection.password" value="********"/> <property name="hibernate.default_schema" value="public"/> <!-- SQL and DB config --> <property name="hibernate.generate_statistics" value="false"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.show_sql" value="false"/> <property name="hibernate.use_sql_comments" value="false"/> <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JDBCTransactionFactory"/> <property name="hibernate.current_session_context_class" value="thread"/> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <property name="hibernate.jdbc.batch_size" value="30"/> <property name="hibernate.jdbc.batch_versioned_data" value="true"/> <!-- DB inititialization --> <!-- <property name="hibernate.hbm2ddl.auto" value="drop-and-create"/> <property name="hibernate.hbm2ddl.import_files" value="META-INF/init.sql"/> --> <!-- Pool configuration --> <property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/> <property name="hibernate.c3p0.acquire_increment" value="5"/> <property name="hibernate.c3p0.idle_test_period" value="60"/> <property name="hibernate.c3p0.min_size" value="5"/> <property name="hibernate.c3p0.max_size" value="20"/> <property name="hibernate.c3p0.max_statements" value="50"/> <property name="hibernate.c3p0.timeout" value="0"/> <property name="hibernate.c3p0.acquireRetryAttempts" value="1"/> <property name="hibernate.c3p0.acquireRetryDelay" value="250"/> <property name="hibernate.c3p0.maxIdleTime" value="3000"/> </properties> </persistence-unit> </persistence> ``` ### Un exemple de fichier de configuration nginx pour le reverse proxy : ``` upstream backend_tomcat{ server 127.0.0.1:8443; } server { server_name debats.terre-de-convergence.org; location / { include proxy_params; proxy_pass https://backend_tomcat; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/debats.terre-de-convergence.org/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/debats.terre-de-convergence.org/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = debats.terre-de-convergence.org) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name debats.terre-de-convergence.org; return 404; # managed by Certbot } ``` Note : remplacer le port `8443` par `8080` dasn le bloc `upstream` et https par http sur la ligne `proxy_pass` si la mise en place d'un certificat SSL autosigné n'a pas été réalisée du coté de tomcat. ### Soucis lors de la mise a jour d'AREN Le fichier `src/main/resources/META-INF/persistence.xml` a été ajouté sous git ce qui cause un problème de conflit avec la version paramétrée localement conformément à ce qui est indiqué dans le README.md du projet : `Copy the persistence.xml file from the config forlder to the src/main/resources/META-INF folder. Fill the following line with the db_user, db_password and db_name previously set.` Seul le fichier d'exemple de configuration `config/persistence.xml` devrait être sous git, pas le fichier `src/main/resources/META-INF/persistence.xml` Même remarque pour le fichier `src/main/resources/application.properties` ``` root@euphorbe:~/aren# git log commit 5e978d6e4f4c78b0735a7520e36cb307d74e7914 (HEAD -> main, origin/main, origin/HEAD) Author: Henintsoa <dev.henintsoa@gmail.com> Date: Fri Apr 16 11:34:24 2021 +0300 Aren new update root@euphorbe:~/aren# git pull remote: Enumerating objects: 85, done. remote: Counting objects: 100% (85/85), done. remote: Compressing objects: 100% (24/24), done. remote: Total 67 (delta 40), reused 64 (delta 37), pack-reused 0 Unpacking objects: 100% (67/67), done. From https://github.com/ArenMg/aren 5e978d6..b068616 main -> origin/main Updating 5e978d6..b068616 error: Your local changes to the following files would be overwritten by merge: src/main/resources/META-INF/persistence.xml Please commit your changes or stash them before you merge. Aborting root@euphorbe:~/aren# ```