Maintenir Nginx à jour sur un vieux tromblon

Nginx est le serveur Web le plus utilisé, juste devant Apache et ces deux programmes «motorisent» à eux seuls 2/3 des sites Web.

Apache, tout comme Nginx,  peut être utilisé comme «reverse-proxy». Mais Nginx est bien plus efficace, performant et facile à configurer dans ce cadre.

Une machine virtuelle ou un conteneur Nginx peut donc être utilisée comme frontal de nombreux sites Web non routés sur Internet. L’intérêt est multiple: cela permet d’avoir de nombreux sites (pas forcément sur le même domaine) sur une seule IPv4/IPv6, les sites ne sont pas directement accessibles et le proxy peut filtrer les requêtes, il peut être utilisé comme mandataire TLS. C’est en quelque sorte une  «gare de triage» pour des requêtes HTTP, HTTPS (merci SAN et SNI) mais aussi  TCP et UDP !

Un frontal qui n’exécute rien d’autre qu’un serveur Web qui assure la fonction de proxy ne craint pas grand chose (il n’interprète pas de code PHP ou autres). Les possibilités d’attaque sont très faibles et il est acceptable d’avoir des uptimes de plusieurs années sur des OS obsolètes … du moment que le principal intéressé (Nginx) soit à jour (ainsi que tous les composants dont il dépend).

Le script suivant télécharge, compile et installe Nginx et ses dépendances en statique:

#!/bin/bash

# Compilation et installation de Nginx + OpenSSL/PCRE/ZLIB statiques
# pour une utilisation en reverse-proxy HTTP/HTTPS/TCP/UDP

mkdir -p nginx-static
cd nginx-static

##################################################

NGINX_VERSION="1.22.1"
FAKE_NGINX_NAME="Microsoft IIS"
SSL_VERSION="1.1.1t"
PCRE_VERSION="10.37"
ZLIB_VERSION="1.2.13"

OPTS="
--with-threads
--with-http_ssl_module
--with-http_v2_module
--with-http_stub_status_module
--with-http_sub_module
--with-http_auth_request_module
--with-stream
--with-stream_ssl_module
--with-stream_ssl_preread_module
--with-openssl=../openssl-${SSL_VERSION}
--with-pcre=../pcre2-${PCRE_VERSION}
--with-zlib=../zlib-${ZLIB_VERSION}
--with-http_gzip_static_module
--add-module=../headers-more-nginx-module
"

##################################################

apt-get -y install build-essential git

##################################################

[ -d nginx ] || mkdir nginx
cd nginx

##################################################

[ -f nginx-${NGINX_VERSION}.tar.gz ] || wget "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz"
tar -xzf nginx-${NGINX_VERSION}.tar.gz

if [ -d headers-more-nginx-module ] ; then
  cd headers-more-nginx-module
  git pull https://github.com/openresty/headers-more-nginx-module.git
  cd ..
else
  git clone https://github.com/openresty/headers-more-nginx-module.git
fi

[ -f openssl-${SSL_VERSION}.tar.gz ] || wget "http://www.openssl.org/source/openssl-${SSL_VERSION}.tar.gz"
[ -d openssl-${SSL_VERSION} ] && rm -rf openssl-${SSL_VERSION}
tar -xzf openssl-${SSL_VERSION}.tar.gz

[ -f pcre2-${PCRE_VERSION}.tar.gz ] || wget "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-${PCRE_VERSION}/pcre2-${PCRE_VERSION}.tar.gz"
[ -d pcre2-${PCRE_VERSION} ] && rm -rf pcre2-${PCRE_VERSION}
tar -xzf pcre2-${PCRE_VERSION}.tar.gz

[ -f zlib-${ZLIB_VERSION}.tar.gz ] || wget "http://zlib.net/zlib-${ZLIB_VERSION}.tar.gz"
[ -d zlib-${ZLIB_VERSION} ] && rm -rf zlib-${ZLIB_VERSION}
tar -xzf zlib-${ZLIB_VERSION}.tar.gz

##################################################

cd nginx-${NGINX_VERSION}

sed -i "s/<center>nginx<\/center>/<center>${FAKE_NGINX_NAME}<\/center>/g" src/http/ngx_http_special_response.c

make clean

./configure --prefix=/usr/local/nginx-static ${OPTS}
make -j $(( $(grep -c ^processor /proc/cpuinfo) + 1 ))

[ $? -eq 0 ] || { echo "erreur compilation" ; exit 1 ; }

make install

##################################################

service nginx stop
PIDS=$(ps awx |grep " nginx: " |grep -v grep |awk '{print $1}')
[ "${PIDS}" = "" ] || kill ${PIDS}

grep -q "^DAEMON=" /etc/default/nginx || cat<<EOT>>/etc/default/nginx
DAEMON="/usr/local/nginx-static/sbin/nginx"
DAEMON_OPTS="-c /etc/nginx/nginx.conf"
EOT

##################################################

service nginx start

cd ..

 

Ada Lovelace : La 1ère Geek informaticienne !

Il y a quelques temps, pendant une session Hacklab, on m’a parlé de Ada Lovelace (1815-1852) qui est considéré comme la 1ère programmeuse de l’histoire de l’informatique.

Et la coïncidence à fait que j’ai fait mes premiers pas avec le langage Ada (nommé à son honneur) pendant le FOSDEM 2023.
Ainsi, pour en savoir plus, je vous recommande les émissions radios suivantes :
Ada Lovelace, la grande ordinatrice
Ada Lovelace : « Je produirai une poésie mathématique »
Ada Lovelace, la toute première programmeuse
Nouveau monde. Le code informatique est né grâce à Ada Lovelace au… XIXe siècle ! :
Ada Lovelace est à l’origine de la création du 1er programme informatique

FOSDEM 2023

Le FOSDEM est la rencontre Européenne des développeurs de logiciel libre, cette manifestation se déroule tous les ans le 1er week-end de février à l’Université Libre de Bruxelles.
Thierry, Samuel, Daniel, Vivian et Michaël ont pu assister à des conférences plus ou moins techniques. Nous avons eu l’occasion de rencontrer Vincent et Eric du Graoulug
Voici donc quelques photos du FOSDEM 2023

Documentaire sur Arte sur Hedy Lamarr

Ce soir de 23h05 à 00h30, sur Arte, il y a un documentaire sur Hedy Lamarr :
Hedy Lamarr : From Extase to Wifi

https://www.programme-tv.net/cinema/11967341-hedy-lamarr-from-extase-to-wifi/

Continue la lecture

filtre fail2ban pour DokuWiki

Comme vous le savez, dokuwiki est le wiki par excellence. Il permet de créer des wiki pour les geeks que nous sommes. Il est léger, réactif, et il est de bon goût pour tout geek d’en posséder un.

Le revers de la médaille étant que sa notoriété fait qu’il devient la cible d’attaques en tout genre.

On trouve dans le fichier /var/log/apache2/access.log de nombreuses lignes telles que

149.62.41.158 – – [14/Jan/2023:18:52:09 +0100] « GET /titiwiki/doku.php?do=register HTTP/1.1 » 200 8668 « https://escola.fr/titiwiki/doku.php?id=%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D0%BB%D1%81%D1%8F-%D1%80%D1%82%D1%83%D1%82%D0%BD%D1%8B%D0%B9-%D0%B3%D1%80%D0%B0%D0%B4%D1%83%D1%81%D0%BD%D0%B8%D0%BA_-%D1%80%D0%B5%D1%88%D0%B8%D0%BB%D0%B0-%D1%81%D0%BE&do=login&sectok= » « Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36 Vivaldi/5.3.2679.68 »

C’est un peu obscure, je n’ai d’ailleurs pas tenté de creuser le pourquoi de cette ligne de log, mais le résultat de ce type d’attaque a été que mon serveur a servi de passerelle de spam pendant quelques jours.

Comme j’ai déjà un fail2ban d’installé sur ma machine, pour bannir les tentatives d’accès à SSH et à l’administration de WordPress, j’ai décidé de créer un filtre supplémentaire pour bannir les machines qui ont tenté de se logguer sur mon DokuWiki de cette manière.

Tout d’abord on crée le jail

#nano /etc/fail2ban/jail.d/dokuwiki.conf
[dokuwiki]
# To use more aggressive modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
enabled = true
mode = aggressive
port = http,https
filter = dokuwiki
action = iptables-multiport[name=DOKUWIKI, port="http,https", protocol=tcp]
logpath = /var/log/apache2/access.log
maxretry = 1
bantime = 4w

il y a ici un réglage simplifié qui fonctionne, on peut le tweaker bien plus, mais je vous laisse le loisir de consulter la documentation.

Pour résumer : on vérifie le fichier de log d’Apache, on bannit à 1 seule tentative, pendant 4 semaines, en utilisant le filtre dokuwiki qu’il faut créer

#nano /etc/fail2ban/filters.d/dokuwiki.conf
[Definition]
failregex = ^<HOST> .*(GET|POST) .*/titiwiki/doku\.php.*(%%.*){10,}.*
ignoreregex =

La seule chose étant une expression régulière, alias  Regex, qui stipule qu’on détecte un GET ou un POST suivi d’un /titiwiki/doku.php puis un minimum de 10 fois le caractère % entrecoupés d’autres caractères.

une fois ces fichiers créés, on peut faire le test

#fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/dokuwiki.conf 
Results
=======
Failregex: 470 total
|- #) [# of hits] regular expression
| 1) [470] ^<HOST> .*(GET|POST) .*/titiwiki/doku\.php.*(%.*){10,}.*

On voit bien qu’il à a eu 470 correspondances entre la regex et le fichier access d’Apache.

#fail2ban reload dokuwiki
va charger ce filtre dans dokuwiki
#fail2ban status dokuwiki
au bout de quelques heures va donner

Status for the jail: dokuwiki
|- Filter
| |- Currently failed: 0
| |- Total failed: 59
| `- File list: /var/log/apache2/access.log
`- Actions
|- Currently banned: 587
|- Total banned: 587
`- Banned IP list: 103.41.106.199 135.181.74.243 139.59.186.196

et je vous fais grâce des 587 IP qui ont été bannies