Installation et configuration d'un serveur virtuel avec AlpineLinux et les vservers-utils
Lexique
-
hôte : machine physique sur laquelle sont installé les invités
-
invités : machines virtuelles installées sur l'hôte
-
$LAN : réseau local ( box + machines connectées au réseau )
-
$VLAN : réseau local virtuel ( invités présents sur l'hôte)
-
$WAN : réseau étendu (Internet )
-
$NBRE_IVTS : nombre d'invités
-
$IFACE : interface de la machine hĂ´te
-
$VIFACE : interface de la machine virtuelle
-
$EXTIP : Ip de la machine sur $LAN ( souvent du type 192.168.x.x )
-
$EXTPORT : port de l'hĂ´te
-
$VHOST : Ip de la machine virtuelle (invité) sur $VLAN
-
$INTPORT : port d'un invité
-
$PUBIP : Ip de la machine sur $WAN ( IP publique )
-
$PASVPORTS_MIN : Port min pour connection ftp > 1024
-
$PASVPORTS_MAX : Port max pour connection ftp > $PASVPORTS_MIN
-
$WWW : racine du site ( ex: /home/www )
-
$nom_utilisateur : nom de l'utilisateur système définis dans I.E ou II.B
-
$LOGIN : Login du module d'authentifcation de Lighttpd définis dans II.C.2.a
-
$MDP : Mdp du module d'authentifcation de Lighttpd définis dans II.C.2.a Dans beaucoup des commandes qui suivent, surveillez attentivement les variables désignées par un $VARIABLE. Leur présence signifie en général qu'il faut la remplacer en l'adaptant à votre configuration
I.Manipulations sur hĂ´te
I.A. Installation d' Alpine linux vserver :
- Télécharger l'.iso d'Alpine Linux Vserver : http://alpinelinux.org/downloads
- Création d'une clé usb bootable avec unetbootin / lili
- Boot sur iso alpine-vserver
- Login : root
Configuration et installation sur le disque dur
$ setup-alpine ## suivre les indications et répondre aux questions :
1. fr, fr-latin9, nom du système, eth0, mdp, disque, mode, repo
$ reboot ## redémarrage de la machine ! Enlever la clé USB !
I.A. 1. (optionnel) Créer une partition par serveur virtuel
Gparted
- Création clé USB Gparted live : unetbootin + .iso (http://gparted.sourceforge.net/livecd.php)
- Démarrer sur clé usb :
- Gparted :
- redimensionnement de la partition /
- création d'un partition étendue puis partitions virtuelles
- reboot sur disque dur
- Gparted :
Ajout des partitions au fichier /etc/fstab :
Création points de montage (autant de pdm que de partitions créées) :
$ mkdir -p /guests/point1 /guests/point2 ...
Trouver partitions systèmes
$ df -h ## chercher nom (sdX) de / (default : sda3)
Faire un backup de /etc/fstab
$ cp /etc/fstab etc/fstab.bak
Ajouter UUIDs a /etc/fstab
$ blkid > tee -a /etc/fstab
Édition du fichier /etc/fstab
$ nano /etc/fstab
Enlever les uuids avec nom < sda 3 et transformer :
en
- /dev/sdaX
UUID=...
Ajout des options de montage en respectant le schéma suivant
UUID=.../guests/point1 ext4 rw,relatime,barrier=1,data=ordered 0 0
Vérifier montage automatique
$ mount /guests/* $ df -h ## doit lister les partitions créées avec Gparted et les points de montage /guests/pointX
I.A. 2. Installation des utilitaires vserver et autres
$ apk add util-vserver nano sudo
I.A. 3. Réglage de la visibilité des processus virtuels et ajout au démarrage
$ /etc/init.d/vprocunhide start && rc-update add vprocunhide
I.B. Construction de machines virtuelles Alpine Linux
I.B.1. Création du modèle
$ apk --initdb -U -X http://dl-2.alpinelinux.org/alpine/v2.2/main --root /tmp/tmpdir add alpine-base () $ cd /tmp/tmpdir && tar -jcf ../base.tar.bz2 && cd .. && rm -rf /tmp/tmpdir
I.B.2. Création d'un invité
$VIFACE: --hostname guest1
--rootdir /guests/point1 -m template --
-t /tmp/base.tar.bz2
-d alpine
- $VHOST ou $PUBIP selon les cas.
- Ă adapter selon les cas.
- $VIFACE : voir I.C.1 > dummyX si emploi de cette méthode.
- L'option '--initstyle' peut-être utilisée pour définir le type de démarrage (plain, openrc)
Commandes vserver :
$ vserver guest1 start | stop | enter | restart | delete
I.B.3 Régler le démarrage automatique de l'invité
L'invité démarre automatiquement si un fichier "mark" contenant "default" est présent dans /etc/vservers/guest1/apps/init/ :
$ mkdir -p /etc/vservers/guest1/apps/init/ $ echo "default" > /etc/vservers/guest1/apps/init/mark $ rc-update add vservers.default Pour créer une machine virtuelle avec une distribution différente ( Debian, Arch, etc.), se référer à l'article suivant : Vserver-utils: Créer une machine virtuelle à base de Debian et autres
I.C. Configuration du réseau
I.C.1. Méthode Dummies
I.C.1.a Chargement du module
$ echo "dummy numdummies=$NBRE_IVTS" | tee -a /etc/modules
I.C.1.b Configuration des périphériques virtuels
Éditer le fichier /etc/network/interfaces et ajouter :
auto dummyN ## dummyN correspond Ă $VIFACE
Où N correspond au numéro de l'interface.
I.C.2. Méthode Iptables (à éviter)
$ apk add iptables ## installation $ rc-update add iptables ## ajout au démarrage
I.C.2.a Création des règles
RequĂŞtes sortantes
- Paquets sortants marqués avec ip du serveur ( $EXTIP ):
! -d 192.168.2.0/24 -j SNAT --to-source $EXTIP
1. plage ip en fonction de $VHOST
Explications :
Cette règle permet d'attribuer aux paquets provenant d'une IP une autre IP source ( L'IP de la machine physique dans notre cas ) afin de régler les problèmes de routage. Le routeur qui reçoit les paquets émis par la machine virtuelle ne voit que l'IP de la machine physique.
-s 192.168.2.0/24 ! -d 192.168.2.0/24 : toute requète provenant de la plage 192.168.2.0 et dont la destination n'est pas sur la plage 192.168.2.0
IPs de -s et -d en fonction de la plage de $VHOST
RequĂŞtes entrantes
- Pour chaque service (i.e : pour chaque port ) dans un système invité ( $VHOST:$INTPORT ), on mappe un port de la machine $EXTPORT afin q'une requète sur $EXTIP:$EXTPORT envoie le traffic sur $VHOST:$INTPORT.
192.168.2.0/24 -m tcp -p tcp --dport $EXTPORT -j DNAT
--to-destination $VHOST:$INTPORT
1. plage ip en fonction de $VHOST
Explications :
Cette règle permet de diriger les paquets provenant d'une ip externe ( ! -s 192.168.2.0/24 ) vers une ip interne définie par --to-destination x.x.x.x:port.
! -s 192.168.2.0/24 : toute requète ne provenant pas de la plage 192.168.2.0
Enregistrement des modifications et vérification
$ /etc/init.d/iptables save ## enregistre regles dans
/var/lib/iptables/rules-save $ iptables-save ## affiche regles actives
I.D. Firewall Shorewall
I.D.1 Installation
$ apk add shorewall
I.D.2 Configuration
-
Dans /etc/shorewall/shorewall.conf :
-
Dans /etc/shorewall/zones :
-
Dans /etc/shorewall/interfaces :
-
Dans /etc/shorewall/policy :
net all DROP ## "net" et "fw" définis dans zone fw all ACCEPT all all DROP ##(REJECT)
- Dans /etc/shorewall/params :
VSERVER_1=$VHOST ## du type 192.168.x.x VSERVER_2=$VHOST ## du type 192.168.x.y ...
- Dans /etc/shorewall/rules :
- NB : port 80 > http, port 21 > ftp, port 443 > ssl
- requetes exterieur > interieur
- ACTION SOURCE DEST PROTO DEST
ACCEPT net fw udp 53 ## port 53 > dhcp ACCEPT net fw:$VSERVER_1 tcp 80,21,443
- requetes interieur > exterieur
ACCEPT fw:$VSERVER_1 net tcp 80,21,443 ##"$VSERVER_1" définis dans "params" ...
- Vérifier les fichiers de configuration de Shorewall
$ shorewall check
I.D.3 Démarrage et ajout démarrage auto
$ /etc/init.d/shorewall start && rc-update add shorewall
I.E. Création utilisateur et désactivation du compte root
Une fois sudo mis en place pour l'utilisateur créé, la plupart des commandes nécessite l'ajout de "sudo" en début de ligne, puis la saisie du mot de passe utilisateur. L'oubli de sudo peut faire apparaître un message d'erreur.
I.E.1. Création utilisateur et mot de passe
$ adduser -h /home/www -G lighttpd $nom_utilisateur && chown $nom_utilisateur :lighttpd /home/www
$ passwd $nom_utilisateur
I.E.2. Ajout au fichier /etc/sudoers
$ apk add sudo ## installation sudo $ visudo ## 'i' , ':x'
- Ajout de la ligne :
II.E.3. Désactivation du compte root
$ passwd -l root
II. Manipulations invités
II.A. Réglages de base
1. ajout dépot, maj et install nano
$ echo
""
>/etc/apk/repositories && apk update && apk upgrade && apk add nano
$ setup-timezone ## réglage du fuseau horaire
1. OPTIONNEL ! SÉCURITÉ
$ setup-acf ## script installation acf : interface web de gestion de
l'invité ( port 443 à activer via shorewall sur l' hôte)
II.B. Création utilisateur et désactivation du compte root
Une fois sudo mis en place pour l'utilisateur créé, la plupart des commandes nécessite l'ajout de "sudo" en début de ligne, puis la saisie du mot de passe utilisateur. L'oubli de sudo peut faire apparaître un message d'erreur.
II.B.1. Création utlisateur et mot de passe
$ adduser -h /home/www -G lighttpd nom_utilisateur && chown nom_utilisateur :lighttpd /home/www
$ passwd nom_utilisateur
II.B.2. Ajout au fichier /etc/sudoers
$ apk add sudo ## installation sudo $ visudo ## 'i' , ':x'
- Ajout de la ligne :
II.B.3. Désactivation du compte root
$ passwd -l root
II.C. Lighttpd web server
II.C.1. Installation de lighttpd et php
$ apk add lighttpd php-common php-iconv php-json php-gd php-curl php-xml php-pgsql php-imap php-pdo php-pdo_pgsql php-soap php-xmlrpc php-posix php-mcrypt php-gettext php-ldap php-ctype php-mysqli php-pdo_mysql php-zip php-bz2 php-zlib
II.C.2. Configuration
- Faire les changements suivants dans /etc/lighttpd/lighttpd.conf :
- Définition de la base du site
var.basedir= $WWW server.document-root = var.basedir
- Décommenter
include "mod_fastcgi.conf" "mod_compress" "mod_rewrite" "mod_expire"
- Régler l'expiration par défaut à une semaine
expire.url = ( "" => "access plus 7 days")
- Emplacement des fichiers d'erreurs
server.errorfile-prefix = var.basedir + "/err" ## fichiers html erreurs dans dossier /err a la racine du site
- Désactivation du listage des répertoires
dir-listing.activate = "disable"
- Régler les limites de sécurité
server.max-keep-alive-requests = 6 server.max-keep-alive-idle = 15 server.max-read-idle = 15 server.max-write-idle = 15
- server.max-request-size = 16 ## optionnel : Ă commenter si on utilise un CMS
server.range-requests = "disable" server.follow-symlink = "disable"
II.C.2.a Configuration de l'authentification
- Dans /etc/lighttpd/lighttpd.conf :
- Décommenter
"mod_auth" auth.backend = "plain"
- Définir le fichier contenant les login/mdp
auth.backend.plain.userfile = "/etc/lighttpd/lighttpd.user"
- Création du fichier de login/mdp :
/etc/lighttpd/lighttpd.user &&
chown lighttpd:lighttpd /etc/lighttpd/lighttpd.user &&
chmod 700 /etc/lighttpd/lighttpd.user
Restriction d'accès à un repertoire selon ip client
Dans /etc/lighttpd/lighttpd.conf :
$HTTP["remoteip"] != "$IP_AUTORISEE { $HTTP["url"] =~ "^/$REPERTOIRE_PROTEGE/" { url.access-deny = ( "" ) } }
II.C.2.b Activation compression
- Dans /etc/lighttpd/lighttpd.conf :
compress.cache-dir = "/tmp/cache/compress" compress.filetype = ("text/plain", "text/html", "text/css", "text/xml", "text/javascript", "image/png" )
- Création du dossier de cache :
$ mkdir -p /tmp/cache/compress/" && chown lighttpd:lighttpd /tmp/cache/compress
- Dans /etc/php/php.ini :
zlib.output_compression = On zlib.output_handler = On
II.C.2.c Filtrage des mauvais user-agents
Il est possible de limiter l'accès à certaines ressources en fonction (entre autres ) de l'user-agent envoyé par un client. La plupart des script-kiddies et bots utilisent des user-agent exotiques qu'il est facile de repérer. Il ne reste alors qu'à modifier les régles de filtrage pour bloquer des requêtes un peu insistante...
Pour plus d'informations sur les différents facteurs de filtrage, voir la page de la doc Lighttpd correspondante. Dans le fichier '/etc/lighttpd/lighttpd.conf', ajouter les lignes suivantes en fin de fichier :
- user-agent vide ou de plusieurs espaces
$HTTP["useragent"] =~ "^ *$"{
url.access-deny = ( "" )
}
- user-agent d'un seul charactère
$HTTP["useragent"] =~ "^.$" {
url.access-deny = ( "" )
}
- user-agent contenant toutes les variantes de casse de zmeu ( )
$HTTP["useragent"] =~ "[Zz][Mm][Ee][Uu]" {
url.access-deny = ( "" )
}
- user-agent contenant le mot 'scanner'
$HTTP["useragent"] =~ "[Ss]canner" {
url.access-deny = ( "" )
}
- user-agent contenant le mot 'bot'
$HTTP["useragent"] =~ "[Bb]ot" {
url.access-deny = ( "" )
}
- user-agent contenant le mot 'libwww-perl' ( )
$HTTP["useragent"] =~ "libwww-perl" {
url.access-deny = ( "" )
}
- liste de mauvais user-agent ( )
$HTTP["useragent"] =~ "ADSARobot|ah-ha|almaden|aktuelles|Anarchie|amzn_assoc|ASPSeek|ASSORT|ATHENS|Atomz|attach|attache|autoemailspider|BackWeb|Bandit|BatchFTP|bdfetch|big.brother|BlackWidow|bmclient|Boston Project|BravoBrian SpiderEngine MarcoPolo|Bot mailto:craftbot@yahoo.com|Buddy|Bullseye|bumblebee|capture|CherryPicker|ChinaClaw|CICC|clipping|Collector|Copier|Crescent|Crescent Internet ToolPak|Custo|cyberalert|DA$|Deweb|diagem|Digger|Digimarc|DIIbot|DISCo|DISCo Pump|DISCoFinder|Download Demon|Download Wonder|Downloader|Drip|DSurf15a|DTS.Agent|EasyDL|eCatch|ecollector|efp@gmx.net|Email Extractor|EirGrabber|email|EmailCollector|EmailSiphon|EmailWolf|Express WebPictures|ExtractorPro|EyeNetIE|FavOrg|fastlwspider|Favorites Sweeper|Fetch|FEZhead|FileHound|FlashGet WebWasher|FlickBot|fluffy|FrontPage|GalaxyBot|Generic|Getleft|GetRight|GetSmart|GetWeb!|GetWebPage|gigabaz|Girafabot|Go!Zilla|Go!Zilla|Go-Ahead-Got-It|GornKer|gotit|Grabber|GrabNet|Grafula|Green Research|grub-client|Harvest|hhjhj@yahoo|hloader|HMView|HomePageSearch|http generic|HTTrack|httpdown|httrack|ia_archiver|IBM_Planetwide|Image Stripper|Image Sucker|imagefetch|IncyWincy|IndyLibrary|Indy Library|informant|Ingelin|InterGET|Internet Ninja|InternetLinkagent|Internet Ninja|InternetSeer.com|Iria|Irvine|JBHagent|JetCar|JOC|JOC Web Spider|JustView|KWebGet|Lachesis|larbin|LeechFTP|LexiBot|lftp|libwww|likse|Link|LinkSleuth|LINKS ARoMATIZED|LinkWalker|LWP|lwp-trivial|Mag-Net|Magnet|Mac Finder|Mag-Net|Mass Downloader|MCspider|Memo|Microsoft.URL|MIDown tool|Mirror|Missigua Locator|Mister PiX|MMMtoCrawl/UrlDispatcherLLL|^Mozilla$|Mozilla.Indy|Mozilla.NEWT|MozillaMSIECrawler|MS FrontPage|MSFrontPage|MSIECrawler|MSProxy|multithreaddb|nationaldirectory|Navroad|NearSite|NetAnts|NetCarta|NetMechanic|netprospector|NetResearchServer|NetSpider|Net Vampire|NetZIP|NetZip Downloader|NetZippy|NEWT|NICErsPRO|Ninja|NPBot|Octopus|Offline Explorer|Offline Navigator|OpaL|Openfind|OpenTextSiteCrawler|OrangeBot|PageGrabber|Papa Foto|PackRat|pavuk|pcBrowser|PersonaPilot|Ping|PingALink|Pockey|Proxy|psbot|PSurf|puf|Pump|PushSite|QRVA|RealDownload|Reaper|Recorder|ReGet|replacer|RepoMonkey|Robozilla|Rover|RPT-HTTPClient|Rsync|Scooter|SearchExpress|searchhippo|searchterms.it|Second Street Research|Seeker|Shai|Siphon|sitecheck|sitecheck.internetseer.com|SiteSnagger|SlySearch|SmartDownload|snagger|Snake|SpaceBison|Spegla|SpiderBot|sproose|SqWorm|Stripper|Sucker|SuperBot|SuperHTTP|Surfbot|SurfWalker|Szukacz|tAkeOut|tarspider|Teleport Pro|Templeton|TrueRobot|TV33_Mercator|UIowaCrawler|UtilMind|URLSpiderPro|URL_Spider_Pro|Vacuum|vagabondo|vayala|visibilitygap|VoidEYE|vspider|Web Downloader|w3mir|Web Data Extractor|Web Image Collector|Web Sucker|Wweb|WebAuto|WebBandit|web.by.mail|Webclipping|webcollage|webcollector|WebCopier|webcraft@bea|webdevil|webdownloader|Webdup|WebEMailExtrac|WebFetch|WebGo IS|WebHook|Webinator|WebLeacher|WEBMASTERS|WebMiner|WebMirror|webmole|WebReaper|WebSauger|Website|Website eXtractor|Website Quester|WebSnake|Webster|WebStripper|websucker|webvac|webwalk|webweasel|WebWhacker|WebZIP|Wget|Whacker|whizbang|WhosTalking|Widow|WISEbot|WWWOFFLE|x-Tractor|^Xaldon WebSpider|WUMPUS|Xenu|XGET|Zeus.Webster|Zeus" {
url.access-deny = ( "" )
}
II.C.2.d SSL
Créer des Certificats SSL auto-signés
- Créer le répertoire où placer le certificat :
$ mkdir /etc/lighttpd/ssl/domain.com -p
- Se rendre dans le répertoire :
$ cd /etc/lighttpd/ssl/domain.com
- Génération du certificat :
$ openssl req -new -newkey rsa:2048 -x509 -keyout server.pem -out server.pem -days 365 -nodes
- Changement des permissions :
$ chown lighttpd:lighttpd /etc/lighttpd/ssl -R $ chmod 0600 /etc/lighttpd/ssl/domain.com
Il vous sera demandé plusieurs informations sur le site.
Configurer Lighttpd
- Ajout des directives suivantes dans /etc/lighttpd/lighttpd.conf :
$SERVER["socket"] == "$PUBIP:443" { server.document-root = "/home/lighttpd/domain.com" ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/ssl/domain.com/server.pem"
-
- Cette partie met en place un mot de passe pour l'accès a
- la racine du site securise ( https ) et nécessite l'activation
- et la configuration du "mod_auth" CF. II.C.2.a
-
auth.require = ( "/" =>
-
("method" => "basic",
-
"realm" => "message",
-
"require" => "user:username"
-
)
-
)
}
Faites attention Ă bien remplacer $PUBIP avec votre adresse IP
publique.
Relancer Lighttpd
- Tester le fichier de configuration pour des erreurs de syntaxe :
$ lighttpd -t -f /etc/lighttpd/lighttpd.conf
- Redémarrer Lighttpd :
$ /etc/init.d/lighttpd restart
- Vérifier que le port 443 est ouvert :
$ netstat -tulpn | grep :443
Optionnel : Ajout des règles iptable
Cette étape n'est pas utile si vous utilisez la méthode Dummies ( CF. I.C.1 ) Dans le système hôte, entrez les commandes suivantes :
$ iptables -A INPUT -p tcp -s 0/0 --sport 1024:65535 -d $VHOST --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT $ iptables -A OUTPUT -p tcp -s $VHOST --sport 443 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
II.C.3. Démarrage auto
$ /etc/init.d/lighttpd start && rc-update add lighttpd default
II.D. VSFTP ftp server
II.D.1. Installation
$ apk add vsftpd
II.D.2. Configuration
- Dans /etc/vsftpd.conf :
- On accepte les utilisateurs locaux
local_enable=YES
- On permet l'ecriture
write_enable=YES
- on désactive l'acces anonyme
anonymous_enable=NO
- mode passif
pasv_enable=YES
- définition des ports pour le mode passif
pasv_min_port=$PASVPORTS_MIN pasv_max_port=$PASVPORTS_MAX
- adresse du serveur pour le mode passif
pasv_address=$EXTIP
- chroot des utilisateurs
chroot_local_user=YES
- utilisation des ciphers > 128 bits seulement
ssl_ciphers=HIGH
II.D.2.a Activation SSL pour FTPS
- Génération du certificat SSL :
$ openssl req -new -newkey rsa:2048 -x509 -nodes -days 365 -out /etc/ssl/vsftpd.pem -keyout /etc/ssl/vsftpd.pem $ chmod 0600 /etc/ssl/vsftpd.pem
- Ajouts au fichier /etc/vsftpd.conf :
- Si utilisation du SSL
ssl_enable=YES rsa_cert_file=/etc/ssl/vsftpd.pem
force_local_logins_ssl=YES force_local_data_ssl=YES
Il vous faudra alors configurer votre client ftp pour utiliser le mode
de connexion FTPES, en mode actif.
II.D.3. Démarrage auto
$ /etc/init.d/vsftpd start && rc-update add vsftpd default
II.E. Mysql
II.E.1. Installation
$ apk add mysql mysql-client
II.E.2 Configuration
$ /usr/bin/mysql_install_db --user=mysql $ /etc/init.d/mysql start && rc-update add mysql default $ /usr/bin/mysqladmin -u root password 'password'
II.F. Web apps
- Création du répertoire :
$ mkdir $WWW/$WEBAPP
- Téléchargement des fichiers :
$ cd $WWW/$WEBAPP $ wget $WEBAPP_URL.tar.gz $ tar zxvf $WEBAPP
- Changement de permissions :
$ chown -R $USER:ligttpd $WEBAPP $ chmod -R 770 $WEBAPP
- Nettoyage :
$ rm *.tar.gz
- Création de la bdd MySql :
$ mysql -u root -p > CREATE DATABASE wordpress;
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost' IDENTIFIED BY 'wordpress password'; FLUSH PRIVILEGES; > EXIT