(Basé sur une distribution ArchLinux)
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/<user>/www; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /home/<user>/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/<user>.conf :
[<user>] listen = 127.0.0.1:9000 user = <user> group = <user> 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/<user>/www/logs/php-fpm.log #chroot = /home/<user>/www #chdir = env[TMP] = /home/<user>/www/tmp php_admin_value[error_log] = /home/<user>/www/logs/php.log
Commandes complémentaires à exécuter :
mkdir -p /home/<user>/www/logs chown -R :http /home/<user>/www find /home/<user>/www/ -type f -exec chmod g+r {} \; find /home/<user>/www/ -type d -exec chmod g+rx {} \; chmod 0755 /home/<user>
usermod -aG http <user> 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
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /;
fastcgi_param DOCUMENT_ROOT $document_root;
Pour chaque site/utilisateur :
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
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
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 <db>.* to <user>@'192.168.0.%' identified by '<mdp>';) # - 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/<user>/www/etc cp /etc/{resolv,nsswitch}.conf /home/<user>/www/etc/ mkdir /home/<user>/www/lib cp /lib/libnss_dns.so.2 /home/<user>/www/lib/ # A moins de retirer la valeur "files" de la ligne "hosts:" de /home/<user>/www/etc/nsswitch.conf touch /home/<user>/www/etc/hosts cp /lib/libnss_files.so.2 /home/<user>/www/lib/
#!/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 <login> ] [ -g <groupe http> ] [ -p <chroot path> ]" 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 <<EOF_FPM_TPL [${USERNAME}] listen = 127.0.0.1:${PORT} listen.allowed_clients = 127.0.0.1 user = ${USERNAME} group = ${USERNAME} 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 = ${CHROOTPATH}/www/logs/php-fpm.log chroot = ${CHROOTPATH}/www #chdir = /docroot/ env[TMP] = /tmp env[TEMP] = /tmp env[TMPDIR] = /tmp php_admin_value[error_log] = /logs/php.log EOF_FPM_TPL ) NGINX_TPL=$(cat <<EOF_NGINX_TPL server { listen 80; server_name TODO; root ${CHROOTPATH}/www; access_log ${CHROOTPATH}/www/logs/access.log vhosts; error_log ${CHROOTPATH}/www/logs/error.log info; location = /fpm-status { fastcgi_pass 127.0.0.1:${PORT}; include fastcgi.conf; allow 127.0.0.1; deny all; } location / { root ${CHROOTPATH}/www/docroot; } location ~ \.php$ { try_files $uri =404; root ${CHROOTPATH}/www; fastcgi_pass 127.0.0.1:${PORT}; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; fastcgi_param DOCUMENT_ROOT /; fastcgi_index index.php; include fastcgi_params; } } EOF_NGINX_TPL ) echo "===> 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=<user> /home/<user> /bin/bash