Sécurisation minimale d'un proxmox
Comme on peut le voir dès que l'on a installé le proxmox, les scans et les tentatives de connexion sur le SSH arrivent dans la minute.
Pour cela il est nécessaire de limiter sa surface d'attaque.
Compte utilisateur
SSH
Par défaut proxmox permet une connexion avec l'utilisateur root. Ce qui est à éviter.
Pour cela nous allons créer un utilisateur qui pourra élever ces privilèges grâce à sudo
| # adduser monusername
Adding user `monusername' ...
Adding new group `monusername' (1000) ...
Adding new user `monusername' (1000) with group `monusername' ...
Creating home directory `/home/monusername' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for monusername
Enter the new value, or press ENTER for the default
Full Name []: Monusername
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
|
Renseigner les valeurs attendues .
Maintenant que nous avons créé notre utilisateur, il faut le rejouter dans le groupe sudo.
Installer le package sudo si il n'est pas présent.
| # apt install sudo
# usermod -aG sudo monusername
|
Tester bien la connexion avec cet utilisateur en SSH avec son mot de passe.
Web
On peut également se servir de ce compte pour se connecter à la page web de Proxmox VE
Se rendre sur la page web : https://[@IP ou FQDN]:8006 et se connecter avec le compte root
Dans le menu Datacenter, Sélectionner le lien Groups afin de créer un groupe Admins.

Cliquer sur le bouton "Create".

Renseigner le nom du commentaire et éventuellement un commentaire associé. Cliquer sur le bouton Create pour valider.

Ensuite il faut attribuer des permissions d'administration au groupe créé précédemment.
Se rendre dans le menu Datacenter, sélectionner le lien Permissions.

Cliquer sur le bouton Add pour attribuer le rôle Administrator au group Admins.

Cliquer sur le bouton Add afin de valider.
Il ne nous reste plus qu'à créer l'utilisateur et l'associer au group Admins.
Pour cela se rendre dans le menu Datacenter, sélectionner le lien Users.

Cliquer sur le bouton Add.
Renseigner le nom de l'utilisateur créé précédemment avec les droits sudo et lui attribuer le groupe Admins.
Bien définir Linux PAM en méthode d'authentification.

Puis cliquer sur le bouton Add .
Avant de désactiver l'authentification par l'utilisateur root, tester de se connecter dans l'interface web avec l'utilisateur nouvellement ajouté.
En cas de succès on peut aller désactiver le compte dans l'authentification pam.
| $ sudo passwd -dl root
passwd: password expiry information changed.
|
Normalement on devrait plus pouvoir se connecter en SSH et en Web avec le compte root.
SSH
Modifier le port d'écoute par défaut du serveur SSH.
Tout se passe dans le fichier de configuration d'OpenSSH: /etc/ssh/sshd_config
| $ sudo vi /etc/ssh/sshd_config
# Renseigner la valeur Port
Port XXXXX
|
Mettre une valeur non prédictible dans les ports haut. (par ex: 44322)
Fail2Ban
Installation du package.
| $ sudo apt install fail2ban
|
Configuration
Création du fichier jail.local pour mettre nos jails en place.
| $ sudo vi /etc/fail2ban/jail.local
[proxmox]
enabled = true
port = https,http,8006
filter = proxmox
logpath = /var/log/daemon.log
maxretry = 3
bantime = 3600
|
Création du fichier de filtre qui permet de faire matcher la chaine avec le pattern souhaité.
| $ sudo vi /etc/fail2ban/filter.d/proxmox.conf
[Definition]
failregex = pvedaemon\[.*authentication failure; rhost=<HOST> user=.* msg=.*
ignoreregex =
|
On peut aussi tester la configuration afin de voir si notre regex est correctement appliquée.
Se connecter sur l'interface et tenter une authentification avec des mauvais identifiants.
| $ sudo fail2ban-regex /var/log/daemon.log /etc/fail2ban/filter.d/proxmox.conf
Running tests
=============
Use failregex filter file : proxmox, basedir: /etc/fail2ban
Use log file : /var/log/daemon.log
Use encoding : UTF-8
Results
=======
Failregex: 1 total
|- #) [# of hits] regular expression
| 1) [1] pvedaemon\[.*authentication failure; rhost=<HOST> user=.* msg=.*
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [207] {^LN-BEG}(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
`-
Lines: 207 lines, 0 ignored, 1 matched, 206 missed
[processed in 0.01 sec]
Missed line(s): too many to print. Use --print-all-missed to print all 206 lines
|
On peut constater que notre regex a matché une fois: Failregex: 1 total.
Il faut également que l'on surcharge le jail ssh du fait que l'on a modifié le port d'écoute par défaut .
| $ sudo vi /etc/fail2ban/jail.local
# Add this line for sshd jail
[sshd]
enabled = true
port = <SSH_PORT>
logpath = /var/log/auth.log
maxretry = 5
|
On peut également rajouter le jail recidive pour boquer des IPs qui insisteraient.
| $ sudo vi /etc/fail2ban/jail.local
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
filter = recidive
# find how many times it was banned today
findtime = 86400 ;
# if it banned 4 times
maxretry = 4
# ban this user for 1w
bantime = 1w
|
Il ne nous reste plus appliquer le service afin que les jail soient actifs.
| $ sudo systemctl restart fail2ban.service
|
Afin de contrôler le bon démarrage du service, regardons son status:
| $ sudo systemctl status fail2ban.service
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-01-10 08:25:00 UTC; 17s ago
Docs: man:fail2ban(1)
Process: 2360384 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS)
Main PID: 2360385 (fail2ban-server)
Tasks: 7 (limit: 38329)
Memory: 11.5M
CPU: 154ms
CGroup: /system.slice/fail2ban.service
└─2360385 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
Jan 10 08:25:00 node1 systemd[1]: Starting Fail2Ban Service...
Jan 10 08:25:00 node1 systemd[1]: Started Fail2Ban Service.
Jan 10 08:25:00 node1 fail2ban-server[2360385]: Server ready
|
Gestion
On peut interagir avec le serveur fail2ban en cli avec fail2ban-client.
| $ sudo fail2ban-client status
Status
|- Number of jail: 3
`- Jail list: proxmox, recidive, sshd
|
- Vérifier les adresses IP bloquées par jail:
| $ sudo fail2ban-client status proxmox
Status for the jail: proxmox
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/daemon.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
|
- Dé-bannir une IP de l'un des jails:
| $ sudo fail2ban-client set proxmox unbanip [IP Concerné]
|
- Bannir manuellement une IP sur l'un des jails:
| $ sudo fail2ban-client set sshd banip [IP à bannir]
|
Portsentry
Installation
| $ sudo apt update
$ sudo apt install portsentry
|
Configuration
Attention, cette configuration n’est valable que si vous utilisez iptables comme pare-feux.
Cela se passe dans les fichiers :
- /etc/portsentry/portsentry.conf
- /etc/default/portsentry
- /etc/portsentry/portsentry.ignore.static
1. /etc/default/portsentry
Pour un fonctionnement plus simple et plus efficace il faut éditer ce fichier de la manière suivante:
| # modes atcp et audp ("a" signifie avancé)
TCP_MODE="atcp"
UDP_MODE="audp"
|
Ainsi vous passez en mode avancé et Portsentry va gérer la liste de ports automatiquement. Il va checker vos ports ouverts et les surveiller de fait.
2. /etc/portsentry/portsentry.conf
placez les deux lignes block de 0 à 1
| # 0 = Do not block UDP/TCP scans.
# 1 = Block UDP/TCP scans.
# 2 = Run external command only (KILL_RUN_CMD)
BLOCK_UDP="1"
BLOCK_TCP="1"
|
Vérifiez que cette ligne est décommentée.
| KILL_HOSTS_DENY="ALL: $TARGET$ : DENY"
|
Commentez toute les kill_route puis décommentez la ligne :
| KILL_ROUTE="/sbin/iptables -I INPUT -s $TARGET$ -j DROP"
|
(Verifiez qu’aucune autre option kill_route ne soit active (décommentée). En effet seule une règle à la fois peut fonctionner.)
Cette ligne va permettre à portsentry d’ajouter une ligne à votre pare-feux iptables lors d’une détection d’un scan afin d’en bloquer l’origine.
Cette ligne doit bien être décommentée. Vérifiez également que « debug » soit bien en minuscules.
| KILL_RUN_CMD="/sbin/iptables -I INPUT -s $TARGET$ -j DROP && /sbin/iptables -I INPUT -s $TARGET$ -m limit --limit 3/minute --limit-burst 5 -j LOG --log-level debug --log-prefix 'Portsentry: dropping: '"
|
vérification inscription blacklist
| $ cd /var/lib/portsentry/
$ ls -al
total 168
drwxr-xr-x 2 root root 4096 Sep 7 15:00 .
drwxr-xr-x 41 root root 4096 Sep 7 12:38 ..
-rw-r--r-- 1 root root 66379 Sep 8 08:17 portsentry.blocked.atcp
-rw-r--r-- 1 root root 3448 Sep 8 08:15 portsentry.blocked.audp
-rw-r--r-- 1 root root 0 Sep 7 12:38 portsentry.blocked.tcp
-rw-r--r-- 1 root root 0 Sep 7 12:38 portsentry.blocked.udp
-rw------- 1 root root 78647 Sep 8 08:17 portsentry.history
|
Ajout ipset
Il nous faut d'abord créer notre set ipset avec un timeout de 1800s.
| ipset create portsentry hash:ip timeout 1800
|
Puis créer notre règle correspondante dans iptables
| $ iptables -I INPUT -m set --match-set portsentry src -j DROP
|
Maintenant, il faut spécifier à portsentry d'ajouter ces IPs bannies à notre set ipset :
Nous allons spécifier la valeur 2 aux options BLOCK_TCP et BLOCK_UDP du fichier /etc/portsentry/portsentry.conf, pour utiliser uniquement la directive KILL_RUN_CMD.
Voici la KILL_RUN_CMD à définir (autour de la ligne 269) :
| KILL_RUN_CMD="/sbin/ipset add portsentry $TARGET$"
|
Blacklist IP avec ipset
Liste de bloquage
| $ wget https://raw.githubusercontent.com/duggytuxy/malicious_ip_addresses/main/botnets_zombies_scanner_spam_ips.txt -qO botnets_zombies_scanner_spam_ips.txt
$ dos2unix botnets_zombies_scanner_spam_ips.txt
|
Création ipset
| $ sudo ipset create manual_blacklist -exist hash:ip hashsize 32768 maxelem 200000 timeout 0
|
Flush ipset
| $ sudo ipset flush manual_blacklist
|
Destruction ipset
| $ sudo ipset destroy manual_blacklist
|
Script
| $ vi iplist.sh
iplist_data=$(cat botnets_zombies_scanner_spam_ips.txt)
for row_data in $iplist_data; do ipset -exist add manual_blacklist ${row_data}; done
|
vérification de la bonne application du script
| $ sudo ipset list manual_blacklist
<SNIP>
170.238.162.191 timeout 0
43.254.133.82 timeout 0
59.48.39.222 timeout 0
<SNIP>
|