Compare commits

..

92 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
60 changed files with 3418 additions and 274 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 ! 🚀

View File

@@ -1,9 +0,0 @@
MIT License
Copyright (c) 2024 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

@@ -20,7 +20,7 @@ Les contributions sont les bienvenues ! Si vous avez des suggestions, des correc
6. **Pousser votre branche** : `git push origin ma-nouvelle-branche` 6. **Pousser votre branche** : `git push origin ma-nouvelle-branche`
7. **Créer une Pull Request** 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 ## Code de Conduite
@@ -28,7 +28,7 @@ Pour garantir un environnement ouvert et accueillant, nous avons adopté un code
## Licence ## 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 ## Remerciements

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://xxxx/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é 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

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

@@ -1,36 +0,0 @@
---
# **📌 Résumé des Scripts**
| **Script** | **Action** | **Exemple d'utilisation** |
|----------------------|-----------------------------------------------|--------------------------|
| `install_mailserver.sh` | Installer Postfix/Dovecot + ajouter un domaine | `bash install_mailserver.sh domain.top` |
| `add_domain.sh` | Ajouter un domaine | `bash add_domain.sh domain2.top` |
| `add_user.sh` | Ajouter un utilisateur | `bash add_user.sh user@domain.top "password"` |
| `add_alias.sh` | Ajouter un alias | `bash add_alias.sh contact@domain2.top user@domain.top` |
| `add_forward.sh` | Ajouter une redirection | `bash add_forward.sh contact@domain.top user@domain2.top` |
| `list_domains.sh` | Lister les domaines | `bash list_domains.sh` |
| `list_users.sh` | Lister les utilisateurs | `bash list_users.sh` |
| `list_aliases.sh` | Lister les alias/redirections | `bash list_aliases.sh` |
| `del_user.sh` | Supprimer un utilisateur | `bash del_user.sh user@domain.top` |
| `del_alias.sh` | Supprimer un alias | `bash del_alias.sh contact@domain2.top` |
| `del_domain.sh` | Supprimer un domaine | `bash del_domain.sh domain2.top` |
---
## 📥 Récupération des scripts
Pour télécharger uniquement les scripts `.sh` et `.py` 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/server-mail/scripts/scripts.txt"
wget -P . --no-cache -i scripts.txt
```
✅ Tous les fichiers listés dans scripts.txt seront téléchargés automatiquement dans le dossier courant.
📌 **Astuce** : Assurez-vous dexécuter cette commande dans le dossier où vous souhaitez stocker les fichiers.

View File

@@ -1,18 +0,0 @@
#!/bin/bash
# Nom du fichier de sortie
OUTPUT_FILE="scripts.txt"
# Nettoyage du fichier s'il existe déjà
> "$OUTPUT_FILE"
# Récupérer le chemin absolu du dossier courant côté Git
BASE_URL="https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts"
# Lister tous les fichiers .sh et .py et générer l'URL complète
for file in *.sh *.py; do
[ -e "$file" ] || continue # Vérifie si des fichiers existent pour éviter une erreur
echo "$BASE_URL/$file" >> "$OUTPUT_FILE"
done
echo "✅ Liste des scripts générée dans $OUTPUT_FILE"

View File

@@ -1,13 +0,0 @@
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/add_alias.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/add_domain.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/add_forward.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/add_user.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/del_alias.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/del_domain.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/del_user.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/generate_password.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/generate_script_list.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/list_aliases.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/list_domains_.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/list_users.sh
https://git.abonnel.fr/cedricAbonnel/notes-techniques/raw/branch/main/notes/server-mail/scripts/setup_mail.sh

View File

@@ -1,147 +0,0 @@
#!/bin/bash
# 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
echo "=== Mise à jour du système ==="
apt update && apt upgrade -y
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 nom dhôte complet (FQDN)
FQDN=$(hostname -f)
# Vérifier si le FQDN est vide
if [[ -z "$FQDN" ]]; then
FQDN=$(cat /etc/hostname)
fi
# Extraire le domaine principal (ex: mail.acemail.fr -> acemail.fr)
DOMAIN=$(echo "$FQDN" | sed -E 's/^[^.]+\.//')
echo "🔍 Serveur détecté : $FQDN"
echo "🌐 Domaine géré pour les emails : $DOMAIN"
# Récupération des IP (IPv4 et 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}')
FQDN_IP=$(dig +short A "$FQDN" | tail -n1)
FQDN_IPv6=$(dig +short AAAA "$FQDN" | tail -n1)
echo "🌍 IP publique du serveur : $SERVER_IP (IPv4), $SERVER_IPv6 (IPv6)"
echo "🔎 IP DNS du serveur : $FQDN_IP (IPv4), $FQDN_IPv6 (IPv6)"
# Vérification du DNS
if [[ -z "$FQDN_IP" ]]; then
echo "❌ Impossible de récupérer l'IP du serveur ($FQDN)."
echo "🔹 Vérifie la configuration DNS et assure-toi que le nom de serveur pointe bien vers ce serveur."
exit 1
fi
if [[ "$SERVER_IP" != "$FQDN_IP" ]]; then
echo "⚠️ Problème DNS : L'IP du serveur ($FQDN_IP) ne correspond pas à l'IP du serveur ($SERVER_IP)."
echo "🔹 Corrige l'entrée DNS ou attends sa propagation avant de continuer."
exit 1
fi
echo "✅ DNS correct : $FQDN pointe bien vers $SERVER_IP"
# Variables
MAIL_DIR="/var/mail/vhosts"
LE_DIR="/etc/letsencrypt/live/$FQDN"
BACKUP_DIR="/backup/mail"
echo "=== Génération du certificat SSL avec Let's Encrypt ==="
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"
else
echo "🔄 Génération dun nouveau certificat SSL..."
certbot certonly --standalone -d "$FQDN" --non-interactive --agree-tos --register-unsafely-without-email
if [[ $? -ne 0 ]]; then
echo "❌ Erreur lors de la génération du certificat Let's Encrypt."
exit 1
fi
fi
# Création des fichiers de configuration
mkdir -p "$BACKUP_DIR"
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=$LE_DIR/fullchain.pem
smtpd_tls_key_file=$LE_DIR/privkey.pem
smtpd_use_tls=yes
smtpd_tls_auth_only = yes
EOF
echo "=== Configuration de Dovecot ==="
cat > /etc/dovecot/dovecot.conf <<EOF
disable_plaintext_auth = no
ssl = required
ssl_cert = <$LE_DIR/fullchain.pem
ssl_key = <$LE_DIR/privkey.pem
mail_location = maildir:$MAIL_DIR/%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
echo "=== Redémarrage des services ==="
systemctl restart postfix dovecot
systemctl enable postfix dovecot
echo "=== Vérification des ports ouverts ==="
ss -tulpen | grep -E "postfix|dovecot"
echo "=== Ajout dun 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 !"

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

@@ -1,4 +1,5 @@
#!/bin/bash #!/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" POSTFIX_ALIASES="/etc/postfix/virtual_aliases"

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
# Définition des variables # Définition des variables
MAILDIR="/var/mail/vhosts" MAILDIR="/var/mail/vhosts"

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/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" POSTFIX_ALIASES="/etc/postfix/virtual_aliases"

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
DOVECOT_USERS="/etc/dovecot/users" DOVECOT_USERS="/etc/dovecot/users"
MAILDIR="/var/mail/vhosts" MAILDIR="/var/mail/vhosts"

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/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" POSTFIX_ALIASES="/etc/postfix/virtual_aliases"

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
MAILDIR="/var/mail/vhosts" MAILDIR="/var/mail/vhosts"
POSTFIX_CONFIG="/etc/postfix/virtual_domains" POSTFIX_CONFIG="/etc/postfix/virtual_domains"

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
DOVECOT_USERS="/etc/dovecot/users" DOVECOT_USERS="/etc/dovecot/users"
MAILDIR="/var/mail/vhosts" MAILDIR="/var/mail/vhosts"

View File

@@ -1,3 +1,6 @@
#!/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) # Récupérer le nom dhôte complet (FQDN)
SERVER_NAME=$(hostname -f) # Privilégier hostname -f SERVER_NAME=$(hostname -f) # Privilégier hostname -f

View File

@@ -1,3 +1,5 @@
#!/bin/bash #!/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 ===" echo "=== Liste des alias et redirections ==="
cat /etc/postfix/virtual_aliases cat /etc/postfix/virtual_aliases

View File

@@ -1,3 +1,5 @@
#!/bin/bash #!/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 ===" echo "=== Liste des domaines gérés ==="
cat /etc/postfix/virtual_domains cat /etc/postfix/virtual_domains

View File

@@ -1,3 +1,5 @@
#!/bin/bash #!/bin/bash
# Basé sur un travail de Cédric Abonnel / Cédrix sous licence CC BY-NC 4.0
echo "=== Liste des utilisateurs ===" echo "=== Liste des utilisateurs ==="
cat /etc/dovecot/users | cut -d: -f1 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."