Initial commit: VPS tutorial complet (105 etapes)
This commit is contained in:
57
01-prerequis.md
Normal file
57
01-prerequis.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# 1. Prerequis et Choix
|
||||||
|
|
||||||
|
## Choix de l'hebergeur VPS
|
||||||
|
|
||||||
|
**Recommande : Contabo** (bon rapport qualite/prix)
|
||||||
|
- VPS S : 2 vCPU / 4 GB RAM (~5 EUR/mois)
|
||||||
|
- VPS M : 4 vCPU / 8 GB RAM (~10 EUR/mois) - recommande
|
||||||
|
- OS : Ubuntu 24.04 LTS
|
||||||
|
|
||||||
|
## Choix du registrar
|
||||||
|
|
||||||
|
**Recommande : OVH**
|
||||||
|
- Interface complete (glue records, NS personnalises, DNSSEC)
|
||||||
|
- Pas besoin de contacter le support pour les modifications
|
||||||
|
- Propagation DNS rapide
|
||||||
|
|
||||||
|
**Eviter :** Cloud4Africa/MTN pour les .ci (support lent, interface buggee pour les NS personnalises)
|
||||||
|
|
||||||
|
**Alternative :** Cloudflare (DNS gratuit, protection DDoS, mais pas de registrar pour tous les TLD)
|
||||||
|
|
||||||
|
## Choix du panel
|
||||||
|
|
||||||
|
### ISPConfig (utilise dans ce guide)
|
||||||
|
- Complet : multi-serveur, revendeur, quotas
|
||||||
|
- Plus lourd et interface ancienne
|
||||||
|
- Documentation : https://vps-installation.readthedocs.io/fr/latest/
|
||||||
|
|
||||||
|
### HestiaCP (recommande pour prochain VPS)
|
||||||
|
- Plus leger, interface moderne
|
||||||
|
- Mises a jour frequentes
|
||||||
|
- Un seul serveur uniquement
|
||||||
|
- Documentation : https://docs.hestiacp.com/
|
||||||
|
|
||||||
|
## Configuration initiale chez l'hebergeur
|
||||||
|
|
||||||
|
1. Commander le VPS avec Ubuntu 24.04
|
||||||
|
2. Noter l'IP publique IPv4 et IPv6
|
||||||
|
3. Se connecter en SSH : `ssh root@<IP>`
|
||||||
|
4. Changer le mot de passe root : `passwd`
|
||||||
|
|
||||||
|
## Configuration chez le registrar (OVH)
|
||||||
|
|
||||||
|
1. Acheter le domaine
|
||||||
|
2. Creer les **glue records** :
|
||||||
|
- `ns1.<DOMAINE>` -> `<IP>`
|
||||||
|
- `ns2.<DOMAINE>` -> `<IP>`
|
||||||
|
3. Changer les **nameservers** vers :
|
||||||
|
- `ns1.<DOMAINE>`
|
||||||
|
- `ns2.<DOMAINE>`
|
||||||
|
|
||||||
|
> **Note :** OVH verifie que le serveur DNS repond avant d'accepter le changement. Il faut d'abord installer ISPConfig et creer la zone DNS (etape 3-4).
|
||||||
|
|
||||||
|
## Pour les domaines .ci chez MTN
|
||||||
|
|
||||||
|
Les domaines .ci ne supportent pas les glue records vers le meme domaine. Solution :
|
||||||
|
- Utiliser les NS de votre domaine principal (ex: `ns1.z-ana.com` pour `stlab.ci`)
|
||||||
|
- Modifier les NS chez MTN vers `ns1.<DOMAINE_PRINCIPAL>` et `ns2.<DOMAINE_PRINCIPAL>`
|
||||||
210
02-config-base.md
Normal file
210
02-config-base.md
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
# 2. Configuration de Base
|
||||||
|
|
||||||
|
## Creer un utilisateur
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adduser <USER>
|
||||||
|
usermod -a -G sudo <USER>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configurer /etc/hosts
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > /etc/hosts << 'EOF'
|
||||||
|
127.0.0.1 localhost
|
||||||
|
127.0.1.1 <FQDN> <HOSTNAME>
|
||||||
|
<IP> <FQDN> <HOSTNAME>
|
||||||
|
|
||||||
|
# IPv6
|
||||||
|
::1 localhost ip6-localhost ip6-loopback
|
||||||
|
ff02::1 ip6-allnodes
|
||||||
|
ff02::2 ip6-allrouters
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verifier le hostname
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hostnamectl set-hostname <FQDN>
|
||||||
|
hostname -f
|
||||||
|
# Doit afficher : <FQDN>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Editeur par defaut
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install vim micro
|
||||||
|
update-alternatives --config editor
|
||||||
|
# Choisir micro ou vim
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installer etckeeper
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt update && apt install etckeeper
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mettre a jour les sources apt
|
||||||
|
|
||||||
|
Ubuntu 24.04 utilise le format deb822 (`/etc/apt/sources.list.d/ubuntu.sources`).
|
||||||
|
Verifier que `main universe restricted multiverse` et `backports` sont presents.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt update && apt dist-upgrade && apt autoremove
|
||||||
|
```
|
||||||
|
|
||||||
|
## Paquets de base
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install curl wget ntpdate apt-transport-https apt-listchanges apt-file apt-rdepends man
|
||||||
|
```
|
||||||
|
|
||||||
|
## Locale FR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install locales
|
||||||
|
dpkg-reconfigure locales
|
||||||
|
# Selectionner fr_FR.UTF-8
|
||||||
|
apt install task-french
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debfoster
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install debfoster
|
||||||
|
debfoster
|
||||||
|
```
|
||||||
|
|
||||||
|
### Script keeper pour etckeeper
|
||||||
|
|
||||||
|
Creer `/etc/etckeeper/pre-commit.d/35debfoster` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
LANG=C
|
||||||
|
export LANG
|
||||||
|
|
||||||
|
shellquote() {
|
||||||
|
sed -e "s/'/'\"'\"'/g" -e "s/^/'/" -e "s/$/'/"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
|
||||||
|
debfoster -q -k /etc/keepers
|
||||||
|
chmod 600 /etc/keepers
|
||||||
|
sed -i "1i\\# debfoster file" /etc/keepers
|
||||||
|
sed -i "1i\\# Generated by etckeeper. Do not edit." /etc/keepers
|
||||||
|
if [ "$VCS" = git ]; then
|
||||||
|
git add keepers
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 755 /etc/etckeeper/pre-commit.d/35debfoster
|
||||||
|
etckeeper commit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mises a jour automatiques
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install unattended-upgrades
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interdire le login root SSH
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verifier dans /etc/ssh/sshd_config :
|
||||||
|
PermitRootLogin no
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sudo sans mot de passe
|
||||||
|
|
||||||
|
```bash
|
||||||
|
addgroup --system sudonp
|
||||||
|
usermod -a -G sudonp <USER>
|
||||||
|
echo '%sudonp ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/010_sudonp
|
||||||
|
chmod 440 /etc/sudoers.d/010_sudonp
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Important :** Deconnectez-vous et reconnectez-vous pour activer le groupe.
|
||||||
|
|
||||||
|
## Neofetch + MOTD
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install neofetch
|
||||||
|
```
|
||||||
|
|
||||||
|
Creer `/etc/neofetch.conf` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
print_info() {
|
||||||
|
info title
|
||||||
|
info underline
|
||||||
|
info "OS" distro
|
||||||
|
info "Host" model
|
||||||
|
info "Kernel" kernel
|
||||||
|
info "Uptime" uptime
|
||||||
|
info "Packages" packages
|
||||||
|
info "Shell" shell
|
||||||
|
info "CPU" cpu
|
||||||
|
info "CPU Usage" cpu_usage
|
||||||
|
prin "Load" "$(cat /proc/loadavg | awk '{print $1, $2, $3}')"
|
||||||
|
info "GPU" gpu
|
||||||
|
info "Memory" memory
|
||||||
|
info "Disk" disk
|
||||||
|
info "Local IP" local_ip
|
||||||
|
info "Public IP" public_ip
|
||||||
|
info "Users" users
|
||||||
|
info "Locale" locale
|
||||||
|
info cols
|
||||||
|
}
|
||||||
|
|
||||||
|
title_fqdn="on"
|
||||||
|
memory_percent="on"
|
||||||
|
memory_unit="mib"
|
||||||
|
package_managers="on"
|
||||||
|
image_backend="ascii"
|
||||||
|
cpu_temp="on"
|
||||||
|
```
|
||||||
|
|
||||||
|
Creer `/etc/update-motd.d/20-neofetch` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/sh
|
||||||
|
neofetch --config /etc/neofetch.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 755 /etc/update-motd.d/20-neofetch
|
||||||
|
```
|
||||||
|
|
||||||
|
## Script MOTD mises a jour
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install python3-apt
|
||||||
|
```
|
||||||
|
|
||||||
|
Creer `/etc/update-motd.d/30-updates` avec le script Python de detection des mises a jour (voir scripts/setup_motd_updates.py).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 755 /etc/update-motd.d/30-updates
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installer dselect
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install dselect
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ajouter un fichier de swap (4 Go)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fallocate -l 4G /swapfile
|
||||||
|
chmod 600 /swapfile
|
||||||
|
mkswap /swapfile
|
||||||
|
swapon /swapfile
|
||||||
|
echo '/swapfile swap swap defaults 0 0' >> /etc/fstab
|
||||||
|
echo 'vm.swappiness = 5' >> /etc/sysctl.conf
|
||||||
|
sysctl -p
|
||||||
|
```
|
||||||
55
03-bis-hestiacp.md
Normal file
55
03-bis-hestiacp.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# 3-bis. HestiaCP (Alternative a ISPConfig)
|
||||||
|
|
||||||
|
## Pourquoi HestiaCP ?
|
||||||
|
|
||||||
|
| Aspect | ISPConfig | HestiaCP |
|
||||||
|
|--------|-----------|----------|
|
||||||
|
| Interface | Ancienne | Moderne, intuitive |
|
||||||
|
| Performance | Plus lourd | Plus leger, plus rapide |
|
||||||
|
| Multi-serveur | Oui | Non |
|
||||||
|
| Mises a jour | Lentes | Frequentes |
|
||||||
|
| Communaute | Grande, ancienne | Plus petite, plus active |
|
||||||
|
|
||||||
|
**Recommande pour un seul serveur.**
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
|
||||||
|
bash hst-install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Options recommandees :
|
||||||
|
- Apache + Nginx (Nginx en proxy)
|
||||||
|
- MariaDB
|
||||||
|
- Bind9
|
||||||
|
- Exim + Dovecot + ClamAV + SpamAssassin
|
||||||
|
- Let's Encrypt
|
||||||
|
|
||||||
|
## Configuration post-installation
|
||||||
|
|
||||||
|
L'installeur configure automatiquement :
|
||||||
|
- Firewall (iptables)
|
||||||
|
- SSL Let's Encrypt pour le panel
|
||||||
|
- Bind9 pour DNS
|
||||||
|
- Mail complet
|
||||||
|
|
||||||
|
## Acces
|
||||||
|
|
||||||
|
```
|
||||||
|
https://<DOMAINE>:8083
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- Site : https://hestiacp.com/
|
||||||
|
- Docs : https://docs.hestiacp.com/
|
||||||
|
- GitHub : https://github.com/hestiacp/hestiacp
|
||||||
|
|
||||||
|
## Differences avec ce guide
|
||||||
|
|
||||||
|
Si vous utilisez HestiaCP, les sections DNS, Mail, et Sites Web seront differentes dans l'interface mais les concepts restent les memes :
|
||||||
|
- Creer une zone DNS avec les templates
|
||||||
|
- Creer un site web avec SSL Let's Encrypt
|
||||||
|
- Creer un domaine mail avec DKIM/DMARC
|
||||||
|
- Les services Docker (Portainer, Wireguard, etc.) restent identiques
|
||||||
67
03-ispconfig.md
Normal file
67
03-ispconfig.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# 3. ISPConfig
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget -O - https://get.ispconfig.org | sh -s -- --use-ftp-ports=40110-40210 --unattended-upgrades
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Important :** Notez les identifiants admin et le mot de passe MySQL root affiches a la fin.
|
||||||
|
|
||||||
|
## Resoudre les conflits
|
||||||
|
|
||||||
|
Si Apache ne demarre pas, verifier si un autre service occupe le port 80 :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ss -tlnp | grep ':80'
|
||||||
|
```
|
||||||
|
|
||||||
|
Si c'est Caddy ou Nginx :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl stop caddy && systemctl disable caddy
|
||||||
|
systemctl restart apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Desactiver UFW
|
||||||
|
|
||||||
|
ISPConfig gere le firewall via iptables. Ne pas utiliser UFW en parallele.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ufw disable
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configurer le firewall ISPConfig
|
||||||
|
|
||||||
|
Dans ISPConfig > **System > Firewall** :
|
||||||
|
|
||||||
|
**Open TCP ports :**
|
||||||
|
```
|
||||||
|
20,21,22,25,53,80,110,143,443,465,587,993,995,2812,3306,4190,8080,8081,10000,50022,40110:40210,7880,7881,5349
|
||||||
|
```
|
||||||
|
|
||||||
|
**Open UDP ports :**
|
||||||
|
```
|
||||||
|
53,7882,3478,51820
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration initiale ISPConfig
|
||||||
|
|
||||||
|
### Main config
|
||||||
|
- **System > Main config > Sites :**
|
||||||
|
- Create subdomains as web site : **Yes**
|
||||||
|
- Create aliasdomains as web site : **Yes**
|
||||||
|
- **System > Main config > Mail :**
|
||||||
|
- Renseigner email et nom administrateur
|
||||||
|
|
||||||
|
### Content Filter (Rspamd)
|
||||||
|
- **System > Server Config > votre serveur > Mail :**
|
||||||
|
- Content Filter : **Rspamd**
|
||||||
|
|
||||||
|
## Acces
|
||||||
|
|
||||||
|
```
|
||||||
|
https://<DOMAINE>:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Piege :** Certains hebergeurs (Contabo) bloquent le port 8080 au niveau firewall externe. Verifier l'acces et debloquer si necessaire.
|
||||||
92
04-dns.md
Normal file
92
04-dns.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# 4. DNS
|
||||||
|
|
||||||
|
## Templates DNS
|
||||||
|
|
||||||
|
Creer deux templates dans ISPConfig > **DNS > DNS Templates** :
|
||||||
|
|
||||||
|
### Template IPV4 autoNS
|
||||||
|
|
||||||
|
**Fields :** Domain, IP Address, Email, DKIM, DNSSEC
|
||||||
|
|
||||||
|
```
|
||||||
|
[ZONE]
|
||||||
|
origin={DOMAIN}.
|
||||||
|
ns=ns1.<DOMAINE_SERVEUR>.
|
||||||
|
mbox={EMAIL}.
|
||||||
|
refresh=7200
|
||||||
|
retry=540
|
||||||
|
expire=604800
|
||||||
|
minimum=3600
|
||||||
|
ttl=3600
|
||||||
|
|
||||||
|
[DNS_RECORDS]
|
||||||
|
A|{DOMAIN}.|{IP}|0|3600
|
||||||
|
A|www|{IP}|0|3600
|
||||||
|
A|mail|{IP}|0|3600
|
||||||
|
A|autoconfig|{IP}|0|3600
|
||||||
|
A|autodiscover|{IP}|0|3600
|
||||||
|
A|webmail|{IP}|0|3600
|
||||||
|
CNAME|ftp|{DOMAIN}|0|3600
|
||||||
|
CNAME|smtp|{DOMAIN}|0|3600
|
||||||
|
CNAME|pop3|{DOMAIN}|0|3600
|
||||||
|
CNAME|imap|{DOMAIN}|0|3600
|
||||||
|
NS|{DOMAIN}.|ns1.<DOMAINE_SERVEUR>.|0|3600
|
||||||
|
NS|{DOMAIN}.|ns2.<DOMAINE_SERVEUR>.|0|3600
|
||||||
|
MX|{DOMAIN}.|mail.{DOMAIN}.|10|3600
|
||||||
|
TXT|{DOMAIN}.|v=spf1 mx a ~all|0|3600
|
||||||
|
SRV|_imaps._tcp|0 1 993 mail.{DOMAIN}|0|3600
|
||||||
|
SRV|_submission._tcp|0 1 465 mail.{DOMAIN}|0|3600
|
||||||
|
```
|
||||||
|
|
||||||
|
### Template IPV6 autoNS
|
||||||
|
|
||||||
|
Meme chose que IPV4 + ajout des AAAA :
|
||||||
|
|
||||||
|
**Fields :** Domain, IP Address, IPv6 Address, Email, DKIM, DNSSEC
|
||||||
|
|
||||||
|
Ajouter dans [DNS_RECORDS] :
|
||||||
|
```
|
||||||
|
AAAA|{DOMAIN}.|{IPV6}|0|3600
|
||||||
|
AAAA|www|{IPV6}|0|3600
|
||||||
|
AAAA|mail|{IPV6}|0|3600
|
||||||
|
AAAA|autoconfig|{IPV6}|0|3600
|
||||||
|
AAAA|autodiscover|{IPV6}|0|3600
|
||||||
|
AAAA|webmail|{IPV6}|0|3600
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Important :** Les NS pointent vers `ns1.<DOMAINE_SERVEUR>` (votre domaine principal), pas `ns1.{DOMAIN}`. Cela evite les problemes de glue records pour les domaines heberges.
|
||||||
|
|
||||||
|
## Creer une zone DNS
|
||||||
|
|
||||||
|
ISPConfig > **DNS > Add DNS Zone > DNS Wizard**
|
||||||
|
|
||||||
|
- Template : Template IPV6 autoNS
|
||||||
|
- Domain : `<DOMAINE>`
|
||||||
|
- IP : `<IP>`
|
||||||
|
- IPv6 : `<IPV6>`
|
||||||
|
- Email : votre email
|
||||||
|
- DKIM : cocher
|
||||||
|
- DNSSEC : decocher (activer plus tard)
|
||||||
|
|
||||||
|
## Configurer les NS chez le registrar
|
||||||
|
|
||||||
|
### OVH
|
||||||
|
|
||||||
|
1. Creer les glue records : `ns1.<DOMAINE>` et `ns2.<DOMAINE>` -> `<IP>`
|
||||||
|
2. Changer les nameservers vers `ns1.<DOMAINE>` et `ns2.<DOMAINE>`
|
||||||
|
|
||||||
|
> **Note :** OVH verifie que Bind9 repond avant d'accepter. Creer la zone DNS dans ISPConfig d'abord.
|
||||||
|
|
||||||
|
### Domaines .ci (MTN/Cloud4Africa)
|
||||||
|
|
||||||
|
Pointer les NS vers le domaine serveur principal :
|
||||||
|
- `ns1.<DOMAINE_SERVEUR>`
|
||||||
|
- `ns2.<DOMAINE_SERVEUR>`
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dig @8.8.8.8 <DOMAINE> NS +short
|
||||||
|
dig @8.8.8.8 <DOMAINE> A +short
|
||||||
|
dig @8.8.8.8 mail.<DOMAINE> A +short
|
||||||
|
```
|
||||||
87
05-webmin.md
Normal file
87
05-webmin.md
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# 5. Webmin
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -o setup-repos.sh https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh
|
||||||
|
sh setup-repos.sh
|
||||||
|
rm setup-repos.sh
|
||||||
|
apt update && apt install webmin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configurer le compte admin
|
||||||
|
|
||||||
|
Remplacer `root` par `<USER>` dans :
|
||||||
|
- `/etc/webmin/miniserv.users`
|
||||||
|
- `/etc/webmin/webmin.acl`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sed -i 's/root:/<USER>:/' /etc/webmin/miniserv.users
|
||||||
|
sed -i 's/root:/<USER>:/' /etc/webmin/webmin.acl
|
||||||
|
service webmin restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## Desactiver SSL natif (utiliser proxy Apache)
|
||||||
|
|
||||||
|
Webmin a des problemes avec SSL sur certaines versions. Utiliser un proxy Apache :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sed -i 's/ssl=1/ssl=0/' /etc/webmin/miniserv.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Ajouter dans `/etc/webmin/config` :
|
||||||
|
```
|
||||||
|
webprefixnoredir=1
|
||||||
|
relative_redir=1
|
||||||
|
```
|
||||||
|
|
||||||
|
Ajouter dans `/etc/webmin/miniserv.conf` :
|
||||||
|
```
|
||||||
|
referers=webmin.<DOMAINE>
|
||||||
|
redirect_port=443
|
||||||
|
redirect_ssl=1
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl restart webmin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creer le sous-domaine
|
||||||
|
|
||||||
|
1. DNS : A record `webmin` -> `<IP>`
|
||||||
|
2. ISPConfig > Sites > Subdomain (vhost) :
|
||||||
|
- Hostname : `webmin`
|
||||||
|
- Domain : `<DOMAINE>`
|
||||||
|
- Web folder : `webmin`
|
||||||
|
- SSL + Let's Encrypt
|
||||||
|
- Rewrite HTTP to HTTPS
|
||||||
|
|
||||||
|
3. Apache Directives :
|
||||||
|
```apache
|
||||||
|
<Proxy *>
|
||||||
|
Order deny,allow
|
||||||
|
Allow from all
|
||||||
|
</Proxy>
|
||||||
|
|
||||||
|
ProxyRequests Off
|
||||||
|
ProxyPass /stats !
|
||||||
|
ProxyPass /.well-known/acme-challenge !
|
||||||
|
|
||||||
|
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
|
||||||
|
ProxyPreserveHost On
|
||||||
|
|
||||||
|
ProxyPass / http://localhost:10000/
|
||||||
|
ProxyPassReverse / http://localhost:10000/
|
||||||
|
|
||||||
|
RedirectMatch ^/$ https://webmin.<DOMAINE>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ajouter le port au firewall
|
||||||
|
|
||||||
|
ISPConfig > System > Firewall : ajouter `10000` aux TCP ports.
|
||||||
|
|
||||||
|
## Acces
|
||||||
|
|
||||||
|
```
|
||||||
|
https://webmin.<DOMAINE>
|
||||||
|
```
|
||||||
163
06-monitoring.md
Normal file
163
06-monitoring.md
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
# 6. Monitoring
|
||||||
|
|
||||||
|
## Munin
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install libcgi-fast-perl libapache2-mod-fcgid
|
||||||
|
a2enmod fcgid
|
||||||
|
apt install munin munin-node munin-plugins-extra logtail libcache-cache-perl
|
||||||
|
```
|
||||||
|
|
||||||
|
### Plugins MySQL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /etc/munin/plugins
|
||||||
|
ln -s /usr/share/munin/plugins/mysql_ mysql_
|
||||||
|
ln -s /usr/share/munin/plugins/mysql_bytes mysql_bytes
|
||||||
|
ln -s /usr/share/munin/plugins/mysql_innodb mysql_innodb
|
||||||
|
ln -s /usr/share/munin/plugins/mysql_isam_space_ mysql_isam_space_
|
||||||
|
ln -s /usr/share/munin/plugins/mysql_queries mysql_queries
|
||||||
|
ln -s /usr/share/munin/plugins/mysql_slowqueries mysql_slowqueries
|
||||||
|
ln -s /usr/share/munin/plugins/mysql_threads mysql_threads
|
||||||
|
```
|
||||||
|
|
||||||
|
### Base de donnees Munin
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE SCHEMA munin_innodb;
|
||||||
|
USE munin_innodb;
|
||||||
|
CREATE TABLE something (anything int) ENGINE=InnoDB;
|
||||||
|
GRANT SELECT ON munin_innodb.* TO 'munin'@'localhost' IDENTIFIED BY 'munin';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Editer `/etc/munin/munin.conf` :
|
||||||
|
- Decommenter `dbdir`, `htmldir`, `logdir`, `rundir`, `tmpldir`
|
||||||
|
- Remplacer `[localhost.localdomain]` par `[munin.<DOMAINE>]`
|
||||||
|
|
||||||
|
### Apache auth
|
||||||
|
|
||||||
|
```bash
|
||||||
|
a2enconf munin
|
||||||
|
htpasswd -c /etc/munin/munin-htpasswd admin
|
||||||
|
```
|
||||||
|
|
||||||
|
Editer `/etc/apache2/conf-enabled/munin.conf` avec auth basic (voir scripts/setup_munin_config.py).
|
||||||
|
|
||||||
|
### Auto-configure plugins
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /etc/munin/plugins
|
||||||
|
munin-node-configure --shell --families=contrib,auto | sh -x
|
||||||
|
service munin-node restart
|
||||||
|
service apache2 restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monit
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install monit
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Creer `/etc/monit/conf.d/monitrc.local` :
|
||||||
|
|
||||||
|
```
|
||||||
|
set daemon 60
|
||||||
|
set logfile syslog facility log_daemon
|
||||||
|
set mailserver localhost
|
||||||
|
set mail-format { from: monit@<DOMAINE> }
|
||||||
|
set alert <EMAIL>
|
||||||
|
set httpd port 2812 and
|
||||||
|
SSL ENABLE
|
||||||
|
PEMFILE /usr/local/ispconfig/interface/ssl/ispserver.pem
|
||||||
|
allow admin:"<MOT_DE_PASSE>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fichiers de monitoring
|
||||||
|
|
||||||
|
Creer dans `/etc/monit/conf-enabled/` les fichiers pour : mariadb, pureftpd, named, sshd, apache2, memcached, ntpd, dovecot, postfix, redis.
|
||||||
|
|
||||||
|
Voir `scripts/setup_monit.py` pour le script complet.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir /var/www/html/monit
|
||||||
|
echo "hello" > /var/www/html/monit/token
|
||||||
|
service apache2 restart
|
||||||
|
service monit restart
|
||||||
|
```
|
||||||
|
|
||||||
|
Ajouter port 2812 au firewall ISPConfig.
|
||||||
|
|
||||||
|
## Grafana + Prometheus
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "deb https://packages.grafana.com/oss/deb stable main" >> /etc/apt/sources.list.d/grafana.list
|
||||||
|
cd /etc/apt/trusted.gpg.d && wget https://packages.grafana.com/gpg.key -O grafana.asc
|
||||||
|
apt update
|
||||||
|
apt install grafana prometheus prometheus-mysqld-exporter prometheus-apache-exporter prometheus-bind-exporter prometheus-process-exporter
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configurer Grafana sur port 3100
|
||||||
|
|
||||||
|
Editer `/etc/grafana/grafana.ini` :
|
||||||
|
```ini
|
||||||
|
http_port = 3100
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configurer Prometheus
|
||||||
|
|
||||||
|
Editer `/etc/prometheus/prometheus.yml` — ajouter les jobs : prometheus, node, dns-master, apache, process, mysql.
|
||||||
|
|
||||||
|
> **Piege :** Ne pas dupliquer les jobs (erreur "found multiple scrape configs with job name").
|
||||||
|
|
||||||
|
### Sous-domaine Grafana
|
||||||
|
|
||||||
|
DNS A `grafana` -> `<IP>`, puis sous-domaine ISPConfig avec proxy vers `http://localhost:3100/`.
|
||||||
|
|
||||||
|
### Demarrer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl enable grafana-server && systemctl start grafana-server
|
||||||
|
service prometheus restart
|
||||||
|
```
|
||||||
|
|
||||||
|
Login par defaut : **admin / admin**
|
||||||
|
|
||||||
|
## Loki + Promtail
|
||||||
|
|
||||||
|
### Loki
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /usr/local/bin
|
||||||
|
# Telecharger la derniere version depuis https://github.com/grafana/loki/releases/
|
||||||
|
wget <URL_LOKI_LINUX_AMD64> -O loki.zip
|
||||||
|
unzip loki.zip && mv loki-linux-amd64 loki && chmod 755 loki && rm loki.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
Creer `/etc/config-loki.yml` et `/etc/systemd/system/loki.service`.
|
||||||
|
|
||||||
|
> **Piege :** Loki v3 a un format de config different de v2. Utiliser `schema: v13` et `store: tsdb`.
|
||||||
|
|
||||||
|
### Promtail
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Promtail n'existe plus dans Loki v3, utiliser la derniere v2
|
||||||
|
wget https://github.com/grafana/loki/releases/download/v2.9.10/promtail-linux-amd64.zip -O promtail.zip
|
||||||
|
unzip promtail.zip && mv promtail-linux-amd64 promtail && chmod 755 promtail && rm promtail.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
Creer `/etc/config-promtail.yml` et `/etc/systemd/system/promtail.service`.
|
||||||
|
|
||||||
|
### Ajouter Loki dans Grafana
|
||||||
|
|
||||||
|
Configuration > Data Sources > Add > Loki > URL : `http://127.0.0.1:3101`
|
||||||
151
07-mail.md
Normal file
151
07-mail.md
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
# 7. Mail
|
||||||
|
|
||||||
|
## Desactiver amavisd
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl stop amavisd-new 2>/dev/null
|
||||||
|
systemctl disable amavisd-new 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configurer Rspamd
|
||||||
|
|
||||||
|
Voir `scripts/setup_rspamd.py` pour le script complet. Fichiers crees :
|
||||||
|
|
||||||
|
- `/etc/rspamd/local.d/classifier-bayes.conf` — apprentissage Bayes + Redis
|
||||||
|
- `/etc/rspamd/local.d/redis.conf` — serveur Redis
|
||||||
|
- `/etc/rspamd/local.d/metrics.conf` — seuils spam
|
||||||
|
- `/etc/rspamd/local.d/history_redis.conf` — historique
|
||||||
|
- `/etc/rspamd/local.d/url_reputation.conf` — reputation URLs
|
||||||
|
- `/etc/rspamd/local.d/mx_check.conf` — verification MX
|
||||||
|
- `/etc/rspamd/local.d/neural.conf` — reseau de neurones
|
||||||
|
- `/etc/rspamd/local.d/neural_group.conf` — groupes neurones
|
||||||
|
- `/etc/rspamd/local.d/milter_headers.conf` — headers spam
|
||||||
|
- `/etc/rspamd/local.d/arc.conf` — protocole ARC
|
||||||
|
- `/etc/rspamd/local.d/antivirus.conf` — ClamAV
|
||||||
|
- `/etc/rspamd/local.d/groups.conf` — groupes antivirus
|
||||||
|
- `/etc/rspamd/local.d/antivirus_group.conf` — detection virus
|
||||||
|
|
||||||
|
```bash
|
||||||
|
a2enmod proxy
|
||||||
|
systemctl restart apache2
|
||||||
|
systemctl restart rspamd
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dovecot Sieve (apprentissage spam/ham)
|
||||||
|
|
||||||
|
Voir `scripts/setup_dovecot_sieve.py`. Configure :
|
||||||
|
- Deplacement vers Junk = apprend comme spam
|
||||||
|
- Deplacement depuis Junk = apprend comme ham
|
||||||
|
- Quota warning a 90%
|
||||||
|
|
||||||
|
Installer les plugins necessaires :
|
||||||
|
```bash
|
||||||
|
apt install dovecot-sieve dovecot-managesieved
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creer le domaine mail
|
||||||
|
|
||||||
|
ISPConfig > **Email > Domain > Add new Domain**
|
||||||
|
- Domain : `<DOMAINE>`
|
||||||
|
- Enable DKIM : cocher
|
||||||
|
- Generate DKIM Private-key
|
||||||
|
|
||||||
|
## Ajouter DMARC
|
||||||
|
|
||||||
|
ISPConfig > DNS > Zones > `<DOMAINE>` > Records > TXT :
|
||||||
|
- Hostname : `_dmarc`
|
||||||
|
- Text : `v=DMARC1;p=reject;sp=quarantine;pct=100;rua=mailto:<EMAIL>`
|
||||||
|
|
||||||
|
## Verifier SPF
|
||||||
|
|
||||||
|
Doit deja exister (cree par le template) :
|
||||||
|
```
|
||||||
|
TXT <DOMAINE>. v=spf1 mx a ~all
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configurer Postfix
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verifier dans /etc/postfix/main.cf :
|
||||||
|
myhostname = mail.<DOMAINE>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sous-domaine webmail (Roundcube)
|
||||||
|
|
||||||
|
1. DNS A `mail` -> `<IP>`
|
||||||
|
2. ISPConfig > Sites > Subdomain (vhost) : `mail.<DOMAINE>`
|
||||||
|
3. Apache Directives :
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<Proxy *>
|
||||||
|
Order deny,allow
|
||||||
|
Allow from all
|
||||||
|
</Proxy>
|
||||||
|
|
||||||
|
ProxyRequests Off
|
||||||
|
ProxyPass /stats !
|
||||||
|
ProxyPass /.well-known/acme-challenge !
|
||||||
|
|
||||||
|
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
|
||||||
|
SSLProxyEngine On
|
||||||
|
ProxyPreserveHost On
|
||||||
|
SSLProxyVerify none
|
||||||
|
SSLProxyCheckPeerCN off
|
||||||
|
SSLProxyCheckPeerName off
|
||||||
|
SSLProxyCheckPeerExpire off
|
||||||
|
|
||||||
|
ProxyPass /webmail https://localhost:8080/webmail/
|
||||||
|
ProxyPass / https://localhost:8080/webmail/
|
||||||
|
ProxyPassReverse / https://localhost:8080/webmail/
|
||||||
|
|
||||||
|
RedirectMatch ^/$ https://mail.<DOMAINE>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sous-domaine Rspamd
|
||||||
|
|
||||||
|
Meme principe avec proxy vers `https://<DOMAINE>:8081/rspamd/`.
|
||||||
|
|
||||||
|
## Autoconfig (Thunderbird/Android)
|
||||||
|
|
||||||
|
1. Sous-domaine `autoconfig.<DOMAINE>` avec Apache Directives :
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<FilesMatch "^.+\.xml$">
|
||||||
|
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
<FilesMatch "^.+\.json$">
|
||||||
|
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
AddHandler application/x-httpd-php .php .xml .json
|
||||||
|
|
||||||
|
<IfModule mod_speling.c>
|
||||||
|
CheckCaseOnly on
|
||||||
|
CheckSpelling on
|
||||||
|
</IfModule>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Creer le fichier `autoconfig/mail/config-v1.1.xml` (voir scripts/setup_autoconfig.py)
|
||||||
|
|
||||||
|
3. Mettre a jour PHP-FPM : ajouter `.xml .json` dans `security.limit_extensions`
|
||||||
|
|
||||||
|
## Autodiscover (Outlook)
|
||||||
|
|
||||||
|
Meme sous-domaine pointant vers le meme dossier `autoconfig`. Creer `autoconfig/Autodiscover/Autodiscover.xml`.
|
||||||
|
|
||||||
|
## Creer une boite mail
|
||||||
|
|
||||||
|
ISPConfig > **Email > Email Mailbox > Add new Mailbox**
|
||||||
|
|
||||||
|
## Tester l'envoi
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "Test" | mail -s "Test" -r contact@<DOMAINE> votre@email.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## MAILER_DSN pour Symfony
|
||||||
|
|
||||||
|
```
|
||||||
|
MAILER_DSN=smtp://127.0.0.1:25?auto_tls=false
|
||||||
|
```
|
||||||
78
08-sni-mail.md
Normal file
78
08-sni-mail.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# 8. SNI Mail Multi-Domaines
|
||||||
|
|
||||||
|
## Probleme
|
||||||
|
|
||||||
|
Par defaut, Dovecot/Postfix servent un seul certificat SSL pour tous les domaines mail. Les clients (iPhone, Gmail app) refusent la connexion si le certificat ne correspond pas au serveur configure.
|
||||||
|
|
||||||
|
## Solution : SNI (Server Name Indication)
|
||||||
|
|
||||||
|
### Dovecot SNI
|
||||||
|
|
||||||
|
Editer `/etc/dovecot/dovecot.conf`, apres la ligne `ssl_prefer_server_ciphers = no` ajouter :
|
||||||
|
|
||||||
|
```
|
||||||
|
# SNI per domain
|
||||||
|
local_name mail.<DOMAINE1> {
|
||||||
|
ssl_cert = </chemin/vers/mail.<DOMAINE1>-le.crt
|
||||||
|
ssl_key = </chemin/vers/mail.<DOMAINE1>-le.key
|
||||||
|
}
|
||||||
|
|
||||||
|
local_name mail.<DOMAINE2> {
|
||||||
|
ssl_cert = </chemin/vers/mail.<DOMAINE2>-le.crt
|
||||||
|
ssl_key = </chemin/vers/mail.<DOMAINE2>-le.key
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Piege :** Ne pas mettre le SNI dans `conf.d/10-ssl.conf` — ISPConfig ou le `dovecot.conf` principal ecrase les valeurs. Toujours ajouter directement dans `dovecot.conf`.
|
||||||
|
|
||||||
|
### Trouver les certificats
|
||||||
|
|
||||||
|
ISPConfig stocke les certificats LE dans le dossier SSL du site :
|
||||||
|
```bash
|
||||||
|
find /var/www/clients/ -name "mail.<DOMAINE>-le.*"
|
||||||
|
```
|
||||||
|
|
||||||
|
Format : `/var/www/clients/clientX/webY/ssl/mail.<DOMAINE>-le.crt` et `.key`
|
||||||
|
|
||||||
|
### Postfix SNI
|
||||||
|
|
||||||
|
Creer `/etc/postfix/sni_map` :
|
||||||
|
|
||||||
|
```
|
||||||
|
mail.<DOMAINE1> /chemin/vers/mail.<DOMAINE1>-le.key /chemin/vers/mail.<DOMAINE1>-le.crt
|
||||||
|
mail.<DOMAINE2> /chemin/vers/mail.<DOMAINE2>-le.key /chemin/vers/mail.<DOMAINE2>-le.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
postmap -F hash:/etc/postfix/sni_map
|
||||||
|
```
|
||||||
|
|
||||||
|
Ajouter dans `/etc/postfix/main.cf` :
|
||||||
|
```
|
||||||
|
tls_server_sni_maps = hash:/etc/postfix/sni_map
|
||||||
|
```
|
||||||
|
|
||||||
|
### Redemarrer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl restart dovecot
|
||||||
|
systemctl restart postfix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo | openssl s_client -connect <IP>:993 -servername mail.<DOMAINE1> 2>&1 | grep "subject="
|
||||||
|
# Doit afficher : subject=CN = mail.<DOMAINE1>
|
||||||
|
|
||||||
|
echo | openssl s_client -connect <IP>:993 -servername mail.<DOMAINE2> 2>&1 | grep "subject="
|
||||||
|
# Doit afficher : subject=CN = mail.<DOMAINE2>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Certificat par defaut ISPConfig
|
||||||
|
|
||||||
|
Le certificat dans `/usr/local/ispconfig/interface/ssl/ispserver.crt` est utilise pour :
|
||||||
|
- ISPConfig panel (port 8080)
|
||||||
|
- Dovecot/Postfix par defaut (quand SNI ne match pas)
|
||||||
|
|
||||||
|
Garder le certificat du domaine principal du serveur (`<DOMAINE>`) comme defaut.
|
||||||
102
09-docker.md
Normal file
102
09-docker.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# 9. Docker
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Si Docker n'est pas deja installe :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt-get update
|
||||||
|
apt-get install ca-certificates curl
|
||||||
|
install -m 0755 -d /etc/apt/keyrings
|
||||||
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||||
|
chmod a+r /etc/apt/keyrings/docker.asc
|
||||||
|
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
|
||||||
|
apt update
|
||||||
|
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
```
|
||||||
|
|
||||||
|
Verifier :
|
||||||
|
```bash
|
||||||
|
docker run hello-world
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Swarm
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker swarm init
|
||||||
|
docker node ls
|
||||||
|
```
|
||||||
|
|
||||||
|
## Portainer
|
||||||
|
|
||||||
|
1. DNS A `portainer` -> `<IP>`
|
||||||
|
2. Sous-domaine ISPConfig `portainer.<DOMAINE>` avec proxy :
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<Proxy *>
|
||||||
|
Order deny,allow
|
||||||
|
Allow from all
|
||||||
|
</Proxy>
|
||||||
|
|
||||||
|
ProxyRequests Off
|
||||||
|
ProxyPass /stats !
|
||||||
|
ProxyPass /.well-known/acme-challenge !
|
||||||
|
|
||||||
|
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
|
||||||
|
ProxyPreserveHost On
|
||||||
|
|
||||||
|
ProxyPass / http://localhost:9050/
|
||||||
|
ProxyPassReverse / http://localhost:9050/
|
||||||
|
|
||||||
|
RedirectMatch ^/$ https://portainer.<DOMAINE>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Installer :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker volume create portainer_data
|
||||||
|
docker run -d -p 9050:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Acceder : `https://portainer.<DOMAINE>` — creer le compte admin.
|
||||||
|
|
||||||
|
## Yacht
|
||||||
|
|
||||||
|
1. DNS A `yacht` -> `<IP>`
|
||||||
|
2. Sous-domaine ISPConfig avec proxy vers `http://localhost:8061/`
|
||||||
|
|
||||||
|
3. Installer :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker volume create yacht_data
|
||||||
|
docker run -d -p 8061:8000 --name=yacht -v /var/run/docker.sock:/var/run/docker.sock --restart=always -v yacht_data:/config selfhostedpro/yacht
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Login par defaut : `admin@yacht.local` / `pass` — changer immediatement.
|
||||||
|
|
||||||
|
## Modele Apache Directives pour proxy Docker
|
||||||
|
|
||||||
|
Pour tous les services Docker accessibles via sous-domaine :
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<Proxy *>
|
||||||
|
Order deny,allow
|
||||||
|
Allow from all
|
||||||
|
</Proxy>
|
||||||
|
|
||||||
|
ProxyRequests Off
|
||||||
|
ProxyPass /stats !
|
||||||
|
ProxyPass /.well-known/acme-challenge !
|
||||||
|
|
||||||
|
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
|
||||||
|
ProxyPreserveHost On
|
||||||
|
|
||||||
|
ProxyPass / http://localhost:<PORT>/
|
||||||
|
ProxyPassReverse / http://localhost:<PORT>/
|
||||||
|
|
||||||
|
RedirectMatch ^/$ https://<SOUS_DOMAINE>.<DOMAINE>
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Piege :** Apres creation du sous-domaine, supprimer le fichier `standard_index.html` si la page par defaut ISPConfig s'affiche. Aussi verifier que SSL/Let's Encrypt est bien coche.
|
||||||
93
10-services-docker.md
Normal file
93
10-services-docker.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# 10. Services Docker
|
||||||
|
|
||||||
|
## Wireguard (VPN)
|
||||||
|
|
||||||
|
1. DNS A `wireguard` -> `<IP>`
|
||||||
|
2. Sous-domaine ISPConfig avec proxy vers `http://localhost:51821/`
|
||||||
|
3. Ouvrir port 51820/udp dans firewall ISPConfig
|
||||||
|
|
||||||
|
4. Generer le hash du mot de passe :
|
||||||
|
```bash
|
||||||
|
docker run --rm python:3-alpine sh -c "pip install bcrypt -q && python3 -c \"import bcrypt; print(bcrypt.hashpw(b'<MOT_DE_PASSE>', bcrypt.gensalt()).decode())\""
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Installer (en une ligne, remplacer le hash) :
|
||||||
|
```bash
|
||||||
|
docker run -d --name=wg-easy -e LANG=fr -e WG_HOST=<IP> -e "PASSWORD_HASH=<HASH_BCRYPT>" -e PORT=51821 -e WG_PORT=51820 -v /etc/wg-easy:/etc/wireguard -p 51820:51820/udp -p 51821:51821/tcp --cap-add=NET_ADMIN --cap-add=SYS_MODULE --sysctl="net.ipv4.conf.all.src_valid_mark=1" --sysctl="net.ipv4.ip_forward=1" --restart unless-stopped ghcr.io/wg-easy/wg-easy
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Piege :** Les versions recentes de wg-easy exigent `PASSWORD_HASH` (bcrypt) au lieu de `PASSWORD`.
|
||||||
|
|
||||||
|
## Vaultwarden (gestionnaire de mots de passe)
|
||||||
|
|
||||||
|
1. DNS A `vaultwarden` -> `<IP>`
|
||||||
|
2. Sous-domaine ISPConfig avec proxy vers `http://localhost:1280/`
|
||||||
|
|
||||||
|
3. Generer le hash admin :
|
||||||
|
```bash
|
||||||
|
echo -n "<MOT_DE_PASSE>" | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Installer (echapper les `$` du hash avec `\$`) :
|
||||||
|
```bash
|
||||||
|
docker volume create vaultwarden_data
|
||||||
|
docker run -d -p 1280:80 --name=vaultwarden --restart=always -v vaultwarden_data:/data:rw -e ROCKET_ENV=staging -e ROCKET_PORT=80 -e ROCKET_WORKERS=10 -e SMTP_HOST=127.0.0.1 -e SMTP_FROM=vaultwarden@<DOMAINE> -e SMTP_PORT=25 -e SMTP_SECURITY=off -e WEBSOCKET_ENABLED=true -e "ADMIN_TOKEN=<HASH_ARGON2>" -e SIGNUPS_ALLOWED=false -e DOMAIN=https://vaultwarden.<DOMAINE> vaultwarden/server:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Activer temporairement les inscriptions via `/admin`, creer son compte, desactiver.
|
||||||
|
|
||||||
|
## Heimdall (dashboard)
|
||||||
|
|
||||||
|
1. DNS A `heimdall` -> `<IP>`
|
||||||
|
2. Sous-domaine ISPConfig avec proxy HTTPS vers `https://localhost:1281/`
|
||||||
|
|
||||||
|
```apache
|
||||||
|
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
|
||||||
|
SSLProxyEngine On
|
||||||
|
ProxyPreserveHost On
|
||||||
|
SSLProxyVerify none
|
||||||
|
SSLProxyCheckPeerCN off
|
||||||
|
SSLProxyCheckPeerName off
|
||||||
|
SSLProxyCheckPeerExpire off
|
||||||
|
|
||||||
|
ProxyPass / https://localhost:1281/
|
||||||
|
ProxyPassReverse / https://localhost:1281/
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Installer :
|
||||||
|
```bash
|
||||||
|
docker volume create heimdall_data
|
||||||
|
docker run -d -p 1281:443 --name=heimdall --restart=always -v heimdall_data:/config:rw -e PGID=1000 -e PUID=1000 linuxserver/heimdall
|
||||||
|
```
|
||||||
|
|
||||||
|
## Guacamole (bureau a distance)
|
||||||
|
|
||||||
|
1. DNS A `guacamole` -> `<IP>`
|
||||||
|
2. Creer base de donnees `guacamole` dans ISPConfig
|
||||||
|
3. Sous-domaine ISPConfig avec proxy :
|
||||||
|
|
||||||
|
```apache
|
||||||
|
ProxyPass /guacamole http://localhost:8085/guacamole
|
||||||
|
ProxyPassReverse /guacamole http://localhost:8085/guacamole
|
||||||
|
RedirectMatch ^/$ https://guacamole.<DOMAINE>/guacamole
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Installer :
|
||||||
|
```bash
|
||||||
|
docker run -d --name guacamole-guacd --restart=always guacamole/guacd
|
||||||
|
docker run -d --name guacamole-web --restart=always --link guacamole-guacd:guacd -e MYSQL_HOSTNAME=172.17.0.1 -e MYSQL_PORT=3306 -e MYSQL_DATABASE=<DB_NAME> -e MYSQL_USER=<DB_USER> -e MYSQL_PASSWORD=<DB_PASS> -p 8085:8080 guacamole/guacamole
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Importer le schema :
|
||||||
|
```bash
|
||||||
|
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql | mysql -u root <DB_NAME>
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Autoriser l'acces depuis Docker :
|
||||||
|
```bash
|
||||||
|
mysql -u root -e "GRANT ALL PRIVILEGES ON <DB_NAME>.* TO '<DB_USER>'@'172.17.0.%' IDENTIFIED BY '<DB_PASS>'; FLUSH PRIVILEGES;"
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Login par defaut : `guacadmin` / `guacadmin` — creer un admin et supprimer guacadmin.
|
||||||
|
|
||||||
|
> **Piege :** Tomcat 10 natif est incompatible avec Guacamole 1.5.5. Utiliser Docker a la place.
|
||||||
115
11-applications.md
Normal file
115
11-applications.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# 11. Applications Web
|
||||||
|
|
||||||
|
## Wordpress
|
||||||
|
|
||||||
|
1. DNS A `wordpress` -> `<IP>`
|
||||||
|
2. Sous-domaine ISPConfig `wordpress.<DOMAINE>` (SSL, LE, PHP-FPM, HTTPS redirect)
|
||||||
|
3. Creer base de donnees `wordpress` (user + database dans ISPConfig)
|
||||||
|
4. Identifier le proprietaire :
|
||||||
|
```bash
|
||||||
|
ls -la /var/www/wordpress.<DOMAINE>/ | head -5
|
||||||
|
# Noter webX:clientY
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Installer :
|
||||||
|
```bash
|
||||||
|
cd /tmp
|
||||||
|
wget -O wordpress.tar.gz https://wordpress.org/latest.tar.gz
|
||||||
|
tar -xzf wordpress.tar.gz
|
||||||
|
mv wordpress/* /var/www/wordpress.<DOMAINE>/wordpress/
|
||||||
|
rm wordpress.tar.gz && rm -rf wordpress
|
||||||
|
chown -R webX:clientY /var/www/wordpress.<DOMAINE>/wordpress/
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Acceder : `https://wordpress.<DOMAINE>` et suivre l'assistant.
|
||||||
|
|
||||||
|
> **Piege :** Si la page par defaut ISPConfig s'affiche, verifier que SSL/LE est coche. Supprimer `standard_index.html` si present.
|
||||||
|
|
||||||
|
## Nextcloud
|
||||||
|
|
||||||
|
1. Installer les prerequis PHP :
|
||||||
|
```bash
|
||||||
|
apt install php-cgi php-curl
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Modifier `/etc/php/8.3/fpm/php.ini` :
|
||||||
|
```ini
|
||||||
|
memory_limit = 512M
|
||||||
|
upload_max_filesize = 500M
|
||||||
|
post_max_size = 500M
|
||||||
|
max_execution_time = 300
|
||||||
|
```
|
||||||
|
|
||||||
|
3. DNS A `nextcloud` -> `<IP>`
|
||||||
|
4. Sous-domaine ISPConfig (SSL, LE, PHP-FPM, HTTPS redirect, Webstatistics: None)
|
||||||
|
5. Creer base de donnees `nextcloud`
|
||||||
|
|
||||||
|
6. Telecharger l'installeur :
|
||||||
|
```bash
|
||||||
|
wget -O /var/www/nextcloud.<DOMAINE>/nextcloud/setup-nextcloud.php https://download.nextcloud.com/server/installer/setup-nextcloud.php
|
||||||
|
chown webX:clientY /var/www/nextcloud.<DOMAINE>/nextcloud/setup-nextcloud.php
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Acceder : `https://nextcloud.<DOMAINE>/setup-nextcloud.php`
|
||||||
|
- Repertoire : `.`
|
||||||
|
- Choisir MariaDB, renseigner la base
|
||||||
|
|
||||||
|
## Gitea
|
||||||
|
|
||||||
|
1. DNS A `gitea` -> `<IP>`
|
||||||
|
2. Sous-domaine ISPConfig avec proxy vers `http://localhost:3000/`
|
||||||
|
3. Creer base de donnees `gitea`
|
||||||
|
|
||||||
|
4. Installer :
|
||||||
|
```bash
|
||||||
|
# Creer l'utilisateur
|
||||||
|
adduser --system --disabled-password --group --shell /bin/bash --home /home/gitea gitea
|
||||||
|
|
||||||
|
# Repertoires
|
||||||
|
mkdir -p /var/lib/gitea/{data,log} /etc/gitea /run/gitea
|
||||||
|
chown -R gitea:gitea /var/lib/gitea /run/gitea
|
||||||
|
chown -R root:gitea /etc/gitea
|
||||||
|
chmod -R 750 /var/lib/gitea
|
||||||
|
chmod 770 /etc/gitea
|
||||||
|
|
||||||
|
# Telecharger (derniere version)
|
||||||
|
VERSION=$(wget -qO- https://api.github.com/repos/go-gitea/gitea/releases/latest | grep tag_name | cut -d'"' -f4 | tr -d v)
|
||||||
|
wget "https://dl.gitea.com/gitea/${VERSION}/gitea-${VERSION}-linux-amd64" -O /usr/local/bin/gitea
|
||||||
|
chmod 755 /usr/local/bin/gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Creer `/etc/systemd/system/gitea.service` :
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Gitea (Git with a cup of tea)
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
Requires=mysqld.service
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=gitea
|
||||||
|
Group=gitea
|
||||||
|
WorkingDirectory=/var/lib/gitea/
|
||||||
|
RuntimeDirectory=gitea
|
||||||
|
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
|
||||||
|
Restart=always
|
||||||
|
Environment=USER=gitea HOME=/home/gitea GITEA_WORK_DIR=/var/lib/gitea
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable gitea.service
|
||||||
|
systemctl start gitea.service
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Acceder : `https://gitea.<DOMAINE>/install` et configurer.
|
||||||
|
|
||||||
|
7. Securiser apres installation :
|
||||||
|
```bash
|
||||||
|
chmod 750 /etc/gitea
|
||||||
|
chown root:gitea /etc/gitea/app.ini
|
||||||
|
chmod 640 /etc/gitea/app.ini
|
||||||
|
systemctl restart gitea
|
||||||
|
```
|
||||||
100
12-backup.md
Normal file
100
12-backup.md
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# 12. Backup Rsync
|
||||||
|
|
||||||
|
## Prerequis
|
||||||
|
|
||||||
|
- Serveur de stockage distant avec acces SSH
|
||||||
|
- Cle SSH configuree pour l'acces sans mot de passe
|
||||||
|
|
||||||
|
## Configurer l'acces SSH
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copier la cle SSH de l'utilisateur vers root (le script tourne en root via cron)
|
||||||
|
mkdir -p /root/.ssh
|
||||||
|
cp /home/<USER>/.ssh/id_* /root/.ssh/
|
||||||
|
cp /home/<USER>/.ssh/known_hosts /root/.ssh/
|
||||||
|
```
|
||||||
|
|
||||||
|
Tester :
|
||||||
|
```bash
|
||||||
|
ssh -p <PORT_SSH_DISTANT> <USER_DISTANT>@<HOST_DISTANT> "echo OK"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creer la config
|
||||||
|
|
||||||
|
Creer `/etc/vps-backup.env` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REMOTE_USER=<USER_DISTANT>
|
||||||
|
REMOTE_HOST=<HOST_DISTANT>
|
||||||
|
REMOTE_PORT=<PORT_SSH_DISTANT>
|
||||||
|
REMOTE_BASE=<CHEMIN_DISTANT>/backups
|
||||||
|
DB_BACKUP_DIR=/tmp/vps-db-backup
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 600 /etc/vps-backup.env
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creer les repertoires distants
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -p <PORT_SSH_DISTANT> <USER_DISTANT>@<HOST_DISTANT> "mkdir -p <CHEMIN_DISTANT>/backups/{db,etc,ispconfig,www}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Script de backup
|
||||||
|
|
||||||
|
Creer `/usr/local/bin/vps-backup.sh` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source /etc/vps-backup.env
|
||||||
|
|
||||||
|
DATE=$(date +%Y%m%d_%H%M%S)
|
||||||
|
LOG="/var/log/vps-backup.log"
|
||||||
|
|
||||||
|
echo "[$DATE] Backup started" >> $LOG
|
||||||
|
|
||||||
|
# Dump databases
|
||||||
|
mkdir -p $DB_BACKUP_DIR
|
||||||
|
rm -f $DB_BACKUP_DIR/*.sql.gz $DB_BACKUP_DIR/*.tar.gz
|
||||||
|
|
||||||
|
for DB in $(mysql -N -e "SHOW DATABASES" | grep -v -E "^(information_schema|performance_schema|sys)$"); do
|
||||||
|
mysqldump --single-transaction --routines --triggers "$DB" | gzip > "$DB_BACKUP_DIR/${DB}.sql.gz"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Compresser en tar
|
||||||
|
tar -czf "$DB_BACKUP_DIR/all-databases-${DATE}.tar.gz" -C $DB_BACKUP_DIR --exclude="*.tar.gz" . || true
|
||||||
|
rm -f $DB_BACKUP_DIR/*.sql.gz
|
||||||
|
|
||||||
|
# Sync
|
||||||
|
rsync -avz -e "ssh -p $REMOTE_PORT" $DB_BACKUP_DIR/*.tar.gz $REMOTE_USER@$REMOTE_HOST:$REMOTE_BASE/db/ || echo "[$DATE] DB sync failed" >> $LOG
|
||||||
|
rsync -avz --delete -e "ssh -p $REMOTE_PORT" /etc/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_BASE/etc/ || echo "[$DATE] etc sync failed" >> $LOG
|
||||||
|
rsync -avz --delete -e "ssh -p $REMOTE_PORT" /usr/local/ispconfig/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_BASE/ispconfig/ || echo "[$DATE] ispconfig sync failed" >> $LOG
|
||||||
|
rsync -avz --delete -e "ssh -p $REMOTE_PORT" /var/www/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_BASE/www/ || echo "[$DATE] www sync failed" >> $LOG
|
||||||
|
|
||||||
|
rm -rf $DB_BACKUP_DIR
|
||||||
|
|
||||||
|
DATE_END=$(date +%Y%m%d_%H%M%S)
|
||||||
|
echo "[$DATE_END] Backup completed" >> $LOG
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 755 /usr/local/bin/vps-backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cron quotidien
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
# Ajouter :
|
||||||
|
0 2 * * * /usr/local/bin/vps-backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tester
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo /usr/local/bin/vps-backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Piege :** Le script tourne en root via cron. La cle SSH de root doit etre configuree pour l'acces distant.
|
||||||
122
13-securite.md
Normal file
122
13-securite.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# 13. Securite
|
||||||
|
|
||||||
|
## Certificats Let's Encrypt pour les outils
|
||||||
|
|
||||||
|
### ISPConfig
|
||||||
|
|
||||||
|
Les certificats sont dans `/var/www/clients/clientX/webY/ssl/<DOMAINE>-le.crt` et `.key`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SSL_DIR="/var/www/clients/client1/web7/ssl"
|
||||||
|
ISP_SSL="/usr/local/ispconfig/interface/ssl"
|
||||||
|
|
||||||
|
cp $SSL_DIR/<DOMAINE>-le.crt $ISP_SSL/ispserver.crt
|
||||||
|
cp $SSL_DIR/<DOMAINE>-le.key $ISP_SSL/ispserver.key
|
||||||
|
|
||||||
|
# Creer PEM (cert + key)
|
||||||
|
cat $ISP_SSL/ispserver.crt $ISP_SSL/ispserver.key > $ISP_SSL/ispserver.pem
|
||||||
|
|
||||||
|
systemctl restart apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Postfix / Dovecot
|
||||||
|
|
||||||
|
Les certificats sont automatiquement utilises via le PEM ISPConfig. Pour le SNI multi-domaines, voir [08-sni-mail.md](08-sni-mail.md).
|
||||||
|
|
||||||
|
## phpMyAdmin securise
|
||||||
|
|
||||||
|
### Changer l'URL et ajouter HTTP Auth
|
||||||
|
|
||||||
|
1. Desactiver l'alias global :
|
||||||
|
```bash
|
||||||
|
a2disconf phpmyadmin
|
||||||
|
```
|
||||||
|
|
||||||
|
2. DNS A `dbmanage` -> `<IP>`
|
||||||
|
3. Sous-domaine ISPConfig `dbmanage.<DOMAINE>` (SSL, LE, PHP-FPM, HTTPS redirect)
|
||||||
|
4. Apache Directives :
|
||||||
|
|
||||||
|
```apache
|
||||||
|
Alias / /usr/share/phpmyadmin/
|
||||||
|
|
||||||
|
<Directory /usr/share/phpmyadmin>
|
||||||
|
Options SymLinksIfOwnerMatch
|
||||||
|
DirectoryIndex index.php
|
||||||
|
|
||||||
|
AuthType Basic
|
||||||
|
AuthName "Database Management - Restricted Access"
|
||||||
|
AuthUserFile /etc/phpmyadmin/htpasswd.setup
|
||||||
|
Require valid-user
|
||||||
|
|
||||||
|
<IfModule mod_php.c>
|
||||||
|
php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
|
||||||
|
php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/:/usr/share/javascript/
|
||||||
|
</IfModule>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory /usr/share/phpmyadmin/setup>
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory /usr/share/phpmyadmin/libraries>
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory /usr/share/phpmyadmin/templates>
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Creer le mot de passe HTTP Auth :
|
||||||
|
```bash
|
||||||
|
htpasswd -c /etc/phpmyadmin/htpasswd.setup admin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fail2ban pour phpMyAdmin
|
||||||
|
|
||||||
|
Creer `/etc/fail2ban/filter.d/phpmyadmin.conf` :
|
||||||
|
```
|
||||||
|
[Definition]
|
||||||
|
failregex = ^<HOST> -.*"(GET|POST).*/dbmanage.*
|
||||||
|
user denied.*client: <HOST>
|
||||||
|
ignoreregex =
|
||||||
|
```
|
||||||
|
|
||||||
|
Creer `/etc/fail2ban/jail.d/phpmyadmin.conf` :
|
||||||
|
```
|
||||||
|
[phpmyadmin]
|
||||||
|
enabled = true
|
||||||
|
port = http,https
|
||||||
|
filter = phpmyadmin
|
||||||
|
logpath = /var/log/apache2/access.log
|
||||||
|
maxretry = 5
|
||||||
|
bantime = 3600
|
||||||
|
findtime = 600
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl restart fail2ban
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creer un admin DB
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mysql -u root -e "CREATE USER 'dbadmin'@'localhost' IDENTIFIED BY '<MOT_DE_PASSE>'; GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES;"
|
||||||
|
```
|
||||||
|
|
||||||
|
## DNSSEC
|
||||||
|
|
||||||
|
### Activer dans ISPConfig
|
||||||
|
|
||||||
|
DNS > Zones > `<DOMAINE>` > Zone settings > Sign Zone (DNSSEC) > Save
|
||||||
|
|
||||||
|
Recuperer les DS-Data affiches.
|
||||||
|
|
||||||
|
### Ajouter chez le registrar
|
||||||
|
|
||||||
|
**OVH :** DS Records > Ajouter
|
||||||
|
- Key tag, Algorithm 13, Digest type 2 (SHA-256), Digest
|
||||||
|
|
||||||
|
> **Piege OVH :** OVH peut retourner "Error while checking DNSKEYS" avec des NS personnalises. Retenter ou contacter le support.
|
||||||
|
|
||||||
|
**MTN (.ci) :** Envoyer les DS records au support car l'interface bug.
|
||||||
86
14-deploiement-symfony.md
Normal file
86
14-deploiement-symfony.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# 14. Deploiement Symfony
|
||||||
|
|
||||||
|
## Creer le site dans ISPConfig
|
||||||
|
|
||||||
|
1. DNS A `<PROJET>` -> `<IP>` (ou zone DNS dediee)
|
||||||
|
2. Site web ISPConfig : `<PROJET_DOMAINE>` (SSL, LE, PHP-FPM, HTTPS redirect)
|
||||||
|
3. Creer base de donnees dans ISPConfig
|
||||||
|
|
||||||
|
## Apache Directives pour Symfony
|
||||||
|
|
||||||
|
Dans l'onglet Options du site :
|
||||||
|
|
||||||
|
```apache
|
||||||
|
DocumentRoot /var/www/<PROJET_DOMAINE>/web/public
|
||||||
|
|
||||||
|
<Directory /var/www/<PROJET_DOMAINE>/web/public>
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
FallbackResource /index.php
|
||||||
|
</Directory>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lien symbolique
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ln -s /var/www/clients/clientX/webY/web /var/www/<PROJET>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Identifier le proprietaire
|
||||||
|
ls -la /var/www/<PROJET_DOMAINE>/ | head -5
|
||||||
|
# Noter webX:clientY
|
||||||
|
|
||||||
|
# Ajouter votre user au groupe client
|
||||||
|
usermod -a -G clientY <USER>
|
||||||
|
|
||||||
|
# Donner l'acces groupe
|
||||||
|
chmod 750 /var/www/clients/clientX/webY/web
|
||||||
|
|
||||||
|
# ACL pour acces complet
|
||||||
|
apt install acl
|
||||||
|
setfacl -R -m u:<USER>:rwx /var/www/clients/clientX/webY/web
|
||||||
|
setfacl -R -d -m u:<USER>:rwx /var/www/clients/clientX/webY/web
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Important :** Apres connexion SSH, executer `newgrp clientY` pour activer le groupe.
|
||||||
|
|
||||||
|
## Cloner le projet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@github.com:<REPO>.git /tmp/<PROJET>
|
||||||
|
cp -r /tmp/<PROJET>/. /var/www/clients/clientX/webY/web/
|
||||||
|
chown -R webX:clientY /var/www/clients/clientX/webY/web/
|
||||||
|
rm -rf /tmp/<PROJET>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installer les dependances
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /var/www/<PROJET>
|
||||||
|
composer install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration .env
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Base de donnees
|
||||||
|
DATABASE_URL="mysql://<DB_USER>:<DB_PASS>@localhost:3306/<DB_NAME>"
|
||||||
|
|
||||||
|
# Mail (Postfix local)
|
||||||
|
MAILER_DSN=smtp://127.0.0.1:25?auto_tls=false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migrations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php bin/console doctrine:migrations:migrate --no-interaction
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cache
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php bin/console cache:clear
|
||||||
|
```
|
||||||
109
15-livekit.md
Normal file
109
15-livekit.md
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# 15. LiveKit (Teleconsultation Video)
|
||||||
|
|
||||||
|
## Prerequis
|
||||||
|
|
||||||
|
- Docker installe
|
||||||
|
- Sous-domaine pour LiveKit (ex: `video.<PROJET_DOMAINE>`)
|
||||||
|
- Certificats SSL
|
||||||
|
|
||||||
|
## DNS et sous-domaine
|
||||||
|
|
||||||
|
1. DNS A `video` -> `<IP>` (dans la zone du projet)
|
||||||
|
2. Sous-domaine ISPConfig `video.<PROJET_DOMAINE>` (SSL, LE, PHP-FPM)
|
||||||
|
|
||||||
|
## Ports firewall
|
||||||
|
|
||||||
|
ISPConfig > System > Firewall, ajouter :
|
||||||
|
- TCP : `7880,7881,5349`
|
||||||
|
- UDP : `7882,3478`
|
||||||
|
|
||||||
|
## Recuperer les certificats
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Trouver les certificats generes par ISPConfig
|
||||||
|
find /var/www/clients/ -name "video.<PROJET_DOMAINE>-le.*"
|
||||||
|
|
||||||
|
# Copier
|
||||||
|
mkdir -p /chemin/projet/docker/livekit/certs
|
||||||
|
cp /var/www/clients/clientX/webY/ssl/video.<PROJET_DOMAINE>-le.crt /chemin/projet/docker/livekit/certs/fullchain.pem
|
||||||
|
cp /var/www/clients/clientX/webY/ssl/video.<PROJET_DOMAINE>-le.key /chemin/projet/docker/livekit/certs/privkey.pem
|
||||||
|
chown -R <USER>:<USER> /chemin/projet/docker/livekit/certs/
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Piege :** Verifier que la cle privee correspond au certificat :
|
||||||
|
> ```bash
|
||||||
|
> openssl x509 -noout -pubkey -in certs/fullchain.pem | md5sum
|
||||||
|
> openssl ec -pubout -in certs/privkey.pem 2>/dev/null | md5sum
|
||||||
|
> # Les deux md5 doivent etre identiques
|
||||||
|
> ```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### .env
|
||||||
|
|
||||||
|
```bash
|
||||||
|
LIVEKIT_API_KEY=<generer avec: openssl rand -hex 16>
|
||||||
|
LIVEKIT_API_SECRET=<generer avec: openssl rand -base64 32>
|
||||||
|
TZ=Africa/Abidjan
|
||||||
|
LIVEKIT_CPU_LIMIT=2.0
|
||||||
|
LIVEKIT_MEM_LIMIT=2G
|
||||||
|
```
|
||||||
|
|
||||||
|
### livekit-prod.yaml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
port: 7880
|
||||||
|
|
||||||
|
redis:
|
||||||
|
address: localhost:6380 # Port different du Redis systeme (6379)
|
||||||
|
|
||||||
|
rtc:
|
||||||
|
udp_port: 7882
|
||||||
|
tcp_port: 7881
|
||||||
|
allow_tcp_fallback: true
|
||||||
|
use_external_ip: false
|
||||||
|
node_ip: <IP>
|
||||||
|
|
||||||
|
turn:
|
||||||
|
enabled: true
|
||||||
|
tls_port: 5349
|
||||||
|
udp_port: 3478
|
||||||
|
domain: video.<PROJET_DOMAINE>
|
||||||
|
cert_file: /etc/livekit/tls/fullchain.pem
|
||||||
|
key_file: /etc/livekit/tls/privkey.pem
|
||||||
|
|
||||||
|
room:
|
||||||
|
auto_create: true
|
||||||
|
empty_timeout: 300
|
||||||
|
max_participants: 2
|
||||||
|
|
||||||
|
webhook:
|
||||||
|
api_key: <LIVEKIT_API_KEY>
|
||||||
|
urls:
|
||||||
|
- https://<PROJET_DOMAINE>/api/v1/teleconsultation/livekit-webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Piege :** Le Redis du container doit tourner sur un port different (6380) du Redis systeme (6379) quand on utilise `network_mode: host`.
|
||||||
|
|
||||||
|
## Demarrer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /chemin/projet/docker/livekit
|
||||||
|
docker compose -f docker-compose.prod.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verifier
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs djeliba_livekit_server --tail 10
|
||||||
|
# Chercher "starting LiveKit server" et "Starting TURN server"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Symfony .env
|
||||||
|
|
||||||
|
```
|
||||||
|
TELECONSULTATION_PROVIDER=livekit
|
||||||
|
LIVEKIT_URL=wss://video.<PROJET_DOMAINE>:7880
|
||||||
|
LIVEKIT_API_KEY=<meme valeur>
|
||||||
|
LIVEKIT_API_SECRET=<meme valeur>
|
||||||
|
```
|
||||||
109
16-notes-pieges.md
Normal file
109
16-notes-pieges.md
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# 16. Notes et Pieges
|
||||||
|
|
||||||
|
## Pieges frequents
|
||||||
|
|
||||||
|
### UFW vs ISPConfig
|
||||||
|
Ne jamais utiliser UFW avec ISPConfig. ISPConfig gere le firewall via iptables. Desactiver UFW : `ufw disable`.
|
||||||
|
|
||||||
|
### Ports bloques par l'hebergeur
|
||||||
|
Contabo bloque certains ports non-standard au niveau de son firewall externe. Toujours tester l'acces depuis l'exterieur apres ouverture d'un port.
|
||||||
|
|
||||||
|
### Page "Welcome to your website" ISPConfig
|
||||||
|
Apres creation d'un sous-domaine, la page par defaut ISPConfig peut s'afficher. Solutions :
|
||||||
|
1. Verifier que SSL/Let's Encrypt est bien coche
|
||||||
|
2. Supprimer `standard_index.html` : `find /var/www/ -path "*<sous-domaine>*standard_index*" -delete`
|
||||||
|
|
||||||
|
### DNS Templates : NS personnalises
|
||||||
|
Les templates DNS doivent pointer les NS vers le domaine serveur principal (ex: `ns1.z-ana.com`) et non `ns1.{DOMAIN}`. Sinon les domaines heberges auront des problemes de delegation.
|
||||||
|
|
||||||
|
### Domaines .ci chez MTN
|
||||||
|
- Les glue records vers le meme domaine ne fonctionnent pas dans l'interface
|
||||||
|
- Solution : pointer les NS vers le domaine principal du serveur
|
||||||
|
- Le support est lent — prevoir des delais
|
||||||
|
|
||||||
|
### Dovecot SNI
|
||||||
|
Le SNI doit etre configure dans `dovecot.conf` principal, pas dans `conf.d/10-ssl.conf`. ISPConfig ecrase les fichiers `conf.d`.
|
||||||
|
|
||||||
|
### Redis conflit de ports
|
||||||
|
Si vous installez un service Docker avec Redis en `network_mode: host`, utiliser un port different (ex: 6380) pour eviter le conflit avec le Redis systeme (6379).
|
||||||
|
|
||||||
|
### Guacamole et Tomcat 10
|
||||||
|
Guacamole 1.5.5 n'est pas compatible avec Tomcat 10 (Ubuntu 24.04). Utiliser Docker a la place.
|
||||||
|
|
||||||
|
### wg-easy PASSWORD vs PASSWORD_HASH
|
||||||
|
Les versions recentes de wg-easy exigent un hash bcrypt (`PASSWORD_HASH`) au lieu du mot de passe en clair (`PASSWORD`).
|
||||||
|
|
||||||
|
### MAILER_DSN Symfony
|
||||||
|
Pour envoyer des mails via Postfix local : `smtp://127.0.0.1:25?auto_tls=false`. Sans `auto_tls=false`, Symfony tente STARTTLS qui echoue localement.
|
||||||
|
|
||||||
|
### Permissions Symfony
|
||||||
|
Apres connexion SSH, executer `newgrp clientX` pour activer le groupe et acceder au dossier du projet.
|
||||||
|
|
||||||
|
### Certificat ISPConfig vs mail
|
||||||
|
Le certificat dans `ispserver.crt` est utilise pour le panel ISPConfig ET Dovecot/Postfix par defaut. Garder le certificat du domaine principal. Le SNI gere les certificats specifiques par domaine mail.
|
||||||
|
|
||||||
|
### Propagation DNS
|
||||||
|
- OVH : quasi instantanee
|
||||||
|
- MTN/Cloud4Africa (.ci) : peut prendre des heures
|
||||||
|
- Utiliser `dig @8.8.8.8 <domaine> A +short` pour verifier
|
||||||
|
|
||||||
|
## Ports utilises
|
||||||
|
|
||||||
|
| Port | Service | Protocole |
|
||||||
|
|------|---------|-----------|
|
||||||
|
| 22/50022 | SSH | TCP |
|
||||||
|
| 25 | SMTP | TCP |
|
||||||
|
| 53 | DNS | TCP+UDP |
|
||||||
|
| 80 | HTTP | TCP |
|
||||||
|
| 110 | POP3 | TCP |
|
||||||
|
| 143 | IMAP | TCP |
|
||||||
|
| 443 | HTTPS | TCP |
|
||||||
|
| 465 | SMTP SSL | TCP |
|
||||||
|
| 587 | SMTP submission | TCP |
|
||||||
|
| 993 | IMAP SSL | TCP |
|
||||||
|
| 995 | POP3 SSL | TCP |
|
||||||
|
| 2812 | Monit | TCP |
|
||||||
|
| 3000 | Gitea | TCP |
|
||||||
|
| 3100 | Grafana | TCP |
|
||||||
|
| 3101 | Loki | TCP |
|
||||||
|
| 3306 | MariaDB | TCP |
|
||||||
|
| 3478 | TURN UDP | UDP |
|
||||||
|
| 5349 | TURN TLS | TCP |
|
||||||
|
| 6379 | Redis systeme | TCP |
|
||||||
|
| 6380 | Redis LiveKit | TCP |
|
||||||
|
| 7880 | LiveKit signal | TCP |
|
||||||
|
| 7881 | LiveKit TCP | TCP |
|
||||||
|
| 7882 | LiveKit UDP | UDP |
|
||||||
|
| 8061 | Yacht | TCP |
|
||||||
|
| 8080 | ISPConfig | TCP |
|
||||||
|
| 8081 | ISPConfig apps | TCP |
|
||||||
|
| 8085 | Guacamole | TCP |
|
||||||
|
| 9050 | Portainer | TCP |
|
||||||
|
| 9080 | Promtail | TCP |
|
||||||
|
| 9090 | Prometheus | TCP |
|
||||||
|
| 10000 | Webmin | TCP |
|
||||||
|
| 51820 | Wireguard | UDP |
|
||||||
|
| 51821 | wg-easy interface | TCP |
|
||||||
|
| 1280 | Vaultwarden | TCP |
|
||||||
|
| 1281 | Heimdall | TCP |
|
||||||
|
|
||||||
|
## Architecture des sous-domaines
|
||||||
|
|
||||||
|
| Sous-domaine | Service | Proxy vers |
|
||||||
|
|-------------|---------|-----------|
|
||||||
|
| mail.* | Roundcube | localhost:8080/webmail/ |
|
||||||
|
| rspamd.* | Rspamd | localhost:8081/rspamd/ |
|
||||||
|
| autoconfig.* | Config mail auto | Fichiers XML directs |
|
||||||
|
| autodiscover.* | Config Outlook | Fichiers XML directs |
|
||||||
|
| webmin.* | Webmin | localhost:10000 |
|
||||||
|
| portainer.* | Portainer | localhost:9050 |
|
||||||
|
| yacht.* | Yacht | localhost:8061 |
|
||||||
|
| grafana.* | Grafana | localhost:3100 |
|
||||||
|
| wireguard.* | Wireguard | localhost:51821 |
|
||||||
|
| vaultwarden.* | Vaultwarden | localhost:1280 |
|
||||||
|
| heimdall.* | Heimdall | localhost:1281 (HTTPS) |
|
||||||
|
| guacamole.* | Guacamole | localhost:8085/guacamole |
|
||||||
|
| dbmanage.* | phpMyAdmin | Direct (Alias) |
|
||||||
|
| wordpress.* | Wordpress | Direct |
|
||||||
|
| nextcloud.* | Nextcloud | Direct |
|
||||||
|
| gitea.* | Gitea | localhost:3000 |
|
||||||
52
README.md
Normal file
52
README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Guide d'Installation VPS Complet
|
||||||
|
|
||||||
|
Guide pas-a-pas pour configurer un serveur VPS de zero avec panel de gestion, mail, Docker, monitoring et services.
|
||||||
|
|
||||||
|
## Variables a personnaliser
|
||||||
|
|
||||||
|
Avant de commencer, notez vos valeurs :
|
||||||
|
|
||||||
|
| Variable | Exemple | Votre valeur |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `<IP>` | 62.169.29.111 | |
|
||||||
|
| `<IPV6>` | 2a02:c207:2316:3066::1 | |
|
||||||
|
| `<DOMAINE>` | z-ana.com | |
|
||||||
|
| `<HOSTNAME>` | mail | |
|
||||||
|
| `<FQDN>` | mail.z-ana.com | |
|
||||||
|
| `<USER>` | scriptshadow | |
|
||||||
|
| `<SSH_PORT>` | 50022 | |
|
||||||
|
| `<EMAIL>` | admin@z-ana.com | |
|
||||||
|
|
||||||
|
## Sommaire
|
||||||
|
|
||||||
|
1. [Prerequis et choix](01-prerequis.md) - Hebergeur, registrar, OS
|
||||||
|
2. [Configuration de base](02-config-base.md) - Hostname, apt, locale, swap, MOTD
|
||||||
|
3. [ISPConfig](03-ispconfig.md) - Installation et configuration
|
||||||
|
4. [HestiaCP (Alternative)](03-bis-hestiacp.md) - Alternative a ISPConfig
|
||||||
|
5. [DNS](04-dns.md) - Templates, zones, glue records
|
||||||
|
6. [Webmin](05-webmin.md) - Administration systeme
|
||||||
|
7. [Monitoring](06-monitoring.md) - Munin, Monit, Grafana, Prometheus, Loki
|
||||||
|
8. [Mail](07-mail.md) - Rspamd, DKIM, DMARC, Roundcube, autoconfig
|
||||||
|
9. [SNI Mail](08-sni-mail.md) - Certificats multi-domaines
|
||||||
|
10. [Docker](09-docker.md) - Docker, Swarm, Portainer, Yacht
|
||||||
|
11. [Services Docker](10-services-docker.md) - Wireguard, Vaultwarden, Heimdall, Guacamole
|
||||||
|
12. [Applications](11-applications.md) - Wordpress, Nextcloud, Gitea
|
||||||
|
13. [Backup](12-backup.md) - Script rsync quotidien
|
||||||
|
14. [Securite](13-securite.md) - Certificats LE, phpMyAdmin, Fail2ban, DNSSEC
|
||||||
|
15. [Deploiement Symfony](14-deploiement-symfony.md) - Projet Symfony sur Apache
|
||||||
|
16. [LiveKit](15-livekit.md) - Teleconsultation video
|
||||||
|
17. [Notes et pieges](16-notes-pieges.md) - Lecons apprises
|
||||||
|
|
||||||
|
## Temps estime
|
||||||
|
|
||||||
|
- Configuration de base + ISPConfig : ~2h
|
||||||
|
- Mail complet : ~1h
|
||||||
|
- Docker + services : ~2h
|
||||||
|
- Monitoring : ~1h
|
||||||
|
- Total : ~6-8h pour un serveur complet
|
||||||
|
|
||||||
|
## Prerequis
|
||||||
|
|
||||||
|
- VPS Ubuntu 24.04 (Contabo ou equivalent)
|
||||||
|
- Domaine chez OVH (recommande) ou autre registrar
|
||||||
|
- Acces root au VPS
|
||||||
Reference in New Issue
Block a user