Tag - linux

Entries feed

Sunday, September 8 2019

Installer un serveur TURN/STUN pour Talk@Nextcloud

L'application "Talk" de Nextcloud gagne toujours plus en maturité à chaque nouvelle version. Pour en profiter pleinement, il est nécessaire de paramétrer un serveur TURN/STUN dans la page de configuration du module Talk de Nextcloud.

Nous allons voir ici comment installer un serveur TURN/STUN sous Debian Buster.

On commence, sans originalité, par installer le paquet :

apt install coturn

Et on le configure dans /etc/turnserver.conf :

tls-listening-port=5349
fingerprint
use-auth-secret
static-auth-secret=secretkey
realm=turn.monurl.tld
total-quota=100
bps-capacity=0
stale-nonce
cert=/etc/turnserver/cert.pem
pkey=/etc/turnserver/privkey.pem
cipher-list="ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
no-loopback-peers
no-multicast-peers

Conformément à ce que nous venons d'écrire dans le fichier de configuration, il faut alors ouvrir le port 5349 de l'éventuel pare-feu, par exemple si on utilise nftables en ajoutant cette ligne dans /etc/nftables.conf :

tcp dport 5349 accept

Il convient également de rendre la clé et le certificat permettant le chiffrement accessibles à l'utilisateur turnserver dans /etc/turnserver/*.pem. Si les certificats ont été obtenus avec letsencrypt, on pourra par exemple effectuer les commandes suivantes :

mkdir /etc/turnserver
cp /etc/letsencrypt/live/turn.monurl.tld/privkey.pem /etc/turnserver/
cp /etc/letsencrypt/live/turn.monurl.tld/cert.pem /etc/turnserver/
chmod a+r /etc/turnserver/privkey.pem
systemctl restart turnserver

Il sera nécessaire de répéter les opérations ci-dessous à chaque mise à jour du certificat et de la clé privée par let's encrypt (ou votre fournisseur de certificat TLS) !

Le serveur TURN/STUN doit alors être fonctionnel !

Saturday, September 7 2019

Asus UX331 et Debian Buster : tout fonctionne parfaitement

À l'achat d'un nouvel ordinateur, tous les utilisateurs de Linux s'interrogent sur le support complet de la machine qu'ils visent par leur distribution préférée. Je n'échappe pas à ce questionnement (fort légitime). Je partage donc ici mon retour d'expérience sur l'installation de Debian Buster sur un ordinateur Asus Zenbook UX331.

Tout fonctionne parfaitement pendant et après l'installation sauf le Wifi qui nécessite un firmware non libre non disponible dans l'installateur. Il est toutefois possible de fournir à l'installateur le firmware à l'aide périphérique amovible avec le fichier en cours d'installation ou bien il faut installer avec un adaptateur Ethernet <-> USB reconnu par Linux.

Principaux points :

  • affichage : écran parfaitement reconnu, la luminosité est correctement contrôlée par les touches ad-hoc du clavier
  • son : parfaitement reconnu, en revanche les touches "volume +" et "volume -" du clavier ne fonctionnent pas
  • rétro-éclairage du clavier : totalement fonctionnel et réglable avec les touches du clavier
  • wifi : pleinement fonctionnel après installation du package "firmware-misc-nonfree"
  • touchpad : pleinement fonctionnel sauf la touche de désactivation du touchpad
  • lecteur d'empreinte : non testé
  • la mise en veille (suspend) et en hibernation se fait sans problème

Au final, absolument rien de bloquant ou de gênant au quotidien ! Ah si, une petite particularité à laquelle il faut s'habituer : la batterie est équipée d'un système de prévention de son usure et donc par défaut la batterie ne se recharge que lorsqu'elle est descendue en-dessous de 80%. Autrement dit, branchée au secteur alors qu'elle se trouve à 88% de charge, la batterie ne bouge pas. Il existe un utilitaire sous Windows pour régler ce comportement. Cela n'existe pas à ma connaissance sous Linux.

Voici ce que rapporte lspci :

00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (rev 08)
00:02.0 VGA compatible controller: Intel Corporation UHD Graphics 620 (rev 07)
00:04.0 Signal processing controller: Intel Corporation Skylake Processor Thermal Subsystem (rev 08)
00:14.0 USB controller: Intel Corporation Sunrise Point-LP USB 3.0 xHCI Controller (rev 21)
00:14.2 Signal processing controller: Intel Corporation Sunrise Point-LP Thermal subsystem (rev 21)
00:15.0 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #0 (rev 21)
00:15.1 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #1 (rev 21)
00:16.0 Communication controller: Intel Corporation Sunrise Point-LP CSME HECI #1 (rev 21)
00:17.0 SATA controller: Intel Corporation Sunrise Point-LP SATA Controller [AHCI mode] (rev 21)
00:1c.0 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #5 (rev f1)
00:1c.5 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #6 (rev f1)
00:1e.0 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO UART Controller #0 (rev 21)
00:1e.2 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO SPI Controller #0 (rev 21)
00:1f.0 ISA bridge: Intel Corporation Sunrise Point LPC Controller/eSPI Controller (rev 21)
00:1f.2 Memory controller: Intel Corporation Sunrise Point-LP PMC (rev 21)
00:1f.3 Audio device: Intel Corporation Sunrise Point-LP HD Audio (rev 21)
00:1f.4 SMBus: Intel Corporation Sunrise Point-LP SMBus (rev 21)
01:00.0 Unassigned class [ff00]: Realtek Semiconductor Co., Ltd. RTS522A PCI Express Card Reader (rev 01)
02:00.0 Network controller: Intel Corporation Wireless 8265 / 8275 (rev 78)

et lsusb :

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 8087:0a2b Intel Corp. 
Bus 001 Device 002: ID 13d3:5a09 IMC Networks 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Sunday, August 25 2019

Prestashop derrière un reverse proxy TLS/SSL

En déployant Prestashop derrière un proxy qui gérait le chiffrement TLS/SSL, j'ai été confronté à un problème de boucle de redirection qui rendait le magasin en ligne inacessible. Le problème a été réglé en exécutant cette modification sur la base de données :

UPDATE ps_configuration SET value='1' WHERE name='PS_SSL_ENABLED';

Configuration de zsh, inspirée de la formation Debian d'Alexis de Lattre

Ceux qui ont débuté sous Debian il y a quelques années ont peut-être découvert la formation Debian d'Alexis de Lattre. Celle-ci a récemment migré vers un nouveau domaine : https://formation-debian.viarezo.fr/ mais il me semble qu'elle n'a plus été mise à jour depuis quelques temps.

Je stocke ici les fichiers de paramétrage de ZSH légèrement modifiés pour tenir compte de ce billet et de ce billet.

On pourra télécharger les fichiers et les placer à l'endroit adéquat du serveur avec cette série de commandes :

wget https://blog.bandinelli.net/public/zshrc
wget https://blog.bandinelli.net/public/zshenv
wget https://blog.bandinelli.net/public/zlogin
wget https://blog.bandinelli.net/public/zlogout
wget https://blog.bandinelli.net/public/dir_colors
mv zshrc zshenv zlogin zlogout /etc/zsh/
mv dir_colors /etc/

LXC 3 sur Debian Buster, "bad template"

Sur une version de Debian Buster fraîchement installée, il était impossible de déployer une instance LXC car aucun template n'était trouvé :

get_template_path: 918 No such file or directory - bad template: debian

Il faut seulement installer les templates de LXC par :

apt install lxc-templates

Wednesday, June 27 2018

Certbot "ImportError: cannot import name jose" on Debian Stretch

I recently ran into the following error when running `certbox renew`:

Traceback (most recent call last):
  File "/usr/bin/certbot", line 11, in <module>
    load_entry_point('certbot==0.19.0', 'console_scripts', 'certbot')()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 561, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2631, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2291, in load
    return self.resolve()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2297, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/lib/python2.7/dist-packages/certbot/main.py", line 11, in <module>
    from acme import jose
ImportError: cannot import name jose

I fixed it by launching the following command:

apt-get install certbot python3-certbot python3-acme python3-cryptography python3-josepy python3-setuptools -f -t stretch-backports

Monday, June 18 2018

Gitlab behind a reverse proxy handling https

I share below my configuration of GitLab when served behind a reverse proxy (haproxy to name it) that is handling the HTTPS part of the communication (and is also load balancing). <Disclaimer> I am not claiming this is the best configuration or the only possible configuration but I can report that it works well</Disclaimer>.

Infrastructure

The network transaction is established as follows:

User <- HTTPS HTTP/2 -> HAPROXY <- HTTP -> NGINX <- HTTP -> Unicorn/GitLab

I will not detail here the configuration of HAProxy which is pretty classical.

Configuration of GitLab

In gitlab.yml (presumably in /home/git/gitlab/config/ if you installed from source), I have the following:

production: &base
    ## Web server settings (note: host is the FQDN, do not include http://)
    host: gitlab.domain.tld
    port: 443
    https: true

And yes I indicate https true and port 445 even if Gitlab itself does not handle the https part of the communication.

Configuration of Nginx

In the config of Nginx (another layer of reverse proxy), I have:

    proxy_set_header    X-Forwarded-Proto   https;

which differs from the configuration proposed by the Gitlab team. Indeed, it does not convey the protocol that is seen by Nginx but rather forces the header to https as initially the communication was https-secured.

And it works flawlessly!

Node et socket.io derrière Apache en Reverse Proxy

Je viens de déployer une application NodeJS basée sur Angular et utilisant socket.io pour communiquer entre le "front-end" et le "back-end". Dans Firefox, je voyais toutefois ce message d'erreur :

Firefox can’t establish a connection to the server at wss://my.app/socket.io/?token=verylongtoken&EIO=3&transport=websocket&sid=verylongsid

et pourtant l'application fonctionnait parfaitement.

Après enquête, il semble que socket.io avait le bon goût de faire un "fallback" sur une méthode AJAX et s'accomodait donc du non établissement du WebSocket.

Pour régler proprement le problème, il fallait :

  • activer le module proxy_wstunnel d'Apache
a2enmod proxy_wstunnel
service apache2 restart
  • puis ajouter ces lignes dans la configuration (attention, le module rewrite d'Apache doit aussi être chargé !)
  RewriteEngine On
  RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
  RewriteCond %{QUERY_STRING} transport=websocket    [NC]
  RewriteRule /(.*)           ws://localhost:3000/$1 [P,L]

Et hop, tout était fonctionnel désormais !

Saturday, May 12 2018

HAProxy et compression Gzip

Pour accélérer l'accès à vos sites et services web propulsées par HAProxy, il est facile d'activer la compression automatique des contenus texte comme HTML, CSS, JS (s'ils ne le sont pas déjà par le serveur sous-jacent).

Rien de plus simple, il suffit d'ajouter les 2 lignes suivantes dans la section defaults de la configuration d'HAProxy :

compression algo gzip
compression type text/html text/plain text/xml text/css text/javascript application/javascript application/json text/json

et redémarrer HAProxy par une commande comme

/etc/init.d/haproxy restart

" Avec cette fonctionnalité activée, vous devez désormais voir dans les en-têtes des transmissions entre le serveur web et le navigateur que le contenu est compressé avec gzip (vérification facile avec le module "Développeur" de Firefox par exemple, onglet "Réseau") :

Content-Encoding: gzip

Sunday, May 6 2018

HAProxy in front of Unicorn

Unicorn, the "Rack HTTP server for fast clients", is really for "fast clients". Fast clients mean clients on the same local network (or even same machine) with very low latency and near-zero chance of packets loss. Slow clients are the usual web users: far away from the server. Unicorn has been designed to serve fast clients and if you try to use it to serve slow clients then the performance may be dismal. This is why the Unicorn developers recommend to use Nginx in front of Unicorn. To know more on the Unicorn philosophy, visit this page.

I recently tried to use HAProxy in front of Unicorn and was disappointed to see that:

  • the system was slow and unresponsive
  • a lot of 502 Gateway errors popped up for seemingly no reason (and this popped up unconsistently)

I came to the conclusion that the default configuration of HAProxy was not appropriate for Unicorn. After some web digging, I discovered the "http-buffer-request" option.

Here is what the HAProxy 1.8 documentation says about the "http-buffer-request" option :

It is sometimes desirable to wait for the body of an HTTP request before taking a decision. This is what is being done by "balance url_param" for example. The first use case is to buffer requests from slow clients before connecting to the server. Another use case consists in taking the routing decision based on the request body's contents. This option placed in a frontend or backend forces the HTTP processing to wait until either the wholebody is received, or the request buffer is full, or the first chunk is complete in case of chunked encoding. It can have undesired side effects with some applications abusing HTTP by expecting unbuffered transmissions between the frontend and the backend, so this should definitely not be used by default.

It seems to be the best fit with Unicorn's philosophy! Let's activate the option in each backend corresponding to a Unicorn-run application:

backend unicorn-app
	option http-buffer-request
	server unicorn-app 1.2.3.4:3000

and restart HAProxy:

/etc/init.d/haproxy reload

Tuesday, April 17 2018

Atheros AR9271 and Debian Stretch

I was expecting an easy use of my brand new Wifi adapter AWUS036NHA under Debian Stretch but I hit an unexpected bug...

I started with

apt install firmware-atheros

and soon the blue LED on the Alfa device was blinking furiously. So good so far! But when I tried to connect to a Wifi network with Network-Manager the tool was unable to connect. And no matter what I did it failed to connect. This is what I could see in the system logs (dmesg):

[  217.118991] usb 1-3: USB disconnect, device number 5
[  219.137772] usb 1-3: new high-speed USB device number 6 using xhci_hcd
[  219.294368] usb 1-3: New USB device found, idVendor=0cf3, idProduct=9271
[  219.294373] usb 1-3: New USB device strings: Mfr=16, Product=32, SerialNumber=48
[  219.294376] usb 1-3: Product: UB91C
[  219.294378] usb 1-3: Manufacturer: ATHEROS
[  219.294380] usb 1-3: SerialNumber: 12345
[  219.295099] usb 1-3: ath9k_htc: Firmware ath9k_htc/htc_9271-1.4.0.fw requested
[  219.295555] usb 1-3: firmware: direct-loading firmware ath9k_htc/htc_9271-1.4.0.fw
[  219.578229] usb 1-3: ath9k_htc: Transferred FW: ath9k_htc/htc_9271-1.4.0.fw, size: 51008
[  219.829806] ath9k_htc 1-3:1.0: ath9k_htc: HTC initialized with 33 credits
[  220.096217] ath9k_htc 1-3:1.0: ath9k_htc: FW Version: 1.4
[  220.096221] ath9k_htc 1-3:1.0: FW RMW support: On
[  220.096224] ath: EEPROM regdomain: 0x833a
[  220.096225] ath: EEPROM indicates we should expect a country code
[  220.096227] ath: doing EEPROM country->regdmn map search
[  220.096229] ath: country maps to regdmn code: 0x37
[  220.096231] ath: Country alpha2 being used: GB
[  220.096232] ath: Regpair used: 0x37
[  220.101582] ieee80211 phy1: Atheros AR9271 Rev:1
[  220.115019] ath9k_htc 1-3:1.0 wlx00c0ca9751d9: renamed from wlan1
[  220.148280] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  220.332215] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  220.578623] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  220.642308] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  255.566737] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  259.745782] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  259.986747] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  265.841754] IPv6: ADDRCONF(NETDEV_UP): wlx00c0ca9751d9: link is not ready
[  276.133407] wlx00c0ca9751d9: authenticate with ec:08:6b:33:71:ba
[  276.391552] wlx00c0ca9751d9: send auth to ec:08:6b:33:71:ba (try 1/3)
[  276.394687] wlx00c0ca9751d9: authenticated
[  281.389219] wlx00c0ca9751d9: aborting authentication with ec:08:6b:33:71:ba by local choice (Reason: 3=DEAUTH_LEAVING)
[  282.900769] wlx00c0ca9751d9: authenticate with ec:08:6b:33:71:ba
[  283.164429] wlx00c0ca9751d9: send auth to ec:08:6b:33:71:ba (try 1/3)
[  283.167350] wlx00c0ca9751d9: authenticated

wlx00c0ca9751d9 is the name the system gave to the adapter and I was intrigued with this error line:

aborting authentication with ec:08:6b:33:71:ba by local choice (Reason: 3=DEAUTH_LEAVING)

After looking up on the web, I discovered that other users of Atheros firmware reported issue when the adapter was given a long name...

So I decided to teach udev to give a shorter name to the wifi device, for example wlan1. And by the way it would be easier to remember!

The first step was to detect the attributes seen by udev on the device. The right command to do so is:

udevadm info -a -p /sys/class/net/wlx00c0ca9751d9

Among many other attributes, I spotted quite precise ones:

ATTRS{manufacturer}=="ATHEROS"
ATTRS{product}=="UB91C"

Then I opened /etc/udev/rules.d/70-persistent-net.rules and added this line:

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTRS{manufacturer}=="ATHEROS", ATTRS{product}=="UB91C", NAME="wlan1"

After restarting udev with

/etc/init.d/udev restart

I unplugged and then plugged back the Wifi adapter and it was recognized as wlan1. And then the Wifi connection could be established.

Complicated but quite effective fix!

Monday, March 12 2018

Utiliser HAProxy pour profiter d'HTTP/2

Les versions 1.8.x d'HAProxy (premier représentant de la branche publié fin 2017) supportent le protocole HTTP/2 pour la communication frontale (section frontend). L'utiliser en amont de votre infrastructure est un moyen facile de rendre ce protocole disponible même si certains de vos serveurs sous-jacents (backend) n'en sont pas encore capables.

Installer HAProxy 1.8.x sur Debian Stretch

La version distribuée officiellement dans Debian Stretch est 1.7.x. Pour installer une version de la branche 1.8.x, il y a au moins 2 alternatives :

  1. compiler l'outil à partir du code source disponible sur le site officiel
  2. utiliser https://haproxy.debian.net/ qui va fournir un dépôt spécifique

Configurer HAProxy

La configuration d'HAProxy se fait par défaut dans /etc/haproxy/haproxy.cfg.

Voici un exemple de fichier de configuration dont les principales sections sont commentées plus bas :

global
	log /dev/log	local0
	log /dev/log	local1 notice
	chroot /var/lib/haproxy
	stats socket /run/haproxy/admin.sock mode 660 level admin
	stats timeout 30s
	user haproxy
	group haproxy
	daemon

	# Default SSL material locations
	ca-base /etc/ssl/certs
	crt-base /etc/ssl/private

	# Default ciphers offered by Mozilla here:
	#  https://mozilla.github.io/server-side-tls/ssl-config-generator
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
    ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets

defaults
	log	global
	mode	http
	option	httplog
	option	dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
	errorfile 400 /etc/haproxy/errors/400.http
	errorfile 403 /etc/haproxy/errors/403.http
	errorfile 408 /etc/haproxy/errors/408.http
	errorfile 500 /etc/haproxy/errors/500.http
	errorfile 502 /etc/haproxy/errors/502.http
	errorfile 503 /etc/haproxy/errors/503.http
	errorfile 504 /etc/haproxy/errors/504.http

frontend http-in
	bind :::80 v4v6

	acl host_letsencrypt path_beg /.well-known/acme-challenge/
	use_backend letsencrypt if host_letsencrypt

	redirect scheme https code 301 if !host_letsencrypt
 
frontend https-in
	bind :::443 v4v6 ssl crt-list /etc/haproxy/crt-list.txt alpn h2,http/1.1
	option forwardfor
	http-request add-header X-Forwarded-Proto https

        # Define hosts
        acl host_alpha hdr_end(host) -i a.fr
	acl host_beta hdr(host) -i precis.b.fr
	acl host_gamma hdr_reg(host) ^d1.c.fr|d2.c.fr$

        # figure out which one to use
        use_backend alpha if host_alpha
	use_backend beta if host_beta
	use_backend gamma if host_gamma

	default_backend iota

backend alpha
        server alpha 192.168.1.1:80

backend beta
        server beta 192.168.1.2:80

backend gamma
        server gamma 192.168.1.3:80

backend iota
        server iota 192.168.1.4:80

backend letsencrypt
        server letsencrypt 192.168.1.1:8080

Quelques commentaires pour bien comprendre...

On écoute d'abord en HTTP (donc sur le port 80, en IPv4 et IPv6) et on redirige tout vers l'HTTPS (redirect scheme https code 301) car c'est une bonne pratique aujourd'hui de n'offrir que du contenu protégé par SSL/TLS.

frontend http-in
	bind :::80 v4v6
	redirect scheme https code 301

Si l'on utilise letsencrypt pour générer ses certificats et qu'ils sont tous générés sur une machine dédiée pour ne pas avoir à se poser de questions sur les différents types de serveurs sous-jacents, on peut rajouter une exception pour les appels utilisés dans l'ACME challenge de letsencrypt et rediriger alors le trafic vers une machine spécifique ici nommée letsencrypt.

frontend http-in
	bind :::80 v4v6

	acl host_letsencrypt path_beg /.well-known/acme-challenge/
	use_backend letsencrypt if host_letsencrypt

	redirect scheme https code 301 if !host_letsencrypt

On écoute bien sûr également sur le port 443 pour gérer les connexions en SSL/TLS :

frontend https-in
	bind :::443 v4v6 ssl crt-list /etc/haproxy/crt-list.txt alpn h2,http/1.1
	option forwardfor
	http-request add-header X-Forwarded-Proto https

Il y a beaucoup de choses intéressantes ici :

  • bind :::443 v4v6 : IPv4 et IPv6 activés
  • bind :::443 v4v6 ssl crt-list /etc/haproxy/crt-list.txt : on active le SSL/TLS et on spécifie un fichier texte qui contient la liste des certificats à charger pour chiffrer les communications
  • bind :::443 v4v6 ssl crt-list /etc/haproxy/crt-list.txt alpn h2,http/1.1 : on active l'HTTP/2 (en plus de l'HTTP/1)
  • option forwardfor : comme on fonctionne en reverse proxy, on demande à HAProxy de passer les en-têtes X-FORWARDED-FOR aux serveurs sous-jacents (utile pour avoir les vraies adresses IP appelantes dans les logs)
  • http-request add-header X-Forwarded-Proto https : on informe les serveurs sous-jacents que la communication est bien chiffrée (et on évite donc une boucle de redirection si le serveur sous-jacent veut forcer le passage en HTTPS, avec ce paramètre il sera déjà satisfait)

On définit ensuite quelques règles ACL pour, selon le nom d'hôte, orienter la connexion vers un backend ou autre. J'ai mis ici plusieurs exemples que j'utilise - il existe des dizaines d'autres filtres y compris sur d'autres critères que le nom d'hôte (on a vu l'URL dans le cas de letsencrypt un peu plus) : filtre sur la fin du nom d'hôte (tout nom d'hôte finissant par a.fr sera redirigé vers le backend alpha), filtre sur le nom d'hôte complet (precis.b.fr sera envoyé vers beta) ou filtre sur le nom d'hôte avec des expressions régulières.

        # Define hosts
        acl host_alpha hdr_end(host) -i a.fr
	acl host_beta hdr(host) -i precis.b.fr
	acl host_gamma hdr_reg(host) ^d1.c.fr|d2.c.fr$

        # figure out which one to use
        use_backend alpha if host_alpha
	use_backend beta if host_beta
	use_backend gamma if host_gamma

On définit également un backend par défaut (iota ici) :

	default_backend iota

Et il reste alors à définir chaque backend :

backend example
        server example 1.2.3.4:80

Pour aller plus loin

Les options possibles dans HAProxy sont fort évidemment beaucoup plus nombreuses ! La documentation est très détaillée et claire ici https://www.haproxy.org/#docs.

HAProxy et IPv6

Pour activer IPv6 sur HAProxy, le plus simple est de modifier la directive bind dans votre fichier de configuration (par ex. /etc/haproxy/haproxy.cfg) pour devenir :

bind :::80 v4v6

ou

bind :::443 v4v6

Il y a 3 fois le caractère ":" car "::" correspond à toute adresse IPv4 ou IPv6, et le troisième ":" sépare l'adresse IP du port.

Saturday, October 28 2017

Volumio over-the-air update, no SSH anymore?

What a surprise when I upgraded Volumio to the latest version (noteworthily to patch against the KRACK attack) and discovered that the SSH access was not activated anymore after a reboot!

It seems that the security-conscious Volumio team has decided to desactivate the SSH access by default, which makes sense. Although, it seems that the dev mode is activated by default (?) at http://ip.to.volumio/dev and permits the reactivation of SSH? Beware in an insecure context, Volumio was clearly built for a home-usage with low security constraints, one willing to go further will have no difficulties in increasing the level of security around Volumio (for example some filtering through a reverse proxy would certainly do a lot of good).

It is however quite easy to re-activate the SSH server: just create a "ssh" file in the /boot folder of Volumio. And reboot!

Tomato by Shibby n'est peut-être pas mort ? Mais vive LEDE malgré tout !

Si j'en crois Wikipedia, l'histoire du micrologiciel Tomato remonte au vénérable Linksys WRT54G et au projet HyperWRT qui avait été développé pour ce routeur. HyperWRT a été supporté par les bénévoles de 2004 à 2008 et en 2008 un fork aura lieu et mènera à Tomato qui sera développé jusqu'en version 1.28. Et là, nouvel abandon, et nouveaux forks, celui de Shibby (un développeur polonais) acquiert une certaine renommée. En 2017, deux vulnérabilités majeures sont publiées :

  • l'une concerne le logiciel dnsmasq (un petit serveur DNS/DHCP) : elle est publiée le 2 octobre 2017 sous le numéro CVE-2017-14491. Brièvement, une faille est détectée qui permet l'exécution de code distant sur une machine propulsant dnsmasq
  • la seconde est KRACK, la découverte par un chercheur belge d'une faille dans le protocole WPA2

Deux très bonnes raisons de mise à jour !

Tous les utilisateurs de firmware de routeurs & points d'accès se sont alors tournés vers les fournisseurs de ceux-ci, et les utilisateurs de Tomato by Shibby ont attendu avec impatience la sortie d'une nouvelle version. Malheureusement, deux semaines après ces annonces, aucun signe de vie et le site qui hébergeait les données de Tomato by Shibby n'est plus accessible au moment où j'écris ces lignes.

Edition au 30 octobre, 8h19 : Shibby m'a répondu - ce n'est qu'un problème temporaire de réseau chez le fournisseur de VPS qui héberge son site internet. Il répond également sur la mise à jour KRACK de la façon suivante : Tomato is using NAS daemon for WPA2 security. The problem is that sources for this daemon are closed by Broadcom. So we have to wait when Asus or Netgear etc will fix it and then try to move newer binaries to Tomato. But that means (probably) only newest routers will have fix for KRACK. I dont think that Asus etc will release fixed firmwares for Mipsel..

Il y a de nombreuses distributions basées sur Tomato by Shibby et d'autres forks de Tomato (cf. la page de Wikipedia sur Tomato, cependant si celle-ci est un jour, aucun des forks n'a été mis à jour post-annonce de KRACK ce qui n'augure rien de bon). Le code source étant disponible, de bonnes âmes expertes sauront peut-être faire renaître la tomate de ses cendres.

Pas de panique, il semble que LEDE soit une bonne alternative à Tomato dans la plupart des cas. Supporté par une communauté qui semble un peu plus large (Tomato by Shibby est (était), ne semble-t-il, soutenu que par un seul homme), LEDE est un fork d'OpenWRT. La dernière version 17.01.4 est très stable, très pratique et a été patchée pour KRACK !

Il est délicat de comparer LEDE et Tomato : là où Tomato se borne (bornait ?) à propulser routeurs et autres périphériques réseau, LEDE (Linux Embedded Development Environment) veut aller plus loin et propose une véritable micro-distribution avec gestion de paquets (avec l'utilitaire opkg). L'interface graphique LuCI de LEDE est très agréable, elle comporte moins de fonctionnalités que Tomato et il est probable qu'il faille recourir plus fréquemment à la ligne de commande de LEDE pour les paramétrages complexes possibles dans Tomato (par ex. la QoS, la gestion avancée des VLAN etc...). Mais dans les situations simples, LEDE peut-être un remplacement immédiat à Tomato. Pour les cas complexes, la migration est à évaluer, surtout si personne ne reprend le flambeau de Shibby !

Pour découvrir LEDE, c'est ici.

Comment LEDE a sauvé mes "vieux" points d'accès Wifi

J'avais acheté il y a peut-être 2-3 ans des petits points d'accès Wifi d'une marque chinoise. Lors de la divulgation de KRACK, je vérifiais le site du fabricant mais je constatais qu'aucune mise à jour n'était publiée pour ces appareils.

Je me tournais alors vers LEDE, le fork open source d'OpenWRT. En quelques minutes, j'identifiais le matériel dans la liste des matériels supportés, je téléchargeais la version 17.01.4 publiée le 18 octobre avec les corrections nécessaires pour KRACK.

L'installation de LEDE sur les points d'accès fut très facile :

  1. réinitialiser les points d'accès à l'aide du bouton RESET
  2. se connecter à l'interface du constructeur chinois, et se rendre dans la section "Firmware upgrade"
  3. téléverser le fichier de micrologiciel de LEDE
  4. ... patienter pendant le processus et le redémarrage
  5. se connecter sur http://192.168.1.1 pour trouver LuCI, l'interface graphique de LEDE

Deux enseignements :

  • si vous ne connaissez pas LEDE, c'est une très belle distribution pour les routeurs/points d'accès et autres petits périphériques du genre ; une bien pratique suite à OpenWRT
  • le llbre est une bonne solution à l'obsolescence et peut apporter une pérennité d'usage de matériels délaissés par les fabricants

Sunday, October 22 2017

Gitlab, fail of yarn when migrating to 10.0.x

For once, the Gitlab upgrade process from 9.5.8 to 10.0.x was not totally smooth on my end. I encountered the following error:

error "webpack#ajv" not installed
error "webpack#ajv-keywords" not installed
error Found 2 errors.
Error: You have unmet dependencies. (`yarn check` command failed)

And installing ajv manually did the trick:

sudo -u git -H yarn add ajv@^4.0.0

In case this helps someone out there!

Monday, October 16 2017

error: error switching euid to 33 and egid to -1: Invalid argument

I recently encountered the following error (after an upgrade from Debian Jessie to Debian Stretch):

/etc/cron.daily/logrotate:
error: error switching euid to 33 and egid to -1: Invalid argument
run-parts: /etc/cron.daily/logrotate exited with return code 1

It was not so easy to find the cause in the long list of possible offenders in /etc/logrotate.d/ ! In the end, it turned out that the faulty line was:

su www-data

in one of the logrotate configuration files. Indeed, no group was given in addition to the user account, hence the gid set to -1 which is blatanly an incorrect value.

The correct and expected syntax was:

su www-data www-data

Sunday, September 17 2017

PG::NotNullViolation error on id column in PostgreSQL

Faced with this error:

PG::NotNullViolation: ERROR:  null value in column "id" violates not-null constraint

it took me some time to realize that my id column was not a serial but a plain integer...

To fix this, just execute:

ALTER TABLE my_table DROP COLUMN id;
ALTER TABLE my_table ADD COLUMN id SERIAL PRIMARY KEY;

Saturday, June 3 2017

Nombre de déclenchements d'un appareil Canon sous Linux avec gphoto2

Si vous êtes l'heureux possesseur d'un appareil photo reflex Canon (et peut-être d'autres marques, je n'ai pas pu tester), vous vous demandez peut-être comment accéder au compteur de déclenchements par exemple pour mesurer le degré d'usure de votre matériel (http://www.olegkikin.com/shutterlife/).

gphoto2 sera votre complice pour cela. Il faut d'abord l'installer avec votre gestionnaire de paquet préféré (ici apt) :

apt install gphoto2

Après avoir branché l'appareil photo en USB sur le PC, on exécute la commande suivante :

gphoto2 --auto-detect

qui doit retourner le type d'appareil photo connecté et reconnu :

Model                          Port                                            
----------------------------------------------------------
Canon EOS 700D                 usb:001,007

Accédons maintenant à l'info souhaitée :

gphoto2 --get-config /main/status/shuttercounter

et voilà :

Label: Shutter Counter                                                         
Type: TEXT
Current: 14611

- page 1 of 8