(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