tag:blog.vyos.net,2013:/posts blog.vyos.net 2018-07-14T23:09:40Z VyOS tag:blog.vyos.net,2013:Post/1302765 2018-07-13T13:36:38Z 2018-07-14T17:58:53Z Infrastructure failure resolved, downloads.vyos.io is back now

We have managed to resolve the infrastructure problems and bring the affected machines back intact. Now downloads.vyos.io and ci.vyos.net are back online, and our build hosts with all the build dependencies setup and uncommited code are back online too, so luckily we can resume the work from the point where it was stopped by the RAID issue.

We are not ready to give a complete post mortem on the actual issue yet (may not even be able to at all) since we have limited data and the service provider support was not exactly helpful. What we can say now is that what was thought to be RAID5 actually was a RAID1 with an additional hot spare drive, and the failure mode included a RAID controller glitch apart from drive failure. The hot spare drive is what allowed us to bring the data back intact.

While this issue was resolved without any data loss, it definitely prompts us to reconsider many things about our infrastructure, including backup strategy, deployment mechanisms, and service provider choice.

We are going to write new posts as we decide upon the options and roll out improvements. Infrastructure deployment is also a good area for contributions, and some people already offered help.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1302723 2018-07-13T09:05:40Z 2018-07-13T09:05:40Z Infrastructure failure

Hi everyone,

We've had a catastrophic failure on one of our hosts: two drives in a RAID5 failed simultaneously. A number of VMs related to the development infrastructure are permanently lost and need to be restored since we didn't have backups of them.

The only piece public infrastructure affected by it is downloads.vyos.io. You can use the old packages.vyos.net server or one of the mirrors to download the stable (1.1.8) or historical VyOS releases.

The other pieces of infrastructure that need to be restored are the Jenkins server, the build machines, and the repositories server. We'll have to restore them before we can continue development. I hope we'll get it done by Monday.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1297570 2018-06-27T12:44:58Z 2018-06-28T14:29:21Z Building VyOS images with custom packages just got simpler

While the new build scripts first introduced when we migrated the development branch to jessie made things much simpler for developers and for people who just want to build the latest VyOS image from source, building an image even simply with a package available from Debian Jessie repos but not present in the VyOS package set by default was still quite an ordeal for a person not familiar with live-build and the structure of our build scripts.

Well, until now. Yesterday I've added ./configure script options that should allow everyone to build a custom image without ever touching the plumbing of the build scripts.

The simplest example, building an image with packages available in Debian Jessie:

./configure --custom-packages "bsdgames robotfindskitten"
sudo make iso

A more interesting example, adding a package from a third party repo signed with its own key. In this case, salt-minion:

wget https://repo.saltstack.com/apt/debian/8/amd64/2017.7/SALTSTACK-GPG-KEY.pub
./configure --custom-apt-entry "deb http://repo.saltstack.com/apt/debian/8/amd64/2017.7 jessie main" --custom-packages "salt-minion" --custom-apt-key ./SALTSTACK-GPG-KEY.pub
sudo make iso

Of course it doesn't guarantee that your image will build or work, but at least it will get you to the debugging phase faster,

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1297080 2018-06-25T16:48:31Z 2018-07-03T09:44:01Z Versions mystery revealed

Over last few years, I saw many combinations and theories around VyOS, Vyatta, EdgeOS that I decided to shed light on this and also explain current and future VyOS versions


First was Vyatta

You can read the detailed history here at Wikipedia, and I just tell that all started back in 2006 (12 years ago!) and with release v6.0  in 2010 Vyatta Community renamed to Vyatta Core to highlight the fact that the Vyatta Subscription was no longer a separate product, but the open source version extended with proprietary add-ons. In retrospect, this is often seen as the beginning of the end. At the time the future of the open source Vyatta didn’t look as bleak though, and while since 6.0 Vyatta officially became “open core” (aka “freemium”), that release incorporated features formerly available only in the proprietary version, along with significant new features like image-based upgrade, and it seems like a sustainable model for a time.


In 2011 Ubiquiti Networks launched their EdgeMax line of products. EdgeOS™ is the essential part of the product line and is a fork of Vyatta Core 6.3 that exclusively runs on Cavium backed hardware produced by Ubiquiti Networks (EdgeRouter Lite, PoE, Pro) Since then they migrated to Debian 7 and replaced quagga with proprietary ZebOS™


In 2012 Vyatta was acquired by Brocade, and in April 2013 they renamed Vyatta Subscription Edition (VSE) to the Brocade Vyatta 5400 vRouter (and later also 5600) those a no longer open source. By that time all community resources were wiped, and future of Vyatta Core was obvious.


In late 2013 Daniil initiated fork of Vyatta Core 6.6 under VyOS name. It's a start of development of so-called old stable 1.1.x series which based on Debian 6 (patched all the way) the latest version is 1.1.8 and now in Extended support



fall of 2015, we began an upgrade of VyOS project in many senses, that is a time when 1.2.x started (decision to skip Debian 7 and go directly to Debian 8 which includes migration to systemd among other things)  enhancements and new development happening in the rolling version that we introduced some time ago.


Now that know the background, it’s a good time to describe the details on the new VyOS release model.


Rolling

You can already download binary images of the rolling release of VyOS 1.2.x here, which are snapshots of the current development state. All new features, refactoring of old code, improvements of the OS package base go there before they can become a part of a release candidate or a stable release.

Rolling release builds may break occasionally, and new features may not work as expected. They are meant for contributors and networking enthusiasts who are willing to help us test those features.


Release Candidate (RC)

About every six months, we will start a new release cycle. The cycle will begin with branching off the rolling release and preparing a release candidate. Release candidates are neither code nor feature frozen, as we fix bugs or design issues, or new features in rolling become stable and well tested, we may prepare a new RC that incorporates them.

Release candidates are supposed to be stable enough for non-critical production, but if you prefer stability over new features, you may want to stick with EPA or LTS.


Early Production Access (EPA)

After RC cycle is over and the release is sufficiently stable, it will become the basis for the next LTS release.

EPA is for customers and community members who want new features before they are available in the LTS, and are willing to help us weed out last bugs in those new features.


Long Term Support (LTS)

LTS version of VyOS will be receiving security patches and high priority fixes from rolling releases.

They are meant for enterprise and service provider users who value stability over everything.



We’d like to encourage everyone to install the least stable version to help us with testing.

As bonus 

VyOS to Debian version map



All product names, logos, and brands are property of their respective owners.


]]>
Yuriy Andamasov
tag:blog.vyos.net,2013:Post/1295763 2018-06-20T16:33:25Z 2018-07-11T09:01:08Z 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.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1288329 2018-05-28T11:42:30Z 2018-06-13T11:24:34Z Writing migration scripts (and manipulating VyOS config files outside VyOS) just got easier

Long story short

VyOS 1.2.0-rolling (starting with the next nightly build) includes a library for parsing and manipulating config files without loading them into the system config. It can be used for automatically converting configs from old versions in case an incompatible change was made, and for standalone utilities. Motivation and history are discussed below.

Here is an example of interacting with the new library:
>>> from vyos import configtree

>>> c = configtree.ConfigTree("system { host-name vyos \n } interfaces { dummy dum0 { address 192.0.2.1/24 \n address 192.0.2.20/24 \n disable \n } }  /* version: 1.2.0 */")

>>> print(c.to_string())
system {
    host-name vyos
}
interfaces {
    dummy dum0 {
        address 192.0.2.1/24
        address 192.0.2.20/24
        disable { }
    }
}

 /* version: 1.2.0 */

>>> c.set(['interfaces', 'dummy', 'dum0', 'address'], value='293.0.113.3/32', replace=False)

>>> c.delete_value(['interfaces', 'dummy', 'dum0', 'address'], '192.0.2.1/24')

>>> c.delete(['interfaces', 'dummy', 'dum0', 'disable'])

>>> c.is_tag(['interfaces', 'dummy'])
True

>>> c.exists(['interfaces', 'dummy', 'dum0', 'disable'])
False

>>> c.list_nodes(['interfaces', 'dummy'])
['dum0']

>>> print(c.to_string())
system {
    host-name vyos
}
interfaces {
    dummy dum0 {
        address 192.0.2.20/24
        address 293.0.113.3/32
    }
}

 /* version: 1.2.0 */

As you can see, it largely mimics the API you get for the running config. The only notable differences are that the "set" method requires that you specify the path and the value separately, and to have nodes formatted as tag nodes (i.e. "ethernet eth0 { ..." as opposed to "ethernet { eth0 { ..." you need to mark them as such with "set_tag", unless they were originally formatted that way in the config you parsed.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1285655 2018-05-21T11:44:57Z 2018-05-26T22:46:11Z Things the new style configuration mode definitions intentionally do not support

I've made three important changes to the design of the configuration command definitions, and later I realized that I never wrote down a complete explanation of the changes and the motivation behind them.

So, let's make it clear: these changes are intentional and they shouldn't be reintroduced. Here's the details:

The "type" option

In the old definitions, you can see the "type:" option in the node.def files very often. In the new style XML definitions, there's no equivalent of it, and the type is always set to "txt" in autogenerated node.def's for tag and leaf nodes (which means "anything" to the configuration backend).

I always felt that the "type" option suffers from two problems: scope creep and redundancy.

The scope creep is in the fact that "type" was used for both value validation and generating completion help in "val_help:" option. Also, the "u32" type (32-bit unsigned integer) has a little known undocumented feature: it could be used for range validation in form of "type: u32:$lower-$upper" (e.g. u32:0-65535). It has never been used consistently even by the original Vyatta Core authors, plenty of node.def's use additional validation statements instead.

Now to the redundancy: there are two parallel mechanisms for validations in the old style definitions. Or three, depending on the way you count them. There are "syntax:expression:" statements that are used for validating values at set time, and "commit:expression:" that are checked at commit time.

My feeling from working with the system for scary amount of time was that the "type" option alone is almost never suffucient, and thus useless, since actual, detailed validation is almost always done elsewhere, in those "syntax/commit:expression:" statements or in the configuration scripts. Sometimes a "commit:expression:" is used where "syntax:expression:" would be more appropriate (i.e. validation is delayed) but let's focus on set-time validation only.

But without data to back it up, a feeling is just a feeling, so I made up a quick and dirty script to do some analysis. You can repeat what I've done easily with "find /opt/vyatta/share/vyatta-cfg/templates/ -type f -maxdepth 100 -name 'node.def' | nodecheck.py".

On VyOS 1.1.8 (which doesn't include any rewritten code) the output is:
Has type: 2737
Has type txt: 1387
Has type other than txt: 1350
Has commit or syntax expression: 1700
Has commit or syntax expression and type txt: 740
Has commit or syntax expression and type other than txt: 960

While irrelevant to the problem on hand, the total count of node.def's is 4293). In other words, of all nodes that have the type option, 50% have it set to "txt". Some of them are genuinely "anything goes" nodes such as "description" options, but most use it as a placeholder.

68% of all nodes that have a type are also using either "syntax:expression:" or "commit:expression:". Of all nodes that have a type more specific than "txt", 73% have additional validation. This means that even for supposedly specific types, type alone is enough only in 23% cases. This raises the question whether we need types at all.

Sure, we could introduce more types and add support for something of a sum type, but is it worth the trouble if validation can be easily delegated to external scripts? Besides, right now types are built in the config backend, which means adding a new one requires modifying it starting from the node.def parser.

In the new style definitions, I felt like the only special case that is special enough is regular expression. This is how value constraints checked at set time are defined:

<leafNode name="foo">
  <properties>
    <constraint>
      <regex>(baz|baz)</regex>
      <validator>quux</validator>
    </constraint>
  </properties>
<leafNode>

Here the "validator" tag contains a reference to a script stored in /usr/libexec/vyos/validators/. Since adding a new validator is easy, there's no reason to hesitate to add new ones for common (and even not so common) cases. Note that "regex" option is automatically wrapped in ^$, so there's no need to do it by hand every time.

Default values

The old definitions used to support "default:" option for setting default values for nodes. It looks innocous on the surface, but things get complicated when you look deeper into its behaviour.

You may think a node either exists, or it does not. What is the value of a node that doesn't exist? Sounds rather like a Zen koan, but here's cheap enlightenment for you: it depends on whether it has a default value or not.

Thus, nodes effectively have three states: "doesn't exist", "exists", and "default". As you can already guess, it's hard to tell the latter two apart. It's also very hard to see if a node was deleted from a config or just reset to a default value. It also means that every node lookup cannot operate on the running config tree alone and has to consult the command definitions as well, which is very bad if you plan to use the same code for the CLI and for standalone config handling programs such as migration scripts.

Last time people tried to introduce rollback without reboot, the difficulties of handling the third virtual "default" state was one of the biggest problems, and it's still one of the reasons we don't have a real rollback. VyConf has no support for default values for this reason, so we should eliminate them as we rewrite the code.

Defaults should be handled by config scripts now. Sure, we lose "show -all" and the ability to view defaults, but the complications that come with it hardly make it worth the trouble. There are also many implicit defaults that come from underlying software options anyway.

Embedded shell scripts

That's just a big "no". Have you ever tried to debug code that is spread across multiple node.def's in nested directories and that cannot be executed separately or stepped through?

While it's tempting to allow that for "trivial" scripts, the code tends to grow and things get ugly. Look the the implementation of PPPoE or tunnel interfaces in VyOS 1.1.8.

If it's more than one command, make it an external script, and you'll never regret the decision when it begins to grow.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1284116 2018-05-16T16:50:29Z 2018-05-19T23:48:58Z New-style operational mode command definitions are here

We've had a convertor from the new style configuration command definitions in XML to the old style "templates" for a while in VyOS 1.2.0. As I predicted, a number of issues were only discovered and fixed as we have rewritten more old scripts, but by now they should be fully functional. However, until very recently, there was no equivalent of it for the operational mode commands. Now there is.

The new style

In case you've missed our earlier posts, here's a quick review. The configuration backend currently used by VyOS keeps command definitions in a very cumbesome format with a lot of nested directories where a directory represents a nesting level (e.g. "system options reboot-on-panic" is in "templates/system/options/reboot-on-panic"), a file with command properties must be present in every directory, and command definition files are allowed to have embedded shell scripts.

This makes command definitions very hard to read, and even harder to write. We cannot easily change that format until a new configuration backend is complete, but we can abstract it away, and that's what we did.

The new command definitions are in XML, and a RelaxNG schema is provided, so everyone can see its complete grammar and automatically check if their definitions are correctly written. Automated validation is already integrated in the build process.

Rewriting the command definitions goes along with rewriting the code they call. New style code goes to the vyos-1x package.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1282282 2018-05-11T08:33:05Z 2018-06-02T12:14:03Z VyOS 1.2.0 status update

While VyOS 1.2.0 nightly builds have been fairly usable for a while already, there are still some things to be done because we can make a named release candidate from it. These are the things that have been done lately:

EC2 AMI scripts retargeting and clean up

The original AMI build scripts had been virtually unchanged since their original implementation in 2014, and by this time they've had ansible warnings at every other step, which prompted us to question everything they do, and we did. This resulted in a big spring cleanup of those scripts, and now they are way shorter, faster, and robust.

Other than the fact that they now work with VyOS 1.2.0 properly, one of the biggest improvements from the user point of view is that it's now easy to build an AMI with a custom config file simply by editing the file at playbooks/templates/config.boot.default.ec2

The primary motivation for it was to replace cumbersome in-place editing of the config.boot.default from the image with a single template, but in the end it's a win-win solution for both developers and users.

The original scripts were also notorious for their long execution time and fragility. What's worse is that when they failed (and it's usually "when" rather than "if"), they would leave behind a lot of gargabe they couldn't automatically clean up, since they used to create a temporary VPC complete with an internet gateway, subnet, and route table, all just for a single build instance. They also used a t2.medium instance that was clearly oversized for the task and could be expensive to leave running if clean up failed.

Now they create the build instance in the first available subnet of the default VPC, so even if they fail, you only need to delete a t2.micro instance, a key pair, and a security group.

It is no longer possible to build VyOS 1.1.x images with those scripts from the baseline code, but I've created a tag named 1.1.x from the last commit where it was possible, so you can do it if you want to — without these recent improvements of course.

Package upgrades and new drivers

We've upgraded StrongSWAN to 5.6.2, which hopefully will fix a few longstanding issues. Some enthusiastic testers are already testing it, but everyone is invited to test it as well.

SR-IOV is now basically a requirement for high performance virtualized networking, and it needs appropriate drivers. Recent nightly builds include a newer version of Intel's ixgbe and Mellanox OFED drivers, so the support for recent 10gig cards and SR-IOV in particular has improved.

A step towards using the master branch again

The "current" git branch we use throughout the project where everyone else uses "master" was never intended to be a permanent setup: it always was a workaround for the master branch in packages inherited from Vyatta Core being messed up beyond any repair. It will take quite some time to get rid of the "current" branch completely and we'll only be able to do it when we finally consolidate all the code under vyos-1x, but we've made jenkins builds correctly put the packages built from the "master" branch in our development repository, so we'll be able to do it for packages that do not include any legacy code at least.

IPv6 VRRP status

This is the most interesting part. IPv6 VRRP is perhaps a single most awaited feature. Originally it was blocked by lack of support for it in keepalived. Now keepalived supports it, but integrating it will need some backwards-incompatible changes.

Originally, keepalived allowed mixing IPv4 and IPv6 in the same group, but it no longer allows it (curiously, the protocol standard does allow IPv4 advertisments over IPv6 transport, but I can see why they may want to keep these separate). This means to take advantage of the improvements it made, we also have to disallow it, thus breaking the configs of people who attempted to use it. We've been thinking about keeping the old syntax while generating different configs from it, or automated migration, but it's not clear if automated migration is really feasible.

An incompatible syntax change is definitely needed because, for example, if we want to support setting hello source address or unicast VRRP peer address for both IPv4 and IPv6, we obviously need separate options.

Soon IPv6 addresses in IPv4 VRRP groups will be disallowed and syntax for IPv6-only VRRP groups will be added alongside the old vrrp-group syntax. If you have ideas for the new syntax, the possible automated migration, or generally how to make the transition smooth, please comment on the relevant task.

PowerDNS recursor instead of dnsmasq

The old dnsmasq (which I, frankly, always viewed as something of a spork, with its limited DHCP server functionality built into what's mainly a caching DNS resolver), has been replaced with PowerDNS recursor, a much cleaner implementation.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1277514 2018-04-27T13:33:11Z 2018-05-16T19:33:15Z On security of GRE/IPsec scenarios

As we've already discussed, there are many ways to setup GRE (or something else) over IPsec and they all have their advantages and disadvantages. Recently an issue was brought to my attention: which ones are safe against unencrypted GRE traffic being sent?

The reason this issue can appear at all is that GRE and IPsec are related to each other more like routing and NAT: in some setups their configuration has to be carefully coordinated, but in general they can easily be used without each other. Lack of tight coupling between features allows greater flexibility, but it may also create situations when the setup stops working as intended without a clear indication as to why it happened.

Let's review the knowingly safe scenarios:

VTI

This one is least flexible, but also foolproof by design: the VTI interface (which is secretly simply IPIP) is brought up only when an IPsec tunnel associated with it is up, and goes down when the tunnel goes down. No traffic will ever be sent over a VTI interface until IKE succeeds.

Tunnel sourced from a loopback address

If you have missed it, the basic idea of this setup is the following:

set interfaces dummy dum0 address 192.168.1.100/32

set interfaces tunnel tun0 local-ip 192.168.1.100/32
set interfaces tunnel tun0 remote-ip 192.168.1.101/32 # assigned to dum0 on the remote side

set vpn ipsec site-to-site peer 203.0.113.50 tunnel 1 local prefix 192.168.1.100/32
set vpn ipsec site-to-site peer 203.0.113.50 tunnel 1 remote prefix 192.168.1.101/32

Most often it's used when the routers are behind NAT, or one side lacks a static address, which makes selecting traffic for encryptions by protocol alone impossible. However, it also introduces tight coupling between IPsec and GRE: since the remote end of the GRE tunnel can only be reached via an IPsec tunnel, no communication between the routers over GRE is possible unless the IPsec tunnel is up. If you fear that any packets may be sent via the default route, you can nullroute the IPsec tunnel network to be sure.

The complicated case

Now let's examine the simplest kind of setup:

set interfaces tunnel tun0 local-ip 192.0.2.100 # WAN address
set interfaces tunnel tun0 remote-ip 203.0.113.200

set vpn ipsec site-to-site peer 203.0.113.200 tunnel 1 protocol gre

In this case IPsec is setup to encrypt the GRE traffic to 203.0.113.200, but the GRE tunnel itself can work without IPsec. In fact, it will work without IPsec, just without encryption, and that is the concern for some people. If the IPsec tunnel goes down due to misconfiguration, it will fall back to the common, unencrypted GRE.

What can you do about it?

As a user, if your requirement is to prevent unencrypted traffic from ever being sent, you should use VTI or use loopback addresses for tunnel endpoints.

For developers this question is more complicated.

What should be done about it?

The opinions are divided. I'll summarize the arguments here.

Arguments for fixing it:

  • Cisco does it that way (attempts to detect that GRE and IPsec are related — at least in some implementations and at least when it's referenced as IPsec profile in the GRE tunnel)
  • The current behaviour is against user's intentions

Arguments against fixing it:

  • Attempts to guess user's intentions are doomed to fail at least some of the time (for example, what if a user intentionally brings an IPsec tunnel down to isolate GRE setup issues?)
  • The only way to guarantee that unencrypted traffic is never sent is checking for a live SA matching protocol and source before forwarding every packet — that's not good for performance).

Practical considerations:

  • Since IKE is in the userspace, the kernel can't even know that an SA is supposed to exist until IKE succeeds: automatic detection would be a big change that is unlikely to be accepted in the mainline kernel.
  • Configuration changes required to avoid the issue are simple
If you have any thoughts on the issue, please share with us!
]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1275008 2018-04-20T14:58:39Z 2018-05-07T00:07:48Z When VyOS CLI isn't enough

Sometimes a particular configuration option is supported by the software that VyOS uses, but the CLI does not expose it. Since VyOS is open source, you can always fix that, but sometimes you need it by tomorrow, and there's simply no time to do it.

In a number of places, we've left an escape hatch for it that allows bypassing the CLI and including a raw snippet into the generated config. Of course, you give up the sanity checks of the CLI and take full responsibility for the correctness of the resulting config, but sometimes it's necessary.

OpenVPN

In openvpn, we have an option called "openvpn-option". You can pass any options to OpenVPN process with it, but note that in the current versions, it has to follow the command line rather than config file option, i.e. prepend it with "--". See this example:

set interfaces openvpn vtun10 openvpn-option "--connect-freq 10 60"

Note that the "push" option em is supported. I see OpenVPN configs with openvpn-option heavily overused once in a while — before including an option, make sure what you need to do is really not supported.

DHCP server

In the DHCP server, there is not one, but too escape hatches. One is the "subnet-parameters" option under "subnet". Another one is a "global-parameters" under "shared-network-name".

See an example:

set service dhcp-server shared-network-name LAN subnet 10.0.0.0/24 subnet-parameters "ping-timeout 5;"

Since dhcpd.conf syntax is more complex than just a list of options, it's important to make sure that generated config will be valid. It's easy to make your DHCP server stop loading and spend some time reading the log to see what is wrong, so be careful here.

Note that these options are not supported by the DHCPv6 server. Anyone thinks we should support it?

Dynamic DNS

In dynamic DNS, you can use the generic HTTP method if your provider and protocol is not supported.

set service dns dynamic interface eth0 use-web url http://dyndns.example.com/?update

Since no one can possibly support all providers, I believe it will remain a necessary option forever.

When all else fails: the postconfig script

If something is not supported and doesn't have a handy escape hatch, you still can implement it with the postconfig script. That script is found at /config/scripts/vyatta-postconfig-bootup.script and runs after config.boot loading is complete, so it's particularly conductive to manipulating things like raw iptables rules.

VyOS doesn't delete or overwrite anything in the global netfilter tables after boot, so it's safe to put your commands there, for example "/sbin/iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" for global MSS clamping.

You still need to be careful not to conflict with any of the rules inserted by VyOS though, in general, so always make sure to check what exactly VyOS generates before using the postconfig script.

Looking forward

VyOS 1.2.0 brings improvements to the postconfig script execution and adds some more escape hatches — stay tuned for updates.


]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1272109 2018-04-13T12:00:00Z 2018-07-14T23:09:40Z DNS forwarding in VyOS

A lot of small networks do not have their own DNS server, but it's not always desirable to just leave hosts to use an external third-party server either, that's why we've had DNS forwarding in VyOS for a long time and are going to keep it there for the foreseeable future.

Experienced VyOS users already know all about it, but we should post something for newcomers too, shouldn't we?

Configuring DNS forwarding is very simple. Assuming you have "system name-server" set, all you need to do to simply forward requests from hosts behind eth0 to it is "set service dns forwarding listen-on eth0". Repeat for every interfaces where you have clients and you are done.

There are some knobs for telling the service to use or not use specific DNS servers though:

set service dns forwarding listen-on eth0

# Use name servers from "system name-server"
set service dns forwarding system

# Use servers received from DHCP on eth1 (typically an ISP interface)
set service dns forwarding dhcp eth1

# Use a hardcoded name server
set service dns forwarding name-server 192.0.2.10

You can also specify cache size:

set service dns forwarding cache-size 1000

One of the less known features is the option to use different name servers for different domains. It can be used for a quick and dirty split-horizon DNS, or simply for using an internal server just for internal domains rather than recursive queries:

set service dns forwarding domain mycompany.local server 192.168.52.100
set service dns forwarding domain mycompany.example.com server 192.168.52.100

And that's all to it. DNS forwarding is not a big feature — useful doesn't always equal complex.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1269516 2018-04-06T11:43:17Z 2018-05-07T00:07:54Z Loopback and the dummies

"There is no place like 127.0.0.1" the old saying goes. While the loopback interface is most often seen as the interface where the 127.0.0.1 address is assigned by default and where the 127.0.0.0/8 network is routed, and just a way for programs on the same host to communicate over the network without actual network, it has uses in networked context as well.

Before we talk about those use cases, we need to discuss interfaces themselves. In some OSes, such as Cisco IOS, and many BSD derivatives, it is possible to create multiple loopbacks. Linux kernel (and thus VyOS) historically allowed only one loopback (named "lo"), and this behaviour has become too traditional and relied upon to change overnight, so to implement multiple loopback, a new interface type called "dummy" was added. Dummy interfaces are functionally identical to loopbacks so the difference is mostly aesthetic.

This is how to setup a dummy interface: "set interfaces dummy dum0 address ...". If your problem does not require independent interfaces, you can also just add another address to the loopback.

So, why would one want to use a loopback/dummy interface instead of assigning another address to a physical NIC?

Case 1: tunnel endpoints

We have already talked about GRE/IPsec behind NAT and/or with dynamic addresses. Since GRE requires fixed local and remote endpoint  addresses to work, and in a setup where dynamic addresses or NAT is involved you do not have fixed addresses, the trick is to use a pair of addresses made up specially for this purpose as GRE endpoints.

Case 2: management addresses

Suppose you have a router A with two NICs, connected to networks B and C that are connected to each other, so that if any of the links fails, the network as a whole is still operational. However, if you choose either NIC A or NIC B address as a management address, it may become inaccessible if one of the NICs fail, forcing you to manually fall back to the other address.

To prevent this situations, people often assign a dedicated management address to a loopback, create a DNS record for it, and advertise that address to all other routers so that as long as there is at least one path to that router that works, they do not need to worry about addresses of physical NICs to SSH to the router, and are free to change those addresses without having to update the DNS or memorize the new address.

Case 3: iBGP peer addresses

Since iBGP uses the same autonomous system number for all routers, it loses the ability to use AS path for path selection and loop detection. This means to keep the network loop-free, one has to setup it as a full mesh, or use a route reflector.

If we use addresses of physical NICs for session endpoints, we run into the same problem as in the previous use case: a session goes down with the link even if there are other valid paths. A possible solution is to select dedicated addresses for iBGP sessions, assign them to loopbacks, and advertise them to all other routers through a link-state protocol such as OSPF.

Your use case?

If you know other cases when a network setup can be improved by using loopback or dummy interfaces, let us know!

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1269300 2018-04-05T20:46:19Z 2018-05-07T00:07:56Z Naming of the nightly builds

Historically, we used to use "999.$timestamp" version numbers for development builds, including nightly builds. In our build scripts termninology, a development build is any build that is started without doing "./configure --build-type=release --version=1.2.0" or similar (before the build script rewrite that was "./configure --with-release-build" and you also needed to put a version string in livecd/version or somethinf like that). In short, most builds in existence had that nondescript 999 version. That's how it was before the fork and we just didn't change that.

However, that approach is rather problematic. The 999 version doesn't tell anything about the branch it's built from or the nearest release, so one can only guess from the timestamp what it might be, and even that is not reliable. With introduction of a rolling release that will exist alongside the stable releases, this gets even more problematic, so something needs to be done about it.

We decided to change the format to "$release-rolling+$timestamp", like "1.2.0-rolling+201804060100". I have some hesitations about the "+", so if people think it should rather be "-", we can change it.

If you visit https://downloads.vyos.io/?dir=rolling/current/amd64 , you can see the new naming scheme in action. Let us know if you experience any problems with it!


]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1267679 2018-04-01T18:23:09Z 2018-05-07T00:07:58Z VyOS to leverage the blockchain technology

Wild success of the blockchain technology on the mass market in the past couple of years is truly remarkable and it allowed many startups to raise substantial capitals. To keep up with those developments, we've been working on vyCoin, a cryptocurrency that will revolutionize the way people think about their network peering.

People will be able to mine vyCoin by routing other people's traffic and pay for traffic routing with it. Through smart contracts, it will be possible to charge vyCoins for routing other people's traffic with it as well. The use cases are endless, from facilitating peering arrangements at Internet exchanges to allowing people to earn something by participating in distributed private networks and ad hoc wireless.

To speed up the adoption, 50% of vyCoins come pre-mined and will be available to early adopters via an ICO. The vyCoin client will be integrated in the VyOS release images along with a kernel module for packet tracking so it will automatically start mining when you route traffic of other networks. The client will be sending 50% of the mined coins back to us as a service fee.

The ICO date will be announced later, meanwhile you can watch the vyCoin introduction video on Youtube.



]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1266870 2018-03-30T10:38:22Z 2018-05-07T00:08:00Z Take a third option: site to site OpenVPN

I've written a long series of post about setting up IPsec VPNs between NATed machines. As you've already seen, with some creative configuration it's possible, but is it always worth the sacrifice? Sometimes performance requirements, or lack of support for anything else on the other side make it necessary, but if the other side is also a VyOS, or another open source system, there's an alternative.

While OpenVPN is usually associated with road warrior VPN setups, it is not limited to it. It does have a site to site option and it's very quick and easy to setup. For some strange reason, that option is neglected by just about everyone who otherwise supports OpenVPN: in OpenWRT it's possible to setup through custom config options, while in Mikrotik RouterOS it's not possible to setup at all. In VyOS we have an explicit option for it. OPNsense also supports site to site OpenVPN out of the box (I thought it doesn't, but the authors corrected me).

The advantages are that it takes very few commands to get a tunnel to work, and that it will work in any network where you can forward a single port, even is both sides are behind double NAT. The downside is performance: squeezing even 100mbit/s of encrypted traffic out of it can be impossible, typical iperf figures are 10-20 mbit/s. For many use cases that performance is more than enough, though if you plan to use the tunnel for storage replication or another high-traffic job, that option is definitely not for you and you'll have to resort to IPsec.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1265535 2018-03-27T16:33:05Z 2018-04-12T21:53:31Z Ongoing improvements in project

Hi everyone,


While developers are working on the 1.2.0 release candidate, myself I’ve been looking into ways to improve the social and commercial aspects of project.

I’m happy to have established a positive relationship with a few companies, many of whom are themselves open source project developers and are ready to support other open source project.

The following open source tools will be added to our toolchain:

-  SonarQube by SonarSource is a source code analyzer that will help us improve code quality of the 1.2.0 and subsequent releases.

It’s odd that we didn’t know about it before, but now that we know of it, I hope it will change the project for the better. It uses an open core model and SonarCloud SaaS offering is available with no cost for open sources projects.

-  Discourse is a great discussion board software that will replace our old mybb forum. The old forum is now in read only mode to allow migration of the old topics to Discourse, and you give the new forum a try at https://forum.vyos.io. Discourse kindly offered us a discount for managed hosting via their open source program. The domain will be eventually changes to discourse.vyos.io (as per their discounted hosting plan requirements), but we’ll setup a redirect from both old domains when it’s ready.

On the commercial side, we are happy to announce that we now a part of two important Technology Alliances:

VMware Technology Alliance Program - Access Level will allow us to validate VyOS 1.2 OVA as a VMware Ready solution, which is also the first step towards the vCloud NFV certification. We hope it will help VyOS gain trust of the enterprise users and increase its adoption in that market.

Nutanix Elevate Technology Alliance Partner Program opens doors to the Nutanix platform for us. One of our goals from the beginning has been to bring VyOS to as many virtual platforms as possible, and it already runs on VMware, Hyper-V, Xen, and KVM, so Nutanix AHV support is a logical continuation of that effort, and we will also be listed on the Nutanix Marketplace to make it easy to deploy for Nutanix users.


I suppose these steps will help VyOS move forward and become a more successful project!

]]>
Yuriy Andamasov
tag:blog.vyos.net,2013:Post/1264373 2018-03-23T11:13:47Z 2018-04-12T21:53:21Z How to use AS path matching in your BGP policies

AS path is one of the most fundamental attributes of a (e)BGP advertisments. Its length is the first parameter in the best path selection algorithm (shorter is better), and it's also the sole mechanism of loop detection (if an AS is seen twice, there's a loop). However, despite the important role it plays behind the scenes, it's rather underutilized in routing policies.

A lot of time when prefix-list or specific route-map rule options such as next-hop can do, route filtering and modification based on AS path can do it better.

Let's see how to use it.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1261908 2018-03-16T13:36:23Z 2018-04-25T20:53:41Z Firewall groups today and tomorrow
Substantial work has been done by Marian Tudosoiu to bring IPv6 firewall groups to the current implementation of firewall configuration scripts even before we give it a complete rewrite. It's already merged into the current branch and is expected to be included in the 1.2.0-rc1 release. Now it's probably a good time to make a post about using firewall groups for those who haven't used them yet.

Of course there's still a lot of work to be done, such as integrating groups into NAT, which likely does require a complete rewrite to be feasible.

The concept is simple enough: instead of creating multiple rules that only differ in one address or port number, you create a group with all those addresses and ports, and reference it in a rule.

VyOS has three group types: address groups, network groups, and port groups. In 1.1.8 they can only be used with IPv4 firewall rulesets, including "policy route" rules.

Let's create some groups:
set firewall group port-group ManagementPorts port 22
set firewall group port-group ManagementPorts port 23
set firewall group port-group ManagementPorts port 443

set firewall group address-group Servers address 10.10.0.10
set firewall group address-group Servers address 10.10.0.15
set firewall group address-group Servers address 10.10.0.20

set firewall group network-group TrustedNets network 192.168.5.0/24
set firewall group network-group TrustedNets network 172.18.19.128/25
set firewall group network-group TrustedNets network 10.20.30.144/32

Now we can create a ruleset that uses them. Let's make a rule that references nothing but groups:

set firewall name DMZ-In rule 10 action accept
set firewall name DMZ-In rule 10 protocol tcp
set firewall name DMZ-In rule 10 source group network-group TrustedNets
set firewall name DMZ-In rule 10 destination group port-group ManagementPorts
set firewall name DMZ-In rule 10 destination group address-group Servers

An important part is that you can modify groups on the fly without updating any rules.

As you can see, groups is a simple concept that can be learnt in minutes. Once they are in IPv6 and NAT, their use will be very similar.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1258874 2018-03-09T14:43:20Z 2018-03-30T18:27:33Z The night of living dead protocols: RIPv2

RIP's name seems to have anticipated its ultimate fate. It used to stand for Routing Information Protocol before newer and better protocols killed it. Still, most routers in the world still support it even though few people seriously consider using it, thus making it an undead protocol.

This is mainly for compatibility reasons. After all, if you have an old box at a remote location, connected to a 128kbps ISDN line or worse, that is working fine and is impractical to replace, but supports nothing but RIP, what can you do? Likewise, some modern small routers by Netgear or D-link only have RIP, so if you can't just replace it, there's no other choice.

Besides, RIP remains a valuable teaching tool since it's conceptually simple, and understanding its limitations can help one understand the new routing protocols and their strengths.

What's bad about RIP?

There are some very good reasons to choose something else than RIP if you can. It's one of the oldest protocols in existence, and it was designed at the time when neither modern route selection techniques existed, nor the size of networks was big enough to warrant those techniques. When RIP reached its scalability limits, it was impossible to retrofit those techniques into it, so it was replaced rather than upgraded. RIPv2, the latest version, replaced broadcast advertisments with multicast and added support for CIDR, but that's about it — the fundamental design problems are, well, fundamental.

The biggest issue is that in RIP, routers are only aware of themselves and their immediate peers. They are completely blind to the rest of  the network. Link-state and path-vector protocols such as OSPF and eBGP are aware of the full topology (concrete or abstract), and can either reduce the full network graph to loop-free tree or immediately detect route advertisments as loop-inducing respectively.

All information that RIP advertisments include is the network, next hop, and an integer metric value. No router has any idea how its peers are connected to one another, so there is no way to detect loops before they form.

RIP includes a number of solutions to this problem, and they all have a limiting effect on its scalability.

Split horizon

It's simple — do not advertise routes received from peers back to them. It prevents the trivial loop when peers are trying to route traffic to networks they learnt about from someone else through you, but it cannot prevent wider loops. At least it has no effect on convergence time and doesn't create scalability limits either.

Counting to infinity

Before the other mechanisms were developed, this one was the only measure for detecting unreachable or looping routes. To make sure a route that is not actually reachable will be eventually recognized as such, it was decided to choose a maximum value that represents "infinite" (unreachable) metric. Since this process already can take quite some time, the value had to be small. In RIP, the infinite metric was set to 16. This means if a network has paths longer than 15 hops, the protocol just stops working.

Reverse poisoning

Even with 16 as infinite metric, the process of counting to infinity can be slow. The next idea was to not just wait for unreachable routes to become known as unreachable naturally, but actively advertise them to your peers as unreachable if a peer that was advertising them goes down.

This still is not a complete solution because if a router first receives  an unreachability advertisment from a router who's aware of the true situation, but later receives an update from a router that is still not aware of it, it will start using the second false advertisment.

Hold timer

The ultimate solution is to ignore any advertisment for a network whose metric has recently increased for some time, to avoid receiving updates from routers who do not know the real situation yet. This time shouldn't be too small, it should be similar to the time it takes for updates to propagate through the entire network. A common default value is 180 seconds. That is, to prevent convergence issues completely, it may take a network of just a few routers three minutes to converge.

Configuration

So, suppose you are aware of all issues, but want or need to configure RIP nonetheless. It's pretty simple. First, enable RIP on all interfaces where you want to send and receive advertisments:


set protocols rip interface eth0
set protocols rip interface eth1

Networks that are configured on those interfaces will become a part of the RIP table automatically. If you want to advertise networks that are on other interfaces, you need to add them explicitly:

set protocols rip network 10.74.74.0/24

You can also use "redistribute" and "default-information originate" commands just like in all other routing protocols.

If everything is right, you will see something like this on the neighbor router:

vyos@vyos# run show ip rip 
Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP
Sub-codes:
      (n) - normal, (s) - static, (d) - default, (r) - redistribute,
      (i) - interface

     Network            Next Hop         Metric From            Tag Time
R(n) 10.74.74.0/24      10.217.32.132         2 10.217.32.132     0 02:55
C(i) 10.217.32.0/24     0.0.0.0               1 self              0

If you remove the interface or the network statement, you will see the unreachable metric 16 for the duration of the hold timer, and only when the timer expires it will disappear from your table complely:

vyos@vyos# run show ip rip 
Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP
Sub-codes:
      (n) - normal, (s) - static, (d) - default, (r) - redistribute,
      (i) - interface

     Network            Next Hop         Metric From            Tag Time
R(n) 10.74.74.0/24      10.217.32.132        16 10.217.32.132     0 01:57
]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1255004 2018-03-02T03:14:44Z 2018-05-21T21:14:05Z Using the "policy route" and packet marking for custom QoS matches

There is only that much you can do in a QoS rules to describe the traffic you want it to match. There's DCP, source/destination, and protocol, and that's enough to cover most of the use cases. Most, but not all. Fortunately, they can also match packet marks and that's what enables creating custom matches.

Packet marks are numeric values set by Netfilter rules that are local to the router and can be used as match criteria in other Netfilter rules and many other components of the Linux kernel (ip, tc, and so on).

Suppose you have a few phones in the office and you want to prioritize their VoIP traffic. You could create a QoS match for each of them, but it's quite some config duplication, which will only get worse when you add more phones. If you find a way to group those addresses in one match, wouldn't it be nice? Sadly, there's no such option in QoS. Firewall can use address groups though, so we can make the QoS rule match a packet mark (e.g. 100) and set that mark to traffic from the phones.

# show traffic-policy 
 priority-queue VoIP {
     class 7 {
         match SIP {
             mark 100
         }
         queue-type drop-tail
     }
     default {
         queue-type fair-queue
     }
 }

Now the confusing bit. Where do we set the mark? Around Vyatta 6.5, an unfortunate design decision was made: "firewall modify" was moved under overly narrow and not so obvious "policy route". Sadly we are stuck with it for the time being because it's not so easy to automatically convert the syntax for upgrades. But, its odd name notwithstanding, it still does the job.

Let's create an address group and a "policy route" instance that sets the mark 100:

# show firewall group 
 address-group Phones {
     address 10.4.5.10
     address 10.4.5.11
     address 10.4.5.12
 }
[edit]
# show policy route 
 route VoIP {
     rule 10 {
         set {
             mark 100
         }
         source {
             group {
                 address-group Phones
             }
         }
     }
 }

Now we need to assign the QoS ruleset to our WAN and the "policy route" instance to our LAN interface:

set interfaces ethernet eth0 policy route VoIP
set interfaces ethernet eth1 traffic-policy out VoIP

You can as well take advantage of "policy route" ruleset options for time-based filtering or matching related connections. Besides, you can use it to set DSCP values in case your QoS setup is on a different router:

set policy route Foo rule 10 set dscp 46
]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1253839 2018-02-27T19:24:52Z 2018-03-19T05:49:05Z Writing the new-style command definitions

Earlier I said new features in Perl code and old style templates will not be merged anymore starting from May the 1st (if you have any such features already working and testing, you still have a chance to get them in, so hurry up!).

Now it's time to write step by step guides to using the new style and we'll start with command definitions.

History and motivation

Old-style command definitions (aka "templates") have quite a lot of design issues and proved to be one of the worst deterrents for new contributors (right after Perl code).

If you are not familiar with them, I'll remind you how they work. Suppose we need to create a command for new interface type "silly" (that's like dummy... but also silly). Suppose we start with address option, "set interfaces silly silly0 address 192.0.2.1/24". What we'd need to do:

  • Create directory structure interfaces/silly/node.tag/address
  • Put a node.def file under interfaces/, silly/, and address/, but not under node.tag (otherwise directory will not be recognized as a command definition)
  • Write a bunch of "tags" such as "help: Silly interface name" in the node.def's

There is a whole lot of problems with this approach:

  • To get the complete picture of commands of a component, you need to read a lot of files in multiple deeply nested directories
  • Every such file can contain embedded shell scripts, which means the logic rather than just data can be scattered across dozens files
  • You cannot check whether your node.def's are even syntactically correct without loading them into VyOS and trying them by hand

Some of these problems such as fragility of the data syntax could possibly be fixed. The problems with data and logic scattering, however, are fundamental, and cannot be cured without changing the approach.

A lot of design and development work went into the configuration mode commands definitions for vyconf and thus VyOS 2.0. However, vyconf is not and will never be a drop-in replacement for the old configuration backend (because it means it would have to reimplement the old unfortunate design decisions to be compatible, which defeats the purpose). And, since the plan is to rewrite VyOS 1.x.x gradually in the new style to have an operational system at all times and be able to reuse the code in 2.0 with minimal changes, we need a way to use new style command definitions alongside the old ones. As a compromise, we've made a convertor from new style definitions to the old style.

To learn how to use the new style and how much better it is, read on...

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1251460 2018-02-23T11:26:18Z 2018-03-30T18:29:09Z IP tunnels I have known and loved

Today we'll talk about the "classic" IP tunneling protocols.

GRE is often seen as a one size fits all solution when it comes to classic IP tunneling protocols, and for a good reason. However, there are more specialized options, and many of them are supported by VyOS. There are also rather obscure GRE options that can be useful.

All those protocols are grouped under "interfaces tunnel" in VyOS. Let's take a closer look at the protocols and options currently supported by VyOS.

MTU considerations

One issues that often comes up in tunneled setups is that of the MTU and MSS. Generally, the kernel is capable of setting the correct MTU on its own, and as long as end to end ICMP works, there should be no MSS issues either, but if you are in doubt, or simply curious what the total overhead of a tunnel will be, I made a tool for quickly calculating MTU and MSS for any combination of encapsulating and encapsulated protocols. Your contributions and corrections to it are always welcome.

If you want to do MSS clamping, here's an example:

set policy route MSS-CLAMP rule 10 protocol 'tcp'
set policy route MSS-CLAMP rule 10 set tcp-mss '1400'
set policy route MSS-CLAMP rule 10 tcp flags 'SYN'

set interfaces ethernet eth1 policy route MSS-CLAMP
Alternatively, you can insert a global rule like "iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" and make it persistent across reboot by placing it in /config/scripts/vyatta-postconfig-bootup.script

IPIP

This is the simplest tunneling protocol in existence. It is defined by RFC2003. It simply takes an IPv4 packet and uses sends it as a payload of another IPv4 packet. For this reason it doesn't really have any configuration options by itself.

An example:

set interfaces tunnel tun0 encapsulation ipip

set interfaces tunnel tun0 local-ip 192.0.2.10
set interfaces tunnel tun0 remote-ip 203.0.113.20
set interfaces tunnel tun0 address 192.168.100.200

If tunneling IPv4 traffic in IPv4 is really all you want, then it's a pretty good and a very lightweight choice.

IP6IP6

This is the IPv6 counterpart of IPIP. I'm not aware of an RFC that defines this encapsulation specifically, but it's a natural specific case of IPv6 encapsulation mechanisms described in RFC2473.

It's not likely that anyone will need it any soon, but it does exist.

An example:

set interfaces tunnel tun0 encapsulation ipip

set interfaces tunnel tun0 local-ip 2001:db8:aa::1/64
set interfaces tunnel tun0 remote-ip 2001:db8:aa::2/64
set interfaces tunnel tun0 address 2001:db8:bb::1/64

IPIP6

I'm pretty sure in a few decades this is going to be a very useful protocol (though there are other proposals).

As the name implies, it's IPv4 encapsulated in IPv6, as simple as that.

An example:

set interfaces tunnel tun0 encapsulation ipip6

set interfaces tunnel tun0 local-ip 2001:db8:aa::1/64
set interfaces tunnel tun0 remote-ip 2001:db8:aa::2/64
set interfaces tunnel tun0 address 192.168.70.80

SIT (6in4)

I believe SIT stands for "Simple Internet Transition". This protocol is defined by RFC4213, but curiously that RFC or any of its predecessor do not refer to it as SIT, so I have no idea where that nickname actually comes from (if you know its origin, tell me).

It encapsulates IPv6 packets in IPv4, as the name suggests. Unlike two previous protocols, it's very useful right now, as it's used by a number of IPv6 tunnel brokers such as that of Hurricane Electric.

An example:
set interfaces tunnel tun0 encapsulation sit

set interfaces tunnel tun0 local-ip 192.0.2.10
set interfaces tunnel tun0 remote-ip 192.0.2.20
set interfaces tunnel tun0 address 2001:db8:bb::1/64

GRE

GRE stands for Generic Routing Encapsulation, and it lives up to its name as it can encapsulate many other protocols at more than one OSI layer. It is defined by RFC2784.

Due to kernel driver layout reasons, in VyOS it comes in two flavours: "gre" and "gre-bridge". The difference is that while "gre" is layer 3 only, "gre-bridge" is layer 2 and can encapsulate ethernet frames, thus it can be bridged with other interfaces to create datalink layer segments that span multiple remote sites. GRE is also unique in that it can encapsulate more than one protocol at the same time, so it's the only way to create dual stack IPv4 and IPv6 tunnels in a single interface.

Layer 3 GRE example:

set interfaces tunnel tun0 encapsulation gre

set interfaces tunnel tun0 local-ip 192.0.2.10
set interfaces tunnel tun0 remote-ip 192.0.2.20
set interfaces tunnel tun0 address 10.40.50.60/24
set interfaces tunnel tun0 address 2001:db8:bb::1/64

Layer 2 GRE example:

set interfaces bridge br0 

set interfaces tunnel tun0 encapsulation gre-bridge
set interfaces tunnel tun0 local-ip 192.0.2.10
set interfaces tunnel tun0 remote-ip 192.0.2.20
set interfaces tunnel tun0 parameters ip bridge-group bridge br0

set interfaces ethernet eth1 bridge-group br0

As you can see, the bridge-group option for tunnels is in a rather unusual place, different from all other interfaces. I can't remember why is that, and we may make that CLI more consistent in the future even though it will take quite some effort to make it backwards-compatible.

GRE is also the only classic protocol that allows creating multiple tunnels with the same source and destination due to its support for tunnel keys. Despite its name, this feature has nothing to do with security: it's simply an identifier that allows routers to tell one tunnel from another.

An example:

set interfaces tunnel tun0 local-ip 192.0.2.10
set interfaces tunnel tun0 remote-ip 192.0.2.20
set interfaces tunnel tun0 address 10.40.50.60/24
set interfaces tunnel tun0 parameters ip key 10

set interfaces tunnel tun0 local-ip 192.0.2.10
set interfaces tunnel tun0 remote-ip 192.0.2.20
set interfaces tunnel tun0 address 172.16.17.18/24
set interfaces tunnel tun0 parameters ip key 20

Conclusion

Classic IP tunneling protocols are often not very flexible, but a lot of time they do their job very well, and are easy to use in conjunction with IPsec. For a more modern and flexible option you may consider L2TPv3 or VXLAN — but that's a story for future posts.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1250580 2018-02-21T12:28:46Z 2018-03-19T05:49:05Z First ProNet Portal drafts, new Partners and Social Media

Hello Community!

We are super excited that VyOS finally gets the traction that it deserves and we have a few interesting updates to share with you!

VyOS 1.2.0-rc1

Will be released within two or three weeks.

Tons of new things, we are still building future release notes and you can always grab a rolling version from here. Of course you are invited to add to the release notes if you spot a resolved issue we forgot, or you want to expand the documentation of the new features.

More contributors!

New contributors are joining our effort and more communication happens about VyOS on different platforms. We would like to remind everybody that you are welcome to join and participate in our development collaboration platform.

Social Media & other communication channels

It's more important than ever to spread the word about VyOS.

This is the reason we’ve been adding profiles on just about every social network over time  and on behalf of the team I encourage you to follow/like/subscribe and participate!

Here is the list of social media accounts:

Twitter - https://twitter.com/vyos_dev

Facebook - https://www.facebook.com/vyosofficial

LinkedIn - https://www.linkedin.com/company/vyos

YouTube - https://www.youtube.com/channel/UCEjJx6j87szaiqtKDrMVb2Q

Instagram - https://www.instagram.com/vyosofficial/

Reddit - https://www.reddit.com/r/vyos/


We also have a forum, a development portal and several chat platforms for real-time communication:

IRC - irc.freenode.net - many people here

Slack - slack.vyos.io - Newly launched!

Rocket.Chat - chat.vyos.io - few people


ProNet web

See the document below, it’s an initial draft rather than anything set in stone, but it’s probably pretty close to what we’ll eventually deploy in its fundamental concepts.

As always all feedback is welcome, email it to pronet@vyos.io

New Partners

We’ve already received quite a few applications for participation in ProNet and continue to receive them.

They are all important for us and we are glad to see interest in VyOS among service providers.

I would like to specially mention two of newly arrived partners:

Packet - The Promise of the Cloud Delivered on Bare Metal. Great folks provide super interesting offering. Bare Metal instances with hourly billing and lot of interesting capabilities (Wide list of supported OSes, API, BGP peering and more). Currently you can boot 1.1.8 following this manual.

And we agreed to work together to get VyOS 1.2 as natively supported OS on Packet.

Protectli - First hardware vendor that showed interest to work with us!

Check out their appliances, those will be first hardware appliances officially supported by VyOS 1.2 so you may want order some. And they support OpnSense and other OSes, you can see full list here

P.S.

As always, for those who read the article to the end get a 30% discount on merchandise via this link

Stay tuned!

]]>
Yuriy Andamasov
tag:blog.vyos.net,2013:Post/1248302 2018-02-16T11:35:19Z 2018-03-30T18:29:34Z NAT with a thousand faces

The familiar use cases for NAT are source NAT/masquerade for allowing private subnets access to the Internet, and port forwarding from the Internet to a host in a private network. However, there are more use cases that are less obvious, in part because they are defined by the relative size of the source/destination and translation address options.

One to one NAT

Very common among cloud providers, but equally useful if your ISP is ready to give you an additional address, but not a routable subnet.

Suppose your ISP gave you two addresses, 203.0.113.114 and 203.0.113.115. You use the .114 address for the router itself and want to map the .115 to a server inside your network that has 192.168.136.100 address.

Here's how to do it:

 interfaces {
     ethernet eth0 {
         address 203.0.113.114/24
         address 203.0.113.115/24
         ...
     }
 nat {
     destination {
         rule 10 {
             inbound-interface eth0
             destination {
                 address 203.0.113.115
             }
             translation {
                 address 192.168.136.100
             }
         }
     }
     source {
         rule 10 {
             outbound-interface eth0
             source {
                 address 192.168.136.100
             }
             translation {
                 address 203.0.113.115
             }
         }
     }
 }

One to many NAT

If the network or range specified in translation address is larger than the network in source/destination address, connections from the same host will be translated to more than one address. In source NAT, this is only useful for a bizzare kind of conspicious consumptions like buying a /24 subnet for yourself and using it all for just your desktop.

In destination NAT, however, it can be used as a simple form of L3, non-application aware load balancing.

Suppose you got 10 web servers all in the range of 192.168.136.100 to 192.168.136.110. You want traffic sent to 203.0.113.115 balanced across them. Here's an example:

nat {
     destination {
         rule 10 {
             destination {
                 address 203.0.113.115
                 port 80,443
             }
             inbound-interface eth0
             protocol tcp
             translation {
                 address 192.168.136.100-192.168.136.110
             }
         }
     }
     source {
         rule 10 {
             outbound-interface eth0
             source {
                 address 192.168.136.100-192.168.136.110
             }
             translation {
                 address 203.0.113.115
             }
         }
     }
 }

Many to many NAT

What happens if the source/destination and translation networks are the same size though? In that case, only the network part is translated, while the host part should stay untouched.

This is useful for getting around subnet conflicts.

nat {
     destination {
         rule 10 {
             destination {
                address 192.168.136.0/24
             }
             inbound-interface eth0
             translation {
                 address 10.20.30.0/24
             }
         }
     }
     source {
         rule 10 {
             outbound-interface eth0
             source {
                 address 10.20.30.0/24
             }
             translation {
                 address 192.168.136.0/24
             }
         }
     }
 }

If you know more variations, please let me know.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1245570 2018-02-10T17:11:50Z 2018-03-19T05:49:05Z Configuration versioning and archiving in VyOS

Last time I promised "node copying/renaming, node comments, and other little known features of the VyOS CLI", but the post actually only mentioned copying/renaming and comments, but not other features. It's time to fix that: today we'll discuss configuration versioning and archiving.

One of the great things about the config model with editing and commits being distinct stages is that it's feasible to execute some actions when the config is changed. In fact, you can execute arbitrary actions via pre/post-commit hooks, but there are built-in actions as well, namely configuration versioning and archiving to a remote location. This model, first introduced by JunOS, makes configuration is a lot more manageable than older Cisco style models.

This approach renders tools like Rancid or Oxydized redundant since the system can make a snapshot of the running config when the change is made rather than periodically. Moreover, right on the router you can see who made this or that commit and view diffs between revisions.

An additional advantage of versioning is that even if you forget to save the config (or purposely powercycle a system with an unsaved config because you forgot to use commit-confirm), you can always view recover the lost changes from the history.

Let's see how to use it.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1244395 2018-02-09T00:30:56Z 2018-03-19T05:49:05Z ProNet details and registration form

We are excited to see so much interest in the ProNet partner program.

While we collect applications from people and companies, we have already started working on the design of the ProNet web portal, and we need your input to make it match actual needs of the people.


What would you like to see in the portal as business users, support and consulting providers, service providers, and hardware vendors?


The current concept includes:

  • Different partner profile types for consultants, support providers, and hardware vendors for easy filtering.

  • Search by service types and location.

  • Badges of Contributor, Sponsor, and Evangelist for people and companies that contributed code, made donations, or written or gave talks about VyOS respectively.


Please send your suggestions to pronet@vyos.io All suggestions authors will get discounts on VyOS merchandize, and authors of best proposals will get a reward from us.

Let’s bring VyOS users and service providers closer to one another!


If you are interested in becoming a partner as an individual or a company, please fill the registration form


]]>
Yuriy Andamasov
tag:blog.vyos.net,2013:Post/1242620 2018-02-04T14:23:59Z 2018-03-19T05:49:05Z ProNet Announcement

Hello Community!

In the past few months there was a significant growth of interest to VyOS Project.

We’ve started getting more requests from companies looking for professional services such as  feature development and support and that is obviously great thing for the project!

However, to satisfy the demand, we need to grow the support team, and rather than try to do everything ourselves, we decided to share the business opportunities with the community of people and companies who are using VyOS and willing to share their expertise.


In other words, it’s time to start building a partner network!

We decided to name it ProNet, for a short and catchy name.


At Sentrium, we’ll focus on developing and maintaining VyOS, expanding our cloud platforms support, and offering custom feature development and developer support to our customers. Existing support contracts will continue to be fulfilled, but we will not take new support customers ourselves from now.


To offer decent level of quality for support services we already talking to several companies that showed interested in providing support services for certain territories however that is only beginning. If you is freelancer with deep VyOS knowledge or company with expertise in networking and VyOS and want to be part of our ProNet please drop us a line to pronet@vyos.io and we follow up from there.


There are three levels - registered, professional, enterprise.

While we finishing program perks and requirements document we can guarantee that all qualified partners of first wave will get very exclusive conditions

We plan to introduce partner locator web on https://pronet.vyos.io in Q2 2018 and we open to suggestions, 

just comment your ideas here or on social media about what you would like to see in future portal and we will be glad to consider them for implementation.

If you read until this line, you deserve 15% discount for our merchandise, just use this link  to get it automatically on check out or use PRONET code on checkout otherwise at our shop here

Stay tuned!

UPD1:
Registration form is now available here


]]>
Yuriy Andamasov
tag:blog.vyos.net,2013:Post/1241194 2018-02-01T06:01:49Z 2018-07-08T08:16:27Z Interaction between IPsec and NAT (on the same router)

I've just completed a certain unusual setup that involved NATing packets before they are sent to an IPsec tunnel, so I thought I'll write about this topic. Even in perfectly ordinary setups, the interaction between the two often catches people off guard, me included.

No, this is not a premature Friday post. The Friday post will be a continuation of the little known featured of the VyOS CLI.

Most routers these days have some NAT configured, so if you setup an IPsec tunnel, you need to understand the interaction between the two. Luckily, it's pretty simple.

Every network OS has a fixed packet processing order, and for a good reason. For example, source NAT has to be performed after routing because otherwise the OS will not know which outgoing interface must be used for the packet, and will not be able to determine which SNAT rule must be applied to that packet. Likewise, destination NAT must happen before routing if we want to be able to send incoming packets to the intended host — the routing decision depends on the new destination address.

Sometimes the order is less critical but reversing it would create inconvenience for network admins. For example, in Linux (and thus in VyOS), inbound firewall rules are processed after DNAT, so the destination address the firewall will see is the internal address, and you can easily setup a firewall that mentions private addresses on your WAN interface. If it was the other way around, then if you wanted to setup firewall rules for your private addresses, you would have to assign the firewall to the out direction of the LAN interface — not quite as logical or convenient, even if the end result is the same.

Where's IPsec in that processing flow and what are the implications of its position in it?

Let's revisit the complete diagram (image by Jan Engelhardt, CC-BY-SA):

If posthaven can't handle images properly, here's a direct link to the larger version:


The box you are looking for is "XFRM". In Linux, IPsec is not a special component, but a part of the XFRM framework that can do encryption amond other things (it also does compression and header modification).

From the diagram we can see that XFRM decode step (thus IPsec encryption) is before DNAT (NAT prerouting), and IPsec decryption is after SNAT (NAT postrouting). The implications of it are twofold: first you need to be careful when setting up SNAT and IPsec on the same machine, second, you can apply NAT rules to traffic that will go to the tunnel if you really have to.

Avoiding adverse interaction

Suppose you have this config:

vyos@vyos# show vpn ipsec site-to-site 
 peer 192.0.2.150 {
     [SNIP]
     tunnel 1 {
         local {
             prefix 192.168.10.0/24
         }
         remote {
             prefix 10.10.10.0/24
         }
     }
 }

vyos@vyos# show nat source 
 rule 10 {
     outbound-interface eth0
     source {
         address 192.168.10.0/24
     }
     translation {
         address 203.0.113.134
     }
 }

What will happen to a packet sent by host 192.168.10.100 to host 10.10.10.200? Since SNAT is performed before IPsec, and the 192.168.10.100 source address matches the rule 10, the rule will be applied and the packet will go down the packet processing pipeline with source address 203.0.113.134, which does not match the IPsec policy from tunnel 1. The packet will be sent out of the eth0 interface, unencrypted, and destined to be dropped by the ISP due to its private destination address (or it will be sent to a wrong host, which is not any better).

In this case this order of packet processing seems to be a real hassle. There's a very easy workaround though: exclude packets with destination address 10.10.10.0/24 from SNAT, like this:

vyos@VyOS-AMI# show nat source 
rule 5 {
    outbound-interface eth0
    destination {
        address 10.10.10.0/24
    }
    exclude
}
 rule 10 {
     outbound-interface eth0
     source {
         address 192.168.10.0/24
     }
     translation {
         address 203.0.113.134
     }
 }

If you've setup IPsec, the SA is up, but for some reason packets don't get through, make sure that you didn't forget to exclude traffic to the remote network from NAT. It's easy to see with tcpdump whether packets are sent the wrong way or not.

Exploiting the interaction

So far we've only seen how this particular processing order can be bad for our setup. Can it be good for anything then? Sometimes it seems like the Linux network stack was optimized to allow doing crazy things. Just a few days ago I've run into a case when this turned beneficial.

Suppose you setup an IPsec tunnel to your partner, and it turns out you both are using 192.168.10.0/24 subnet internally. None of you is willing to renumber your own network to solve the problem cleanly, but some compromise must be made. The solution is to NAT packets before they are encrypted, which works as expected precisely because IPsec happens after SNAT.

For simplicity let's assume only a single host from our network (internal address 192.168.10.45) needs to interact with a single host from the remote network (10.10.10.55). We will make up an intermediate 172.16.17.45 address and NAT the tunnel traffic to and from 10.10.10.55 host to actually be sent to the 192.168.10.45 host.

The config looks like this:

vyos@vyos# show vpn ipsec site-to-site 
 peer 192.0.2.150 {
     [SNIP]
     tunnel 1 {
         local {
             prefix 172.16.17.45/32
         }
         remote {
             prefix 10.10.10.55/32
         }
     }
 }

vyos@vyos# show nat source 
 rule 10 {
     outbound-interface any
destination {
address 10.10.10.55
}
 source { address 192.168.10.45 }
 translation { address 172.16.17.45 } } vyos@vyos# show nat destination rule 10 { destination { address 172.16.17.45 } inbound-interface any translation { address 192.168.10.45 } }

If IPsec was performed before source NAT, this kind of setup would be impossible.

]]>
Daniil Baturin
tag:blog.vyos.net,2013:Post/1238077 2018-01-26T02:54:16Z 2018-07-11T09:55:04Z Copying/renaming, node comments, and other little known features of the VyOS CLI

I promised not to write about either IPsec or NAT this time, so we'll discuss something else: the little known features of the VyOS CLI. Many people only ever use set/delete and commit, but there's more to it, and those features can save quite a bit of time.

The edit level (never write long node paths again)

You might have noticed that after every command, the CLI outputs a mysterious "[edit]" line. This is a side effect of the system that allows editing the config at any level.

By default, you are at the top level, so you have to specify the full path, such as "set firewall name Foo rule 10 action accept". However, to avoid writing or pasting long paths, you can set the edit level to any node with the "edit" command, such as "edit firewall name Foo". Once you are at some level, you can use relative node paths, such as "set rule 10 action accept" in this case.

To move between levels, you can use the "up" command to move one level up, or the "top" command to instantly move back to the top level.

Look at this session transcript:

dmbaturin@reki# edit firewall name Foo
[edit firewall name Foo]

dmbaturin@reki# set rule 10 protocol tcp
[edit firewall name Foo]

dmbaturin@reki# edit rule 10
[edit firewall name Foo rule 10]

dmbaturin@reki# set destination port 22
[edit firewall name Foo rule 10]

dmbaturin@reki# up
[edit firewall name Foo]

dmbaturin@reki# set rule 10 description "Allow SSH"
[edit firewall name Foo]

dmbaturin@reki# top
[edit]

]]>
Daniil Baturin