Tag Archives: freebsd
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"
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 thesu
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 usegroup=su
instead ofgroup=wheel
.
Now I don’t personally do that, but I guess what you do it’s your business.
MSP430 and Contiki on FreeBSD
If you were trying to compile a Contiki application that targets an MSP430 platform (T-Mote Sky for example) on FreeBSD, you might have noticed that msp430-gcc was removed from the port tree and replaced by gcc-msp430-ti-toolchain. Contiki does not support this newer toolchain so you might find yourself a bit stuck there.
Fortunately you can still access the last version of the msp430-gcc packages from the FreeBSD archives:
Suspend on lid closed + battery
If you use FreeBSD 11 on the good ol’ ThinkPad X201, you’ve probably noticed now that suspend and resume work perfectly flawlessly with the latest FreeBSD release.
You probably wish to take advantage of this and suspend your laptop automatically when the lid is closed. Nothing could be easier:
sysctl hw.acpi.lid_switch_state=S3
Save this option /etc/sysctl.conf
for it to be permanent.
Close the lid, the laptop goes to sleep, you’re done!
It’s that simple.
But, with this method it will go to sleep each time the lid is closed, completely ignoring whether the laptop is on battery or not. And if you’re like me you probably don’t want this. Instead you want it to suspend itself when the lid is closed and the laptop is on battery. Easy enough! We just have to invoke the mighty power of devd along with a very little shell script.
First we need to tell devd how to react when the lid is closed. Put this in /etc/devd/lid.conf
, then restart (service devd restart
):
# Notify lid close/open events. notify 10 { match "system" "ACPI"; match "subsystem" "Lid"; action "/etc/acpi/lid.sh $notify"; };
Now we will make a script that checks the lid and AC line states and chooses to suspend the laptop when both the lid is closed and AC line is disconnected. This goes in /etc/acpi/lid.sh
:
#!/bin/sh lid="$1" # 0x00 is closed, 0x01 is open (see devd.conf) acline=$(sysctl -n hw.acpi.acline) # 0 is battery, 1 is online (man acpi) if [ \( "$lid" = "0x00" \) -a \( "$acline" -eq 0 \) ] then logger "Lid closed on battery. Going to sleep." acpiconf -s3 fi
Try it out! Disconnect the AC line, close the lid, it should go to sleep within seconds. However if it doesn’t work you might want to modify the script above a little to check whether lid events are received correctly or not.
Now you may use a modified version of this script to lock xscreensaver when the lid is closed and before the actual suspend. Well OK, I’ve done that for you:
#!/bin/sh # XScreensaver should be called BEFORE going to sleep to avoid the desktop to be # shown for a few seconds when the system resumes from sleep. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin lid="$1" # 0x00 is closed, 0x01 is open (see devd.conf) acline=$(sysctl -n hw.acpi.acline) # 0 is battery, 1 is online (man acpi) lock_display() ( socket="$1" display=$(echo "$socket" | tr "X" ":") # Temporary pid file for the watching command tpid=$(mktemp) # Wait until the display is actually locked. (timeout 2s xscreensaver-command -display "$display" -watch & echo $! > $tpid) | ( # Issue the lock command only when we know that # the watching pipe is ready. xscreensaver-command -display "$display" -lock while read line do line=$(echo $line | cut -d' ' -f 1) if [ "$line" = LOCK ] then # We have to kill the watching command manually before breaking. kill -TERM $(cat $tpid) break fi done ) rm $tpid ) # The X server may not be running if [ ! -d /tmp/.X11-unix ] then exit 0 fi # Lock each available display for socket in $(ls /tmp/.X11-unix) do # Lock the display logger "Locking xscreensaver on $socket" lock_display $socket & done # Wait until every displays are locked wait # Now we can suspend if needed if [ \( "$lid" = "0x00" \) -a \( "$acline" -eq 0 \) ] then logger "Lid closed on battery. Going to sleep." acpiconf -s3 fi
Linuxulator ist kaputt
Since a few weeks I’m running RELEASE on a custom kernel to use a patch that I made for a missing feature in the IPv6 stack (namely icmp_may_rst
).
But a few minutes ago I had the surprise to find that the Linuxulator was no longer working. Trying to run a Linux binary failed with the following error:
ELF binary type "0" not known. exec: test: Exec format error
Actually looking at kldstat
, the Linux kernel module wasn’t even loaded. Trying to load it manually gave me the following error:
link_elf_obj: symbol kern_sched_setscheduler undefined linker_load_file: Unsupported file type
OK so what is this sched_setscheduler
you are talking about? Well there you go!
Now the Linuxulator depends on that syscall, but for some reason the necessary option disappeared from my custom kernel configuration. All I had to do was to add it again and recompile:
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
And now I can run Linux binaries again!
Display WiFi RSSI on FreeBSD
On FreeBSD we also use the ifconfig command to configure wireless interfaces. The command ifconfig wlan0 list scan
lists available AP along with their SNR. However the ifconfig command does not display the RSSI/SNR on the current link. To do so we need another command, wlanstats. It is not included in base system but you can find it in the source tree under /usr/src/tools/tools/net80211/wlanstats
. This command also shows you the signal level (in dBm) and current transmit rate among other things.
I wonder why the RSSI is not visible with the ifconfig command. I suppose they wanted to regroup all those stats with another command. But again I wonder why this command is not part of the base system.
Giving Tuesday
Aside
Dedibox serial shell access
If you cannot access the shell on a FreeBSD dedibox from the online.net console, here is a quick tip. Create an alternate root account with csh or tcsh and access ttyu1 on this account instead. That’s almost precisely what the toor account is made for, except that we generally leave the default shell on root.
No idea why sh, bash and zsh are not working through the serial connection, more doesn’t work either, but vi does. Probably a termcap thingy ? If anyone has a clue…