====== Apache2 ====== ===== Catch-all ===== Lien: http://michauko.org/blog/2012/03/28/catch-all-dns-virtualhost-et-on-fait-mumuse-avec-les-noms-de-sous-domaines/ " Catch-all DNS, VirtualHost et on fait mumuse avec les noms de sous-domaines " ... a suivre. ===== Stress avec Curl-Loader ===== Liens: * http://www.opensourcetesting.org/performance.php * http://curl-loader.sourceforge.net/doc/faq.html#environment $ cd /usr/local/src $ wget http://downloads.sourceforge.net/project/curl-loader/curl-loader-stable/curl-loader-0.54/curl-loader-0.54.tar.gz $ tar xvzf curl-loader-0.54.tar.gz ==== Dependances ==== # aptitude install make gcc openssl libssl-dev mais aussi: # aptitude install bzip2 patch ==== Compilation ==== $ cd /usr/local/src/curl-loader-0.54 $ make cleanall $ make optimize=1 debug=0 $ su # make install Hu? mkdir -p /usr/bin mkdir -p /usr/share/man/man1 mkdir -p /usr/share/man/man5 mkdir -p /usr/share/doc/curl-loader/ cp -f curl-loader /usr/bin cp -f doc/curl-loader.1 /usr/share/man/man1/ cp -f doc/curl-loader-config.5 /usr/share/man/man5/ cp -f doc/* /usr/share/doc/curl-loader/ cp -rf conf-examples /usr/share/doc/curl-loader/ ... passons. ==== Environment and System ==== Running hundreds and thousands of clients, please, do not forget: - to increase limit of descriptors (sockets) by running e.g. #ulimit -n 10000; - optionally, to set reuse of sockets in time-wait state: by setting #echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle and/or #echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse; A defaut: # ulimit -a ... open files (-n) 1024 ... Ce qui est peu. Donc: # ulimit -n 10000 ==== Exemples de conf ==== En pratique: J'ai fait des tests en utilisant des machines virtuels, dans un reseau virtualisé avec des interfaces "dummy". Les principaux interets: *le reseau est hyper rapide (estimé à 10Gb/s!) puisque tout passe en RAM *ce reseau etant vierge, je suis libre d'y mettre n'importe quoi, y compris 2000 IPs :) Voici une conf de test, largement inspiré de l'exemple "10K.conf". ########### GENERAL SECTION ################################ BATCH_NAME= test CLIENTS_NUM_MAX=10000 CLIENTS_NUM_START=50 CLIENTS_RAMPUP_INC=25 INTERFACE=eth1 NETMASK=17 IP_ADDR_MIN= 192.168.128.32 IP_ADDR_MAX= 192.168.191.255 #Actually - this is for self-control CYCLES_NUM= 5 URLS_NUM= 3 ########### URL SECTION #################################### URL=http://www.thierry-jaouen.fr/index.html URL_SHORT_NAME="www-index" REQUEST_TYPE=GET TIMER_URL_COMPLETION = 1500 # In msec. When positive, Now it is enforced by cancelling url fetch on timeout TIMER_AFTER_URL_SLEEP = 20 ### URL=http://www.thierry-jaouen.fr/cgi-bin/agenda?action=query&year=2012&month=-1&style=gogol-the-first URL_SHORT_NAME="www-agenda" REQUEST_TYPE=GET TIMER_URL_COMPLETION = 5000 # In msec. When positive, Now it is enforced by cancelling url fetch on timeout TIMER_AFTER_URL_SLEEP = 2500 ### URL=http://www.thierry-jaouen.fr/music/Devin_Townsend/Devin_Townsend_-_2011_-_Contain_Us/CD1/01_Synchronicity_Freaks.mp3 URL_SHORT_NAME="www-music" REQUEST_TYPE=GET TIMER_URL_COMPLETION = 5000 # In msec. When positive, Now it is enforced by cancelling url fetch on timeout TIMER_AFTER_URL_SLEEP = 500 ### Donc, on va faire notre test en communicant via eth1 , avec beaucoup d'IP. # curl-loader test.conf Voila. ===== Log Syslog ===== Liens: *http://oreilly.com/pub/a/sysadmin/2006/10/12/httpd-syslog.html *http://zenprog.com/index.php?cle=Surveillance-du-fichier-error.log Envoyer les logs apache ailleurs... On suppose qu'on a deja une conf qui envoi les logs ailleurs, par exemple, un fichier **''/etc/rsyslog.d/maconf.conf''** avec dedans: *.* @ Si on utilise "syslog-ng" ou tout autre service de log qui accepte le tcp (au lieu d'udp): *.* @@ ==== Error ==== Envoyer les ERROR dans les logs: #ErrorLog /var/log/apache2/error.log ErrorLog syslog:local1 Et pour quand même les renvoyer, aussi, en local dans le fichier "error.log", ajouter dans un fichier, par exemple **''/etc/rsyslog.d/apache-error.conf''** avec dedans: local1.* /var/log/apache2/error.log # /etc/init.d/rsyslog restart # apache2ctl graceful ==== Access ==== Dans la conf apache: CustomLog /var/log/apache2/access.log combined # ---- envoi des logs ailleurs... CustomLog |/usr/local/bin/apache_syslog combined Et le script "apache_syslog" contenant: #!/usr/bin/perl use Sys::Syslog qw( :DEFAULT setlogsock ); setlogsock('unix'); openlog('apache', 'cons', 'pid', 'local2'); while ($log = ) { syslog('notice', $log); } closelog Et relancer apache: # apache2ctl graceful ===== nginx ===== Liens: *http://blog.crifo.org/post/2010/03/11/Nginx-en-reverse-proxy *https://calomel.org/nginx.html ==== Installation ==== Vite dit: Installer: # aptitude install nginx Configurer: # cd /etc/nginx/conf.d # vi proxy.conf Et mettre dedans: (adapter) proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; client_header_buffer_size 64k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 16k; proxy_buffers 32 16k; proxy_busy_buffers_size 64k; Dans **''/etc/nginx/nginx.conf''** , apporter les modifs suivantes (adapter!) : # TJ -------------------- # Pour info, source: # http://blog.crifo.org/post/2010/03/11/Nginx-en-reverse-proxy # ----------------------- http { include /etc/nginx/mime.types; access_log /var/log/nginx/access.log; sendfile on; # TJ ------------------- #tcp_nopush on; tcp_nopush on; # --------------------- #keepalive_timeout 0; keepalive_timeout 65; tcp_nodelay on; gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; # TJ ------------------- gzip_comp_level 5; gzip_http_version 1.0; gzip_types text/plain text/xml text/xhtml text/css image/x-icon application/x-javascript; gzip_buffers 16 8k; gzip_min_length 0; gzip_vary on; server_tokens off; # --------------------- include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } Editer le fichier (par exemple, et adapté) **''/etc/nginx/sites-enabled/default''** , pour avoir: # TJ -------------------- server { listen 80; server_name thierry-jaouen.fr www.thierry-jaouen.fr; location / { proxy_pass http://127.0.0.1:8080/; access_log off; } location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|txt|xml|pdf|PDF)$ { root /var/www/thierry-jaouen.fr; access_log /var/log/nginx/thierry-jaouen.fr.access.log; error_log /var/log/nginx/thierry-jaouen.fr.errors.log; expires 30d; } location ~ /\.ht { deny all; } # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/nginx-default; } } # ------------------------- ... L'idée: *apache ecoutera sur le port 8080, en local. *nginx prend la place d'apache en ecoutant tout sur le port 80 *tout ce qui n'est pas caché par nginx et envoyer a apache. # mkdir /var/www/nginx-default Créer un fichier **''50x.html''** , contenant par exemple:

Nginx Error: 50x

Modifier la conf apache afin qu'il n'ecoute que sur le port 8080 en local. Dans **''/etc/apache2/port.conf''** , par exemple: # TJ ------------ #NameVirtualHost *:80 #Listen 80 # pour nginx NameVirtualHost 127.0.0.1:8080 Listen 127.0.0.1:8080 # --------------- Et pour le VirtualHost , par ailleurs: ... etc... Pour que les logs Apache reporte l'IP du client final (et non pas 127.0.0.1): # aptitude install libapache2-mod-rpaf Et voila: # /etc/init.d/apache2 restart # /etc/init.d/nginx restart Avec "rpaf", il faut modifier l'adresse local du proxy en editant "rpaf.conf" , pour par exemple: RPAFproxy_ips ==== Logs ==== Voir plus loin avec webalizer. ==== Tweaks et bugs ==== === Too many open files === Liens: http://www.cyberciti.biz/faq/linux-unix-nginx-too-many-open-files/ Voyons les limites actuelles de "www-data" (ou plutot: de l'utilisateur qui execute "nginx") : # su - www-data $ ulimit -a time(seconds) unlimited file(blocks) unlimited data(kbytes) unlimited stack(kbytes) 8192 coredump(blocks) 0 memory(kbytes) unlimited locked memory(kbytes) 64 process unlimited nofiles 1024 vmemory(kbytes) unlimited locks unlimited Il faut faire au moins faire ça: Augmenter les limites imposés dans **''/etc/security/limits.conf''** , par exemple: # TJ --------------- www-data hard nofile 30000 www-data soft nofile 10000 # ------------------ Si on veut voir le resultat avec un shell (pas indispensable), faire aussi ça, dans **''/etc/pam.d/common-session''** afin d'ajouter: # TJ ------------ session required pam_limits.so # --------------- ... Mais ce n'est pas indispensable pour nginx. On peut vérifier les limits en cours pour un process comme ça: Exemple avec le "pid" de nginx: # cat /proc//limits ... Max open files 1024 1024 files ... Mais il faut encore faire 2 modifs dans **''/etc/nginx/nginx.conf''** : worker_rlimit_nofile 30000; Et dans la section "events": events { # TJ ------------ #worker_connections 1024; worker_connections 10000; # --------------- # multi_accept on; } Voila. ==== https reverse proxy ==== Liens: *http://www.cyberciti.biz/faq/howto-linux-unix-setup-nginx-ssl-proxy/ *http://thomaswabner.wordpress.com/2009/11/17/create-self-signed-multi-domain-certificate/ *http://nginx.org/en/docs/http/configuring_https_servers.html Soit un domain: toto.mondomain.fr export NAME=toto.mondomain.fr openssl genrsa -des3 -out $NAME.key 1024 (entrer une passe phrase provisoire) openssl req -new -key $NAME.key -out $NAME.csr CN:toto.mondomain.fr Virer la pass-phrase: cp $NAME.key $NAME.key.bak openssl rsa -in $NAME.key.bak -out $NAME.key === 1 domaine === Un seul domaine openssl x509 -req -days 3650 -in $NAME.csr -signkey $NAME.key -out $NAME.crt Les clefs sont prêtes. === multi-domaine === Lien: http://thomaswabner.wordpress.com/2009/11/17/create-self-signed-multi-domain-certificate/ Il faut mettre plusieurs domaines dans le certificat de la facon suivante: Créer un fichier "$NAME.domain_extensions.txt" contenant : [ mydomain_http ] nsCertType = server keyUsage = digitalSignature,nonRepudiation,keyEncipherment extendedKeyUsage = serverAuth subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer subjectAltName = @mydomain_http_subject [ mydomain_http_subject ] DNS.1 = sub1.mondomain.fr DNS.2 = sub2.mondomain.fr ... etc ... DNS.x = xxxx.mondomain.fr Et enfin openssl x509 -req -days 3650 -in $NAME.csr -signkey $NAME.key -out $NAME.crt -extfile $NAME.domain_extensions.txt -extensions mydomain_http Et voila: tout les domaines "DNS.1" a "DNS.x" sont associés aux clefs. | :!: Il serai aussi possible d'utiliser "*.mondomain.fr" | === nginx === FIXME : Un exemple, mais je n'ai pas tout compris... server { listen 443; server_name .thierry-jaouen.fr .tjaouen.fr; ssl on; ssl_certificate /etc/nginx/ssl/thierry-jaouen.fr.crt; ssl_certificate_key /etc/nginx/ssl/thierry-jaouen.fr.key; keepalive_timeout 60; location / { proxy_pass http://wwwcave.local.eez.fr:80/; access_log off; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; ### Set headers #### proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ### Most PHP, Python, Rails, Java App can use this header ### proxy_set_header X-Forwarded-Proto https; ### By default we don't want to redirect it #### proxy_redirect off; } } Le "https" est alors géré entre le client et **''nginx''** . **MAIS** , entre **''nginx''** et le serveur apache, ce n'est que du **''http''** . C'est pour cela que le flag "X-Forwarded-Proto https" est fixé. Ainsi, pour vos règles de **''rewrite''**, par exemple: Remplacer: | **''RewriteCond %{SERVER_PORT} !^443$''** | par | **''RewriteCond %{HTTP:X-Forwarded-Proto} !^https$''** | ===== Apache HA ===== Apache haute-disponibilité ? Liens: * http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/ * http://www.pavnay.fr/index.php/fr/administration-systeme/10-sys-cluster-ip ===== Apache Load balancing ===== Liens: *http://www.bastien-louche.fr/2010/05/configuration-cluster-apache-2-haproxy/ *http://www.pavnay.fr/index.php/fr/administration-systeme/10-sys-cluster-ip ===== Optimiser ===== Liens: *http://www.devside.net/articles/apache-performance-tuning *http://www.queret.net/blog_old/post/2009/04/30/Apache2-%3A-Utiliser-apache2-%28-2.1%29-en-repartiteur-de-charge-/-load-balanceur-%28mod_proxy-mod_proxy_balancer%29 *http://mdvmondelinux.tuxfamily.org/Optimisation-de-serveur-Apache ===== auth ===== Plein de bonne manière de s'authentifier sur apache, en francais: *http://artisan.karma-lab.net/node/22 ===== PAM ===== ==== mod-auth-pam === Liens: *http://pam.sourceforge.net/mod_auth_pam/configure.html *http://www.cyberciti.biz/tips/howto-deny-allow-linux-user-group-login.html # aptitude install libapache2-mod-auth-pam Comme ce n'est pas dit dans la doc, je le dis ici: Il faut ajouter "www-data" dans le group shadow: # adduser www-data shadow ... afin qu'il puisse lire (peut être pas directement) le fichier **''/etc/shadow''** . | :!: "mod-auth-pam" serait déprécié, du fait de son accès trop direct a "shadow": mais pour l'heure, pas de remplacant ! | Pas besoin d'activer ce module, il l'est automatiquement... ==== Directory ==== AuthType Basic AuthName "Restricted area for My Server" AuthPAM_Enabled On AuthPAM_FallThrough off AuthBasicAuthoritative off AuthUserFile /dev/null Require valid-user Satisfy All Ne pas oublier: **''Require valid-user''** :)) Aprés un **''apache2ctl graceful''** , :!: **ATTENTION** :!: C'est l'ensemble des comptes qui vont être autorisé a se connecter ... ! Et ça ne me plait pas !!! voir la section suivante... ==== PAM et group ==== On va autoriser uniquement certains groupes, mais surement pas tous. Pour cela, il faut d'abord changer la conf dans **''/etc/pam.d/apache2''** , afin d'avoir: # TJ ------------ auth required pam_listfile.so onerr=fail item=group sense=allow file=/etc/login-pam-apache-group.allowed # --------------- @include common-auth @include common-account ... et il faut creer un fichier contenant la liste des groupes, là: **''/etc/login-pam-apache-group.allowed''** , avec dedans: users webfriends nolife Je n'autorise que ces 3 groups. ====== Installation ====== ===== avec Perl ===== # aptitude update # aptitude install apache2 libapache2-mod-perl2 ==== apache2 et inetd ==== Aprés lecture, il s'avere qu'Apache2 ne peut que fonctionner en "daemon". Cela viendrait du "Prefork" et autres pour optimiser le temps de reponse.\\ On ne peut que limiter les ressources utiliser par le daemon. ===== logs ===== # mkdir logs # chown www-data: logs ===== Perl Templates ===== Lien: http://perl.enstimac.fr/ModulesFr/Html-Template.html Pour **''HTML::Template''** # aptitude install libhtml-template-perl C'est quoi la version: $ perl -MHTML::Template -e 'print $HTML::Template::VERSION' 2.9 ===== Perl CGI Plugin ===== | :!: Preferer l'installation par cpan ! version moins buggée | # apt-get install libcgi-application-plugins-perl Ou plus simplement: # aptitude install libcgi-session-perl Ce qui installe (entre autres!) **''CGI::Session''** : $ perl -MCGI::Session -e 'print $CGI::Session::VERSION' 4.20 ===== CGI::Carp::DebugScreen ===== # cpan -i CGI::Carp::DebugScreen Version installé (applicable a d'autres modules bien sur): $ perl -MCGI::Carp::DebugScreen -e 'print $CGI::Carp::DebugScreen::VERSION' 0.14 ==== Desinstaller ==== Desinstaller le module cpan... D'abord, trouver où ils sont installé (compilé en fait).\\ Moi c'est la: /root/.cpan On va dans: # cd /root/.cpan/build/CGI-Carp-DebugScreen-0.14 Et puis: # make uninstall | :!: En fait, ca ne marche pas ... il faut bricoler! | ===== mod_perl 1 puis 2 ===== Renommage de "mod_perl" pour "Apache2". *http://perl.apache.org/docs/2.0/rename.html *http://perl.apache.org/docs/2.0/user/porting/porting.html Solution: Dans ''httpd.conf'' ou ailleurs, ajouter: # TJ # -------- PerlModule Apache2::compat # -------- Dans les scripts Perl, mettre en commentaire les chargements de package "Apache.pm" et mettre plutot: #use Apache (); #use Apache::Constants qw( OK ); #use Apache2::compat; use Apache2::Const qw( OK ); Il ne faut pas rever: On ne compile pas avec "use Apache2::compat" a cause de recurrent: Can't locate object method "header_in" via package "Apache2::RequestRec" ... ====== Anti DoS ou evasive ====== Protection contre DoS, etc ... Liens: *http://www.bortzmeyer.org/limit-apache.html *http://www.debianadmin.com/how-to-protect-apache-against-dosddos-or-brute-force-attacks.html ====== webalizer ====== ===== Installation ===== ==== webalizer.conf ==== # aptitude install webalizer Configurer en adaptant le fichier **''/etc/webalizer/webalizer.conf''** : En dehors du "hostName", on ajoute: # TJ ------------- #Incremental no Incremental yes # ---------------- Afin qu'on puisse faire plusieurs traitements sur des gros logs, quotidiennement. On a rien d'autres a faire pour l'instant et le fichier **''/var/log/apache2/access.log.1''** existe et "attend" son traitement. # /etc/cron.daily/webalizer Et voila. Le répertoire **''/var/www/webalizer''** contient des fichiers. ==== Apache ==== La racine du site est dans **''/var/www/webalizer''** . Dans la conf apache, on peut ajouter un truc comme ça: # Webalizer -------------- Alias /webalizer /var/www/webalizer Options +FollowSymLinks AllowOverride None order deny,allow deny from all allow from 127. allow from AuthName "access restreint" AuthUserFile /var/lib/passwd-www/webalizer_htpasswd AuthGroupFile /dev/null AuthType Basic require valid-user # soit "allow" , soit "Auth" est suffisant pour autoriser l'acces... Satisfy Any # mkdir -p /var/lib/passwd-www (Avec **''-c''** en option la 1er fois pour créer le fichier) # htpasswd -c /var/lib/passwd-www/webalizer_htpasswd New password: Re-type new password: Adding password for user # apache2ctl graceful Mais la 1er fois, il est vide ce répertoire: donc on le remplir avec un 1er traitement des logs. Mais d'abord: configurer "webalizer" himself. ==== Log Apache et nginx ==== Liens: *http://www.cyberciti.biz/faq/unix-linux-merging-multiple-access-logs-with-logfile-merger/ === vite dit === # aptitude install awstats Pour récuperer le scripte: /usr/share/awstats/tools/logresolvemerge.pl Donc: # ln -s /usr/share/awstats/tools/logresolvemerge.pl /usr/local/bin On doit merger les logs nginx et apache pour que webalizer soit juste correct. Exemple: # mkdir /labo # cd /labo # cp /etc/webalizer/webalizer.conf . Modifier **''webalizer.conf''** et commenter la ligne "LogFile". # logresolvemerge.pl /var/log/nginx/thierry-jaouen.fr.access.log.1 /var/log/apache2/access.log.1 | webalizer - Et voila. On a merge et on envoyer directement le flow en traitement pour webalizer... | :!: les fichiers mergés doivent couvrir la __même période__ de temps !!! | ... la dernière date traité faisant office de point de départ pour le fichier suivant. (toutes les dates anterieures étant ignoré) === en pratique === Soit les rotations de logs **''nginx''** et **''apache''** en "daily" (ou en weekly, mais identique) Soit : - **''nginx''** qui génère des logs, et a la rotation quotidienne: ''/var/log/nginx/thierry-jaouen.fr.access.log.1'' - **''apache''** qui génère des logs, et à la rotation quotidienne: ''/var/log/apache2/access.log.1'' Soit dans **''webalizer.conf''** dans ''/usr/local/etc'' et contenant essentiennellement. # pas de ligne "LogFile" Incremental yes Soit dans **''/etc/cron.daily/''** un fichier nommé **''webalizer-update''** et contenant: #!/bin/sh /usr/local/bin/webalizer-update Soit un script nommé **''webalizer-update''** dans ''/usr/local/bin'' et contenant: #!/bin/sh # -------------------------------------------- # - La conf est dans /etc/webalizer/webalizer.conf !!! # - La ligne "LogFile" est ignoré au profit de STDIN # - Desactiver/modifier le "cron.daily/webalizer" afin d'executer ce script # -------------------------------------------- NAME=`basename $0` WEBALIZER=/usr/local/bin/webalizer MERGE=/usr/share/awstats/tools/logresolvemerge.pl STAT=/usr/bin/stat AWK=/usr/bin/awk # ------------------------------------ # Les fichiers de LOGS a "merger" # ------------------------------------ LOGS="/var/log/nginx/thierry-jaouen.fr.access.log.1 /var/log/apache2/access.log.1" logger -t ${NAME} "start ..." # Verifions l'existance des binaires principaux if [ ! -x ${WEBALIZER} ] || [ ! -x ${MERGE} ] ; then echo "${WEBALIZER} or ${MERGE} missing" >&2 exit 1 fi # Verifier l'ecart de temps entre les 2 (premiers?) fichiers (2?) if ! EPOCHs="$( ${STAT} --printf='%Z ' ${LOGS} )" ; then echo "ERREUR: MERGE webalizer non effectué" >&2 exit 1 fi # ecart en secondes entre les dates de modifications des 2 fichiers (valeur absolue) DIFFS=$( echo ${EPOCHs} | ${AWK} -F' ' '{ diff=$2-$1; diff=(diff<0?-diff:diff); printf "%ld", diff; }' ) # On tolere 120 secondes, soit 2 minutes if [ ${DIFFS} -ge 120 ]; then echo -e "ERREUR!\nEcart de ${DIFFS} secondes entre les fichiers:\n${LOGS}\nMERGE webalizer non effectué\n" >&2 exit 1 fi # Sinon Ok. logger -t ${NAME} "running... ${LOGS}" ${MERGE} ${LOGS} | ${WEBALIZER} -c /usr/local/etc/webalizer.conf - logger -t ${NAME} "end." # -------------- # EOF Que fait ce script ? - il verifie que l'essentiel pour s'executer est en place - que l'ecart de date de modification entre les 2 fichiers n'est pas énorme (sinon, y a surement une rotation qui ne se fait pas) - merge et import des données dans webalizer ===== Compilation ===== Suite a un bug curieux, reproductible a volonté, me voila a chercher une version "recente" de webalizer. D'abord, virer la version installé: :!: Faire des copies de sauvegarde de /etc/webalizer/*conf /var/www/webalizer Tout va disparaitre: # dpkg -P webalizer Télécharger la dernière version "stable": $ cd /usr/local/src $ wget ftp://ftp.mrunix.net/pub/webalizer/webalizer-2.23-05-src.tgz $ tar xvzf webalizer-2.23-05-src.tgz $ cd webalizer-2.23-05 Dépendances: $ su # aptitude install gcc make libz-dev libpng-dev libgd2-noxpm-dev # exit $ ./configure $ make $ su # make install L'executable s'installe dans : /usr/local/bin On mettra la conf dans: /usr/local/etc Et voila ? Bug corrigé. ====== Music ====== Permettre l'accés a ma musique, juste pour moi bien sur. ===== module ===== ==== package ==== # aptitude install libapache2-mod-musicindex ... Les NOUVEAUX paquets suivants vont être installés : libapache2-mod-musicindex libarchive1 libflac7 libid3tag0 libmad0 libogg0 libvorbis0a libvorbisfile3 mod-musicindex-common ... Paramétrage de libapache2-mod-musicindex (1.1.3-4) ... ==== Activer ==== # a2enmod musicindex ===== site www ===== Composer un hôte virtuel comme ca (exemple) : ServerName music.thierry-jaouen.fr ServerAdmin webmaster@localhost DocumentRoot /mnt/music Order deny,allow deny from all Order deny,allow deny from all allow from .thierry-jaouen.local AuthName "access restreint" AuthUserFile AuthGroupFile /dev/null AuthType Basic require valid-user # soit "allow" , soit "Auth" est suffisant pour autoriser l'acces... Satisfy Any Options Indexes MultiViews FollowSymlinks AllowOverride Indexes MusicSortOrder album disc track artist title length bitrate freq filet$ MusicFields title artist length bitrate # ------------ voir commentaire --------- MusicLister On MusicAllowDownload Off MusicAllowStream On MusicAllowSearch On # MusicRssItems Off # --------------------------------------- MusicPageTitle titi #MusicCssDefault musicindex.css #MusicCachePath /tmp/musicindex # MusicIceServer [ice.domain.my]:8000 # MusicCookieLife 300 ErrorLog /var/log/apache2/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/log/apache2/access.log combined ServerSignature On | :!: Depuis "Debian Lenny" , le module "musicindex" a changé | Dans le cas de "Lenny" et "musicindex version 1.2.2-3", il faut plutot mettre certains paramètres comme cela: MusicIndex On +Stream +Search +Download -Rss -Tarbal Au lieu de : MusicLister On etc... Le **''''** est composé avec **''htpasswd''** et ce place, là ou vous pouvez. Ensuite, on active le nouveau site: # a2ensite 220-titi-music.conf Et on relance apache2: # apache2ctl graceful Et on regarde dans **''http://music.thierry-jaouen.fr''** ====== Rewrite ====== Invalid command 'RewriteEngine' Il faut activer le module: # a2enmod rewrite ====== Proxy ===== ===== http ===== Invalid command 'ProxyRequests' En conséquence: # a2enmod proxy_http Enabling proxy as a dependency Module proxy installed; run /etc/init.d/apache2 force-reload to enable. Module proxy_http installed; run /etc/init.d/apache2 force-reload to enable. ===== html ===== Liens: *http://www.apachetutor.org/admin/reverseproxies *http://apache.webthing.com/mod_proxy_html30/ *http://wiki.uniformserver.com/index.php/Reverse_Proxy_Server_2 On utilise: ''libapache2-mod-proxy-html 3.0.0-1'' ... et non pas "3.1"... Donc là: http://apache.webthing.com/mod_proxy_html30/config.html "If you are using a mod_proxy_html version older than 3.1, there is no ProxyHTMLEnable directive, and you'll have to insert the filter with Apache's standard directives: for example \\ ''SetOutputFilter proxy-html''\\ " C'est bon a savoir! le module "deflate" peut poser un problème, et il y a plusieurs solutions: *soit le desactiver sur le serveur 'zm' : **''a2dismod deflate''** *soit l'activer sur tout les serveurs ( **''a2enmod deflate''** ) et mettre: **''SetOutputFilter INFLATE;proxy-html;DEFLATE''** (en lieu et place de **''SetOutputFilter proxy-html''**) *soit modifier l'entête en faisant: **''a2enmod headers''** et dans la conf: **''RequestHeader unset Accept-Encoding''** Une conf complète, qui fonctionne, dans la mesure ou le html n'est pas trop tordu :-? ProxyRequests Off Order deny,allow Allow from all RedirectMatch ^/zm$ /zm/ # Simple 1 # ProxyPass /zm/ http://192.168.6.12/ # ProxyPassReverse /zm/ http://192.168.6.12/ # Simple 2 # http://wiki.uniformserver.com/index.php/Reverse_Proxy_Server_2 ProxyPass /zm/ http://192.168.6.12/ ProxyHTMLURLMap http://192.168.6.12 /zm ProxyPassReverse http://192.168.6.12/ # methode 1 #SetOutputFilter proxy-html # methode 2 #SetOutputFilter INFLATE;proxy-html;DEFLATE # methode 3 # avec: # a2enmod headers SetOutputFilter proxy-html RequestHeader unset Accept-Encoding ProxyHTMLURLMap / /zm/ #ProxyHTMLURLMap /zm /zm #ProxyHTMLExtended On ====== Expires ====== ===== Perl ===== Un scripte perl qui retourne un "gif" (ou autres choses), et on ne veut pas que ce soit caché:\\ (En reponse dans le entête HTTP) print "Cache-Control: max-age=0\n"; ===== Module ===== Lien: http://httpd.apache.org/docs/1.3/mod/mod_expires.html En activant un module **''apache''** ... # a2enmod expires Modifier dans l'hôte virtuel (par exemple) ExpiresActive On ExpiresDefault "access plus 1 hour" ExpiresByType image/gif "access plus 0 second" Par defaut, on cache 1 heure (ce qui n'est pas beaucoup en fait).\\ Mais pour les "gif", on ne cache jamais. ====== Fast CGI ====== Lien: * http://www.fastcgi.com/ ===== Quoi ===== C'est un CGI qui est chargé 1 fois, puis execute les requetes au fur et a mesure... ===== Comment ===== ==== mod ==== Installer le module "fastcgi" # apt-get install libapache2-mod-fastcgi Si nécessaire, activer le module avec:\\ (En passant, on jettera un oeil dans ''fastcgi.conf'') # a2enmod fastcgi Si nécessaire, redémarrer **''apache''** : # apache2ctl graceful ==== Perl ==== === Installer === Installer le module Perl "CGI::Fast" # apt-get install libcgi-fast-perl === Exemple === $ vi /var/lib/cgi-bin/example.fcgi #!/usr/bin/perl -w use CGI::Fast qw( :standard ); my $COUNTER = 0; { while( my $q = new CGI::Fast ) { print STDOUT $q->header(); print STDOUT "

Hello World


\n"; print STDOUT "$COUNTER
"; $COUNTER++; } } La 1er requete **''/cgi-bin/example.fcgi''** charge le scripte et pas les suivantes. ===== Probleme ===== * Prendre garde aux fuites de mémoires * Il faut redemarrer apache pour changer les versions des CGI ====== SSI ou SHTML ou INCLUDE ====== Lien: [[http://httpd.apache.org/docs/2.0/howto/ssi.html]] (Existe aussi pour Apache1)\\ Rendre "dynamique" le html, en activant la fonctionnalité SSI (Server Side Includes). ===== shtml ===== Par defaut, Apache2 est presque prêt... Dans des "Directory/Location" de son choix, ajouter: Options +Includes Verifier qu'on a quand même quelque part dans 'apache2.conf': AddType text/html .shtml AddOutputFilter INCLUDES .shtml Donc, maintenant, les fichiers ayant l'extension ".shtml" sont parsé à la recherche de "commande/include" SSI. ===== XBitHack ===== Mais, on prèfere ne pas changer l'extention de ".html", sans, toutefois, activer le SSI pour tout les fichiers ".html" (c'est vivement déconseillé). Dans son "VirtualHost" ou des "Directory/Location" de son choix, ajouter: XBitHack on (Sans oublier le "''Options +Includes''" comme vu ci-dessus) Activer le module "''Include''" : # a2enmod include Et maintenant, tout fichier "''.html''" ayant le bit "''X''" (eXecute) d'activé, seront parsé à la recherche d'instruction SSI. Exemple:
====== Apache2 et SSL ====== Liens: * http://www.narno.com/blog/debian-apache2-ssl * http://thenico.fr.eu.org/site/inico/index.php?2007/07/06/77-virtual-host-avec-ssl-sous-apache-2-avec-une-seule-adresse-ipv4 * http://xhtml.net/articles/subversion-apache2-debian ===== Certificat ===== | Vite dit: il y aurait beaucoup plus simple avec: make-ssl-cert /usr/share/ssl-cert/ssleay.cnf apache.pem | NAME=le nom que vous voulez Choisissez convenablement le **''Common Name''**, afin qu'il soit le nom du site. Exemple: www.mon_site_en_https.com Créer la clef: $ openssl req -new > $NAME.csr Enlever la passphrase: (sinon, elle sera demandé au demarrage d'apache) $ openssl rsa -in privkey.pem -out $NAME.key Creation du certificat (.crt) et de la clef (.key): $ openssl x509 -in $NAME.csr -out $NAME.crt -req -signkey $NAME.key -days 3650 Valable pour moins de 10 ans... Et voila, on a: - $NAME.crt - $NAME.key Copier les clefs quelques parts (et effacer les relicats de la création): # mkdir /etc/apache2/ssl.crt # mkdir /etc/apache2/ssl.key # chmod 700 /etc/apache2/ssl.key # mv ..../$NAME.crt /etc/apache2/ssl.crt/ # mv ..../$NAME.key /etc/apache2/ssl.key/ ===== module SSL ===== Si nécessaire, activer le module SSL en faisant: # a2enmod ssl Ou en creant les liens symboliques qui vont bien pour avoir: /etc/apache2/mods-enabled# ls -lart ... lrwxrwxrwx 1 root root 26 2007-07-28 16:56 ssl.load -> ../mods-available/ssl.load lrwxrwxrwx 1 root root 26 2007-07-28 16:56 ssl.conf -> ../mods-available/ssl.conf ... Sauf erreur, rien a toucher dans **''ssl.conf''** . ===== https ===== Activer l'ecoute sur le port 443 , c'est dire **''https''** . # vi /etc/apache2/ports.conf Et ajouter: Listen 443 ===== VirtualHost ===== Lien: http://httpd.apache.org/docs/2.2/fr/vhosts/examples.html ==== vite ==== Créer un VirtualHost, en prenant garde d'avoir ça (si necessaire): NameVirtualHost *:80 NameVirtualHost *:443 # FACULTATIF # # Si declaré, c'est l'hote par defaut si aucun autre ne correspond # # Sinon, c'est le 1er "virtualhost" qui recupere la requete. # # NE PAS METTRE DE "servername" ou "serveralias" ... etc... # www via http ServerName www.thierry-jaouen.fr ServerAlias thierry-jaouen.fr tjaouen.fr www.tjaouen.fr ServerAdmin webmaster@localhost DocumentRoot /... ... etc ... ServerName myblog.thierry-jaouen.fr ... etc ... ServerName blackhole.thierry-jaouen.fr ... etc ... # www via https SSLEngine on SSLCertificateFile /etc/apache2/ssl.crt/$NAME.crt SSLCertificateKeyFile /etc/apache2/ssl.key/$NAME.key ServerAdmin webmaster@localhost DocumentRoot /... ... etc ... ==== IP ==== Toutefois, il semblerait que l'emploi du joker "*" est inapproprié si on a une IP fixe... Ok, mais dans ce cas, la notion de "VirtualHost _default_" disparait, ou dumoins, ne fonctionne plus.\\ Il faut alors créer , en tête de configuration, un "VirtualHost" comme ca: NameVirtualHost 192.168.0.123:80 # "_default_" en quelque sorte... ... etc ... ServerName www.thierry-jaouen.fr ...etc... Il m'a fallu quelques heures pour comprendre... :-x ====== ImageMagick ====== ===== PerlMagick ===== ==== install ==== # aptitude install perlmagick ==== STDOUT ==== La doc donne cette manière d'envoyer l'image dans STDOUT: binmode STDOUT; print STDOUT "Content-type: image/jpeg\r\n\r\n"; $image->Write( 'jpeg:-' ); Mais dans un cgi, et peut être a cause de "Mod Perl" (d'aprés cette [[http://www.gossamer-threads.com/lists/modperl/modperl/97637|note]]), ca ne fonctionnera pas, et de façon sournoise. La solution: Utiliser les "Blob" ! binmode STDOUT; print STDOUT "Content-type: image/jpeg\r\n\r\n"; print STDOUT ( $image->ImageToBlob() )[0]; ou en plus lisible: my @blobs = $image->ImageToBlob(); binmode STDOUT; print STDOUT "Content-type: image/jpeg\r\n\r\n"; print STDOUT $blobs[0]; :!: En fait, "binmode STDOUT" est superflu dans un cgi :!: Préablement à génération du "blob", il peut être necessaire de préciser le format et les attributs souhaités ! $image->Set( quality=>85, magick => 'jpeg' );