Home Lab - Networking

In this post I will cover the basic set up of the basic building block network which is a simple flat network behind a router acting as Firewall, NAT, DHCP and VPN for the network.

The first action is to create a Virtual Switch that will be connectivity for all the virtual machines in this flat network. Almost all virtual solutions support having a virtual switch under one name or another. Since I choose for my home lab ESXi the commands shown will be for this platform but in general terms can be done the same with Hyper-V or XenServer. 

The main reason why I'm showing all the steps via command line is so that they can be automated later in a script if this is a process that will be repeated several times.

Current Network

For the configuration I will use PowerCLI PowerShell Module (can be used in Windows, Linix and OS X). We start by creating a session to the ESXi server in a PowerCLI window and connect using the Connect-VIServer cmdlet.

PowerCLI C:\> Connect-VIServer -Server 192.168.1.3 -Credential (Get-Credential root) -Force
WARNING:
The server certificate is not valid.


Name                           Port  User
----                           ----  ----
192.168.1.3                    443   root

Once connected we can look at the port groups of the first switch on the server. The default first switch that sets a port group for management and another for virtual machines is vSwitch0 unless it has been renamed. 

 

PowerCLI C:\> Get-VirtualSwitch -Name vSwitch0 | Get-VirtualPortGroup

Name                      Key                            VLanId PortBinding NumPorts
----                      ---                            ------ ----------- --------
Management Network        key-vim.host.PortGroup-Mana... 0
VM Network                key-vim.host.PortGroup-VM N... 0

As it can bee seen the portgroup for the VMs is named VMNetwork. this will the our external network for our lab building block. We can see the details of the switch to know which of the network interfaces is connected by seeing all the properties of the switch object using Format-List cmdlet

PowerCLI C:\> Get-VirtualSwitch -Name vSwitch0 | Format-List -Property *


Id                : key-vim.host.VirtualSwitch-vSwitch0
Key               : key-vim.host.VirtualSwitch-vSwitch0
Name              : vSwitch0
NumPorts          : 1792
NumPortsAvailable : 1779
Nic               : {vmnic0}
Mtu               : 1500
VMHostId          : HostSystem-ha-host
VMHost            : 192.168.1.3
VMHostUid         : /VIServer=root@192.168.1.3:443/VMHost=HostSystem-ha-host/
Uid               : /VIServer=root@192.168.1.3:443/VMHost=HostSystem-ha-host/VirtualSwitch=key-vim.host.VirtualSwitch-v
                    Switch0/
ExtensionData     : VMware.Vim.HostVirtualSwitch
Client            : VMware.VimAutomation.ViCore.Impl.V1.VimClient

We can see that the interface is vmnic0. All this information tells us that the current network configuration looks like the image bellow.

This will be what we will consider our external network for the block. The external interface of the VyOS router will be on the VM Network port group. 

Lab vSwitch and Port Group

Now we need to create the Virtual Switch and Port Group that will host our Virtual Machine. We will user PowerCLI for this also. For this we will use the cmdlet New-VirtualSwitch and then we will confirm no NIC is connected to it.

PowerCLI C:\> New-VirtualSwitch -Name "Lab1"

Name                           NumPorts   Mtu   Notes
----                           --------   ---   -----
Lab1                           1792       1500


PowerCLI C:\> Get-VirtualSwitch -Name lab1 | Format-List -Property *


Id                : key-vim.host.VirtualSwitch-Lab1
Key               : key-vim.host.VirtualSwitch-Lab1
Name              : Lab1
NumPorts          : 1792
NumPortsAvailable : 1778
Nic               :
Mtu               : 1500
VMHostId          : HostSystem-ha-host
VMHost            : 192.168.1.3
VMHostUid         : /VIServer=root@192.168.1.3:443/VMHost=HostSystem-ha-host/
Uid               : /VIServer=root@192.168.1.3:443/VMHost=HostSystem-ha-host/VirtualSwitch=key-vim.host.VirtualSwitch-L
                    ab1/
ExtensionData     : VMware.Vim.HostVirtualSwitch
Client            : VMware.VimAutomation.ViCore.Impl.V1.VimClient

 

Now we create a Port Group so we we can connect the VMs and the internal interface of the router to. We use the  New-VirtualPortGroup cmdlet.

PowerCLI C:\> New-VirtualPortGroup -Name Lab1 -VirtualSwitch Lab1

Name                      Key                            VLanId PortBinding NumPorts
----                      ---                            ------ ----------- --------
Lab1                      key-vim.host.PortGroup-Lab1    0

In ESXi virtual switches by default have a security policy that prevents one from experimenting by enabling sniffing, ARP Spoofing and other network based attacks and techniques. If one wishes to practice these it is recommended to reduce the security posture of the virtual switch. To see the current security policy that is being applied we use the cmdlet Get-SecurityPolicy.

PowerCLI C:\> Get-VirtualSwitch -Name lab1 | Get-SecurityPolicy

VirtualSwitch                  AllowPromiscuous   ForgedTransmits  MacChanges
-------------                  ----------------   ---------------  ----------
Lab1                           False              True             True

As it can be seen i the output the switch will allow forge transmit, MAC changes but not allow to put an interface in promiscuous mode. To modify the policy we use Set-SecurityPolicy cmdlet. In the example bellow I will set AllowPromiscuous to true.

PowerCLI C:\> Get-VirtualSwitch -Name lab1 | Get-SecurityPolicy | Set-SecurityPolicy -AllowPromiscuous $true

VirtualSwitch                  AllowPromiscuous   ForgedTransmits  MacChanges
-------------                  ----------------   ---------------  ----------
Lab1                           True               True             True

Installing VyOS Router

For my labs I like using VyOS as my router OS, it supports in addition to routing and NAT it can server as a firewall and VPN solution (L2TP/IPSEC and OpenVPN). The OS is open source, installation can be done via ISO image, VMware Appliance (OVA) and even Amazon EC2 has a pre-built appliance one can deploy. It can be downloaded from the VyOS Web Page

I will deploy the VMware OVA appliance using PowerCLI but if you want to install it using the ISO you can use the instruction from the VyOS User Guide

To import a OVA in to ESXi we use the Import-vApp cmdlet. When we look at the help information of the cmdlet we see that Source and VMHost are mandatory parameters.

PowerCLI C:\> help Import-VApp

NAME
    Import-VApp

SYNOPSIS
    This cmdlet imports OVF (Open Virtualization Format) and OVA packages. The package can contain a virtual appliance
    or a virtual machine.


SYNTAX
    Import-VApp [-Source] <String> [-OvfConfiguration <Hashtable>] [[-Name] <String>] [-Location <VIContainer>]
    [-VMHost] <VMHost> [-Datastore <StorageResource>] [-Force] [-DiskStorageFormat <VirtualDiskStorageFormat>]
    [-Server <VIServer[]>] [-RunAsync] [-WhatIf] [-Confirm] [<CommonParameters>]


DESCRIPTION
    This cmdlet imports OVF (Open Virtualization Format) and OVA packages. The package can contain a vApp or a virtual
    machine. The cmdlet returns a VApp object when the OVF contains a vApp and a VirtualMachine object when the OVF
    contains a single virtual machine.


RELATED LINKS
    Online version: http://www.vmware.com/support/developer/PowerCLI/PowerCLI63R1/html/Import-VApp.html
    Export-VApp
    Get-VApp
    New-VApp
    Remove-VApp
    Set-VApp
    Start-VApp
    Stop-VApp
    Move-VApp

REMARKS
    To see the examples, type: "get-help Import-VApp -examples".
    For more information, type: "get-help Import-VApp -detailed".
    For technical information, type: "get-help Import-VApp -full".
    For online help, type: "get-help Import-VApp -online"

We need to make sure we provide the proper values to them. We start by saving in to a variable the VMhost for the ESXi server where we will deploy the OVA file

PowerCLI C:\> $vmhost = Get-VMHost

One of the parameters is Datastore, it is not madatory but I want to make sure the VM goes in to the SSD I have on my server so I list the datastores available.

PowerCLI C:\> Get-Datastore

Name                               FreeSpaceGB      CapacityGB
----                               -----------      ----------
datastore1                             690.048         691.000
SSD1                                   904.075         931.250
isostore                             1,554.740       2,759.977

Once I identified the one I want to use I save the object for it in a variable.

$datastore = Get-Datastore -Name "SSD1"

Now I can import the OVA file I just downloaded from the VyOS web page.

PowerCLI C:\> Import-VApp -Source C:\vyos-1.1.7-amd64-signed.ova -Name "Lab1_Router" -VMHost $vmhost -Datastore $datastore

Name                 PowerState Num CPUs MemoryGB
----                 ---------- -------- --------
Lab1_Router          PoweredOff 1        1.000

When we look at the network adapters of the VM we see that it only has 1 and that it is connected to the "VM Network" port group

PowerCLI C:\> Get-NetworkAdapter -VM "Lab1_Router"

Name                 Type       NetworkName  MacAddress         WakeOnLan
                                                                  Enabled
----                 ----       -----------  ----------         ---------
Network adapter 1    Vmxnet3    VM Network                           True

We need to add another network adapter to VM and add it to the Lab1 port group we created. We start by saving the port group object in to a variable and using that variable with the PortGroup parameter of the New-NetworkAdapter cmdlet to create a new adapter on the VM.

PowerCLI C:\> $pg = Get-VirtualPortGroup -Name lab1
PowerCLI C:\> Get-VM -Name "lab1_router" | New-NetworkAdapter -Portgroup $pg -StartConnected
WARNING: Parameter 'VM' is obsolete. Passing multiple values to this parameter is obsolete.

Name                 Type       NetworkName  MacAddress         WakeOnLan
                                                                  Enabled
----                 ----       -----------  ----------         ---------
Network adapter 2    e1000      Lab1                                False

Once we have added the secondary adapter our logical router network configuration should look as the image bellow.

Router Config

Now we start the router configuration. The home network for this example is a 192.168.1.0/24 network and the internal network will be a 10.101.101.0.24. In the case I need to create subnets using other routers or additional interfaces I will use the third octet to differentiate between them. I tend to commit and and save my configuration as I progress to as to be able to perform test as I move along.

The initial IP configuration of the router will look like the image bellow.

We log via the console to the router using the default credentials of vyos/vyos and in the prompt we can verify the interface names using the show command and run show interfaces, once the names are confirmed I can start the configuration by entering in configuration mode and setting the IP addresses and gateway.

configure
set interfaces ethernet eth0 address 192.168.1.9/24
set interfaces ethernet eth1 address '10.101.101.1/24'
set system gateway-address  192.168.1.1
commit
save

We can test our configuration by using the ping command from the configuration mode prompt sendind 3 echo requests to 8.8.8.8 to test that we can reach the gateway and go beyond it.

vyos@vyos# ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1 ttl=54 time=50.3 ms
64 bytes from 8.8.8.8: icmp_req=2 ttl=54 time=53.6 ms
64 bytes from 8.8.8.8: icmp_req=3 ttl=54 time=47.5 ms

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 47.570/50.545/53.675/2.508 ms
[edit]
vyos@vyos#

Once we know the basic configuration is set we can name the router and change the default password of the vyos account to a more secure one. If you use special characters you need to enclose the password between quotes.

set system login user vyos authentication plaintext-password '$secureP@ss'
set system host-name R0
commit
save

Now we enable SSH on the router for remote administration. In this case we are simply enabling the service. I do recommend you explore hardening the system with the use of keys, limiting ciphers and mac and taking other steps so as to get in to the habit of configuring the lab as if it is a production environment.

set service ssh port '22'
commit
save

In the next step we will configure NAT on the router by tagging the interfaces one outside and the inside and then create the first NAT rile to masquerade the network 10.101.0.0/16. Remember at the beginning I mentioned we could have other subnets and use the third octed to differentiate between them. 

##########################
# Configura NAT interfaces
##########################
set interfaces ethernet eth0 description 'OUTSIDE'
set interfaces ethernet eth1 description 'INSIDE'

#####################
# Configure NAT rule.
#####################
set nat source rule 100 outbound-interface 'eth0'
set nat source rule 100 source address '10.101.0.0/16'
set nat source rule 100 translation address masquerade

commit
save

Next step will be to set an initial configuration of the internal DHCP server. This server will issue IP addresses and basic configuration to the VMs we deploy in the lab

  1. IP Addresses Pool: 10.101.101.20 - .254
  2. Domain: "acmelabs.pv" (you can use any you like)
  3. DNS Server: 10.101.101.1 (Once we have a Active Directory Domain Controller we will change the address)
  4. Default Gateway: 10.101.101.1
#########################
# Configure DHCP service.
#########################
set service dhcp-server disabled 'false'
set service dhcp-server shared-network-name LAN subnet 10.101.101.0/24 default-router '10.101.101.1'
set service dhcp-server shared-network-name LAN subnet 10.101.101.0/24 dns-server '10.101.101.1'
set service dhcp-server shared-network-name LAN subnet 10.101.101.0/24 domain-name 'acmelabs.pvt'
set service dhcp-server shared-network-name LAN subnet 10.101.101.0/24 lease '86400'
set service dhcp-server shared-network-name LAN subnet 10.101.101.0/24 start '10.101.101.20' stop '10.101.101.254'

commit
save

Since in the DHCP pool we specified the router as the DNS server, we will configure the router to act as a DNS forwarder and specify both of google public DNS servers.  The cache size it set to 0 so it always fetches the address, you can change this stetting if you wish and we set it to listen on the internal interface of the router.

###########################
# Configure DNS Forwarding.
###########################
set service dns forwarding cache-size '0'
set service dns forwarding listen-on 'eth1'
set service dns forwarding name-server '8.8.8.8'
set service dns forwarding name-server '8.8.4.4'

commit
save

Next we will configure a basic set of firewall rules and have each set with names.

  • OUTSIDE-LOCAL is for traffic that will hit services ran on the firewall from the outside.
  • OUTSIDE-IN is traffic that comes from the outside to the internal network

The rule set is an easy one. We will allow connection from the outside to the router for:

  • ICMP-ECHO requests, Ping.
  • SSH connections.
  • Basic brute-force mitigation for SSH.
#####################
# Configure Firewall.
#####################

# Default Drop Rules
set firewall name OUTSIDE-IN default-action 'drop'
set firewall name OUTSIDE-IN rule 10 action 'accept'
set firewall name OUTSIDE-IN rule 10 state established 'enable'
set firewall name OUTSIDE-IN rule 10 state related 'enable'

set firewall name OUTSIDE-LOCAL default-action 'drop'
set firewall name OUTSIDE-LOCAL rule 10 action 'accept'
set firewall name OUTSIDE-LOCAL rule 10 state established 'enable'
set firewall name OUTSIDE-LOCAL rule 10 state related 'enable'

# Accept Ping requests
set firewall name OUTSIDE-LOCAL rule 20 action 'accept'
set firewall name OUTSIDE-LOCAL rule 20 icmp type-name 'echo-request'
set firewall name OUTSIDE-LOCAL rule 20 protocol 'icmp'
set firewall name OUTSIDE-LOCAL rule 20 state new 'enable'

# Deter SSh brute-force attacks by allowing only 4 new connections within 60 seconds
set firewall name OUTSIDE-LOCAL rule 30 action 'drop'
set firewall name OUTSIDE-LOCAL rule 30 destination port '22'
set firewall name OUTSIDE-LOCAL rule 30 protocol 'tcp'
set firewall name OUTSIDE-LOCAL rule 30 recent count '4'
set firewall name OUTSIDE-LOCAL rule 30 recent time '60'
set firewall name OUTSIDE-LOCAL rule 30 state new 'enable'

# Allow SSH to Router from the outside.
set firewall name OUTSIDE-LOCAL rule 31 action 'accept'
set firewall name OUTSIDE-LOCAL rule 31 destination port '22'
set firewall name OUTSIDE-LOCAL rule 31 protocol 'tcp'
set firewall name OUTSIDE-LOCAL rule 31 state new 'enable'

# Apply firewall rules
set interfaces ethernet eth0 firewall in name 'OUTSIDE-IN'
set interfaces ethernet eth0 firewall local name 'OUTSIDE-LOCAL'

commit
save
  • Conclusion

In the second part of the series we have:

  • Created a virtual switch and port group for internal network.
  • Deployed a VyOS router image.
  • Basic NAT, SSH and Firewall configuration on the router.

On the next blog post I will cover VPN configuration for both L2TP/IPSec and OpenVPN for access to the internal network.

As always I hope you have found the information useful.