Restructuration du dépot

This commit is contained in:
mablr
2020-02-20 15:41:25 +01:00
parent ae0727b26e
commit ef9c5c3c83
16 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
# Présentation de la zone CTF
Vous trouverez ici toute la documentation relative au fonctionnement et à la configuration de la zone CTF. Cela comprend le reverse proxy CTF, l'environnement Web, l'environnement Système et CTFd.

View File

@@ -0,0 +1,250 @@
# Environnement Système CTF
Il faut impérativement une VM pour que Docker soit fluide
## Installation de Docker
```
apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-get update
apt-get install docker-ce
```
## Mise en place de l'environement système
La restauration des challenges actuels est expliquée à la fin.
### Procédure pour la création d'un nouveau challenge
Placer les Dockerfile est la source du challenge dans /home/systeme/SystemeChall/<challenge>
Le Dockerfile doit idéalement être fait à partir de debmod, créer un utilisateur systemeXX et contenir
```
USER systemeXX
WORKDIR /home/systemeXX
```
### Installation et création de l'utilisateur administrateur non root
```
apt-get install python3-pip
pip3 install --upgrade docker
pip3 install --upgrade argcomplete
adduser systeme
adduser systeme sudo
adduser systeme docker
su systeme
```
#### /usr/local/bin/dockersh
```
#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK
import os
os.environ['TERM'] = 'xterm'
import argparse
from configparser import ConfigParser, ExtendedInterpolation
import docker
import random
import string
import sys
from pwd import getpwnam
prog = 'dockersh'
config_file = "/etc/dockertempsh.ini"
import os
user = os.getlogin()
host = os.uname()[1]
cli = docker.APIClient()
def containers(image_filter='', container_filter='', sort_by='Created', all=True):
cs = cli.containers(all=all, filters={'label': "user="+user})
cs.sort(key=lambda c: c[sort_by])
cs = [c for c in cs if str(c['Image']+':latest').startswith(image_filter)]
cs = [c for c in cs if c['Names'][0][1:].startswith(container_filter)]
return cs
def random_string(length):
def random_char():
return random.choice(string.ascii_uppercase + string.digits)
return ''.join(random_char() for _ in range(length))
def strip(s, suffix=''):
for c in ['/', ':', '.', ' ']:
s = s.replace(c, '')
if s.endswith(suffix):
s = s[:len(s)-len(suffix)]
return s
def image_split(s):
sp = s.split(':')
if len(sp) == 1:
return sp[0], 'latest'
else:
return sp[0], sp[1]
#Chargement du fichier de configuration
config_envir = {
"USER": user,
"HOME": os.environ['HOME']
}
cfg = ConfigParser(config_envir, interpolation=ExtendedInterpolation())
cfg.read(config_file)
ini = cfg[user] if cfg.has_section(user) else cfg['DEFAULT']
#Spécification particulière
post_cmd = ""
name = ""
image = ""
home = ini['homedir']
suffix = ini['suffix']
#Vérification des spécifications
name_passed = (name != "")
image_passed = (image != "")
#Génération du container temporaire
#Création du nom random
if not image_passed:
image = ini['image']
image_base, image_tag = image_split(image)
image = image_base + ':' + image_tag
name = strip(image) + '_tmp' + random_string(4)
full_name = name + suffix
#Création
if len(containers(container_filter=name)) == 0:
volumes = []
if "volumes" in ini:
volumes = volumes + ini["volumes"].split(",")
volumes = [v.split(":") for v in volumes]
binds = {v[0].strip():{"bind":v[1].strip(),"mode":v[2].strip()} for v in volumes}
volumes = [v[1] for v in volumes]
host_config = cli.create_host_config(
binds=binds,
restart_policy={'Name' : 'unless-stopped'},
cap_add='SYS_PTRACE', #GDB
security_opt=['seccomp:unconfined']) #GDB
userpwd = getpwnam(user)
cli.create_container(image,
stdin_open=True,
tty=True,
name=full_name,
hostname='systemekrkn',
labels={'group': prog, 'user': user},
volumes=volumes,
working_dir=home,
environment={
"HOST_USER_ID": userpwd.pw_uid,
"HOST_USER_GID": userpwd.pw_gid,
"HOST_USER_NAME": user
},
host_config=host_config
)
#Lancement et attach
cli.start(full_name)
os.popen('docker exec '+full_name + ' echo Initialization finished.').read().split(":")[-1]
user_bash = "/bin/bash" #Path par défaut
cmd = post_cmd if post_cmd else user_bash #Donne la posibilité de spécifié le path dans le .ini
os.system('docker exec -u '+user+" " + "-it" +' '+ full_name + ' ' + cmd)
#Arrêt à la fin
cli.remove_container(full_name, v=True, force=True)
cli.close()
```
```
chmod +x /usr/local/bin/dockersh
```
### Création d'une image docker de base
#### Dockerfile
```
FROM debian:latest
RUN dpkg --add-architecture i386
RUN apt update && apt install -y gdb elfutils binutils python-minimal perl zip pwgen nano gcc
```
Création de l'image de base debmod
```
docker built -t debmod .
```
### Script pour la création des images Docker à partir des Dockerfile
Usage : ./createImg <systemeXX> <dockerfile>
```
#!/bin/bash
if [ "$#" -lt "2" ]
then
echo "Usage : ./createImg <systemeXX> <dockerfile>"
else
if [ -f "$2" ];then
docker build -t $1 $2
else
echo "Usage : ./createImg <systemeXX> <dockerfile>"
exit 0
fi
fi
```
### Script pour la création d'un utilisateur et son ajout à DockerTemp
Usage ./deployEnv <systemeXX>
```
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "Usage : ./deployEnv <systemeXX>"
else
if grep -q "$1" /etc/dockertempsh.ini
then
echo "Utilisateur déjà crée dans /etc/dockertempsh.ini ECHEC"
exit 1
else
useradd -m -p $1 -s /usr/local/bin/dockersh $1
echo "$1:$1" | chpasswd
adduser $1 docker
echo -e "[$1]
image = $1
suffix = _$1
homedir = /home/$1
volumes = /globalinfo:/globalinfo:ro" >> /etc/dockertempsh.ini
fi
fi
```
Une fois le programme mis au bon endroit et les deux scripts exécutés avec succès tout est prêt. Pour personnaliser le message d'accueil, il faut modifier le /etc/motd de la VM et non celui des containers Docker.
## Restauration des challenges déjà existants
Voilà la correspondance utilisateur / challenge
```
systeme1 -> easyshell
systeme2 -> pwn_my_home
systeme3 -> overflow
systeme4 -> shellcode1
systeme5 -> shellcode3
systeme6 -> shellcode3
systeme7 -> history
```
Extraire l'archive des challenge dans /home/systeme/SystemeChall/
### Script qui utilisera les deux autres pour tout déployer
```
#!/bin/bash
declare -a path=(easyshell pwn_my_home overflow shellcode1 shellcode2 shellcode3 history)
for i in `seq 0 6`;
do
./createImg.sh systeme$(($i+1)) "/home/systeme/SystemeChall/${path[${i}]}"
./deployEnv.sh systeme$(($i+1))
done
```

View File

@@ -0,0 +1,63 @@
# Environnement Web CTF
Il faut impérativement une VM pour que Docker soit fluide
## Installation de Docker et Docker-Compose
```
apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-get update
apt-get install docker-ce
curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```
## Mise en place de l'environnement Web
L'archive contient les sources docker des 11 environnements ainsi qu'un fichier docker-compose qui mettra en place tous les environnements.
```
Easy HTML : Port 8081
Fais moi un cookie : Port 8082
Header manquant : Port 8083
Easy admin : Port 8084
Easy LFI & Harder LFI : Port 8085
SQL Injection : Port 8086
strcmp : Port 8087
Easy NoSQL & Standard & Harder NoSQL : Port 8088
Blind SQL : Port 8089
XML : Port 8090
Vole mon cookie si tu peux : Port 8091
```
Un reverse proxy en local redirigera vers le bon port en fonction du numéro du challenge.
### Création d'un utilisateur non-root
```
adduser WebChalls --force-badname
adduser WebChalls sudo
su WebChalls
```
Pour la mise en place il suffit de placer le contenu de l'archive dans /home/WebChalls/WebChalls
### Création d'un service pour le démarrage automatique
#### /etc/systemd/system/webchall.service
```
[Unit]
Description=WebChall
Requires=webchall.service
After=webchall.service
[Service]
Restart=always
ExecStart=/usr/local/bin/docker-compose -f /home/WebChalls/WebChalls/docker-compose.yml up
ExecStop=/usr/local/bin/docker-compose -f /home/WebChalls/WebChalls/docker-compose.yml down
[Install]
WantedBy=multi-user.target
```
Il suffit maintenant de l'activer
```
systemctl enable webchall
systemctl start webchall
```

View File

@@ -0,0 +1,41 @@
# Reverse proxy NGINX sur le réseau CTF
## Spécification du container
Ce service n'est pas redondé car non vital, son IP est 10.0.2.5 sur le réseau CTF.
## Objectif
Il doit rediriger les requêtes arrivant de HAProxy vers le bon container en fonction de l'hostname. Pour cela nous allons utiliser des serveurs web HTTP Nginx.
## Installation de nginx et persistance,
```
apt-get update
apt-get install -y nginx
systemctl enable nginx.service
```
## Mise en place d'un serveur faisant office de reverse proxy
On ajoute un serveur web dans /etc/nginx/sites-available avec un nom décrivant bien le service derrière ce serveur.
Voilà la template du serveur web,
```
server {
listen 80;
server_name address.fr;
location / {
proxy_pass http://ip_reseau_ctf/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
On active ce serveur web,
```
ln -s /etc/nginx/sites-available/<nom_serveur> /etc/nginx/sites-enabled
systemctl restart nginx
```
La procédure est tout le temps la méthode générale pour ajouter un serveur à Nginx. Elle est décrite ici. Cependant, dans certians cas, il peut être nécessaire d'enlever un ou plusieurs proxy\_set\_header dans la configuration du serveur Nginx.

View File

@@ -0,0 +1,2 @@
# Présentation de la zone KRKN
Vous trouverez ici toute la documentation relative au fonctionnement et à la configuration de la zone KRKN. Cela comprend tous les containers des services publics (Nextcloud, Gitea...) et les services internes nécessaires au fonctionnement des services publics comme l'annuaire LDAP.

View File

@@ -0,0 +1,570 @@
# LDAP
Nous allons ici mettre en place le serveur LDAP qui sera répliqué sur les deux nodes. Tout les services utiliseront LDAP pour l'authentification des utilisateurs.
A noté que pour des questions pratique nous n'allons pas utilisé Fusion Directory, il faudra donc créer un schéma pour chaque service et modifier les utilisateur avec ldapadd et ldapmodify.
Pour la sécurisation de LDAP nous allons utiliser LDAP avec STARTTLS.
## Installation slapd
On commence par installer le serveur ldap.
```
apt-get update
apt-get install slapd ldap-utils
```
## Configuration de sladp
On commence par reconfigurer le packet
```
dpkg-reconfigure slapd
```
Il faut répondre de la manière suivante
```
Omit OpenLDAP server configuration? No
DNS domain name: krhacken.org
Organization name? Kr[HACK]en
Administrator password: PASSWORD
Confirm password: PASSWORD
Database backend to use: MDB
Do you want the database to be removed when slapd is purged? YES
Allow LDAPv2 protocol? No
```
### /etc/ldap/ldap.conf
```
BASE dc=krhacken,dc=org
URI ldap://IP.LDAP/
```
## Centralisation des fichiers de configuration
Nous allons créer un répertoire /root/ldap/conf qui va centraliser tous nos fichiers de configuration
```
mkdir -p /root/ldap/conf/
```
## Mise en place SSL
```
apt-get install gnutls-bin ssl-cert
mkdir /etc/ssl/templates
```
### /etc/ssl/templates/ca_server.conf
```
cn = LDAP Server CA
ca
cert_signing_key
```
### /etc/ssl/templates/ldap_server.conf
```
organization = "krhacken"
cn = ldap.krhacken.org
tls_www_server
encryption_key
signing_key
expiration_days = 3652
```
### CA clé et certificat
```
certtool -p --outfile /etc/ssl/private/ca_server.key
certtool -s --load-privkey /etc/ssl/private/ca_server.key --template /etc/ssl/templates/ca_server.conf --outfile /etc/ssl/certs/ca_server.pem
```
### LDAP clé et certificat
```
certtool -p --sec-param high --outfile /etc/ssl/private/ldap_server.key
certtool -c --load-privkey /etc/ssl/private/ldap_server.key --load-ca-certificate /etc/ssl/certs/ca_server.pem --load-ca-privkey /etc/ssl/private/ca_server.key --template /etc/ssl/templates/ldap_server.conf --outfile /etc/ssl/certs/ldap_server.pem
```
Nous avons maintenant créer tout les certificats nécessaire pour pouvoir chiffrer LDAP avec STARTTLS.
## Chiffrement par STARTTLS
Nous avons choisi STARTTLS au lieu de LDAPS car il est plus sûr pour notre usage.
### Gestion des permissions
```
usermod -aG ssl-cert openldap
chown :ssl-cert /etc/ssl/private/ldap_server.key
chmod 640 /etc/ssl/private/ldap_server.key
```
## Ajout des certificat à OpenLDAP
### /root/ldap/conf/addcerts.ldif
```
dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/ca_server.pem
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap_server.pem
dn: cn=config
changetype: modify
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap_server.key
```
Application des modification et redémarrage de slapd
```
ldapmodify -H ldapi:// -Y EXTERNAL -f addcerts.ldif
service slapd force-reload
```
## Sur le serveur
```
cp /etc/ssl/certs/ca_server.pem /etc/ldap/ca_certs.pem
```
Il faut ensuite ajuster la configuration en modifiant la ligne suivante
### /etc/ldap/ldap.conf
```
...
TLS_CACERT /etc/ldap/ca_certs.pem
...
```
### Vérification
La commande
```
ldapsearch -xLLL -H ldap://localhost -D cn=viewer,ou=system,dc=krhacken,dc=org -w passview -b "dc=krhacken,dc=org"
```
doit retourner une erreur, si on ajout -ZZ à la fin ça doit fonctionner
## Configuration des futurs client LDAP
Sur tout les futurs client LDAP il faudra activer la connexion SSL.
Il faut commencer par copier le certificat de la CA (ca_server.pem)
```
cat ca_server.pem | tee -a /etc/ldap/ca_certs.pem
```
Il faut ensuite modifier la configuration en modifiant la ligne suivante
### /etc/ldap/ldap.conf
```
...
TLS_CACERT /etc/ldap/ca_certs.pem
...
```
## Droits d'accès pour la configuration
### /root/ldap/conf/acces-conf-admin.ldif
```
dn: olcDatabase={0}config,cn=config
changeType: modify
add: olcAccess
olcAccess: to * by dn.exact=cn=admin,dc=krhacken,dc=org manage by * break
```
Puis on applique le .ldif
```
ldapmodify -Y external -H ldapi:/// -f acces-conf-admin.ldif
```
# Les overlays
Les overlays sont des fonctionnalités supplémentaires. Si dessous l'ensemble des overlays que nous allons utiliser ainsi que leur utilité.
## MemberOf
Loverlay memberof permet de savoir dans quels groupes se trouve un utilisateur en une seule requête au lieu de deux.
### /root/ldap/conf/memberof_act.ldif
```
dn: cn=module,cn=config
cn:module
objectclass: olcModuleList
objectclass: top
olcmoduleload: memberof.la
olcmodulepath: /usr/lib/ldap
```
### /root/ldap/conf/memberof_conf.ldif
```
dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: olcConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
```
On applique les modifications
```
ldapadd -Y EXTERNAL -H ldapi:/// -f memberof_act.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f memberof_conf.ldif
```
Vérification
```
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcModuleList"
```
## refint
L'overlay permet de sassurer de la cohérence de lannuaire lors de suppression dentrées.
### /root/ldap/conf/refint_act.ldif
```
dn: cn=module,cn=config
cn: module
objectclass: olcModuleList
objectclass: top
olcmoduleload: refint.la
olcmodulepath: /usr/lib/ldap
```
### /root/ldap/conf/refint_conf.ldif
```
dn: olcOverlay=refint,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: refint
olcRefintAttribute: memberof member manager owner
olcRefintNothing: cn=admin,dc=krhacken,dc=org
```
On applique les modifications
```
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f refint_act.ldif
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f refint_conf.ldif
```
Vérifications
```
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcModuleList"
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcRefintConfig"
```
## Audit Log
Cet overlay sert à auditer chaque modification au sein de lannuaire. Dans notre cas, cela sera inscrit dans le fichier : /var/log/openldap/audit.ldif
### /root/ldap/conf/auditlog_act.ldif
```
dn: cn=module,cn=config
cn: module
objectclass: olcModuleList
objectclass: top
olcModuleLoad: auditlog.la
olcmodulepath: /usr/lib/ldap
```
### /root/ldap/conf/auditlog_conf.ldif
```
dn: olcOverlay=auditlog,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcAuditLogConfig
olcOverlay: auditlog
olcAuditlogFile: /var/log/openldap/auditlog.ldif
```
On applique les modifications
```
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f auditlog_act.ldif
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f auditlog_conf.ldif
```
On créer le fichier
```
mkdir /var/log/openldap
chmod 755 /var/log/openldap
chown openldap:openldap /var/log/openldap
touch /var/log/openldap/auditlog.ldif
chmod 755 /var/log/openldap/auditlog.ldif
chown openldap:openldap /var/log/openldap/auditlog.ldif
```
Vérifications
```
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcModuleList"
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcAuditLogConfig"
```
## Unique
Cet overlay permet de nous assurer lunicité des attributs que lon spécifie.
### /root/ldap/conf/unique_act.ldif
```
dn: cn=module,cn=config
cn: module
objectclass: olcModuleList
objectclass: top
olcModuleLoad: unique.la
olcmodulepath: /usr/lib/ldap
```
### /root/ldap/conf/unique_conf.ldif
```
dn: olcOverlay=unique,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcUniqueConfig
olcOverlay: unique
olcUniqueUri: ldap:///ou=people,dc=krhacken,dc=org?uid?sub
olcUniqueUri: ldap:///ou=people,dc=krhacken,dc=org?mail?sub
olcUniqueUri: ldap:///ou=people,dc=krhacken,dc=org?uidNumber?sub
olcUniqueUri: ldap:///ou=groups,dc=krhacken,dc=org?cn?sub
```
Nous demandons ici à ce que les attributs UI, mail et uidNumber dans lou people soient uniques. Et que lattribut cn dans lou groups soit lui aussi unique.
On applique les modifications,
```
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f unique_act.ldif
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f unique_conf.ldif
```
Vérifications,
```
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcModuleList"
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcUniqueConfig"
```
## Ppolicy
Cet overlay va nous permettre de spécifier une politique de mot de passe.
On va ajouter son schéma dans lannuaire
```
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif
```
Dans la branche cn=schema, on doit voir le schéma ppolicy,
```
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=schema,cn=config" cn
```
### /root/ldap/conf/ppolicy_act.ldif
```
dn: cn=module,cn=config
cn: module
objectclass: olcModuleList
objectclass: top
olcModuleLoad: ppolicy.la
olcmodulepath: /usr/lib/ldap
```
### /root/ldap/conf/ppolicy_conf.ldif
```
dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcPpolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=ppolicy,dc=krhacken,dc=org
olcPPolicyHashCleartext: TRUE
olcPPolicyUseLockout: FALSE
```
Explication,
- olcPPolicyDefault : Indique le DN de configuration utilisé
- olcPPolicyHashCleartext : Indique si les mots de passe doivent être cryptés.
On applique les modifications,
```
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f ppolicy_act.ldif
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f ppolicy_conf.ldif
```
On va maintenant créer la politique par défaut.
### /root/ldap/conf/ppolicy_def.ldif
```
dn: cn=ppolicy,dc=krhacken,dc=org
objectClass: top
objectClass: device
objectClass: pwdPolicy
cn: ppolicy
pwdAllowUserChange: TRUE
pwdAttribute: userPassword
pwdCheckQuality: 1
pwdExpireWarning: 0
pwdFailureCountInterval: 30
pwdGraceAuthNLimit: 5
pwdInHistory: 5
pwdLockout: TRUE
pwdLockoutDuration: 60
pwdMaxAge: 0
pwdMaxFailure: 5
pwdMinAge: 0
pwdMinLength: 5
pwdMustChange: FALSE
pwdSafeModify: FALSE
```
La signification des attributs est :
- pwdAllowUserChange : indique si lutilisateur peut changer son mot de passe.
- pwdCheckQuality : indique si OpenLDAP renvoie une erreur si le mot de passe nest pas conforme
- pwdExpireWarning : avertissement dexpiration.
- pwdFailureCountInterval : Intervalle de temps entre deux tentatives infructueuses pour quelles soient considérées comme « à la suite ».
- pwdGraceAuthNLimit : période de grâce suite à lexpiration du mot de passe.
- pwdInHistory : nombre de mots de passe dans lhistorique.
- pwdLockout : indique si on bloque le compte au bout de X échecs.
- pwdLockoutDuration : durée du blocage du compte (en secondes).
- pwdMaxAge : age maximal du mot de passe (en secondes).
- pwdMaxFailure : nombre déchecs de saisie du mot de passe maximal (avant blocage).
- pwdMinAge : age minimal du mot de passe (en secondes).
- pwdMinLength : longueur minimale du mot de passe.
- pwdMustChange : indique si lutilisateur doit changer son mot de passe.
- pwdSafeModify : indique si il faut envoyer lancien mot de passe avec le nouveau pour modification.
On applique les modifications,
```
ldapadd -H ldap://localhost -D cn=admin,dc=krhacken,dc=org -y /root/pwdldap -f ppolicy_def.ldif
```
Vérifications
```
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=schema,cn=config" cn
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "Objectclass=olcPpolicyConfig" -LLL
ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "dc=krhacken,dc=org" "Objectclass=pwdPolicy"
```
## Mise en place des OU
Les OUs sont des conteneurs qui permettent de ranger les données dans lannuaire, de les hiérarchiser.
### /root/ldap/conf/OU.ldif
```
dn: ou=people,dc=krhacken,dc=org
ou: people
objectClass: organizationalUnit
dn: ou=group,dc=krhacken,dc=org
ou: group
objectClass: organizationalUnit
dn: ou=system,dc=krhacken,dc=org
ou: system
objectClass: organizationalUnit
dn: ou=krhacken,ou=people,dc=krhacken,dc=org
ou: krhacken
objectClass: organizationalUnit
dn: ou=client,ou=people,dc=krhacken,dc=org
ou: client
objectClass: organizationalUnit
dn: ou=sysgroup,ou=group,dc=krhacken,dc=org
ou: sysgroup
objectClass: organizationalUnit
dn: ou=workgroup,ou=group,dc=krhacken,dc=org
ou: workgroup
objectClass: organizationalUnit
```
On rajoute les OU au ldap
```
ldapadd -cxWD cn=admin,dc=krhacken,dc=org -y /root/pwdldap -f OU.ldif
```
Explication rapide
- krhacken contenant tout les utilisateurs krhacken
- people contient tout les utilisateurs (krhacken ou non)
## Utilisateurs
### /root/ldap/conf/User_PSEUDO.ldif
```
dn: uid=PSEUDO,ou=krhacken,ou=people,dc=krhacken,dc=org
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: niko
sn: niko
givenName: Nicolas
cn: Nicolas
displayName: Nicolas
userPassword: password
mail: mail@spam.com
title: Admin
initials: N
```
On ajoute l'utilisateur
```
ldapadd -cxWD cn=admin,dc=krhacken,dc=org -y /root/pwdldap -f User_PSEUDO.ldif
```
Commande pour la connexion à un utilisateur
```
ldapsearch -xLLLH ldap://localhost -D uid=PSEUDO,ou=krhacken,ou=people,dc=krhacken,dc=org -W -b "dc=krhacken,dc=org" "uid=PSEUDO"
```
## Groupes
Il existe deux types de groupes : les posixgroup et les groupofnames.
Les posixgroup sont similaires au groupes Unix, et les groupofnames ressemblent plus à des groupes AD.
Pour faire simple, lavantage des groupofnames est quavec un filtre sur un utilisateur, on peut connaitre ses groupes (avec loverlay memberof). Chose impossible avec les posixgroups.
### /root/ldap/conf/Group.ldif
```
dn: cn=cloud,ou=sysgroup,ou=group,dc=krhacken,dc=org
cn: cloud
description: Cloud
objectClass: groupOfNames
member: cn=admin,dc=krhacken,dc=org
dn: cn=krhacken,ou=workgroup,ou=group,dc=krhacken,dc=org
cn: krhacken
description: krhacken
objectClass: groupOfNames
member: cn=admin,dc=krhacken,dc=org
```
On ajoute les
```
ldapadd -cxWD cn=admin,dc=krhacken,dc=org -y /root/pwdldap -f Group.ldif
```
On peu tester memberof pour voir si admin est bien dans les bon groupes
```
ldapsearch -xLLLH ldap://localhost -D cn=admin,dc=krhacken,dc=org -y /root/pwdldap -b "dc=krhacken,dc=org" "cn=admin" memberof
```
Pour rajouter un utilisateur dans un groupe avec un fichier ldif (addusertogroup.ldif)
```
dn: cn=cloud,ou=sysgroup,ou=group,dc=krhacken,dc=org
changetype: modify
add: member
member: uid=niko,ou=krhacken,ou=people,dc=krhacken,dc=org
```
On ajoute l'utilisateur avec
```
ldapmodify -cxWD cn=admin,dc=krhacken,dc=org -y /root/pwdldap -f addusertogroup.ldif
```
# Sécurisation de l'annuaire
## Comptes avec permissions réduite
Nous allons créer deux compte systèmes.
- Un viewer qui aura uniquement les droits en lecture de l'arbre
- Un Writer qui lui aura les droits en écriture
### /root/ldap/conf/viewer.ldif
```
dn: cn=viewer,ou=system,dc=krhacken,dc=org
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: viewer
description: LDAP viewer
userPassword: passview
```
### /root/ldap/conf/writer.ldif
```
dn: cn=writer,ou=system,dc=krhacken,dc=org
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: writer
description: LDAP Writer
userPassword: passwrite
```
Ajout des utilisateurs,
```
ldapadd -cxWD cn=admin,dc=krhacken,dc=org -y /root/pwdldap -f viewer.ldif
ldapadd -cxWD cn=admin,dc=krhacken,dc=org -y /root/pwdldap -f writer.ldif
```
On autorise la lecture de l'arbre uniquement au utilisateur authentifié en modifiant une ACL
### /root/ldap/conf/acl.ldif
```
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to attrs=userPassword by self write by anonymous auth by dn="cn=writer,ou=system,dc=krhacken,dc=org" write by dn="cn=viewer,ou=system,dc=krhacken,dc=org" read by dn="cn=admin,dc=krhacken,dc=org" write by * none
olcAccess: to dn.base="dc=krhacken,dc=org" by users read
olcAccess: to * by self write by dn="cn=admin,dc=krhacken,dc=org" write by * read by anonymous none
```
On modife l'ACL
```
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f acl.ldif
```
## Forcer SSL
Si c'est le cas on peut maintenant forcer la connexion SSL
### /root/ldap/conf/forcetls.ldif
```
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSecurity
olcSecurity: tls=1
```
Ajout des modifications et application
```
ldapmodify -H ldapi:// -Y EXTERNAL -f forcetls.ldif
systemctl restart slapd
```
Vérifions si TLS est obligatoire,
Cette commande doit retourner une erreur
```
ldapsearch -H ldap:// -x -b "dc=sessionkrkn,dc=fr" -LLL dn
```
et celle la doit aboutir
```
ldapsearch -H ldap:// -x -b "dc=example,dc=com" -LLL -Z dn
```
Voilà pour la mise en place de base du LDAP cependant il faut configuré chaque client pour se connecter au serveur avec STARTTLS.
NB : Il manque la réplication que nous mettrons en place plus tard.

1081
applicatif/zone_krkn/mail.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
# Présentation de la zone ROUTE
Vous trouverez ici toute la documentation relative au fonctionnement et à la configuration de la zone ROUTE. Cela comprend les deux HAProxy et les deux reverses proxy public nginx.

View File

@@ -0,0 +1,323 @@
# Gestion du flux post-firewall
## Présentation des containers
Deux containers Debian 10 identiques, un sur Alpha l'autre sur Bêta avec deux interfaces
- Sur Alpha le container HAProxy a comme IP 10.0.0.3/24 sur ROUTE (eth0) 10.0.1.3/24 sur CTF (eth1)
- Sur Beta le container HAProxy a comme IP 10.0.0.4/24 sur ROUTE 10.0.1.4/24 sur CTF
L'option Firewall PVE des interfaces est désactivée
## Objectifs et choix techniques
Trois objectifs pour la gestion du flux post-firewall
- Redondance du proxy/load balancer entre les deux nodes.
- Séparation des flux (reverse public et reverse ctf).
- Load balancing entre deux reverse proxy Nginx public (un sur chaque nodes).
- Connexion SSL entre l'utilisateur et le proxy.
- Vérification du certificat du client et de son CN si tentative de connexion au panel Proxmox (uniquement).
Voici les choix techniques faits afin de répondre à ces objectifs
- Pour le load balancing entre les deux reverse proxy Nginx, on utilisera HAProxy.Le lien sécurisé sera entre l'utilisateur de HAProxy qui soumettra ensuite des requêtes HTTP à un des reverse proxy Nginx.
- Pour la redondance du proxy entre les deux nodes, on utilisera keepalived et la technologie VRRP pour garantir la disponibilité du proxy via une ip virtuelle.
- Pour la vérification du certificat client - uniquement si le client veut se connecter au panel Proxmox- on fera une première frontend à la couche 4 (TCP) pour les connexions https qui rediregera les connexions vers le panel sur une frontend dédié et le reste vers une frontend par défaut.
- Pour les certificats SSL, nous allons utiliser Let's Encrypt avec un serveur Nginx local dédié à l'obtention des certificats et des scripts pour le dépoiement sur les deux containers HAProxy.
- La séparation des flux entre les deux reverse public et le reverse ctf ce fera au niveau de la seconde frontend par défaut tout comme le filtrage des requêtes par nom de domaine.
### Voilà un schéma résumé
![Topologie de la zone Route](schema_route.png)
## Création d'un canal d'échange par clé entre les deux containers
Afin de pouvoir faire des scp de manière automatique entre les deux containers, il faut mettre en place une connexion ssh par clé en root entre les deux containers.
Le procédé est le même, en voici les variantes,
- Sur Alpha le container HAProxy aura comme IP 10.0.0.3
- Sur Beta le container HAProxy aura comme IP 10.0.0.4
### /etc/ssh/sshd_config
Remplacer la ligne concernée par
```
PermitRootLogin yes
```
### Génération et échange de la clé
```
adduser hasync
ssh-keygen -o -a 100 -t ed25519 -f /root/.ssh/id_ed25519
Alpha : ssh-copy-id -i /root/.ssh/id_ed25519 root@10.0.0.4
Beta : ssh-copy-id -i /root/.ssh/id_ed25519 root@10.0.0.3
```
### /etc/ssh/sshd_config
Remplacer les lignes concernées par
```
PermitRootLogin without-password
PubkeyAuthentication yes
```
Il est maintenant possible de se connecter par clé entre les containers
## Installation et configuration de HAProxy sur chaque node
Le procédé est le même, en voici les variantes,
- Sur Alpha le container HAProxy aura comme IP 10.0.0.3
- Sur Beta le container HAProxy aura comme IP 10.0.0.4
### Installation
```
apt-get update
apt-get install -y haproxy hatop certbot nginx
systemctl enable haproxy
systemctl enable nginx
```
Pour la vérification du certificat du client, la méthode est dans la git. Il faut placer le ca.crt dans /home/hasync/pve.crt et ajouter le CN autorisé dans /home/hasync/allowed_cn.txt
### Configuration
Voilà une rapide explication de la configuration faite
- Une première frontend (all-web-in) de type TCP en écoute sur le port 443 qui vérifie si les requêtes tcp sont bien SSL et redirige tout vers la frontend principale via un proxy sauf les requêtes vers la panel Proxmox qui sont redirigées vers la frontend admin via un proxy.
- La frontend principale (user-web-in) de type http écoute sur le ports 80 et le proxy évoqué plus haut. Filtrage des requêtes ne respectant pas le nom de domaine et forçage du https sans www sinon rejet du packet. Redirection des requêtes Let's Encrypt vers un serveur Nginx local dédié aux certifications sinon séparation du flux avec d'un côté une backend s'occupant du load balancing entre les deux reverse proxy Nginx public et de l'autre une backend redirigeant vers le reverse proxy ctf à l'aide du nom de domaine.
#### /etc/haproxy/haproxy.cfg
```
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
tune.ssl.default-dh-param 2048
defaults
log global
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend all-web-in
mode tcp
bind *:443 interface eth0
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend is-admin if { req_ssl_sni -i pve.sessionkrkn.fr }
use_backend is-admin if { req_ssl_sni -i rspamd.sessionkrkn.fr }
default_backend is-user
frontend user-web-in
mode http
bind *:80 interface eth0
bind abns@haproxy-user accept-proxy ssl accept-proxy no-sslv3 crt /etc/ssl/letsencrypt interface eth0
acl host_letsencrypt path_beg /.well-known/acme-challenge
acl authorized_host hdr_end(host) sessionkrkn.fr
acl mail hdr_end(host) mail.sessionkrkn.fr
acl rspamd path_beg /rspamd/
acl ctf_host hdr_end(host) ctf.sessionkrkn.fr
acl ctf_host hdr_end(host) web.sessionkrkn.fr
acl host_www hdr_beg(host) -i www.
reqirep ^Host:\ www.(.*)$ Host:\ \1 if host_www !host_letsencrypt !mail
reqadd X-Forwarded-Proto:\ http
reqadd X-Forwarded-Proto:\ https
redirect scheme https code 301 if !{ ssl_fc } authorized_host !host_letsencrypt !mail
use_backend nginx-ctf if ctf_host !host_letsencrypt !mail
use_backend letsencrypt if host_letsencrypt !mail
use_backend reverse-nginx if authorized_host !ctf_host OR mail
default_backend drop-http
frontend admin-in
mode http
bind abns@haproxy-admin accept-proxy ssl no-sslv3 crt /etc/ssl/letsencrypt ca-file /home/hasync/pve.crt verify required interface eth0
acl is_auth ssl_c_s_dn(cn) -i -f /etc/haproxy/allowed_cn.txt
acl pve hdr_end(host) pve.sessionkrkn.fr
acl rspamd hdr_end(host) rspamd.sessionkrkn.fr
use_backend reverse-nginx if { ssl_fc_has_crt } is_auth rspamd
use_backend pve-interface if { ssl_fc_has_crt } is_auth pve
default_backend drop-http
backend is-admin
mode tcp
server admin-in abns@haproxy-admin send-proxy-v2
backend is-user
mode tcp
server admin-in abns@haproxy-user send-proxy-v2
backend letsencrypt
mode http
http-request set-header Host letsencrypt.requests
server letsencrypt 127.0.0.1:8164
backend pve-interface
mode http
balance roundrobin
server pve-alpha 10.0.0.1:8006 check ssl verify none
server pve-beta 10.0.0.2:8006 check ssl verify none
backend reverse-nginx
mode http
balance roundrobin
server reverse1 10.0.0.6:80 check
server reverse2 10.0.0.7:80 check
backend nginx-ctf
mode http
server nginx-ctf1 10.0.2.5:80 check
backend drop-http
mode http
http-request deny
```
Une fois HAProxy configuré, il faut configurer le serveur Nginx permettant l'obtention des certificats Let's Encrypt.
```
rm /etc/nginx/sites-enabled/default
rm /etc/nginx/sites-available/default
rm /etc/letsencrypt/live/README
mkdir -p /home/hasync/letsencrypt-requests
```
#### /etc/nginx/sites-availables/letsencrypt.conf
```
server {
listen 8164;
server_name letsencrypt.requests;
root /home/hasync/letsencrypt-requests;
}
```
### Démarrage des services
```
systemctl restart nginx.service
systemctl restart haproxy.service
```
### Obtention des premiers certificats et déploiement
```
certbot certonly --webroot -w /home/hasync/letsencrypt-requests/ -d sub.sessionkrkn.fr
```
Voici un script pour mettre en place les certificats Let's Encrypt au bon endroit qui s'occupe de propager les certificats sur l'autre container.
```
#!/bin/bash
rm -f /etc/letsencrypt/live/README
rm -rf /etc/ssl/letsencrypt/*
for domain in $(ls /etc/letsencrypt/live); do
cat /etc/letsencrypt/live/$domain/privkey.pem /etc/letsencrypt/live/$domain/fullchain.pem > /etc/ssl/letsencrypt/$domain.pem
done
scp -r /etc/ssl/letsencrypt/* root@10.0.0.3:/etc/ssl/letsencrypt
ssh root@10.0.0.3 'systemctl restart haproxy.service'
service haproxy restart
```
## Mise en place de la haute disponibilité du load balancer
Voilà la configuration que nous allons mettre en place,
- Sur Alpha le container HAProxy aura comme IP 10.0.0.3
- Sur Beta le container HAProxy aura comme IP 10.0.0.4
- L'IP virtuelle 10.0.0.5 sera attribuée en fonction de la disponibilité des load balancer
- La node Alpha sera le master et la node Beta sera le Slave
### Installation (commune au deux nodes)
```
apt-get install -y keepalived
systemctl enable keepalived.service
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
echo "net.ipv4.ip_nonlocal_bind=1" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
```
### Configuration sur Alpha
Comme décrite plus haut
#### /etc/keepalived/keepalived.conf
```
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
interface eth0
state MASTER
virtual_router_id 51
priority 101 # 101 on master, 100 on backup
virtual_ipaddress {
10.0.0.5 # the virtual IP
}
track_script {
chk_haproxy
}
}
```
### Configuration sur Beta
Comme décrite plus haut
#### /etc/keepalived/keepalived.conf
```
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
interface eth0
state MASTER
virtual_router_id 51
priority 100 # 101 on master, 100 on backup
virtual_ipaddress {
10.0.0.5 # the virtual IP
}
track_script {
chk_haproxy
}
}
```
#### Vérification
Le retour de cette commande doit montrer l'adresse IP 10.0.0.5 sur Alpha
```
ip a | grep -e inet.*eth0
```
## Renouvellement automatique des certificats
Pour une question de simplicité d'administration, les certificats Let's Encrypt se renouvelleront automatiquement grâce à une crontab. Le problème est qu'un seul des deux containers sera accessible depuis l'extérieur. Il faut donc copier les certificats via scp entre les deux containers.
### /home/hasync/renew.sh
Voilà un script d'automatisation à mettre sur les deux containers
```
#!/bin/bash
if [ "$(ip a | grep -c "10.0.0.5")" -ge 1 ]; then
certbot renew
rm -rf /etc/ssl/letsencrypt/*
for domain in $(ls /etc/letsencrypt/live); do
cat /etc/letsencrypt/live/$domain/privkey.pem /etc/letsencrypt/live/$domain/fullchain.pem > /etc/ssl/letsencrypt/$domain.pem
done
scp -r /etc/ssl/letsencrypt/* hasync@<ip_autre_ct>:/etc/ssl/letsencrypt
else
fi
```
Le script est stocké dans /home/hasync/renew.sh, voici la crontab à ajouter (crontab -e) sur les deux containers.
```
0 4 */15 * * /bin/sh /home/hasync/renew.sh >/dev/null 2>&1
```
C'est tout pour la configuration de HAProxy, la prochaine étape est la mise en place des trois reverses proxy.

View File

@@ -0,0 +1,83 @@
# Reverse proxy NGINX sur le réseau public
## Spécification des containers
Ce service est redondé car vital, son IP est 10.0.0.6 sur Alpha et 10.0.0.7 sur Beta.
## Objectif
Il doit rediriger les requêtes arrivant de HAProxy vers le bon container en fonction de l'hostname. Pour cela nous allons utiliser des serveurs web HTTP avec des proxy sur Nginx sans s'occuper de l'autre serveur web.
## Création d'un canal d'échange par clé entre les deux containers
Afin de pouvoir faire des scp de manière automatique entre les deux containers, il faut mettre en place une connexion ssh par clé en root entre les deux containers.
Le procédé est le même, en voici les variantes,
- Sur Alpha le container Nginx aura comme IP 10.0.0.6
- Sur Beta le container HAProxy aura comme IP 10.0.0.7
### /etc/ssh/sshd_config
Remplacer la ligne concernée par
```
PermitRootLogin yes
```
### Génération et échange de la clé
```
ssh-keygen -o -a 100 -t ed25519 -f /root/.ssh/id_ed25519
Alpha : ssh-copy-id -i /root/.ssh/id_ed25519 root@10.0.0.7
Beta : ssh-copy-id -i /root/.ssh/id_ed25519 root@10.0.0.6
```
### /etc/ssh/sshd_config
Remplacer les lignes concernées par
```
PermitRootLogin without-password
PubkeyAuthentication yes
```
Il est maintenant possible de se connecter par clé entre les containers
## Installation de Nginx sur les deux containers
```
apt-get update
apt-get install -y nginx
systemctl enable nginx.service
```
## Mise en place d'un serveur faisant office de reverse proxy
On ajoute un serveur web dans /etc/nginx/sites-available avec un nom décrivant bien le service derrière ce serveur.
Voilà la template du serveur web,
```
server {
listen 80;
server_name address.fr;
location / {
proxy_pass http://ip_reseau_public/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
Voilà un script permetant l'installation d'un serveur web présent dans /etc/nginx/sites-available. Il prend en entrée le nom du fichier du serveur à activer
```
if [ "$#" -eq "0" ]
then
echo "Bad Usage !"
else
if [ -f "/etc/nginx/sites-available/$1" ]
then
ln -s /etc/nginx/sites-available/$1 /etc/nginx/sites-enabled
systemctl restart nginx.service
scp /etc/nginx/sites-available/$1 root@<ip_autre_ct>:/etc/nginx/sites-available/
ssh root@<ip_autre_ct> "ln -s /etc/nginx/sites-available/$1 /etc/nginx/sites-enabled"
ssh root@<ip_autre_ct> 'systemctl restart nginx.service'
else
echo "Not exist !"
fi
fi
```
La procédure est tout le temps la méthode générale pour ajouter un serveur à Nginx. Elle est décrite ici. Cependant, dans certains cas, il peut être nécessaire d'enlever un ou plusieurs proxy\_set\_header dans la configuration du serveur Nginx.

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

View File

@@ -0,0 +1,41 @@
# Firewall
Au niveau du pare-feu nous allons utiliser OPNSense (fork de pfSense). Les deux nodes auront une VM avec OPNSense pour la Haute Disponibilité, l'IP publique (WAN) se déplacera entre les deux VM grâce à une IP virtuelle à CARP et à pfSense. Ca sera la même chose pour la gateway sur chaque interface.
## Les interfaces
- Interface d'entrée WAN (vmbr0)
- Interfaces de sortie ROUTE, KRKN, CTF, EXT (vmbr1 et vmbr2)
Toutes les autres interfaçe seront pour des liens purement locaux (Corosync, pfSync et VXLAN) donc géré avec un parefeu local type UFW et non par OPNSense.
## Configuration de la VM
- Guest OS : Other
- Bus Device : VirtIO Block
- Network device model : VirtIO (paravirtualized)
Il faudra ensuite ajouter au moins deux interfaces réseau.
## Installation du système
Il faut récupérer une image iso "DVD" sur le site d'OpnSense
Lors du démarrage il faut utiliser,
- login : installer
- pass : opnsense
Ne pas configurer de VLANs.
Une fois installation terminée, quitter le programme d'installation et redémarrer la VM.
## Premiers paramétrages d'OPNSense
### Interfaces
Une fois la VM rédémarrée pour la première fois, il faut faut assigner les interfaces, choix 1 dans le menu (assign interfaces).
Il faut configurer 2 interfaces pour commencer, une le WAN (vmbr0) et une pour le LAN (vmbr1). On ajoutera le reste plus tard.
# En attente du choix WAN...
### Règles (uniquement DNAT)
- DNAT 80,443 route:10.0.0.5
- DNAT 25,465,587,143,993,4190 krkn:10.0.1.10
- DNAT 2222 ctf:10.0.2.12
- DNAT 8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091 ctf:10.0.2.13

View File

@@ -0,0 +1,22 @@
# Différentes options pour la zone WAN
Pour l'accès au pare-feu du serveur, plusieurs options sont envisageables :
## En ipv4
NB: Il y aura un firewall de type OPNSense dans un VM sur chaque node. Il faut donc que l'ipv4 puisse être alloué à une VM.
### Une seule ipv4
Un firewall sur chaque serveur et une ipv4 publique (virtuelle) qui se déplacerait entre les deux firewall en fonction de leur disponibilité.
### Deux ipv4
Deux combinaisons possibles
- Une par serveur avec un firewall sur chaque serveur, le choix du serveur se ferait au niveau des entrées DNS.
- Une pour l'accès au firewall sur le même modèle que décrit pour une seule ipv4 et une autre pour un accès direct au serveur sans passer par le firewall principal.
## En ipv6
Un réseau uniquement ipv6 serait plus compliqué à mettre en place au niveau des accès depuis des clients ipv4. Cependant un bloc d'ipv6 en plus d'une ou deux ipv4 serait un plus.
## Conclusion
Le choix qui serait le plus fiable au niveau de la gestion de la disponibilité du serveur serait une ipv4 pour l'accès au firewall et une seconde ipv4 pour l'accès direct au serveur car plus sûr en cas de crash des deux VM. Avec un bloc d'ipv6 pour pouvoir rajouter progressivement le support de l'ipv6.