Installation et configuration d'un serveur virtuel avec AlpineLinux et les vservers-utils

Lexique

I.A. Installation d' Alpine linux vserver :

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
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

  1. /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 

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

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

 ! -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

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

net all DROP ## "net" et "fw" définis dans zone fw all ACCEPT all all DROP ##(REJECT)

VSERVER_1=$VHOST ## du type 192.168.x.x VSERVER_2=$VHOST ## du type 192.168.x.y ...

  1. NB : port 80 > http, port 21 > ftp, port 443 > ssl
  2. requetes exterieur > interieur
  3. ACTION SOURCE DEST PROTO DEST

ACCEPT net fw udp 53 ## port 53 > dhcp ACCEPT net fw:$VSERVER_1 tcp 80,21,443

  1. requetes interieur > exterieur

ACCEPT fw:$VSERVER_1 net tcp 80,21,443 ##"$VSERVER_1" définis dans "params" ...

$ 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'

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'

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

  1. Définition de la base du site

var.basedir= $WWW server.document-root = var.basedir

  1. Décommenter

include "mod_fastcgi.conf" "mod_compress" "mod_rewrite" "mod_expire"

  1. Régler l'expiration par défaut à une semaine

expire.url = ( "" => "access plus 7 days")

  1. Emplacement des fichiers d'erreurs

server.errorfile-prefix = var.basedir + "/err" ## fichiers html erreurs dans dossier /err a la racine du site

  1. Désactivation du listage des répertoires

dir-listing.activate = "disable"

  1. 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

  1. 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

  1. Décommenter

"mod_auth" auth.backend = "plain"

  1. Définir le fichier contenant les login/mdp

auth.backend.plain.userfile = "/etc/lighttpd/lighttpd.user"

/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

compress.cache-dir = "/tmp/cache/compress" compress.filetype = ("text/plain", "text/html", "text/css", "text/xml", "text/javascript", "image/png" )

$ mkdir -p /tmp/cache/compress/" && chown lighttpd:lighttpd /tmp/cache/compress

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 :

  1. user-agent vide ou de plusieurs espaces

$HTTP["useragent"] =~ "^ *$"{

    url.access-deny = ( "" ) 

}

  1. user-agent d'un seul charactère

$HTTP["useragent"] =~ "^.$" {

    url.access-deny = ( "" ) 

}

  1. user-agent contenant toutes les variantes de casse de zmeu ( )

$HTTP["useragent"] =~ "[Zz][Mm][Ee][Uu]" {

    url.access-deny = ( "" ) 

}

  1. user-agent contenant le mot 'scanner'

$HTTP["useragent"] =~ "[Ss]canner" {

    url.access-deny = ( "" ) 

}

  1. user-agent contenant le mot 'bot'

$HTTP["useragent"] =~ "[Bb]ot" {

    url.access-deny = ( "" ) 

}

  1. user-agent contenant le mot 'libwww-perl' ( )

$HTTP["useragent"] =~ "libwww-perl" {

    url.access-deny = ( "" ) 

}

  1. 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

$ mkdir /etc/lighttpd/ssl/domain.com -p

$ cd /etc/lighttpd/ssl/domain.com

$ openssl req -new -newkey rsa:2048 -x509 -keyout server.pem -out server.pem -days 365 -nodes

$ 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

$SERVER["socket"] == "$PUBIP:443" { server.document-root = "/home/lighttpd/domain.com" ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/ssl/domain.com/server.pem"

    1. Cette partie met en place un mot de passe pour l'accès a
    2. la racine du site securise ( https ) et nécessite l'activation
    3. et la configuration du "mod_auth" CF. II.C.2.a
  1. auth.require = ( "/" =>

  2. ("method" => "basic",

  3. "realm" => "message",

  4. "require" => "user:username"

  5. )

  6. )

}
Faites attention à bien remplacer $PUBIP avec votre adresse IP publique.

Relancer Lighttpd

$ lighttpd -t -f /etc/lighttpd/lighttpd.conf

$ /etc/init.d/lighttpd restart

$ 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

Source

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

  1. On accepte les utilisateurs locaux

local_enable=YES

  1. On permet l'ecriture

write_enable=YES

  1. on désactive l'acces anonyme

anonymous_enable=NO

  1. mode passif

pasv_enable=YES

  1. définition des ports pour le mode passif

pasv_min_port=$PASVPORTS_MIN pasv_max_port=$PASVPORTS_MAX

  1. adresse du serveur pour le mode passif

pasv_address=$EXTIP

  1. chroot des utilisateurs

chroot_local_user=YES

  1. utilisation des ciphers > 128 bits seulement

ssl_ciphers=HIGH

II.D.2.a Activation SSL pour FTPS

$ 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

  1. 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

$ mkdir $WWW/$WEBAPP

$ cd $WWW/$WEBAPP $ wget $WEBAPP_URL.tar.gz $ tar zxvf $WEBAPP

$ chown -R $USER:ligttpd $WEBAPP $ chmod -R 770 $WEBAPP

$ rm *.tar.gz

$ mysql -u root -p > CREATE DATABASE wordpress;

GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost' IDENTIFIED BY 'wordpress password'; FLUSH PRIVILEGES; > EXIT