Remembering TITR


So it's now been 16 years since the end of TITR (This Is True, Really) News. I still occasionally listen to the old recordings of what we now know as 'podcasts' and have a giggle. Scott, Tony, wherever you guys are, hope all is going well. If you want to share in on the laughs, I've put up the small archive I have on soundcloud.

Adding a PPS source to ntpd


So I recently got given a Symmetricom TimeProvider 100 to have a bit of a play with - and was excited to see an ethernet port marked "NTP" on the front. After firing it up and having no luck at all talking to it on this port other than ICMP ping packets, I trawled online to try and find the manual. That's a challenge! So, as a favour to Google and all others that try to find the manual for this damn thing, I've uploaded it here. Symmetricom TimeProvider 100 User Manual One thing that struck me is this little note:

Note: The NTP feature in the NTP port is currently not implemented.
Ok, so no NTP server running on it. A little bit of a shame, but we still have a PPS port. But its BNC?! Linux has an entire API for PPS sources, but the main one seems to be using the DCD lines on a physical serial port. But how to convert a 50 ohm BNC connection to a RS232 serial port?! Easy: dsc_0057 It turns out that the PPS signal is compatible with the logic levels of the DCD line. Now all that's left is to set it up software wise. I'm using Scientific Linux 7 - so this should work across CentOS and RedHat Enterprise Linux. Testing:
$ yum install pps-tools
$ modprobe pps_ldisc
$ ldattach 18 /dev/ttyS0
$ $ ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1474704714.000005460, sequence: 4828 - clear  1474702748.000922784, sequence: 3229
source 0 - assert 1474704715.000005644, sequence: 4829 - clear  1474702748.000922784, sequence: 3229
source 0 - assert 1474704716.000002819, sequence: 4830 - clear  1474702748.000922784, sequence: 3229
source 0 - assert 1474704717.000002645, sequence: 4831 - clear  1474702748.000922784, sequence: 3229
If all of the above works, congratulations. Your PPS source works. Now you get to finalise the configuration. Firstly, we need to set up udev to properly configure the serial port on boot, add the following to: /etc/udev/rules.d/pps-sources.rules:
KERNEL=="pps0", OWNER="root", GROUP="ntp", MODE="0660"
KERNEL=="ttyS0", RUN+="/bin/setserial -v /dev/%k low_latency irq 4"
Now we need to automatically load the pps_ldisc module on boot. Create /etc/modules-load.d/pps-source.conf and throw this in there:
## Load the PPS module on boot.
pps_ldisc
Next we need to configure systemd to attach the serial port to the PPS driver on boot. Create /etc/systemd/system/ldattach@.service and use this:
[Unit]
Description=Line Discipline for GPS Timekeeping for %i
Before=ntpd.service
 
[Service]
ExecStart=/sbin/ldattach 18 /dev/%i
Type=forking
 
[Install]
WantedBy=multi-user.target
Enable this on boot and specify your serial port: $ systemctl enable ldattach@ttyS0.service The last step is to configure /etc/ntp.conf to use your PPS source. One thing to keep in mind is that the PPS source doesn't contain an actual time - so you MUST have an NTP server set to a preferred time source. I use:
server 127.127.22.0 minpoll 4 maxpoll 4
server 0.au.pool.ntp.org iburst prefer
server 1.au.pool.ntp.org iburst
server 2.au.pool.ntp.org iburst
Restart ntpd now, and you should be done: $ systemctl restart ntpd After a while, you should see some good accuracy:
$ ntpstat -q
synchronised to atomic clock at stratum 1
   time correct to within 1 ms
   polling server every 16 s
$ ntptime
ntp_gettime() returns code 0 (OK)
  time db90b5e4.76394f80  Sat, Sep 24 2016 18:20:52.461, (.461812146),
  maximum error 5500 us, estimated error 1 us, TAI offset 0
ntp_adjtime() returns code 0 (OK)
  modes 0x0 (),
  offset -1.654 us, frequency -5.593 ppm, interval 1 s,
  maximum error 5500 us, estimated error 1 us,
  status 0x2001 (PLL,NANO),
  time constant 4, precision 0.001 us, tolerance 500 ppm,

Why people hate #systemd


So yeah, I've been forced into using SystemD for just about everything now that the entire community has taken the koolaid. I recently had a question where if a ConditionFileIsExecutable fails in the [Unit] section, the logs say that the service was started - but in fact the service won't attempt to be started. No errors, no warnings, but a message of success. This seemed strange, so I jumped onto #systemd on Freenode and ended up with the following conversation:

17:37 -!- Irssi: Join to #systemd was synced in 5 secs 17:38 < CRCinAU> ok - so if the start of a service fails because ConditionFileIsExecutable fails, is it expected to be a silent failure? 17:38 < CRCinAU> ie nothing in the journal or logged to state why a service failed? just a "Started" then nothing further? 17:39 < grawity> CRCinAU: yeah, it's supposed to be mostly silent 17:39 < grawity> unlike AssertFileIsExecutable=, by the way 17:39 < CRCinAU> logic behind that? 17:39 < grawity> its primary purpose is in filtering units which should or shouldn't auto-start 17:40 < grawity> logging failures at default level would result in too much logspam on most systems 17:40 < CRCinAU> o_O 17:40 < grawity> e.g. there's ssh-keygen.service with Condition= that at least one ssh_host_key is missing 17:41 < grawity> if you want things to be logged loudly, use Assert= 17:41 < CRCinAU> I don't see a problem with that? 17:41 < grawity> with what 17:41 < CRCinAU> a message that a file doesn't exist..... 17:41 < grawity> with users seeing "warning: ssh-keygen not started because EVERYTHING IS FINE" on every reboot? 17:42 < grawity> some programs install units with ConditionVirtualization=, which would either log warnings on every VM, or on every bare metal system 17:42 < grawity> if you want things to be logged loudly, use Assert= 17:42 < CRCinAU> wait........ 17:42 < CRCinAU> what the hell is systemd doing thinking about virtualisation? 17:43 < grawity> there are daemons which are only needed in VMs, or aren't needed in VMs 17:43 < CRCinAU> urrrmmmm....... 17:43 < grawity> e.g. systemd's own udev has no business running in a container 17:43 < CRCinAU> holy crap... so what you're telling me is systemd is still hungry and needs to be fed more? 17:44 < michich> another example: vmtoolsd.service:ConditionVirtualization=vmware 17:44 < CRCinAU> I think I just died a little inside in that level of retardation. 17:45 < grawity> so by your own logic, a few minutes ago you were telling me systemd should be checking for your config files, instead of your own daemons doing that themselves? 17:46 < CRCinAU> no - the unit failed to start, and had no warning. if there was a problem and the unit failed, I'd expect to see something that says "blah.service failed because ConditionFileIsExecutable failed" or similar. 17:46 < CRCinAU> not just "Unit blah.service started" 17:46 < CRCinAU> when it fact it wasn't 17:46 < CRCinAU> it *attempted* to start 17:46 < CRCinAU> but failed. 17:49 < CRCinAU> on another note, now I'm hearing that systemd is becoming virtualisation aware because users are too stupid to do "systemctl enable vmtoolsd.service" when they do a virtualised install? 17:49 -!- mode/#systemd [+b $a:CRCinAU] by evilgrawity 17:49 < CRCinAU> well, not even that... as I guess you'd have to install the VMWare tools in that situation to even have the service file in the first place - so it could even be part of the package install. 17:50 -!- #systemd Cannot send to channel 17:50 -!- CRCinAU was kicked from #systemd by evilgrawity [CRCinAU]
I'm kinda speechless now.

Postfix, LDAP and Fusion Directory


Recently, I've been going all out on deploying LDAP and realising how much easier it would have made my life over the years. Fusion Directory has proven to be a good management interface for keeping things in check.

That's the easy part though - now how do you go about making all your software to implement the features of LDAP and FusionDirectory? Sometimes with difficulty!

After a lot of mucking around, I've managed to get postfix working properly with LDAP as a source of email accounts, alias, forwards etc. We want to use the standard gosaMailDelivery flags to make life easy - and these are well documented for Fusion Directory.

Firstly, I'm going to assume that you already have openLDAP and Fusion Directory running. The documentation here is more than adequate to follow.

So now we're down to postfix.

Firstly, we want to handle accounts that postfix needs to deliver mail to. Create a new file /etc/postfix/ldap-accounts.cf and use the following:

server_host             = ldap.example.com
search_base             = ou=people,dc=example,dc=com
scope                   = sub
bind                    = no
version                 = 3
 
query_filter            = (&amp;(mail=%s)(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*I*])))
result_attribute        = mail

Now we want to handle aliases - so create /etc/postfix/ldap-aliases.cf:

server_host             = ldap.example.com
search_base             = ou=people,dc=example,dc=com
scope                   = sub
bind                    = no
version                 = 3
 
query_filter            = (&amp;(gosaMailAlternateAddress=%s)(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*I*])))
result_attribute        = mail

Next step is forwards with delivery to the local account as well - create /etc/postfix/ldap-forward.cf:

server_host             = ldap.example.com
search_base             = ou=people,dc=example,dc=com
scope                   = sub
bind                    = no
version                 = 3
 
query_filter            = (&amp;(|(gosaMailAlternateAddress=%s)(mail=%s))(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*I*])))
result_attribute        = mail,gosaMailForwardingAddress

And lucky last, we have forwards only - without a local delivery in /etc/postfix/ldap-forward-only.cf:

server_host             = ldap.example.com
search_base             = ou=people,dc=example,dc=com
scope                   = sub
bind                    = no
version                 = 3
 
query_filter            = (&amp;(|(gosaMailAlternateAddress=%s)(mail=%s))(gosaMailDeliveryMode=[*I*])(objectClass=gosaMailAccount))
result_attribute        = gosaMailForwardingAddress

Once these files have been created, we can configure postfix. I use a full virtual delivery - so no user accounts exist on the mail server. Add the following to /etc/postfix/main.cf:

virtual_alias_maps = proxy:ldap:/etc/postfix/ldap-aliases.cf proxy:ldap:/etc/postfix/ldap-forward.cf proxy:ldap:/etc/postfix/ldap-forward-only.cf
virtual_mailbox_maps = proxy:ldap:/etc/postfix/ldap-accounts.cf

That is the bulk of the setup done.

Basic implementation of StartAPI


As I've been using StartSSL for a long time to secure everything from SMTP / IMAP to this web site, I've gathered quite a few certificates. The scene has changed quite a bit these days with Lets Encrypt becoming available with free certs (but limited to 30 days). StartAPI was introduced by StartSSL to do a lot of the same features, but gives you a 1 year certificate that you are able to manually place wherever you like. No custom software, no daemons etc. In my mind, this is what Lets Encrypt should have been. I've created a few tools to assist in validating domains, and then retrieving certificates and am looking for people to help me test them before I release them to the general public. If you already use StartSSL, I'd be happy to hear from you and get you to test what I've built up. EDIT: After having a few people test it out and things work successfully, I've written some basic documentation and made it available on GitHub for testing / contribution.

N600 & N750 nightlies not getting built


Just wanted to write a quick note to explain why the current nightlies aren't working. The openwrt servers had an outage recently. As of now, svn.openwrt.org, downloads.openwrt.org and I think lists.openwrt.org are still down. As the nightly builds feed from svn.openwrt.org, the builds won't start again until svn.openwrt.org is restored. If you've just flashed an image, chances are that you can't install things like luci at the moment - as those are stored on downloads.openwrt.org. All in all, when things are back in working order, things should just magically start working again.

The feed from FlightRadar24's F-YMML4 receiver


Quite a while ago, I applied to host Flight Radar 24s receiver at my place near Melbourne Airport, Australia (YMML). It started off with the ID F-YMML1 (being the first in Victoria), but a faulty unit saw the handle change to F-YMML4. With it, there was a massive boost in ASD-B reporting for Victoria - being the first receiver that could pick up aircraft on the ground and at the gate at YMML. I always knew the coverage was fairly wide spread, but never really visualised it - until today. From my location, it covers high flight levels almost as far as Tasmania, and as north as the NSW border. In the attached screenshot, this plot shows all aircraft received by F-YMML4 in red. The normal FR24 feed shows in other colours. Rather good for a tiny receiver box. FR24 F-YMML4 plot

WD N600 & N750 image updates


Last night I made some changes to the build process of the generated images for the WD N600 and N750 routers. Starting from r48362, the following changes are active:

  1. The designated_driver_luci repository is enabled by default. This allows people to install luci by doing: opkg update && opkg install luci
  2. Added an entry to /etc/opkg/distfeeds.conf that will point to that revisions base packages
  3. Enabled building all KMODs for the openwrt kernel as packages. Combined with the above change, this allows auto-dependency resolution to work correctly.
As always, bug reports and comments are welcome.