(Basé sur une distribution ArchLinux)
====== Installation de base (non chrootée) ======
Installer nginx + php-fpm :
pacman -S nginx php-fpm
La configuration de nginx pour la partie PHP :
location ~ \.php$ {
try_files $uri =404;
root /home//www;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /home//www$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
(ne pas oublier de modifier tous les root)
Dans /etc/rc.conf, ajouter php-fpm et nginx aux services à démarrer :
DAEMONS=(syslog-ng network netfs sshd crond php-fpm nginx)
Dans /etc/php/php-fpm.conf, décommenter la ligne suivante :
include=/etc/php/fpm.d/*.conf
Créer /etc/php/fpm.d/.conf :
[]
listen = 127.0.0.1:9000
user =
group =
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
pm.status_path = /fpm-status
ping.path = /fpm-ping
request_terminate_timeout = 10s
request_slowlog_timeout = 10s
slowlog = /home//www/logs/php-fpm.log
#chroot = /home//www
#chdir =
env[TMP] = /home//www/tmp
php_admin_value[error_log] = /home//www/logs/php.log
Commandes complémentaires à exécuter :
* en tant qu'utilisateur :
mkdir -p /home//www/logs
chown -R :http /home//www
find /home//www/ -type f -exec chmod g+r {} \;
find /home//www/ -type d -exec chmod g+rx {} \;
chmod 0755 /home/
* en tant que root :
usermod -aG http
usermod -aG http http
Démarrer à la main les services à moins d'attendre le prochain (re)démarrage :
/etc/rc.d/php-fpm start
/etc/rc.d/nginx start
====== chrooter ======
* Décommenter la ligne chroot de /etc/php/fpm.d/.conf
* Modifier la ligne fastcgi_param de SCRIPT_FILENAME dans le fichier de configuration de nginx (/etc/nginx/conf/nginx.conf) de façon à avoir : fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
* Ajouter, à la suite de celle ci-dessus :fastcgi_param DOCUMENT_ROOT /;
* Dans /etc/nginx/conf/fastcgi_params, commenter celle-ci :fastcgi_param DOCUMENT_ROOT $document_root;
Pour chaque site/utilisateur :
* créer un serveur nginx (bloc server)
* créer une configuration php-fpm propre (en commençant par modifier la directive listen : le port ou le socket doit être différent)
====== FTP ======
pacman -S vsftpd
Dans /etc/vsftpd.conf, apporter les changements suivants :
anonymous_enable=YES
A changer en NO
local_umask=022
A changer en 027
Décommenter les lignes :
local_enable=YES
write_enable=YES
chroot_local_user=YES
Autoriser les entrées au serveur FTP (tcpwrapper) en modifiant /etc/hosts.allow :
vsftpd: ALL
Démarrage du service : ajouter vsftpd aux DAEMONS (/etc/rc.conf) :
DAEMONS = (... vsftpd)
Attendre le prochain (re)démarrage sinon, démarrer manuellement le service par :
/etc/rc.d/vsftpd start
====== SSH ======
Installer ssh :
pacman -S openssh
Éditer /etc/ssh/sshd_config, ajouter/remplacer :
ChrootDirectory %h
Autoriser les connexions ssh (tcpwrapper) en ajoutant à /etc/hosts.allow :
sshd: ALL
Démarrage automatique du service : ajouter sshd au tableau DAEMONS de /etc/rc.conf :
DAEMONS = (... sshd)
Attendre le prochain (re)démarrage de la machine, sinon le démarrer manuellement :
/etc/rc.d/sshd start
====== À faire ======
* du plus "propre" : créer/utiliser un groupe dédié ?, revoir l'aborescence de la partie chrootée (plus "profonde") ?
* services (SSH ?, FTP ?)
* tout ce qui est lié au chroot (résolution des noms ?, accès à MySQL ?, changer le répertoire temporaire TMP ?, locale(s) ?)
MySQL :
# Activer le pilote MySQL de PDO
echo 'extension=pdo_mysql.so' >> /etc/php/conf.d/mysql.ini
pacman -S mysql
/etc/rc.d/mysqld start && mysql_secure_installation
# Ajouter mysqld au DAEMONS
# --
# Dans PHP : utiliser l'adresse IP extérieure de la machine
# Pour MySQL :
# - commenter skip-networking dans /etc/mysql/my.cnf
# - créer les comptes MySQL pour les permettre d'y accéder en conséquence (grant all privileges on .* to @'192.168.0.%' identified by '';)
# - whitelister les entrées MySQL dans tcpwrapper (/etc/hosts.allow) en y ajoutant : mysqld: 192.168.0.0/255.255.255.0
Résolution DNS :
mkdir /home//www/etc
cp /etc/{resolv,nsswitch}.conf /home//www/etc/
mkdir /home//www/lib
cp /lib/libnss_dns.so.2 /home//www/lib/
# A moins de retirer la valeur "files" de la ligne "hosts:" de /home//www/etc/nsswitch.conf
touch /home//www/etc/hosts
cp /lib/libnss_files.so.2 /home//www/lib/
====== Création des utilisateurs par script ======
#!/bin/bash
BINARIES=(bash cat cp mv rm grep ls mkdir chmod chown chgrp ps tar touch echo cat kill less)
# TODO:
# - les services en cours : nginx, php-fpm
# - les services à faire : mysql : mysql -u root -p < create database db_${USERNAME}; grant all privileges ... ?)
# - /etc/bash* à copier ?
# - la(les) locale(s) ?
# - le domaine ?
# 1,1 utilisateur <=> 1,N sites/serveurs <=> 1,? bdd
# http://publications.jbfavre.org/web/php-fpm-apps-server-nginx.fr
declare -r PROGNAME=`basename $0`
declare -r SHORTOPTS="g:u:p:s"
declare -r LONGOPTS="group:,user:,path:,ssh"
declare -r DATADIR=$(dirname $(readlink -f "${BASH_SOURCE}"))
SSH=false
usage() {
echo "Usage: ${PROGNAME} [ -u ] [ -g ] [ -p ]"
exit 2
}
OPTS=$(getopt -o $SHORTOPTS --long $LONGOPTS -n "${PROGNAME}" -- "$@")
[ $? -eq 0 ] || usage
eval set -- "$OPTS"
while true; do
case "$1" in
-u|--user)
USERNAME=$2
shift 2;;
-p|--path)
CHROOTPATH=$2
shift 2;;
-g|--group)
HTTPGROUP=$2
shift 2;;
-s|--ssh)
SSH=true
shift;;
--)
shift; break;;
esac
done
[ -n "${USERNAME}" ] || usage
[ $# -eq 0 ] || usage
CHROOTPATH=${CHROOTPATH:-"/home/${USERNAME}"}
HTTPGROUP=${HTTPGROUP:-"http"}
declare -r SU="su - ${USERNAME} -c"
PORT=$(grep -rhE '^[[:blank:]]*listen[[:blank:]]*=[[:blank:]]*([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}:' /etc/php/ | cut -d : -f 2 | sort -rn | head -1)
if [ -z "${PORT}" ]; then
PORT=9001
else
((PORT++))
fi
FPM_TPL=$(cat < php-fpm configuration :"
echo -e "${FPM_TPL}"
echo "===> Nginx configuration :"
echo -e "${NGINX_TPL}"
exit
useradd -d "${CHROOTPATH}" -m -G "${HTTPGROUP}" -s /bin/bash -U "${USERNAME}"
passwd "${USERNAME}"
if [ $SSH ]; then
chmod 0775 "${CHROOTPATH}"
chown root "${CHROOTPATH}"
else
chmod 0755 "${CHROOTPATH}"
fi
$SU "mkdir -p ${CHROOTPATH}/dev/"
mknod "${CHROOTPATH}/dev/null" c 1 3 -m 0666
mknod "${CHROOTPATH}/dev/zero" c 1 5 -m 0666
mknod "${CHROOTPATH}/dev/random" c 1 8 -m 0444
mknod "${CHROOTPATH}/dev/urandom" c 1 9 -m 0444
mknod "${CHROOTPATH}/dev/tty" c 5 0 -m 0755
mkdir -p "${CHROOTPATH}/dev/pts/"
mknod "${CHROOTPATH}/dev/pts/0" c 136 0 -m 666
mknod "${CHROOTPATH}/dev/pts/1" c 136 1 -m 666
$SU "mkdir -p ${CHROOTPATH}/etc/"
$SU "echo -n > ${CHROOTPATH}/etc/group"
for group in $(groups "${USERNAME}"); do
$SU "grep '^${group}:' /etc/group | sed 's/:[^:]*$/:${USERNAME}/' >> '${CHROOTPATH}/etc/group'"
done
$SU "grep '^${USERNAME}:' /etc/passwd > '${CHROOTPATH}/etc/passwd'"
$SU "echo '127.0.0.1 localhost' > '${CHROOTPATH}/etc/hosts'"
for lib in $(grep '^hosts:' /etc/nsswitch.conf | cut -d ' ' -f 2-); do
$SU "install -D '/lib/libnss_${lib}.so.2' '${CHROOTPATH}/lib/libnss_${lib}.so.2'"
done
$SU "grep '^hosts:' /etc/nsswitch.conf > '${CHROOTPATH}/etc/nsswitch.conf'"
for bin in "${BINARIES[@]}"; do
bin=$(which "${bin}")
if [ -n "${bin}" ]; then
for lib in $(ldd ${bin} 2>/dev/null | sed "s|.*=>\(.*\)|\1|"); do
if [ -n "${lib}" ]; then
notls=$(echo ${lib} | sed 's|/lib/tls.*/\(lib.*\)|/lib/\1|')
[ -e "${notls}" ] && lib="${notls}"
if [ -f "${lib}" ]; then
$SU "install -D '${lib}' '${CHROOTPATH}${lib}'"
fi
fi
done
for lib in $(strings "${bin}" | grep 'ld.*\.so'); do
$SU "install -D '${lib}' '${CHROOTPATH}${lib}'"
done
$SU "install -D '${bin}' '${CHROOTPATH}${bin}'"
fi
done
read -p "Recharger la configuration de Nginx maintenant ? [o/N] " answer
[[ $answer = [oOyY] ]] && /etc/rc.d/nginx reload
read -p "Recharger la configuration de php-fpm maintenant ? [o/N] " answer
[[ $answer = [oOyY] ]] && /etc/rc.d/php-fpm reload
Test rapide du chroot :
chroot --userspec= /home/ /bin/bash