Lightweight music streamer with Icecast

Wednesday, 03 February 2021
Écrit par
Grégory Soutadé

My Cubox server offers a lot of services and one I specially appreciate when I'm not at home is that it contains all my music I can access through HTTP(S) interface. This is really fine for Linux clients where mplayer is installed, but it's not the case for Windows : VLC refuse to play my music (which requires login/password) and Windows player doesn't support m3u playlists, so I have to play each track individually.

I started to look for streamer software and the biggest open source one is Icecast which implement SHOUTcast standard. Like for all my online services, software must be lightweight (I don't have a lot of RAM) ! Plus I don't have any sound card plugged and don't want to spare cpu bandwidth with decoding/encoding files. This is a reason why basic HTTP(S) transfert is good : files are trasfered as is. Even if it's not clearly indicated by the documentation, icecast coupled with ezstream has all the qualities I need ! I was really suprised to find how it was easy to setup !

Here is a tutorial for basic setup (with current Debian stable distribution) :

If ezstream is available in your repository

sudo apt-get install icecast2 ezstream

If not (for an ARM target)

sudo apt-get install icecast2 libshout3 libtagc0 libxml2
sudo dpkg -i ezstream_1.0.1-1_armhf.deb

Now, we have to configure icecast. You must edit /etc/icecast2/icecast.xml. Update (at least) :

  • Admin name/address
  • Server address
  • Optional : server port

Some of these values has already been configured by installer. There is a lot of avaible options not needed for basic setting. After that, restart icecast :

sudo service icecast restart

Now, add a NAT rule to redirect external port (8000 by default) to your server. Then, copy an example of ezstream configuration :

cp /usr/share/doc/ezstream/examples/ezstream-minimal.xml .

and edit it (be careful, here end tag are crafted by my editor) :






I choose to play track only once. If not set, it will be played indefinitely. Now, we can run ezstream :

ezstream -c ezstream-minimal.xml

On Windows, we can use VLC to read this stream by opening :

This is a basic setup, but we can do a lot of more complex things by autogenerating config file and auto start ezsteram from a web frontend for example.

Trust your SSH server

Friday, 23 October 2020
Écrit par
Grégory Soutadé

This article you're reading is hosted on my own server. This last one runs a lot of services : web, mail, database, XMPP... and to manage it I need an SSH connection which is the more secure way to connect to a remote server. But, how I can trust this connection in an hostile environment ?

Connection protocols and key exchange has greatly evolved the last 20 years, but there are still based on a root asymmetric key pair (RSA, DSA, ECDSA...). When you connect to a server for the first time, you get a message like this :

The authenticity of host ' (' can't be established.
RSA key fingerprint is 6a:de:e0:af:56:f8:0c:04:11:5b:ef:4d:49:ad:09:23.
Are you sure you want to continue connecting (yes/no)? no

This is a human readable fingerprint of the root key used to establish a connection. Personally, I don't know my server fingerprint by heart. There is some solutions to check it :

  • Manually by printing it on a paper/on your phone/on a USB key
  • Register it with a DNS record, but DNS server/response can be easily spoofed
  • Using a public key based connection (you need to keep it on a USB key)

The better remains having the secret (key or fingerprint) somewhere you could access it. I propose in this article an other solution you can always run in an hostile environment without any previous setup.

The idea is to create a restricted user that can only run a verification script that will check fingerprint once connection is established which avoid Man In The Middle attacks !


First, we'll have to create this user named check-user :

useradd --create-home --no-user-group --shell /bin/rbash check-user
cd /home/check-user

You can set a password or not. I don't do it, so I cannot open a connection from external nor internal as my server always checks for password (we can still use su/sudo command). I also set a restricted shell (rbash).

Then, we have to create a key pair

su check-user
cp .ssh/ .ssh/authorized_keys

You can set or not a password for this key. Then, edit .ssh/authorized_keys and add :

command="rbash" ssh-rsa AAAA...

Now, downloads in /home/check-user and set execution permissions.

Then, go to your webserver directory were you can put some downloadable files (something like /var/www) and copy SSH the private key.

cd /var/www
cp /home/check-user/.ssh/id_rsa ssh_check
chmod a+r ssh_check

Now, you can edit and run from any network !

How does it works ?

The client starts by establishing an SSH connection and close it immediately in order to retrieve remote fingerprint. Then, it downloads check-user SSH private key and use it to connect to the server and send the fingerprint. The only command that can be run with this key is rbash which get the fingerprint and compare with the ones installed on the server side. A message is then displayed which indicates if the connection is secure or not.



target_key=`echo $SSH_ORIGINAL_COMMAND| tr -d "\r\n"`

if [ -z "${target_key}" ] ; then
    echo "Empty key provided, abort"
    exit 0

for keyfile in /etc/ssh/ssh_host_* ; do
    a=`ssh-keygen -l -f ${keyfile}|grep "${target_key}"` # To avoid print
    if [ $? -eq 0 ] ; then
        echo "Target key found, your connection is secure !"
        exit 0

echo "!!! WARNING !!! Key not found, the connection may not be secure"

exit 1


KEY_TRACE="Server host key:"

if [ -z "$1" ] ; then
    echo "usage : $@ <ssh server>"
    exit 0

echo "Retrieve remote key for $1"
ssh -v -o "NumberOfPasswordPrompts=0" $@ >${tmp_file} 2>&1
key=`cat ${tmp_file}|grep "${KEY_TRACE}"`
key=`echo ${key}|cut -d" " -f6`
rm -f ${tmp_file}

echo "Retrieve SSH private key from ${SSH_CHECK_KEY}"
wget -O ssh_check ${SSH_CHECK_KEY}
chmod 0400 ssh_check

echo "Check for key ${key}"
ssh -l ${REMOTE_USER} -i ssh_check $@ "${key}"
echo "Cleaning"
rm -f ssh_check

Install Debian on SolidRun Clearfog board

Monday, 15 June 2020
Écrit par
Grégory Soutadé

ClearFog base board

For a project, I need to run java on an ARMv7 core. I could have used my Cubox server, but I don't have enough memory to run web services & java in parallel. Fortunately, I could find a SolidRun ClearFog Base board. This board is mainly network focused and only have an old dual Cortex A9 with 1GB of memory which is quick reached by today web applications, but it should be okay with a single one (I hope).

SolidRun provides documentation & ready to use OS (Debian FreeBSD, Yocto, OpenWRT), so board start should take less than one half hour. Nevertheless, documentation is split in multiple files, and there is no step by step guide. Moreover, Debian images seems crafted (we can't read main ext4 partition). After 2 hours of fails I started to turn crazy ! Here is my step by step tutorial.

The goal is to install Debian on an 8GB SDCard

1) Get an 8GB SDCard and delete all partitions thanks to gparted (or fdisk).

2) Within gparted create an ext4 partition that starts at 4MB with 8GB length

3) Download target Debian images from SolidRun resources. You should take .tar.xz file which is a compressed tar file of root filesystem.

4) Go to SDCard main partition and extract data from Debian image (using sudo)

cd /media/soutade/UUID/
sudo tar -Jxvf ~/clearfog/sr-a38x-debian-buster-20200218.tar.xz

5) Update fstab with your new SDCard UUID

sudo emacs etc/fstab

6) Download U-Boot for base-sdhc variant

7) Burn it to SDCard at address 512 (first sector). We assume SDCard is /dev/sdb (check it before applying this command)

sudo dd if=u-boot-clearfog-base-sdhc.kwb of=/dev/sdb1 seek=1 bs=512

8) Configure ClearFog switches to start using SDcard (Off Off On On On)

9) Insert SDCard into the board, connect serial line USB to your computer

10) Power up the board and start serial line screen

sudo screen -L /dev/ttyUSB0 115200

11) Stop U-Boot process by hit a key

12) Setup kernel bootargs. Here we setup root filesystem read/write at startup, but it should be re mounted rw by fstab. Only root argument is mandatory

setenv bootargs root=/dev/mmcblk0p1 rw
env save

The board should now start with a fresh Debian ! I suggest to connect within SSH which is more comfortable to use than serial line console. Login/password is debian:debian.

Have fun !

IWLA 0.5

Thursday, 16 April 2020
Écrit par
Grégory Soutadé

Capture d'écran IWLA

3 ans se sont écoulés depuis la dernière version d'IWLA. C'est avant tout une histoire de flemme avec des commits restés trop longtemps en test (notamment la série d'août 2019), mais cela prouve aussi que le logiciel est relativement stable et répond au besoin. Cette nouvelle mouture apporte :

  • L'ajout d'un mode test (dry run)
  • De nouvelles règles pour la détection des robots (plus de 10 erreurs 404, affichage d'une page sans élément (hit), pas de page et pas de hit)
  • Un nouveau format de base de données qui réduit considérablement la taille à stocker : les statistiques de pages (vues et non vues), de hits (vus et non vus) ainsi que la bande passante sont désormais cumulés et non plus stockés jour par jour. Cette modification entraîne une incompatibilité avec les versions précédentes
  • La mise à jour des données depuis la branche de développement d'AWSTATS
  • Plugin top_pages_diff
  • La possibilité d'exclure une IP des statistiques
  • L'utilisation de cPickle à la place de Pickle
  • Les requêtes des robots ne sont plus sauvegardées (gain de place)
  • Quelques corrections de bug

Comme mentionnées, les modifications visent avant tout à réduire l'empreinte mémoire et disque du logiciel, ce dernier devant tourner sur un serveur avec seulement 1GB de RAM.

À vos téléchargements !

Upgrade Cubox-i Linux kernel

Saturday, 05 October 2019
Écrit par
Grégory Soutadé

In the beginning of October, Debian pushed a security update for libssl. After installing it, all new SSH connections fails with message (even with correct password, or root login) :

fatal: privsep_preauth: preauth child terminated by signal 31

After searching on Internet, I found that nor SSH, nor libssl were in cause. It was due to an old kernel. I was running Linux 3.14 kernel because is not maintained.

Fortunately, Solid Run still maintains Linux kernel source tree on Github. Next instructions are based on this page.

First, mount Cubox-i filesystem from SDcard (assume it's in /mnt/cubox).

At startup, uBoot is configured to load zImage and dtb/$dtb_file. zImage is a symbolic link allowing us to have multiple kernel in /boot, let's do the same for dtb directory :

cd /mnt/cubox
cd boot
sudo mv dtb/ 3.4.14
sudo mkdir dtbs
sudo mv 3.4.14 dtbs
sudo ln -s dtbs/3.4.14/ dtb

Next, kernel compilation. The linked page suggest to do a git clone which is very big (~3GB), I suggest to download a snapshot from Github. Now, we'll follows Solid Run instructions :

sudo apt install crossbuild-essential-armhf
cd linux_sources
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
make imx_v7_cbi_hb_defconfig
make -j4 zImage dtbs modules

Then, install compiled files :

export INSTALL_PATH=$PWD/linux_install
export INSTALL_MOD_PATH=$PWD/modules_install
mkdir linux_install
make install modules_install dtbs_install
cp arch/arm/boot/zImage linux_install/vmlinuz-4.9.124
sudo cp -r linux_install/* /mnt/cubox/boot/
sudo cp -r modules_install/lib/modules/4.9.124/ /mnt/cubox/lib/modules/

Linux creates an image compressed with lzop which not seems to be supported by my version of uBoot, so we need to manually copy created zImage.

Modules installation can be done in one line :

sudo make modules_install INSTALL_MOD_PATH=/mnt/cubox/

Optionally, you can export headers :

sudo make headers_install INSTALL_HDR_PATH=/mnt/cubox/usr/local/include

Switch kernel

cd /mnt/cubox
sudo rm dtb
sudo ln -s dtbs/4.9.124/ dtb
sudo rm zImage
sudo ln -s vmlinuz-4.9.124 zImage

Unmount and unplug SDcard. Power up. It should now run new Linux kernel !

Solid Run also have a repository for a Debian package for kernel, but for now I didn't saw any binary repository available on Internet.

Warning, Github kernel make my server crash a lot of time due to an error in ext4/fs driver. I compiled a vanilla kernel, from linux-4.19.y branch (same as Debian stable one). Use the same instructions for compilation (just add dtbs_install to make install command). My .config is available here. I didn't test HDMI, Bluetooth nor IR (red LED is off). Last thing : root partition is now on /dev/mmcblk1p1, don't forget to update kernel command line !

Enabling serial console

The serial console seems to not work anymore. To enable it, first edit /etc/inittab and add at then end :

1:2345:respawn:/sbin/getty -L ttymxc0 115200 vt100

Then, we need to enable getty with SystemD to have login prompt at startup :

sudo systemctl enable "getty@ttymxc0"

Finally, we need to update kernel command line. Edit /boot/boot.cmd and put :


Build boot.scr from boot.cmd, documentation here:

mkimage -C none -A arm -T script -d boot.cmd boot.scr