NAS (pt. 1): Parts and build

In a previous post, I explained how a disk failure prompted me to build that NAS I’ve dreamed of for years. That happened months ago, but in the meantime we’ve been reviewing mainboards, CPU specs, reading other configurations over and over again. We finally settled on a setup of our own.

We did so with a set of constraints. First anything with less than 4 HDD was out of the question. You need at least 3 HDD for RAID5, 4 for RAID6, with RAID1 (mirroring) and only 2 HDD you would waste half of your total disk space, and RAID0 (no redundancy) would be completely insane, disk failures do happen, believe me! Since we also want to upgrade our setup, we looked for mainboards with at least 6 SATA.

Second, it would run FreeNAS, anything else doesn’t come close. We avoided some component that are known to cause trouble in FreeBSD, mostly some NIC. Although as far as I can remember I didn’t have any problem for a while.

Finally I’ve been a long time advocate of ECC memory for NAS. However ECC memory is expensive and finding cheap and reliable mainboard/CPU that support ECC is difficult. So we relaxed that constraint. But I’d be happy to know about any good alternative.

Parts

Our base setup is 12TB HDD / 16GB RAM upgradable to 24TB HDD / 32GB RAM. Total cost was 688€ and 310€ without any HDD. We were lucky enough to receive HDD from different batches even though we bought all of them from the same vendor. Similar HDD would increase the risk of multiple disk failing at the same time (which is a very bad thing for a RAID5 setup).

  • CPU: Intel G3900
  • MB: Gigabyte GA-B150M-DS3P
  • RAM: 2x8GB Crucial DDR4
  • HDD: 3xWD Red 4TB
  • PSU: Corsair VS350
  • Case: CoolerMaster Elite 343
  • USB: SanDisk Cruzer Fit SDCZ33-016G-B35

Now if we could change only one thing, that would be the CM Elite 343 case. While it is possible to mount 6 HDD, their positioning is not optimal and arranging the cables properly was difficult.

Build

The build was relatively straight forward. As I said we had some problem with the CM Elite 343 case. Another problem was the SYS_FAN cable from the case which was too short to reach the MB. We also had some problem with one of the two mainboards which constantly rebooted. We had to reset the CMOS to fix it. But now everything works flawlessly.

I already booted FreeNAS 11, everything seems to be working properly. The idle consumption is 28W, peaks at 60W on boot, but we’ll see about that when the system will be fully installed. The setup is amazingly silent, although the front system fan is not connected for now.

In the next episode I will install and configure FreeNAS on Gandalf (it already has a name).  Until then I’m going to fold the gazillion amazon boxes spread all over my apartment.

WIDE DHCPv6 flood

On FreeBSD we generally use WIDE DHCPv6 (also known as KAME DHCPv6, dhcp6c or simply dhcp6) as DHCPv6 client. However a rare bug can trigger this client to flood the DHCP server with requests. This happened to us and quickly prompted online.net to block our server for outgoing flood. This scared me a bit at first, as I thought we might have been part of a DDoS attack. Thankfully that was not the case.

But we still had to disable dhcp6 (and consequently IPv6). On Linux it is generally recommended to limit the DHCPv6 traffic using iptables rules. However this is not as simple with PF on FreeBSD. You cannot provide a limit on the packet rate per rule. You can limit the connection rate (see max-src-conn-rate), but I’m not sure this could be of any use here. It should be possible to use altq but this is not part of the GENERIC kernel. I really didn’t want to compile a custom kernel just as a workaround.

Instead I used another DHCPv6 client, namely ISC DHCP client (isc-dhcp43-client). Just create /usr/local/etc/dhclient6.conf and configure your DUID:

interface "igb0" {
  send dhcp6.client-id <DUID>;
}

On FreeBSD, isc-dhcp43-client doesn’t come with any rc starting script, so here is one for DHCPv6 (you should place it in /usr/local/etc/rc.d/dhclient6:

#!/bin/sh
#
# PROVIDE: dhclient6
# REQUIRE: DAEMON
# KEYWORD: dhcp
#
# Add the following lines to /etc/rc.conf to enable dhclient6:
#
# dhclient6_enable="YES"
#

. /etc/rc.subr

name="dhclient6"
desc="ISC DHCPv6 client"
rcvar="dhclient6_enable"

start_cmd="dhclient6_start"
stop_cmd="dhclient6_stop"

dhclient6_start()
{
  /usr/local/sbin/dhclient -cf "${dhclient6_conf}" -P -v "${dhclient6_iface}"
}

dhclient6_stop()
{
  if [ -r "${dhclient6_pid}" ]
  then
    kill -- -$(cat "${dhclient6_pid}")
    rm -f "${dhclient6_pid}"
  fi
}

load_rc_config ${name}

: ${dhclient6_enable="NO"}
: ${dhclient6_pid="/var/run/dhclient6.pid"}
: ${dhclient6_conf="/usr/local/etc/dhclient6.conf"}
: ${dhclient6_iface=""}

run_rc_command "$1"

Finally enable this in /etc/rc.conf:

dhclient6_iface="igb0"
dhclient6_enable="YES"

Today’s movie: Doctor Strange

“I like red cape.”

Doctor Strange by Scott Derrickson. It was cool, a no brainer for an easy evening! Although not exactly what we initially planned to see but you’ll probably know more about that in our next installment. Now if I had the power to refill beer indefinitely, I’d totally over abuse that! Beside that I’d also point out that the GFX were particularly nice. It reminded me of some other cool things.

Awesome rant

I am a long time user of Awesome WM as my window manager. However we had a major version bump (3.5 -> 4.1) from the ports today and my configuration disintegrated like a mellowcake that just found itself teleported into the twenty-fourth dimension. This is a recurring problem with this window manager, their API is as much stable as a node.js developer under influence on St Patrick’s day. Now if you are using the default configuration you’ll be fine. But if your configuration is heavily customized, man, you are in for a ride!

Thankfully FreeBSD port maintainers being the good guys that they are, it is still possible to install the older version from the x11-wm/awesome3 port. This will remove x11-wm/awesome-vicious though. But if you ever need to install lib-vicious for Awesome3, I archived my own version here. This also comes with patches for some widgets on FreeBSD which I have been too lazy to report (my bad).

Now I am not yet entirely sure if I will stay on Awesome3 for a while, upgrade to Awesome4 eventually, switch to i3 or xmonad. Well, we’ll see about that.

Hide logs from wheel users

If you have grown accustomed to FreeBSD administration, you’ve probably learned that users need to be member of the wheel group to be able to use the su command. Some in the land of GNU don’t agree so much with this way of doing and firmly believe that wheel is an instrument of power (which is true in a literal sens) but that’s another story.

In fact I am perfectly fine with this save for one little detail. By default most log files are owned by root:wheel. Altough while some of them have permission 600, a lot of them are 640 which means that members of the wheel group will be able to read them. We have basically two solutions to fix this:

  • Fix permissions in /etc/newsyslog.conf.
  • Use another group instead of wheel for the su command.

Fixing newsyslog.conf is quite easy, just replace the mode column with any permission you fancy (in our case 600). Don’t forget to restart newsyslog and fix existing permissions with find /var/log -type f -exec chmod 600 {} \;.

However that might not be enough. You see on most BSD wheel has gid 0, whereas on Linux it is root that has gid 0. Nobody is supposed to be a member of root, but it serves as a general purpose group for anything owned solely by root. As such you can often use chown 0:0 as a synonym of owned by root.

But root:root on Linux would not have the same meaning as root:wheel on BSD. In particular you can generally suppose that files owned by root:root with permission 640 on Linux are only readable by the root user but the same supposition doesn’t translate so well for us BSD users.

While I’m not keen of importing such kind of Linuxism into FreeBSD, one way to deal with it would be to use another group for su users. For this we would:

  • Create the su system group.
  • Move all members of wheel to this group.
  • Modify /etc/pam.d/su to use group=su instead of group=wheel.

Now I don’t personally do that, but I guess what you do it’s your business.

Today’s movie: Ex Machina

<INSERT APPROPRIATE QUOTE HERE>

This movie by Alex Garland was on my watchlist since quite some time. Bring together AI, consciousness, existentialism, deal with the singularity and stuff and you got me talking. There are so many ways that such a movie can go wrong. But that’s not a problem here. The narrative is well thought, and it gets to the point. The movie is also honest with itself. But that’s about just that. In the end there is nothing new to learn, no door opened on further reflection and this is what bugged us.

Spoiler alert! Warning! Spoiler ahead!

I guess there are several possible readings. But if you think it revolved around a robot passing the Turing test, my two cents are that you are probably wrong. Instead the whole purpose wasn’t a test of Ava’s ability to fake human behavior and consciousness as she could probably pass this test with ease (as did her preceding iterations), but whether an average human (Caleb) was still capable of seeing her as just a machine or at least not human. And obviously that test has failed.

My other guess is that Nathan, beside being a total drunk twat hypocritical misogynistic asshole, is actually on our side. This guy is genuinely scared by the consequences that a singularity just round the corner will have on humanity (beyond all ethical concerns). So his purpose was not to create the first human-like AI, but to get one step ahead and limit the damage. He wanted to draw the blurry line that would separate machines from humanity so that he could let those machines exist (which he sees as inevitable), but at the same time ensure that humanity thrives and stays true to itself.

Now being a smart guy, Nathan was capable of this assumption. Also forcing himself to make this distinction had a very negative impact on his personality (probably turning him into the boozer and asshole that he is). But he was truly aware of that which is why he designed Ava with such apparent robotic features and why he needed an external human factor (Caleb) to continue his tests.

OK so after some more explanations by Alex Garland that’s probably not what he meant at all. Instead it really is just a test of how smart she is and will she escape. But I tend to disagree, but that’s just my opinion.

Custom user Xsession with SDDM

Debian stretch is out, a lot of obsolete packages, a lot of major upgrades, which all in all resulted in quite a painful transition the last few days. But I’ll tell you more about that in the following posts.

I don’t really spend much time on Linux nowadays so KDE (along with KDM) has always been my goto solution for a jack all trade no-BS works-out-of-the-box desktop environment. And it worked like that just fine, until… well you know how software goes. KDE has been upgraded, KDM has been depreciated and replaced with SDDM.

I also use xsession so that I have a common way of starting session scripts and daemons (such as this one) and configuring stuff across different desktops. I generally selected custom session in the display manager and that was it. But SDDM does not seem to provide a way to do so, or at least that’s not so clear.

By default, it will execute /etc/sddm/xsession which itself sources /etc/X11/Xsession to which it will pass as argument the value of the Exec line in the desktop file (located in /usr/share/xsessions) describing the currently selected session.

If we want to bypass this, we need to scrap the argument passed to /etc/X11/Xsession no matter what SDDM thinks the current session should be. To do so create a wrapper for Xsession in /etc/X11/user-Xsession:

#!/bin/sh

export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin

# Discard argument, we don't care about selecting the desktop environment.
/etc/X11/Xsession

And now configure SDDM to use this instead of its own version of it, in /etc/sddm.conf:

[X11]
SessionCommand=/etc/X11/user-Xsession