Compare commits
116 Commits
f8c6ef9a3f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 48c26f9f84 | |||
| 70facd85f3 | |||
| 5eda1c002e | |||
| 24a45fecf3 | |||
| 1b758b6161 | |||
| b75afa7df8 | |||
| 58b6a44819 | |||
| 8e882c7756 | |||
| b8808e4219 | |||
| 5375a48bfd | |||
| 4936d3c8e7 | |||
| 3d64c538af | |||
| d9c2e20402 | |||
| 12cbbd0a6a | |||
| bd74da92ff | |||
| 5e663d8925 | |||
| 2f0831aa09 | |||
| cad29cdc71 | |||
| eabf6c042e | |||
| ca73246a47 | |||
| 1b7173b824 | |||
| bc57514c0d | |||
| 9b29b85fb2 | |||
| 4ee5bcc04f | |||
| 164c69f580 | |||
| 00c1c9562b | |||
| a8cd67f38c | |||
| 285e332a9f | |||
| 0d46cf7752 | |||
| a3ecc212dd | |||
| 506dfb1086 | |||
| f22cf0bff7 | |||
| 917f3a68bb | |||
| 579631df00 | |||
| 680b9a2af9 | |||
| bf8b686477 | |||
| 86583798f5 | |||
| 4c1ca83681 | |||
| cdd5b93432 | |||
| 400b22d821 | |||
| 56352f2749 | |||
| 482dabf05f | |||
| 0cfc306351 | |||
| 428110dad1 | |||
| 8e0136d8dd | |||
| d6d9f5b14a | |||
| f5c7214107 | |||
| fa1fa6f1aa | |||
| 18822822e3 | |||
| 58bbe9051d | |||
| 0c5f0e9770 | |||
| 9101bf061a | |||
| 5631e5a1ad | |||
| a88483a2a2 | |||
| fe7f57dbc7 | |||
| cb0897aa2f | |||
| 2f59a957d7 | |||
| 565a3e2216 | |||
| e3e779c870 | |||
| 97504443ea | |||
| 1d7cb2eb15 | |||
| f6087a5e0f | |||
| 1ff01b383f | |||
| 0f6cdc7fcc | |||
| 6b997e9446 | |||
| 569ec5457e | |||
| 2bd7121f6e | |||
| 765057a367 | |||
| 97531efe3d | |||
| 99e06e97ce | |||
| a703b0f429 | |||
| a70dcfb818 | |||
| 13866482b9 | |||
| be0f6f50c0 | |||
| 9a8c9dea12 | |||
| 46ab7a92c9 | |||
| ff61441355 | |||
| 2bbd533024 | |||
| 09259162d3 | |||
| e3053f90cc | |||
| b3d3313e61 | |||
| a81189e5d2 | |||
| 6005045e7c | |||
| d181ed7d68 | |||
| 2af16cf8a7 | |||
| 54a0c21787 | |||
| 240acff0d4 | |||
| 93855e11e6 | |||
| e9cc0b8221 | |||
| 35dc05df26 | |||
| 71fc606145 | |||
| ef51ecb38a | |||
| e123bb115b | |||
| 7c7bfb5010 | |||
| 23e324bfef | |||
| 97707f1ffd | |||
| dfbe21c2fc | |||
| 6a316e84ac | |||
| 027c3ab250 | |||
| c88689b5e9 | |||
| c633440fe7 | |||
| 920a0b9cdb | |||
| ad4796f187 | |||
| cf809a1aa9 | |||
| 3a2952a81f | |||
| c7cf651727 | |||
| 5055213835 | |||
| 4fad0f88da | |||
| 6f7dfecef4 | |||
| 6d45a52983 | |||
| b04dcb48c2 | |||
| 7cd803942f | |||
| 86c9b9dbf7 | |||
| c45f3a0357 | |||
| b3d583aa83 | |||
| f8f93ed49b |
58
CONTRIBUTING.md
Normal file
58
CONTRIBUTING.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# 🤝 Contribution au projet
|
||||
|
||||
Merci de votre intérêt pour ce projet ! Ce guide explique comment contribuer efficacement.
|
||||
|
||||
## 🚀 Comment contribuer ?
|
||||
|
||||
### 1️⃣ Forker et cloner le dépôt
|
||||
|
||||
1. Forkez le dépôt sur votre compte Git.
|
||||
2. Clonez-le en local :
|
||||
```bash
|
||||
git clone https://git.abonnel.fr/cedricAbonnel/notes-techniques.git
|
||||
cd notes-techniques
|
||||
```
|
||||
|
||||
### 2️⃣ Créer une branche
|
||||
|
||||
Avant de faire vos modifications, créez une nouvelle branche :
|
||||
```bash
|
||||
git checkout -b feature/nom-de-votre-feature
|
||||
```
|
||||
Remplacez `nom-de-votre-feature` par une description claire de votre ajout ou correction.
|
||||
|
||||
### 3️⃣ Développer et tester
|
||||
|
||||
- Assurez-vous que votre code respecte la structure existante.
|
||||
- Testez vos scripts avant de proposer une modification.
|
||||
- Documentez vos changements si nécessaire (ajout d'explication dans `README.md` ou `INSTALL.md`).
|
||||
|
||||
### 4️⃣ Soumettre une Pull Request (PR)
|
||||
|
||||
1. Ajoutez et validez vos changements :
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Ajout d'une fonctionnalité X"
|
||||
```
|
||||
2. Poussez votre branche :
|
||||
```bash
|
||||
git push origin feature/nom-de-votre-feature
|
||||
```
|
||||
3. Créez une Pull Request depuis l'interface Git en expliquant vos changements.
|
||||
|
||||
## 📌 Bonnes pratiques
|
||||
|
||||
- **Code clair et lisible** : Commentez si nécessaire.
|
||||
- **Respect de la structure** : Gardez les fichiers organisés.
|
||||
- **Petites PRs bien définies** : Une PR = une seule amélioration claire.
|
||||
- **Discussions ouvertes** : N'hésitez pas à poser des questions ou à proposer des idées.
|
||||
|
||||
## 🛠 Signaler un problème
|
||||
|
||||
Si vous trouvez un bug ou avez une suggestion, ouvrez une issue avec :
|
||||
- Une description claire du problème
|
||||
- Les étapes pour le reproduire
|
||||
- Le comportement attendu
|
||||
|
||||
Merci pour votre contribution ! 🚀
|
||||
|
||||
15
FILES.md
Normal file
15
FILES.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Liste des fichiers Markdown
|
||||
- [Code de Conduite du Contributeur](./code_of_conduct.md)
|
||||
- [Contribuer au Projet](./contribute.md)
|
||||
- **Certificats**
|
||||
- [Créer une autorité de certification (CA) privée](./notes/certificats/creer_une_autorite_de_certification_CA_privee.md)
|
||||
- **Linux**
|
||||
- [Configurer une IP statique](./notes/linux/network_ipStatic.md)
|
||||
- **Serveur**
|
||||
- [Sécuriser avec fail2ban](./notes/serveur/fail2ban.md)
|
||||
- [Sécuriser Postfix avec fail2ban](./notes/serveur/fail2ban-postfix-sasl.md)
|
||||
- [Sécuriser sshd avec fail2ban](./notes/serveur/fail2ban-sshd.md)
|
||||
- [Automatisation de la Gestion des Messages Différés de Postfix](./notes/serveur/postfix-delete-messages-deferred.md)
|
||||
- **Webapps**
|
||||
- [Rendre accessible Clamav à NextCloud](./notes/webapps/clamav-avec-nextcloud.md)
|
||||
- [Notes Techniques](./README.md)
|
||||
9
LICENCE
9
LICENCE
@@ -1,9 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 cedricAbonnel / Cédrix
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
31
LICENCE.md
Normal file
31
LICENCE.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# License for Scripts and Notes
|
||||
|
||||
This work is licensed under the **Creative Commons Attribution - NonCommercial 4.0 International (CC BY-NC 4.0)**.
|
||||
|
||||
## Terms of Use
|
||||
|
||||
You are allowed to:
|
||||
- **Use** this work for personal and non-commercial purposes.
|
||||
- **Modify** and adapt this work for your own needs.
|
||||
- **Share** this work under the same license, provided you give credit to the original author.
|
||||
|
||||
### Attribution
|
||||
Any reuse, distribution, or modification of this work must include a clear mention of the original author.
|
||||
Example: *"Based on work by Cédric Abonnel / Cédrix under CC BY-NC 4.0 license"*.
|
||||
|
||||
## Commercial Use
|
||||
The use of this work in a **commercial or for-profit context** (including but not limited to businesses, paid services, and integration into commercial products) **is not allowed without specific agreement**.
|
||||
|
||||
If you wish to use this work for commercial purposes, please contact me to establish a suitable license.
|
||||
|
||||
## Disclaimer
|
||||
This work is provided "as is," without any warranty. The author shall not be held liable for any damages resulting from its use.
|
||||
|
||||
## Compliance with NIS2 Directive
|
||||
This license and the usage of the associated scripts and notes should be considered in the context of the **NIS2 Directive** (Network and Information Security Directive 2). Organizations using these materials within their cybersecurity frameworks should ensure compliance with NIS2, particularly regarding risk management, reporting obligations, and security measures. The author does not assume responsibility for compliance violations related to the integration or use of these materials.
|
||||
|
||||
Furthermore, while this license allows free non-commercial use, it does not exempt organizations from their legal obligations under **NIS2**. Users should assess whether modifications or adaptations of these materials impact their regulatory requirements and take necessary actions to remain compliant.
|
||||
|
||||
## Additional Information
|
||||
For more details on the CC BY-NC 4.0 license, visit:
|
||||
[https://creativecommons.org/licenses/by-nc/4.0/](https://creativecommons.org/licenses/by-nc/4.0/)
|
||||
32
LICENCE_FR.md
Normal file
32
LICENCE_FR.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Licence d'Utilisation des Scripts et Notes
|
||||
|
||||
Ce travail est sous licence **Creative Commons Attribution - Pas d'Utilisation Commerciale 4.0 International (CC BY-NC 4.0)**.
|
||||
|
||||
## Conditions d'Utilisation
|
||||
|
||||
Vous êtes autorisé à :
|
||||
- **Utiliser** ce travail à des fins personnelles et non commerciales.
|
||||
- **Modifier** et adapter ce travail pour vos propres besoins.
|
||||
- **Partager** ce travail sous la même licence, en mentionnant l'auteur original.
|
||||
|
||||
### Attribution
|
||||
Toute réutilisation, distribution ou modification de ce travail doit inclure une mention claire de l’auteur original.
|
||||
Exemple : *"Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0"*.
|
||||
|
||||
## Usage Commercial
|
||||
L'utilisation de ce travail dans un cadre **commercial ou lucratif** (incluant, mais sans s'y limiter, les entreprises, services payants, et intégration dans des produits commerciaux) **n'est pas autorisée sans accord spécifique**.
|
||||
|
||||
Si vous souhaitez utiliser ce travail à des fins commerciales, veuillez me contacter pour établir une licence adaptée.
|
||||
|
||||
## Exclusions de Garantie
|
||||
Ce travail est fourni "tel quel", sans garantie d'aucune sorte. L'auteur ne pourra être tenu responsable d'éventuels dommages liés à son utilisation.
|
||||
|
||||
## Conformité avec la Directive NIS2
|
||||
Cette licence et l’utilisation des scripts et notes associés doivent être considérées dans le cadre de la **Directive NIS2** (Network and Information Security Directive 2). Les organisations utilisant ces matériaux dans leur cadre de cybersécurité doivent s’assurer de leur conformité avec NIS2, en particulier en ce qui concerne la gestion des risques, les obligations de déclaration et les mesures de sécurité. L’auteur ne saurait être tenu responsable d’éventuelles violations de conformité résultant de l’intégration ou de l’utilisation de ces matériaux.
|
||||
|
||||
De plus, bien que cette licence autorise une utilisation libre à des fins non commerciales, elle n’exempte pas les organisations de leurs obligations légales au titre de la **NIS2**. Les utilisateurs doivent évaluer si les modifications ou adaptations de ces matériaux ont un impact sur leurs exigences réglementaires et prendre les mesures nécessaires pour rester conformes.
|
||||
|
||||
## Informations Complémentaires
|
||||
Pour plus d’informations sur la licence CC BY-NC 4.0, consultez :
|
||||
[https://creativecommons.org/licenses/by-nc/4.0/](https://creativecommons.org/licenses/by-nc/4.0/)
|
||||
|
||||
26
README.md
26
README.md
@@ -6,39 +6,21 @@ Bienvenue dans le dépôt de **Notes Techniques**. Ce dépôt contient une colle
|
||||
|
||||
Le dépôt est organisé en différentes catégories pour faciliter la navigation :
|
||||
|
||||
- **Certification**
|
||||
- [Créer une autorité de certification (CA) privée](notes/certificats/creer_une_autorite_de_certification_CA_privee.md)
|
||||
|
||||
### PAS ENCORE RÉDIGÉES
|
||||
|
||||
- **Sécurité**
|
||||
- [Configurer un serveur web sécurisé](notes/securite/configurer_serveur_web_securise.md)
|
||||
- **DevOps**
|
||||
- [Automatiser les déploiements avec CI/CD](notes/devops/automatiser_deploiements_CI_CD.md)
|
||||
- [Utiliser Docker pour la gestion des conteneurs](notes/devops/utiliser_docker_pour_conteneurs.md)
|
||||
- **Développement**
|
||||
- [Optimiser les performances des applications web](notes/developpement/optimisation_performances_applications_web.md)
|
||||
- [Sécuriser les applications avec des pratiques de codage sécurisé](notes/developpement/pratiques_codage_securise.md)
|
||||
- **Bases de données**
|
||||
- [Introduction aux bases de données NoSQL](notes/bases_de_donnees/introduction_bases_donnees_NoSQL.md)
|
||||
- **Agile**
|
||||
- [Meilleures pratiques pour le développement agile](notes/agile/meilleures_pratiques_developpement_agile.md)
|
||||
- **Outils**
|
||||
- [Guide de survie en ligne de commande](notes/outils/guide_survie_ligne_commande.md)
|
||||
- [Consulter le fichier FILES](FILES.md)
|
||||
|
||||
## Contribuer
|
||||
|
||||
Les contributions sont les bienvenues ! Si vous avez des suggestions, des corrections ou de nouvelles notes à ajouter, veuillez suivre les étapes suivantes :
|
||||
|
||||
1. **Fork le dépôt**
|
||||
2. **Cloner votre fork** : `git clone https://github.com/votre-utilisateur/votre-repo.git`
|
||||
2. **Cloner votre fork** : `git clone https://xxxx/votre-utilisateur/votre-repo.git`
|
||||
3. **Créer une branche** : `git checkout -b ma-nouvelle-branche`
|
||||
4. **Faire des modifications**
|
||||
5. **Commits** : `git add .` puis `git commit -m "Ajouter une nouvelle note sur [sujet]"`
|
||||
6. **Pousser votre branche** : `git push origin ma-nouvelle-branche`
|
||||
7. **Créer une Pull Request**
|
||||
|
||||
Pour plus de détails, veuillez lire le fichier [CONTRIBUTING.md](contribute.md).
|
||||
Pour plus de détails, veuillez lire le fichier [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
## Code de Conduite
|
||||
|
||||
@@ -46,7 +28,7 @@ Pour garantir un environnement ouvert et accueillant, nous avons adopté un code
|
||||
|
||||
## Licence
|
||||
|
||||
Ce projet est sous licence MIT. Voir le fichier [LICENSE](LICENSE) pour plus de détails.
|
||||
Voir le fichier [LICENCE](LICENCE.md) et [LICENCE en Français](LICENCE_FR.md) pour plus de détails.
|
||||
|
||||
## Remerciements
|
||||
|
||||
|
||||
40
check_links.sh
Executable file
40
check_links.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Temporaire pour les résultats des liens brisés
|
||||
BROKEN_LINKS=$(mktemp)
|
||||
|
||||
# Fonction pour vérifier les liens
|
||||
check_links() {
|
||||
local file=$1
|
||||
local base_dir=$(dirname "$file")
|
||||
|
||||
# Cherche les liens vers les fichiers .md
|
||||
grep -o '\[.*\](.*\.md)' "$file" | while read -r link; do
|
||||
# Extraire le chemin du fichier lié
|
||||
linked_file=$(echo "$link" | sed 's/^.*(\(.*\))$/\1/')
|
||||
|
||||
# Résoudre le chemin relatif
|
||||
resolved_path=$(realpath -m "$base_dir/$linked_file")
|
||||
|
||||
# Vérifie si le fichier lié existe
|
||||
if [ ! -f "$resolved_path" ]; then
|
||||
echo "Lien brisé dans $file: $linked_file (résolu en $resolved_path)" >> "$BROKEN_LINKS"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Répertorie tous les fichiers .md dans le dépôt
|
||||
find . -type f -name "*.md" ! -name "README.md" | while read -r file; do
|
||||
check_links "$file"
|
||||
done
|
||||
|
||||
# Affiche les liens brisés
|
||||
if [ -s "$BROKEN_LINKS" ]; then
|
||||
echo "Les liens brisés suivants ont été trouvés :"
|
||||
cat "$BROKEN_LINKS"
|
||||
else
|
||||
echo "Aucun lien brisé trouvé."
|
||||
fi
|
||||
|
||||
# Nettoyage
|
||||
rm "$BROKEN_LINKS"
|
||||
@@ -1,49 +0,0 @@
|
||||
# Contribuer au Projet
|
||||
|
||||
Merci de votre intérêt pour contribuer à ce projet ! Vos contributions sont essentielles pour améliorer ce dépôt de notes techniques. Voici quelques lignes directrices pour vous aider à démarrer.
|
||||
|
||||
## Comment Contribuer
|
||||
|
||||
1. **Fork le dépôt** : Cliquez sur le bouton "Fork" en haut à droite de la page pour créer une copie de ce dépôt dans votre compte Git (GitHub, GitLab, Gitea ...).
|
||||
|
||||
2. **Cloner votre fork** : Clonez le dépôt forké sur votre machine locale.
|
||||
```bash
|
||||
git clone https://github.com/votre-utilisateur/votre-repo.git
|
||||
```
|
||||
|
||||
3. **Créer une branche** : Créez une nouvelle branche pour votre fonctionnalité ou correction.
|
||||
```bash
|
||||
git checkout -b ma-nouvelle-branche
|
||||
```
|
||||
|
||||
4. **Faire des modifications** : Apportez vos modifications ou ajoutez de nouvelles notes techniques dans la structure de dossiers appropriée.
|
||||
|
||||
5. **Commits** : Faites des commits de vos modifications avec des messages clairs et concis.
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Ajouter une nouvelle note sur [sujet]"
|
||||
```
|
||||
|
||||
6. **Pousser votre branche** : Poussez votre branche vers votre dépôt forké.
|
||||
```bash
|
||||
git push origin ma-nouvelle-branche
|
||||
```
|
||||
|
||||
7. **Créer une Pull Request** : Allez sur la page de votre dépôt forké sur GitHub et cliquez sur "New Pull Request". Décrivez vos modifications dans la description de la Pull Request.
|
||||
|
||||
## Lignes Directrices pour les Contributions
|
||||
|
||||
- **Clarté et précision** : Assurez-vous que vos notes sont claires, précises et faciles à suivre.
|
||||
- **Formatage** : Utilisez le format Markdown pour rédiger vos notes. Utilisez des titres, des sous-titres, des listes et du code formaté pour une meilleure lisibilité.
|
||||
- **Consistance** : Suivez le même style et les mêmes conventions que les autres notes du dépôt.
|
||||
- **Licences et droits d'auteur** : Assurez-vous que votre contribution n'enfreint aucun droit d'auteur. Mentionnez les sources si vous vous basez sur des travaux existants.
|
||||
|
||||
## Suggestions et Discussions
|
||||
|
||||
Si vous avez des idées, des suggestions ou des questions, n'hésitez pas à ouvrir une issue. Nous encourageons les discussions et le brainstorming pour améliorer ce projet.
|
||||
|
||||
## Code de Conduite
|
||||
|
||||
En contribuant à ce projet, vous acceptez de respecter notre [Code de Conduite](code_of_conduct.md). Veuillez lire ce document pour comprendre les comportements que nous attendons et ceux que nous n'acceptons pas.
|
||||
|
||||
Merci de votre contribution !
|
||||
@@ -1,6 +1,6 @@
|
||||
# Créer une autorité de certification (CA) privée
|
||||
|
||||
Cédric Abonnel - 2024-07-21
|
||||
Cédrix - 2024-07-21
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -116,7 +116,7 @@ Email Address []: john.doe@example.com
|
||||
|
||||
En suivant ces indications, vous aurez correctement configuré les informations de votre CA privée pour un usage personnel.
|
||||
|
||||
Le certificat créé (`ca.crt`) sera valide pendant 10 ans (3650 jours).
|
||||
Le certificat créé (`ca.crt`) sera valide pendant 10 ans (3650 jours).
|
||||
|
||||
En suivant ces étapes, vous aurez configuré une structure de base pour votre CA privée sur Debian 12, prête à émettre et gérer des certificats au sein de votre infrastructure.
|
||||
|
||||
@@ -424,4 +424,20 @@ En suivant ces étapes, vous pourrez révoquer des certificats compromis ou obso
|
||||
|
||||
## Références
|
||||
|
||||
https://ca-ra.org/fr/comment-installer-et-configurer-une-autorit%C3%A9-de-certification-ca-sur-ubuntu-20-04/
|
||||
1. **Cyklodev** :
|
||||
- Ce guide fournit des instructions détaillées sur la création d'une clé privée, la génération d'une demande de signature de certificat (CSR), la vérification de la demande, et la signature du certificat avec OpenSSL.
|
||||
- [Créer une autorité de certification avec OpenSSL](https://sysadmin.cyklodev.com)
|
||||
|
||||
2. **CA-RA** :
|
||||
- Ce site explique comment installer et configurer une autorité de certification sur Ubuntu 20.04, en utilisant Easy-RSA pour générer les fichiers de certificats publics et privés nécessaires, ainsi que les étapes pour distribuer ces certificats.
|
||||
- [Comment installer et configurer une autorité de certification sur Ubuntu 20.04](https://ca-ra.org/fr/comment-installer-et-configurer-une-autorit%C3%A9-de-certification-ca-sur-ubuntu-20-04/)
|
||||
|
||||
3. **Aymeric Cucherousset** :
|
||||
- Ce guide aborde la création d'une autorité de certification sous Debian, en détaillant la création du répertoire de la CA, la génération des clés et certificats, ainsi que l'installation des certificats sur diverses plateformes.
|
||||
- [Créer une autorité de certification](https://aymeric-cucherousset.fr)
|
||||
|
||||
4. **Elao** :
|
||||
- Ce guide explique comment créer une clé et un certificat pour un serveur, ainsi que les étapes pour générer une requête de signature de certificat et signer cette requête avec l'autorité de certification.
|
||||
- [Créer une autorité de certification et des certificats SSL auto-signés](https://www.elao.com)
|
||||
|
||||
|
||||
|
||||
88
notes/creer-une-cle-avec-gpg.md
Normal file
88
notes/creer-une-cle-avec-gpg.md
Normal file
@@ -0,0 +1,88 @@
|
||||
### ✅ **Résumé des commandes pour créer une clé GPG avec une sous-clé sur Debian**
|
||||
|
||||
---
|
||||
|
||||
## **1️⃣ Générer une clé principale avec une sous-clé automatique**
|
||||
```bash
|
||||
gpg --full-generate-key
|
||||
```
|
||||
- Choisissez **RSA and RSA (par défaut)**
|
||||
- Sélectionnez **4096 bits** (plus sécurisé)
|
||||
- Définissez la durée de validité (**ex: 2y pour 2 ans, 0 pour illimité**)
|
||||
- Renseignez **Nom, Email et un commentaire (facultatif)**
|
||||
- Définissez un **mot de passe sécurisé** pour protéger votre clé
|
||||
|
||||
🔹 **Résultat** :
|
||||
GPG crée **une clé principale** (pour signer/certifier) et **une sous-clé** (pour chiffrer les messages).
|
||||
|
||||
---
|
||||
|
||||
## **2️⃣ Vérifier la clé et la sous-clé**
|
||||
```bash
|
||||
gpg --list-keys
|
||||
```
|
||||
Vous devriez voir quelque chose comme :
|
||||
```
|
||||
pub rsa4096 2025-03-13 [SC]
|
||||
B8423648B0F61354C04C06CD45E9DF477F0EC7A5
|
||||
uid [ultimate] Donald Duck <donald@duck.com>
|
||||
sub rsa4096 2025-03-13 [E]
|
||||
```
|
||||
- `pub` = **Clé principale** (Sign & Certify)
|
||||
- `sub` = **Sous-clé** (Encryption)
|
||||
|
||||
---
|
||||
|
||||
## **3️⃣ Ajouter une nouvelle sous-clé (facultatif)**
|
||||
Si vous voulez **ajouter une sous-clé manuellement**, exécutez :
|
||||
```bash
|
||||
gpg --edit-key B8423648B0F61354C04C06CD45E9DF477F0EC7A5
|
||||
```
|
||||
Puis, dans l’interface interactive :
|
||||
```text
|
||||
addkey
|
||||
```
|
||||
- Choisissez **RSA (4096 bits)**
|
||||
- Sélectionnez **Usage : E pour chiffrement, S pour signature, A pour authentification**
|
||||
- Définissez la **durée de validité**
|
||||
- Confirmez avec `save`
|
||||
|
||||
---
|
||||
|
||||
## **4️⃣ Exporter votre clé publique pour la partager**
|
||||
```bash
|
||||
gpg --armor --export donald@duck.com > public-key.asc
|
||||
```
|
||||
📤 **Envoyez ce fichier** aux personnes qui doivent vérifier vos signatures.
|
||||
|
||||
---
|
||||
|
||||
## **5️⃣ Exporter votre clé privée pour la sauvegarder (⚠️ Sécurisez-la !)**
|
||||
```bash
|
||||
gpg --export-secret-keys --armor donald@duck.com > private-key.asc
|
||||
```
|
||||
📌 **Ne partagez jamais cette clé !** Stockez-la en lieu sûr.
|
||||
|
||||
---
|
||||
|
||||
## **6️⃣ Envoyer votre clé publique à un serveur de clés**
|
||||
```bash
|
||||
gpg --keyserver hkps://keys.openpgp.org --send-keys B8423648B0F61354C04C06CD45E9DF477F0EC7A5
|
||||
```
|
||||
Cela permet aux autres d’obtenir votre clé pour vérifier vos signatures.
|
||||
|
||||
---
|
||||
|
||||
### 🎯 **Récapitulatif des commandes essentielles**
|
||||
| **Action** | **Commande** |
|
||||
|---------------------------------|-------------|
|
||||
| Générer une clé GPG | `gpg --full-generate-key` |
|
||||
| Voir les clés | `gpg --list-keys` |
|
||||
| Voir les clés secrètes | `gpg --list-secret-keys` |
|
||||
| Modifier une clé existante | `gpg --edit-key <ID_CLÉ>` |
|
||||
| Ajouter une sous-clé | `addkey` (dans `gpg --edit-key`) |
|
||||
| Exporter la clé publique | `gpg --armor --export <email> > public-key.asc` |
|
||||
| Exporter la clé privée (backup) | `gpg --export-secret-keys --armor <email> > private-key.asc` |
|
||||
| Publier la clé sur un serveur | `gpg --keyserver hkps://keys.openpgp.org --send-keys <ID_CLÉ>` |
|
||||
|
||||
---
|
||||
63
notes/linux/network_ipStatic.md
Normal file
63
notes/linux/network_ipStatic.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Configurer une IP statique
|
||||
|
||||
Cédrix - 2024-07-24
|
||||
|
||||
*#debian #network #bash*
|
||||
|
||||
---
|
||||
|
||||
Pour configurer une adresse IP statique sous Debian 12 on utilise le fichier `/etc/dhcpcd.conf`.
|
||||
|
||||
1. **Ouvrir le fichier `dhcpcd.conf`** :
|
||||
|
||||
Utilisez votre éditeur de texte préféré pour ouvrir le fichier de configuration `dhcpcd.conf`. Par exemple, avec `nano` :
|
||||
```sh
|
||||
sudo nano /etc/dhcpcd.conf
|
||||
```
|
||||
|
||||
2. **Ajouter la configuration de l'adresse IP statique** :
|
||||
|
||||
Il est crucial de noter que dans les systèmes Debian et autres distributions Linux, l'interface réseau par défaut n'est pas toujours nommée `eth0`. En fonction de la version du système d'exploitation et des règles de dénomination des interfaces réseau (comme celles introduites par `udev`), les interfaces réseau peuvent avoir des noms différents. Ces noms peuvent suivre divers schémas, tels que `enp3s0`, `ens33`, ou des noms plus spécifiques comme `enxb827eb7bd083`.
|
||||
|
||||
Les noms d'interface réseau peuvent varier pour plusieurs raisons :
|
||||
1. **Règles de dénomination prédictives** : Modern systems use predictable network interface names to make it easier to identify which interface is which. For example, `enp3s0` could indicate Ethernet (en), PCI bus (p), slot 3 (3), and port 0 (0).
|
||||
2. **Interfaces intégrées et périphériques USB** : Les interfaces réseau intégrées à la carte mère et les adaptateurs USB peuvent avoir des noms différents pour les distinguer des autres interfaces.
|
||||
3. **Ordre de détection** : L'ordre dans lequel les interfaces sont détectées au démarrage peut affecter leur dénomination.
|
||||
|
||||
Pour identifier le nom de votre interface réseau, vous pouvez utiliser la commande `ip` :
|
||||
|
||||
```sh
|
||||
ip link show
|
||||
```
|
||||
Cette commande listera toutes les interfaces réseau disponibles sur votre système avec leurs noms actuels.
|
||||
|
||||
Ajoutez ou modifiez la configuration pour votre interface réseau à la fin du fichier. Voici un exemple de configuration pour une interface appelée `eth0` :
|
||||
```sh
|
||||
interface eth0
|
||||
static ip_address=192.168.1.100/24
|
||||
static routers=192.168.1.1
|
||||
static domain_name_servers=9.9.9.9 8.8.8.8
|
||||
```
|
||||
|
||||
- `interface eth0` : Cette ligne spécifie l'interface réseau que vous configurez.
|
||||
- `static ip_address=192.168.1.100/24` : L'adresse IP statique et le masque de sous-réseau (24 correspond à 255.255.255.0).
|
||||
- `static routers=192.168.1.1` : L'adresse IP de la passerelle (généralement le routeur).
|
||||
- `static domain_name_servers=9.9.9.9 8.8.8.8` : Les serveurs DNS à utiliser (facultatif mais recommandé).
|
||||
|
||||
3. **Redémarrer le service `dhcpcd`** :
|
||||
|
||||
Après avoir enregistré les modifications, redémarrez le service `dhcpcd` pour appliquer la nouvelle configuration :
|
||||
```sh
|
||||
sudo systemctl restart dhcpcd
|
||||
```
|
||||
|
||||
4. **Vérifier la configuration** :
|
||||
|
||||
Pour vous assurer que l'adresse IP statique est correctement configurée, vous pouvez utiliser la commande `ip` ou `ifconfig` :
|
||||
```sh
|
||||
ip addr show eth0
|
||||
```
|
||||
ou
|
||||
```sh
|
||||
ifconfig eth0
|
||||
```
|
||||
@@ -0,0 +1,10 @@
|
||||
# Fail2Ban filter for postfix authentication failures
|
||||
[INCLUDES]
|
||||
before = common.conf
|
||||
|
||||
[Definition]
|
||||
_daemon = postfix/smtpd
|
||||
#failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
|
||||
failregex = warning: .*\[<HOST>\]: SASL LOGIN authentication failed
|
||||
improper command pipelining after CONNECT from .*\[<HOST>\]:
|
||||
ignoreregex =
|
||||
128
notes/serveur/_files/fail2ban/etc/fail2ban/filter.d/sshd.conf
Normal file
128
notes/serveur/_files/fail2ban/etc/fail2ban/filter.d/sshd.conf
Normal file
@@ -0,0 +1,128 @@
|
||||
[INCLUDES]
|
||||
|
||||
# Read common prefixes. If any customizations available -- read them from
|
||||
# common.local
|
||||
before = common.conf
|
||||
|
||||
[DEFAULT]
|
||||
|
||||
_daemon = sshd
|
||||
|
||||
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
|
||||
__pref = (?:(?:error|fatal): (?:PAM: )?)?
|
||||
# optional suffix (logged from several ssh versions) like " [preauth]"
|
||||
#__suff = (?: port \d+)?(?: \[preauth\])?\s*
|
||||
__suff = (?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*
|
||||
__on_port_opt = (?: (?:port \d+|on \S+)){0,2}
|
||||
# close by authenticating user:
|
||||
__authng_user = (?: (?:invalid|authenticating) user <F-USER>\S+|.*?</F-USER>)?
|
||||
|
||||
# for all possible (also future) forms of "no matching (cipher|mac|MAC|compression method|key exchange method|host key type) found",
|
||||
# see ssherr.c for all possible SSH_ERR_..._ALG_MATCH errors.
|
||||
__alg_match = (?:(?:\w+ (?!found\b)){0,2}\w+)
|
||||
|
||||
# PAM authentication mechanism, can be overridden, e. g. `filter = sshd[__pam_auth='pam_ldap']`:
|
||||
__pam_auth = pam_[a-z]+
|
||||
|
||||
[Definition]
|
||||
|
||||
prefregex = ^<F-MLFID>%(__prefix_line)s</F-MLFID>%(__pref)s<F-CONTENT>.+</F-CONTENT>$
|
||||
|
||||
cmnfailre = ^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \S+)?%(__suff)s$
|
||||
^User not known to the underlying authentication module for <F-USER>.*</F-USER> from <HOST>%(__suff)s$
|
||||
<cmnfailre-failed-pub-<publickey>>
|
||||
^Failed <cmnfailed> for (?P<cond_inv>invalid user )?<F-USER>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
|
||||
^<F-USER>ROOT</F-USER> LOGIN REFUSED FROM <HOST>
|
||||
^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> from <HOST>%(__suff)s$
|
||||
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because not listed in AllowUsers%(__suff)s$
|
||||
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because listed in DenyUsers%(__suff)s$
|
||||
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because not in any group%(__suff)s$
|
||||
^refused connect from \S+ \(<HOST>\)
|
||||
^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*3: .*: Auth fail%(__suff)s$
|
||||
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because a group is listed in DenyGroups%(__suff)s$
|
||||
^User <F-USER>\S+|.*?</F-USER> from
|
||||
|
||||
<HOST> not allowed because none of user's groups are listed in AllowGroups%(__suff)s$
|
||||
^<F-NOFAIL>%(__pam_auth)s\(sshd:auth\):\s+authentication failure;</F-NOFAIL>(?:\s+(?:(?:logname|e?uid|tty)=\S*)){0,4}\s+ruser=<F-ALT_USER>\S*</F-ALT_USER>\s+rhost=<HOST>(?:\s+user=<F-USER>\S*</F-USER>)?%(__suff)s$
|
||||
^maximum authentication attempts exceeded for <F-USER>.*</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?%(__suff)s$
|
||||
^User <F-USER>\S+|.*?</F-USER> not allowed because account is locked%(__suff)s
|
||||
^<F-MLFFORGET>Disconnecting</F-MLFFORGET>(?: from)?(?: (?:invalid|authenticating)) user <F-USER>\S+</F-USER> <HOST>%(__on_port_opt)s:\s*Change of username or service not allowed:\s*.*\[preauth\]\s*$
|
||||
^Disconnecting: Too many authentication failures(?: for <F-USER>\S+|.*?</F-USER>)?%(__suff)s$
|
||||
^<F-NOFAIL>Received <F-MLFFORGET>disconnect</F-MLFFORGET></F-NOFAIL> from <HOST>%(__on_port_opt)s:\s*11:
|
||||
<mdre-<mode>-other>
|
||||
^<F-MLFFORGET><F-MLFGAINED>Accepted \w+</F-MLFGAINED></F-MLFFORGET> for <F-USER>\S+</F-USER> from <HOST>(?:\s|$)
|
||||
|
||||
cmnfailed-any = \S+
|
||||
cmnfailed-ignore = \b(?!publickey)\S+
|
||||
cmnfailed-invalid = <cmnfailed-ignore>
|
||||
cmnfailed-nofail = (?:<F-NOFAIL>publickey</F-NOFAIL>|\S+)
|
||||
cmnfailed = <cmnfailed-<publickey>>
|
||||
|
||||
mdre-normal =
|
||||
# used to differentiate "connection closed" with and without `[preauth]` (fail/nofail cases in ddos mode)
|
||||
mdre-normal-other = ^<F-NOFAIL><F-MLFFORGET>(Connection closed|Disconnected)</F-MLFFORGET></F-NOFAIL> (?:by|from)%(__authng_user)s <HOST>(?:%(__suff)s|\s*)$
|
||||
|
||||
mdre-ddos = ^Did not receive identification string from <HOST>
|
||||
^kex_exchange_identification: (?:[Cc]lient sent invalid protocol identifier|[Cc]onnection closed by remote host)
|
||||
^Bad protocol version identification '.*' from <HOST>
|
||||
^<F-NOFAIL>SSH: Server;Ltype:</F-NOFAIL> (?:Authname|Version|Kex);Remote: <HOST>-\d+;[A-Z]\w+:
|
||||
^Read from socket failed: Connection <F-MLFFORGET>reset</F-MLFFORGET> by peer
|
||||
# same as mdre-normal-other, but as failure (without <F-NOFAIL>) and [preauth] only:
|
||||
mdre-ddos-other = ^<F-MLFFORGET>(Connection (?:closed|reset)|Disconnected)</F-MLFFORGET> (?:by|from)%(__authng_user)s <HOST>%(__on_port_opt)s\s+\[preauth\]\s*$
|
||||
|
||||
mdre-extra = ^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*14: No(?: supported)? authentication methods available
|
||||
^Unable to negotiate with <HOST>%(__on_port_opt)s: no matching <__alg_match> found.
|
||||
^Unable to negotiate a <__alg_match>
|
||||
^no matching <__alg_match> found:
|
||||
# part of mdre-ddos-other, but user name is supplied (invalid/authenticating) on [preauth] phase only:
|
||||
mdre-extra-other = ^<F-MLFFORGET>Disconnected</F-MLFFORGET>(?: from)?(?: (?:invalid|authenticating)) user <F-USER>\S+|.*?</F-USER> <HOST>%(__on_port_opt)s \[preauth\]\s*$
|
||||
|
||||
mdre-aggressive = %(mdre-ddos)s
|
||||
%(mdre-extra)s
|
||||
# mdre-extra-other is fully included within mdre-ddos-other:
|
||||
mdre-aggressive-other = %(mdre-ddos-other)s
|
||||
|
||||
# Parameter "publickey": nofail (default), invalid, any, ignore
|
||||
publickey = nofail
|
||||
# consider failed publickey for invalid users only:
|
||||
cmnfailre-failed-pub-invalid = ^Failed publickey for invalid user <F-USER>(?P<cond_user>\S+)|(?:(?! from ).)*?</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
|
||||
# consider failed publickey for valid users too (don't need RE, see cmnfailed):
|
||||
cmnfailre-failed-pub-any =
|
||||
# same as invalid, but consider failed publickey for valid users too, just as no failure (helper to get IP and user-name only, see cmnfailed):
|
||||
cmnfailre-failed-pub-nofail = <cmnfailre-failed-pub-invalid>
|
||||
# don't consider failed publickey as failures (don't need RE, see cmnfailed):
|
||||
cmnfailre-failed-pub-ignore =
|
||||
|
||||
cfooterre = ^<F-NOFAIL>Connection from</F-NOFAIL> <HOST>
|
||||
|
||||
failregex = %(cmnfailre)s
|
||||
<mdre-<mode>>
|
||||
%(cfooterre)s
|
||||
|
||||
# Parameter "mode": normal (default), ddos, extra or aggressive (combines all)
|
||||
# Usage example (for jail.local):
|
||||
# [sshd]
|
||||
# mode = extra
|
||||
# # or another jail (rewrite filter parameters of jail):
|
||||
# [sshd-aggressive]
|
||||
# filter = sshd[mode=aggressive]
|
||||
#
|
||||
mode = normal
|
||||
|
||||
#filter = sshd[mode=aggressive]
|
||||
|
||||
ignoreregex =
|
||||
|
||||
maxlines = 1
|
||||
|
||||
journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd
|
||||
|
||||
# DEV Notes:
|
||||
#
|
||||
# "Failed \S+ for .*? from <HOST>..." failregex uses non-greedy catch-all because
|
||||
# it is coming before use of <HOST> which is not hard-anchored at the end as well,
|
||||
# and later catch-all's could contain user-provided input, which need to be greedily
|
||||
# matched away first.
|
||||
#
|
||||
# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black and Sergey Brester aka sebres
|
||||
# Rewritten using prefregex (and introduced "mode" parameter) by Serg G. Brester.
|
||||
30
notes/serveur/_files/fail2ban/etc/fail2ban/jail.local
Normal file
30
notes/serveur/_files/fail2ban/etc/fail2ban/jail.local
Normal file
@@ -0,0 +1,30 @@
|
||||
[pureftpd]
|
||||
enabled = true
|
||||
port = ftp
|
||||
filter = pure-ftpd
|
||||
logpath = /var/log/syslog
|
||||
maxretry = 3
|
||||
|
||||
[postfix-sasl]
|
||||
enabled = true
|
||||
mode = auth
|
||||
logpath = /var/log/mail.log
|
||||
maxretry = 2
|
||||
bantime = 432000 # 5 jours en secondes
|
||||
findtime = 86400 # 24 heures en secondes
|
||||
banaction = iptables-allports
|
||||
|
||||
[apache-fakegooglebot]
|
||||
enabled = true
|
||||
logpath = /var/www/clients/client1/www.abonnel.fr/log/access.log
|
||||
maxretry = 3
|
||||
bantime = 86400
|
||||
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
bantime = 432000 # 5 jours en secondes
|
||||
maxretry = 3
|
||||
55
notes/serveur/_files/fail2ban/home/cedrix/ban-ip-sasl.php
Normal file
55
notes/serveur/_files/fail2ban/home/cedrix/ban-ip-sasl.php
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
echo "-- Execution de ".__FILE__."\n";
|
||||
|
||||
// Créer des fichiers temporaires pour stocker les logs et les IPs
|
||||
$tempLog = trim(shell_exec('mktemp /tmp/fail2ban_temp.XXXXXX.log'));
|
||||
$banList = trim(shell_exec('mktemp /tmp/ban_ips.XXXXXX.txt'));
|
||||
|
||||
$logFile = "/var/log/mail.log";
|
||||
$filterFile = "/etc/fail2ban/filter.d/postfix-sasl.conf";
|
||||
|
||||
// Utiliser fail2ban-regex pour analyser le fichier de log et extraire les adresses IP correspondantes
|
||||
exec("sudo fail2ban-regex $logFile $filterFile --print-all-matched > $tempLog");
|
||||
|
||||
// Lire le fichier temporaire et extraire les adresses IP
|
||||
$logContent = file_get_contents($tempLog);
|
||||
preg_match_all('/\[\K[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(?=\])/', $logContent, $matches);
|
||||
|
||||
// Supprimer les doublons
|
||||
$ips = array_unique($matches[0]);
|
||||
|
||||
// Obtenir la liste des IP déjà bannies
|
||||
exec("sudo fail2ban-client status postfix-sasl", $output);
|
||||
$bannedIps = [];
|
||||
$bannedIpsFound = false;
|
||||
foreach ($output as $line) {
|
||||
if (strpos($line, 'Banned IP list:') !== false) {
|
||||
$bannedIpsFound = true;
|
||||
$bannedIps = array_merge($bannedIps, preg_split('/\s+/', trim($line)));
|
||||
} elseif ($bannedIpsFound && trim($line) !== '') {
|
||||
$bannedIps = array_merge($bannedIps, preg_split('/\s+/', trim($line)));
|
||||
}
|
||||
}
|
||||
|
||||
// Écrire les adresses IP dans un fichier temporaire
|
||||
file_put_contents($banList, implode("\n", $ips));
|
||||
|
||||
// Lire le fichier contenant les adresses IP et les bannir avec fail2ban-client
|
||||
foreach ($ips as $ip) {
|
||||
if (!in_array($ip, $bannedIps)) {
|
||||
echo "Banning IP: $ip\n";
|
||||
exec("sudo fail2ban-client set postfix-sasl banip $ip");
|
||||
}
|
||||
}
|
||||
|
||||
// Nettoyer les fichiers temporaires
|
||||
unlink($tempLog);
|
||||
unlink($banList);
|
||||
|
||||
echo "All matching IPs have been processed.\n";
|
||||
|
||||
echo "-- Fin d'exection de ".__FILE__."\n";
|
||||
|
||||
?>
|
||||
77
notes/serveur/_files/postfix/home/cedrix/delete_deferred.php
Normal file
77
notes/serveur/_files/postfix/home/cedrix/delete_deferred.php
Normal file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
echo "-- Debut de ".__FILE__."\n";
|
||||
|
||||
// Chemin vers le fichier de log
|
||||
$logFile = '/var/log/mail.log';
|
||||
// Chemin vers le fichier pour stocker les IDs traités
|
||||
$processedIdsFile = '/var/log/processed_ids_deferred.txt';
|
||||
|
||||
// Fonction pour lire les IDs traités à partir du fichier
|
||||
function readProcessedIds($file) {
|
||||
if (!file_exists($file)) {
|
||||
return [];
|
||||
}
|
||||
$content = file_get_contents($file);
|
||||
return $content ? explode(PHP_EOL, trim($content)) : [];
|
||||
}
|
||||
|
||||
// Fonction pour écrire les IDs traités dans le fichier
|
||||
function writeProcessedIds($file, $ids) {
|
||||
file_put_contents($file, implode(PHP_EOL, $ids) . PHP_EOL);
|
||||
}
|
||||
|
||||
// Lire les IDs déjà traités
|
||||
$processedIds = readProcessedIds($processedIdsFile);
|
||||
|
||||
// Expression régulière pour trouver les messages d'erreur spécifiques avec status=deferred et extraire l'ID du message
|
||||
$pattern = '/postfix\/smtp\[\d+\]: (\w+): .* status=deferred /';
|
||||
|
||||
// Lire le fichier de log
|
||||
$logContent = file_get_contents($logFile);
|
||||
|
||||
if ($logContent === false) {
|
||||
die("Erreur lors de la lecture du fichier de log.\n");
|
||||
}
|
||||
|
||||
// Rechercher les correspondances
|
||||
preg_match_all($pattern, $logContent, $matches);
|
||||
|
||||
// Extraire les IDs de message
|
||||
$messageIds = array_unique($matches[1]);
|
||||
|
||||
if (empty($messageIds)) {
|
||||
echo "Aucun message à supprimer de la file d'attente.\n";
|
||||
echo "-- Fin de ".__FILE__."\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Filtrer les IDs pour ne conserver que ceux qui n'ont pas encore été traités
|
||||
$newMessageIds = array_diff($messageIds, $processedIds);
|
||||
if (empty($newMessageIds)) {
|
||||
echo "Tous les messages ont déjà été traités.\n";
|
||||
echo "-- Fin de ".__FILE__."\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Supprimer les messages de la file d'attente
|
||||
foreach ($newMessageIds as $messageId) {
|
||||
$command = "postsuper -d $messageId";
|
||||
$output = [];
|
||||
$return_var = 0;
|
||||
exec($command, $output, $return_var);
|
||||
|
||||
if ($return_var === 0) {
|
||||
echo "Message $messageId supprimé de la file d'attente.\n";
|
||||
$processedIds[] = $messageId;
|
||||
} else {
|
||||
echo "Erreur lors de la suppression du message $messageId de la file d'attente.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Mettre à jour le fichier des IDs traités
|
||||
writeProcessedIds($processedIdsFile, $processedIds);
|
||||
|
||||
echo "-- Fin de ".__FILE__."\n";
|
||||
|
||||
192
notes/serveur/fail2ban-postfix-sasl.md
Normal file
192
notes/serveur/fail2ban-postfix-sasl.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Sécuriser Postfix avec fail2ban
|
||||
|
||||
Cédrix - 2024-07-24
|
||||
|
||||
#debian #postfix #fail2ban #php #bash
|
||||
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Le fichier [/etc/fail2ban/jail.local](_files/fail2ban/etc/fail2ban/jail.local) est un fichier de configuration pour [Fail2Ban](fail2ban.md) qui spécifie les "jails" à surveiller et les actions à entreprendre en cas de tentatives de connexion échouées ou malveillantes. Chaque jail est configurée pour surveiller un service particulier (comme SSH, Postfix, ou Pure-FTPd) en utilisant des fichiers de filtre définis dans des fichiers séparés, comme [/etc/fail2ban/filter.d/postfix-sasl.conf](_files/fail2ban/etc/fail2ban/filter.d/postfix-sasl.conf).
|
||||
|
||||
Pour renforcer la sécurité de nos services, nous allons configuré Fail2Ban pour surveiller et bloquer les tentatives de connexion malveillantes.
|
||||
|
||||
## Configurer les règles de filtrage postfix-sasl (Ban2Fail)
|
||||
|
||||
La configuration du fichier `/etc/fail2ban/filter.d/postfix-sasl.conf` pour Fail2Ban est utilisée pour détecter les échecs d'authentification SASL (Simple Authentication and Security Layer) dans les journaux de Postfix. Voici une explication détaillée de chaque section et ligne de ce fichier :
|
||||
|
||||
|
||||
- **[INCLUDES]** : Cette section permet d'inclure des configurations communes avant de traiter les définitions spécifiques à ce filtre.
|
||||
- **before = common.conf** : Inclut le fichier `common.conf` avant d'appliquer les définitions de ce fichier. `common.conf` contient des paramètres communs utilisés par plusieurs filtres.
|
||||
|
||||
- **[Definition]** : Cette section contient les définitions spécifiques au filtre.
|
||||
- **_daemon = postfix/smtpd** : Définit le démon à surveiller, ici `postfix/smtpd`, qui est le processus de réception de courrier de Postfix.
|
||||
|
||||
|
||||
- **failregex** : Cette directive définit les expressions régulières utilisées pour détecter les tentatives d'authentification échouées dans les journaux de Postfix.
|
||||
|
||||
Les expressions régulières suivantes sont définies :
|
||||
|
||||
1. `warning: .*\[<HOST>\]: SASL LOGIN authentication failed` :
|
||||
- Cette regex correspond aux lignes de journal qui contiennent un avertissement indiquant un échec d'authentification SASL LOGIN.
|
||||
- **<HOST>** est une variable utilisée par Fail2Ban pour capturer l'adresse IP de l'attaquant.
|
||||
|
||||
2. `improper command pipelining after CONNECT from .*\[<HOST>\]:` :
|
||||
- Cette regex correspond aux lignes de journal indiquant une tentative de connexion incorrecte après la commande CONNECT, souvent indicative de comportements suspects ou de tentatives de contournement des protocoles de sécurité.
|
||||
|
||||
|
||||
- **ignoreregex** : Cette directive permet de définir des expressions régulières pour ignorer certaines lignes des journaux, même si elles correspondent à `failregex`. Dans ce cas, `ignoreregex` est vide, ce qui signifie qu'aucune ligne n'est ignorée.
|
||||
|
||||
|
||||
## Tester les règle Fail2ban
|
||||
|
||||
`fail2ban-regex` offre un moyen puissant de valider, déboguer et optimiser les filtres Fail2Ban, assurant ainsi que seules les activités malveillantes sont détectées et bloquées.
|
||||
|
||||
L'utilisation de `fail2ban-regex` implique principalement deux éléments : le fichier de journal à analyser et le fichier de filtre contenant les expressions régulières. Voici comment vous pouvez l'utiliser :
|
||||
|
||||
```sh
|
||||
fail2ban-regex [fichier_journal] [fichier_filtre]
|
||||
```
|
||||
|
||||
### Exemple Pratique
|
||||
|
||||
Supposons que vous souhaitiez tester un filtre Fail2Ban pour les tentatives d'authentification échouées de Postfix SASL. Vous avez un fichier de journal `/var/log/mail.log` et un fichier de filtre `/etc/fail2ban/filter.d/postfix-sasl.conf`.
|
||||
|
||||
```sh
|
||||
sudo fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/postfix-sasl.conf
|
||||
```
|
||||
|
||||
Cette commande analysera le fichier de journal en utilisant les expressions régulières définies dans le fichier de filtre et affichera les résultats.
|
||||
|
||||
La sortie de `fail2ban-regex` est divisée en plusieurs sections :
|
||||
|
||||
1. **Summary** : Un résumé des lignes analysées, du nombre de correspondances trouvées et des lignes ignorées.
|
||||
2. **Success, Ignored, Missed** : Montre quelles lignes de journal ont été capturées avec succès par les expressions régulières, lesquelles ont été ignorées, et lesquelles ont été manquées.
|
||||
3. **Matches** : Affiche les correspondances spécifiques trouvées dans les journaux.
|
||||
4. **Lines** : Montre les lignes de journal exactes qui correspondent ou non aux expressions régulières.
|
||||
|
||||
|
||||
|
||||
## Automatisation de l'ajout d'adresses IP malveillantes
|
||||
|
||||
Comment automatiser l'ajout des adresses IP suspectes détectées dans les journaux de Postfix SASL à Fail2Ban, en utilisant un script PHP ? L'objectif est de renforcer la sécurité de votre serveur de messagerie en bloquant automatiquement les adresses IP qui tentent des connexions malveillantes et qui seraient passées à travers les mailles du filet.
|
||||
|
||||
Le script [ban_ip_sasl.php](_files/fail2ban/home/cedrix/ban-ip-sasl.php) est écrit en PHP et utilise Fail2Ban pour analyser les journaux de Postfix SASL, extraire les adresses IP malveillantes et les ajouter à la liste de bannissement.
|
||||
|
||||
### Revue de Code : Script PHP pour Automatiser le Bannissement des Adresses IP avec Fail2Ban
|
||||
|
||||
Ce script PHP vise à automatiser l'ajout d'adresses IP suspectes détectées dans les journaux de Postfix SASL à la liste de bannissement de Fail2Ban. Voici une revue de code détaillée, mettant en évidence les points forts, les aspects à améliorer et les suggestions pour une meilleure pratique.
|
||||
|
||||
#### Points Forts
|
||||
|
||||
1. **Automatisation Efficace** : Le script permet d'automatiser le processus de surveillance des journaux et de bannissement des IPs, réduisant ainsi la charge administrative.
|
||||
2. **Utilisation des Outils Existants** : Le script utilise `fail2ban-regex` et `fail2ban-client`, tirant parti des outils Fail2Ban pour extraire et gérer les adresses IP.
|
||||
3. **Gestion des Fichiers Temporaires** : La création et la suppression de fichiers temporaires permettent de traiter les données sans laisser de traces inutiles sur le système.
|
||||
4. **Vérification des IPs Déjà Bannies** : Avant de bannir une adresse IP, le script vérifie si elle est déjà bannie, évitant ainsi des opérations redondantes.
|
||||
|
||||
#### Aspects à Améliorer
|
||||
|
||||
1. **Utilisation de `exec` et `shell_exec`** : L'utilisation de ces fonctions peut poser des risques de sécurité si les entrées ne sont pas correctement échappées. Bien que ce script soit destiné à un usage interne, il est crucial de minimiser les risques d'injection de commandes.
|
||||
2. **Gestion des Erreurs** : Le script ne gère pas les erreurs potentielles de manière exhaustive. Par exemple, si `fail2ban-regex` ou `fail2ban-client` échoue, le script ne le détecte pas et continue son exécution.
|
||||
3. **Permissions** : L'exécution de commandes avec `sudo` nécessite que le script soit exécuté avec les privilèges appropriés. Une meilleure approche pourrait être d'exécuter le script en tant qu'utilisateur root directement, ou de configurer `sudo` pour permettre des commandes spécifiques sans mot de passe.
|
||||
4. **Validation des Entrées et des Sorties** : Avant d'exécuter les commandes, valider les chemins des fichiers et les entrées pour s'assurer qu'ils sont sûrs et existent.
|
||||
5. **Gestion des Erreurs** : Implémentez une gestion des erreurs robustes en vérifiant les codes de retour des commandes et en ajoutant des messages d'erreur appropriés.
|
||||
6. **Logging** : Ajouter des logs pour suivre les actions du script, ce qui facilite le débogage et la surveillance des opérations.
|
||||
7. **Sécurisation des Commandes** : Utiliser des fonctions PHP pour échapper correctement les arguments de commande et minimiser les risques d'injection.
|
||||
8. **Documentation** : Ajouter des commentaires détaillés et une documentation pour expliquer le fonctionnement du script et les prérequis nécessaires.
|
||||
|
||||
#### Exemple d'Amélioration pour la Gestion des Erreurs
|
||||
|
||||
Au lieu de :
|
||||
```php
|
||||
exec("sudo fail2ban-regex $logFile $filterFile --print-all-matched > $tempLog");
|
||||
```
|
||||
|
||||
Vous pouvez utiliser :
|
||||
```php
|
||||
$returnVar = 0;
|
||||
$output = [];
|
||||
exec("sudo fail2ban-regex " . escapeshellarg($logFile) . " " . escapeshellarg($filterFile) . " --print-all-matched > " . escapeshellarg($tempLog), $output, $returnVar);
|
||||
if ($returnVar !== 0) {
|
||||
echo "Erreur lors de l'exécution de fail2ban-regex.\n";
|
||||
exit(1);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Après 12 heures de fonctionnement, il y a plus de 388 adresses repertoriées.
|
||||
|
||||
```log
|
||||
Status for the jail: postfix-sasl
|
||||
|- Filter
|
||||
| |- Currently failed: 31
|
||||
| |- Total failed: 31
|
||||
| `- File list: /var/log/mail.log
|
||||
`- Actions
|
||||
|- Currently banned: 388
|
||||
|- Total banned: 388
|
||||
`- Banned IP list: x.x.x.x x.x.x.x x.x.x.x x.x.x.x x.x.x.x
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
### Retour d'expérience
|
||||
|
||||
Après seulement 12 heures de fonctionnement, le script a permis de répertorier plus de 388 adresses IP suspectes.
|
||||
|
||||
Ce résultat impressionnant laisse entrevoir la possibilité de développer un service en ligne qui centraliserait ces adresses IP suspectes à l'instar de [SpamHaus](https://spamhaus.org). Voici comment ce service pourrait fonctionner et les avantages qu'il apporterait :
|
||||
|
||||
1. **Centralisation des Données**
|
||||
- Le service recueillerait les adresses IP suspectes de différents serveurs et sources. Chaque serveur exécutant le script pourrait envoyer ses données à une base de données centralisée.
|
||||
|
||||
2. **Base de Données Partagée**
|
||||
- Les adresses IP recueillies seraient stockées dans une base de données accessible en ligne. Cette base de données serait régulièrement mise à jour et maintenue pour assurer la pertinence des informations.
|
||||
|
||||
3. **API d'Interrogation**
|
||||
- Un API (Application Programming Interface) permettrait une interaction avec les données. Cela faciliterait l'intégration avec d'autres systèmes de sécurité et permettrait une réponse rapide aux menaces potentielles.
|
||||
|
||||
4. **Rapports et Analyses**
|
||||
- Le service pourrait générer des rapports détaillés sur les tendances des attaques, les adresses IP les plus fréquentes, et les types d'attaques les plus courants. Ces informations seraient précieuses pour ajuster les stratégies de sécurité.
|
||||
|
||||
6. **Accès Sécurisé**
|
||||
- Pour garantir la sécurité et l'intégrité des données, l'accès à ce service en ligne serait restreint aux utilisateurs autorisés. Des mesures de sécurité, telles que l'authentification multi-facteurs, seraient mises en place.
|
||||
|
||||
|
||||
|
||||
## Vérifier la jail postfix-sasl (Fail2Ban)
|
||||
|
||||
L'utilisation de la commande `sudo fail2ban-client status postfix-sasl` est destinée à vérifier l'état du service Fail2Ban pour la jail spécifique `postfix-sasl`. Cette commande affiche des informations sur les adresses IP qui ont été bannies et les actions effectuées par Fail2Ban pour protéger le serveur de messagerie Postfix contre les tentatives de connexion SASL (Simple Authentication and Security Layer) échouées.
|
||||
|
||||
Voici comment cette commande fonctionne et ce que chaque partie signifie :
|
||||
|
||||
1. **sudo** : Exécute la commande avec des privilèges administratifs.
|
||||
2. **fail2ban-client** : Interface en ligne de commande pour interagir avec le service Fail2Ban.
|
||||
3. **status** : Paramètre de la commande Fail2Ban pour afficher l'état.
|
||||
4. **postfix-sasl** : Nom de la jail pour laquelle l'état est demandé.
|
||||
|
||||
### Exemple de sortie de la commande
|
||||
|
||||
Lors de l'exécution de la commande, la sortie pourrait ressembler à ceci :
|
||||
|
||||
```
|
||||
Status for the jail: postfix-sasl
|
||||
|- Filter
|
||||
| |- Currently failed: 3
|
||||
| |- Total failed: 124
|
||||
| `- File list: /var/log/mail.log
|
||||
`- Actions
|
||||
|- Currently banned: 2
|
||||
|- Total banned: 5
|
||||
`- Banned IP list: 192.168.1.100 192.168.1.101
|
||||
```
|
||||
|
||||
### Explication des résultats
|
||||
|
||||
- **Currently failed** : Nombre de tentatives de connexion échouées actuellement enregistrées.
|
||||
- **Total failed** : Nombre total de tentatives de connexion échouées depuis la dernière réinitialisation.
|
||||
- **File list** : Liste des fichiers de log surveillés pour détecter les tentatives de connexion échouées.
|
||||
- **Currently banned** : Nombre d'adresses IP actuellement bannies.
|
||||
- **Total banned** : Nombre total d'adresses IP bannies depuis la dernière réinitialisation.
|
||||
- **Banned IP list** : Liste des adresses IP actuellement bannies.
|
||||
|
||||
91
notes/serveur/fail2ban-sshd.md
Normal file
91
notes/serveur/fail2ban-sshd.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Sécuriser sshd avec fail2ban
|
||||
|
||||
Cédrix - 2024-07-24
|
||||
|
||||
#debian #sshd #fail2ban #php #bash
|
||||
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Le fichier [/etc/fail2ban/jail.local](_files/fail2ban/etc/fail2ban/jail.local) est un fichier de configuration pour Fail2Ban qui spécifie les "jails" à surveiller et les actions à entreprendre en cas de tentatives de connexion échouées ou malveillantes. Chaque jail est configurée pour surveiller un service particulier (comme SSH, Postfix, ou Pure-FTPd) en utilisant des fichiers de filtre définis dans des fichiers séparés, comme [/etc/fail2ban/filter.d/sshd.conf](_files/fail2ban/etc/fail2ban/filter.d/sshd.conf).
|
||||
|
||||
Pour renforcer la sécurité de nos services, nous allons configuré Fail2Ban pour surveiller et bloquer les tentatives de connexion malveillantes.
|
||||
|
||||
## Configurer les règles de filtrage sshd (Ban2Fail)
|
||||
|
||||
La configuration du fichier `/etc/fail2ban/filter.d/sshd.conf` pour Fail2Ban permet de définir les règles de filtrage des journaux SSH pour détecter et bloquer les tentatives de connexion malveillantes. Voici une explication détaillée des différentes sections et lignes de ce fichier :
|
||||
|
||||
### [INCLUDES]
|
||||
|
||||
Cette section inclut des configurations communes à partir du fichier `common.conf`. Cela permet de partager des paramètres communs entre plusieurs fichiers de configuration.
|
||||
|
||||
### [DEFAULT]
|
||||
|
||||
- **_daemon = sshd** : Définit le démon à surveiller, ici `sshd` (le serveur SSH).
|
||||
- **__pref** et **__suff** : Définit les préfixes et suffixes facultatifs qui peuvent apparaître dans les journaux SSH, pour tenir compte des variations entre différentes versions et configurations de SSH.
|
||||
- **__on_port_opt** : Définit des options supplémentaires pour le port, comme "port" ou "on".
|
||||
- **__authng_user** : Modèle pour les utilisateurs en cours d'authentification ou invalides.
|
||||
- **__alg_match** : Modèle pour les erreurs de correspondance d'algorithmes.
|
||||
- **__pam_auth** : Définit le mécanisme d'authentification PAM utilisé.
|
||||
|
||||
### [Definition]
|
||||
|
||||
- **prefregex** : Expression régulière pour identifier les lignes de log pertinentes.
|
||||
|
||||
- **cmnfailre** : Définit plusieurs expressions régulières pour détecter les échecs d'authentification communs, les utilisateurs invalides, les tentatives d'accès refusées, etc.
|
||||
|
||||
- **mdre-normal** : Modèles pour les messages normaux de déconnexion.
|
||||
- **mdre-ddos** : Modèles pour les tentatives de déni de service (DDoS).
|
||||
- **mdre-extra** : Modèles pour des erreurs supplémentaires spécifiques.
|
||||
- **mdre-aggressive** : Combine les modèles `ddos` et `extra`.
|
||||
|
||||
- **publickey** : Paramètre pour gérer les échecs d'authentification par clé publique.
|
||||
|
||||
- **failregex** : Définit les expressions régulières principales utilisées pour détecter les tentatives d'accès échouées.
|
||||
|
||||
- **mode** : Définit le mode de détection, qui peut être `normal`, `ddos`, `extra` ou `aggressive`.
|
||||
|
||||
- **journalmatch** : Filtre pour les journaux systemd, spécifique au service SSH (`sshd.service`).
|
||||
|
||||
|
||||
## Vérifier la jail sshd (Fail2Ban)
|
||||
|
||||
```
|
||||
sudo fail2ban-client status sshd
|
||||
```
|
||||
|
||||
La commande `sudo fail2ban-client status sshd` est utilisée pour vérifier l'état du service Fail2Ban pour la jail spécifique `sshd`. Cette jail est configurée pour protéger le serveur SSH contre les tentatives de connexion non autorisées ou échouées.
|
||||
|
||||
Voici comment cette commande fonctionne et ce que chaque partie signifie :
|
||||
|
||||
1. **sudo** : Exécute la commande avec des privilèges administratifs.
|
||||
2. **fail2ban-client** : Interface en ligne de commande pour interagir avec le service Fail2Ban.
|
||||
3. **status** : Paramètre de la commande Fail2Ban pour afficher l'état.
|
||||
4. **sshd** : Nom de la jail pour laquelle l'état est demandé.
|
||||
|
||||
### Exemple de sortie de la commande
|
||||
|
||||
Lors de l'exécution de la commande, la sortie pourrait ressembler à ceci :
|
||||
|
||||
```
|
||||
Status for the jail: sshd
|
||||
|- Filter
|
||||
| |- Currently failed: 2
|
||||
| |- Total failed: 56
|
||||
| `- File list: /var/log/auth.log
|
||||
`- Actions
|
||||
|- Currently banned: 1
|
||||
|- Total banned: 12
|
||||
`- Banned IP list: 203.0.113.45
|
||||
```
|
||||
|
||||
### Explication des résultats
|
||||
|
||||
- **Currently failed** : Nombre de tentatives de connexion échouées actuellement enregistrées.
|
||||
- **Total failed** : Nombre total de tentatives de connexion échouées depuis la dernière réinitialisation.
|
||||
- **File list** : Liste des fichiers de log surveillés pour détecter les tentatives de connexion échouées, généralement `/var/log/auth.log` pour SSH.
|
||||
- **Currently banned** : Nombre d'adresses IP actuellement bannies.
|
||||
- **Total banned** : Nombre total d'adresses IP bannies depuis la dernière réinitialisation.
|
||||
- **Banned IP list** : Liste des adresses IP actuellement bannies.
|
||||
|
||||
164
notes/serveur/fail2ban.md
Normal file
164
notes/serveur/fail2ban.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Sécuriser avec fail2ban
|
||||
|
||||
Cédrix - 2024-07-24
|
||||
|
||||
#debian #fail2ban #bash
|
||||
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Fail2Ban est un logiciel de sécurité conçu pour protéger les systèmes informatiques contre les attaques par force brute et d'autres comportements malveillants. Il fonctionne en surveillant les fichiers de journalisation des services et en prenant des mesures automatisées pour bloquer les adresses IP suspectes.
|
||||
|
||||
|
||||
### Fonctionnement de Fail2Ban
|
||||
|
||||
1. **Surveillance des journaux :**
|
||||
Fail2Ban surveille les fichiers de log des différents services sur un système, tels que SSH, Apache, Postfix, etc. Lorsqu'une tentative de connexion échouée ou un comportement suspect est détecté, il enregistre l'adresse IP de l'attaquant.
|
||||
|
||||
2. **Détection des attaques :**
|
||||
Grâce à des expressions régulières définies dans ses fichiers de configuration, Fail2Ban identifie les tentatives de connexion échouées, les erreurs d'authentification, et d'autres types de comportements malveillants.
|
||||
|
||||
3. **Actions automatisées :**
|
||||
Lorsque le nombre de tentatives échouées pour une adresse IP dépasse un certain seuil (défini dans la configuration), Fail2Ban peut prendre des mesures automatisées telles que :
|
||||
- Ajouter une règle au pare-feu pour bloquer l'adresse IP.
|
||||
- Envoyer des notifications par email à l'administrateur.
|
||||
- Exécuter des scripts personnalisés pour répondre à l'incident.
|
||||
|
||||
### Composants principaux de Fail2Ban
|
||||
|
||||
1. **Fail2Ban Server :**
|
||||
Le serveur Fail2Ban est le processus principal qui exécute les actions de surveillance et de blocage. Il lit les fichiers de configuration, surveille les journaux et applique les actions définies.
|
||||
|
||||
2. **Fail2Ban Client :**
|
||||
Le client Fail2Ban est une interface en ligne de commande qui permet aux utilisateurs d'interagir avec le serveur Fail2Ban. Il est utilisé pour vérifier l'état des jails, débloquer des adresses IP, redémarrer le serveur Fail2Ban, etc.
|
||||
|
||||
3. **Fichiers de configuration :**
|
||||
Les fichiers de configuration de Fail2Ban se trouvent généralement dans le répertoire `/etc/fail2ban/`. Ils incluent :
|
||||
- **jail.conf** et **jail.local** : Définissent les jails et les paramètres globaux.
|
||||
- **filter.d/** : Contient les filtres spécifiques aux services, qui définissent les expressions régulières pour détecter les comportements suspects.
|
||||
- **action.d/** : Contient les actions spécifiques que Fail2Ban peut prendre lorsqu'une attaque est détectée.
|
||||
|
||||
### Processus de blocage
|
||||
|
||||
1. **Détection :**
|
||||
Fail2Ban utilise les filtres définis pour analyser les journaux des services. Lorsqu'une ligne correspondant à une tentative de connexion échouée ou à une erreur d'authentification est trouvée, elle est enregistrée.
|
||||
|
||||
2. **Comptage des tentatives :**
|
||||
Fail2Ban garde une trace du nombre de tentatives échouées pour chaque adresse IP. Si le nombre de tentatives échouées dépasse le seuil défini (par exemple, 3 tentatives), l'adresse IP est considérée comme suspecte.
|
||||
|
||||
3. **Application des actions :**
|
||||
Une fois qu'une adresse IP est identifiée comme suspecte, Fail2Ban applique les actions définies dans sa configuration. Cela peut inclure l'ajout d'une règle au pare-feu pour bloquer l'adresse IP pendant une certaine période.
|
||||
|
||||
### Avantages de Fail2Ban
|
||||
|
||||
1. **Automatisation :**
|
||||
Fail2Ban permet de bloquer automatiquement les adresses IP suspectes sans intervention manuelle, réduisant ainsi la charge de travail des administrateurs système.
|
||||
|
||||
2. **Personnalisation :**
|
||||
Les fichiers de configuration de Fail2Ban sont hautement personnalisables, permettant aux administrateurs de définir des règles spécifiques pour chaque service et de configurer les actions à prendre en cas d'attaque.
|
||||
|
||||
3. **Extensibilité :**
|
||||
Fail2Ban peut être étendu pour surveiller n'importe quel service qui génère des journaux en texte clair, en ajoutant simplement des filtres et des jails appropriés.
|
||||
|
||||
4. **Protection en temps réel :**
|
||||
Fail2Ban fournit une protection en temps réel contre les attaques par force brute et d'autres comportements malveillants, améliorant ainsi la sécurité globale du système.
|
||||
|
||||
|
||||
## Installer Fail2Ban sous Debian 12
|
||||
|
||||
Pour installer Fail2Ban sous Debian 12, suivez les étapes ci-dessous :
|
||||
|
||||
### Étape 1 : Mettre à jour les paquets
|
||||
|
||||
Avant d'installer Fail2Ban, il est recommandé de mettre à jour la liste des paquets et les paquets installés sur votre système Debian. Ouvrez un terminal et exécutez les commandes suivantes :
|
||||
|
||||
```sh
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
```
|
||||
|
||||
### Étape 2 : Installer Fail2Ban
|
||||
|
||||
Installez le paquet Fail2Ban en utilisant `apt` :
|
||||
|
||||
```sh
|
||||
sudo apt install fail2ban -y
|
||||
```
|
||||
|
||||
### Étape 3 : Vérifier l'installation
|
||||
|
||||
Après l'installation, vérifiez que le service Fail2Ban est correctement installé et fonctionne en vérifiant son statut :
|
||||
|
||||
```sh
|
||||
sudo systemctl status fail2ban
|
||||
```
|
||||
|
||||
Vous devriez voir une sortie indiquant que le service Fail2Ban est actif et en cours d'exécution.
|
||||
|
||||
### Étape 4 : Configuration de base
|
||||
|
||||
1. **Créer un fichier de configuration local :**
|
||||
|
||||
Pour personnaliser la configuration de Fail2Ban sans modifier les fichiers de configuration par défaut, créez un fichier `jail.local` à partir du fichier de configuration par défaut `jail.conf` :
|
||||
|
||||
```sh
|
||||
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
|
||||
```
|
||||
|
||||
2. **Éditer le fichier `jail.local` :**
|
||||
|
||||
Ouvrez le fichier `jail.local` avec votre éditeur de texte préféré :
|
||||
|
||||
```sh
|
||||
sudo nano /etc/fail2ban/jail.local
|
||||
```
|
||||
|
||||
Apportez les modifications nécessaires pour configurer les jails que vous souhaitez activer. Par exemple, pour activer la protection SSH, recherchez la section `[sshd]` et définissez `enabled` à `true` :
|
||||
|
||||
```ini
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
```
|
||||
|
||||
Vous pouvez configurer d'autres options comme `maxretry`, `bantime`, et `findtime` selon vos besoins.
|
||||
|
||||
### Étape 5 : Redémarrer Fail2Ban
|
||||
|
||||
Après avoir modifié la configuration, redémarrez le service Fail2Ban pour appliquer les changements :
|
||||
|
||||
```sh
|
||||
sudo systemctl restart fail2ban
|
||||
```
|
||||
|
||||
### Étape 6 : Vérifier le statut des jails
|
||||
|
||||
Pour vérifier que vos jails sont correctement configurées et actives, utilisez la commande suivante :
|
||||
|
||||
```sh
|
||||
sudo fail2ban-client status
|
||||
```
|
||||
|
||||
Cette commande affichera un résumé des jails activées et leur statut.
|
||||
|
||||
### Étape 7 : Vérifier les logs de Fail2Ban
|
||||
|
||||
Pour vérifier que Fail2Ban fonctionne correctement et bannit les adresses IP malveillantes, consultez les logs de Fail2Ban :
|
||||
|
||||
```sh
|
||||
sudo tail -f /var/log/fail2ban.log
|
||||
```
|
||||
|
||||
## Autres articles
|
||||
|
||||
- [Sécuriser Postfix avec fail2ban](fail2ban-postfix-sasl.md)
|
||||
|
||||
- [Sécuriser sshd avec fail2ban](fail2ban-sshd.md)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
64
notes/serveur/postfix-delete-messages-deferred.md
Normal file
64
notes/serveur/postfix-delete-messages-deferred.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Automatisation de la Gestion des Messages Différés de Postfix
|
||||
|
||||
#debian #postfix #php #bash
|
||||
|
||||
---
|
||||
|
||||
L'objectif du script PHP [delete_deferred.php](_files/postfix/home/cedrix/delete_deferred.php) est de gérer automatiquement les messages de courrier électronique en attente dans la file d'attente de Postfix, spécifiquement ceux avec un statut `deferred` dans `/var/log/mail.log`. Le script identifie ces messages, les supprime de la file d'attente et garde une trace des messages dans déjà traités `/var/log/processed_ids_deferred.txt` pour éviter les traitements redondants.
|
||||
|
||||
## Fonctionnalités Principales
|
||||
|
||||
1. **Initialisation et Configuration**
|
||||
- Le script commence par définir les chemins vers le fichier de journal de Postfix et le fichier utilisé pour stocker les IDs des messages déjà traités.
|
||||
|
||||
2. **Lecture des IDs Traités**
|
||||
- Une fonction lit les IDs des messages déjà traités à partir d'un fichier de suivi, assurant que les messages ne sont pas traités plusieurs fois.
|
||||
|
||||
3. **Recherche des Messages Différés**
|
||||
- Utilise une expression régulière pour analyser le fichier de journal de Postfix et identifier les messages avec le statut `deferred`.
|
||||
|
||||
4. **Filtrage des Messages Non Traités**
|
||||
- Compare les IDs des messages trouvés dans le journal avec ceux déjà traités pour ne conserver que les nouveaux messages à traiter.
|
||||
|
||||
5. **Suppression des Messages de la File d'Attente**
|
||||
- Pour chaque nouveau message identifié, le script exécute la commande `postsuper -d` pour supprimer le message de la file d'attente.
|
||||
- Si la suppression est réussie, l'ID du message est ajouté à la liste des IDs traités.
|
||||
|
||||
6. **Mise à Jour du Fichier des IDs Traités**
|
||||
- Après avoir traité les nouveaux messages, le script met à jour le fichier de suivi avec les nouveaux IDs, garantissant qu'ils ne seront pas traités à nouveau lors de la prochaine exécution.
|
||||
|
||||
## Déroulement du Script
|
||||
|
||||
1. **Affichage de Début d'Exécution**
|
||||
- Le script commence par afficher un message indiquant son démarrage.
|
||||
|
||||
2. **Définition des Chemins des Fichiers**
|
||||
- Les variables `$logFile` et `$processedIdsFile` sont définies pour stocker les chemins vers les fichiers nécessaires.
|
||||
|
||||
3. **Fonctions de Lecture et Écriture**
|
||||
- Deux fonctions, `readProcessedIds` et `writeProcessedIds`, sont définies pour lire et écrire les IDs des messages traités.
|
||||
Le script utilise un fichier spécifique pour stocker les IDs des messages déjà traités. Ce fichier est situé à `/var/log/processed_ids_deferred.txt`.
|
||||
|
||||
4. **Lecture et Analyse du Journal**
|
||||
- Le fichier de journal de Postfix est lu, et les messages correspondant au statut `deferred` sont identifiés à l'aide d'une expression régulière.
|
||||
|
||||
5. **Traitement des Messages**
|
||||
- Les IDs des messages différés sont extraits et filtrés pour ne conserver que ceux qui n'ont pas encore été traités.
|
||||
- Pour chaque nouveau message, la commande `postsuper -d` est exécutée pour supprimer le message de la file d'attente.
|
||||
- Les IDs des messages réussis sont ajoutés à la liste des IDs traités.
|
||||
|
||||
6. **Mise à Jour des IDs Traités**
|
||||
- Le fichier des IDs traités est mis à jour avec les nouveaux IDs après le traitement.
|
||||
|
||||
7. **Affichage de Fin d'Exécution**
|
||||
- Le script affiche un message indiquant la fin de l'exécution.
|
||||
|
||||
## Avantages du Script
|
||||
|
||||
- **Automatisation** : Réduit la nécessité d'intervention manuelle pour gérer les messages différés dans Postfix.
|
||||
- **Efficacité** : Assure que les messages sont traités de manière efficace en évitant les traitements redondants.
|
||||
- **Traçabilité** : Garde une trace des messages déjà traités, ce qui facilite le suivi et la gestion des opérations.
|
||||
|
||||
## À consulter
|
||||
|
||||
- `postsuper`
|
||||
175
notes/serveur/postfix_block_spam.md
Normal file
175
notes/serveur/postfix_block_spam.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Comment Bloquer les Spams avec le Serveur Email Postfix
|
||||
|
||||
Cédrix - 2024-07-27
|
||||
|
||||
#debian #postfix
|
||||
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
L'augmentation des spams dans les courriers électroniques est un fléau moderne auquel chaque administrateur de serveur de messagerie doit faire face. Le serveur de messagerie Postfix, grâce à sa flexibilité et à sa puissance, offre plusieurs techniques pour combattre efficacement les courriers indésirables. Cet article s'inspire d'un billet de blog détaillant les méthodes pour stopper les spams avec Postfix, en se basant sur la version 3.5.25 de Postfix sur Debian 12.
|
||||
|
||||
## Analyse des Spams et Configuration de Postfix
|
||||
|
||||
Avant de plonger dans les configurations, il est essentiel de comprendre comment les spams se manifestent et d'analyser les logs des emails. Les logs de Postfix se trouvent généralement dans le fichier `/var/log/mail.log` et ses archives associées. Par exemple, un log peut révéler des tentatives de spam où l'expéditeur utilise des noms d'utilisateur trompeurs et des techniques pour contourner les filtres.
|
||||
|
||||
## Techniques de Filtrage de Spam
|
||||
|
||||
1. **Service Anvil de Postfix** : Introduit dans la version 2.2 de Postfix, le service Anvil permet de limiter les attaques par inondation de courriels en imposant des restrictions sur les erreurs et les connexions. Voici quelques paramètres clés :
|
||||
- `smtpd_error_sleep_time = 3s`
|
||||
- `smtpd_soft_error_limit = 5`
|
||||
- `smtpd_hard_error_limit = 10`
|
||||
- `smtpd_client_connection_count_limit = 5`
|
||||
- `smtpd_client_connection_rate_limit = 20`
|
||||
|
||||
2. **Restrictions SMTP** : Les restrictions SMTP peuvent être configurées pour filtrer les spams à différents niveaux de l'interaction SMTP. Voici quelques-unes des restrictions les plus efficaces :
|
||||
- `smtpd_helo_required = yes`
|
||||
- `disable_vrfy_command = yes`
|
||||
- `unverified_sender_reject_reason = Address verification failed`
|
||||
|
||||
3. **Étapes de Restrictions SMTP** : Postfix traite les restrictions dans un ordre prédéfini. Les étapes incluent :
|
||||
- `smtpd_client_restrictions`
|
||||
- `smtpd_helo_restrictions`
|
||||
- `smtpd_sender_restrictions`
|
||||
- `smtpd_recipient_restrictions`
|
||||
|
||||
## Exemple de Configuration
|
||||
|
||||
Voici un exemple de configuration des restrictions dans le fichier `main.cf` de Postfix :
|
||||
|
||||
```plaintext
|
||||
smtpd_relay_restrictions =
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_unknown_sender_domain,
|
||||
reject_unauth_destination
|
||||
|
||||
smtpd_recipient_restrictions =
|
||||
permit_mynetworks,
|
||||
reject_non_fqdn_helo_hostname,
|
||||
reject_non_fqdn_sender,
|
||||
reject_non_fqdn_recipient,
|
||||
reject_unknown_reverse_client_hostname,
|
||||
reject_invalid_helo_hostname,
|
||||
reject_unknown_helo_hostname,
|
||||
reject_unknown_sender_domain,
|
||||
reject_unknown_recipient_domain,
|
||||
check_recipient_access hash:/etc/postfix/recipient_access,
|
||||
check_helo_access hash:/etc/postfix/helo_checks,
|
||||
check_sender_access hash:/etc/postfix/sender_access,
|
||||
permit
|
||||
|
||||
smtpd_data_restrictions =
|
||||
reject_unauth_pipelining,
|
||||
permit
|
||||
```
|
||||
|
||||
Si vous n'avez pas l'intention de créer les fichiers `/etc/postfix/recipient_access`, `/etc/postfix/helo_checks` et `/etc/postfix/sender_access`, mettez les lignes en commentaire.
|
||||
|
||||
**## Explications des Restrictions
|
||||
|
||||
- **`smtpd_relay_restrictions`** : Contrôle les règles de relais des emails.
|
||||
- **`smtpd_recipient_restrictions`** : Filtre les destinataires des emails pour bloquer les domaines non valides ou inconnus.
|
||||
- **`smtpd_data_restrictions`** : Empêche le pipelining non autorisé des données, une technique souvent utilisée par les spams.
|
||||
|
||||
## Détails des Vérifications d'Accès
|
||||
|
||||
### `check_recipient_access`
|
||||
|
||||
Le paramètre `check_recipient_access` utilise un fichier de hachage pour définir des règles spécifiques pour les destinataires d'email. Ce fichier permet de rejeter les emails envoyés à certaines adresses obsolètes ou non valides.
|
||||
|
||||
**Configuration du fichier de hachage**
|
||||
|
||||
Le fichier `/etc/postfix/recipient_access` doit être créé et rempli avec les adresses et les actions associées. Exemple de contenu :
|
||||
|
||||
```plaintext
|
||||
holly@brackin.net 550 Mailbox doesn't exist.
|
||||
anthony@brackin.net 550 Mailbox doesn't exist.
|
||||
peggy@brackin.net 550 Mailbox doesn't exist.
|
||||
gute@brackin.net 550 Mailbox doesn't exist.
|
||||
```
|
||||
|
||||
Chaque entrée suit le format : `adresse_destinataire action`, où l'action peut être de rejeter avec un code d'erreur spécifique (ici, 550 indiquant que la boîte aux lettres n'existe pas).
|
||||
|
||||
**Mise en place du fichier de hachage**
|
||||
|
||||
Après avoir créé et édité le fichier, il faut générer le fichier de hachage avec la commande :
|
||||
|
||||
```bash
|
||||
postmap /etc/postfix/recipient_access
|
||||
```
|
||||
|
||||
Cette commande crée un fichier binaire `/etc/postfix/recipient_access.db` utilisé par Postfix pour effectuer des recherches rapides.
|
||||
|
||||
### `check_helo_access`
|
||||
|
||||
Le paramètre `check_helo_access` permet de vérifier les informations envoyées dans la commande HELO/EHLO. Il peut empêcher les spammeurs de se faire passer pour des domaines ou des adresses IP locales.
|
||||
|
||||
**Configuration du fichier de hachage**
|
||||
|
||||
Le fichier `/etc/postfix/helo_checks` doit être créé et rempli avec les valeurs HELO/EHLO et les actions associées. Exemple de contenu :
|
||||
|
||||
```plaintext
|
||||
# HELO'ing as being in our own domain(s)?
|
||||
grokshop.tv REJECT You are not in grokshop.tv
|
||||
brackin.net REJECT You are not in brackin.net
|
||||
|
||||
# HELO'ing with our IP address?
|
||||
198.58.109.26 REJECT You are not 198.58.109.26
|
||||
|
||||
# HELO'ing as "localhost?"
|
||||
localhost REJECT You are not me
|
||||
```
|
||||
|
||||
Chaque entrée suit le format : `valeur_HELO action`, où l'action peut être de rejeter avec un message spécifique.
|
||||
|
||||
**Mise en place du fichier de hachage**
|
||||
|
||||
Après avoir créé et édité le fichier, il faut générer le fichier de hachage avec la commande :
|
||||
|
||||
```bash
|
||||
postmap /etc/postfix/helo_checks
|
||||
```
|
||||
|
||||
Cette commande crée un fichier binaire `/etc/postfix/helo_checks.db` utilisé par Postfix pour effectuer des recherches rapides.
|
||||
|
||||
### `check_sender_access`
|
||||
|
||||
Le paramètre `check_sender_access` est utilisé pour filtrer les expéditeurs spécifiques. Par exemple, si une entreprise continue d'envoyer des emails à une adresse obsolète malgré les demandes de cessation, cette vérification peut bloquer ces expéditeurs.
|
||||
|
||||
**Configuration du fichier de hachage**
|
||||
|
||||
Le fichier `/etc/postfix/sender_access` doit être créé et rempli avec les domaines ou adresses expéditeurs et les actions associées. Exemple de contenu :
|
||||
|
||||
```plaintext
|
||||
draftkings.com REJECT
|
||||
draftkings.zendesk.com REJECT
|
||||
```
|
||||
|
||||
Chaque entrée suit le format : `domaine_expediteur action`, où l'action est de rejeter les emails provenant de ces domaines.
|
||||
|
||||
**Mise en place du fichier de hachage**
|
||||
|
||||
Après avoir créé et édité le fichier, il faut générer le fichier de hachage avec la commande :
|
||||
|
||||
```bash
|
||||
postmap /etc/postfix/sender_access
|
||||
```
|
||||
|
||||
Cette commande crée un fichier binaire `/etc/postfix/sender_access.db` utilisé par Postfix pour effectuer des recherches rapides.
|
||||
|
||||
## Autres Paramètres Importants
|
||||
|
||||
- **`smtpd_helo_required`** : Ce paramètre exige que le client s'identifie avec la commande HELO ou EHLO avant d'envoyer toute autre commande SMTP. Par défaut, il est désactivé (`no`), mais il est recommandé de l'activer (`yes`) pour améliorer la vérification des expéditeurs.
|
||||
- **`disable_vrfy_command`** : Désactive la commande VRFY, qui peut être utilisée par les spammeurs pour vérifier l'existence des adresses email sur le serveur. En la désactivant (`yes`), on réduit le risque d'énumération des utilisateurs.
|
||||
- **`unverified_sender_reject_reason`** : Permet de définir un message de rejet personnalisé pour les expéditeurs non vérifiés. Par exemple, `Address verification failed` est un message standard qui peut être utilisé.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Postfix est un outil extrêmement puissant pour gérer et bloquer les spams sans nécessiter de logiciels tiers comme SpamAssassin. La configuration des paramètres de restriction et l'analyse des logs permettent de réduire efficacement les courriers indésirables. En comprenant et en personnalisant les différentes options disponibles, les administrateurs peuvent protéger leurs serveurs de messagerie contre les attaques de spam tout en maintenant une flexibilité et une robustesse optimales. Pour les serveurs soumis à des volumes de spam très élevés, il peut être utile d'explorer l'utilisation de Postscreen, une fonctionnalité avancée de Postfix dédiée à la lutte contre le spam.
|
||||
|
||||
## Liens Utiles
|
||||
|
||||
- [Documentation officielle de Postfix](http://www.postfix.org/documentation.html)
|
||||
- [Tutoriels sur la configuration de Postfix](https://www.linode.com/docs/email/postfix/how-to-install-and-configure-postfix-on-debian-10/)
|
||||
@@ -0,0 +1,21 @@
|
||||
# Scimagic New Multi Frequency Universal Remote Control Duplicator
|
||||
|
||||
Best Copy Position
|
||||
|
||||
## Programming
|
||||
|
||||
### Standard
|
||||
|
||||
1. Press and hold button 1 and press button 2 four times at same time
|
||||
|
||||
2. Release 2 buttons LED fashed once every three seconds
|
||||
|
||||
3. Put original remote in te front of new remote (as closer as possible), press the orignial remote button which need to be copied until the LED of new remote flash quickly
|
||||
|
||||
(LED have regular flashes)
|
||||
|
||||
4. Press the button of New remote that you want to use to sav the code
|
||||
|
||||
5. if you do not copy successfully, please repeat above steps
|
||||
|
||||
6. To duplicate a second button, repeat the above steps
|
||||
@@ -0,0 +1,21 @@
|
||||
# Scimagic Nouvelle Télécommande Universelle Multi-Fréquence
|
||||
|
||||
Meilleure Position de Copie
|
||||
|
||||
## Programmation
|
||||
|
||||
### Standard
|
||||
|
||||
1. Appuyez et maintenez le bouton 1 tout en appuyant quatre fois sur le bouton 2 en même temps.
|
||||
|
||||
2. Relâchez les deux boutons, la LED clignote une fois toutes les trois secondes.
|
||||
|
||||
3. Placez la télécommande d'origine en face de la nouvelle télécommande (le plus proche possible), appuyez sur le bouton de la télécommande d'origine qui doit être copié jusqu'à ce que la LED de la nouvelle télécommande clignote rapidement.
|
||||
|
||||
(La LED a des clignotements réguliers)
|
||||
|
||||
4. Appuyez sur le bouton de la nouvelle télécommande que vous souhaitez utiliser pour enregistrer le code.
|
||||
|
||||
5. Si la copie n'est pas réussie, veuillez répéter les étapes ci-dessus.
|
||||
|
||||
6. Pour dupliquer un deuxième bouton, répétez les étapes ci-dessus.
|
||||
60
notes/webapps/clamav-avec-nextcloud.md
Normal file
60
notes/webapps/clamav-avec-nextcloud.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Rendre accessible Clamav à NextCloud
|
||||
|
||||
Cédrix - 2024-07-22
|
||||
|
||||
## Introduction
|
||||
|
||||
Vous avez raison de vous préoccuper de la sécurité en ouvrant `open_basedir` pour inclure `/usr/bin`. Permettre l'accès à ce répertoire peut exposer votre serveur à des risques potentiels, car cela donne à PHP l'accès à tous les exécutables de ce répertoire.
|
||||
|
||||
Voici quelques suggestions pour atténuer les risques de sécurité tout en permettant à votre programme PHP d'utiliser `clamscan` :
|
||||
|
||||
1. **Utiliser `clamscan` via un wrapper** : Au lieu d'ouvrir `/usr/bin` en entier, vous pourriez créer un script wrapper qui appelle `clamscan` et placer ce script dans un répertoire déjà inclus dans `open_basedir`. Par exemple, créez un script shell `/var/www/clients/client1/web8/web/clamscan_wrapper.sh` :
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
/usr/bin/clamscan "$@"
|
||||
```
|
||||
|
||||
Assurez-vous que ce script est exécutable :
|
||||
|
||||
```bash
|
||||
chmod +x /var/www/clients/client1/web8/web/clamscan_wrapper.sh
|
||||
```
|
||||
|
||||
Vous pouvez ensuite appeler ce script depuis PHP :
|
||||
|
||||
```php
|
||||
<?php
|
||||
$output = shell_exec('/var/www/clients/client1/web8/web/clamscan_wrapper.sh /path/to/file');
|
||||
echo $output;
|
||||
?>
|
||||
```
|
||||
|
||||
2. **Configurer les permissions de fichier** : Assurez-vous que seuls les utilisateurs nécessaires ont accès au script wrapper et aux fichiers qu'il scanne. Limitez les permissions autant que possible.
|
||||
|
||||
3. **Utiliser `suexec` ou `php-fpm`** : Si vous utilisez Apache, vous pouvez envisager de configurer `suexec` pour exécuter des scripts en tant qu'utilisateur spécifique, ce qui peut aider à limiter l'impact potentiel des failles de sécurité. Pour `php-fpm`, configurez des pools de processus avec des utilisateurs spécifiques pour chaque site ou application.
|
||||
|
||||
4. **Auditer et surveiller** : Mettez en place des mécanismes d'audit et de surveillance pour détecter toute activité suspecte. Les logs peuvent être très utiles pour repérer des comportements anormaux.
|
||||
|
||||
5. **Limiter l'accès réseau** : Assurez-vous que le serveur ne permet pas d'accès non autorisé depuis l'extérieur et utilisez un pare-feu pour limiter les connexions entrantes et sortantes.
|
||||
|
||||
Voici un exemple de script wrapper et de configuration PHP pour appeler `clamscan` :
|
||||
|
||||
### Script Wrapper (`/var/www/clients/client1/web8/web/clamscan_wrapper.sh`)
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
/usr/bin/clamscan "$@"
|
||||
```
|
||||
|
||||
### Code PHP
|
||||
|
||||
```php
|
||||
<?php
|
||||
$file_to_scan = '/path/to/file';
|
||||
$clamscan_output = shell_exec('/var/www/clients/client1/web8/web/clamscan_wrapper.sh ' . escapeshellarg($file_to_scan));
|
||||
echo $clamscan_output;
|
||||
?>
|
||||
```
|
||||
|
||||
En suivant ces pratiques, vous pouvez réduire les risques de sécurité associés à l'ouverture de `open_basedir` tout en permettant à votre programme PHP d'utiliser `clamscan`.
|
||||
7
scripts/.directories.txt
Normal file
7
scripts/.directories.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
all_inclusive
|
||||
common
|
||||
server-dhcp
|
||||
server-httpd
|
||||
server-mail
|
||||
server-mariadb
|
||||
server-postgres
|
||||
19
scripts/.generate_directories.sh
Executable file
19
scripts/.generate_directories.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Fichier de sortie
|
||||
OUTPUT_FILE=".directories.txt"
|
||||
|
||||
# Exclure certains dossiers si nécessaire (ex: .git, .github, autres fichiers spécifiques)
|
||||
EXCLUDE_DIRS=(".git" ".github") # Ajuste selon tes besoins
|
||||
|
||||
# Lister les dossiers à partir du répertoire actuel (ajuste si le script est exécuté ailleurs)
|
||||
find . -mindepth 1 -maxdepth 1 -type d | sed 's|./||' | sort > "$OUTPUT_FILE"
|
||||
|
||||
# Exclure les dossiers non souhaités
|
||||
for dir in "${EXCLUDE_DIRS[@]}"; do
|
||||
sed -i "/^$dir$/d" "$OUTPUT_FILE"
|
||||
done
|
||||
|
||||
echo "✅ Fichier '$OUTPUT_FILE' généré avec succès !"
|
||||
cat "$OUTPUT_FILE"
|
||||
26
scripts/.generate_list_files.sh
Executable file
26
scripts/.generate_list_files.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Nom du fichier de sortie
|
||||
OUTPUT_FILE=".list_files.txt"
|
||||
|
||||
# Fonction pour lister les fichiers dans un dossier donné
|
||||
list_files() {
|
||||
local dir="$1"
|
||||
local output="$dir/$OUTPUT_FILE"
|
||||
|
||||
# Nettoyage du fichier s'il existe déjà
|
||||
> "$output"
|
||||
|
||||
# Lister les fichiers dans le dossier courant (évite les répertoires) et trier
|
||||
find "$dir" -maxdepth 1 -type f ! -name "$OUTPUT_FILE" -print0 | sort -z | while IFS= read -r -d '' file; do
|
||||
echo "$(basename "$file")" >> "$output"
|
||||
done
|
||||
|
||||
echo "✅ Liste des fichiers générée dans $output"
|
||||
}
|
||||
|
||||
# Parcourir récursivement tous les dossiers sauf le dossier courant
|
||||
find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' dir; do
|
||||
list_files "$dir"
|
||||
done
|
||||
109
scripts/INSTALL.md
Normal file
109
scripts/INSTALL.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# 📥 Installation des scripts
|
||||
|
||||
Ce guide vous explique comment télécharger et exécuter les scripts d'installation et de configuration disponibles dans ce dépôt.
|
||||
|
||||
## 🛠 Prérequis
|
||||
Avant d'utiliser les scripts, assurez-vous de disposer des éléments suivants :
|
||||
- Un système Linux de type Debian
|
||||
- `git` installé si vous déployez avec GIT (sauf méthode 3)
|
||||
- Les droits administrateur (`sudo`)
|
||||
|
||||
## 🚀 Installation
|
||||
Vous avez trois options pour récupérer les scripts. La troisième est recommandée.
|
||||
|
||||
### 1️⃣ Cloner le dépôt
|
||||
Si vous souhaitez récupérer l'intégralité du projet, utilisez la commande suivante :
|
||||
```bash
|
||||
git clone https://git.abonnel.fr/cedricAbonnel/notes-techniques.git
|
||||
cd notes-techniques/scripts
|
||||
```
|
||||
|
||||
### 2️⃣ Télécharger uniquement un dossier spécifique
|
||||
Si vous ne souhaitez pas cloner tout le projet, utilisez Git sparse checkout :
|
||||
```bash
|
||||
git clone --depth 1 --filter=blob:none --sparse https://git.abonnel.fr/cedricAbonnel/notes-techniques.git
|
||||
cd notes-techniques
|
||||
git sparse-checkout add scripts/server-mail
|
||||
```
|
||||
Remplacez `server-mail` par le dossier du service que vous souhaitez installer.
|
||||
|
||||
### 3️⃣ Exécuter le script d'installation personnalisé (recommandé)
|
||||
Un script personnalisé permet de télécharger un ou plusieurs scripts en fonction des éléments sélectionnés. Il offre les avantages suivants :
|
||||
- Mise à jour automatique avec la dernière version disponible
|
||||
- Téléchargement sélectif des scripts depuis le dépôt
|
||||
- Interface interactive de sélection des scripts avec `whiptail`
|
||||
- Suppression des fichiers obsolètes
|
||||
- Application automatique des permissions d'exécution
|
||||
- Pas besoin d'avoir le programme `git`
|
||||
|
||||
---
|
||||
|
||||
# 🔄 Installation et mise à jour automatique des scripts
|
||||
|
||||
## 🛠 Prérequis
|
||||
Avant d'exécuter le script, assurez-vous que votre système répond aux exigences suivantes :
|
||||
- Système d'exploitation Linux
|
||||
- `bash` installé
|
||||
- `wget` installé
|
||||
- `whiptail` (inclus dans `dialog` sur certaines distributions)
|
||||
|
||||
Pour installer les dépendances, utilisez la commande suivante :
|
||||
```bash
|
||||
sudo apt update && sudo apt install -y wget dialog
|
||||
```
|
||||
(Sur une distribution utilisant `yum` ou `dnf`, adaptez la commande en conséquence.)
|
||||
|
||||
## 📥 Installation
|
||||
### 1️⃣ Télécharger le script
|
||||
```bash
|
||||
wget -O fetch_scripts.sh https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/scripts/fetch_scripts.sh
|
||||
```
|
||||
|
||||
### 2️⃣ Rendre le script exécutable
|
||||
```bash
|
||||
chmod +x fetch_scripts.sh
|
||||
```
|
||||
|
||||
### 3️⃣ Exécuter le script
|
||||
```bash
|
||||
./fetch_scripts.sh
|
||||
```
|
||||
|
||||
Accédez ensuite au dossier de votre choix et exécutez le script d'installation correspondant. Par exemple, pour installer un serveur de messagerie :
|
||||
```bash
|
||||
cd scripts/server-mail
|
||||
./setup_server.sh
|
||||
```
|
||||
Suivez ensuite les instructions affichées.
|
||||
|
||||
## ⚙️ Fonctionnement du script
|
||||
Le script permet de :
|
||||
- Se mettre à jour automatiquement en téléchargeant la dernière version disponible
|
||||
- Télécharger une liste de scripts depuis le dépôt
|
||||
- Offrir une interface interactive pour sélectionner les scripts à télécharger
|
||||
- Supprimer les fichiers obsolètes
|
||||
- Appliquer les permissions d'exécution aux scripts téléchargés
|
||||
|
||||
## 🔄 Mise à jour des scripts
|
||||
Le script se met à jour automatiquement à chaque exécution si une nouvelle version est disponible. Pour forcer une mise à jour, exécutez :
|
||||
```bash
|
||||
./fetch_scripts.sh
|
||||
```
|
||||
|
||||
## 🛠 Problèmes courants
|
||||
|
||||
- **Erreur : `whiptail: command not found`**
|
||||
- Installez `whiptail` avec la commande suivante :
|
||||
```bash
|
||||
sudo apt install dialog # ou sudo yum install dialog
|
||||
```
|
||||
|
||||
- **Erreur de connexion au dépôt**
|
||||
- Vérifiez votre connexion internet
|
||||
- Assurez-vous que l'URL du dépôt est correcte
|
||||
|
||||
## 📖 Support & Contribution
|
||||
Si vous rencontrez un problème ou souhaitez proposer une amélioration, consultez le fichier `CONTRIBUTING.md` ou ouvrez une issue sur le dépôt.
|
||||
|
||||
Bonne installation ! 🚀
|
||||
|
||||
24
scripts/README.md
Normal file
24
scripts/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 📌 Scripts d'installation et de configuration
|
||||
|
||||
Ce répertoire regroupe plusieurs familles de scripts permettant l'installation et la configuration de différents services sur un serveur.
|
||||
|
||||
## 📂 Structure du répertoire
|
||||
|
||||
Chaque sous-dossier contient une famille de scripts destinés à l'installation et à la configuration d'un service particulier :
|
||||
|
||||
- **`server-mail/`** : Scripts pour installer et configurer un serveur de messagerie.
|
||||
- **`server-httpd/`** : Scripts pour installer et configurer un serveur web (HTTPD).
|
||||
|
||||
## ⚙️ Utilisation
|
||||
|
||||
Consulter le document d'[installation](INSTALL.md).
|
||||
|
||||
## 🤝 Contribution
|
||||
|
||||
Vous pouvez ajouter de nouveaux scripts en respectant la structure existante et en documentant leur fonctionnement.
|
||||
Consulter le document de [contribution](../CONTRIBUTING.md) pour plus d'informations.
|
||||
|
||||
## 📜 Licence
|
||||
|
||||
Ce projet est sous licence [CC By-NC](../LICENSE.md). Vous trouverez plus d'explications dans la [note d'informations concernant la Licence en français](../LICENCE_FR.md).
|
||||
|
||||
1
scripts/all_inclusive/.list_files.txt
Normal file
1
scripts/all_inclusive/.list_files.txt
Normal file
@@ -0,0 +1 @@
|
||||
lychee_install.sh
|
||||
159
scripts/all_inclusive/lychee_install.sh
Normal file
159
scripts/all_inclusive/lychee_install.sh
Normal file
@@ -0,0 +1,159 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Vérifier que le script est lancé en root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Ce script doit être exécuté en tant que root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Définir les variables
|
||||
DB_NAME="lychee"
|
||||
DB_USER="lycheeuser"
|
||||
LYCHEE_DIR="/var/www/lychee"
|
||||
APACHE_CONF="/etc/apache2/sites-available/lychee.conf"
|
||||
PHP_VERSION="8.3"
|
||||
|
||||
PHP_INI_CLI="/etc/php/${PHP_VERSION}/cli/php.ini"
|
||||
PHP_INI_APACHE="/etc/php/${PHP_VERSION}/apache2/php.ini"
|
||||
|
||||
TIMEZONE=$(timedatectl show --value --property=Timezone)
|
||||
|
||||
# Générer un mot de passe alphanumérique sécurisé
|
||||
DB_PASSWORD=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 16)
|
||||
echo "Mot de passe généré pour la base de données : ${DB_PASSWORD}"
|
||||
|
||||
# Sauvegarde temporaire root-only
|
||||
echo "${DB_PASSWORD}" > /root/.lychee_db_password
|
||||
chmod 600 /root/.lychee_db_password
|
||||
|
||||
# Mise à jour du système
|
||||
apt update && apt upgrade -y
|
||||
|
||||
# Ajout du dépôt Sury pour PHP 8.3
|
||||
apt install -y apt-transport-https lsb-release ca-certificates wget gnupg2
|
||||
wget -qO - https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/php.gpg
|
||||
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
|
||||
apt update
|
||||
|
||||
# Installation des paquets nécessaires
|
||||
apt install -y apache2 mariadb-server php${PHP_VERSION} php${PHP_VERSION}-cli php${PHP_VERSION}-intl php${PHP_VERSION}-xmlrpc \
|
||||
php${PHP_VERSION}-soap php${PHP_VERSION}-mysql php${PHP_VERSION}-zip php${PHP_VERSION}-gd php${PHP_VERSION}-tidy \
|
||||
php${PHP_VERSION}-mbstring php${PHP_VERSION}-curl php${PHP_VERSION}-xml php${PHP_VERSION}-bcmath php${PHP_VERSION}-imagick \
|
||||
php${PHP_VERSION}-tokenizer libapache2-mod-php${PHP_VERSION} unzip
|
||||
|
||||
# Définir la timezone PHP pour CLI et Apache
|
||||
sed -i "s|^;*date.timezone =.*|date.timezone = ${TIMEZONE}|" "${PHP_INI_CLI}"
|
||||
sed -i "s|^;*date.timezone =.*|date.timezone = ${TIMEZONE}|" "${PHP_INI_APACHE}"
|
||||
|
||||
# Sécuriser MariaDB
|
||||
mysql_secure_installation <<EOF
|
||||
|
||||
y
|
||||
n
|
||||
y
|
||||
y
|
||||
y
|
||||
y
|
||||
EOF
|
||||
|
||||
# Créer la base et l'utilisateur avec droits restreints
|
||||
mysql <<EOF
|
||||
CREATE DATABASE ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
# Télécharger et installer Lychee proprement
|
||||
cd /tmp
|
||||
wget https://github.com/LycheeOrg/Lychee/releases/latest/download/Lychee.zip
|
||||
unzip Lychee.zip
|
||||
rm -rf ${LYCHEE_DIR}
|
||||
mv Lychee ${LYCHEE_DIR}
|
||||
rm Lychee.zip
|
||||
|
||||
# Demander le nom de domaine ou l'IP publique
|
||||
read -p "Entrez le nom de domaine ou l'adresse IP d'accès à Lychee (ex: lychee.mondomaine.fr ou 192.168.1.100) : " LYCHEE_HOST
|
||||
|
||||
# Forcer le protocole HTTP pour APP_URL
|
||||
APP_URL="http://${LYCHEE_HOST}"
|
||||
|
||||
# Modification du .env
|
||||
cp ${LYCHEE_DIR}/.env.example ${LYCHEE_DIR}/.env
|
||||
|
||||
sed -i "s|^APP_URL=.*|APP_URL=${APP_URL}|" ${LYCHEE_DIR}/.env
|
||||
sed -i "s|^DB_CONNECTION=.*|DB_CONNECTION=mysql|" ${LYCHEE_DIR}/.env
|
||||
sed -i "s|^DB_HOST=.*|DB_HOST=127.0.0.1|" ${LYCHEE_DIR}/.env
|
||||
sed -i "s|^DB_PORT=.*|DB_PORT=3306|" ${LYCHEE_DIR}/.env
|
||||
sed -i "s|^#*DB_DATABASE=.*|DB_DATABASE=${DB_NAME}|" ${LYCHEE_DIR}/.env
|
||||
sed -i "s|^#*DB_USERNAME=.*|DB_USERNAME=${DB_USER}|" ${LYCHEE_DIR}/.env
|
||||
sed -i "s|^#*DB_PASSWORD=.*|DB_PASSWORD=\"${DB_PASSWORD}\"|" ${LYCHEE_DIR}/.env
|
||||
|
||||
# Définir le fuseau horaire
|
||||
echo "APP_TIMEZONE=Europe/Paris" >> ${LYCHEE_DIR}/.env
|
||||
|
||||
# Propriétés et permissions
|
||||
chown -R www-data:www-data ${LYCHEE_DIR}
|
||||
chmod 640 ${LYCHEE_DIR}/.env
|
||||
find ${LYCHEE_DIR} -type f -exec chmod 640 {} \;
|
||||
find ${LYCHEE_DIR} -type d -exec chmod 750 {} \;
|
||||
|
||||
# Permissions spécifiques pour data/upload
|
||||
chmod -R 750 ${LYCHEE_DIR}/uploads/ ${LYCHEE_DIR}/data/
|
||||
|
||||
# Permissions spécifiques attendues par Lychee
|
||||
chmod -R g+s ${LYCHEE_DIR}/public/uploads
|
||||
chmod -R g+s ${LYCHEE_DIR}/public/sym
|
||||
chmod 2775 ${LYCHEE_DIR}/public/uploads
|
||||
chmod 2775 ${LYCHEE_DIR}/public/uploads/import
|
||||
chmod 2775 ${LYCHEE_DIR}/public/sym
|
||||
chmod 0664 ${LYCHEE_DIR}/public/uploads/import/index.html
|
||||
chmod 0664 ${LYCHEE_DIR}/public/sym/index.html
|
||||
chmod 2775 ${LYCHEE_DIR}/storage/tmp/jobs
|
||||
chmod 2775 ${LYCHEE_DIR}/storage/tmp/uploads
|
||||
chmod -R g+s ${LYCHEE_DIR}/storage/tmp/jobs
|
||||
chmod -R g+s ${LYCHEE_DIR}/storage/tmp/uploads
|
||||
|
||||
# Protéger les fichiers sensibles via .htaccess
|
||||
cat > ${LYCHEE_DIR}/.htaccess <<EOF
|
||||
<FilesMatch "\.(env|env\.example|sql|log|conf)$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</FilesMatch>
|
||||
EOF
|
||||
|
||||
# Configuration Apache
|
||||
cat > ${APACHE_CONF} <<EOF
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin webmaster@localhost
|
||||
DocumentRoot ${LYCHEE_DIR}/public
|
||||
|
||||
<Directory ${LYCHEE_DIR}/public>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog \${APACHE_LOG_DIR}/lychee_error.log
|
||||
CustomLog \${APACHE_LOG_DIR}/lychee_access.log combined
|
||||
|
||||
LimitRequestBody 10485760
|
||||
</VirtualHost>
|
||||
EOF
|
||||
|
||||
# Désactiver modules inutiles
|
||||
a2dismod -f autoindex status cgi userdir
|
||||
|
||||
# Activer Lychee et désactiver le site par défaut
|
||||
a2enmod rewrite
|
||||
a2ensite lychee.conf
|
||||
a2dissite 000-default.conf
|
||||
|
||||
# Recharger Apache
|
||||
systemctl reload apache2
|
||||
|
||||
# Déterminer l'IP locale
|
||||
IP=$(hostname -I | awk '{print $1}')
|
||||
|
||||
echo "Installation de Lychee terminée."
|
||||
echo "Accédez à l’interface web pour finaliser la configuration : http://${IP}"
|
||||
3
scripts/common/.list_files.txt
Normal file
3
scripts/common/.list_files.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
common_utils.sh
|
||||
setup_debian.sh
|
||||
setup_mdns.sh
|
||||
167
scripts/common/common_utils.sh
Normal file
167
scripts/common/common_utils.sh
Normal file
@@ -0,0 +1,167 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "❌ Ce script doit être exécuté en tant que root."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_token() {
|
||||
tr -dc 'A-Za-z0-9' < /dev/urandom | head -c "${1:-32}"
|
||||
echo
|
||||
}
|
||||
|
||||
update_system() {
|
||||
echo "=== Mise à jour du système ==="
|
||||
|
||||
# Mise à jour des paquets APT
|
||||
if command -v apt &> /dev/null; then
|
||||
echo "🔄 Mise à jour des paquets APT..."
|
||||
sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y && sudo apt clean
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Erreur lors de la mise à jour des paquets APT." >&2
|
||||
exit 1
|
||||
else
|
||||
echo "✅ Mise à jour terminée."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Mise à jour des paquets Flatpak si Flatpak est installé
|
||||
if command -v flatpak &> /dev/null; then
|
||||
echo "🔄 Mise à jour des paquets Flatpak..."
|
||||
flatpak update -y
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Erreur lors de la mise à jour des paquets Flatpak." >&2
|
||||
exit 1
|
||||
else
|
||||
echo "✅ Mise à jour terminée."
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Récupérer le nom d’hôte complet (FQDN) et le domaine
|
||||
get_fqdn_and_domain() {
|
||||
local fqdn domain
|
||||
|
||||
# Récupérer le FQDN en priorité avec hostname -f
|
||||
fqdn=$(hostname -f 2>/dev/null) || fqdn=$(cat /etc/hostname 2>/dev/null)
|
||||
|
||||
# Vérifier si la récupération du FQDN a réussi
|
||||
if [[ -z "$fqdn" ]]; then
|
||||
echo "❌ Erreur : Impossible de déterminer le FQDN" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extraire le domaine
|
||||
domain=${fqdn#*.}
|
||||
|
||||
echo "$fqdn" "$domain"
|
||||
}
|
||||
|
||||
|
||||
# Vérification de la résolution DNS
|
||||
check_dns() {
|
||||
local server_name=$1
|
||||
|
||||
# Récupération de l'adresse IP publique du serveur
|
||||
SERVER_IP=$(curl -4 -s ifconfig.me || hostname -I | awk '{print $1}')
|
||||
|
||||
# Récupération de l'adresse IP associée au FQDN
|
||||
FQDN_IP=$(dig +short A "$server_name" | tail -n1)
|
||||
|
||||
# Vérification si l'IP du FQDN est récupérable
|
||||
if [[ -z "$FQDN_IP" ]]; then
|
||||
echo "❌ Erreur : Impossible de récupérer l'adresse IP associée à $server_name via DIG."
|
||||
echo "➡️ Vérifie la configuration DNS et l'existence du domaine."
|
||||
return 1 # Erreur bloquante uniquement ici
|
||||
fi
|
||||
|
||||
# Comparaison des IPs mais uniquement en Alerte non bloquante
|
||||
if [[ "$SERVER_IP" != "$FQDN_IP" ]]; then
|
||||
echo "⚠️ Alerte DNS : L'adresse IP résolue ($FQDN_IP) ne correspond pas à l'IP publique actuelle ($SERVER_IP)."
|
||||
echo "➡️ Vérifie la configuration DNS et la propagation si nécessaire."
|
||||
else
|
||||
echo "✅ Vérification réussie : $server_name pointe correctement vers $SERVER_IP."
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
setup_ssl() {
|
||||
local fqdn=$1
|
||||
local le_dir="/etc/letsencrypt/live/$fqdn"
|
||||
|
||||
echo "=== Configuration du certificat SSL pour $fqdn ==="
|
||||
|
||||
if [[ -f "$le_dir/fullchain.pem" ]]; then
|
||||
echo "✅ Certificat SSL déjà existant."
|
||||
openssl x509 -noout -text -in "$le_dir/fullchain.pem" | grep "Not After"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "🔄 Test de génération d’un nouveau certificat SSL via HTTP..."
|
||||
|
||||
while true; do
|
||||
# Vérification que le dossier webroot existe
|
||||
webroot_path="/var/www/cedrix"
|
||||
if [[ ! -d "$webroot_path" ]]; then
|
||||
echo "❌ Le dossier $webroot_path n'existe pas. Apache n'a pas été installé..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔍 Test de génération de certificat via webroot ($webroot_path)..."
|
||||
|
||||
certbot certonly --webroot -w "$webroot_path" --dry-run -d "$fqdn" --non-interactive --agree-tos --register-unsafely-without-email
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "✅ Test réussi, génération réelle du certificat..."
|
||||
certbot certonly --webroot -w "$webroot_path" -d "$fqdn" --non-interactive --agree-tos --register-unsafely-without-email
|
||||
break
|
||||
else
|
||||
echo "⚠️ Échec du test via HTTP. Tentative via DNS..."
|
||||
echo "🔄 Test de génération d’un nouveau certificat SSL via challenge DNS..."
|
||||
echo "🛠️ Veuillez ajouter un enregistrement TXT pour _acme-challenge.$fqdn avec la valeur fournie par certbot."
|
||||
|
||||
while true; do
|
||||
certbot certonly --manual --preferred-challenges dns --dry-run -d "$fqdn" --non-interactive --agree-tos --register-unsafely-without-email
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "✅ Test DNS réussi. Veuillez maintenant ajouter le bon enregistrement TXT."
|
||||
echo "⏳ Appuyez sur une touche pour continuer après l'ajout de l'enregistrement TXT..."
|
||||
read -n 1 -s # Attente de l'appui sur une touche
|
||||
|
||||
# Génération réelle du certificat avec DNS challenge
|
||||
echo "✅ Génération réelle du certificat via challenge DNS..."
|
||||
certbot certonly --manual --preferred-challenges dns -d "$fqdn" --non-interactive --agree-tos --register-unsafely-without-email
|
||||
break 2 # Sort de la boucle interne ET de la boucle externe
|
||||
else
|
||||
echo "❌ Échec de la génération du certificat SSL avec toutes les méthodes."
|
||||
read -p "Voulez-vous interrompre le processus ? (o/n) : " choix
|
||||
if [[ "$choix" == "o" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
echo "✅ Certificat SSL généré avec succès."
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# Fonction pour récupérer et retourner les adresses IP de la machine
|
||||
get_server_ips() {
|
||||
local SERVER_IP SERVER_IPv6
|
||||
|
||||
SERVER_IP=$(curl -4 -s ifconfig.me || hostname -I | awk '{print $1}')
|
||||
SERVER_IPv6=$(curl -6 -s ifconfig.me || hostname -I | awk '{print $2}')
|
||||
|
||||
echo "$SERVER_IP" "$SERVER_IPv6"
|
||||
}
|
||||
165
scripts/common/setup_debian.sh
Normal file
165
scripts/common/setup_debian.sh
Normal file
@@ -0,0 +1,165 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
### Fonction pour mettre à jour le système
|
||||
update_system() {
|
||||
echo "Mise à jour du système..."
|
||||
apt update && apt upgrade -y && sudo apt autoremove -y && command -v flatpak >/dev/null && flatpak update -y
|
||||
}
|
||||
|
||||
### Fonction pour installer sudo s'il n'est pas déjà présent
|
||||
install_sudo() {
|
||||
if command -v sudo &>/dev/null; then
|
||||
echo "Sudo est déjà installé."
|
||||
else
|
||||
echo "Installation de sudo..."
|
||||
apt install -y sudo
|
||||
fi
|
||||
}
|
||||
|
||||
### Fonction pour ajouter un utilisateur administrateur
|
||||
add_admin_user() {
|
||||
# Vérifier s'il existe déjà un utilisateur autre que root
|
||||
EXISTING_USER=$(awk -F: '$3 >= 1000 && $3 < 60000 {print $1; exit}' /etc/passwd)
|
||||
|
||||
if [[ -n "$EXISTING_USER" ]]; then
|
||||
echo "Un utilisateur ($EXISTING_USER) existe déjà sur le système."
|
||||
read -p "Voulez-vous ajouter un autre utilisateur administrateur ? (o/N) " ADD_NEW_USER
|
||||
if [[ ! "$ADD_NEW_USER" =~ ^[Oo]$ ]]; then
|
||||
echo "Aucun nouvel utilisateur ajouté."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
read -p "Entrez le nom du nouvel utilisateur : " NEW_USER
|
||||
|
||||
# Vérifier si l'utilisateur existe déjà
|
||||
if id "$NEW_USER" &>/dev/null; then
|
||||
echo "L'utilisateur $NEW_USER existe déjà."
|
||||
else
|
||||
adduser "$NEW_USER"
|
||||
echo "Utilisateur $NEW_USER créé."
|
||||
fi
|
||||
|
||||
# Vérifier si l'utilisateur est dans le groupe sudo
|
||||
if groups "$NEW_USER" | grep -q "\bsudo\b"; then
|
||||
echo "$NEW_USER est déjà dans le groupe sudo."
|
||||
else
|
||||
usermod -aG sudo "$NEW_USER"
|
||||
echo "$NEW_USER ajouté au groupe sudo."
|
||||
fi
|
||||
# Vérifier si les permissions sudo sont déjà définies
|
||||
if [ -f "/etc/sudoers.d/$NEW_USER" ]; then
|
||||
echo "Les permissions sudo sont déjà configurées pour $NEW_USER."
|
||||
else
|
||||
echo "$NEW_USER ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/$NEW_USER"
|
||||
chmod 0440 "/etc/sudoers.d/$NEW_USER"
|
||||
echo "Configuration sudo appliquée pour $NEW_USER."
|
||||
fi
|
||||
|
||||
# Demander si on veut ajouter une clé SSH
|
||||
read -p "Voulez-vous ajouter une clé SSH pour $NEW_USER ? (o/N) " ADD_SSH
|
||||
if [[ "$ADD_SSH" =~ ^[Oo]$ ]]; then
|
||||
SSH_DIR="/home/$NEW_USER/.ssh"
|
||||
AUTH_KEYS="$SSH_DIR/authorized_keys"
|
||||
|
||||
# Créer le dossier .ssh s'il n'existe pas
|
||||
if [ ! -d "$SSH_DIR" ]; then
|
||||
mkdir -p "$SSH_DIR"
|
||||
chown "$NEW_USER:$NEW_USER" "$SSH_DIR"
|
||||
chmod 700 "$SSH_DIR"
|
||||
echo "Dossier .ssh créé pour $NEW_USER."
|
||||
fi
|
||||
|
||||
read -p "Collez la clé publique SSH : " SSH_KEY
|
||||
|
||||
# Vérifier si la clé est déjà présente
|
||||
if grep -qxF "$SSH_KEY" "$AUTH_KEYS" 2>/dev/null; then
|
||||
echo "Cette clé SSH est déjà ajoutée."
|
||||
else
|
||||
echo "$SSH_KEY" >> "$AUTH_KEYS"
|
||||
chown "$NEW_USER:$NEW_USER" "$AUTH_KEYS"
|
||||
chmod 600 "$AUTH_KEYS"
|
||||
echo "Clé SSH ajoutée pour $NEW_USER."
|
||||
fi
|
||||
else
|
||||
echo "Aucune clé SSH ajoutée."
|
||||
fi
|
||||
}
|
||||
|
||||
### Fonction pour configurer SSH de manière sécurisée
|
||||
configure_ssh() {
|
||||
if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config; then
|
||||
echo "La connexion root SSH est déjà désactivée."
|
||||
else
|
||||
echo "Désactivation de la connexion root via SSH..."
|
||||
sed -i 's/^#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
systemctl restart ssh
|
||||
echo "Sécurisation SSH appliquée."
|
||||
fi
|
||||
}
|
||||
|
||||
### Fonction pour installer et configurer Fail2Ban
|
||||
install_fail2ban() {
|
||||
if dpkg -l | grep -q "^ii fail2ban"; then
|
||||
echo "Fail2Ban est déjà installé."
|
||||
else
|
||||
echo "Installation de Fail2Ban..."
|
||||
apt install -y fail2ban
|
||||
fi
|
||||
}
|
||||
|
||||
### Fonction pour configurer les locales en français UTF-8
|
||||
configure_locales() {
|
||||
echo "Configuration des locales en français UTF-8..."
|
||||
apt install -y locales
|
||||
|
||||
# Vérifier si fr_FR.UTF-8 est déjà activé
|
||||
if locale -a | grep -q "fr_FR.utf8"; then
|
||||
echo "Les locales en fr_FR.UTF-8 sont déjà activées."
|
||||
else
|
||||
sed -i 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' /etc/locale.gen
|
||||
locale-gen
|
||||
fi
|
||||
|
||||
# Appliquer les variables locales si nécessaire
|
||||
if grep -q "LANG=fr_FR.UTF-8" /etc/default/locale; then
|
||||
echo "Les variables locales sont déjà configurées."
|
||||
else
|
||||
update-locale LANG=fr_FR.UTF-8 LANGUAGE=fr_FR.UTF-8 LC_ALL=fr_FR.UTF-8
|
||||
echo "Variables locales mises à jour."
|
||||
fi
|
||||
}
|
||||
|
||||
configure_timezone() {
|
||||
echo "Détection de la timezone via l'IP publique..."
|
||||
TIMEZONE=$(curl -s https://ipinfo.io/timezone)
|
||||
|
||||
# Définir la timezone via timedatectl
|
||||
echo "Définition de la timezone à : $TIMEZONE"
|
||||
timedatectl set-timezone "$TIMEZONE"
|
||||
}
|
||||
|
||||
install_paquets() {
|
||||
apt install -y curl
|
||||
}
|
||||
|
||||
### SECTION PRINCIPALE : Activer/Désactiver les options ici
|
||||
update_system
|
||||
install_sudo
|
||||
add_admin_user
|
||||
configure_ssh
|
||||
install_fail2ban
|
||||
configure_locales
|
||||
install_paquets
|
||||
configure_timezone
|
||||
|
||||
echo "Installation et configuration de base terminées."
|
||||
echo "Vous pouvez maintenant vous connecter avec l'utilisateur : $NEW_USER"
|
||||
133
scripts/common/setup_mdns.sh
Normal file
133
scripts/common/setup_mdns.sh
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Détection des interfaces réseau actives ==="
|
||||
INTERFACES=$(ip -o link show | awk -F': ' '{print $2}' | grep -Ev 'lo|docker|veth|br|vmnet|virbr')
|
||||
echo "Interfaces détectées : $INTERFACES"
|
||||
ALLOWED_INTERFACES=$(echo "$INTERFACES" | paste -sd "," -)
|
||||
|
||||
echo "=== Installation d'Avahi (mDNS) et des dépendances ==="
|
||||
apt update
|
||||
apt install -y avahi-daemon avahi-utils libnss-mdns nscd systemd-resolved
|
||||
|
||||
echo "=== Vérification de la présence de libnss_mdns.so.2 ==="
|
||||
if [[ ! -f /lib/x86_64-linux-gnu/libnss_mdns.so.2 ]]; then
|
||||
echo "❌ libnss_mdns.so.2 manquante, tentative de réinstallation"
|
||||
apt install --reinstall -y libnss-mdns
|
||||
fi
|
||||
|
||||
echo "=== Configuration de /etc/nsswitch.conf ==="
|
||||
if grep -q '^hosts:' /etc/nsswitch.conf; then
|
||||
sed -i 's/^hosts:.*/hosts: files mdns4 dns/' /etc/nsswitch.conf
|
||||
else
|
||||
echo "hosts: files mdns4 dns" >> /etc/nsswitch.conf
|
||||
fi
|
||||
grep hosts /etc/nsswitch.conf
|
||||
|
||||
echo "=== Redémarrage des caches DNS si présents ==="
|
||||
systemctl restart nscd || echo "nscd non utilisé"
|
||||
systemctl restart systemd-resolved || echo "systemd-resolved non utilisé"
|
||||
|
||||
echo "=== Vérification d'un éventuel service sur le port 80 ==="
|
||||
if ss -tuln | grep -q ':80 '; then
|
||||
echo "❌ Un service écoute déjà sur le port 80. Abandon de la publication HTTP de test."
|
||||
PUBLISH_HTTP=false
|
||||
else
|
||||
PUBLISH_HTTP=true
|
||||
fi
|
||||
|
||||
echo "=== Sauvegarde de la conf avahi ==="
|
||||
cp /etc/avahi/avahi-daemon.conf /etc/avahi/avahi-daemon.conf.bak.$(date +%F-%H%M)
|
||||
|
||||
echo "=== Génération de la configuration avahi-daemon.conf ==="
|
||||
cat > /etc/avahi/avahi-daemon.conf <<EOF
|
||||
[server]
|
||||
host-name=$(hostname)
|
||||
use-ipv4=yes
|
||||
use-ipv6=no
|
||||
allow-interfaces=$ALLOWED_INTERFACES
|
||||
ratelimit-interval-usec=1000000
|
||||
ratelimit-burst=10
|
||||
|
||||
[wide-area]
|
||||
enable-wide-area=no
|
||||
|
||||
[publish]
|
||||
publish-addresses=yes
|
||||
publish-hinfo=yes
|
||||
publish-workstation=yes
|
||||
publish-domain=yes
|
||||
|
||||
[reflector]
|
||||
enable-reflector=no
|
||||
|
||||
[rlimits]
|
||||
rlimit-as=0
|
||||
rlimit-core=0
|
||||
rlimit-data=4194304
|
||||
rlimit-fsize=0
|
||||
rlimit-nofile=300
|
||||
rlimit-stack=4194304
|
||||
EOF
|
||||
|
||||
if $PUBLISH_HTTP; then
|
||||
echo "=== Publication temporaire d'un service HTTP de test ==="
|
||||
mkdir -p /etc/avahi/services
|
||||
cat > /etc/avahi/services/test-http.service <<EOF
|
||||
<?xml version="1.0" standalone='no'?>
|
||||
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
|
||||
<service-group>
|
||||
<name replace-wildcards="yes">Test HTTP on %h</name>
|
||||
<service>
|
||||
<type>_http._tcp</type>
|
||||
<port>80</port>
|
||||
</service>
|
||||
</service-group>
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "=== Activation et redémarrage du service Avahi ==="
|
||||
systemctl enable avahi-daemon
|
||||
systemctl restart avahi-daemon
|
||||
|
||||
echo "=== Vérification du statut du service ==="
|
||||
systemctl status avahi-daemon --no-pager || { echo "❌ Avahi ne fonctionne pas."; exit 1; }
|
||||
|
||||
echo "=== Vérification du multicast sur l'interface ==="
|
||||
ip a | grep MULTICAST || echo "⚠️ Aucune interface multicast détectée"
|
||||
|
||||
echo "=== Vérification de l'écoute sur le port UDP 5353 ==="
|
||||
ss -uln | grep 5353 || echo "⚠️ Aucun service écoutant sur UDP/5353"
|
||||
|
||||
echo "=== Test de la résolution mDNS avec getent (NSS) ==="
|
||||
LOCAL_HOST="$(hostname).local"
|
||||
if getent hosts "$LOCAL_HOST"; then
|
||||
echo "✅ Résolution mDNS de $LOCAL_HOST réussie via getent"
|
||||
else
|
||||
echo "❌ La résolution mDNS de $LOCAL_HOST a échoué via getent"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Scan des services mDNS disponibles ==="
|
||||
avahi-browse -a -t || echo "⚠️ Aucun service mDNS visible (normal si peu de services publiés)"
|
||||
|
||||
echo "✅ mDNS opérationnel sur : $ALLOWED_INTERFACES"
|
||||
echo "$INTERFACES" > /var/log/mdns_interfaces.log
|
||||
echo "Interfaces enregistrées dans /var/log/mdns_interfaces.log"
|
||||
|
||||
if $PUBLISH_HTTP; then
|
||||
echo "=== Suppression du service HTTP de test ==="
|
||||
rm -f /etc/avahi/services/test-http.service
|
||||
systemctl restart avahi-daemon
|
||||
echo "✅ Service HTTP de test retiré proprement"
|
||||
fi
|
||||
|
||||
echo "✅ Script terminé avec succès"
|
||||
146
scripts/fetch_scripts.sh
Executable file
146
scripts/fetch_scripts.sh
Executable file
@@ -0,0 +1,146 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Définition de l'URL du script
|
||||
SCRIPT_URL="https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/scripts/fetch_scripts.sh"
|
||||
SCRIPT_NAME=$(basename "$0")
|
||||
TMP_SCRIPT="/tmp/$SCRIPT_NAME"
|
||||
|
||||
# Télécharger la dernière version du script
|
||||
wget -q -O "$TMP_SCRIPT" "$SCRIPT_URL"
|
||||
|
||||
# Vérifier si la mise à jour est différente de la version actuelle
|
||||
if ! cmp -s "$TMP_SCRIPT" "$0"; then
|
||||
echo "🔄 Mise à jour du script..."
|
||||
mv "$TMP_SCRIPT" "$0"
|
||||
chmod +x "$0"
|
||||
echo "✅ Script mis à jour ! Redémarrage..."
|
||||
exec "$0" "$@"
|
||||
exit 0
|
||||
else
|
||||
rm "$TMP_SCRIPT"
|
||||
fi
|
||||
|
||||
|
||||
# Définition du dépôt et des fichiers de configuration
|
||||
REPO_URL="https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/scripts"
|
||||
DIR_LIST_FILE=".directories.txt"
|
||||
SELECTED_DIRS_FILE=".selected_dirs.txt"
|
||||
MANDATORY_DIR="common"
|
||||
|
||||
# Télécharger la liste des dossiers disponibles
|
||||
TMP_DIR=$(mktemp -d)
|
||||
DIR_LIST_PATH="$TMP_DIR/$DIR_LIST_FILE"
|
||||
|
||||
wget -q -O "$DIR_LIST_PATH" "$REPO_URL/$DIR_LIST_FILE"
|
||||
|
||||
# Vérifier que la liste a bien été téléchargée
|
||||
if [ ! -s "$DIR_LIST_PATH" ]; then
|
||||
echo "❌ Erreur : Impossible de récupérer la liste des dossiers."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Lire les dossiers disponibles dans un tableau
|
||||
mapfile -t AVAILABLE_DIRS < "$DIR_LIST_PATH"
|
||||
|
||||
# Vérifier qu'il y a bien des dossiers disponibles
|
||||
if [ ${#AVAILABLE_DIRS[@]} -eq 0 ]; then
|
||||
echo "❌ Aucun dossier disponible dans la liste."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Charger les dossiers précédemment sélectionnés
|
||||
if [ -f "$SELECTED_DIRS_FILE" ]; then
|
||||
mapfile -t PREVIOUS_SELECTION < "$SELECTED_DIRS_FILE"
|
||||
else
|
||||
PREVIOUS_SELECTION=()
|
||||
fi
|
||||
|
||||
# Construire la liste pour whiptail
|
||||
CHOICES=()
|
||||
for dir in "${AVAILABLE_DIRS[@]}"; do
|
||||
if [ "$dir" == "$MANDATORY_DIR" ]; then
|
||||
continue # Ne pas inclure le dossier obligatoire dans le choix
|
||||
fi
|
||||
if [[ " ${PREVIOUS_SELECTION[*]} " =~ " $dir " ]]; then
|
||||
CHOICES+=("$dir" "" ON)
|
||||
else
|
||||
CHOICES+=("$dir" "" OFF)
|
||||
fi
|
||||
done
|
||||
|
||||
# Affichage du menu de sélection avec whiptail
|
||||
SELECTED_DIRS=$(whiptail --title "Sélection des dossiers" --checklist \
|
||||
"Sélectionnez les dossiers à télécharger :" 20 60 10 \
|
||||
"${CHOICES[@]}" 3>&1 1>&2 2>&3)
|
||||
|
||||
# Vérifier si l'utilisateur a annulé
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Annulation par l'utilisateur."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Convertir la sélection en tableau
|
||||
SELECTED_DIRS_ARRAY=("$MANDATORY_DIR" $(echo "$SELECTED_DIRS" | tr -d '"'))
|
||||
|
||||
# Enregistrer la sélection actuelle
|
||||
echo "${SELECTED_DIRS_ARRAY[@]}" > "$SELECTED_DIRS_FILE"
|
||||
|
||||
# Identifier les dossiers à supprimer (ceux qui ne sont plus sélectionnés)
|
||||
for dir in "${PREVIOUS_SELECTION[@]}"; do
|
||||
if [[ ! " ${SELECTED_DIRS_ARRAY[*]} " =~ " $dir " ]]; then
|
||||
echo "🗑 Suppression du dossier $dir..."
|
||||
rm -rf "$dir"
|
||||
fi
|
||||
done
|
||||
|
||||
# Télécharger ou mettre à jour les fichiers pour chaque dossier sélectionné
|
||||
for TARGET_DIR in "${SELECTED_DIRS_ARRAY[@]}"; do
|
||||
LIST_FILE=".list_files.txt"
|
||||
LIST_PATH="$TMP_DIR/$LIST_FILE"
|
||||
|
||||
echo "🔹 Récupération des scripts de '$TARGET_DIR'..."
|
||||
|
||||
# Télécharger la liste des fichiers
|
||||
wget -q -O "$LIST_PATH" "$REPO_URL/$TARGET_DIR/$LIST_FILE"
|
||||
|
||||
if [ ! -s "$LIST_PATH" ]; then
|
||||
echo "❌ Erreur : Impossible de récupérer la liste des fichiers pour $TARGET_DIR."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Création du répertoire s'il n'existe pas
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
# Télécharger chaque fichier listé
|
||||
while read -r file; do
|
||||
FILE_NAME=$(basename "$file")
|
||||
FILE_PATH="$TARGET_DIR/$FILE_NAME"
|
||||
|
||||
if [ -f "$FILE_PATH" ]; then
|
||||
echo " ↻ Mise à jour de $FILE_NAME..."
|
||||
else
|
||||
echo " ↳ Téléchargement de $FILE_NAME..."
|
||||
fi
|
||||
wget -q -O "$FILE_PATH" "$REPO_URL/$TARGET_DIR/$file"
|
||||
done < "$LIST_PATH"
|
||||
|
||||
# Supprimer les fichiers obsolètes
|
||||
for existing_file in "$TARGET_DIR"/*; do
|
||||
if [ -f "$existing_file" ] && ! grep -qx "$(basename "$existing_file")" "$LIST_PATH"; then
|
||||
echo " 🗑 Suppression de $(basename "$existing_file")..."
|
||||
rm "$existing_file"
|
||||
fi
|
||||
done
|
||||
|
||||
# Rendre exécutables les scripts téléchargés
|
||||
chmod +x "$TARGET_DIR"/*.sh
|
||||
|
||||
echo "✅ Scripts de '$TARGET_DIR' mis à jour avec succès."
|
||||
done
|
||||
|
||||
# Nettoyage
|
||||
rm -rf "$TMP_DIR"
|
||||
|
||||
echo "🚀 Tous les scripts sélectionnés ont été mis à jour et sont exécutables."
|
||||
|
||||
7
scripts/server-dhcp/.list_files.txt
Normal file
7
scripts/server-dhcp/.list_files.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
add_dns_entry.sh
|
||||
find_hostname.sh
|
||||
get_first_free_ip.sh
|
||||
remove_dns_entry.sh
|
||||
search_entry.sh
|
||||
setup_dhcp.sh
|
||||
setup_nat_auto.sh
|
||||
173
scripts/server-dhcp/add_dns_entry.sh
Normal file
173
scripts/server-dhcp/add_dns_entry.sh
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Fichier de configuration de dnsmasq
|
||||
DNSMASQ_CONF="/etc/dnsmasq.d/custom_hosts"
|
||||
|
||||
# Vérifier que dnsmasq est installé
|
||||
if ! command -v dnsmasq &> /dev/null; then
|
||||
echo "dnsmasq n'est pas installé. Installez-le avec : sudo ./setup_dhcp.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier les arguments
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "Usage: $0 <IP> <HOSTNAME1> [HOSTNAME2] [HOSTNAME3] ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IP="$1"
|
||||
shift # Supprime le premier argument pour ne garder que les hostnames
|
||||
HOSTNAMES=("$@")
|
||||
|
||||
# Fonction pour obtenir le PTR record formaté
|
||||
get_ptr_record() {
|
||||
local ip="$1"
|
||||
local reversed_ip=$(echo "$ip" | awk -F. '{print $4"."$3"."$2"."$1".in-addr.arpa"}')
|
||||
echo "$reversed_ip"
|
||||
}
|
||||
|
||||
# Fonction pour vérifier si un PTR existe
|
||||
is_ptr_registered() {
|
||||
local ip="$1"
|
||||
local ptr=$(get_ptr_record "$ip")
|
||||
grep -q "ptr-record=$ptr" "$DNSMASQ_CONF"
|
||||
return $?
|
||||
}
|
||||
|
||||
# Fonction pour obtenir le FQDN d'un hostname
|
||||
get_fqdn() {
|
||||
local hostname="$1"
|
||||
local domain_name=$(dnsdomainname)
|
||||
if [[ -n "$domain_name" ]]; then
|
||||
echo "$hostname.$domain_name"
|
||||
else
|
||||
echo "$hostname"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Fonction pour obtenir le FQDN réel avec `host`
|
||||
get_actual_fqdn() {
|
||||
local ip="$1"
|
||||
local actual_fqdn=$(host "$ip" | awk '/domain name pointer/ {print $5}' | sed 's/\.$//')
|
||||
echo "$actual_fqdn"
|
||||
}
|
||||
|
||||
# Fonction pour vérifier si un hostname est déjà enregistré
|
||||
is_hostname_registered() {
|
||||
local hostname="$1"
|
||||
grep -q "address=/$hostname/$IP" "$DNSMASQ_CONF"
|
||||
return $?
|
||||
}
|
||||
|
||||
# Variable pour suivre si un changement a été fait
|
||||
MODIFIED=0
|
||||
MODIFIED_BY_HOSTNAME=0
|
||||
MODIFIED_BY_FQDN=0
|
||||
|
||||
# Vérifier si l'IP existe déjà dans le fichier
|
||||
EXISTING_HOSTNAMES=($(grep -E "address=/[^ ]+/$IP$" "$DNSMASQ_CONF" | sed -E "s/address=\/([^\/]+)\/$IP/\1/"))
|
||||
|
||||
if [[ ${#EXISTING_HOSTNAMES[@]} -gt 0 ]]; then
|
||||
echo "L'adresse IP $IP existe déjà avec les noms suivants : ${EXISTING_HOSTNAMES[*]}"
|
||||
else
|
||||
echo "Nouvelle adresse IP détectée : $IP"
|
||||
fi
|
||||
|
||||
# Vérifier et ajouter chaque hostname
|
||||
for HOSTNAME in "${HOSTNAMES[@]}"; do
|
||||
FQDN=$(get_fqdn "$HOSTNAME")
|
||||
echo "Le FQDN détecté pour $HOSTNAME est : $FQDN"
|
||||
|
||||
if is_hostname_registered "$FQDN"; then
|
||||
echo "L'association $FQDN -> $IP existe déjà."
|
||||
else
|
||||
read -p "Le FQDN $FQDN n'est pas dans la liste. Voulez-vous l'ajouter ? (o/N) " REPLY
|
||||
# Si aucune entrée n'est faite dans le délai imparti, on met "n" par défaut
|
||||
if [[ -z "$REPLY" ]]; then
|
||||
REPLY="n"
|
||||
echo -e "\nRéponse par défaut : n"
|
||||
fi
|
||||
if [[ "$REPLY" =~ ^[Oo]$ ]]; then
|
||||
echo "address=/$FQDN/$IP" >> "$DNSMASQ_CONF"
|
||||
echo "Ajout de : $FQDN -> $IP"
|
||||
MODIFIED=1
|
||||
MODIFIED_BY_FQDN=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if is_hostname_registered "$HOSTNAME"; then
|
||||
echo "L'association $HOSTNAME -> $IP existe déjà."
|
||||
else
|
||||
echo "address=/$HOSTNAME/$IP" >> "$DNSMASQ_CONF"
|
||||
echo "Ajout de : $HOSTNAME -> $IP"
|
||||
MODIFIED=1
|
||||
MODIFIED_BY_HOSTNAME=1
|
||||
fi
|
||||
|
||||
# Vérification et ajout du PTR record
|
||||
PTR_RECORD=$(get_ptr_record "$IP")
|
||||
EXISTING_PTR=$(grep -E "ptr-record=$PTR_RECORD," "$DNSMASQ_CONF" | cut -d'=' -f2)
|
||||
|
||||
if [[ $MODIFIED -eq 1 ]]; then
|
||||
# Déterminer $ACTUAL_FQDN
|
||||
test $MODIFIED_BY_HOSTNAME -eq 1 && ACTUAL_FQDN=$HOSTNAME
|
||||
if is_hostname_registered "$FQDN"; then
|
||||
ACTUAL_FQDN=$FQDN
|
||||
fi
|
||||
test $MODIFIED_BY_FQDN -eq 1 && ACTUAL_FQDN=$FQDN
|
||||
else
|
||||
ACTUAL_FQDN=""
|
||||
|
||||
if is_hostname_registered "$HOSTNAME"; then
|
||||
ACTUAL_FQDN=$HOSTNAME
|
||||
fi
|
||||
if is_hostname_registered "$FQDN"; then
|
||||
ACTUAL_FQDN=$FQDN
|
||||
fi
|
||||
fi
|
||||
|
||||
# Si ACTUAL_FQDN n'est pas vide, alors
|
||||
if [[ -n "$ACTUAL_FQDN" ]]; then
|
||||
# Si l'enregistrement actuel ne correspond pas déjà à $ACTUAL_FQDN, procéder à la mise à jour
|
||||
if [[ "$(get_actual_fqdn "$IP")" != "$ACTUAL_FQDN" ]]; then
|
||||
if [[ -n "$EXISTING_PTR" ]]; then
|
||||
if [[ "$EXISTING_PTR" != "ptr-record=$PTR_RECORD,$ACTUAL_FQDN" ]]; then
|
||||
read -p "Voulez-vous le remplacer ? (o/N) " REPLY
|
||||
if [[ -z "$REPLY" ]]; then
|
||||
REPLY="n"
|
||||
echo -e "\nRéponse par défaut : n"
|
||||
fi
|
||||
if [[ "$REPLY" =~ ^[Oo]$ ]]; then
|
||||
sed -i "/ptr-record=$PTR_RECORD/d" "$DNSMASQ_CONF"
|
||||
echo "ptr-record=$PTR_RECORD,${ACTUAL_FQDN}" >> "$DNSMASQ_CONF"
|
||||
echo "PTR mis à jour : $PTR_RECORD -> ${ACTUAL_FQDN}"
|
||||
MODIFIED=1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "ptr-record=$PTR_RECORD,${ACTUAL_FQDN}" >> "$DNSMASQ_CONF"
|
||||
echo "Ajout du PTR : $PTR_RECORD -> ${ACTUAL_FQDN}"
|
||||
MODIFIED=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
|
||||
# Redémarrer dnsmasq seulement si des changements ont été faits
|
||||
if [[ $MODIFIED -eq 1 ]]; then
|
||||
systemctl restart dnsmasq
|
||||
echo "Redémarrage de dnsmasq effectué."
|
||||
else
|
||||
echo "Aucune modification nécessaire."
|
||||
fi
|
||||
63
scripts/server-dhcp/find_hostname.sh
Normal file
63
scripts/server-dhcp/find_hostname.sh
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Fichier contenant les enregistrements
|
||||
FILE="/etc/dnsmasq.d/custom_hosts"
|
||||
|
||||
# Vérification de l'existence du fichier
|
||||
if [[ ! -f "$FILE" ]]; then
|
||||
echo "Erreur: Le fichier $FILE n'existe pas."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérification des arguments
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 <nom_machine|FQDN|adresse_IP>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SEARCH_TERM="$1"
|
||||
|
||||
# Détection du nom de domaine
|
||||
if [[ -f /etc/resolv.conf ]]; then
|
||||
DOMAIN=$(awk '/^search / {print $2; exit} /^domain / {print $2; exit}' /etc/resolv.conf)
|
||||
fi
|
||||
|
||||
# Alternative si resolv.conf n'existe pas ou est vide
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
DOMAIN=$(hostname --domain 2>/dev/null) # Essayer avec hostname
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
DOMAIN=$(nmcli -t -f IP4.DOMAIN dev show | head -n 1) # Essayer avec nmcli
|
||||
fi
|
||||
fi
|
||||
|
||||
# Vérifier qu'on a bien trouvé un domaine
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
echo "Erreur: Impossible de détecter le nom de domaine."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Si l'entrée ne contient pas un point, on ajoute le domaine détecté
|
||||
if [[ ! "$SEARCH_TERM" =~ \. ]]; then
|
||||
SEARCH_TERM="$SEARCH_TERM.$DOMAIN"
|
||||
fi
|
||||
|
||||
# Vérification si l'entrée est une adresse IP
|
||||
if [[ "$SEARCH_TERM" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
RESULTS=$(grep -E "/$SEARCH_TERM\$" "$FILE")
|
||||
else
|
||||
if [[ ! "$SEARCH_TERM" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
||||
echo "Erreur: '$SEARCH_TERM' ne semble pas être un FQDN valide."
|
||||
exit 1
|
||||
fi
|
||||
RESULTS=$(grep -E "^address=/$SEARCH_TERM/" "$FILE")
|
||||
fi
|
||||
|
||||
# Vérification et affichage des résultats
|
||||
if [[ -n "$RESULTS" ]]; then
|
||||
echo "Résultats trouvés :"
|
||||
echo "$RESULTS"
|
||||
else
|
||||
echo "Aucun résultat trouvé pour '$SEARCH_TERM'."
|
||||
fi
|
||||
|
||||
83
scripts/server-dhcp/get_first_free_ip.sh
Normal file
83
scripts/server-dhcp/get_first_free_ip.sh
Normal file
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Déterminer l'interface réseau active (exclure loopback)
|
||||
INTERFACE=$(ip route | awk '/default/ {print $5; exit}')
|
||||
|
||||
# Vérifier si une interface est détectée
|
||||
if [[ -z "$INTERFACE" ]]; then
|
||||
echo "❌ Aucune interface réseau active détectée."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Déterminer l'adresse IP et le masque réseau de l'interface active
|
||||
IP_INFO=$(ip -4 addr show "$INTERFACE" | awk '/inet / {print $2}')
|
||||
NETWORK_IP=$(echo "$IP_INFO" | cut -d'/' -f1)
|
||||
NETMASK_CIDR=$(echo "$IP_INFO" | cut -d'/' -f2)
|
||||
|
||||
# Extraire le préfixe réseau (ex: "192.168.100")
|
||||
PREFIX=$(echo "$NETWORK_IP" | awk -F. '{print $1"."$2"."$3}')
|
||||
|
||||
# Calculer la plage IP en fonction du masque
|
||||
TOTAL_HOSTS=$(( 2 ** (32 - NETMASK_CIDR) ))
|
||||
IP_RANGE_START="$PREFIX.1"
|
||||
IP_RANGE_END="$PREFIX.$(( TOTAL_HOSTS - 2 ))" # -2 pour exclure le broadcast et l'adresse réseau
|
||||
|
||||
# Afficher la plage détectée
|
||||
echo "🔍 Plage IP détectée :"
|
||||
echo " ➡ Début : $IP_RANGE_START"
|
||||
echo " ➡ Fin : $IP_RANGE_END"
|
||||
|
||||
# Demander confirmation ou modification de la plage
|
||||
read -p "Nouvelle adresse de début (laisser vide pour conserver $IP_RANGE_START) : " NEW_START
|
||||
read -p "Nouvelle adresse de fin (laisser vide pour conserver $IP_RANGE_END) : " NEW_END
|
||||
|
||||
# Si l'utilisateur ne saisit rien, conserver les valeurs détectées
|
||||
IP_RANGE_START=${NEW_START:-$IP_RANGE_START}
|
||||
IP_RANGE_END=${NEW_END:-$IP_RANGE_END}
|
||||
|
||||
# Fichier contenant les réservations DHCP
|
||||
RESERVATION_FILE="/etc/dnsmasq.d/custom_hosts"
|
||||
|
||||
# Fonction pour convertir une IP en un entier
|
||||
ip_to_int() {
|
||||
local IFS=.
|
||||
local ip=($1)
|
||||
echo $(( (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3] ))
|
||||
}
|
||||
|
||||
# Fonction pour convertir un entier en IP
|
||||
int_to_ip() {
|
||||
local ip=$1
|
||||
echo "$(( (ip >> 24) & 255 )).$(( (ip >> 16) & 255 )).$(( (ip >> 8) & 255 )).$(( ip & 255 ))"
|
||||
}
|
||||
|
||||
# Vérifier si le fichier des réservations existe
|
||||
if [[ ! -f "$RESERVATION_FILE" ]]; then
|
||||
echo "Erreur : Le fichier des réservations $RESERVATION_FILE n'existe pas."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Lire toutes les IP utilisées dans le fichier de réservation
|
||||
USED_IPS=($(grep -oE 'address=/[^/]+/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$RESERVATION_FILE" | awk -F'/' '{print $3}'))
|
||||
|
||||
# Vérification et recherche de la première IP disponible
|
||||
START_INT=$(ip_to_int "$IP_RANGE_START")
|
||||
END_INT=$(ip_to_int "$IP_RANGE_END")
|
||||
|
||||
CURRENT_IP_INT=$START_INT
|
||||
|
||||
while (( CURRENT_IP_INT <= END_INT )); do
|
||||
CURRENT_IP=$(int_to_ip "$CURRENT_IP_INT")
|
||||
|
||||
# Vérifier si l'IP est déjà réservée
|
||||
if [[ ! " ${USED_IPS[@]} " =~ " $CURRENT_IP " ]]; then
|
||||
echo "✅ Première IP disponible : $CURRENT_IP"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
(( CURRENT_IP_INT++ ))
|
||||
done
|
||||
|
||||
echo "❌ Plus aucune IP disponible dans la plage définie."
|
||||
exit 1
|
||||
61
scripts/server-dhcp/remove_dns_entry.sh
Normal file
61
scripts/server-dhcp/remove_dns_entry.sh
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Fichier de configuration de dnsmasq
|
||||
DNSMASQ_CONF="/etc/dnsmasq.d/custom_hosts"
|
||||
|
||||
# Vérifier que dnsmasq est installé
|
||||
if ! command -v dnsmasq &> /dev/null; then
|
||||
echo "dnsmasq n'est pas installé. Installez-le avec : sudo ./setup_dhcp.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier les arguments
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 <IP | HOSTNAME>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET="$1"
|
||||
MODIFIED=0
|
||||
|
||||
# Vérifier si le fichier existe
|
||||
if [[ ! -f "$DNSMASQ_CONF" ]]; then
|
||||
echo "Le fichier $DNSMASQ_CONF n'existe pas. Aucun enregistrement à supprimer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Supprimer par IP
|
||||
if [[ "$TARGET" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
# Vérifier si l'IP existe dans le fichier
|
||||
if grep -q "/$TARGET$" "$DNSMASQ_CONF"; then
|
||||
sed -i "/\/$TARGET$/d" "$DNSMASQ_CONF"
|
||||
echo "Toutes les entrées associées à l'IP $TARGET ont été supprimées."
|
||||
MODIFIED=1
|
||||
else
|
||||
echo "Aucune entrée trouvée pour l'IP $TARGET."
|
||||
fi
|
||||
# Supprimer par Nom d'hôte
|
||||
else
|
||||
if grep -qE "^address=/$TARGET/" "$DNSMASQ_CONF"; then
|
||||
sed -i "/^address=\/$TARGET\//d" "$DNSMASQ_CONF"
|
||||
echo "L'enregistrement $TARGET a été supprimé."
|
||||
MODIFIED=1
|
||||
else
|
||||
echo "Aucune entrée trouvée pour le nom d'hôte $TARGET."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Redémarrer dnsmasq seulement si une modification a été effectuée
|
||||
if [[ $MODIFIED -eq 1 ]]; then
|
||||
systemctl restart dnsmasq
|
||||
echo "Redémarrage de dnsmasq effectué."
|
||||
else
|
||||
echo "Aucune modification nécessaire."
|
||||
fi
|
||||
56
scripts/server-dhcp/search_entry.sh
Normal file
56
scripts/server-dhcp/search_entry.sh
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Fichier contenant les enregistrements
|
||||
FILE="/etc/dnsmasq.d/custom_hosts"
|
||||
|
||||
# Vérification de l'existence du fichier
|
||||
if [[ ! -f "$FILE" ]]; then
|
||||
echo "Erreur: Le fichier $FILE n'existe pas."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérification des arguments
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 <nom_machine|FQDN|adresse_IP>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SEARCH_TERM="$1"
|
||||
|
||||
# Détecter le nom de domaine depuis /etc/resolv.conf
|
||||
DOMAIN=$(awk '/^search / {print $2; exit} /^domain / {print $2; exit}' /etc/resolv.conf)
|
||||
|
||||
# Vérifier qu'on a bien trouvé un domaine
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
echo "Erreur: Impossible de détecter le nom de domaine depuis /etc/resolv.conf."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Si l'entrée ne contient pas un point (ex: "www" au lieu de "www.domaine.local"), on ajoute le domaine détecté
|
||||
if [[ ! "$SEARCH_TERM" =~ \. ]]; then
|
||||
SEARCH_TERM="$SEARCH_TERM.$DOMAIN"
|
||||
fi
|
||||
|
||||
# Vérification si l'entrée est une adresse IP
|
||||
if [[ "$SEARCH_TERM" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
# Recherche stricte de l'adresse IP en tenant compte du format 'address=/FQDN/IP'
|
||||
RESULTS=$(grep -E "/$SEARCH_TERM\$" "$FILE")
|
||||
else
|
||||
# Vérification que le terme recherché est bien un FQDN valide
|
||||
if [[ ! "$SEARCH_TERM" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
||||
echo "Erreur: '$SEARCH_TERM' ne semble pas être un FQDN valide."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Recherche stricte du FQDN en tenant compte du format 'address=/FQDN/IP'
|
||||
RESULTS=$(grep -E "^address=/$SEARCH_TERM/" "$FILE")
|
||||
fi
|
||||
|
||||
# Vérification et affichage des résultats
|
||||
if [[ -n "$RESULTS" ]]; then
|
||||
echo "Résultats trouvés :"
|
||||
echo "$RESULTS"
|
||||
else
|
||||
echo "Aucun résultat trouvé pour '$SEARCH_TERM'."
|
||||
fi
|
||||
209
scripts/server-dhcp/setup_dhcp.sh
Normal file
209
scripts/server-dhcp/setup_dhcp.sh
Normal file
@@ -0,0 +1,209 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Installer dnsmasq s'il n'est pas déjà installé
|
||||
if ! command -v dnsmasq &> /dev/null; then
|
||||
echo "Installation de dnsmasq..."
|
||||
apt update && apt install -y dnsmasq
|
||||
echo "Installation d'outils réseau..."
|
||||
apt install -y avahi-utils net-tools smbclient nmap
|
||||
systemctl disable --now avahi-daemon
|
||||
else
|
||||
echo "dnsmasq est déjà installé."
|
||||
fi
|
||||
|
||||
# Récupérer toutes les interfaces réseau sauf loopback
|
||||
mapfile -t NOMS < <(ip -o link show | awk -F': ' '{print $2}' | grep -v lo)
|
||||
|
||||
if [[ ${#NOMS[@]} -eq 0 ]]; then
|
||||
echo "Aucune interface réseau trouvée."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Construire les options avec IP si existante
|
||||
OPTIONS=()
|
||||
for IFACE in "${NOMS[@]}"; do
|
||||
# Nettoyer l'interface de @ifX
|
||||
IFACE_CLEAN=$(echo "$IFACE" | cut -d'@' -f1)
|
||||
IP=$(ip -4 -o addr show "$IFACE_CLEAN" 2>/dev/null | awk '{print $4}' | cut -d'/' -f1)
|
||||
if [[ -n "$IP" ]]; then
|
||||
OPTIONS+=("$IFACE_CLEAN ($IP)")
|
||||
else
|
||||
OPTIONS+=("$IFACE_CLEAN (Pas d'IP)")
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Sélectionnez l'interface réseau à utiliser (IP affichée si existante) :"
|
||||
PS3="Votre choix : "
|
||||
select CHOIX in "${OPTIONS[@]}"; do
|
||||
if [[ -n "$CHOIX" ]]; then
|
||||
INTERFACE=$(echo "$CHOIX" | awk '{print $1}')
|
||||
break
|
||||
else
|
||||
echo "Choix invalide. Veuillez réessayer."
|
||||
fi
|
||||
done
|
||||
|
||||
# Maintenant que l'interface est choisie, récupérer l'IP
|
||||
IP_EXISTANTE=$(ip -4 -o addr show "$INTERFACE" 2>/dev/null | awk '{print $4}' | cut -d'/' -f1)
|
||||
|
||||
if [[ -n "$IP_EXISTANTE" ]]; then
|
||||
IP_SERVEUR="$IP_EXISTANTE"
|
||||
else
|
||||
read -rp "Aucune IP détectée sur $INTERFACE. Veuillez entrer une IP à utiliser : " IP_SAISIE
|
||||
IP_SERVEUR="$IP_SAISIE"
|
||||
fi
|
||||
|
||||
echo "✅ Interface sélectionnée : $INTERFACE"
|
||||
echo "✅ Adresse IP sélectionnée : $IP_SERVEUR"
|
||||
|
||||
# Vérifier si l'IP est privée ou publique
|
||||
if [[ "$IP_SERVEUR" =~ ^10\. ]] || [[ "$IP_SERVEUR" =~ ^192\.168\. ]] || [[ "$IP_SERVEUR" =~ ^172\.(1[6-9]|2[0-9]|3[0-1])\. ]]; then
|
||||
echo "✅ Adresse IP privée détectée : $IP_SERVEUR"
|
||||
else
|
||||
echo "⚠️ Attention : L'adresse IP $IP_SERVEUR semble PUBLIQUE !"
|
||||
fi
|
||||
|
||||
FORCE=false
|
||||
if [[ "$1" == "--force" ]]; then
|
||||
FORCE=true
|
||||
echo "Mode forçage activé : reconfiguration complète..."
|
||||
fi
|
||||
|
||||
DNSMASQ_CONF="/etc/dnsmasq.conf"
|
||||
|
||||
if grep -q "# CONFIGURE_PAR_CEDRIX" "$DNSMASQ_CONF" && [ "$FORCE" = false ]; then
|
||||
echo "dnsmasq est déjà configuré. Utilisez --force pour reconfigurer."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Déduire le sous-réseau et proposer des domaines en fonction du réseau détecté
|
||||
if [[ "$IP_SERVEUR" =~ ^10\. ]]; then
|
||||
SOUS_RESEAU=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1".0.0.0/8"}')
|
||||
DHCP_START=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1".0.0.10"}')
|
||||
DHCP_END=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1".0.0.100"}')
|
||||
DOMAIN_SUGGESTIONS=("lan10.local" "private10.local" "intranet10.local")
|
||||
elif [[ "$IP_SERVEUR" =~ ^172\.(1[6-9]|2[0-9]|3[0-1])\. ]]; then
|
||||
SOUS_RESEAU=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1"."$2".0.0/16"}')
|
||||
DHCP_START=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1"."$2".0.10"}')
|
||||
DHCP_END=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1"."$2".0.100"}')
|
||||
DOMAIN_SUGGESTIONS=("lan172.local" "private172.local" "intranet172.local")
|
||||
elif [[ "$IP_SERVEUR" =~ ^192\.168\. ]]; then
|
||||
SOUS_RESEAU=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1"."$2"."$3".0/24"}')
|
||||
DHCP_START=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1"."$2"."$3".10"}')
|
||||
DHCP_END=$(echo "$IP_SERVEUR" | awk -F '.' '{print $1"."$2"."$3".100"}')
|
||||
DOMAIN_SUGGESTIONS=("home.local" "office.local" "lan.local")
|
||||
fi
|
||||
|
||||
# Afficher les suggestions de domaine et demander à l'utilisateur de choisir
|
||||
echo "Propositions de domaine :"
|
||||
for i in "${!DOMAIN_SUGGESTIONS[@]}"; do
|
||||
echo "[$((i+1))] ${DOMAIN_SUGGESTIONS[$i]}"
|
||||
done
|
||||
echo "[0] Saisir un autre domaine"
|
||||
|
||||
read -p "Choisissez un domaine (1-${#DOMAIN_SUGGESTIONS[@]}) ou 0 pour entrer le vôtre : " CHOIX_DOMAINE
|
||||
|
||||
if [[ "$CHOIX_DOMAINE" =~ ^[1-9]+$ ]] && ((CHOIX_DOMAINE >= 1 && CHOIX_DOMAINE <= ${#DOMAIN_SUGGESTIONS[@]})); then
|
||||
DOMAINE=${DOMAIN_SUGGESTIONS[$((CHOIX_DOMAINE-1))]}
|
||||
elif [[ "$CHOIX_DOMAINE" == "0" ]]; then
|
||||
read -p "Entrez votre domaine personnalisé : " DOMAINE
|
||||
if [[ -z "$DOMAINE" ]]; then
|
||||
echo "Domaine invalide."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Choix invalide."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configurer dnsmasq
|
||||
echo "Configuration de dnsmasq..."
|
||||
|
||||
cat <<EOF > $DNSMASQ_CONF
|
||||
# CONFIGURE_PAR_CEDRIX
|
||||
# Configuration de dnsmasq
|
||||
|
||||
# Interface réseau principale
|
||||
interface=$(ip route show default | awk '/default/ {print $5}')
|
||||
listen-address=127.0.0.1,$IP_SERVEUR
|
||||
|
||||
# Activer le service DHCP
|
||||
dhcp-range=${DHCP_START},${DHCP_END},12h
|
||||
|
||||
# Associer le nom de domaine
|
||||
domain=${DOMAINE}
|
||||
|
||||
# Gestion des Alias
|
||||
alias=8.8.8.8,$IP_SERVEUR
|
||||
|
||||
# Activer la mise à jour DNS dynamique pour les clients DHCP
|
||||
dhcp-authoritative
|
||||
expand-hosts
|
||||
domain-needed
|
||||
no-negcache
|
||||
bogus-priv
|
||||
filterwin2k
|
||||
no-resolv
|
||||
server=9.9.9.9
|
||||
server=149.112.112.112
|
||||
|
||||
# Activer la journalisation pour voir les affectations DHCP/DNS
|
||||
log-queries
|
||||
log-dhcp
|
||||
|
||||
# Option DHCP
|
||||
dhcp-option=1,255.255.255.0
|
||||
# Passerelle par défaut
|
||||
dhcp-option=3,$IP_SERVEUR
|
||||
# DNS
|
||||
dhcp-option=6,$IP_SERVEUR
|
||||
# NIS Domain Name
|
||||
# dhcp-option=40,$DOMAINE
|
||||
# Domaine DNS
|
||||
dhcp-option=15,$DOMAINE
|
||||
# TTL des paquests (eviter les boucles réseau)
|
||||
dhcp-option=23,64
|
||||
# Taille MTU
|
||||
dhcp-option=26,1500
|
||||
# Désactiver NetBIOS sur Windows
|
||||
dhcp-option=43,01:04:00:00:00:02
|
||||
# Suffixe DNS
|
||||
dhcp-option=119,$DOMAINE
|
||||
# WPAD (Web Proxy Auto-Discovery Protocol)
|
||||
dhcp-option=252,"\n"
|
||||
dhcp-name-match=set:wpad-ignore,wpad
|
||||
dhcp-ignore-names=tag:wpad-ignore
|
||||
|
||||
EOF
|
||||
|
||||
# Redémarrer dnsmasq pour appliquer les modifications
|
||||
systemctl restart dnsmasq
|
||||
|
||||
# Modifier /etc/resolv.conf
|
||||
echo 'nameserver 127.0.0.1' > /etc/resolv.conf
|
||||
echo "Configuration DNS mise à jour sur 127.0.0.1"
|
||||
# Redémarrer les services nécessaires
|
||||
echo "Redémarrage des services..."
|
||||
for service in dnsmasq systemd-resolved networking NetworkManager; do
|
||||
if systemctl list-unit-files | grep -qw "${service}.service"; then
|
||||
echo "Redémarrage de $service..."
|
||||
if timeout 5s systemctl restart "$service" 2>/dev/null; then
|
||||
echo "$service redémarré."
|
||||
else
|
||||
echo "⚠️ Timeout ou erreur sur $service."
|
||||
fi
|
||||
else
|
||||
echo "Service $service non disponible sur ce système."
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Configuration terminée avec succès!"
|
||||
echo "Serveur DHCP/DNS fonctionnel sur $IP_SERVEUR"
|
||||
echo "Les clients recevront une IP entre $DHCP_START et $DHCP_END et seront associés au domaine $DOMAINE"
|
||||
88
scripts/server-dhcp/setup_nat_auto.sh
Normal file
88
scripts/server-dhcp/setup_nat_auto.sh
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
# Objectif : Faire du NAT du LAN vers le WAN
|
||||
|
||||
# Import des fonctions utilitaires communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérification des droits root
|
||||
check_root
|
||||
|
||||
echo "[+] Détection des interfaces réseau..."
|
||||
|
||||
# Détection de l'interface WAN (par défaut la passerelle)
|
||||
WAN_IF=$(ip route | grep default | awk '{print $5}' | head -n 1)
|
||||
if [[ -z "$WAN_IF" ]]; then
|
||||
echo "[❌] Aucune interface WAN détectée (pas de route par défaut)."
|
||||
exit 1
|
||||
fi
|
||||
echo "[+] Interface WAN détectée : $WAN_IF"
|
||||
|
||||
# Détection de l'interface LAN (IP privée autre que WAN_IF)
|
||||
LAN_IF=""
|
||||
LAN_IP=""
|
||||
LAN_SUBNET=""
|
||||
|
||||
while IFS= read -r line; do
|
||||
IFACE=$(echo "$line" | awk '{print $2}')
|
||||
IP_CIDR=$(echo "$line" | awk '{print $4}')
|
||||
IP_ADDR=${IP_CIDR%%/*}
|
||||
|
||||
# Vérifie que l'interface n'est pas celle du WAN et possède une IP privée
|
||||
if [[ "$IFACE" != "$WAN_IF" ]] && (
|
||||
[[ "$IP_ADDR" =~ ^192\.168\. ]] ||
|
||||
[[ "$IP_ADDR" =~ ^10\. ]] ||
|
||||
([[ "$IP_ADDR" =~ ^172\. ]] && [[ $(echo "$IP_ADDR" | cut -d. -f2) -ge 16 ]] && [[ $(echo "$IP_ADDR" | cut -d. -f2) -le 31 ]])
|
||||
); then
|
||||
LAN_IF="$IFACE"
|
||||
LAN_IP="$IP_ADDR"
|
||||
LAN_SUBNET="$IP_CIDR"
|
||||
break
|
||||
fi
|
||||
done < <(ip -o -4 addr show)
|
||||
|
||||
if [[ -z "$LAN_IF" || -z "$LAN_SUBNET" ]]; then
|
||||
echo "[❌] Impossible de détecter l'interface LAN ou le sous-réseau."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[+] Interface LAN détectée : $LAN_IF ($LAN_IP / $LAN_SUBNET)"
|
||||
echo "[ℹ️] Toutes les interfaces réseau :"
|
||||
ip -o -4 addr show | awk '{print "- Interface:", $2, "=> IP:", $4}'
|
||||
|
||||
if [[ "$LAN_IF" == "$WAN_IF" ]]; then
|
||||
echo "[❌] Erreur : L'interface LAN et WAN sont identiques ($WAN_IF). Corrige ta configuration réseau."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$LAN_IF" ]]; then
|
||||
echo "[+] Interface LAN détectée : $LAN_IF"
|
||||
echo "[+] Sous-réseau LAN détecté : $LAN_SUBNET"
|
||||
else
|
||||
echo "[⚠️] Aucune interface réseau avec une IP privée détectée."
|
||||
echo " Vérifiez votre configuration réseau ou connectez-vous à un réseau local."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
echo "[+] Mise à jour et installation des paquets nécessaires..."
|
||||
apt update -y
|
||||
apt install -y iptables iproute2
|
||||
|
||||
echo "[+] Activation de l'IP forwarding..."
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
sed -i '/^#net.ipv4.ip_forward=1/s/^#//' /etc/sysctl.conf
|
||||
sysctl -p
|
||||
|
||||
echo "[+] Nettoyage des anciennes règles iptables NAT..."
|
||||
iptables -t nat -F
|
||||
iptables -F
|
||||
|
||||
echo "[+] Mise en place du NAT (MASQUERADE)..."
|
||||
iptables -t nat -A POSTROUTING -s "$LAN_SUBNET" -o "$WAN_IF" -j MASQUERADE
|
||||
|
||||
echo "[+] Sauvegarde des règles iptables..."
|
||||
apt install -y iptables-persistent
|
||||
netfilter-persistent save
|
||||
|
||||
echo "[✅] NAT opérationnel : $LAN_SUBNET sort par $WAN_IF"
|
||||
5
scripts/server-httpd/.list_files.txt
Normal file
5
scripts/server-httpd/.list_files.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
add_domain.sh
|
||||
add_domain_ssl.sh
|
||||
install-php8-3.sh
|
||||
set-permissions-www.sh
|
||||
setup_httpd.sh
|
||||
51
scripts/server-httpd/add_domain.sh
Executable file
51
scripts/server-httpd/add_domain.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
DOMAIN="$1"
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Vérification DNS (alerte non bloquante)
|
||||
if ! check_dns "$DOMAIN"; then
|
||||
echo "⚠️ Attention : Résolution DNS impossible pour $DOMAIN. Vérifie si c'est bien ce que tu veux."
|
||||
fi
|
||||
|
||||
REVERSED_DOMAIN=$(echo "$DOMAIN" | awk -F. '{for(i=NF; i>0; i--) printf "%s%s", $i, (i>1 ? "." : "")}')
|
||||
VHOST_CONF="/etc/apache2/sites-available/$REVERSED_DOMAIN.conf"
|
||||
|
||||
# Préparer le dossier du VirtualHost
|
||||
mkdir -p "/var/www/$REVERSED_DOMAIN"
|
||||
chown -R www-data:www-data "/var/www/$REVERSED_DOMAIN"
|
||||
chmod -R 755 "/var/www/$REVERSED_DOMAIN"
|
||||
|
||||
# Vérifier si le VirtualHost HTTP existe déjà
|
||||
if [[ ! -f "$VHOST_CONF" ]]; then
|
||||
echo "=== Création du fichier VirtualHost HTTP pour $DOMAIN ==="
|
||||
cat > "$VHOST_CONF" <<EOF
|
||||
<VirtualHost *:80>
|
||||
ServerName $DOMAIN
|
||||
DocumentRoot /var/www/$REVERSED_DOMAIN
|
||||
ErrorLog \${APACHE_LOG_DIR}/$REVERSED_DOMAIN-error.log
|
||||
CustomLog \${APACHE_LOG_DIR}/$REVERSED_DOMAIN-access.log combined
|
||||
|
||||
<Directory /var/www/$REVERSED_DOMAIN>
|
||||
Options +Indexes
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
</VirtualHost>
|
||||
EOF
|
||||
# Activer le VirtualHost et recharger Apache
|
||||
a2ensite "$REVERSED_DOMAIN"
|
||||
systemctl reload apache2
|
||||
else
|
||||
echo "✅ VirtualHost HTTP déjà configuré pour $DOMAIN."
|
||||
fi
|
||||
|
||||
echo "✅ Virtual Host configuré pour $DOMAIN avec succès !"
|
||||
exit 0
|
||||
15
scripts/server-httpd/add_domain_ssl.sh
Executable file
15
scripts/server-httpd/add_domain_ssl.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
DOMAIN="$1"
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Vérification DNS
|
||||
check_dns "$DOMAIN"
|
||||
|
||||
setup_ssl "$DOMAIN"
|
||||
165
scripts/server-httpd/install-php8-3.sh
Executable file
165
scripts/server-httpd/install-php8-3.sh
Executable file
@@ -0,0 +1,165 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Définition des couleurs pour un affichage clair
|
||||
GREEN="\e[32m"
|
||||
YELLOW="\e[33m"
|
||||
RED="\e[31m"
|
||||
RESET="\e[0m"
|
||||
|
||||
echo -e "${YELLOW}Mise à jour des paquets...${RESET}"
|
||||
apt update && apt upgrade -y || { echo -e "${RED}Échec de la mise à jour des paquets${RESET}"; exit 1; }
|
||||
|
||||
# Détection de la version de Debian
|
||||
VERSION=$(lsb_release -sc)
|
||||
SUPPORTED_VERSIONS=("buster" "bullseye" "bookworm")
|
||||
|
||||
TIMEZONE=$(timedatectl show --value --property=Timezone)
|
||||
|
||||
if [[ ! " ${SUPPORTED_VERSIONS[@]} " =~ " ${VERSION} " ]]; then
|
||||
echo -e "${RED}Version de Debian non supportée : $VERSION${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Version de Debian détectée : $VERSION${RESET}"
|
||||
|
||||
# Vérification de l'existence du dépôt Sury
|
||||
if ! grep -q "packages.sury.org" /etc/apt/sources.list.d/php.list 2>/dev/null; then
|
||||
echo -e "${YELLOW}Ajout du dépôt Sury pour PHP...${RESET}"
|
||||
apt install -y ca-certificates apt-transport-https software-properties-common || { echo -e "${RED}Échec de l'installation des paquets nécessaires${RESET}"; exit 1; }
|
||||
wget -qO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg || { echo -e "${RED}Échec du téléchargement de la clé GPG de Sury${RESET}"; exit 1; }
|
||||
echo "deb https://packages.sury.org/php/ $VERSION main" | tee /etc/apt/sources.list.d/php.list
|
||||
apt update
|
||||
else
|
||||
echo -e "${GREEN}Le dépôt Sury est déjà installé.${RESET}"
|
||||
fi
|
||||
|
||||
# Définition de la version PHP souhaitée
|
||||
PHP_VERSION="8.3"
|
||||
|
||||
PHP_INI_CLI="/etc/php/${PHP_VERSION}/cli/php.ini"
|
||||
PHP_INI_APACHE="/etc/php/${PHP_VERSION}/apache2/php.ini"
|
||||
|
||||
# Vérification de l'installation de PHP
|
||||
echo -e "${YELLOW}Installation de PHP $PHP_VERSION et des modules courants...${RESET}"
|
||||
|
||||
# Base des modules PHP à installer
|
||||
PHP_MODULES=(
|
||||
php${PHP_VERSION}
|
||||
php${PHP_VERSION}-cli
|
||||
php${PHP_VERSION}-fpm
|
||||
php${PHP_VERSION}-curl
|
||||
php${PHP_VERSION}-gd
|
||||
php${PHP_VERSION}-mbstring
|
||||
php${PHP_VERSION}-xml
|
||||
php${PHP_VERSION}-zip
|
||||
php${PHP_VERSION}-bcmath
|
||||
php${PHP_VERSION}-soap
|
||||
php${PHP_VERSION}-intl
|
||||
php${PHP_VERSION}-readline
|
||||
php${PHP_VERSION}-ldap
|
||||
php${PHP_VERSION}-imagick
|
||||
php${PHP_VERSION}-exif
|
||||
php${PHP_VERSION}-gmp
|
||||
php${PHP_VERSION}-apcu
|
||||
php${PHP_VERSION}-opcache
|
||||
php${PHP_VERSION}-sqlite3
|
||||
)
|
||||
|
||||
# Vérification MySQL / MariaDB
|
||||
if dpkg -l | grep -qE 'mysql-server|mariadb-server'; then
|
||||
echo -e "${GREEN}MySQL/MariaDB détecté. Ajout du module php-mysql.${RESET}"
|
||||
PHP_MODULES+=(php${PHP_VERSION}-mysql)
|
||||
fi
|
||||
|
||||
# Vérification PostgreSQL
|
||||
if dpkg -l | grep -q postgresql; then
|
||||
echo -e "${GREEN}PostgreSQL détecté. Ajout du module php-pgsql.${RESET}"
|
||||
PHP_MODULES+=(php${PHP_VERSION}-pgsql)
|
||||
fi
|
||||
|
||||
# Installation des modules PHP
|
||||
echo -e "${GREEN}Installation des modules PHP...${RESET}"
|
||||
apt install -y "${PHP_MODULES[@]}" || {
|
||||
echo -e "${RED}❌ Échec de l'installation de PHP ou des modules.${RESET}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Vérification si Apache est installé et installation du module PHP si nécessaire
|
||||
if systemctl list-units --type=service --all | grep -q "apache2.service"; then
|
||||
echo -e "${YELLOW}Apache détecté. Installation de libapache2-mod-php${RESET}"
|
||||
apt install -y libapache2-mod-php$PHP_VERSION || { echo -e "${RED}Échec de l'installation de libapache2-mod-php${RESET}"; exit 1; }
|
||||
|
||||
echo -e "${YELLOW}Redémarrage d'Apache...${RESET}"
|
||||
systemctl restart apache2 || { echo -e "${RED}Échec du redémarrage d'Apache${RESET}"; exit 1; }
|
||||
fi
|
||||
|
||||
# Configuration de PHP-FPM si ce n'est pas déjà fait
|
||||
PHP_INI="/etc/php/$PHP_VERSION/fpm/php.ini"
|
||||
PHP_INI_DIR="/etc/php/${PHP_VERSION}/fpm/conf.d"
|
||||
|
||||
if grep -q "memory_limit = 512M" "$PHP_INI"; then
|
||||
echo -e "${GREEN}Configuration de PHP-FPM déjà optimisée.${RESET}"
|
||||
else
|
||||
echo -e "${YELLOW}Configuration de PHP-FPM...${RESET}"
|
||||
sed -i 's/memory_limit = .*/memory_limit = 512M/' "$PHP_INI"
|
||||
sed -i 's/upload_max_filesize = .*/upload_max_filesize = 100M/' "$PHP_INI"
|
||||
sed -i 's/post_max_size = .*/post_max_size = 100M/' "$PHP_INI"
|
||||
sed -i 's/max_execution_time = .*/max_execution_time = 300/' "$PHP_INI"
|
||||
|
||||
echo -e "${YELLOW}Redémarrage de PHP-FPM...${RESET}"
|
||||
systemctl restart php$PHP_VERSION-fpm || { echo -e "${RED}Échec du redémarrage de PHP-FPM${RESET}"; exit 1; }
|
||||
fi
|
||||
|
||||
# Configuration OPCache
|
||||
OPCACHE_INI="${PHP_INI_DIR}/10-opcache.ini"
|
||||
cat > "$OPCACHE_INI" <<EOF
|
||||
; Configuration OPcache optimisée
|
||||
opcache.enable=1
|
||||
opcache.memory_consumption=128
|
||||
opcache.interned_strings_buffer=16
|
||||
opcache.max_accelerated_files=10000
|
||||
opcache.revalidate_freq=60
|
||||
opcache.fast_shutdown=1
|
||||
opcache.enable_cli=1
|
||||
EOF
|
||||
echo "==> Fichier $OPCACHE_INI mis à jour."
|
||||
|
||||
# Configuration APCu
|
||||
APCU_INI="${PHP_INI_DIR}/20-apcu.ini"
|
||||
cat > "$APCU_INI" <<EOF
|
||||
; Configuration APCu optimisée
|
||||
apc.enabled=1
|
||||
apc.shm_size=64M
|
||||
apc.ttl=7200
|
||||
apc.enable_cli=0
|
||||
EOF
|
||||
echo "==> Fichier $APCU_INI mis à jour."
|
||||
|
||||
# Définir la timezone PHP pour CLI et Apache
|
||||
sed -i "s|^;*date.timezone =.*|date.timezone = ${TIMEZONE}|" "${PHP_INI_CLI}"
|
||||
sed -i "s|^;*date.timezone =.*|date.timezone = ${TIMEZONE}|" "${PHP_INI_APACHE}"
|
||||
|
||||
# Test de la configuration Apache
|
||||
if systemctl is-active --quiet apache2; then
|
||||
read -rp "Voulez-vous tester le support de PHP par Apache ? (o/n) : " test_php
|
||||
if [[ "$test_php" =~ ^[oOyY]$ ]]; then
|
||||
echo -e "${YELLOW}Vérification du support de PHP par Apache...${RESET}"
|
||||
echo "<?php phpinfo(); ?>" > /var/www/html/info.php
|
||||
chown www-data:www-data /var/www/html/info.php
|
||||
chmod 644 /var/www/html/info.php
|
||||
echo -e "${GREEN}Vous pouvez tester PHP en accédant à : http://<IP_SERVEUR>/info.php${RESET}"
|
||||
else
|
||||
echo -e "${YELLOW}Test PHP annulé.${RESET}"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}Le service Apache n'est pas actif.${RESET}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Installation terminée avec succès ! 🚀${RESET}"
|
||||
70
scripts/server-httpd/set-permissions-www.sh
Executable file
70
scripts/server-httpd/set-permissions-www.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
WWW_DIR="/var/www"
|
||||
CURRENT_USER="${SUDO_USER:-$(whoami)}"
|
||||
|
||||
echo "Correction des permissions de $WWW_DIR/html si nécessaire..."
|
||||
if [ -d "$WWW_DIR/html" ]; then
|
||||
OWNER_GROUP=$(stat -c "%U:%G" "$WWW_DIR/html")
|
||||
if [ "$OWNER_GROUP" != "www-data:www-data" ]; then
|
||||
sudo chown -R www-data:www-data "$WWW_DIR/html"
|
||||
echo "Propriétaire de $WWW_DIR/html corrigé en www-data:www-data"
|
||||
else
|
||||
echo "$WWW_DIR/html est déjà correctement configuré."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Liste des dossiers dans $WWW_DIR :"
|
||||
dirs=()
|
||||
i=1
|
||||
for d in "$WWW_DIR"/*/; do
|
||||
folder=$(basename "$d")
|
||||
dirs+=("$folder")
|
||||
echo "[$i] $folder"
|
||||
((i++))
|
||||
done
|
||||
|
||||
echo "[0] Tous les dossiers"
|
||||
|
||||
read -p "Sur quel dossier appliquer la règle ? (Entrer le numéro ou 0 pour tous) : " choix
|
||||
|
||||
# Ajout de l'utilisateur courant au groupe www-data
|
||||
if id -nG "$CURRENT_USER" | grep -qw "www-data"; then
|
||||
echo "L'utilisateur $CURRENT_USER est déjà dans le groupe www-data"
|
||||
else
|
||||
echo "Ajout de $CURRENT_USER au groupe www-data..."
|
||||
usermod -aG www-data "$CURRENT_USER"
|
||||
fi
|
||||
|
||||
# Fonction d'application des droits
|
||||
apply_permissions() {
|
||||
dossier="$1"
|
||||
echo "Application des permissions sur $WWW_DIR/$dossier ..."
|
||||
chown -R www-data:www-data "$WWW_DIR/$dossier"
|
||||
chmod -R g+rwX "$WWW_DIR/$dossier"
|
||||
}
|
||||
|
||||
if [ "$choix" -eq 0 ]; then
|
||||
for d in "${dirs[@]}"; do
|
||||
apply_permissions "$d"
|
||||
done
|
||||
else
|
||||
index=$((choix - 1))
|
||||
if [ "$index" -ge 0 ] && [ "$index" -lt "${#dirs[@]}" ]; then
|
||||
apply_permissions "${dirs[$index]}"
|
||||
else
|
||||
echo "Choix invalide."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Opération terminée. Pensez à vous déconnecter/reconnecter si c'est la première fois que vous rejoignez le groupe www-data."
|
||||
180
scripts/server-httpd/setup_httpd.sh
Executable file
180
scripts/server-httpd/setup_httpd.sh
Executable file
@@ -0,0 +1,180 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Mise à jour du système
|
||||
update_system
|
||||
|
||||
# Installation d'Apache et des outils nécessaires
|
||||
echo "=== Installation d'Apache et des outils nécessaires ==="
|
||||
apt install -y apache2 curl dnsutils certbot python3-certbot-apache
|
||||
|
||||
# Activer et démarrer Apache uniquement si ce n'est pas déjà fait
|
||||
echo "=== Activation et démarrage d'Apache ==="
|
||||
systemctl is-enabled apache2 || systemctl enable apache2
|
||||
systemctl is-active --quiet apache2 || systemctl start apache2
|
||||
|
||||
# Activer les modules nécessaires uniquement s'ils ne le sont pas déjà
|
||||
MODULES=(rewrite ssl headers http2 socache_shmcb proxy proxy_http setenvif)
|
||||
for MODULE in "${MODULES[@]}"; do
|
||||
if ! a2query -m "$MODULE" >/dev/null 2>&1; then
|
||||
a2enmod "$MODULE"
|
||||
fi
|
||||
done
|
||||
systemctl reload apache2
|
||||
|
||||
# Récupérer le FQDN
|
||||
FQDN=$(get_fqdn_and_domain | awk '{print $1}')
|
||||
echo "🔍 Serveur détecté : $FQDN"
|
||||
|
||||
# Vérification DNS
|
||||
check_dns "$FQDN"
|
||||
|
||||
# Configurer le VirtualHost uniquement si ce n'est pas déjà fait
|
||||
echo "=== Configuration du Virtual Host pour $FQDN ==="
|
||||
if ! grep -q "ServerName $FQDN" /etc/apache2/sites-available/*.conf; then
|
||||
./add_domain.sh "$FQDN"
|
||||
EXIT_CODE=$?
|
||||
if [[ $EXIT_CODE -ne 0 ]]; then
|
||||
echo "❌ Échec de la configuration du serveur ($FQDN). Code erreur : $EXIT_CODE"
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configuration SSL uniquement si nécessaire
|
||||
setup_ssl "$FQDN"
|
||||
|
||||
# Sécurisation des accès
|
||||
echo "=== Sécurisation des accès ==="
|
||||
SECURITY_CONF="/etc/apache2/conf-available/security.conf"
|
||||
# Vérifier si le fichier existe et contient déjà la configuration
|
||||
if [ ! -f "$SECURITY_CONF" ]; then
|
||||
echo "Création de $SECURITY_CONF avec les paramètres de sécurité."
|
||||
cat <<EOF > "$SECURITY_CONF"
|
||||
<Directory />
|
||||
AllowOverride None
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
<FilesMatch "\.(htaccess|htpasswd|env|ini|log|sh|bak)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
EOF
|
||||
a2enconf security
|
||||
systemctl reload apache2
|
||||
echo "Configuration de sécurité appliquée et rechargement d'Apache."
|
||||
else
|
||||
echo "Le fichier $SECURITY_CONF existe déjà. Aucune modification nécessaire."
|
||||
fi
|
||||
|
||||
# Vérifier si le fichier de configuration existe
|
||||
if [ -f "$SECURITY_CONF" ]; then
|
||||
# Vérifier si les directives sont déjà présentes pour éviter les doublons
|
||||
if ! grep -q "Header always unset X-Powered-By" "$SECURITY_CONF"; then
|
||||
echo "Ajout des directives de sécurité HTTP à $SECURITY_CONF."
|
||||
cat <<EOF >> "$SECURITY_CONF"
|
||||
|
||||
# Renforcement des en-têtes HTTP
|
||||
ServerTokens Prod
|
||||
ServerSignature Off
|
||||
TraceEnable Off
|
||||
Header always unset X-Powered-By
|
||||
EOF
|
||||
echo "Configuration mise à jour et rechargement d'Apache."
|
||||
else
|
||||
echo "Les directives de sécurité HTTP sont déjà présentes. Aucune modification nécessaire."
|
||||
fi
|
||||
else
|
||||
echo "Erreur : le fichier $SECURITY_CONF n'existe pas. Assurez-vous que la configuration de sécurité est en place."
|
||||
fi
|
||||
|
||||
# Activer HTTP Strict Transport Security (HSTS) uniquement si nécessaire
|
||||
SSL_CONF="/etc/apache2/sites-available/default-ssl.conf"
|
||||
if ! grep -q "Strict-Transport-Security" "$SSL_CONF"; then
|
||||
echo "Header always set Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\"" >> "$SSL_CONF"
|
||||
fi
|
||||
|
||||
|
||||
# Activation de l'OCSP Stapling uniquement si nécessaire
|
||||
echo "=== Activation de l'OCSP Stapling ==="
|
||||
# Vérifier si le fichier de configuration SSL existe
|
||||
if [ -f "$SSL_CONF" ]; then
|
||||
# Vérifier si l'option est déjà activée pour éviter les doublons
|
||||
if ! grep -q "^SSLUseStapling on" "$SSL_CONF"; then
|
||||
echo "Ajout des directives OCSP Stapling à $SSL_CONF."
|
||||
cat <<EOF >> "$SSL_CONF"
|
||||
|
||||
# Configuration OCSP Stapling
|
||||
SSLUseStapling on
|
||||
SSLStaplingResponderTimeout 5
|
||||
SSLStaplingReturnResponderErrors off
|
||||
SSLStaplingCache shmcb:/var/run/ocsp(128000)
|
||||
EOF
|
||||
systemctl reload apache2
|
||||
echo "Configuration OCSP Stapling mise à jour et rechargement d'Apache."
|
||||
else
|
||||
echo "OCSP Stapling est déjà activé. Aucune modification nécessaire."
|
||||
fi
|
||||
else
|
||||
echo "Erreur : le fichier $SSL_CONF n'existe pas. Assurez-vous que le module SSL est bien installé."
|
||||
fi
|
||||
|
||||
# Désactivation des chiffres faibles et renforcement TLS
|
||||
echo "=== Renforcement de la configuration SSL/TLS ==="
|
||||
|
||||
SSL_MOD_CONF="/etc/apache2/mods-available/ssl.conf"
|
||||
|
||||
# Vérifier si le fichier de configuration SSL existe
|
||||
if [ -f "$SSL_MOD_CONF" ]; then
|
||||
# Vérifier si la configuration est déjà appliquée pour éviter les doublons
|
||||
if ! grep -q "^SSLProtocol -all +TLSv1.2 +TLSv1.3" "$SSL_MOD_CONF"; then
|
||||
echo "Ajout des directives SSL/TLS sécurisées à $SSL_MOD_CONF."
|
||||
cat <<EOF >> "$SSL_MOD_CONF"
|
||||
|
||||
# Renforcement de la configuration SSL/TLS
|
||||
SSLProtocol -all +TLSv1.2 +TLSv1.3
|
||||
SSLCipherSuite TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
|
||||
SSLHonorCipherOrder on
|
||||
SSLCompression off
|
||||
SSLSessionTickets off
|
||||
EOF
|
||||
systemctl reload apache2
|
||||
echo "Configuration SSL/TLS mise à jour et rechargement d'Apache."
|
||||
else
|
||||
echo "La configuration SSL/TLS est déjà sécurisée. Aucune modification nécessaire."
|
||||
fi
|
||||
else
|
||||
echo "Erreur : le fichier $SSL_MOD_CONF n'existe pas. Assurez-vous que le module SSL est bien installé."
|
||||
fi
|
||||
|
||||
|
||||
# Limitation de la taille des requêtes (éviter les doublons)
|
||||
echo "=== Limitation de la taille des requêtes ==="
|
||||
if ! grep -q "LimitRequestBody" "$SECURITY_CONF"; then
|
||||
echo "LimitRequestBody 10485760" >> "$SECURITY_CONF"
|
||||
fi
|
||||
|
||||
# Vérifier la configuration avant rechargement
|
||||
echo "=== Vérification de la configuration Apache ==="
|
||||
apachectl configtest
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "❌ Erreur dans la configuration Apache !"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Appliquer des permissions sécurisées (éviter les erreurs si déjà appliquées)
|
||||
echo "=== Sécurisation des permissions des fichiers de configuration ==="
|
||||
chmod 640 /etc/apache2/sites-available/* 2>/dev/null
|
||||
chmod 640 /etc/apache2/conf-available/* 2>/dev/null
|
||||
chown root:root /etc/apache2/sites-available/* 2>/dev/null
|
||||
chown root:root /etc/apache2/conf-available/* 2>/dev/null
|
||||
|
||||
# Rechargement final d'Apache
|
||||
systemctl reload apache2
|
||||
|
||||
echo "✅ Installation et sécurisation d'Apache terminées !"
|
||||
13
scripts/server-mail/.list_files.txt
Normal file
13
scripts/server-mail/.list_files.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
add_alias.sh
|
||||
add_domain.sh
|
||||
add_forward.sh
|
||||
add_user.sh
|
||||
del_alias.sh
|
||||
del_domain.sh
|
||||
del_user.sh
|
||||
generate_password.sh
|
||||
list_aliases.sh
|
||||
list_domains_.sh
|
||||
list_users.sh
|
||||
README.md
|
||||
setup_mail.sh
|
||||
39
scripts/server-mail/README.md
Normal file
39
scripts/server-mail/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# **📌 Résumé des Scripts**
|
||||
| **Script** | **Action** | **Exemple d'utilisation** |
|
||||
|----------------------|-----------------------------------------------|--------------------------|
|
||||
| `install_mailserver.sh` | Installer Postfix/Dovecot + ajouter un domaine | `./install_mailserver.sh domain.top` |
|
||||
| `add_domain.sh` | Ajouter un domaine | `./add_domain.sh domain2.top` |
|
||||
| `add_user.sh` | Ajouter un utilisateur | `./add_user.sh user@domain.top` |
|
||||
| `generate_passowrd.sh` | Generer un mot de passe pour un utilisateur | `./generate_password.sh user@domain.top` |
|
||||
| `add_alias.sh` | Ajouter un alias | `./add_alias.sh contact@domain2.top user@domain.top` |
|
||||
| `add_forward.sh` | Ajouter une redirection | `./add_forward.sh contact@domain.top user@domain2.top` |
|
||||
| `list_domains.sh` | Lister les domaines | `./list_domains.sh` |
|
||||
| `list_users.sh` | Lister les utilisateurs | `./list_users.sh` |
|
||||
| `list_aliases.sh` | Lister les alias/redirections | `./list_aliases.sh` |
|
||||
| `del_user.sh` | Supprimer un utilisateur | `./del_user.sh user@domain.top` |
|
||||
| `del_alias.sh` | Supprimer un alias | `./del_alias.sh contact@domain2.top` |
|
||||
| `del_domain.sh` | Supprimer un domaine | `./del_domain.sh domain2.top` |
|
||||
|
||||
---
|
||||
|
||||
## 📥 Récupération des scripts
|
||||
|
||||
Pour télécharger uniquement les scripts `.sh` du dossier `server-mail/scripts`, utilisez la commande suivante :
|
||||
|
||||
```bash
|
||||
wget -O scripts.txt "https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/scripts/server-mail/.list_files.txt"
|
||||
while read -r url; do
|
||||
wget -O "$(basename "$url")" "$url"
|
||||
done < scripts.txt
|
||||
chmod +x *.sh
|
||||
|
||||
```
|
||||
|
||||
Tous les fichiers listés dans scripts.txt seront téléchargés automatiquement dans le dossier courant.
|
||||
|
||||
Assurez-vous d’exécuter cette commande dans le dossier où vous souhaitez stocker les fichiers.
|
||||
19
scripts/server-mail/add_alias.sh
Executable file
19
scripts/server-mail/add_alias.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
POSTFIX_ALIASES="/etc/postfix/virtual_aliases"
|
||||
|
||||
if [[ -z "$1" || -z "$2" ]]; then
|
||||
echo "Usage: $0 <alias> <cible>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ALIAS=$1
|
||||
TARGET=$2
|
||||
|
||||
echo "$ALIAS $TARGET" >> $POSTFIX_ALIASES
|
||||
|
||||
postmap $POSTFIX_ALIASES
|
||||
systemctl reload postfix
|
||||
|
||||
echo "Alias $ALIAS ajouté vers $TARGET 🎉"
|
||||
54
scripts/server-mail/add_domain.sh
Executable file
54
scripts/server-mail/add_domain.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Définition des variables
|
||||
MAILDIR="/var/mail/vhosts"
|
||||
POSTFIX_CONFIG="/etc/postfix/virtual_domains"
|
||||
USER_VMAIL="vmail"
|
||||
GROUP_VMAIL="vmail"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "❌ Ce script doit être exécuté en tant que root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier si un domaine a été passé en paramètre
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 <domaine>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DOMAIN=$1
|
||||
|
||||
# Vérifier si le domaine est déjà enregistré
|
||||
if grep -q "^$DOMAIN$" "$POSTFIX_CONFIG"; then
|
||||
echo "⚠️ Le domaine $DOMAIN est déjà configuré dans Postfix."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔹 Ajout du domaine : $DOMAIN"
|
||||
echo "$DOMAIN" >> "$POSTFIX_CONFIG"
|
||||
|
||||
# Création du répertoire pour le domaine
|
||||
DOMAIN_DIR="$MAILDIR/$DOMAIN"
|
||||
if [[ ! -d "$DOMAIN_DIR" ]]; then
|
||||
echo "📁 Création du dossier mail pour $DOMAIN"
|
||||
mkdir -p "$DOMAIN_DIR"
|
||||
chown -R "$USER_VMAIL:$GROUP_VMAIL" "$DOMAIN_DIR"
|
||||
chmod -R 770 "$DOMAIN_DIR"
|
||||
else
|
||||
echo "⚠️ Le dossier $DOMAIN_DIR existe déjà."
|
||||
fi
|
||||
|
||||
# Recharger Postfix pour appliquer les changements
|
||||
echo "🔄 Rechargement de Postfix..."
|
||||
systemctl reload postfix
|
||||
|
||||
# Vérification de la bonne prise en compte
|
||||
if systemctl is-active --quiet postfix; then
|
||||
echo "✅ Domaine $DOMAIN ajouté avec succès et Postfix rechargé 🎉"
|
||||
else
|
||||
echo "❌ Erreur : Postfix ne fonctionne pas correctement après la mise à jour."
|
||||
exit 1
|
||||
fi
|
||||
22
scripts/server-mail/add_forward.sh
Executable file
22
scripts/server-mail/add_forward.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
POSTFIX_ALIASES="/etc/postfix/virtual_aliases"
|
||||
|
||||
if [[ -z "$1" || -z "$2" ]]; then
|
||||
echo "Usage: $0 <adresse_source> <adresse_cible1> [adresse_cible2] ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SOURCE=$1
|
||||
shift # Supprime le premier argument (l'adresse source)
|
||||
TARGETS="$@"
|
||||
|
||||
echo "Ajout de la redirection de $SOURCE vers $TARGETS"
|
||||
|
||||
echo "$SOURCE $TARGETS" >> $POSTFIX_ALIASES
|
||||
|
||||
postmap $POSTFIX_ALIASES
|
||||
systemctl reload postfix
|
||||
|
||||
echo "Redirection de $SOURCE vers $TARGETS ajoutée"
|
||||
30
scripts/server-mail/add_user.sh
Executable file
30
scripts/server-mail/add_user.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
DOVECOT_USERS="/etc/dovecot/users"
|
||||
MAILDIR="/var/mail/vhosts"
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 <adresse email>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EMAIL=$1
|
||||
DOMAIN=$(echo $EMAIL | cut -d@ -f2)
|
||||
USER=$(echo $EMAIL | cut -d@ -f1)
|
||||
|
||||
# Vérifier si l'utilisateur existe déjà
|
||||
if grep -q "^$EMAIL:" "$DOVECOT_USERS"; then
|
||||
echo "Erreur : L'utilisateur $EMAIL existe déjà."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ajouter l'utilisateur sans mot de passe
|
||||
echo "$EMAIL:" >> "$DOVECOT_USERS"
|
||||
|
||||
# Création du répertoire de messagerie
|
||||
mkdir -p "$MAILDIR/$DOMAIN/$USER"
|
||||
chown -R vmail:vmail "$MAILDIR/$DOMAIN/$USER"
|
||||
chmod -R 770 "$MAILDIR/$DOMAIN/$USER"
|
||||
|
||||
echo "Utilisateur $EMAIL créé avec succès. Utilisez 'generate_password.sh $EMAIL' pour lui assigner un mot de passe."
|
||||
21
scripts/server-mail/del_alias.sh
Executable file
21
scripts/server-mail/del_alias.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
POSTFIX_ALIASES="/etc/postfix/virtual_aliases"
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 <alias>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ALIAS=$1
|
||||
|
||||
echo "Suppression de l'alias : $ALIAS"
|
||||
|
||||
# Supprimer l'entrée de l'alias
|
||||
sed -i "/^$ALIAS /d" $POSTFIX_ALIASES
|
||||
|
||||
postmap $POSTFIX_ALIASES
|
||||
systemctl reload postfix
|
||||
|
||||
echo "Alias $ALIAS supprimé"
|
||||
24
scripts/server-mail/del_domain.sh
Executable file
24
scripts/server-mail/del_domain.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
MAILDIR="/var/mail/vhosts"
|
||||
POSTFIX_CONFIG="/etc/postfix/virtual_domains"
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 <domaine>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DOMAIN=$1
|
||||
|
||||
echo "Suppression du domaine : $DOMAIN"
|
||||
|
||||
# Supprimer le domaine du fichier de Postfix
|
||||
sed -i "/^$DOMAIN$/d" $POSTFIX_CONFIG
|
||||
|
||||
# Supprimer les boîtes mail associées
|
||||
rm -rf $MAILDIR/$DOMAIN
|
||||
|
||||
systemctl reload postfix
|
||||
|
||||
echo "Domaine $DOMAIN supprimé"
|
||||
24
scripts/server-mail/del_user.sh
Executable file
24
scripts/server-mail/del_user.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
DOVECOT_USERS="/etc/dovecot/users"
|
||||
MAILDIR="/var/mail/vhosts"
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 <adresse mail>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EMAIL=$1
|
||||
DOMAIN=$(echo $EMAIL | cut -d@ -f2)
|
||||
USER=$(echo $EMAIL | cut -d@ -f1)
|
||||
|
||||
echo "Suppression de l'utilisateur : $EMAIL"
|
||||
|
||||
# Supprimer l'entrée du fichier des utilisateurs
|
||||
sed -i "/^$EMAIL:/d" $DOVECOT_USERS
|
||||
|
||||
# Supprimer le répertoire de la boîte mail
|
||||
rm -rf $MAILDIR/$DOMAIN/$USER
|
||||
|
||||
echo "Utilisateur $EMAIL supprimé"
|
||||
86
scripts/server-mail/generate_password.sh
Executable file
86
scripts/server-mail/generate_password.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Récupérer le nom d’hôte complet (FQDN)
|
||||
SERVER_NAME=$(hostname -f) # Privilégier hostname -f
|
||||
|
||||
# Vérifier si le FQDN est vide (cas rare)
|
||||
if [[ -z "$SERVER_NAME" ]]; then
|
||||
SERVER_NAME=$(cat /etc/hostname) # Lecture depuis /etc/hostname
|
||||
fi
|
||||
|
||||
# Construire l'URL du serveur
|
||||
SERVER_URL="http://$SERVER_NAME/passwords"
|
||||
|
||||
echo "Serveur détecté : $SERVER_NAME"
|
||||
|
||||
DOVECOT_USERS="/etc/dovecot/users"
|
||||
WEB_DIR="/var/www/passwords"
|
||||
EXPIRATION_TIME=600 # 10 minutes avant suppression
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 <adresse email>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EMAIL=$1
|
||||
|
||||
# Vérifier si l'utilisateur existe
|
||||
if ! grep -q "^$EMAIL:" "$DOVECOT_USERS"; then
|
||||
echo "Erreur : L'utilisateur $EMAIL n'existe pas. Utilisez 'create_user.sh' d'abord."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Génération d'un mot de passe sécurisé
|
||||
PASSWORD=$(tr -dc 'A-Za-z0-9@#%&*()-_=+' </dev/urandom | head -c 20)
|
||||
|
||||
# Hachage sécurisé du mot de passe
|
||||
HASHED_PASS=$(doveadm pw -s SHA512-CRYPT -p "$PASSWORD")
|
||||
|
||||
# Mettre à jour le mot de passe dans le fichier des utilisateurs
|
||||
sed -i "s|^$EMAIL:.*|$EMAIL:$HASHED_PASS|" "$DOVECOT_USERS"
|
||||
|
||||
# Génération d'un lien temporaire
|
||||
mkdir -p "$WEB_DIR"
|
||||
chmod 750 "$WEB_DIR"
|
||||
|
||||
FILE_ID=$(uuidgen)
|
||||
FILE_PATH="$WEB_DIR/$FILE_ID.html"
|
||||
|
||||
# Création de la page HTML temporaire
|
||||
cat <<EOF > "$FILE_PATH"
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Votre nouveau mot de passe</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
|
||||
.container { background: #f4f4f4; padding: 20px; border-radius: 10px; display: inline-block; }
|
||||
h1 { color: #333; }
|
||||
.password { font-size: 20px; font-weight: bold; background: #ddd; padding: 10px; border-radius: 5px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Votre nouveau mot de passe</h1>
|
||||
<p>Adresse email : <strong>$EMAIL</strong></p>
|
||||
<p>Mot de passe temporaire :</p>
|
||||
<p class="password">$PASSWORD</p>
|
||||
<p><strong>Notez-le, cette page sera supprimée après consultation.</strong></p>
|
||||
</div>
|
||||
<script>
|
||||
fetch(window.location.href, { method: 'DELETE' }).then(() => console.log('Fichier supprimé'));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
chmod 600 "$FILE_PATH"
|
||||
|
||||
# Suppression automatique après expiration
|
||||
(sleep $EXPIRATION_TIME && rm -f "$FILE_PATH") &
|
||||
|
||||
echo "Mot de passe mis à jour pour $EMAIL"
|
||||
echo "Lien temporaire pour récupérer le mot de passe : $SERVER_URL/$FILE_ID.html"
|
||||
5
scripts/server-mail/list_aliases.sh
Executable file
5
scripts/server-mail/list_aliases.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
echo "=== Liste des alias et redirections ==="
|
||||
cat /etc/postfix/virtual_aliases
|
||||
5
scripts/server-mail/list_domains_.sh
Executable file
5
scripts/server-mail/list_domains_.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
echo "=== Liste des domaines gérés ==="
|
||||
cat /etc/postfix/virtual_domains
|
||||
5
scripts/server-mail/list_users.sh
Executable file
5
scripts/server-mail/list_users.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
echo "=== Liste des utilisateurs ==="
|
||||
cat /etc/dovecot/users | cut -d: -f1
|
||||
92
scripts/server-mail/setup_mail.sh
Executable file
92
scripts/server-mail/setup_mail.sh
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Mise à jour du système
|
||||
update_system
|
||||
|
||||
# Installation de Postfix, Dovecot et outils nécessaires
|
||||
echo "=== Installation de Postfix, Dovecot et outils nécessaires ==="
|
||||
apt install -y postfix dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-sieve certbot curl dnsutils
|
||||
|
||||
# Récupérer le FQDN et le domaine
|
||||
read FQDN DOMAIN <<< $(get_fqdn_and_domain)
|
||||
echo "🔍 Serveur détecté : $FQDN"
|
||||
echo "🌐 Domaine géré pour les emails : $DOMAIN"
|
||||
|
||||
# Vérification DNS
|
||||
check_dns "$FQDN"
|
||||
|
||||
# Génération du certificat SSL
|
||||
setup_ssl "$FQDN"
|
||||
|
||||
# Configuration de Postfix
|
||||
echo "=== Configuration de Postfix ==="
|
||||
cat > /etc/postfix/main.cf <<EOF
|
||||
smtpd_banner = \$myhostname ESMTP
|
||||
biff = no
|
||||
append_dot_mydomain = no
|
||||
readme_directory = no
|
||||
myhostname = $FQDN
|
||||
myorigin = /etc/mailname
|
||||
mydestination = localhost
|
||||
relayhost =
|
||||
mynetworks = 127.0.0.0/8
|
||||
mailbox_size_limit = 0
|
||||
recipient_delimiter = +
|
||||
inet_interfaces = all
|
||||
inet_protocols = ipv4
|
||||
|
||||
# Sécurisation avec TLS
|
||||
smtpd_tls_cert_file=/etc/letsencrypt/live/$FQDN/fullchain.pem
|
||||
smtpd_tls_key_file=/etc/letsencrypt/live/$FQDN/privkey.pem
|
||||
smtpd_use_tls=yes
|
||||
smtpd_tls_auth_only = yes
|
||||
EOF
|
||||
|
||||
# Configuration de Dovecot
|
||||
echo "=== Configuration de Dovecot ==="
|
||||
cat > /etc/dovecot/dovecot.conf <<EOF
|
||||
disable_plaintext_auth = no
|
||||
ssl = required
|
||||
ssl_cert = </etc/letsencrypt/live/$FQDN/fullchain.pem
|
||||
ssl_key = </etc/letsencrypt/live/$FQDN/privkey.pem
|
||||
mail_location = maildir:/var/mail/vhosts/%d/%n
|
||||
|
||||
protocols = imap pop3 lmtp
|
||||
auth_mechanisms = plain login
|
||||
|
||||
service imap-login {
|
||||
inet_listener imap {
|
||||
port = 143
|
||||
}
|
||||
inet_listener imaps {
|
||||
port = 993
|
||||
ssl = yes
|
||||
}
|
||||
}
|
||||
service pop3-login {
|
||||
inet_listener pop3 {
|
||||
port = 110
|
||||
}
|
||||
inet_listener pop3s {
|
||||
port = 995
|
||||
ssl = yes
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Redémarrer les services
|
||||
echo "=== Redémarrage des services ==="
|
||||
systemctl restart postfix dovecot
|
||||
systemctl enable postfix dovecot
|
||||
|
||||
# Ajout d'un cron pour renouveler le certificat
|
||||
echo "0 3 * * * certbot renew --quiet && systemctl reload postfix dovecot" > /etc/cron.d/letsencrypt-renew
|
||||
|
||||
echo "✅ Configuration terminée avec succès !"
|
||||
4
scripts/server-mariadb/.list_files.txt
Normal file
4
scripts/server-mariadb/.list_files.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
check_mysql_secure.sh
|
||||
create_db.sh
|
||||
set_root_password.sh
|
||||
setup_mariadb.sh
|
||||
220
scripts/server-mariadb/check_mysql_secure.sh
Executable file
220
scripts/server-mariadb/check_mysql_secure.sh
Executable file
@@ -0,0 +1,220 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Audit Sécurité MariaDB sur $(hostname) ($(date)) ==="
|
||||
|
||||
CONFIG_FILE="/etc/mysql/mariadb.conf.d/50-server.cnf"
|
||||
ISSUES_FOUND=0
|
||||
RESTART_REQUIRED=0
|
||||
|
||||
# Vérifier la présence de la commande mysql
|
||||
if ! command -v mysql >/dev/null 2>&1; then
|
||||
echo "❌ La commande 'mysql' est introuvable. Veuillez l'installer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_password_from_cnf() {
|
||||
local file=$1
|
||||
sed -n '/\[client\]/,/^\[/p' "$file" | grep -m1 'password' | sed -E 's/^[ \t]*password[ \t]*=[ \t]*//'
|
||||
}
|
||||
|
||||
if [[ -f /etc/mysql/debian.cnf ]]; then
|
||||
DB_USER=$(grep -A5 '\[client\]' /etc/mysql/debian.cnf | grep -m1 'user' | awk -F= '{gsub(/ /,"",$2); print $2}')
|
||||
DB_ROOT_PASSWORD=$(get_password_from_cnf "/etc/mysql/debian.cnf" || echo "")
|
||||
DB_ROOT_PASSWORD=$(echo "$DB_ROOT_PASSWORD" | tr -d '\r\n')
|
||||
else
|
||||
DB_USER="root"
|
||||
read -rp "🔐 Entrez le mot de passe root pour MariaDB : " -s DB_ROOT_PASSWORD
|
||||
echo
|
||||
fi
|
||||
|
||||
TEMP_CNF=$(mktemp)
|
||||
chmod 600 "$TEMP_CNF"
|
||||
cat > "$TEMP_CNF" <<EOF
|
||||
[client]
|
||||
user=$DB_USER
|
||||
password=$DB_ROOT_PASSWORD
|
||||
EOF
|
||||
|
||||
MYSQL_CMD="mysql --defaults-extra-file=$TEMP_CNF"
|
||||
|
||||
echo "🔎 Test de connexion..."
|
||||
if ! $MYSQL_CMD -e "SELECT 1;" >/dev/null 2>&1; then
|
||||
echo "❌ Échec de connexion ($DB_USER)"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Connexion $DB_USER réussie"
|
||||
|
||||
echo
|
||||
|
||||
check_permissions() {
|
||||
echo "Vérification des permissions systèmes..."
|
||||
if [[ $(stat -c "%U %G" /var/lib/mysql) != "mysql mysql" ]]; then
|
||||
echo "❌ /var/lib/mysql n'appartient pas à mysql:mysql"
|
||||
ISSUE=1
|
||||
else
|
||||
echo "✔️ Permissions /var/lib/mysql OK"
|
||||
fi
|
||||
|
||||
if [[ $(stat -c "%U %G" $CONFIG_FILE) != "root root" ]]; then
|
||||
echo "❌ $CONFIG_FILE n'appartient pas à root:root"
|
||||
ISSUE=1
|
||||
else
|
||||
echo "✔️ Permissions du fichier de conf OK"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
check_storage_engines() {
|
||||
echo "🛠 Vérification des moteurs de stockage..."
|
||||
ENABLED=$($MYSQL_CMD -e "SHOW ENGINES;" | awk '$2 ~ /YES|DEFAULT/ {print $1}')
|
||||
for ENGINE in ARCHIVE BLACKHOLE FEDERATED; do
|
||||
if grep -q "$ENGINE" <<< "$ENABLED"; then
|
||||
echo "❌ $ENGINE actif"
|
||||
read -rp "Désactiver $ENGINE (ajout dans disabled_storage_engines) ? (y/n) " choice
|
||||
if [[ $choice == "y" ]]; then
|
||||
if ! grep -q "disabled_storage_engines" "$CONFIG_FILE"; then
|
||||
echo "disabled_storage_engines=$ENGINE" >> "$CONFIG_FILE"
|
||||
else
|
||||
sed -i "/^disabled_storage_engines/s/$/,$ENGINE/" "$CONFIG_FILE"
|
||||
fi
|
||||
RESTART_REQUIRED=1
|
||||
ISSUES_FOUND=1
|
||||
echo "✔️ $ENGINE désactivé (redémarrage requis)"
|
||||
fi
|
||||
else
|
||||
echo "✔️ $ENGINE non actif"
|
||||
fi
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
check_bind() {
|
||||
echo "🌐 Vérification du bind-address..."
|
||||
BIND_ADDRESS=$(grep -E "^bind-address" "$CONFIG_FILE" | cut -d= -f2 | tr -d ' ')
|
||||
if [[ "$BIND_ADDRESS" != "127.0.0.1" ]]; then
|
||||
echo "❌ MariaDB écoute sur $BIND_ADDRESS"
|
||||
read -rp "Forcer 127.0.0.1 ? (y/n) " choice
|
||||
if [[ $choice == "y" ]]; then
|
||||
sed -i 's/^bind-address.*/bind-address = 127.0.0.1/' "$CONFIG_FILE"
|
||||
RESTART_REQUIRED=1
|
||||
echo "✔️ bind-address corrigé"
|
||||
fi
|
||||
else
|
||||
echo "✔️ bind-address sécurisé"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
check_anonymous_users() {
|
||||
echo "👤 Vérification des utilisateurs anonymes..."
|
||||
if [[ $($MYSQL_CMD -N -e "SELECT COUNT(*) FROM mysql.user WHERE User='';") -gt 0 ]]; then
|
||||
echo "❌ Utilisateurs anonymes trouvés"
|
||||
read -rp "Supprimer ? (y/n) " choice
|
||||
[[ $choice == "y" ]] && $MYSQL_CMD -e "DELETE FROM mysql.user WHERE User=''; FLUSH PRIVILEGES;" && echo "✔️ Anonymes supprimés"
|
||||
else
|
||||
echo "✔️ Aucun utilisateur anonyme"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
check_remote_root() {
|
||||
echo "🔑 Vérification des accès root distants..."
|
||||
if [[ $($MYSQL_CMD -N -e "SELECT COUNT(*) FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');") -gt 0 ]]; then
|
||||
echo "❌ Accès root distant détecté"
|
||||
read -rp "Supprimer ces accès ? (y/n) " choice
|
||||
[[ $choice == "y" ]] && $MYSQL_CMD -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); FLUSH PRIVILEGES;" && echo "✔️ Accès root externe supprimé"
|
||||
else
|
||||
echo "✔️ Aucun accès root distant"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
check_test_db() {
|
||||
echo "🧪 Vérification de la base 'test'..."
|
||||
if $MYSQL_CMD -e "SHOW DATABASES LIKE 'test';" | grep -q "test"; then
|
||||
echo "❌ Base 'test' présente"
|
||||
read -rp "Supprimer ? (y/n) " choice
|
||||
[[ $choice == "y" ]] && $MYSQL_CMD -e "DROP DATABASE test;" && echo "✔️ Base test supprimée"
|
||||
else
|
||||
echo "✔️ Base 'test' absente"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
check_file_priv() {
|
||||
echo "📂 Vérification des FILE PRIV..."
|
||||
USERS=$($MYSQL_CMD -N -e "SELECT CONCAT(User, '@', Host) FROM mysql.user WHERE File_priv='Y';")
|
||||
if [[ -n "$USERS" ]]; then
|
||||
echo "❌ Utilisateurs avec FILE PRIV détectés:"
|
||||
echo "$USERS"
|
||||
read -rp "Retirer le droit FILE ? (y/n) " choice
|
||||
if [[ $choice == "y" ]]; then
|
||||
while read -r user; do
|
||||
$MYSQL_CMD -e "REVOKE FILE ON *.* FROM '$user';"
|
||||
done <<< "$USERS"
|
||||
$MYSQL_CMD -e "FLUSH PRIVILEGES;"
|
||||
echo "✔️ FILE révoqué"
|
||||
fi
|
||||
else
|
||||
echo "✔️ Aucun droit FILE abusif"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
check_slow_log() {
|
||||
echo "🐌 Vérification du slow query log..."
|
||||
ACTIVE=$($MYSQL_CMD -N -e "SHOW VARIABLES LIKE 'slow_query_log';" | awk '{print $2}')
|
||||
if [[ "$ACTIVE" != "ON" ]]; then
|
||||
echo "⚠️ Slow query log désactivé"
|
||||
read -rp "Activer dans la conf ? (y/n) " choice
|
||||
if [[ $choice == "y" ]]; then
|
||||
cat >> "$CONFIG_FILE" <<EOL
|
||||
|
||||
slow_query_log = 1
|
||||
slow_query_log_file = /var/log/mysql/mariadb-slow.log
|
||||
long_query_time = 2
|
||||
EOL
|
||||
touch /var/log/mysql/mariadb-slow.log
|
||||
chown mysql:mysql /var/log/mysql/mariadb-slow.log
|
||||
RESTART_REQUIRED=1
|
||||
echo "✔️ Slow query log activé"
|
||||
fi
|
||||
else
|
||||
echo "✔️ Slow query log actif"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
echo "===> Démarrage de l'audit..."
|
||||
echo
|
||||
|
||||
# Lancer les contrôles
|
||||
check_permissions
|
||||
check_storage_engines
|
||||
check_bind
|
||||
check_anonymous_users
|
||||
check_remote_root
|
||||
check_test_db
|
||||
check_file_priv
|
||||
check_slow_log
|
||||
|
||||
if [[ $RESTART_REQUIRED -eq 1 ]]; then
|
||||
echo "♻️ Redémarrage de MariaDB requis"
|
||||
systemctl restart mariadb
|
||||
echo
|
||||
fi
|
||||
|
||||
if [[ $ISSUES_FOUND -eq 1 ]]; then
|
||||
echo "⚠️ Audit terminé avec des recommandations ou actions effectuées."
|
||||
else
|
||||
echo "✅ Audit terminé - Aucun problème majeur détecté."
|
||||
fi
|
||||
157
scripts/server-mariadb/create_db.sh
Executable file
157
scripts/server-mariadb/create_db.sh
Executable file
@@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
echo "=== Gestion du mot de passe administrateur ==="
|
||||
|
||||
# Vérifier la présence de la commande mysql
|
||||
if ! command -v mysql >/dev/null 2>&1; then
|
||||
echo "❌ La commande 'mysql' est introuvable. Veuillez l'installer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fonction de recherche dans un fichier cnf ou conf
|
||||
get_password_from_cnf() {
|
||||
local file=$1
|
||||
if [[ -f "$file" ]]; then
|
||||
PASSWORD=$(grep -m1 'password\s*=' "$file" | sed -E 's/.*password\s*=\s*//;s/"//g')
|
||||
if [[ -n "$PASSWORD" ]]; then
|
||||
echo "$PASSWORD"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Tentative de récupération depuis /etc/mysql/debian.cnf
|
||||
DB_ROOT_PASSWORD=$(get_password_from_cnf "/etc/mysql/debian.cnf")
|
||||
if [[ -n "$DB_ROOT_PASSWORD" ]]; then
|
||||
echo "✅ Mot de passe root récupéré depuis /etc/mysql/debian.cnf"
|
||||
else
|
||||
# Recherche dans d'autres fichiers .cnf ou .conf
|
||||
for file in /etc/mysql/*.cnf /etc/mysql/conf.d/*.cnf /etc/my.cnf /etc/my.cnf.d/*.cnf; do
|
||||
DB_ROOT_PASSWORD=$(get_password_from_cnf "$file")
|
||||
if [[ -n "$DB_ROOT_PASSWORD" ]]; then
|
||||
echo "✅ Mot de passe root trouvé dans $file"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Si toujours rien, demande à l'utilisateur
|
||||
if [[ -z "$DB_ROOT_PASSWORD" ]]; then
|
||||
echo -n "🔐 Entrez le mot de passe root pour MariaDB : "
|
||||
read -r -s USER_PASSWORD
|
||||
echo
|
||||
DB_ROOT_PASSWORD="$USER_PASSWORD"
|
||||
fi
|
||||
|
||||
# Création d'un fichier temporaire sécurisé pour la connexion MySQL
|
||||
TEMP_CNF=$(mktemp)
|
||||
chmod 600 "$TEMP_CNF"
|
||||
cat > "$TEMP_CNF" <<EOF
|
||||
[client]
|
||||
user=root
|
||||
password=$DB_ROOT_PASSWORD
|
||||
EOF
|
||||
|
||||
# TEST du mot de passe root
|
||||
echo "🔎 Test de connexion avec le mot de passe root..."
|
||||
if ! mysql --defaults-extra-file="$TEMP_CNF" -e "SELECT 1;" 2>/dev/null; then
|
||||
echo "❌ Échec de la connexion avec le mot de passe root. Arrêt du script."
|
||||
rm -f "$TEMP_CNF"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Connexion root réussie."
|
||||
|
||||
# Définir la variable MYSQL_CMD pour le reste du script
|
||||
MYSQL_CMD="mysql --defaults-extra-file=$TEMP_CNF"
|
||||
|
||||
# N'oublie pas de prévoir un nettoyage à la fin :
|
||||
trap 'rm -f "$TEMP_CNF"' EXIT
|
||||
|
||||
echo "=== Création d'une nouvelle base de données MariaDB ==="
|
||||
|
||||
# Lecture du nom de la base de données
|
||||
read -rp "Nom de la base de données : " DB_NAME
|
||||
if [[ -z "$DB_NAME" ]]; then
|
||||
echo "❌ Nom de base de données requis."
|
||||
rm -f "$TEMP_CNF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérification de l'existence de la base de données
|
||||
DB_EXISTS=$(mysql --defaults-extra-file="$TEMP_CNF" -sse "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='$DB_NAME'")
|
||||
if [[ "$DB_EXISTS" == "$DB_NAME" ]]; then
|
||||
echo "❌ La base de données '$DB_NAME' existe déjà."
|
||||
rm -f "$TEMP_CNF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Lecture du nom de l'utilisateur
|
||||
read -rp "Nom de l'utilisateur : " DB_USER
|
||||
if [[ -z "$DB_USER" ]]; then
|
||||
echo "❌ Nom d'utilisateur requis."
|
||||
rm -f "$TEMP_CNF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérification de l'existence de l'utilisateur
|
||||
USER_EXISTS=$(mysql --defaults-extra-file="$TEMP_CNF" -sse "SELECT COUNT(*) FROM mysql.user WHERE user='$DB_USER'")
|
||||
if [[ "$USER_EXISTS" -gt 0 ]]; then
|
||||
echo "ℹ️ L'utilisateur '$DB_USER' existe déjà. Il ne sera pas recréé."
|
||||
CREATE_USER_SQL=""
|
||||
USER_PASS_TO_SAVE=""
|
||||
else
|
||||
echo "✅ L'utilisateur '$DB_USER' sera créé."
|
||||
# Demande du mot de passe utilisateur ou génération
|
||||
read -rsp "Mot de passe de l'utilisateur (laisser vide pour générer) : " DB_PASS
|
||||
echo
|
||||
if [[ -z "$DB_PASS" ]]; then
|
||||
DB_PASS=$(generate_token 64)
|
||||
echo "🔑 Mot de passe généré : $DB_PASS"
|
||||
fi
|
||||
CREATE_USER_SQL="CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
|
||||
USER_PASS_TO_SAVE="$DB_PASS"
|
||||
fi
|
||||
|
||||
# Création de la base et attribution des droits
|
||||
SQL=$(cat <<EOF
|
||||
CREATE DATABASE \`$DB_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
$CREATE_USER_SQL
|
||||
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
)
|
||||
|
||||
echo "✅ Exécution de la création..."
|
||||
if mysql --defaults-extra-file="$TEMP_CNF" -e "$SQL"; then
|
||||
echo "🎉 Base de données '$DB_NAME' créée et droits attribués à '$DB_USER'."
|
||||
else
|
||||
echo "❌ Erreur lors de la création."
|
||||
rm -f "$TEMP_CNF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Sauvegarde des identifiants
|
||||
if [[ -n "$USER_PASS_TO_SAVE" ]]; then
|
||||
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||
CRED_FILE="db_${DB_NAME}_${TIMESTAMP}.credentials"
|
||||
|
||||
umask 077 # Restriction immédiate des droits sur le fichier
|
||||
{
|
||||
printf "Base: %s\n" "$DB_NAME"
|
||||
printf "User: %s\n" "$DB_USER"
|
||||
printf "Password: %s\n" "$USER_PASS_TO_SAVE"
|
||||
} > "$CRED_FILE"
|
||||
|
||||
echo "🔒 Identifiants sauvegardés dans $CRED_FILE"
|
||||
fi
|
||||
|
||||
# Nettoyage du fichier temporaire de connexion
|
||||
rm -f "$TEMP_CNF"
|
||||
112
scripts/server-mariadb/set_root_password.sh
Executable file
112
scripts/server-mariadb/set_root_password.sh
Executable file
@@ -0,0 +1,112 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Variables
|
||||
NEW_PASS=$(generate_token 20)
|
||||
DB_SERVICE="mariadb" # Adapter si besoin
|
||||
MYSQL_SOCK="/var/run/mysqld/mysqld.sock"
|
||||
CNF_FILES=("/etc/mysql/debian.cnf" "/root/.my.cnf")
|
||||
MYSQLD_SAFE_LOG="/tmp/mysqld_safe.log"
|
||||
|
||||
echo "[+] Nouveau mot de passe root généré."
|
||||
|
||||
# Arrêt du service MySQL/MariaDB
|
||||
echo "[+] Arrêt du service $DB_SERVICE..."
|
||||
systemctl stop "$DB_SERVICE"
|
||||
|
||||
echo "[+] Attente de l'arrêt complet du service..."
|
||||
while systemctl is-active --quiet "$DB_SERVICE"; do
|
||||
sleep 1
|
||||
done
|
||||
echo "[+] Service arrêté."
|
||||
|
||||
# Nettoyage des éventuels sockets ou PID bloquants
|
||||
echo "[+] Nettoyage des sockets et PID..."
|
||||
rm -f /var/run/mysqld/mysqld.pid /var/run/mysqld/mysqld.sock
|
||||
|
||||
# Démarrage en mode sans échec
|
||||
echo "[+] Démarrage de MySQL en mode sans échec..."
|
||||
mysqld_safe --skip-grant-tables --skip-networking > "$MYSQLD_SAFE_LOG" 2>&1 &
|
||||
SAFE_PID=$!
|
||||
|
||||
# Attente que mysqld_safe soit vraiment prêt
|
||||
echo "[+] Attente de la disponibilité de mysqld_safe..."
|
||||
for i in {1..10}; do
|
||||
if mysqladmin ping --socket="$MYSQL_SOCK" >/dev/null 2>&1; then
|
||||
echo "[+] mysqld_safe est prêt."
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if ! mysqladmin ping --socket="$MYSQL_SOCK" >/dev/null 2>&1; then
|
||||
echo "[❌] Échec du démarrage de mysqld_safe. Voir $MYSQLD_SAFE_LOG"
|
||||
kill -9 $SAFE_PID 2>/dev/null
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Réinitialisation du mot de passe root
|
||||
echo "[+] Réinitialisation du mot de passe root..."
|
||||
mysql --socket="$MYSQL_SOCK" <<EOF
|
||||
FLUSH PRIVILEGES;
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED BY '$NEW_PASS';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
# Nettoyage complet du mode sans échec
|
||||
echo "[+] Arrêt complet du mode sans échec et des processus MySQL/MariaDB..."
|
||||
kill -9 $SAFE_PID
|
||||
killall -9 mysqld_safe mariadbd mysqld || true
|
||||
sleep 5
|
||||
|
||||
# Redémarrage du service
|
||||
echo "[+] Redémarrage du service $DB_SERVICE..."
|
||||
systemctl start "$DB_SERVICE"
|
||||
|
||||
# Vérification du bon démarrage
|
||||
echo "[+] Attente du démarrage complet de MariaDB..."
|
||||
for i in {1..10}; do
|
||||
if systemctl is-active --quiet "$DB_SERVICE"; then
|
||||
echo "[+] MariaDB est démarré."
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if ! systemctl is-active --quiet "$DB_SERVICE"; then
|
||||
echo "[❌] MariaDB ne démarre pas. Voir journalctl -xeu $DB_SERVICE"
|
||||
systemctl status "$DB_SERVICE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test de connexion avec le nouveau mot de passe
|
||||
echo "[+] Test de connexion réel avec le nouveau mot de passe root..."
|
||||
if mysql -uroot -p"$NEW_PASS" -e "SELECT 'Connexion réussie' AS Status;" >/dev/null 2>&1; then
|
||||
echo "[✔] Connexion root réussie."
|
||||
|
||||
# Mise à jour des fichiers .cnf si user = root
|
||||
for file in "${CNF_FILES[@]}"; do
|
||||
if [[ -f "$file" ]]; then
|
||||
if grep -q "^\s*user\s*=\s*root" "$file"; then
|
||||
echo "[+] Mise à jour du fichier $file (user=root détecté)."
|
||||
sed -i -E "s/(password\s*=\s*).*/\1$NEW_PASS/" "$file"
|
||||
else
|
||||
echo "[!] Pas de user=root dans $file, aucune modification."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "---------------------------------------------"
|
||||
echo "[✔] Mot de passe root MySQL/MariaDB réinitialisé avec succès."
|
||||
echo "[✔] Nouveau mot de passe root : $NEW_PASS"
|
||||
echo "---------------------------------------------"
|
||||
else
|
||||
echo "[❌] Échec de la connexion root après redémarrage de MariaDB."
|
||||
exit 1
|
||||
fi
|
||||
164
scripts/server-mariadb/setup_mariadb.sh
Executable file
164
scripts/server-mariadb/setup_mariadb.sh
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
# Mise à jour du système
|
||||
update_system
|
||||
|
||||
PASS_FILE=~/mariadb_root_password.txt
|
||||
DEBIAN_CNF=/etc/mysql/debian.cnf
|
||||
MARIADB_CNF=/etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
|
||||
echo "=== Installation de MariaDB ==="
|
||||
apt install -y mariadb-server mariadb-client
|
||||
|
||||
echo "=== Activation et démarrage de MariaDB ==="
|
||||
systemctl enable mariadb
|
||||
systemctl start mariadb
|
||||
|
||||
echo "=== Configuration du bind-address pour bloquer les connexions externes ==="
|
||||
if grep -q "^bind-address" $MARIADB_CNF; then
|
||||
sed -i 's/^bind-address.*/bind-address = 127.0.0.1/' $MARIADB_CNF
|
||||
else
|
||||
echo "bind-address = 127.0.0.1" >> $MARIADB_CNF
|
||||
fi
|
||||
|
||||
echo "=== Activation du log binaire et purge automatique des anciens logs ==="
|
||||
if ! grep -q "^log-bin" "$MARIADB_CNF"; then
|
||||
cat >> "$MARIADB_CNF" <<EOL
|
||||
|
||||
# Journalisation binaire activée pour la réplication et la sécurité
|
||||
log-bin = /var/log/mysql/mariadb-bin
|
||||
expire_logs_days = 7
|
||||
EOL
|
||||
fi
|
||||
|
||||
echo "=== Vérification et création du répertoire pour les binlogs ==="
|
||||
mkdir -p /var/log/mysql
|
||||
chown mysql:mysql /var/log/mysql
|
||||
chmod 750 /var/log/mysql
|
||||
|
||||
|
||||
systemctl restart mariadb
|
||||
|
||||
echo "=== Gestion du mot de passe administrateur ==="
|
||||
|
||||
# Fonction de recherche dans un fichier cnf ou conf
|
||||
get_password_from_cnf() {
|
||||
local file=$1
|
||||
if [[ -f "$file" ]]; then
|
||||
PASSWORD=$(grep -m1 'password\s*=' "$file" | sed -E 's/.*password\s*=\s*//;s/"//g')
|
||||
if [[ -n "$PASSWORD" ]]; then
|
||||
echo "$PASSWORD"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Générer ou récupérer le mot de passe root MariaDB
|
||||
if [[ -f "$PASS_FILE" ]]; then
|
||||
DB_ROOT_PASSWORD=$(grep 'root password:' "$PASS_FILE" | awk '{print $3}')
|
||||
echo "Mot de passe root existant récupéré."
|
||||
else
|
||||
# Tentative de récupération depuis /etc/mysql/debian.cnf
|
||||
DB_ROOT_PASSWORD=$(get_password_from_cnf "/etc/mysql/debian.cnf")
|
||||
if [[ -n "$DB_ROOT_PASSWORD" ]]; then
|
||||
echo "Mot de passe root récupéré depuis /etc/mysql/debian.cnf"
|
||||
else
|
||||
# Tentative dans d'autres fichiers .cnf ou .conf connus
|
||||
for file in /etc/mysql/*.cnf /etc/mysql/conf.d/*.cnf /etc/my.cnf /etc/my.cnf.d/*.cnf; do
|
||||
DB_ROOT_PASSWORD=$(get_password_from_cnf "$file")
|
||||
if [[ -n "$DB_ROOT_PASSWORD" ]]; then
|
||||
echo "Mot de passe root trouvé dans $file"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Si toujours pas de mot de passe trouvé, demander ou générer
|
||||
if [[ -z "$DB_ROOT_PASSWORD" ]]; then
|
||||
echo -n "Entrez un mot de passe root pour MariaDB ou le mot de passe existant (laisser vide pour générer automatiquement) : "
|
||||
read -r -s USER_PASSWORD
|
||||
echo
|
||||
if [[ -n "$USER_PASSWORD" ]]; then
|
||||
DB_ROOT_PASSWORD="$USER_PASSWORD"
|
||||
echo "Mot de passe root défini par l'utilisateur."
|
||||
else
|
||||
DB_ROOT_PASSWORD=$(generate_token 64)
|
||||
echo "Mot de passe root généré automatiquement."
|
||||
echo "root password: $DB_ROOT_PASSWORD" > "$PASS_FILE"
|
||||
chmod 600 "$PASS_FILE"
|
||||
echo "Mot de passe root sauvegardé dans $PASS_FILE."
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
echo "=== Sécurisation de MariaDB ==="
|
||||
mysql -u root -p"$DB_ROOT_PASSWORD" <<EOF
|
||||
-- Définir le mot de passe root correctement
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED BY '$DB_ROOT_PASSWORD';
|
||||
|
||||
-- Supprimer les utilisateurs anonymes
|
||||
DELETE FROM mysql.user WHERE User='';
|
||||
|
||||
-- Supprimer tout accès root externe ou d'autres users externes
|
||||
DELETE FROM mysql.user WHERE Host NOT IN ('localhost', '127.0.0.1', '::1');
|
||||
|
||||
-- Supprimer la base de test si elle existe
|
||||
DROP DATABASE IF EXISTS test;
|
||||
|
||||
-- Supprimer les droits sur la base de test
|
||||
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
|
||||
|
||||
-- Recharger les privilèges
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
echo "=== Mise à jour de /etc/mysql/debian.cnf pour les scripts de maintenance ==="
|
||||
cat > /etc/mysql/debian.cnf <<EOL
|
||||
[client]
|
||||
host = localhost
|
||||
user = root
|
||||
password = $DB_ROOT_PASSWORD
|
||||
socket = /run/mysqld/mysqld.sock
|
||||
|
||||
[mysql_upgrade]
|
||||
host = localhost
|
||||
user = root
|
||||
password = $DB_ROOT_PASSWORD
|
||||
socket = /run/mysqld/mysqld.sock
|
||||
EOL
|
||||
chmod 600 /etc/mysql/debian.cnf
|
||||
|
||||
echo "=== Vérification de la présence de PHP ==="
|
||||
if command -v php >/dev/null 2>&1; then
|
||||
PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
|
||||
echo "PHP version détectée : $PHP_VERSION"
|
||||
|
||||
echo "=== Installation de php-mysql pour PHP $PHP_VERSION ==="
|
||||
apt install -y php${PHP_VERSION}-mysql
|
||||
|
||||
echo "=== Redémarrage d'Apache si installé ==="
|
||||
if systemctl list-units --type=service | grep -q apache2; then
|
||||
systemctl restart apache2
|
||||
echo "Apache redémarré"
|
||||
fi
|
||||
|
||||
echo "=== Redémarrage de PHP-FPM si installé ==="
|
||||
if systemctl list-units --type=service | grep -q php${PHP_VERSION}-fpm; then
|
||||
systemctl restart php${PHP_VERSION}-fpm
|
||||
echo "PHP-FPM redémarré"
|
||||
fi
|
||||
else
|
||||
echo "PHP n'est pas installé. Installation de MariaDB terminée sans liaison PHP."
|
||||
fi
|
||||
|
||||
echo "=== Fin de l'installation et sécurisation de MariaDB ==="
|
||||
3
scripts/server-postgres/.list_files.txt
Normal file
3
scripts/server-postgres/.list_files.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
create_pg_db.sh
|
||||
create_pg_role.sh
|
||||
setup-postgres.sh
|
||||
52
scripts/server-postgres/create_pg_db.sh
Executable file
52
scripts/server-postgres/create_pg_db.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
set -e
|
||||
|
||||
echo "👉 Nom de la base de données à créer : "
|
||||
read DB_NAME
|
||||
|
||||
echo "👉 Nom de l'utilisateur PostgreSQL propriétaire : "
|
||||
read DB_USER
|
||||
|
||||
# Lecture du mot de passe en mode sécurisé
|
||||
read -s -p "🔑 Mot de passe PostgreSQL de l'utilisateur 'postgres' : " DB_PASS
|
||||
echo ""
|
||||
|
||||
# Exporter le mot de passe temporairement
|
||||
export PGPASSWORD="$DB_PASS"
|
||||
|
||||
echo "🔎 Vérification de l'existence de l'utilisateur PostgreSQL '$DB_USER'..."
|
||||
USER_EXISTS=$(sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='${DB_USER}'")
|
||||
|
||||
|
||||
if [[ "$USER_EXISTS" != "1" ]]; then
|
||||
echo "❌ L'utilisateur '$DB_USER' n'existe pas dans PostgreSQL."
|
||||
unset PGPASSWORD
|
||||
exit 2
|
||||
else
|
||||
echo "✅ L'utilisateur '$DB_USER' existe."
|
||||
fi
|
||||
|
||||
echo "🔎 Vérification de l'existence de la base de données '$DB_NAME'..."
|
||||
DB_EXISTS=$(sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname='${DB_NAME}'")
|
||||
|
||||
|
||||
if [[ "$DB_EXISTS" == "1" ]]; then
|
||||
echo "⚠️ La base de données '$DB_NAME' existe déjà."
|
||||
else
|
||||
echo "🛠 Création de la base de données '$DB_NAME' avec le propriétaire '$DB_USER'..."
|
||||
sudo -u postgres createdb -O "$DB_USER" "$DB_NAME"
|
||||
echo "✅ Base de données '$DB_NAME' créée avec succès."
|
||||
fi
|
||||
|
||||
# Nettoyage de la variable d'environnement
|
||||
unset PGPASSWORD
|
||||
|
||||
echo "🎉 Opération terminée."
|
||||
73
scripts/server-postgres/create_pg_role.sh
Executable file
73
scripts/server-postgres/create_pg_role.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
set -e
|
||||
|
||||
# Demande interactive si le rôle n’est pas passé en paramètre
|
||||
if [[ -n "$1" ]]; then
|
||||
ROLE_NAME="$1"
|
||||
else
|
||||
read -p "👤 Entrez le nom du rôle PostgreSQL à créer : " ROLE_NAME
|
||||
fi
|
||||
|
||||
if [[ -z "$ROLE_NAME" ]]; then
|
||||
echo "❌ Le nom du rôle est obligatoire."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Demander le mot de passe de l'utilisateur 'postgres'
|
||||
read -s -p "🔑 Entrez le mot de passe de l'utilisateur 'postgres' : " POSTGRES_PASSWORD
|
||||
echo ""
|
||||
|
||||
# Générer le mot de passe du rôle
|
||||
echo "🔐 Génération d'un mot de passe fort pour le rôle '$ROLE_NAME'..."
|
||||
ROLE_PASSWORD=$(generate_token 20)
|
||||
|
||||
# Générer un fichier SQL temporaire pour la vérification + création
|
||||
SQL_FILE=$(mktemp)
|
||||
|
||||
cat <<EOF > "$SQL_FILE"
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${ROLE_NAME}') THEN
|
||||
RAISE NOTICE '🛠 Création du rôle "${ROLE_NAME}"...';
|
||||
CREATE ROLE ${ROLE_NAME} WITH LOGIN PASSWORD '${ROLE_PASSWORD}';
|
||||
ELSE
|
||||
RAISE NOTICE '⚠️ Le rôle "${ROLE_NAME}" existe déjà.';
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
EOF
|
||||
|
||||
chmod 644 "$SQL_FILE"
|
||||
|
||||
# Une seule exécution de psql via sudo avec mot de passe PostgreSQL exporté
|
||||
echo "🔎 Exécution des commandes SQL avec sudo..."
|
||||
sudo -u postgres bash -c "PGPASSWORD='${POSTGRES_PASSWORD}' psql -v ON_ERROR_STOP=1 -f '${SQL_FILE}'"
|
||||
|
||||
rm -f "$SQL_FILE"
|
||||
|
||||
# Affichage des identifiants si création
|
||||
echo ""
|
||||
echo "-------------------------------------------"
|
||||
echo " Nom du rôle : ${ROLE_NAME}"
|
||||
echo " Mot de passe : ${ROLE_PASSWORD}"
|
||||
echo "-------------------------------------------"
|
||||
|
||||
# Proposer d’enregistrer dans ~/.pgpass
|
||||
read -p "💾 Voulez-vous enregistrer ces identifiants dans ~/.pgpass ? (y/n) " SAVE_PASS
|
||||
if [[ "$SAVE_PASS" =~ ^[Yy]$ ]]; then
|
||||
PGPASS_FILE="${HOME}/.pgpass"
|
||||
echo "*:*:*:${ROLE_NAME}:${ROLE_PASSWORD}" >> "$PGPASS_FILE"
|
||||
chmod 600 "$PGPASS_FILE"
|
||||
echo "✅ Identifiants sauvegardés dans $PGPASS_FILE"
|
||||
fi
|
||||
|
||||
echo "⚠️ Pensez à sauvegarder ces informations si vous ne les enregistrez pas."
|
||||
echo "🎉 Opération terminée."
|
||||
77
scripts/server-postgres/setup-postgres.sh
Executable file
77
scripts/server-postgres/setup-postgres.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/bin/bash
|
||||
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
|
||||
|
||||
# Importer les fonctions communes
|
||||
source "$(dirname "$0")/../common/common_utils.sh"
|
||||
|
||||
# Vérifier si le script est exécuté en root
|
||||
check_root
|
||||
|
||||
set -e
|
||||
|
||||
echo "📦 Mise à jour des paquets..."
|
||||
apt update -y
|
||||
|
||||
echo "📚 Installation de postgresql-common (pour script de dépôt officiel)..."
|
||||
apt install -y postgresql-common
|
||||
|
||||
echo "➕ Ajout automatique du dépôt officiel PostgreSQL (via pgdg script)..."
|
||||
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
|
||||
|
||||
echo ""
|
||||
echo "🧩 Versions disponibles dans le dépôt :"
|
||||
AVAILABLE_VERSIONS=$(apt-cache search "^postgresql-[0-9][0-9]$" | awk '{print $1}' | cut -d'-' -f2 | sort -nr)
|
||||
echo "$AVAILABLE_VERSIONS"
|
||||
|
||||
read -p "➡️ Entrez la version PostgreSQL à installer (ex: 17) : " PG_VERSION
|
||||
|
||||
if ! echo "$AVAILABLE_VERSIONS" | grep -q "^${PG_VERSION}$"; then
|
||||
echo "❌ Version PostgreSQL invalide ou non disponible : ${PG_VERSION}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📦 Installation de PostgreSQL $PG_VERSION..."
|
||||
apt update -y
|
||||
apt install -y "postgresql-${PG_VERSION}"
|
||||
|
||||
echo "🚀 Activation et démarrage du service PostgreSQL..."
|
||||
systemctl enable postgresql
|
||||
systemctl start postgresql
|
||||
|
||||
echo "⏳ Attente du démarrage du service PostgreSQL..."
|
||||
sleep 3
|
||||
|
||||
echo "✅ Vérification du service..."
|
||||
if ! systemctl is-active --quiet postgresql; then
|
||||
echo "❌ Le service PostgreSQL ne fonctionne pas correctement."
|
||||
journalctl -xeu postgresql --no-pager | tail -n 20
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🧪 Test de connexion à PostgreSQL..."
|
||||
if ! sudo -u postgres psql -c '\q' 2>/dev/null; then
|
||||
echo "❌ Échec de la connexion à PostgreSQL. Vérifiez que le socket est disponible."
|
||||
echo " Astuce : systemctl status postgresql"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔐 Génération d'un mot de passe fort pour l'utilisateur postgres..."
|
||||
POSTGRES_PASSWORD=$(generate_token 20)
|
||||
|
||||
echo "🔧 Configuration du mot de passe de l'utilisateur postgres..."
|
||||
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${POSTGRES_PASSWORD}';"
|
||||
|
||||
echo "🔧 Configuration de l'accès local en md5..."
|
||||
PG_HBA="/etc/postgresql/${PG_VERSION}/main/pg_hba.conf"
|
||||
sed -i "s/^\(local\s\+all\s\+postgres\s\+\)peer/\1md5/" "$PG_HBA"
|
||||
|
||||
echo "♻️ Redémarrage de PostgreSQL pour appliquer les changements..."
|
||||
systemctl restart postgresql
|
||||
|
||||
echo ""
|
||||
echo "✅ Installation de PostgreSQL ${PG_VERSION} terminée."
|
||||
echo "-------------------------------------------"
|
||||
echo " Mot de passe de l'utilisateur postgres :"
|
||||
echo " ${POSTGRES_PASSWORD}"
|
||||
echo "-------------------------------------------"
|
||||
echo " Pensez à le sauvegarder en lieu sûr."
|
||||
51
update_files.sh
Executable file
51
update_files.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
# Fichier README.md
|
||||
README="FILES.md"
|
||||
|
||||
# Temporary file for new list
|
||||
TEMP_FILE=$(mktemp)
|
||||
|
||||
# Get all .md files in the repository except the README.md
|
||||
find . -type f -name "*.md" ! -name "$README" | sort > "$TEMP_FILE"
|
||||
|
||||
# Function to get the title from a Markdown file
|
||||
get_title() {
|
||||
local file="$1"
|
||||
grep -m 1 '^# ' "$file" | sed 's/^# //'
|
||||
}
|
||||
|
||||
# Start with a clean README.md
|
||||
echo "# Liste des fichiers Markdown" > "$README"
|
||||
|
||||
# Initialize variable to track the last directory
|
||||
last_directory=""
|
||||
|
||||
# Read the list of files and append to README.md
|
||||
while read -r file; do
|
||||
title=$(get_title "$file")
|
||||
# Convert file path to hierarchical levels
|
||||
IFS='/' read -r -a path_parts <<< "$file"
|
||||
indent=""
|
||||
for ((i=1; i<${#path_parts[@]}-1; i++)); do
|
||||
indent="$indent "
|
||||
done
|
||||
# Determine the current directory name
|
||||
if [ ${#path_parts[@]} -gt 2 ]; then
|
||||
level="${path_parts[-2]}"
|
||||
capitalized_level=$(echo "$level" | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}')
|
||||
|
||||
# Only add the directory name if it's different from the last one
|
||||
if [ "$last_directory" != "$capitalized_level" ]; then
|
||||
echo "$indent- **${capitalized_level}**" >> "$README"
|
||||
last_directory="$capitalized_level"
|
||||
fi
|
||||
echo "$indent - [$title]($file)" >> "$README"
|
||||
else
|
||||
echo "- [$title]($file)" >> "$README"
|
||||
fi
|
||||
done < "$TEMP_FILE"
|
||||
|
||||
# Clean up
|
||||
rm "$TEMP_FILE"
|
||||
|
||||
echo "$README has been updated."
|
||||
Reference in New Issue
Block a user