You can choose a wiki page from left sidebar or go the the blog for blog archives.

Here are the latest 10 posts with pagination:

Debian diskless using PXE and root on NFS.

I wanted to have a debian bootable using PXE with full persistency so I opted for root on NFS.

It use debian stretch for both the server and the target.

The pxelinux config by default select to boot on the local drive, so I can set my workstation to boot by default on PXE and be able to boot the debian without having to spawn the bios to select the PXE.

Conventions I used at this time

  • PXE/tftp server IP:
  • TFTP root dir: /mnt/zfs/deadpool0/public/TFTP
  • NFS root dir: /nfsroot
  • OS on PXE/tftp server: debian stretch, same for the target nfs root
  • Kernel for target (if your debian/version have a newer, use the latest): 4.9.0-4-amd64
  • My NFS root is shared from ZFS using parameters:
    • You should be able to use the same parameters with


To be able to PXE boot I needed to add the following in my DHCP “vlan_lan” service:

bootfile-name /pxelinux.0


apt install tftpd-hpa syslinux initramfs-tools pxelinux debootstrap

Configuring TFTP server

I use TFTPD-HPA so I changed the config file to:

TFTP_OPTIONS="--secure --create"

Configure pxelinux

cd /mnt/zfs/deadpool0/public/TFTP
cp /usr/lib/PXELINUX/pxelinux.0 .
mkdir -p pxelinux.cfg boot/isolinux/
cp -r /usr/lib/syslinux/modules/bios/* boot/isolinux/
cp /boot/initrd.img-4.9.0-4-amd64 /boot/initrd.img-4.9.0-6-amd64 .
DEFAULT menu.c32
LABEL reboot
        MENU LABEL reboot computer
        COM32 reboot.c32
LABEL local
        MENU LABEL boot local drive
        LOCALBOOT 0
LABEL linux
        MENU LABEL Linux Debian 4.9.0-4-amd64
        KERNEL vmlinuz-4.9.0-4-amd64
        APPEND root=/dev/nfs initrd=initrd.img-4.9.0-4-amd64 nfsroot= ip=dhcp rw

Install target nfs root

# create /nfsroot if not exists, don't forget the NFS export
debootstrap stretch /nfsroot
# Then after finish:
cp /etc/network/interfaces /nfsroot/etc/network/interfaces
cp /etc/hosts /nfsroot/etc/
cp /etc/fstab /nfsroot/etc/

Now edit the two last files to be like that:

/nfsroot/etc/hosts       localhost       pxeboot
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# /etc/fstab: static file system information.
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/ram0  /       ext4   defaults    0   0
proc       /proc      proc   defaults    0   1
tmpfs      /tmp       tmpfs  defaults    0   1

Then chroot to the target and edit some more things:

chroot /nfsroot
echo pxeboot > /etc/hostname
apt update
# If you want more stuff and a GUI like MATE:
apt install task-mate-desktop openssh-server screen tmux sudo htop vim
# Don't forget a root password
passwd root
# And an user with the right groups!
useradd -m -G adm,dialout,cdrom,sudo,dip,plugdev,users dashie
passwd dashie

Now you can boot any computer on PXE and it should get a full diskless debian!

2018/03/07 00:00 · dashie

Elka Concorde 405 - project state.

I've just got an Elka Concorde 405 and this will one one of the two major projects for 2018.

I've been looking for one since years and I finally got one, really cheap, for parts, and huge delivery price.

Fortunately, as usual, the delivery carrier dropped the thing on the ground, because, hey, why taking care when you pay 70€ for delivery ? (yes, that was the delivery price)

So here is the current issues:

  • whole bracket with connectors (pedal, power, headphones) and transformer are ripped from the case
  • PCB for the connectors is broken in four parts (I may need to do a whole new PCB for it)
  • some PSU cables are partially snapped because of the transformer drop
  • one magnet HP was ripped from it and was attached to the transformer
  • the same HP has his whole cone without any edge foam (the thing to attach the cone to the armature)
  • some boards are in a V shape, that's strange since they are attached on top with spacers…
  • some leds (most) doesn't works
  • some buttons works or not I don't know since no leds are working
  • the reverb tank has lost one spring and I can't find it in the case, the other one was detached and attached to another HP magnet …
  • the bass HP (I think) seems to have some issues and vibrations
  • the flycase does have various issues, broken handle, corners snapped, hinge does not perform as hinge anymore

But except for that, it does produce sound, four or five keys doesn't works only.

So well, lot of work, still 4 to 7 times cheaper than a “second hand” one who would works perfectly.

The first thing I will do will be, not in order :

  • reslot all cards and clean all contacts
  • dump some EPROMS for conservation
  • look on the PCB issue (this does not cause issues for the moment)
  • look how to get a schematic (free or paid)
  • check PSU voltages
  • replace some leaky capacitors
  • check all swiches and clean
  • check all keys and clean

For the reverb tank it will probably be hard to find the right spring, so I will may end up replacing the whole tank.

And now, some pictures:

2017/12/26 00:00 · dashie

How to work-around firefox lack of respect for the CSP specification for CSP reports to Sentry

As stated in Firefox doesn't respect the specification and doesn't include the fields effective-directive or status-code.

Sentry expect them, and then refuse the reports because of that.

To workaround the issue, I used Nginx LUA module to manipulate the JSON body before it is send to the uwsgi backend of Sentry.

Note: use it at your own risks.

The CSP should contains:

Content-Security-Policy: whatever-you; want;... report-uri

Makes sures the module is enabled, on Debian it's something like:

# cat /etc/nginx/modules-enabled/00-mod-http-ndk.conf
load_module modules/;
# cat /etc/nginx/modules-enabled/50-mod-http-lua.conf
load_module modules/;
# Makes sure there is:
include /etc/nginx/modules-enabled/*.conf;
# before the http {} directive in /etc/nginx/nginx.conf

I also needed to do in /etc/nginx/nginx.conf because the paths seems wrong by default:

http {
	lua_package_path "/usr/share/lua/5.1/?.lua;;";
	lua_package_cpath '/usr/lib/x86_64-linux-gnu/lua/5.1/?.so;;';

Packages needed are:

nginx-extras libnginx-mod-http-lua libnginx-mod-http-ndk lua-cjson

Add LUA call in the virtual host of your Sentry:

	location ~ ^/api/(?<projet>[0-9]+)/csp-report/ {
		access_by_lua_file /etc/nginx/proxy_csp.lua;
		include uwsgi_params;

	location / {
		include uwsgi_params;

And the most usefull file:

if ngx.req.get_method() == "POST" then
    local cjson = require "cjson"
    -- read body and set local variables, also dump into logs for debugging if needed
    local body = ngx.req.get_body_data()
    --ngx.log(ngx.STDERR, body)
    -- read json body
    local json =
    -- We need to manipulate the JSON body to add if missing:
    -- effective-directive: the violated directive name
    -- status-code: HTTP status code of the violated directive
    if (not json['csp-report']['effective-directive']) then
	-- ugly split thing to get the directive name
    	words = {}
    	local vd = json['csp-report']['violated-directive']
    	for word in vd:gmatch("[a-zA-Z0-9-]+") do table.insert(words, word) end
    	if (words[1]) then
        	json['csp-report']['effective-directive'] = words[1]
        	json['csp-report']['effective-directive'] = 'Unknown violation wrong format string'
    if (not json['csp-report']['status-code']) then
    	json['csp-report']['status-code'] = 200
    -- reencode new body
    new_json = cjson.encode(json)
    -- set new body
    -- we are done
2017/04/19 00:00 · dashie

Use an extended bridge using OpenVSwitch and VXLan over internal network

Classic bridges are local only, with OpenVSwitch and automatic VXLan tunelling if you have a private network between your two servers you can have a bridge on each one linked.
They will have the same subnet, and servers from one side could reach the other without issue.
It's possible to switch from brctl to ovs without issues since there is no required config in the interfaces side of the containers, only setup the bridge and use it.

The eth1vmbr0 or vmbr2 is in fact transparent, you don't add it in the bridge, it's juste “transparently” used by VXLan (because you use the tunnel over the private network).

OpenVSwitch bridges are not compatible with brctl, you should use ovs-vsctl, like

ovs-vsctl show


Here we are assuming:

  • Server 1 PRIVATE LAN IP:
  • Server 2 PRIVATE LAN IP:
  • Bridge name on each server: vmbr0
  • Extended Bridge network:
  • Server 1 BRIDGE IP:
  • Server 2 BRIDGE IP:


apt install openvswitch-switch openvswitch-common

Create an OpenVSWitch bridge on each server:

ovs-vsctl add-br vmbr0

Config on server1:

auto vmbr0
iface vmbr0 inet static
	ovs_type OVSBridge
	post-up ovs-vsctl add-port vmbr0 vxlan1 -- set Interface vxlan1 type=vxlan options:remote_ip=

For server2:

auto vmbr0
iface vmbr0 inet static
	ovs_type OVSBridge
	post-up ovs-vsctl add-port vmbr0 vxlan1 -- set Interface vxlan1 type=vxlan options:remote_ip=

Up the network on each:

ifup vmbr0

You may need to reboot to load OpenVSwitch kernel modules.
And you should be able to


from server 1 and server 1 from server 2.
You can get OpenVSwitch status config by using:

server1:~# ovs-vsctl show
    Bridge "vmbr0"
        Port "vmbr0"
            Interface "vmbr0"
                type: internal
        Port "vxlan1"
            Interface "vxlan1"
                type: vxlan
                options: {remote_ip=""}
        Port "veth2ES9B5"
            Interface "veth2ES9B5"
    ovs_version: "2.3.0"

LXC Notes

LXC Uses brctl and brctl isn't compatible with OpenVSwitch, here is the configuration needed to use the new ovs bridge:

ovs-vsctl --may-exist add-br $BRIDGE
ovs-vsctl --if-exists del-port $BRIDGE $5
ovs-vsctl --may-exist add-port $BRIDGE $5
ovs-vsctl --if-exists del-port ${ovsBr} $5

In the CT config:

/var/lib/lxc/derpy/config = veth = up = eth0 = /etc/lxc/ifup = /etc/lxc/ifdown = =
2017/04/09 00:00 · dashie

File recovery from formatted hard drive


  • testdisk did nothing, found no recoverable partition and then cannot restore files
  • foremost doesn't manage plain ascii text (they don't probably have real markers or whatever)

Now, the happy story:

  • I accidentally formatted the wrong hard drive, ok, that's not that bad.
  • And reinstalled debian on it. Upgraded packages, installed, done some service configurations, mysql, nginx. Oops…
  • I haven't backupped some asterisk configuration because this hard drive wasn't supposed to be formatted.
  • I needed to recover theses files.


  • The poor hard drive (/dev/sda)
  • Another hard drive (in my case two USB drives, /mnt/usb1 and /mnt/usb2, each with enough to store the full /dev/sda)
  • I preferred to have two hard drives, one to store the image and another to store whatever extracted from it, may help for usb speed
  • dd, strings, cp, etc.
  • A pizza. (I ate one, this may help you too)


dd if=/dev/sda of=/mnt/usb1/hdd.bin bs=1M

Make indexes

When finished, you remember some patterns of your config file, right ?

In my case it was something like […ovh…], don't remember the case, if there where a dash or whatever.

Extract all strings matching this:

strings -t d /mnt/usb1/hdd.bin | grep -i "ovh" | grep "\[" | grep "\]" | tee /mnt/usb2/

-t d will print a decimal offset, we will use that to get some “index” in the hdd.bin file.

After long times, we may have some things:

19527608307 exten => _0[67]X.,1,NoOp(SIP/To-Ovh/P_${EXTEN}, ${TIMEOUT}, ${DIAL_OPTS})
19527609393 [Dp-From-Ovh]

Not really automatic extraction

Now is the best part, start with:

dd if=/mnt/usb1/hdd.bin bs=1 count=100 skip=19527608307

bs will stay at 1, count is the number of bs to show after skip (our “index”).

What i've done is to round the index, like 19527608307 then 19527608300 then 19527608000, etc.

In backward, because you want to get the start of the file. Round as close as possible of the top without getting too many garbage.

You will finally get the start of the file, then increment the count, 100, 1000, 10000, 10500, 11000 etc.

Finally you will may end with SOME VERSION of your config file, there is multiple version, or “revisions” as you edited them in the past.

You will need to do that for every repetitting index found in the file like:

19527627416 [sip-ovh](!)            ; OVH Template
19527627812 [To-Ovh](sip-ovh)
19527627878 [From-Ovh](sip-ovh)
21673001628 [sip-ovh](!)            ; OVH Template
21673002024 [To-Ovh](sip-ovh)
21673002043 [From-Ovh](sip-ovh)
21673005724 [sip-ovh](!)            ; OVH Template
21673006120 [To-Ovh](sip-ovh)
21673006139 [From-Ovh](sip-ovh)

Then do the dd bs count skip for every index (the one matching ; OVH Template, for example), then diff them and found the latest.

You will not have any timestamp or anything unless your config have it in plain text.

Have fun.

2016/11/06 00:00 · dashie

Older entries >>

  • start.txt
  • Last modified: 2016/12/28 23:02
  • by dashie