I described my needs and ideas for home lab network last time. Recall the main points of our blueprint and let’s go to set up.

Sum-up requirements[1]:

  • configuration should be one and wide on whole cluster
  • separate subnets
  • I have to be able to quick create it and easy connect and switch VM’s to them
  • free authorized access beside local network

[1]January 20, 2024 “Safe and adaptable home lab network configuration with a virtual router on Proxmox”

railway-bernina-railway-express-bernina-preview

Step 0: Proxmox network setup.

First, we have to prepare virtual network interfaces. I think about it like virtual Ethernet plugs. The first plug was already created during installation. Its characteristic feature is that it has the bridge ports parameter set. What’s meant is reflected to our physical network card. It will be our WAN. I always use the Linux bridge with the lowest index - vmbr0 for example.

Option path is: {YOUR_NODE} > system > Network

  • On the list you cen see your network card (the real one); its type is Network Device.
  • important thing is to put an IP address with a mask in the CIDR field when you set up proxmox availability in your network (1.1.1.1/24 - for example).

WAN

proxmox-WAN-setup ~WAN example

If you get the WAN, you can create the rest of the plugs. The rest of the vyos configuration you can repeat for all of them. It’s kind of a common configuration pack.  When creating a new Linux Bridge setup, only the autostart option and comment. The remaining fields are dependent on the needs.

SUBNET

proxmox-subnet-example ~SUBNET example

Step 1: Creating and installation vyos virtual machine. 

I won’t describe the details of that now. I’ll post some installation tutorials another time, maybe. But now, what you need to know are two facts.

  • Unfortunately, to use a stable version of the vyos you’ve got to compile yourself. It sounds hard, but it is super easy. A great step-by-step guide is available in the official docs
  • This guide was created for a stable version. As of the date of writing this article, this is 1.3.x.
  • The virtual machine specification is following the documentation again.

“The minimum system requirements are 512 MiB RAM and 2 GiB storage. Depending on your use, you might need additional RAM and CPU resources e.g. when having multiple BGP full tables in your system."[2]

[2]“Installation and Image Management » Installation » Hardware requirements”

VM’s network devices

Remember, add all of created Linux Bridge to our virtual machine, like Network Divace. Recommend that the indexes match. vmbr0net0. The Vyos changes names a little, and nat0 is eth0, for example, but you’ll know what it looks like on the index number.

Stop for a second and understand how do things with the vyos

The Vyos has two modes:

  • operation mode - where can you check some configuration, etc.
  • configure mode - this mode is for changing our settings.
1
2
vyos@vyos$ configure
vyos@vyos#

To apply changes, use the commit command. For saving, you have to type save. You can save any committed changes. Claro? 🧐

I recommend looking at official documentation for more.

Step 2: WAN Configuration

WAN - it’s wide network. The simplest way to say it’s that network is the Internet. In our configuration, one of the things we have to know is that all rules to describe traffic in and out of that network are public. It’s our window to the world.

Add a description for our WAN interface. The name of the interface depends on the virtual machine configuration.

1
set interfaces ethernet eth0 description 'WAN'

DHCP

Enabling DHCP for our WAN (eth0) interface

1
set interfaces ethernet eth0 address dhcp

OUTSIDE-IN

Create OUTSIDE-IN firewall rules that control the traffic from the outside network to the inside network. The rule drops all traffic by default, except for the packets that match rule 10, which allows traffic that is either established or related to an existing connection.

In all examples below, I use variables for easy coping and pasting.

1
2
3
4
5
6
7
8
firewall_name='OUTSIDE-IN'

set firewall name $firewall_name default-action 'drop'
set firewall name $firewall_name 10 action 'accept'
set firewall name $firewall_name rule 10 state established 'enable'
set firewall name $firewall_name 10 state related 'enable'

set interfaces ethernet eth0 firewall local name $firewall_name

commit & save

OUTSIDE-LOCAL

And the same action for OUTSIDE-LOCAL. This firewall rule defines a policy for the OUTSIDE-LOCAL interface, which drops all traffic by default, except for the following cases:

  • It allows traffic that is part of an established or related connection (rule 10).
  • It allows ICMP echo-request packets (ping) that are new (rule 20).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
firewall_name='OUTSIDE-LOCAL'

set firewall name $firewall_name default-action 'drop'
set firewall name $firewall_name rule 10 action 'accept'
set firewall name $firewall_name rule 10 state established 'enable'
set firewall name $firewall_name rule 10 state related 'enable'
set firewall name $firewall_name rule 20 action 'accept'
set firewall name $firewall_name rule 20 icmp type-name 'echo-request'
set firewall name $firewall_name rule 20 protocol 'icmp'
set firewall name $firewall_name rule 20 state new 'enable'

set interfaces ethernet eth0 firewall in name $firewall_name

commit & save

Step 3: The Vyos’s SSH access: do it once and for all.

The important secure step that you should take immediately after installation is ssh setup and disabling ssh password login.

Enabling ssh port listing.

For example, I use 22, but my recommendation is to use other, non-typical ports.

1
2
3
firewall_port='22'

set service ssh port $firewall_port

OUTSIDE-LOCAL

Open the ssh port. It has to be the same as the port that we typed before. We have to add a rule to Created before [OUTSIDE-LOCAL]

1
2
3
4
5
$firewall_name='OUTSIDE-LOCAL'
set firewall name $firewall_name rule 30 action 'accept'
set firewall name $firewall_name rule 30 destination port $firewall_port
set firewall name $firewall_name rule 30 protocol 'tcp'
set firewall name $firewall_name rule 30 state new 'enable'

commit & save

Remember to forward port to the vyos IP on the physical router.

The IP address is under command (operation mode):

show interfaces ethernet eth0

Disable password authentication.

Chceck it works and disable ssh password auth.

1
2
delete system login user vyos
set service ssh disable-password-authentication

commit & save

Step 4(+ n) - Creation of a separate network (for HOME or LAB VMs)

It’s recursive, repeat this step every time you set up a new network.

Interface

In the creation of new subnets, you have to decide some things:

  • Interface which it’ll be configured

  • Description. It’s obvious.

  • IP address range. Strongly recommend uing RFC 1918 standards.

    10.0.0.0 - 10.255.255.255 (10/8 prefix)

    172.16.0.0 - 172.31.255.255 (172.16/12 prefix)

    192.168.0.0 - 192.168.255.255 (192.168/16 prefix)

  • Domain name.

  • Dhcp addesses range.

1
2
3
4
5
6
7
8
interface='eth1'
desc='HOME'
getway='192.168.1.1'
mask='24'
subnet='192.168.1.0/24'
domain_name='home.local'
dhcp_range_start='192.168.1.9'
dhcp_range_stop='192.168.1.254'

Assigns a description, an IP address, and a subnet mask to the Ethernet interface.

1
2
set interfaces ethernet $interface description $desc
set interfaces ethernet $interface address $getway/$mask

commit & save

DHCP

Assigns network settings to devices that connect to the VyOS device. The service has a name and a subnet, which define the network segment that the service applies to. The commands also specify the gateway, the DNS server, the domain name, the lease time, and the range of IP addresses that the service can assign to the devices.

1
2
3
4
5
6
set service dhcp-server shared-network-name $desc subnet $subnet default-router $getway
set service dhcp-server shared-network-name $desc subnet $subnet name-server $getway
set service dhcp-server shared-network-name $desc subnet $subnet domain-name $domain_name
set service dhcp-server shared-network-name $desc subnet $subnet lease '86400'
set service dhcp-server shared-network-name $desc subnet $subnet range 0 start $dhcp_range_start
set service dhcp-server shared-network-name $desc subnet $subnet range 0 stop $dhcp_range_stop

commit & save

NAT - The internet access

These commands are used to configure network address translation. NAT is a technique that allows devices with private IP addresses to communicate with the public Internet by using a public IP address.

The Important thing is knowing which interface is WAN in your setup. In this example is eth0

You have to check I choose correct rule number. My recommendation is to 100-199 for WAN 200-299 for the next subnet, and so on.

1
2
3
4
5
6
7
rule_number=200
description='internet access'

set nat source rule $rule_number outbound-interface eth0
set nat source rule $rule_number translation address masquerade
set nat source rule $rule_number source address $subnet
set nat source rule $rule_number source description "$description"

commit & save

Here I draw your attention to the translation address field. I use masquarade technique, which allows multiple devices on a private network to share a single public IP address by changing the source address and port number of outgoing packets.

HOME-OUT

It’s time to block access from your subnet. If you want to separate your network from others.

1
2
3
4
5
6
7
8
9
firewall_name='HOME-OUT'

set firewall name $firewall_name default-action drop
set firewall name $firewall_name rule 10 action accept 
set firewall name $firewall_name rule 10 destination address $subnet
set firewall name $firewall_name rule 10 state established enable 
set firewall name $firewall_name rule 10 state related enable

set interfaces ethernet $interface firewall out name $firewall_name

commit & save

DNS

If you have your own DNS server, you should set up forwarding for the created subnet.

1
2
3
4
5
6
7
dns='192.168.1.2'

set service dns forwarding cache-size '0'

set service dns forwarding listen-address $getway
set service dns forwarding allow-from $subnet
service dns forwarding name-server $dns

commit & save

Step 5: Access to the subnet via the WireGuard

I decided to use WireGuard instead of a VPN. Simplicity of configuration, security of connection, and the vyos has it out-of-the-box. Besides this, people say it utilises state-of-the-art cryptography.

firewall

To establish a connection, we have to open ports in our WAN, so add the next rule in OUTSIDE-LOCAL. I suggest changing ports one more time. It’s a one-time step.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
description='WG1_IN'
firewall_name='OUTSIDE-LOCAL'
port='51820'
rule_number=50

set firewall name $firewall_name rule $rule_number action accept
set firewall name $firewall_name rule $rule_number description $description
set firewall name $firewall_name rule $rule_number destination port $port
set firewall name $firewall_name rule $rule_number log enable
set firewall name $firewall_name rule $rule_number protocol udp
set firewall name $firewall_name rule $rule_number source

commit & save

And one more time, remember to forward port to the vyos IP on the physical router.

interface

Setting up the WireGuard is very similar to creating a new subnet. The little difference is that you have to generate key pairs at the beginning. The rest is almost the same.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
wireguard_name='wg1'
wireguard_subnet='192.168.255.1/24'
description='HOME VPN'

run generate wireguard named-keypairs kp_$wireguard_name

set interfaces wireguard $wireguard_name private-key kp_$wireguard_name 
set interfaces wireguard $wireguard_name address $wireguard_subnet
set interfaces wireguard $wireguard_name description "$description"
set interfaces wireguard $wireguard_name port $port

At least one WireGuard peer is required, so add it. In the beginning, create a public key and a preshared key. This second isn’t necessary but will increase security, so use it. Next, we assign those keys to the newly created peer. On the end, set up allowed-ips. It usually sets one possible address for per-peer communication, but everything demands what you need to achieve.

1
2
3
4
5
6
7
8
9
client_name='device-name'
client_pubkey='your-client-pub-key'
client_presharedkey=$(run generate wireguard preshared-key)
allowed_ips='192.168.255.2/32'

set interfaces wireguard $wireguard_name peer $client_name pubkey $client_pubkey
set interfaces wireguard $wireguard_name peer $client_name preshared-key $client_presharedkey
set interfaces wireguard $wireguard_name peer $client_name persistent-keepalive 15
set interfaces wireguard $wireguard_name peer $client_name allowed-ips $allowed_ips

commit & save

generate peer

The vyos provides us with a tool to generate configuration files, but it’s not recommended for production use.

1
2
3
4
$server='your-public-ip'
$address='is-some-address-from-$allowed_ips-range'

run generate wireguard client-config $client_name interface $wireguard_name server $server address 

[3]Remote Access “RoadWarrior” clients

HOME-OUT

Now we can create a link to the network whose access we want. For doing this, open port in HOME-OUT and setup NAT translation from WireGuard net to subnet.

1
2
3
4
5
6
7
8
firewall_name='HOME-OUT'
wireguard_subnet='192.168.255.1/24'
interface_network_to_access='eth1'
description='WireGuard to Home'
nat_rule_number=201

set firewall name $firewall_name rule 20 action 'accept'
set firewall name $firewall_name rule 20 source address $wireguard_subnet

commit & save

NAT

These vyos commands configure a NAT source rule for a WireGuard VPN. They set the outbound interface, replace the source IP with the interface IP (masquerade), specify the WireGuard subnet to apply the rule to. This step is optional, use if you’d like mask WireGuard IPs

1
2
3
4
set nat source rule $nat_rule_number outbound-interface $interface_network_to_access 
set nat source rule $nat_rule_number translation address masquerade 
set nat source rule $nat_rule_number source address $wireguard_subnet
set nat source rule $nat_rule_number description "$description"

commit & save

In case you want to allow all internet traffic via the WireGuard connection, you have to set up NAT translation for the WAN network.

1
2
3
4
5
6
7
8
9
wireguard_subnet='192.168.255.0/24'
interface_network_to_access='eth0'
description='WireGuard HOME internet access'
rule_number=202

set nat source rule $rule_number outbound-interface $interface_network_to_access 
set nat source rule $rule_number translation address masquerade 
set nat source rule $rule_number source address $wireguard_subnet
set nat source rule $rule_number description "$description"

commit & save

Fianl step 🏁 - Connect VMs to setted up subnet and see how easy and fast can you switch them

Finally, now you can manage which VMs are on which network. Only one thing you need to do is select which Linux Bridge (vmbr) uses your VM. It’s Hardware > Network Divace. Visualise it like plugs one into a virtual router, the other into your machine. It’s simple.