VyOS 1.4.0-rc1 release candidate
- ️Daniil Baturin
Daniil Baturin
Posted 22 Dec, 2023
Hello, community! Exactly two years ago we made the VyOS 1.3.0/Equuleus LTS release. Now, after two years of development, the upcoming 1.4.0/Sagitta release has taken its final shape and we are happy to announce the first release candidate. The 1.4.0-rc1 image is now available for everyone to download and test and will become the new LTS release when real-world testing proves that it's stable and free of unexpected regressions. If you are using an older VyOS LTS release, please try it out in your staging environments and let us know if it works well for you. That includes both negative and positive findings: if a config fails to load or some feature doesn’t work, we need to know that, but it’s equally important to hear if it works well for you without any regressions or surprises. If you are new to VyOS release naming, here's a refresher: after 1.2.0, we name our LTS releases after constellations, sorted by area in square degrees. This release is named after Sagitta — a small constellation of the northern sky. Sagitta means an arrow in Latin, and you will see that in the updated boot screen artwork. But, of course, the name is the least interesting part, so let's get to the features. Since the earliest days of Vyatta (the predecessor of VyOS) and until VyOS 1.4, firewall rulesets were assigned to network interfaces and individual rules in a ruleset could not apply to different interfaces. That was a really strange design decision that was apparently made to make the CLI feel more familiar to network admins experienced with Cisco IOS and its look-alikes. There was no technical reason for that, since Linux firewalls never had that limitation and always allowed admins to either apply a rule to all interfaces or specify an interface — it was a limitation of the CLI. Unfortunately, lifting that limitation wasn't easy because it required a complete redesign of the firewall CLI and a complete rewrite of its configuration scripts. However, we had to rewrite it anyway since we were migrating it from iptables to nftables, so we also used it as a chance to give it the necessary redesign. Now there is no need to assign a ruleset to multiple interfaces, since rules of global policies (such as We also made a strategic mistake during the redesign process: initially, we removed the zone-based firewall. Originally, the zone-based firewall was introduced to make it easier to apply rulesets to network interfaces, since it allowed the admin to assign a ruleset only once to every zone pair and assign network interfaces to zones. Zone-based firewall configuration scripts were also a headache for us because they were separate from the rest of the firewall subsystem but still tightly coupled with it. We assumed that when people could just apply a rule to all interfaces, there wouldn't be any need for zone-based firewall anymore, so we removed it and wrote a migration script that converted old zone-based firewalls to the "normal" firewalls instead. However, we were wrong: many people told us that they liked the mental model and the UI of the zone-based firewall, and that semantically equivalent auto-generated "zone-less" configs were often several times longer. So we corrected our mistake and implemented a zone-based firewall CLI on top of the new nftables-based system. It works and looks like before, with a minor difference: it's under We hope that you enjoy the capabilities of the new firewall system (such as support for transparent bridge firewalls, multiple new group types, and more) and that it works well for you. But if anything is wrong, don't hesitate to report a bug. The original HTTPS API that we introduced in VyOS 1.2.x was pretty good for configuration automation, it has its limitations that made it unsuitable for making full-featured management tools, such as web UIs: it did not provide machine-readable operational mode command versions and could only authenticate clients by pre-configured API keys. Now there is a new API that provides a GraphQL schema, offers a unified approach to configuration and operational mode commands, and, yes, supports authenticating users with their login names and passwords through PAM. Here is now to enable it: Then you can authenticate with the login name and password of any system user, get a JWT token, and use it for queries. Here is a minimal example of a Python script for retrieving the machine-readable equivalent of The output will be like: We will eventually make official bindings for the API to make it even easier to use — at least for Python, and likely for more languages. We expect the new API to make it dramatically simpler to write integrations for any automation and management tools, too. The configuration rollback command that we inherited from Vyatta Core had a serious disadvantage: it would reboot the system before loading the older configuration version. That made it a command of last resort rather than a convenient way to revert changes that did not work as expected. There were two main reasons for that. First, the old approach to default values inadvertently made it impossible to tell if an option was deleted or manually set to its built-in default value. Second, there was no way to construct a "reverse diff" between two config files. Now all command definitions are converted to the new XML-based format that does not have that issue, and we have a library for calculating config diffs, so we introduced an experimental live rollback command. For now, the original rollback is still there, and the new implementation is called rollback-soft. Please try it out and let us know if it works well for you! Once it's fully stable, we will likely rename it to just "rollback" in the 1.5.0 release and rename the original command to "rollback-hard", or remove the old command and add a command to set the default config to a specific revision instead. Now there is a CLI for configuring load balancing with LVS (Linux Virtual Server). For a long time, OpenVPN site-to-site mode with pre-shared keys served as a lightweight alternative to full-blown client-server setups with PKI and to VPN protocols that are less tolerant to weird networks, since it can work over TCP (alas, mostly tolerant to unintentionally weird networks — OpenVPN was proved vulnerable to blocking with DPI and there's no built-in obfuscation solution yet, but that's another story). However, the pre-shared key support is due to be removed in upcoming OpenVPN versions. It's still supported in VyOS 1.4, but we are almost certain that we will be unable to support it in VyOS 1.5, so we encourage everyone to migrate to site-to-site with self-signed certificates and peer fingerprint verification — a mode that is a lot more secure but only slightly more cumbersome to set up. In short, you can generate a self-signed certificate — we recommend using elliptic curve ones: Then you can view its fingerprint using a new operational mode command: Finally, you can specify the fingerprint on the remote router: Then generate a certificate on the remote router and repeat the procedure on the local one. Another thing to note: the DH file option is no longer required for OpenVPN — if it's not set, it defaults to the elliptic curve Diffie-Hellman algorithm, so a self-signed certificate for each side is literally all you need for the new site-to-site setup to work, and client-server setups can now use fewer options as well. In the final 1.4.0 release post, we will include something about every new feature. Right now it's too early to give an exhaustive list because there still may be backports from the current branch. But here is a list of features you may want to test: Testing! A lot of testing... but we hope that no serious issues turn up and we can release the final 1.4.0 images early in the new year. Then the 1.4.0 LTS branch will be supported for at least three years. Since it's based on Debian 12/Bookworm, that gives us almost four years of security updates even before we turn to the extended LTS from Freexian. And there are big plans for the next 1.5 release, of course — stay tuned for development updates!
If you are a community member, note that we are always happy to offer contributor subscriptions to everyone who tests release candidates and reports the findings, so grab the image and give it a try in your home lab.What’s new?
The new firewall
firewall ipv4 forward
) apply to all interfaces by default. Moreover, it's now possible to make a rule apply to multiple interfaces at once by using interface groups. For example:vyos@vyos# show firewall
group {
interface-group WAN {
interface eth1
interface eth2
}
}
ipv4 {
forward {
filter {
rule 10 {
action jump
jump-target In
}
}
}
name In {
rule 10 {
action accept
destination {
port 443
}
inbound-interface {
group WAN
}
protocol tcp
}
}
}
firewall zone
rather than the top-level zone-policy
node:set firewall zone LAN from WAN firewall name WAN-In
GraphQL API and PAM authentication
set service https api graphql authentication type token
show version
:#!/usr/bin/env python3
import json
from requests import request
VYOS_URL = 'https://vyos.example.com/graphql'
auth_query = """
mutation {
AuthToken (data: {username: "vyos", password: "vyos"}) {
success
errors
data {
result
}
}
}
"""
version_query = """
{
ShowVersion (data: {}) {
success
errors
op_mode_error {
name
message
vyos_code
}
data {
result
}
}
}
"""
res = request('POST', VYOS_URL, verify=False, headers={}, json={'query': auth_query})
token = res.json()["data"]["AuthToken"]["data"]["result"]["token"]
res = request('POST', VYOS_URL, verify=False, headers={'Authorization': f'Bearer {token}'}, json={'query': version_query})
print(json.dumps(res.json(), indent=2))
$ python3 ./api-client.py
{
"data": {
"ShowVersion": {
"success": true,
"errors": null,
"op_mode_error": null,
"data": {
"result": {
"version": "1.4.0-rc1",
"built_by": "Sentrium S.L.",
"built_on": "Thu 21 Dec 2023 19:06 UTC",
"build_uuid": "2463607a-ddc5-4942-8685-00d078350c68",
"build_git": "81ec3de04eb291",
"build_branch": "sagitta",
"release_train": "sagitta",
"lts_build": true,
"build_comment": "",
"system_arch": "x86_64",
"system_type": "KVM guest",
"boot_via": "livecd",
"hardware_vendor": "innotek GmbH",
"hardware_model": "VirtualBox",
"hardware_serial": "0",
"hardware_uuid": "33d93ca6-9d47-de4a-bb49-85ed5101970c"
}
}
}
}
}
Live configuration rollback
Load balancing with LVS
vyos@vyos# show high-availability virtual-server
virtual-server Test {
address 203.0.113.1
algorithm least-connection
forward-method nat
port 443
protocol tcp
real-server 10.0.0.1 {
port 443
}
real-server 10.0.0.2 {
port 443
}
}
OpenVPN site-to-site with TLS and peer fingerprint verification
vyos@left# run generate pki certificate self-signed install openvpn-local
Enter private key type: [rsa, dsa, ec] (Default: rsa) ec
Enter private key bits: (Default: 256)
Enter country code: (Default: GB)
Enter state: (Default: Some-State)
Enter locality: (Default: Some-City)
Enter organization name: (Default: VyOS)
Enter common name: (Default: vyos.io)
Do you want to configure Subject Alternative Names? [y/N]
Enter how many days certificate will be valid: (Default: 365)
Enter certificate type: (client, server) (Default: server)
Note: If you plan to use the generated key on this router, do not encrypt the private key.
Do you want to encrypt the private key with a passphrase? [y/N]
2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
[edit]
vyos@left# compare
[pki]
+ certificate openvpn-local {
+ certificate "MIICJTCCAcugAwIBAgIUMXLfRNJ5iOjk/ uAZqUe4phW8MdgwCgYIKoZIzj0EAwIwVzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzEQMA4GA1UEAwwHdnlvcy5pbzAeFw0yMzA5MDcyMTQzMTNaFw0yNDA5MDYyMTQzMTNaMFcxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlTb21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxEDAOBgNVBAMMB3Z5b3MuaW8wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASp7D0vE3SKSAWAzr/lw9Eq9Q89r247AJR6ec/GT26AIcVA1bsongV1YaWvRwzTPC/yi5pkzV/PcT/WU7JQIyMWo3UwczAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUBrAxRdFppdG/UBRdo7qNyHutaTQwHwYDVR0jBBgwFoAUBrAxRdFppdG/UBRdo7qNyHutaTQwCgYIKoZIzj0EAwIDSAAwRQIhAI2+8C92z9wTcTWkQ/goRxs10EBC+h78O+vgo9k97z5iAiBSeqfaVr5taQTS31+McGTAK3cYWNTg0DlOBI8aKO2oRg=="
+ private {
+ key "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgtOeEb0dMb5P/2Exi09WWvk6Cvz0oOBoDuP68ZimS2LShRANCAASp7D0vE3SKSAWAzr/lw9Eq9Q89r247AJR6ec/GT26AIcVA1bsongV1YaWvRwzTPC/yi5pkzV/PcT/WU7JQIyMW"
+ }
+ }
[edit]
vyos@left# commit
vyos@left# run show pki certificate openvpn-local fingerprint sha256
5C:B8:09:64:8B:59:51:DC:F4:DF:2C:12:5C:B7:03:D1:68:94:D7:5B:62:C2:E1:83:79:F1:F0:68:B2:81:26:79
vyos@right# set interfaces openvpn vtun1 tls peer-fingerprint '5C:B8:09:64:8B:59:51:DC:F4:DF:2C:12:5C:B7:03:D1:68:94:D7:5B:62:C2:E1:83:79:F1:F0:68:B2:81:26:79'
What else?
set protocols babel
)set load-balancing reverse-proxy
)set service monitoring zabbix-agent
)set interfaces sstpc
)What's next?