Checking Western Digital Green load cycle per hour / Intellipark issues

I got a few Western Digital Green hard disk. I’ve read they have been rebranded blue now. It was supposed to be hard disk with long consumption, possibly lower speed due to low rotation. Low rotation, you would assume: longer-life span, since usually, mechanical devices lives longer when running slower.

But when you do realize that these Green have the shortest warranty possible (2 years against 3 or 5 for others), you wonder.

And then, when you have a hard disk that starts to fails, you learn stuff like these Western Digital Green having a 8 seconds timeout to park the drive (yeah, like in old DOS era, when you where using park before shutting off your computer). I assume it is to save energy but it takes no genious to evaluate the result if your system writes every 10 seconds, which is not un unlikely scenario.

I am not talking theory, I do have a failing Western Digital Green 2Tb (WDC WD20EZRX-22D8PB0) that is just 2 years and a few months.

With different cables and different mainboards, power supply units, etc, it sprouts:

 [ 3996.054577] ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 3996.054580] ata7.00: irq_stat 0x40000001
[ 3996.054585] ata7.00: failed command: READ DMA EXT
[ 3996.054595] ata7.00: cmd 25/00:08:00:88:e0/00:00:e8:00:00/e0 tag 17 dma 4096 in
 res 51/04:08:00:88:e0/00:00:e8:00:00/e0 Emask 0x1 (device error)
[ 3996.054598] ata7.00: status: { DRDY ERR }
[ 3996.054600] ata7.00: error: { ABRT }
[ 3996.055191] ata7.00: failed to enable AA (error_mask=0x1)
[ 3996.056015] ata7.00: failed to enable AA (error_mask=0x1)

So what about this wdidle3 timeout and resulting Load_Cycle?

# hdparm -J /dev/sdd
 wdidle3 = 8.0 secs

# smartctl /dev/sdd -a | grep Load_Cycle
193 Load_Cycle_Count 0x0032 116 116 000 Old_age Always - 253474

253474 for recent hard disk? I’ve read the life expectancy is usually between 300000 and 1000000 load cycle count. But as reference, I’ll check my other hard drives on the workstation I put the disk to test:

# DISK="a b c d e"
# TMP=`mktemp` && for disk in $DISK; do smartctl -xa /dev/sd$disk > $TMP ; grep "Device Model" $TMP ; hdparm -J /dev/sd$disk 2>/dev/null| grep wdidle ; grep Power_On_Hours $TMP ; grep Load_Cycle_Count $TMP ; Count=`grep Load_Cycle_Count $TMP | grep -oE '[^ ]+$'` ; Hours=`grep Power_On_Hour $TMP | sed "s/\s[(][^)]*[)]//g" | grep -oE '[^ ]+$'` ; if [ x$Hours != x ]; then echo `echo print $Count/$Hours. | perl` load cycles per hour ; echo ; fi ; done
Device Model: WDC WD5000AZRX-00A8LB0
 wdidle3 = 128 ??
 9 Power_On_Hours -O--CK 075 075 000 - 18587
193 Load_Cycle_Count -O--CK 121 121 000 - 239519
12.8863721956206 load cycles per hour

Device Model: ST2000DX002-2DV164
 wdidle3 = 1 ??
 9 Power_On_Hours -O--CK 094 094 000 - 5385
193 Load_Cycle_Count -O--CK 099 099 000 - 3617
0.671680594243268 load cycles per hour

Device Model: WDC WD20EZRX-22D8PB0
 wdidle3 = 8.0 secs
 9 Power_On_Hours -O--CK 090 090 000 - 7672
193 Load_Cycle_Count -O--CK 116 116 000 - 253490
33.0409280500521 load cycles per hour

Device Model: WDC WD2001FASS-00W2B0
 wdidle3 = 128 ??
 9 Power_On_Hours -O--CK 038 038 000 - 45726
193 Load_Cycle_Count -O--CK 073 073 000 - 382183
8.35811135896427 load cycles per hour

Depends obviously of the purpose of the hard disk. Still, the affected Western Digital Green, with its 33  load cycles per hour stands out, in the wrong sense. At this rate, the first disk would reach 613000 load cycles instead of 239519 by now, likely a goner already.  And the last one would be around 1509000, a goner definitely too!

Then on a  server:

Device Model: ST4000DM005-2DP166
 wdidle3 = 1 ??
 9 Power_On_Hours -O--CK 090 090 000 - 9091 (43 85 0)
193 Load_Cycle_Count -O--CK 100 100 000 - 400
0.0439995600044 load cycles per hour

Device Model: WDC WD40EFRX-68WT0N0
 wdidle3 = 300 secs (or 13.8 secs for older drives)
 9 Power_On_Hours -O--CK 062 062 000 - 28038
193 Load_Cycle_Count -O--CK 200 200 000 - 653
0.0232898209572723 load cycles per hour

We have read too an infamous Western Digital, but not a Green, so the widle3 is much less extreme.

What about on a laptop (Lenovo 20017 IdeaPad Y550 ) ?

Device Model: WDC WD5000BEVT-22ZAT0
 wdidle3 = 8.0 secs
 9 Power_On_Hours -O--CK 041 041 000 - 43353
193 Load_Cycle_Count -O--CK 001 001 000 - 889112
20.508661453648 load cycles per hour

Gasp! But wait, isn’t it a Western Digital Blue – so, Green rebranded?

Questioned about this kind of issue, it seems that Western Digital claims “we’ve not seen the drives fail over high load/unload counts”. It may be right, maybe the problem is something else. But that the only odd thing noticeable to me. And I am apparently not the only one questioning Western Digital statements, if not challenging them.

As you can see, I got a few disk from this brand and must say even the Western Digital knowledge base entry titled “The Load/Unload counter for S.M.A.R.T Attribute 193 continues to increase under some distributions of the Linux Operating system and some Windows applications”  is not what I expect as customer. They do not question their 8 seconds timer, which is questionable – I do not care about their very own opinion about how often a system should or should not write to a disk.  They claim the issue “artificially increases the number of load-unload cycles”. There is nothing artificial, it simply does increase. They say it is no problem because they are “within design margins (drive has been validated to 1 million load/unload cycles without issue)”. But my test shows that it is out of proportions in any case, for no real added benefits.

I have to admit the issue is not new. But if you do not especially pay attention to hard drives in general, why would you be aware of it.

What to make out of this?

First, on the laptop, I’ll disable this widle3:

# apt install idle3-tools 
# idle3ctl -g /dev/sda
Idle3 timer set to 80 (0x50)
# idle3ctl -d /dev/sda

Myself, I think I’ll stay clear of Western Digital all together.





Build a simple mobile music player with mpd and a Raspberry Pi B+

Turned out that my kitchen device was not satisfying. Not for the reasons suggested in comments, not because I wanted to use cheezy OS like the ones actually supported for most tablets (last time I checked, you cannot get a decent libre OS with full hardware support) for instance. But  the Raspberry Pi B+ is just not powerful enough to browse Internet of these days with such a resolution. It is just too slow.

On another hand, for years, I had issues with a declining portable music player I have plugged into the car audio system (that have RCA connectors or otherwise only specific mp3 files support). Either it got stuck on some files, or it had problems to recharge. And even working best as it could, the random mode seemed to have a few songs in favor.

So, for less than 30 €, I ordered a tactile 3,5″ screen from Quimat. It work fines with Raspbian, provided you use their specific script that you can obtain via (otherwise the screen would  remain white):

git clone

The box isn’t perfect, on one side the screen won’t be properly supported. But I do not intend to put my paws so much on it so let’s say it is acceptable for such price.

Then, to get some acceptable music player system, I went for a mpc/mpd solution, not wanting to bother with Kodi or any complicated solution that might not work or require a dedicated system other  than raspbian.

So I ended up with mpd along with awesomewm and a few wrapper scripts for mpc just build playlist or send OSD notifications.


(since the screen I improved the icon set, removed the visible cursor)

I use cava to provide a visualizer. Access to the device is made through anonymous Samba. My -utils-mpc package carries such setup mostly based on mpc-monitor (check currently played, could be used to made stats or scrobbling later), mpc+notify (run mpc command with sendnotify call),  mpc-playlist-build, mpc-playlist-next and few sample conffiles (awesome/rc.lua, smb.conf, redshift.conf + extra details in the README about input calibration, mpd.conf).

This Raspbian was purged of systemd, because I do want unexpected troubles, and of pulseaudio, because it causes mpd sometimes to stall and works perfectly without.

All files at stored in the main mpd music directory. Any file within a subdirectory will be treated as belonging to a specific playlist.

Plugging the USB energy input on the car relevant plug generates some odd noise: it has to be plugged to an energy bank. It seems to draw very little power.

Last step was to fill the 32GB USB key serving as storage for the music directory. Turns it was quite boring to hand pick such amount of files. So I used another quite crude script to fill it, taking randomly two thirds of available files for a given directory (a band name):


if [ ! -d "$PWD/$1" ]; then echo "$PWD/$1" not found && exit; fi

LIST=`find "$1" | grep -v .JPG$ | grep -v .jpg$ | grep -v .png$ | shuf`

for file in $LIST; do
 [ -d "$file" ] && continue ;

echo $COUNT
THIRD=$(($COUNT / 3))
echo a third is... $COUNT
# div by 3 and and skip this count

if [ "$2" ]; then COUNT=$2; fi

echo but... $COUNT

for file in $LIST; do
 if [ "$COUNT" -lt 0 ]; then exit ; fi
 [ -d "$file" ] && continue ;
 #echo $COUNT $file
 COUNT=$(($COUNT - 1))
 cp -v "$file" $DEST/`basename "$file"`

Quite crude indeed. mpc-monitor could be used to make stats to, in the end, remove unwanted out. But for now it should properly replace dying mp3/ogg player that you have no control over beside the power-off and play button.

Sure, maybe there are cool mp3/ogg/whatever players out there that could come for cheaper. Not really the point, I enjoy having full control over this one, even if I am not using more than 0,001% of this power. And, BTW, I intend, for another pre-electronics vehicule, to get a proper setup with music player and GPS so any experience in this regard is worth it.





Build a simple kitchen terminal out of an old laptop screen and Raspberry Pi

On some occasion, it is practical to have a terminal in the kitchen, mainly to check on recipes. While a phone screen is not that great, a tablet would do. I do not have any tablet and I am not that fond of systems readily available on tablets. But I do have a few old laptops around plus a Raspberry Pi B+.


The following RasPi.TV‘s video explains it all:

Quite straightforward, you unmount and identify your screen. So for my Dell Latitude C640, I got a Samsung LTN141X8-L02 14,1″ screen for which I easily found a controller board kit on ebay for 21,5 €.IMG_20170122_115114.jpg

Here’s the back of the said screen, with the original inverter board still attached. The kit will include another one.

Once acquired, there is not much to think about, everything just have to be plugged where it belongs according to the seller docs:


Obviously, you need to buy also a HDMI cable and a power adapter power adapter (12V, 4A).


Obviously, as it is no tablet, it requires peripherals. I opted for a slim USB wireless keyboard with trackpad and some USB powered stereo speaker. These devices will be powered by the Raspberry Pi (a phone charger can be plugged to the keyboard to recharge it).

Finally, the charger and the Raspberry are plugged onto a power socket with 5V USB. It will be used to put on/off the whole.

Afterwards, I put the screen within a cheap photo frame and fixed the rest on some board.

That frame looks too fragile, though, I would recommend to build a proper one instead.


1/ Raspbian desktop

I first tried some default Raspbian. Epiphany web browser is as bad as you cannot even set a default webpage without editing the .desktop files. And once it is done, it crashes on mediawiki standard page layout. Raspbian also fails to properly open videos (OMX sprout error messages, even with lot of memory attributed). Not convincing.

2/ Kodi media player

Afterwards, I went for LibreElec along with Kodi. Surprisingly, it loads movies with no problem, the interface is quite neat in general and the control with a distant web browser (port 8080 by default) is a plus. As media player, it would be nice.


But it is not perfect: Kodi does not provide any proper web browser, even lacking features. They only provide some cheezy sort of said text web browser. Sort of because it is no lynx/links/elinks, it is just a strange graphical interface with low HTML layout capabilities – but, kudos, it does not crash on mediawiki, yay! Nonetheless, that is quite a blocker issue for me. Even a media player, in my opinion, should have integrated web browser. It is not a challenge to reuse gecko/khtml, whatever, to make so.


3/ (tiger) VNC on top of Raspbian

So I went back on Raspbian. I found out that netsurf works fine to browse mediawiki. So just that satisfies the first requirement.

Instead of expecting to be able to finely setup Raspbian for video website, etc, I decided it might just be smarter to really think of this as terminal and so, to show some window from another computer session.

On an Devuan desktop, it is just enough to get tigervnc-scraping-server, generate a host file (for IP based control):

mkdir .vnc
echo "+IP_OF_YOUR_RASPBIAN" > .vnc/hosts

then to start it whenever you want to share your screen:

x0vncserver -HostsFile=$HOME/.vnc/hosts -SecurityTypes=None

Windows version is configured in a similar fashion.

Raspbian provides a VNC viewer graphical interface that will allow you to connect and you’ll immediately notice that TigerVNC is damned efficient and play with no problem youtube video, etc.

Ok, but VNC, while much more convenient than RDP to setup, does not care to sound forwarding.

I give some tries to PulseAudio RTP capabilities: it fails with errors like [alsa-sink-bcm2835 ALSA] module-rtp-recv.c: Sample rates too different, not adjusting (44100 vs. 90522) and when I tried to document myself about it, I found that this PulseAudio feature was bugged, flooding the network with UDP packets, a bug found in 2009 and still existing in 2017. Gosh, a feature bugged since near to a decade: back to why I try to keep away from systemd and anything made by the same crowd.

I ended up streaming audio with vlc,

cvlc -vvv pulse://`pactl list | grep "Monitor Source" | cut --delimiter ":" -f 2 | tr -d [:blank:]` --sout "#transcode{acodec=mp3,ab=128,channels=2}:standard{access=http,dst=}" &

simply played on the Raspbian with:

mpg123 http://hostname:9999/pc.mp3

I has been summarized in a script to be run on the distant host side. I considered stream both audio and video with vlc but it  is convenient to be able to move around with VNC. This will require further testing.

Removing car’s error messages with an ELM327 device and AndrOBD

Removing car’s error message: am I insane? Well, indeed, in a perfect world where no faulty design exist, I would be. Fixing an error message, that would really mean fixing not even a symptom but a warning and that can only be wrong.

But in the world of french automobile, it is not so (I cannot tell for expensive german or asian cars, I don’t own any). Namely, with Peugeot-Citroën HDI (and strangely not so much with similar Fiat’s JTD and Ford’s TDCi), you easily end up with the infamous Anti Pollution Fault error code after firing the engine. Sometimes it really means something is very wrong, often it only means that a probe is faulty. Sometimes some car shop do not replace/fix the probe but just reset it, so the problem stops only for time. And later it would pop-up and cause the engine to work in degraded mode, stuck to less than 2500 RPM or so – not great. On my HDI-based car, the mechanic decided to completely deactivate the probe, faulty when the car was only a few years old and with less than 50000km, considering it is not worth being changed to a new one that may die early as the original part anyway. Since then, the engine works nicely but on startup there is this Anti Pollution Fault error code that stays on. Not really dramatic but it causes you to pay actually less attention to any error message.

So all modern cars are electronics or even computer-based. But it is unlikely that you’ll manage to access to any code running. For your security they might say. Convenient to fake gaz emission tests, nonetheless.

Still, these days, you can get for cheap some OBD-II devices, OBD standing for on-board diagnostics. It is quite limited in scope and a capabilities, still, it can be used to set off error codes.

I tested a few (libre) software and cheap hardware. What worked for me (Peugeot car with HDI engine) is a bluetooth ELM327  (10 €) device along with AndrOBD (available through F-Droid). It provides data seemingly accurate and reset error code actually works (when the contact is on but engine is off).

I also tried an WiFi ELM327 device, the dedicated software failed to connect or was not providing any usable info. I’d be interested in any other option (for instance with a GNU/Linux laptop instead of F-Droid phone).


Fixing black screen during boot caused by LVDS-panel presence assumption by GMA 3650 drivers

On a Intel DN2800MT-based system, so having Graphics Media Accelerator 3650 integrated processor graphic card, your screen turn to black/off during the boot process, exactly starting when the system switch to framebuffer if you connect a VGA screen (no problem so far with HDMI).

Passing nomodeset or any similar option is of no help.

You cannot invent it, apparently GMA 3600 kernel DRM driver always assumes there is a LVDS panel, as it would on laptop but probably not on home servers, and defaults to a 1920×1080 panel.

So you need to add to the grub kernel line:


Or, in /etc/default/grub :


And run update-grub afterwards.

Dealing with WRITE FPDMA QUEUED hard disk trouble

Recently, on one of my servers, I had the main hard disk being set to failsafe read-only with the following ATA errors logged in /var/log/kern.log:

ata1.00: failed command: WRITE FPDMA QUEUED
ata1.00: cmd 61/00:90:40:7e:85/04:00:ea:00:00/40 tag 18 ncq 524288 out
res 40/00:0c:40:b6:85/00:00: ea:00:00/40 Emask 0x10 (ATA bus error)
ata1.00: status: { DRDY }
ata1.00: failed command: WRITE FPDMA QUEUED
ata1.00: cmd 61/00:98:40:82:85/04:00:ea:00:00/40 tag 19 ncq 524288 out
res 40/00:0c:40:b6:85/00:00:ea:00:00/40 Emask 0x10 (ATA bus error)
ata1.00: status: { DRDY }
ata1.00: failed command: WRITE FPDMA QUEUED

It looks like a physical issue with the drive. Though there was no specific error reported by  smartctl -a /dev/sdX, and the disk was quite new (just one year old), a Western Digital Red (SATA 3 model WDC WD40EFRX-68WT0N0). The mainboard being only SATA 2, the drive is not at all pushed to its limits.

The SATA cables were the same age and SATA 3 and not in bad apparent condition except it looks like they did not stayed perfectly plugged in over time.

I switched the apparently faulty disk to the SATA connector used by the secondary hard disk and made sure they are both  properly plugged: so far, it fixed it. It really looks like a SATA cable issue.


How to properly set contrast on Iiyama ProLite GE2488HS-B1

In the spirit of this Finnish IT retailer listing most returned products, for once, this is not really an howto. The easiest solution I found was to return it. The contrast and luminosity is impossible to set. It changes over reboot, it changes over operating system. And even set to get high contrast, black is never black, despite Iiyama claiming that “it is also possible to adjust the brightness and the dark shades with the Black Tuner, giving greater viewing performance in shadowed areas”. I replaced it with a SyncMaster S24D340H and had none of these problems.

Side note: I also had a defective pixel, but that could happen I assumed. Well, turns out that out of 16 comments of the shop, 4 report 0 day defective pixels.

Synchronizing your (Roundcube) webmail and (KDE) desktop with a (Android) phone

So I finally got an Android-based phone. I thought waiting for Ubuntu/Firefox stuff to be released but my current one (Bada-based: never ever) died.

First, I learned that actually you need to lock your phone with a Google account for life. It just confirmed that the sane proper first steps with this is too remove anything linked to Google.

First place to go is to F-Droid. From there, instead of getting tons of shitty freeware from Google Play/Apps/whatever, you get Free Software, as in freedom even though I like free beer.

Using ownCloud? From F-Droid, get DavDroid. Yes, that works perfectly and is easy to set up, unlike the Dav-related crap on Google Apps. The only thing you have to take care of, if your SSL certificate (trendy topic theses days) is self signed, is to make a certificate the specific way Android accepts them. For now, they recommends to do it like:


openssl req -new -x509 -days 3550 -nodes -out $KEY.pem -keyout $KEY.key
openssl x509 -in $KEY.pem -outform der -out $KEY.crt

Apart from that, everything is straight-forward. You just add your IMAPS, CalDav and CardDav info like you did with KDE and Roundcube. And can obviously also use mozilla sync through your ownCloud.


Update: As described in this recent post, it’s best to use options -newkey rsa:4096 -sha512.

Running Debian GNU with kFreeBSD

As you could have guess considering my latest update to my iPXE setup, I’m currently giving a try to Debian GNU along with FreeBSD kernel – Debian GNU/kFreeBSD.

The hardware I’m giving this try with is neither simple nor complicated: it’s old but it’s also laptop; a Dell Latitude C640 with a P4 mobile CPU and 1GB RAM.

The install was made over network. There’s nothing overly complicated but to avoid wasting time, it’s always good to properly RTFM. For instance, I learned too late that kFreeBSD does not handle / partition set on a logical one. I did not understood exactly how come, but I had to get my / partition on ufs (ext2 for /home was ok though). I did not even got into ZFS, as it looks like it’s not recommended with a simple i686 CPU. It took me a while and find no way to get my NFS4 partitions mounted as usual from /etc/fstab, or even with mount, I had to add a dirty call to /sbin/mount_nfs -o nfsv4 gate:/all /path in /etc/rc.local. And when it came to Xorg, I found the mouse to be sometimes working, sometimes not, plenty of overly complicated and confusing info on the web, to finally come up with a working /etc/X11/xorg.conf containing only  Section “ServerFlags”  Option “AutoAddDevices” “False” EndSection (on three lines).

These are some little inconveniencies that you would not expect with a recent GNU/Linux system install, that the debian-installer does not prevent you in any way to hit/create. I’m not even sure that I found the best fixes for them. It feels a bit like installing RedHat 5.2 🙂 with is more than what I actually expected.

So far I did not encountered any issue to get anything working but the suspend/sleep and general energy management looks much less reliable (with xfce4). On a side note, the fact that only OSS is available with kFreeBSD pushed me to update my script, I expect it to run on any BSD now.

Setting up a silent/low energy consumption home server (DHCP/DNS/SMB/UPnP)

Most users are probably fine with their ISP modem/box that even provides an hard disk. But having it’s own home server gives full control over the process and it’s not something utterly frivolous: no storage space real limit (except budget), finely tuned firewall, etc. In the past, it was at the expense of silence, energy consumption and space, but no longer, as described here.

Hardware setup:

The hardware is the following:
– board (APU) Intel DN2800MT
– RAM: 2 x 2 Go PC8500 DDR3 SODIMM
– Hard drive: Western Digital WD Green 3,5″ – SATA III 6 Gb/s – 2 To (Caviar)
– Secondary ethernet: ST1000SMPEX (Mini PCI-E)
– Wifi: TP-Link TL-WDN4800 (PCI-E)
+ a laptop adapter (16V, 4A)
+ a small case

The APU itself have a thermal design power (TDP) inferior to 10W. The hard drive is of the “Green” typen (RPM is lower than usual, etc). It’s important to note the RAM is of the SO-DIMM type (usually for laptops) PC8500 (max frequency supported by this board/CPU) and an laptop power charger/adapter is necessary instead of a regular power supply unit. Any case designed for the mini-ITX form factor could do. Low energy consumption, silent and small.

I was, actually, looking towards Sapphire Mini xxxx hardware at first, but it’s quite painy to get it shipped. So I went instead for the Intel Nano based hardware, despite its obvious drawbacks, which are supporting SATA II instead of 3, the SODIMM 4Gb RAM max and being known to be poorly supported on the target system, which is Debian GNU/Linux. I actually don’t care much for the GPU support, 4 Gb is more than enough for a home server and SATA II acceptable enough, so it should be fine anyway.

(Obviously, you should plug a hub on the secondary ethernet otherwise you’ll only be able to connect one box over ethernet)

Software setup:

Picking softwares:

Most obvious: we’ll run Debian stable on it, so to say Wheezy, the about-to-be-released-and-frozen one. The stable model in itself makes this distro the best choice for a server: this is stable and kept secure over time.

It’s supposed to work with an heterogenous network: GNU/Linux, MS Windows, over ethernet or wireless. So we’ll want:
– OpenSSH as secure shell, for the administrator
– any dhcpd server to provide IPs on the fly
– Samba for networked filesystems – and only, as we want each box to keep it’s original setup and not getting specific
– Bind to act as DNS cache and manage the domain
– Nginx as http server to provide basic sysinfo (phpsysinfo) and basic sysadmin (mostly: reset Samba passwords and connected wireless devices surveillance)
– transmission-daemon plus my script to provide a networked BitTorrent client
– minidlna to make files available to non computer networked devices

Start with Debian netinst base install:

Obviously we’ll want some SWAP space. 2 Gb should be more than enough. Then we’ll want three ext4 filesystems. One for user data, one for the system, one for a system copy, as fallback. If we had two different disk, obviously the system copy would be the second one.

We’ll start the basic debian installation with that in mind: we’ll anyway just install the debian base stuff with OpenSSH.





Setting up basic functionalities/networking after reboot:

First, we’ll install some useful utilities:

apt-get install lm-sensors hddtemp cpufrequtils debfoster etckeeper localepurge
ethtool emacs23-nox ntp wget

Regarding sensors, you should configure hddtemp to run as a daemon listening on and run:


At this point, network devices should be known to the system. We have quite usual hardware so correct modules should already be loaded. lspci should return:

01:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
02:00.0 Network controller: Atheros Communications Inc. AR9300 Wireless LAN adaptor (rev 01)
03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 06)

Edit the NAME strings in /etc/udev/rules.d/70-persistent-net.rules in order to have eth0 being the internet device, eth1 and wlan1 the intranet ones, for clarity sake. You may unload and reload modules of these devices in order for them to get their definitive name.

We’ll use hostapd to provide Wifi access.

apt-get install hostapd




## base

## wifi mode

## access with WPA PSK

# hw address filter (relaxed, as it is not real security)

touch /etc/hostapd/hostapd.deny

(this enable WPA2 access, if you want also WPA1, you must set wpa=3 and uncomment wpa_pairwise)

Then we’ll configure the network, defining a different subnet for wired and wireless connectivity. Some tutorials on the web propose to bridge the wireless to the wired. We won’t do that, we actually want to be able to easily distinguish the source of any request. Regarding security, the safe bet is to assume that wireless is always on the verge of getting cracked, so it must be kept confined.
editing /etc/network/interface:

# internet
auto eth0 iface
allow-hotplug eth0
iface eth0 inet dhcp

# intranet (wired)
auto eth1 iface
eth1 inet static 

# intranet (wireless) 
auto wlan1 iface
wlan1 inet static

We need a working dhcp daemon, able to dynamically register new boxes:

apt-get install isc-dhcp-server

In /etc/default/isc-dhcp-server:

INTERFACES="eth1 wlan1"

In /etc/dhcp/dhcpd.conf:

option domain-name "mynetworkname.ici";
option domain-name-servers;
option routers;

log-facility local7;

# wired
subnet netmask {

# wireless
subnet netmask {
option routers;

(it’s best to add, as fallback, to the domain-name-servers option the defaults DNS provided by your ISP, as shown in /etc/resolv.conf)

The dhcp client must be tuned a bit, /etc/dhcp/dhclient.conf:

prepend domain-name-servers;
supersede domain-name "mynetworkname.ici";

We obviously need ip forwarding, editing /etc/sysctl.conf:


and also immediately doing a:

echo 1 > /proc/sys/net/ipv4/ip_forward

We also need iptables

apt-get install iptables-persistent
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
/etc/init.d/iptables-persistent save

(I actually reused a perl script that also does some nice firewalling instead of simply doing this)

ifup eth1
ifup wlan1
invoke-rc.d hostapd restart
invoke-rc.d isc-dhcp-server restart

At this point, you should be able to log in with SSH on a distant box.

Provide local (dynamic) domain name server:

apt-get install bind9

Set up forwarders with your ISP’s DNS (as in /etc/resolv.conf) in /etc/bind/named.conf.options. Don’t bother doing that, /etc/bind/named.conf.options will be automatically generated by a script installed at the latest step. Instead, remove it so the script will make sure it is set proper at its first run:

rm -f /etc/bind/named.conf.options

You need to create zones (named as you like) in /etc/bin/named.conf.local:

zone "mynetworkname.ici" {
type master;
notify no;
file "/etc/bind/db.mynetworkname.ici";
allow-update { key dhcpupdate; };

zone "" {
type master;
notify no;
file "/etc/bind/db.10.0.0";
allow-update { key dhcpupdate; };
cd /etc/bind && cp db.local db.mynetworkname.ici


$TTL    64800
@           IN      SOA      gate.mynetworkname.ici. root.mynetworkname.ici. (
2         ; Serial
604800         ; Refresh
86400         ; Retry
2419200         ; Expire
604800 )       ; Negative Cache TTL

IN      NS      nano.mynetworkname.ici.
mynetworkname.ici.                     IN      A
mynetworkname.ici.    IN    MX         10
nano        IN    A
gate            IN      CNAME   nano
cp db.255 db.10.0


; BIND reverse data file
@       IN    SOA    nano.mynetworkname.ici. root.mynetworkname.ici. (
1                     ; Serial
604800         ; Refresh
8600               ; Retry
2419200               ; Expire
604800 ) ; Negative Cache TTL         NS  nano.mynetworkname.ici.
1.0                        PTR nano.mynetworkname.ici.

Now we add support for dynamic updates:

cd /etc/dhcp
dnssec-keygen -a hmac-md5 -b 256 -n USER dhcpupdate


key dhcpupdate {
algorithm hmac-md5;

(the secret being the latest string of .key file we’ve just generated)


ddns-domainname "mynetworkname.ici";
ddns-rev-domainname "";
ddns-update-style interim;
ignore client-updates;
update-static-leases on;

key dhcpupdate {
algorithm hmac-md5;
zone mynetworkname.ici. {
key dhcpupdate;
zone {
key dhcpupdate;

Restrict read access to files containing the secret key and restart all:

chmod o-r /etc/bind/named.conf.local
chmod o-r /etc/dhcp/dhcpd.conf
rm /etc/dhcp/Kdhcpupdate.*.key /etc/dhcp/Kdhcpupdate.*.private

invoke-rc.d isc-dhcp-server restart
invoke-rc.d bind9 restart

Put user data in place:

User data will go in /srv. So we’ll add a few symlinks, after mounting the partition.

mkdir /srv/home /srv/common
rm -r /home && ln -s /srv/home /home

We then add default dirs:

mkdir /srv/common/torrents /srv/common/download /srv/common/musique /srv/common/films /srv/common/temp
cd /srv/common && chmod a+w * -R

We’ll also make sure any new user get a ~/samba directory.

mkdir /etc/skel/samba

Make it accessible over Samba:

Users will access files with Samba: anonymous in r+w in common, user only in their ~/samba (we don’t allow direct access to ~/ to block any tampering with directories like ~/.ssh)

apt-get install samba libpam-smbpass


interfaces = eth1 wlan1
bind interfaces only = yes
security = user
invalid users = root
unix password sync = yes
pam password change = yes
map to guest = bad user
# discard filename mangling backward compatibility, see
mangle case = no
mangled names = no

comment = Données protégées
path = /srv/home/%S/samba
writable = yes

comment = Commun
path = /srv/common
browseable = yes
public = yes
force group = users
force user = nobody
guest ok = yes
writable = yes

comment = clef USB, etc
path = /media
browseable = yes
public = yes
force group = users
force user = nobody
guest ok = yes
writable = yes

We also want to use unix passwords for Samba instead of having two passwords databases.


@include common-password

Make it accessible with UPnP-AV/DLNA:

apt-get install minidlna



Once set up, we regenerate the database properly:

rm -f /var/lib/minidlna/files.db
invoke-rc.d minidlna restart

We add relevant iptables rules where SRC is the IP of your dlna client (you may want to alter this, for instance by using –source-range IP-IP instead of –src IP):

apt-get install iptables-persistent
iptables -A INPUT -i eth0 --src SRC -p udp --dport 1900 -j ACCEPT
iptables -A INPUT -i eth0 --src SRC -p tcp --dport 8200 -j ACCEPT
/etc/init.d/iptables-persistent save

Provide torrent client:

apt-get install transmission-daemon libtimedate-perl
invoke-rc.d transmission-daemon stop

mkdir /home/torrent
ln -s /srv/common/torrents /home/torrent/watch
usermod -d /home/torrent Debian-transmission

cd /usr/local/bin && wget && chmod +x
cd /etc/cron.d && wget
cd /etc/cron.weekly && wget

Edit /etc/cron.d/torrent (uncomment, check pathes – you may want to add ~/watch/ instead of ~/watch if symlinks are involveed, etc).

Edit /etc/transmission-daemon/settings.json

"alt-speed-down": 120,
"alt-speed-enabled": false,
"alt-speed-up": 1,
"blocklist-enabled": true,
"download-dir": "/srv/common/download",
"message-level": 0,
"peer-port-random-on-start": true,
"port-forwarding-enabled": true,
"rpc-authentication-required": false,
invoke-rc.d transmission-daemon start

And log rotation /etc/logrotate.d/torrent:

/srv/common/torrents/log {
rotate 2
su debian-transmission users

Provide basic info and management:

The following will provides reminders of upgrades to be performed.

apt-get install libapt-pkg-perl
cd /etc/cron.daily && wget && chmod +x apt-warn
phpsysinfo : basic system infos

phpsysinfo : basic system infos

We’ll use phpsysinfo to provide an overview of the system and a homemade script to allow distant administration.

apt-get install nginx phpsysinfo php5-cgi spawn-fcgi libfcgi-perl mysql-server libemail-sender-perl
cd /etc/init.d && wget && chmod +x php-fcgi && update-rc.d php-fcgi defaults
wget -O /usr/bin/ && wget -O /etc/init.d/perl-fcgi && chmod +x /usr/bin/ /etc/init.d/perl-fcgi && update-rc.d perl-fcgi defaults

mkdir /srv/www
ln -s /usr/share/phpsysinfo/ /srv/www/sysinfo


listen 80; ## listen for ipv4; this line is default and implied
listen [::]:80 default_server ipv6only=on; ## listen for ipv6

root /srv/www;
index index.html index.htm index.php;
autoindex on;
server_name localhost nano nano.mynetworkname.ici;

# restrict to local wired network
deny all;

# pass the  scripts to FastCGI server listening on
location ~ ^/sysinfo/(.*)\.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_index index.php;
include fastcgi_params;
location /sysadmin/ {
fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_na\
include fastcgi_params;


cgi.fix_pathinfo = 0;


define('PSI_ADD_PATHS', '/bin,/usr/bin,/sbin,/usr/sbin');
define('PSI_BYTE_FORMAT', 'auto_binary');
define('PSI_SENSOR_PROGRAM', 'LMSensors');
define('PSI_HDD_TEMP', 'tcp');
define('PSI_SHOW_MOUNT_OPTION', false);
define('PSI_HIDE_FS_TYPES', 'tmpfs,usbfs,devtmpfs');
define('PSI_HIDE_DISKS', '/dev/disk/by-uuid/8f7f616e-9140-4876-890a-cd6abfde837\
define('PSI_HIDE_NETWORK_INTERFACE', 'lo,mon.wlan0');
define('PSI_SHOW_NETWORK_INFOS', true);
sysadmin : admin unix/samba passwords and watch wifi connections

sysadmin : admin unix/samba passwords and watch wifi connections

Follows the specific sysadmin web interface:

apt-get install passwdqc liburi-encode-perl libdata-password-perl libdbd-mysql-perl libemail-send-perl
cd /srv/www
mkdir sysadmin

cd /srv/www/sysadmin && wget
cd /usr/local/bin && wget
chgrp www-data /srv/www/sysadmin/
chmod +x /srv/www/sysadmin/ /usr/local/bin/
chmod o-rwx /srv/www/sysadmin/ /usr/local/bin/
mysql -e "CREATE DATABASE sysadmin"
mysql -e "CREATE TABLE sambaclients (ip_address varchar(32) NOT NULL default '0', user_name text NOT NULL, PRIMARY KEY (ip_address))" sysadmin
mysql -e "CREATE TABLE wificlients (hw_address varchar(32) NOT NULL default '0', status varchar(32) NOT NULL default 'S', PRIMARY KEY (hw_address), ip_address varchar(32), hostname varchar(128))" sysadmin
mysql -e "CREATE USER 'www-data'@'localhost'"
mysql -e "SET PASSWORD FOR 'www-data'@'localhost' = PASSWORD('kdkadkda')"
mysql -e "GRANT ALL ON sysadmin.* TO 'www-data'@'localhost'"


my $db_password = "kdkadkda";


my $db_password = "kdkadkda";

It requires a cronjob to be set up in /etc/cron.d/sysadmin:

* * * * * root /usr/local/bin/
invoke-rc.d nginx restart
invoke-rc.d php-fcgi restart
invoke-rc.d perl-fcgi restart

Both http://nano/sysinfo and http://nano/sysadmin should work. The sysadmin script allows to change, on-the-fly UNIX passwords, by sending random ones by mail. It means that anyone within the intranet could sniff them out. That obviously won’t do if your legit users aren’t trustworthy.

(note : the sysadmin interface is in French but the strings can easily be translated in English. Adding gettext support would have been overkill here)

Create backup system:

With only one disk, having a redundant system is not optimal. But it’s still an okay failsafe.

The following assumes you gave a label to your root partition, something like wd2Tdebian64 here. Create a filesystem on the backup partition:

mkfs.ext4 -L wd2Tdebian64bak /dev/sda7
mkdir /mnt/sysclone

Add /etc/cron.weekly/backup-system (based on

if [ `hostname` != "nano" ]; then exit; fi

## system cloning
ignore="dev lost+found media proc run sys tmp srv"

# determines which partition is currently / by reading /etc/fstab
orig=`cat /etc/fstab | grep $sys | cut -f 1 | cut -f 2 -d = | sed 's/ //g'`
case $orig in
echo "Unable to determine whether we are currently using $sys or $bak, we found $orig. Exiting!"

# then proceed

# easy reminder of the last cloning run
date > /etc/.lastclone
echo "$orig > $dest" >> /etc/.lastclone
etckeeper commit "cloning system from $orig to $dest" >/dev/null 2>/dev/null

# mount clone system
if [ ! -d $mount ]; then exit; fi
mount -L $dest $mount

# set up ignore list
for dir in $ignore; do
touch /$dir.ignore

# do copy
for dir in /*; do
if [ -d $dir ]; then
if [ ! -e $dir.ignore ]; then
# update if not set to be ignored
/usr/bin/rsync --archive --one-file-system --delete $dir $mount/
# otherwise just make sure the directory actually exists
if [ ! -e $mount/$dir ]; then mkdir $mount/$dir; fi
rm $dir.ignore

# update filesystem data
sed -i s/^LABEL\=$orig/LABEL\=$dest/g $mount/etc/fstab

# make system bootable (use --force: gpt partition table)
/usr/sbin/grub-mkdevicemap 2>/dev/null
/usr/sbin/update-grub 2>/dev/null
/usr/sbin/grub-install --force `blkid -L $orig | tr -d [:digit:]` >/dev/null 2>/dev/null

# (sleep to avoid weird timeout after rsync)
sleep 10s

# then cleanup
umount $mount
fsck -a LABEL=$dest > /dev/null

## EOF

Final tuning: set mails, restrict SSH access, etc:

We activate exim4 for direct SMTP (and make sure the ISP does not block the relevant traffic) with the command:

dpkg-reconfigure exim4-config

Then we want some specific SSH access model. We already set up the sysadmin interface to change users password – both Samba and unix. But we actually have only one admin here. He’s own account will be the only one given SSH access. No root direct access. And he’ll be able to connect with a password only from wired intranet (eth1). Otherwise, internet (eth0) or wireless intranet (wlan1) will require a pair of SSH keys. To achieve this, we’ll actually restrict SSH to members of the staff unix group (just in case, at some point, we want to add a second one).

To achieve this easily, will plug OpenSSH into xinetd.

We have a few terminals open on the server. We shut SSH down (opened sessions wont be affected) and forbid the init script to start it anymore:

invoke-rc.d ssh stop
touch /etc/ssh/sshd_not_to_be_run

We change a bit the default configuration in /etc/ssh/sshd_config:

PermitRootLogin no
X11Forwarding no
AllowGroups staff
PasswordAuthentication no

We add the relevant user to the group:

adduser thisguy staff

Then we set up xinetd to run it:

apt-get install xinetd

Edit /etc/xinetd.d/ssh_intranet:

# To work, sshd must not run by itself, so /etc/ssh/sshd_not_to_be_run
# should exists

# only from local wired network
service ssh
socket_type     = stream
protocol        = tcp
wait            = no
user        = root
bind            =
only_from    =
server          = /usr/sbin/sshd
server_args     = -i -o PasswordAuthentication=yes
log_on_success  = HOST USERID

# from local wireless network
service ssh
socket_type     = stream
protocol        = tcp
wait            = no
user        = root
bind            =
only_from       =
server          = /usr/sbin/sshd
server_args     = -i
log_on_success  = HOST USERID


This set up only access for intranet interfaces (eth1 and wlan1 if you named them as recommended in this page). Internet interface IP is obtained with DHCP so it would be a pain in the ass to keep it up to date, especially if we’re behind a dynamic IP. However, xinetd does not allow to set interface by device name but wants an IP. So we need to script this. And, at the same time, we’ll deal with Bind DNS forwarders so it does proper caching. So we’ll add /etc/dhcp/dhclient-exit-hooks.d/xinetd-bind:


# SSH over xinetd requires the IP to be hardcoded
if [ -n "$new_ip_address" ]; then 

    # change only if we have a new ip and if this one mismatch the old
    if [ "$new_ip_address" != "$old_ip_address" ] || 
         [ ! -e $XINETD_CONFFILE ]; then

        echo "# DO NOT EDIT, automatically generated by $0
# (IP changed from $old_ip_address to $new_ip_address)
# `date`
service ssh
  socket_type     = stream
  protocol        = tcp
  wait            = no
  user            = root
  bind            = $new_ip_address
  server          = /usr/sbin/sshd
  server_args     = -i
  cps             = 30 10
  per_source      = 5
  log_on_success  = HOST USERID


        # now reload xinetd
        invoke-rc.d xinetd restart >/dev/null 2>&1

# Bind DNS cache need forwarders similar to the content of resolv.conf
if [ -n "$new_domain_name_servers" ]; then
    # change only if we have DNS
    if [ "$new_domain_name_servers" != "$old_domain_name_servers" ] ||
        [ ! -e $XINETD_CONFFILE ]; then

         echo "// DO NOT EDIT, automatically generated by $0
// (IPs changed from $old_domain_name_servers to $new_domain_name_servers) 
// `date`
options {
        directory \"/var/cache/bind\";

        // If there is a firewall between you and nameservers you want
        // to talk to, you may need to fix the firewall to allow multiple
        // ports to talk.  See

        // If your ISP provided one or more IP addresses for stable 
        // nameservers, you probably want to use them as forwarders.  
        // Uncomment the following block, and insert the addresses replacing 
        // the all-0's placeholder.

        forward first;
        forwarders {" > $BIND_CONFFILE

        # add valid forwarders
        for server in $new_domain_name_servers; do
            # (verbose) skip local ips
            if [ ! -n "`ifconfig | grep ":$server "`" ]; then 
                echo "                $server;" >> $BIND_CONFFILE
                echo "                //SKIP THIS LOCAL IP! $server;" >> $BIND_CONFFILE


        echo "        };

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };

       # now reload bind
       # (this may be useles because another script may do that already)
       invoke-rc.d bind9 restart >/dev/null 2>&1

It should modify conffiles and restart daemons only if there is an actual change. You can test that it works properly doing:

ifdown eth0 && ifup eth0

Then you can make a few SSH login test and see results in /var/log/auth.log.

At this point, you should realize that this perfectly working setup has an obvious drawback: if you’re wirelessly connected (subnet `ssh nano` will, thanks to the DNS, actually do a `ssh`. And per our xinetd rules, you’ll get kicked out, as we accept on this IP only clients from the same subnet ( So you’ll have to manually type ssh to be able to connect. We’ll add an iptable rule to fix this: we’ll say that whenever we try to connect to over ssh from wireless interface, we’ll redirect to same port. So we’ll do:

iptables -t nat -A PREROUTING -p tcp -i wlan1 --destination --dport 22 -j DNAT --to
/etc/init.d/iptables-persistent save


Update 1: Yeah, just published and already patched. Ahem. I noticed that, on reboot, sometimes hostapd is not working as expected. Users can connect but never get an IP. The LSB  init script of hostapd looks odd to me, since it actually makes it starting before dhcpd. I modified /etc/init.d/hostapd so isc-dhcp-server $network gets in Required-Start and then ran rc-update.d hostapd.

Update 2: /media was configured to be served over Samba but no automount was set for USB mass storage devices. Here it is, (not thoroughly tested as I don’t use such devices much), edit /etc/udev/rules.d/80-removable-usb.rules:

ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="sd*", ENV{ID_FS_TYPE}!="", SYMLINK+="usb%k"
ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="sd*", ENV{ID_FS_TYPE}!="", RUN+="/bin/mkdir /media/usb%k"
ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="sd*", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_extra_options}="dmask=0000,fmask=0111,"
ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="sd*", ENV{ID_FS_TYPE}!="", RUN+="/bin/mount -t auto -s -o $env{mount_extra_options}noatime,nodiratime,noexec,nodev /dev/usb%k /media/usb%k", OPTIONS="last_rule"
ACTION=="remove", SUBSYSTEMS=="usb", KERNEL=="sd*", ENV{ID_FS_TYPE}!="", RUN+="/bin/umount /media/usb%k"
ACTION=="remove", SUBSYSTEMS=="usb", KERNEL=="sd*", ENV{ID_FS_TYPE}!="", RUN+="/bin/rmdir /media/usb%k", OPTIONS="last_rule"

Update 3: I added /srv to the list of directories to be ignored by the backup script, as it contains data.

Update 4: Now /etc/xinet.d/ssh is split between ssh_intranet and ssh_internet, the later being generated by a script in /etc/dhcp/dhclient-exit-hooks.d/. This avoids us to hardcode IPs by hand. Still, it implies hardcoding IP in conffiles, so it must be kept in mind when doing major software upgrade that may imply conffile syntax change, etc.

Update 5: I noticed auto eth0 was missing in /etc/network/interfaces. I added it (and maybe Update 1 was related to that).

Update 6: I added sample firewall rules for minidlna.

Update 7: In case you have no static IP from your ISP, you may want to create a free account on no-ip and install a client:

apt-get install ddclient

And configure /etc/ddclient.conf

invoke-rc.d ddclient restart

Update 8: Now debian packages are provided, notably for torrents over SAMBA management.

Update 9: Use usual listen statement in /etc/nginx/site-available/default

Update 10: Deactivate Samba backward compatibility filename mangling

Reminder, needs to be changed checked whenever the server is relocated:

(obviously you should not use any sample password provided in this page)

We avoided hardcoding IPs but it was not always possible. Yes we did. However, in case of an ISP/main network change, which usually implies IP changes, make sure the following are properly updated by the dhclient:

/etc/bind/named.conf.option: ISP DNS IPs as in /etc/resolv.conf
/etc/xinetd.d/ssh_internet: internet IP as provided by ifconfig

Disclaimer: this whole setup has been made to be maintainable by people that have not much experience in computer system administration – but enough to log in via SSH without being completely lost in limbo. As such, you’ll probably notice I made some tradeoff between security and easiness, for instance by providing in clear text the Wifi passphrase on the web sysadmin page. Anyway I think most important pieces are rock solid and secondary one does not matter much (Wifi is insecure by design, by concept I would even dare to say, using it is itself such an obvious tradeoff).

(this is still being tested, I may update this page soon; it’s likely I forgot to mention a few apt-get of perl packages required by the scripts; please mail me if you find any flaws or obvious issues with what is proposed here)