VyOS 1.2.0 development news in June

If we haven't written any new blog posts in a while, that's because we've all been busy with development. Here is what happened since the last status update.

RADIUS authentication and authorization

We've had nominal support for RADIUS authentication for system login for a long time, but it was essentially useless because it required that the user account to already exist in VyOS to actually work, it was just a password checking method.

Kim Hagen found a way to implement real support for it and it appears to work fine (but of course needs testing). Apart from authentication, his implementation also supports authorization through the priv-lvl attribute. Privilege level 15 is mapped to admin users, anything below it is operator. This seems to be the most common way to do that, after Cisco.

Correct naming of PPTP and L2TP interfaces works again

The idea to switch to the upstream PPPD turned out to be premature — while it does have support for pre-up scripts, it still makes an assumption that the interface name is not changed by pre-up script, so remote access VPN interfaces were named pppX, which broke the "run show vpn remote-access" commands, and would break zone-based firewalls of people who rely on that naming.

We've re-applied the old patches for it to the latest upstream PPPD and opened pull requests for them, so if they are merged, we can finally stop building our own, and if not, we have clean patches that should be easy to apply to future releases.

Rewritten SNMP and SSH

Christian Poessinger did a lot of work on rewriting old Perl/shell code to Python and extending it. After making the switch from dnsmasq to PowerDNS recursor happen, he focused on SNMP and SSH, and now we have far cleaner implementations of both. In particular, support for SNMPv3 was cleaned up and improved.

SSH rewrite is not just a rewrite either: now it supports access controls through "set service ssh access-control <allow|deny> <user|group> <name>" commands.

Ongoing operational mode commands rewrite

In the old vyatta-op package, we have a lot of op mode commands that are not directly related to any configuration mode features. They make a good target for testing and refining the new operational command infrastructure. They also make excellent tasks for first time contributors.
Runar Borge answered our call to action and converted a whole bunch of those commands — that might have been the biggest pull request in terms of the number of involved commands we have ever received. While he's already done a great work, there are still plenty of commands to convert and thus lots of room for collabotation. That work is coordinated in https://phabricator.vyos.net/T689, and everyone is welcome to join it.

Support for VRRP health check scripts

Just yesterday we've added support for VRRP health check scripts that can add more flexibility to VRRP setups. Here's an example:
vrrp {
             vrrp-group 10 {
                 advertise-interval 1
                 health-check {
                     failure-count 2
                     interval 5
                     script /config/scripts/test.sh
                 preempt true

This was made specially for a user who needs it right now. When we get to rewriting VRRP to move its configuration to a separate subtree, we'll make sure to include this in migration scripts.

New implementation of "run show configuration commands"

The original implementation was a rather dirty hack. First, it would first save the output of the "show" command to file and then parse it from there. Second, it used the same flawed parser that was used by migration scripts, so it was unable to handle comments at all and would insert quotes where none are needed (ethernet 'eth0') — internally, because it could not tell tag nodes from leaf nodes with values.

I've adapted the library that is now used for migration scripts for this purpose, and now the config to commands convertor takes advantage of the new, correct parser. See an example:

vyos@vyos-test# show interfaces dummy 
 /* So very dummy */
 dummy dum0 {
 dummy dum1 {
 dummy dum2 {
vyos@vyos-test# show interfaces dummy | commands 
set dummy dum0 address ''
comment dummy dum0 'So very dummy'
set dummy dum1 address ''
set dummy dum2 address ''
set dummy dum2 disable

The new implementation is also about 40% faster (when used on a complete config, as in "run show configuration commands"), though the "|commands" pipe is slightly slower due to some hacks needed to convert an incomplete (and thus ungrammatical) outputs such as that of a single leaf node to a complete config, but is normally operates on very small data so it shouldn't be noticeable).

UNIX purists would also be pleased to know that the new "|commands" is a real pipe. It doesn't create any temporary files, even though it's not streaming (but then again, neither VyOS config format is line-oriented).

You can also call it by hand on any config file, e.g. "cat /config/config.boot | vyos-config-to-commands".

intfwatchd is no more

The kernel behaviour for IPv4 addresses always has been to restore them if an interface goes down and then goes up. The behaviour for IPv6 addreses used to be the same, but in the 3.13 kernel we used for 1.1.x, the behaviour was changed to remove them forever if an interface goes down. I kinda can see how this makes sense for hosts that use autoconfiguration, but for routers , that's just inexcusable. NetworkManager also isn't a good solution for routers as it doesn't make non-disruptive reconfiguration any easy, so we've had to find a workaround, and I wrote a simple daemon that watched netlink events and restored IPv6 addresses when necessary. The only really good thing it did was that it helped us discover a memory leak in the Perl config access library (the bad things is that it made the daemon eat up too much memory and crash before the bug was fixed).

Anyway, luckily, recent kernels have sysctl knobs to control this behaviour, and old (sensible) behaviour could be restored. I was happy to remove intfwatchd from the system when I verified that we can again have it work properly without any crutches.

All user scripts should run with correct GID now

In the old config backend, there's still a problem that messes up running config permissions unless all processes that modify it run with correct GID, else no one but the user who started the process can commit anymore unless the routed is rebooted or the permissions are fixed by hand.

To alleviate this problem, we've made VRRP transition scripts, cron scripts, and load balancing scripts automatically use correct GID. If you are running them from elsewhere, you still need to wrap them in "sg vyattacfg".

API documentation

We should have done it long time ago, but better late than never. Today I've added sphinx setup and makefile targets to the vyos-1x package, added docstrings to the vyos.config module, and we've setup a web host to keep the generated docs. You can find them here: http://docs.vyos.io/api/vyos.html#module-vyos.config 

There is much to do there of course, but it's some start.

Licensing of VyOS libraries

As the new Python code is written, it's gradually splitting into common libraries and executables. It means the time to sort out licensing has come. Originally, the vyos.config module was under MIT, and there were a few other files under MIT from the time when VyOS had just a few Python files, but other libraries from the vyos-1x package era were under LGPLv2+. This was quite a mess to be fair.

Now all libraries in the vyos.* module hierarchy are LGPLv2+, while executable scripts are GPLv2+. I hope this will simplify linking to the common VyOS libraries from third-party extensions, while still protecting that code from proprietary forks.