Quelques techniques de sioux pour sécuriser un hôte Proxmox VE

Maintenant que ma nouvelle installation de Proxmox VE tourne à merveille suite aux déboires que j'ai pu avoir chez mon ancien prestataire, je vais vous dévoiler quelques-unes de mes techniques de sioux pour sécuriser un peu plus un hôte Proxmox, car en configuration par défaut ce n'est pas très excitant. Ces quelques billes ne transformeront pas votre hôte en forteresse inviolable, mais il sera déjà un peu plus blindé ! 😁

Sécuriser SSH

Un petit tour dans /etc/ssh/sshd_config rapidement, et on va procéder au changement de quelques paramètres, tout d'abord le port par défaut sur lequel SSH écoute. Le 22 étant le port par défaut, on va le changer. Naturellement, on évitera de mettre un port qui est déjà utilisé pour une autre application ou qui pourrait être bloqué par un éventuel pare-feu. Ensuite, l'option PermitRootLogin ne doit surtout pas être à yes mais à without-password, prohibit-password ou à no. Les deux premières options peuvent être utilisées avec des clefs SSH, tandis que la dernière bloquera complètement le login en root, forçant un su une fois la connexion avec un utilisateur standard établie.

Rejeter les tentatives de connexion avec une autre IP

Dans /etc/hosts.allow, on va pouvoir définir les adresses IP qui sont autorisées à communiquer avec certains services installés sur la machine. Il peut être judicieux de rejeter les connexions SSH sur toutes les IP sauf une. Par exemple, celle d'un VPN et éventuellement d'une de vos machines virtuelles si vous avez une VM dédiée à l'administration.

Dans cet exemple, je n'autorise qu'une IP à se connecter et je bloque toutes les autres.

sshd : 192.168.1.2 : allow
sshd : all : deny

Autoriser l'accès à l'interface web de Proxmox uniquement sur une adresse ou un range d'IP

Par défaut, l'interface web de Proxmox est accessible sur le port 8006 pour tout le réseau internet. Le moteur web étant basé sur Apache, il est possible d'appliquer des règles allow et deny toutes simples pour n'autoriser l'accès à l'interface web que sur les IP que l'on souhaite. Ici aussi, utiliser un VPN peut s'avérer utile car on déplace derrière une authentification supplémentaire le portail web.

On édite avec nano le fichier /etc/default/pveproxy, puis on saisit les IP qu'on souhaite autoriser ou refuser comme ceci :

ALLOW_FROM="192.168.1.2,192.168.2.12"
DENY_FROM="all"

POLICY="allow"

Un redémarrage de l'interface web est nécessaire :

pveproxy restart

Installer fail2ban

fail2ban est une application tournant en tâche de fond qui écoute les divers logs système et applicatifs et repère les tentatives de brute-force et place en cas d'échecs répétés de connexion les IP dans les règles de rejet du pare-feu ; en conséquence, toutes les IP (ou plage) voient leurs connexions rejetées pendant un certain laps de temps durant la configuration. Celle par défaut suffit normalement pour le peu de services qui sont en théorie installés sur l'hôte.

apt install fail2ban

Le fichier de configuration le plus intéressant est /etc/fail2ban/jail.conf car c'est ici que l'on peut éventuellement ajouter des services à monitorer.

En dehors de ces astuces, je ne saurai que conseiller de créer des utilisateurs avec le minimum de privilège par VM, créer un compte pour l'administration du datastore, et de passer par un VPN pour vous connecter en SSH ou en web. Vous pouvez trouver plus de documentation sur ces liens concernant fail2ban, pveproxy et sshd_config.

Migration des VM d'un hôte Proxmox VE vers un autre hôte sans cluster

Suite à des déboires par rapport à l'hébergeur de mon serveur, j'ai fini par revenir chez OVH chez qui j'ai toujours été satisfait. Sur ce nouveau serveur, j'ai donc rempilé pour la même distribution que l'ancien, un Proxmox VE 5 sur base de Debian 9, pour des raisons de compatibilité principalement, et aussi car j'étais satisfait de cet hyperviseur après quelques années sous ESXi.

Le principal intérêt étant la possibilité de conserver les machines virtuelles et ne rien avoir à réinstaller à part l'hyperviseur lui-même et refaire la configuration (ou plutôt, la redéployer étant donné que j'avais tout sauvegardé), je vais expliquer dans cet article comment procéder à l'export et à l'importation des VM de l'ancien hôte vers le nouveau.

Sur l'interface de Proxmox, sélectionner la machine virtuelle que l'on souhaite sauvegarder, puis aller dans Backup, et enfin, cliquer sur Backup Now. Si le datastore est invisible, il faut activer le stockage de fichiers de sauvegarde dessus (Datacenter > Storage > Edit > Content, cocher VZDump backup file).

La fenêtre de sauvegarde d'une VM. Il faut choisir le datastore sur lequel écrire la sauvegarde, le mode (snapshot, mise en veille de la VM ou arrêt complet) et enfin, spécifier si l'on souhaite une compression de celle-ci et/ou un mail.

Un snapshot n'étant pas suffisant pour restaurer une VM sur un autre hôte sans cluster, il faut donc soit mettre en sommeil la VM le temps de la sauvegarde (option Suspend) ou l'arrêter complètement (option Stop). Dans mon cas, le mode Suspend suffit ; j'ai choisi une compression LZO pour réduire le temps de transfert vers l'autre hyperviseur.

Il se peut que la sauvegarde échoue : le message d'erreur est généralement assez clair, mais s'assurer qu'il ne reste pas un ISO de monté et inaccessible ou que la VM n'est pas en cours d'extinction déjà est un début.

Un écran apparaît alors permettant de suivre le déroulement de la sauvegarde, en fonction de la taille de la machine, de vos performances CPU et disque, il n'y a pas de vrai moyen de déterminer le temps que cela peut prendre. A titre d'exemple, une sauvegarde d'une VM avec un seul disque virtuel contenant environ 65 Go de données s'est terminée en environ 15 minutes (CPU Core i7-4770, 32 Go de RAM, disques SATA 10K).

Une fois la sauvegarde terminée, il va s'agir de la transférer. Le moyen présentant le meilleur ratio simplicité/sécurité est d'utiliser SCP. Dans un shell, nous allons donc nous placer dans le répertoire des dumps, identifier le fichier de sauvegarde, puis lancer le transfert SCP.

cd /var/lib/vz/dump/
ls

La sauvegarde est donc au format .vma.lzo puisque l'on a décidé de compresser en LZO. En cas de doute un ls -l affiche la taille, permettant de différencier le log de la sauvegarde elle-même.

Reste plus qu'à lancer le SCP :

scp vzdump-qemu-machineid-time_stamp.vma.lzo user@destination:/var/lib/vz/dump/vzdump-qemu-machineid-time_stamp.vma.lzo

A noter que machineid et time_stamp sont des variables qui changent naturellement en fonction de l'ID de la VM et de l'heure à laquelle la sauvegarde a commencé ; on utilisera bien sûr le nom récupéré plus haut. scp utilisant SSH, il peut être nécessaire de préciser le port sur lequel écoute SSH sur le serveur de destination (scp -P 2222 par exemple, si le port SSH est 2222). Il faut également que l'utilisateur spécifié soit en mesure d'écrire dans le répertoire de destination. Vous pouvez faire le transfert vers un homedirectory avec un utilisateur tout simple puis ensuite déplacer la sauvegarde vers le répertoire des dumps.

Le temps de transfert dépendant quasi-uniquement de la bande passante entre les deux hôtes, impossible de prédire celui-ci. Une fois le transfert terminé, sur le nouveau Proxmox, il suffit de se rendre sur les propriétés du datastore pour permettre de gérer les sauvegardes si cela n'est pas déjà fait  (éventuellement déjà opéré sur l'hôte d'origine pour faire les sauvegardes) :

En cochant VZDump backup file, on permet au datastore de gérer les fichiers dumps.

Puis, en se rendant dans le datastore lui-même, on aperçoit bien notre backup :

Il ne reste plus qu'à le sélectionner, cliquer sur Restore, indiquer un ID de machine virtuelle libre sur le nouvel hôte et le datastore de stockage. Puis au redémarrage, tout sera comme à l'extinction sur l'ancien hôte 😎

Si l'envie vous prend de réaliser tout en ligne de commande ou que vous ne pouvez pas utiliser l'interface web, je vous renvoie vers la documentation de vzdump et qmrestore.

Configuration d'OpenVPN pour accéder aux autres machines du réseau

Pour des raisons de sécurité, j'applique des filtres IP sur les principaux points d'entrée de mon cloud, avec un serveur ouvert vers l'extérieur qui sert de passerelle vers le réseau interne. Ayant installé OpenVPN pour d'autres usages, je me suis dit qu'il ne serait pas idiot de se servir d'OpenVPN pour accéder au réseau local et donc accéder aux machines de mon réseau cloud sur ma station personnelle, ce qui fait que peu importe mon emplacement, je suis toujours sur une IP acceptée par les différents services et accès de ma plateforme.

Pour ce faire, il suffit tout simplement d'aller dans les propriétés d'un utilisateur OpenVPN, et d'autoriser cet utilisateur à accéder à d'autres sous-réseaux :
Il reste donc à saisir par exemple 172.21.1.0/24 si les machines auxquelles on souhaite accéder sont sur ce sous-réseau.
Une fois la configuration appliquée, un simple ping permet de vérifier les machines du réseau local répondent, et on peut même s'y connecter directement, car étant sur le réseau local, nous ne sommes plus concernés par d'éventuelles règles NAT appliquées sur l'interface physique du serveur.
Ainsi, sur chacun de mes serveurs GNU/Linux, mon fichier /etc/hosts.allow est comme ceci :

sshd : 12.34.56.78 : allow
sshd : 12.34.56.79 : allow
sshd : ALL : deny

La machine est donc accessible uniquement via SSH par le serveur qui fait office de passerelle, soit par le VPN.

Dans le cadre d'un usage du bureau à distance sur une VM Windows, on peut filtrer grâce aux règles de pare-feu et aux étendues :

Je peux donc laisser plus sereinement ma VM Windows ouverte en TSE car elle rejettera systématiquement ce qui ne provient pas de mon réseau local.

Utilisation de rClone avec Amazon Drive

Mise à jour du 18 mai 2017 : à partir de ce jour, Amazon Cloud Drive a décidé de bannir rClone des applications autorisées à se connecter à l'API, ce qui signifie qu'il n'est plus possible à ce jour d'utiliser rClone pour se connecter et accéder aux fichiers stockés sur un compte Amazon Cloud Drive. J'ai rédigé un billet concernant le dysfonctionnement en date du 19 mai 2017 (cliquez pour y accéder).

J'utilise deux serveurs Plex pour mes séries, films, musiques et autres contenus multimédias, afin que je puisse y accéder depuis tous mes appareils sans perdre la continuité de ceux-ci. Le stockage est déporté sur Amazon Cloud Drive et non en local, pour sa capacité "illimitée" (en réalité, elle semble être de 100 To, ce qui laisse tout de même une marge plus qu'énorme). Cependant, afin que Plex puisse voir les fichiers d'Amazon Cloud Drive (abrégé ACD par la suite), il faut une application sur le système - non pas pour synchroniser les fichiers auquel cas le stockage en ligne est inutile - mais pour simuler leur présence afin que Plex puisse les détecter et y accéder si la lecture est demandée.

Jusqu'à hier, j'utilisais une application nommée acd_cli. Cependant, depuis hier soir, elle ne semble plus fonctionner, car il semblerait que le quota de requêtes fixé par Amazon a été dépassé. En effet, Amazon applique un quota de requêtes par heure sur l'API en fonction du nombre d'utilisateurs d'une application donnée. Il y a plusieurs workarounds proposés par le développeur d'acd_cli mais j'ai préféré sauter sur l'occasion pour abandonner cette solution temporairement (elle est toujours installée sur le système, mais je ne monte plus ACD avec acd_cli) et passer sur rClone, qui fait exactement la même chose, mais qui peut fonctionner avec bien plus de fournisseurs de stockage en ligne.

Je vais partir du principe que vous possédez déjà un système GNU/Linux Debian prêt à l'utilisation et que vous avez obtenu une élévations de droits, avec su ou en précédant les instructions de sudo. J'ai procédé à l'installation sur un serveur équipé de 4 vCPU, 4 Go de mémoire vive et avec un disque dur de 60 Go.

1. Prérequis

Tout d'abord, mettre à jour le système, puis installer FUSE ainsi que screen - si vous ne connaissez pas screen, il s'agit d'un outil permettant de simuler un terminal pour une application - puisqu'il nous sera utile lorsqu'on aura monté ACD avec rClone. rClone étant compressé au format zip, unzip sera nécessaire.

apt-get update && apt-get dist-upgrade
apt-get install fuse screen unzip

2. Téléchargement et installation de rClone

Le lien de la version peut évoluer avec le temps, mais un autre lien existe pour référence dans un script par exemple, il est possible d'utiliser l'un des deux liens, au choix (à noter qu'il est également possible d'installer rClone via git) :

wget https://downloads.rclone.org/rclone-v1.36-linux-amd64.zip

ou

wget https://downloads.rclone.org/rclone-current-linux-amd64.zip

Une fois que le fichier est récupéré, on va le décompresser (bien sûr, adapter le nom du fichier à la version récupérée, ou à current si vous avez pris le deuxième lien) :

unzip rclone-v1.36-linux-amd64.zip

On va se placer dans le répertoire extrait, puis copier le contenu vers /usr/sbin/rclone afin de pouvoir commencer à configurer l'application et à l'exécuter :

cd rclone-v1.36-linux-amd64
cp rclone /usr/sbin

L'installation est terminée, il faut désormais configurer l'application.

3. Configuration de rClone

On peut lancer l'assistant de configuration en saisissant :

rclone config

Si cela ne marche pas (ce qui m'est arrivé avec un autre utilisateur que root...), il faut simplement rajouter /usr/sbin devant rclone :

/usr/sbin/rclone config

L'assistant apparaît, et c'est là qu'on va déclarer notre compte ACD. On créé donc un nouveau "remote". Plusieurs paramètres vont être à saisir, il faut être vigilant lors de cette partie sous peine d'avoir à reconfigurer le compte :

  • Le nom : dans cet exemple, je l'ai appelé amazondrive. Ce nom sera utilisé dans l'instruction permettant de monter ACD.
  • Le type de compte à monter : plusieurs choix sont disponibles, mais le "1" est Amazon Cloud Drive, il faut donc saisir 1.
  • Les Amazon Application Client ID et Client Secret sont utiles si vous êtes développeur Amazon et que vous utilisez votre propre application. Etant donné que rClone n'est pas votre propre application, les champs sont à laisser vides.
  • On refuse la configuration automatique : en effet, on a besoin d'une clé d'authentification qui permet de lier rClone à ACD : clé qu'on récupère lorsqu'on s'identifie sur ACD et qu'on autorise rClone à lire et écrire sur ACD, lors de l'étape suivante.
L'étape qui consiste à récupérer la clé d'authentification peut être un peu plus chiante si vous n'avez pas d'environnement graphique sur le serveur sur lequel vous installez rClone.

Si vous avez un environnement graphique avec un navigateur web : ouvrez un terminal avec le même utilisateur que vous avez utilisé jusqu'ici, puis saisissez : rclone authorize amazon cloud drive.
Si vous n'avez pas d'environnement graphique : répétez la procédure d'installation de rClone sur un système Windows, GNU/Linux ou encore OS X, mais sans la configuration. Saisissez simplement rclone authorize amazon cloud drive.
Dans les deux cas, une fenêtre de navigateur va s'ouvrir, avec un prompt d'identification. On va donc saisir l'identifiant et le mot de passe du compte ACD, et autoriser rClone à accéder à ACD. Une fois que la manipulation est faite, la fenêtre va afficher un "Success" et la clé sera affichée dans le terminal. Il est possible de la copier-coller temporairement dans un fichier texte, mais il faudra surtout la coller une fois que l'assistant de configuration le demande, c'est-à-dire, juste après avoir demandé de saisir "rclone authorize amazon cloud drive". Il est très important de prendre toute la clé, c'est-à-dire accolades comprises.
Il ne reste plus qu'à confirmer la clé, et la configuration est terminée. rClone peut se connecter à ACD sans problèmes, il ne reste plus qu'à monter ACD.

4. Montage d'ACD

Il est nécessaire d'avoir un répertoire vide dans lequel on va monter ACD. Dans cet exemple, on va lancer rCloud avec l'utilisateur amazon, on va donc monter ACD dans son répertoire personnel :
rclone mount amazondrive: /home/amazon/
Le problème, c'est que rClone occupe le terminal. Ce qui peut être gênant si il n'est pas possible de laisser le terminal SSH ouvert par exemple. C'est pourquoi on va utiliser screen qui va nous permettre de simuler un terminal pour rClone afin qu'on puisse quand même couper la connexion SSH sans pour autant tuer le processus rClone.
On créé le nouveau terminal, que l'on va nommer rcloneacd :
screen -S rcloneacd
Une fois dans ce screen - lorsque l'on a validé la commande précédente - on peut donc saisir de nouveau la commande de montage. Attention, il n'est pas possible sans workaround de créer un screen si vous avez utilisé une élévation de droits ou un changement d'utilisateurs avec su. Il faut donc lancer le screen en tant qu'utilisateur simple et ensuite effectuer une élévation de droits si besoin, dans le screen. Lorsque rClone est lancé et le partage monté, il suffit de presser CTRL+A puis D pour quitter le screen sans le fermer.
Il est possible d'y accéder de nouveau au terminal exécutant rClone en saisissant cette commande :
screen -R rcloneacd

Enfin, pour démonter ACD :

fusermount -u /home/amazon

Normalement, le répertoire /home/amazon/ contient tous les fichiers de votre ACD, mais virtuellement. Cela signifie que grâce à FUSE, votre système voit les fichiers comme si ils étaient présents, et une bonne majorité d'applications sont également bernées. En cas d'accès en lecture ou en écriture, rClone se charge de télécharger les données, et FUSE de les rendre exploitable comme si ils étaient disponibles sur un système de fichiers standard.

Installation d'X2Go sur Debian Jessie

X2go est une application client/serveur qui permet de rediriger l'affichage d'un serveur X sur une autre machine. Dans mon cas personnel, j'ai une machine sous GNU/Linux Debian Jessie qui me permet de surfer sur internet et d'exécuter quelques applications graphiques, j'ai donc un environnement graphique MATE auquel j'accède via la console VMware, mais cela n'est pas toujours pratique (besoin de s'identifier côté VMware, de lancer la console et de se connecter ensuite à la machine). Afin de pouvoir me connecter à la machine comme je me connecterai en RDP à une machine Windows, je vais donc installer le composant serveur d'X2go sur ma machine GNU/Linux et le client sur les systèmes à partir desquels je vais accéder à Debian.

X2go se sert de SSH pour communiquer avec le serveur X présent sur le serveur. Cela signifie que tous les flux sont sécurisés et qu'il est nécessaire que le port 22 soit en écoute afin que l'on puisse se connecter, bien qu'il soit possible de modifier le port d'X2go.

Installation du serveur 

Ajouter le dépôt pour les paquets d'X2go, car ils ne sont pas fournis par défaut dans les dépôts officiels de Debian. On créé un fichier x2go.list dans /etc/apt/sources.list.d et on y ajoute la ligne suivante :



deb http://packages.x2go.org/debian jessie main

Puis on y installe le premier paquet x2go-keyring qui va permettre de communiquer avec les dépôts d'X2go et de gérer la partie sécurité de ceux-ci. Étant donné qu'il n'est pas encore installé, on aura un message d'avertissement lors de la mise à jour de la liste, il est à ignorer et ne reviendra pas par la suite.

apt-get update 
apt-get install x2go-keyring
apt-get update

Et enfin, on installe le paquet x2goserver, et toutes les dépendances nécessaires qui seront ajoutées automatiquement.

apt-get install x2goserver

Installation du client et configuration d'un hôte

 

Il est possible de récupérer le setup d'installation pour la plateforme désirée sur le site d'X2go. Dans cet exemple, je vais partir sur un client pour Windows. L'installation est des plus standard : suivant, suivant, suivant...

Une fois l'installation terminée, il faut configurer la session à ouvrir :

Le chemin peut-être laissé par défaut, tandis qu'il est nécessaire de saisir le serveur, l'identifiant de connexion, et le mot de passe associé. Le type de session indique l'environnement graphique que l'on va ouvrir : dans mon cas, j'ai choisi MATE mais de nombreux autres environnements sont disponibles : KDE, GNOME, XFCE... Dans les autres onglets sont disposés plusieurs autres paramètres : la vitesse de connexion, le partage réseau de dossiers, la gestion du copier-coller, l'écoute du périphérique audio de la machine serveur, etc. Une fois tous les paramètres saisis, il est possible de se connecter ; il faudra accepter le hash de la clef SSH du serveur, et si vous êtes sous Windows en fonction de vos GPO ou de vos réglages, autoriser l'application à communiquer à travers le pare-feu.

Et voilà ! Une simple exécution du client, un double-clic sur la connexion et je peux accéder à ma machine de la même manière que j'ouvrirais une session RDP sur une machine Windows.