Compare commits

..

116 Commits

Author SHA1 Message Date
48c26f9f84 Actualiser scripts/server-postgres/create_pg_role.sh
passage par un script temporaire
2025-05-19 05:22:16 +00:00
70facd85f3 sql sécurisé - pgpassword 2025-04-07 07:29:46 +02:00
5eda1c002e autoconfirmation pour iinstall curl 2025-04-07 07:07:19 +02:00
24a45fecf3 respect du standard pour l'installation de postgres 2025-04-06 19:38:21 +02:00
1b758b6161 définir la timezone 2025-04-05 06:23:52 +02:00
b75afa7df8 eviter de deamnder plusieurs fois le mdp 2025-04-04 07:12:37 +02:00
58b6a44819 amélioration de la créaton des db et role 2025-04-04 00:30:51 +02:00
8e882c7756 update script postgres 2025-03-31 22:32:48 +02:00
b8808e4219 add lychee_install script 2025-03-30 23:52:47 +02:00
5375a48bfd amélioration 2025-03-24 13:40:04 +01:00
4936d3c8e7 améiloration de la gestion du mot d epasse 2025-03-24 13:34:05 +01:00
3d64c538af chmod +x 2025-03-24 12:24:53 +01:00
d9c2e20402 create script create_role for pg 2025-03-24 12:23:51 +01:00
12cbbd0a6a add create_db for pg 2025-03-24 12:21:19 +01:00
bd74da92ff ajout script pour postgres 2025-03-24 12:16:58 +01:00
5e663d8925 listing update 2025-03-24 00:43:14 +01:00
2f0831aa09 configuraiton des modules opcache et apcu 2025-03-23 21:55:54 +01:00
cad29cdc71 demande si on créé la page info.php 2025-03-23 21:49:17 +01:00
eabf6c042e ajout de sqlite3 2025-03-23 21:35:15 +01:00
ca73246a47 correction 2025-03-23 21:29:09 +01:00
1b7173b824 suppression du timer 2025-03-23 17:38:31 +01:00
bc57514c0d create scripts 'mdns' and 'set_root_password'
edit for secure create_db.sh
2025-03-23 17:27:49 +01:00
9b29b85fb2 scripts pour mysql 2025-03-22 11:52:23 +01:00
4ee5bcc04f erreur sur le current user 2025-03-22 08:10:19 +01:00
164c69f580 correction pour utilisation avec sudo 2025-03-22 08:08:19 +01:00
00c1c9562b syntaxt error "sudo" 2025-03-22 08:04:30 +01:00
a8cd67f38c add script set-persmissions-www dans server-httpd 2025-03-22 07:55:04 +01:00
285e332a9f ajout 2025-03-22 00:19:53 +01:00
0d46cf7752 suppression de systemd-resolved 2025-03-20 08:07:55 +01:00
a3ecc212dd ajout d'une configuration pour faire du NAT entre WAN et LAN 2025-03-20 08:06:55 +01:00
506dfb1086 choix de l'interface et de l'interface IP 2025-03-20 07:27:41 +01:00
f22cf0bff7 demander sur quelle IP le DHCP va porter 2025-03-20 06:58:33 +01:00
917f3a68bb correciton de l récupération des IP 2025-03-20 01:11:04 +01:00
579631df00 amélioration de la découverte du nom de domaine. amelioration de l'efficacité de la recherche du domaine 2025-03-14 13:17:48 +01:00
680b9a2af9 amélioration de l'interacetion et de la proposition de recherhe 2025-03-14 13:14:54 +01:00
bf8b686477 précision sur l'utilisation de gti 2025-03-14 08:42:53 +01:00
86583798f5 détail dans l'installation 2025-03-14 08:35:01 +01:00
4c1ca83681 correction syntaxique 2025-03-14 08:28:22 +01:00
cdd5b93432 update licence 2025-03-14 08:18:25 +01:00
400b22d821 suprresion d'un script de correction 2025-03-14 08:14:08 +01:00
56352f2749 Modification de licence 2025-03-14 08:12:48 +01:00
482dabf05f création du clé GPG 2025-03-13 22:33:24 +01:00
0cfc306351 amélioration de la gestion du DNS sur la machine 2025-03-13 08:46:43 +01:00
428110dad1 ajotu de la condition root pour find_hostname 2025-03-13 08:31:59 +01:00
8e0136d8dd ajout de find_hostname.sh 2025-03-13 08:29:53 +01:00
d6d9f5b14a ajout de find_hostname.sh 2025-03-13 08:29:33 +01:00
f5c7214107 amélioration du PTR 2025-03-13 08:04:24 +01:00
fa1fa6f1aa afficher le PTR déjà existant 2025-03-13 07:06:29 +01:00
18822822e3 ajout de la gestion PTR 2025-03-13 07:00:27 +01:00
58bbe9051d redondance dans le controle de hostname 2025-03-13 06:45:21 +01:00
0c5f0e9770 ajout FQDN et non FQDN proposé 2025-03-13 06:44:34 +01:00
9101bf061a ajout de l'adresse non FQDN 2025-03-13 06:33:56 +01:00
5631e5a1ad suppression demande confirmation ajout non FQDN 2025-03-13 06:31:46 +01:00
a88483a2a2 ajout du FQDN par défaut sinon accepter l'entrée 2025-03-13 06:30:21 +01:00
fe7f57dbc7 recherche d'une entrée dans les alias 2025-03-12 09:21:15 +01:00
cb0897aa2f pb sur la recherche d'IP corrigée 2025-03-12 07:51:57 +01:00
2f59a957d7 optimisation pour récupérer l'adresse IP disponible 2025-03-11 21:07:10 +01:00
565a3e2216 nom du fichier réduit au silence ! 2025-03-11 20:52:51 +01:00
e3e779c870 auto mise à jour 2025-03-11 20:50:54 +01:00
97504443ea pb de recopie 2025-03-11 20:48:54 +01:00
1d7cb2eb15 mémorise les options cochées 2025-03-11 20:47:40 +01:00
f6087a5e0f ajout d'un script de suppression 2025-03-11 20:45:21 +01:00
1ff01b383f maj list_files 2025-03-11 20:40:30 +01:00
0f6cdc7fcc gestion fine de l'ajout d'une entrée DNS 2025-03-11 20:39:31 +01:00
6b997e9446 modification de méthode vérification de l'adresse IP 2025-03-11 14:03:50 +01:00
569ec5457e ajout d'un script pour trouver la première adresse IP disponible 2025-03-11 13:53:20 +01:00
2bd7121f6e script pour ajouter une entrée DNS 2025-03-11 13:52:06 +01:00
765057a367 erreur sur le NTP 2025-03-11 13:41:28 +01:00
97531efe3d ajout des options DHCP 2025-03-11 13:14:25 +01:00
99e06e97ce amélioration du traitement des IP 2025-03-11 10:27:42 +01:00
a703b0f429 ajout des possibilités de réseaux privés 2025-03-11 10:18:11 +01:00
a70dcfb818 ajout de l'installation dhcp 2025-03-11 10:14:52 +01:00
13866482b9 generate list files 2025-03-11 09:31:25 +01:00
be0f6f50c0 erreur de synrtaxe 2025-03-11 07:03:24 +01:00
9a8c9dea12 Ajout script de préparation d'un serveur Debian 2025-03-10 08:46:39 +01:00
46ab7a92c9 Documentation mise à jour 2025-03-10 07:58:10 +01:00
ff61441355 sécurité renforcée 2025-03-09 20:07:39 +01:00
2bbd533024 sécurisation d'apache 2025-03-09 17:45:52 +01:00
09259162d3 fonctionnement de certbot en challenge http corrigé 2025-03-09 17:28:17 +01:00
e3053f90cc chemin pour recupérer les fichiers 2025-03-09 16:14:15 +01:00
b3d3313e61 modification du challenge pour certbot 2025-03-09 16:04:54 +01:00
a81189e5d2 traitement de la liste sélectionnée 2025-03-09 15:40:57 +01:00
6005045e7c amélioration de la gestion de génération des fichiers 2025-03-09 13:11:49 +01:00
d181ed7d68 correction du chemin 2025-03-09 13:02:34 +01:00
2af16cf8a7 deplacement de scripts 2025-03-09 13:00:26 +01:00
54a0c21787 régoranisation générale et ajout d'un script d'install 2025-03-09 12:55:27 +01:00
240acff0d4 correction sur l'appel de add_user dans la doc 2025-03-08 08:47:23 +01:00
93855e11e6 modification de l'indication d'appel des scripts 2025-03-08 08:46:54 +01:00
e9cc0b8221 lister que les fichiers .sh 2025-03-08 08:45:48 +01:00
35dc05df26 modification de syntaxe 2025-03-08 08:45:07 +01:00
71fc606145 rendre les fichiers executables après etre téléchargés 2025-03-08 02:55:16 +01:00
ef51ecb38a CORRECTION : force le téléchargement des fichiers avec wget 2025-03-08 02:53:31 +01:00
e123bb115b forcer le téléchargement avec wget 2025-03-08 02:51:18 +01:00
7c7bfb5010 Empêcher la duplication avec wget 2025-03-08 02:48:24 +01:00
23e324bfef setup_mail.sh en IPv4 2025-03-08 02:46:42 +01:00
97707f1ffd facilitateur de téléchargement des scripts 2025-03-08 02:40:12 +01:00
dfbe21c2fc scripts rendus executables 2025-03-08 02:31:26 +01:00
6a316e84ac ajout infos : récupération des scripts 2025-03-08 02:20:15 +01:00
027c3ab250 Scripts pour gestion d'un serveur mail 2025-03-08 02:03:38 +01:00
c88689b5e9 ajout de l'article "Comment Bloquer les Spams avec le Serveur Email Postfix" 2024-07-27 22:53:51 +02:00
c633440fe7 mise à jour des tags 2024-07-27 21:53:10 +02:00
920a0b9cdb precisions concernant th0 2024-07-24 13:54:58 +02:00
ad4796f187 précisions concernant eth0 2024-07-24 13:54:34 +02:00
cf809a1aa9 Configurer une IP statique. Gestion des # 2024-07-24 13:31:32 +02:00
3a2952a81f Amélioration de la liste des fichiers MD 2024-07-24 03:15:43 +02:00
c7cf651727 correction des liens 2024-07-24 03:03:25 +02:00
5055213835 corrections divers 2024-07-24 03:02:25 +02:00
4fad0f88da ajout du fichier FILES.MD 2024-07-24 02:56:27 +02:00
6f7dfecef4 liste des fichiers MD dans le dépot 2024-07-24 02:55:09 +02:00
6d45a52983 correction de syntaxe 2024-07-24 02:48:17 +02:00
b04dcb48c2 Ajout d'un retour d'experience dans le script php pour sasl 2024-07-24 02:47:52 +02:00
7cd803942f message-deferred traités + complément dans fail2ban 2024-07-24 02:35:14 +02:00
86c9b9dbf7 sasl-script-php 2024-07-24 02:13:39 +02:00
c45f3a0357 ajout de fail2ban et des configurations pour sshd et postifx-sasl 2024-07-24 01:56:08 +02:00
b3d583aa83 Infos sur la contributions adaptées 2024-07-21 16:24:52 +02:00
f8f93ed49b modification des références 2024-07-21 13:43:54 +02:00
74 changed files with 4975 additions and 83 deletions

58
CONTRIBUTING.md Normal file
View 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
View 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)

View File

@@ -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
View 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
View 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 lauteur 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 lutilisation 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 sassurer 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é. Lauteur ne saurait être tenu responsable déventuelles violations de conformité résultant de lintégration ou de lutilisation de ces matériaux.
De plus, bien que cette licence autorise une utilisation libre à des fins non commerciales, elle nexempte 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 dinformations 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/)

View File

@@ -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
View 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"

View File

@@ -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 !

View File

@@ -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
@@ -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)

View 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 linterface 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 dobtenir 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É>` |
---

View 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
```

View File

@@ -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 =

View 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.

View 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

View 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";
?>

View 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";

View 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.

View 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
View 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)

View 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`

View 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/)

View File

@@ -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

View File

@@ -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.

View 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
View File

@@ -0,0 +1,7 @@
all_inclusive
common
server-dhcp
server-httpd
server-mail
server-mariadb
server-postgres

View 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
View 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
View 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
View 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).

View File

@@ -0,0 +1 @@
lychee_install.sh

View 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 à linterface web pour finaliser la configuration : http://${IP}"

View File

@@ -0,0 +1,3 @@
common_utils.sh
setup_debian.sh
setup_mdns.sh

View 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 dhô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 dun 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 dun 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"
}

View 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"

View 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
View 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."

View 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

View 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

View 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

View 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

View 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

View 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

View 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"

View 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"

View File

@@ -0,0 +1,5 @@
add_domain.sh
add_domain_ssl.sh
install-php8-3.sh
set-permissions-www.sh
setup_httpd.sh

View 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

View 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"

View 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}"

View 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."

View 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 !"

View 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

View 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 dexécuter cette commande dans le dossier où vous souhaitez stocker les fichiers.

View 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 🎉"

View 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

View 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
View 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."

View 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é"

View 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
View 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é"

View 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 dhô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"

View 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

View 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

View 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

View 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 !"

View File

@@ -0,0 +1,4 @@
check_mysql_secure.sh
create_db.sh
set_root_password.sh
setup_mariadb.sh

View 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

View 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"

View 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

View 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 ==="

View File

@@ -0,0 +1,3 @@
create_pg_db.sh
create_pg_role.sh
setup-postgres.sh

View 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."

View 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 nest 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 denregistrer 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."

View 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
View 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."