A Blog About Self-Imposed IT Projects and Tech Exploration

Category: Walk Throughs and Guides (Page 2 of 2)

Creating a Domain: Install Active Directory in Server Core

It’s time to create the internal LAN network starting with a domain controller and Active Directory domain. I am going to install Active Directory on server core using PowerShell. I will start by cloning the template from the previous post.

Creating the Domain Controller

Prerequisite: Streamline and Simplify Installs: Create a Windows Server Template

Cloning a template saves significant time on new server creation. To clone the Windows server template, I just right click the template and select clone. I am going to create a full clone and call it AD.

Specify the name as AD and mode as full clone.
Naming the new server and selecting the mode

After running that I have to wait for the clone to finish creating. In Proxmox it has a lock symbol over the name until its done.

Lock symbol over the name showing it is still creating the server.
Proxmox is still creating the clone

After clone creation, I just start it and then I have to reset the Administrator account password. Sysprep removed all existing user accounts so I have to reset the password again.

Resetting the administrator account password on initial login.
Reset the administrator account password

Next I used SConfig to set a static IP address aligned to my network diagram, and configured the DNS server to use the Pi-hole in my DMZ. After that my server is ready for the Active Directory install.

Using SConfig to set a static IP address.
Setting a static IP address and DNS server using SConfig

Install Active Directory on Server Core

To install Active Directory on server core, I am going to use PowerShell. From PowerShell I run this command. After running I will see the progress on a bar at the top of the window.

PS C:\Users\Administrator> Install-WindowsFeature AD-Domain-Services -IncludeManagementTools -Verbose
Install Active Directory on Server Core using PowerShell

After the feature installation finished, I need to install the forest for my domain. The domain name I am using is corp.globomantics.local because I am using this lab for Pluralsight courses. The command to install the forest is:

PS C:\Users\Administrator> Install-ADDSForest -DomainName corp.globomantics.local

Once that runs I just need to set the Safe Mode Administrator Password and confirm that the server will be a domain controller after completion. After confirming, the servers creates the domain and becomes a domain controller.

Set safe mode administrator password and confirm that server is a domain controller
Confirm that the server will be a domain controller
Install-ADDSForest command running

After the install finishes the server reboots and then I need to login, check services, and configure DNS. I ran a dcdiag command to check the server and made sure it passed all the tests. Success! My domain is up and running.

Example output of dcdiag command
Check AD functionality by running dcdiag

Configure DNS for the internal domain

The next step is configuring DNS for our internal domain. The first check is making sure the DNS forwarders are set correctly to my Pi-hole in the DMZ.

PS C:\Users\Administrator> Get-DNSServerForwarder
Output of Get-DNSServerForwarder command
Check DNS forwarders and confirm they are correct

Next I had to configure the DMZ Pi-hole to allow requests from outside of the DMZ network. While the warning says potentially dangerous, since this server is not directly connected to the Internet it meets the home setup criteria.

Change Pi-hole Interface settings to permit all origins
Permit all origins set in Pi-hole to enable queries from outside of the DMZ

Now I can confirm that DNS is resolving correctly by pinging an external host and the internal domain.

Ping results showing that DNS is resolving correctly.

The last step for DNS configuration is adding a reverse lookup zone using PowerShell. I can add the zone using the command below and check it using the Get-DNSServerZone command.

PS C:\Users\Administrator> Add-DnsServerPrimaryZone -NetworkID "10.0.1.0/24" -ReplicationScope "Domain"
Example output showing Reverse lookup zone creation in PowerShell

Now that DNS is working correctly, I need to change the DHCP scope from pfsense to use the new server.

Changing pfsense DHCP to use the new server's IP address
Changing the DHCP settings in pfsense

Add Active Directory Users in Server Core

The last step I am taking is creating a new user to act as Globomantics domain administrator, Bob. I am going to create a user account and separate admin account called Bob User and Bob Admin. I can use PowerShell to create the accounts with these commands.

PS C:\Users\Administrator> New-ADUser -Name "Bob User" -GivenName "Bob" -Surname "User" -SamAccountName "BUser" -UserPrincipalName "Buser@corp.globomantics.local" -AccountPassword(Read-Host -AsSecureString "Input Password") -Enabled $true

PS C:\Users\Administrator> New-ADUser -Name "Bob Admin" -GivenName "Bob" -Surname "Admin" -SamAccountName "BAdmin" -UserPrincipalName "BAdmin@corp.globomantics.local" -AccountPassword(Read-Host -AsSecureString "Input Password") -Enabled $true

Adding the Bob Admin account to domain admins is another quick command.

PS C:\Users\Administrator> Add-ADGroupMember -Identity "Domain Admins" -Members BAdmin

That’s it, we have a domain, domain controller, DNS server, and domain admin. Globomantics internal network is ready for new users and computers. The first computer I am going to add is a Windows 10 machine that my user Bob Admin will use. I will install the Remote Server Administration Tools (RSAT) to enable remote administration of the servers.

Streamline and Simplify Installs: Create a Windows Server Template

Creating a base Windows Server template for my future VMs and later another for my Windows workstations allows me to conduct all the basic configuration, updates, and other typical install task once rather than with each server I create. This also allows me to clone the template which is much faster than an install from ISO. While I only have two servers planned for now, this will save time creating even the second machine, and significant time on all future servers I create.

Creating Windows Server Templates

I am using Proxmox if you haven’t been following along, but the process of creating a template to clone is similar in all Virtualization platforms with minor variations.

Creating any virtual machine template consists of four basic steps:

  1. Install the VM with all drivers, updates, and software packages
  2. Configure any other standard configurations that will apply to all servers
  3. Remove all user data, passwords, and keys – for Windows run a sysprep
  4. Convert the machine to a template

I created a virtual machine in Proxmox with the following specs:

  • Name: WinSrv2019
  • OS: mapped to ISO file on my host
  • Disk: 100GB (can be less)
  • CPU: 1 socket / 4 cores
  • Memory: 4096MB (4 GB)
  • Network: LAN / MTU 1450 (this is due to VXLAN in my lab)

After creating the VM and booting up, I get the install screen for Windows Server 2019.

Windows Server 2019 Install screen for template VM
Windows Server 2019 install screen

When selecting an operating system I am going to use Windows Server 2019 Standard Evaluation edition without the desktop experience. I will configure the servers from command prompt / PowerShell and then remotely administer from one of the Windows 10 workstations.

OS selection for Windows 2019 installer, selecting default standard without desktop experience
Selecting the desired version for install

After this step I configured my desired install drive and started the server installation.

Server 2019 installation starting
Server 2019 install in progress

After the install finished, I rebooted the server and then logged in with the Administrator account to access the command prompt.

Command prompt in Windows Server 2019 without desktop experience
Command prompt after initial login to Server 2019

To update the server, I used PowerShell to check Windows update with the command below and then reviewed the updates.

PS C:\Users\Administrator> $updates = Start-WUScan
Reviewing the updates stored in the $updates variable
Review the applicable updates

To install the updates, I used the command below. You get some feedback showing the install progress as it runs.

PS C:\Users\Administrator> Install-WUUpdates -Updates $updates
Install updates from command line progress screen
Screen showing the update install progress

Once complete I got the feedback “True” in the command prompt. I then ran the command below to check for pending reboot. In my case a reboot was required so I rebooted the server.

PS C:\Users\Administrator> Get-WUIsPendingReboot

After reboot I enabled Windows Remote Management (winrm).

PS C:\Users\Administrator> winrm quickconfig

I also set some basic options like enabling remote desktop and ensuring my servers had the correct timezone using SConfig.

Example SConfig screen run from command prompt to configure the server
Example SConfig after enabling Remote Desktop

I also made a firewall change and registry change to ensure remote desktop access is enabled.

PS C:\Users\Administrator> netsh advfirewall firewall set rule group="remote desktop" new enable=Yes

PS C:\Users\Administrator> cscript C:\windows\system32\scregedit.wsf /ar 0

These were all the custom changes I wanted to make so now I just need to run a sysprep to make the server ready for use as a template.

Prepare for Template Creation

Running a Sysprep is done by running sysprep.exe and setting the options in a Window that comes up. I chose to generalize, Enter System Out-of-Box Experience (OOBE), and shutdown once complete.

PS C:\Users\Administrator> C:\Windows\System32\Sysprep\sysprep.exe
Sysprep window with OOBE, Generalize, and Shutdown selected.
Selecting the options in sysprep

Once shutdown, the last step is converting to a template. In Proxmox that is a very simple process, I just right click and select “convert to template”.

Server install converted to template for cloning
Server template in Proxmox

That’s it, I am ready to clone the template into my domain controller and file server. The new servers will already have all the updates and basic configuration I want for my lab.

New Capabilities: Install Pi-hole for DNS on an LXC

I need a Domain Name System (DNS) server to control DNS queries and allow my internal and DMZ networks to access the Internet. Due to the low resource requirements, I can use Linux Containers (LXCs) rather than a full VM for these servers. I am going to install a Pi-hole for DNS on an LXC in the DMZ and on the external network. This allows the internal network to forward requests to a server within the domains control without exposing the Active Directory servers to the Internet. Using Pi-hole also allows me to configure a blacklist for certain domains. I use this on my personal network to remove ads which is Pi-hole’s main purpose.

Set up a Linux Container (LXC) for Pi-hole

Prerequisite: Creating a DMZ in pfsense to Separate Internal Servers

Since it’s the first time I am using a Linux Container (LXC) I will walk through the process to set one up in Proxmox. The first step is to get a CT Template since I don’t have one already. I will use the Ubuntu-20.04-standard tempalte.

Image of local storage on vmhost1 showing CT template screen.
Add a CT Template to local storage
Selecting ubuntu-20.04-standard as the template for DNS LXCs.
Selecting a template

Once the download is complete you can create a LXC container in Proxmox.

Example first screen of LXC configuration
Configure the basic information for the LXC
Screen showing template selection
Choose the template previously downloaded

After selecting the template I selected the system resources for the LXC. My DNS servers will have the following resources:

  • Disk: 8GB
  • CPU cores: 1
  • Memory: 512MB / Swap: 512MB
  • Network: Bridge for external / DMZ for DMZ server
  • Static IP: follows network diagram
  • DNS: use host settings for external / external DNS server IP for DMZ

Once you create the LXC the install happens automatically. Once you start it you access using root and the password set during configuration.

pi-hole login page for external DNS
LXC login page for my external DNS server

Install Pi-hole for DNS on the LXC

Like with the other VMs my first step is to update, upgrade, and install dependencies. All I need for Pi-hole is curl to run the command in Pi-hole’s install guide.

# apt update && apt upgrade -y
# apt install curl
Install curl using # apt install curl
Install curl to run the Pi-hole install command

After the update and upgrade I rebooted, then I ran the install command.

# curl -sSL https://install.pi-hole.net | bash
Install screen after running command
Install screen should show up after running the command

After running the system checks the Pi-hole automated installer will start.

Pi-hole automated installer screen
Pi-hole automated installer screen

From here I chose the following settings for my server:

  • Upstream servers: OpenDNS for external / External pi-hole for DMZ
  • Blocklists: Yes
  • Install Admin Web Interface: Yes
  • Web Server: Yes
  • Everything else was left default

After that I had a summary page with admin webpage login password.

Install complete summary page
Install complete summary page with web admin password

Once the server is finished installing I accessed the web interface, and then logged in to the Pi-hole dashboard.

Pi-hole dashboard after initial login
Pi-hole web admin dashboard

Firewall and DHCP changes

I am using the pfsense firewall as my DHCP server so for the DMZ interface I needed to change the DNS servers to the new Pi-hole. I am not changing the LAN interface yet because those machines will eventually use the domain controller for its DNS which will forward requests to the Pi-hole.

Pi-hole DNS changes on pfsense web interface
Changing the DHCP scope on Pi-hole

Next it’s finally time to build my internal network, starting with a domain controller. Before installing that I am going to create a Windows Server template to streamline future server installs.

Creating a DMZ in pfsense to Separate Internal Servers

The next step to set up my lab involves configuring the pfsense firewall to create a DMZ. Within the DMZ I will create a DNS server using Pi-hole, email server using iRedMail, and a vulnerable web server from Vulnhub. Using a DMZ allows me to set different firewall rules for external facing and internal servers. This also allows me to control the traffic between the DMZ and LAN which provides a greater level of protection for the internal network.

How pfsense Firewall Rules Work

Before creating any rules it helps to understand the traffic flow through pfsense on our small network. There are two ways of setting up a DMZ. One way is to have two separate firewalls, one attached to the WAN, and one to the LAN. Between the two firewalls is the DMZ.

Example DMZ using two firewalls to separate the external and internal networks
Example configuration using two firewalls

Configuring rules is fairly straightforward in this setup since each firewall only has two interfaces to configure. In my network I am using a single firewall to enable this using this network diagram.

Diagram of lab network with firewall, external, DMZ, and internal networks.
Lab network overview diagram

To help understand how to configure rules in this setup, we need to think about how the traffic flows. The WAN interface is by default configured to block all traffic, and each interface is configured with a default deny. I will configure WAN rules later to forward specific ports to servers in the DMZ. To configure the DMZ I need to choose which traffic to allow out and to where. All traffic not specifically permitted will be denied.

Firewall rule configuration on each interface in the lab network
Firewall rule configuration in pfsense

Creating the DMZ in pfsense

Prerequisite: Creating the Linux Admin Workstation

Using the Linux admin workstation I accessed the firewall’s webConfigurator and changed the OPT1 interface’s firewall rules. The first rule shown in a step by step below was adding UDP port 53 to allow DNS traffic.

Empty firewall rules page on DMZ interface in pfsense
Firewall rules page on DMZ interface before rules are added
Add a UDP port 53 rule in the pfsense add rule interface.
Adding the rule for UDP port 53 to enable DNS traffic
Adding a rule description for future reference to understand the rule's purpose
Adding a rule description for future reference

While configuring the DMZ I also added rule necessary for web traffic and the ability to ping between the LAN and DMZ. These rules included:

  • TCP port 80 (HTTP) from DMZ to all
  • TCP port 443 (HTTPS) from DMZ to all
  • ICMP any from LAN to DMZ
  • ICMP echo reply from DMZ to LAN
Full DMZ list of rules for the lab network
Full DMZ firewall rule set for my lab

The last step I took was to rename the OPT1 interface and make sure the right MTU is set for VXLANs.

Renaming the DMZ interface to DMZ and setting the MTU to 1450
Rename the DMZ interface

That’s all there is to it, I created a DMZ using pfsense and it’s ready for server deployment. Next I am going to install a DNS server on the external and DMZ networks.

Creating the Linux Admin Workstation

To connect to the LAN interface of the pfsense firewall and use the webConfigurator I need a virtual machine on the LAN Vnet. I am going to install Ubuntu Desktop in Proxmox to act as the Linux admin workstation for my lab network. The desktop version will give me a web browser to access the firewall, and later I can add the machine to the networks Active Directory domain.

Install Ubuntu Desktop in Proxmox

Prerequisite: Installing a Network Firewall Using Pfsense in Proxmox

I covered the step by step instructions with screenshots for creating a virtual machine in Proxmox in the post linked above. From this post on I will list the settings used for each machine instead of walking through each step.

Linux Admin Workstation:

  • Name: UbuntuDesktop
  • Start on boot: no
  • ISO image: ubuntu-22.04.2-desktop-amd64.iso
  • System: defaults
  • Disk size: 40GB
  • CPU: 1 socket / 2 cores
  • Memory: 2048MB
  • Network: LANnet / MTU 1450

On boot you will see the Install screen for Ubuntu where you select the language and install Ubuntu.

Ubuntu Desktop install screen with language select and try or install Ubuntu options.
Install screen for Ubuntu Desktop

I kept the default options throughout the install with the exception of selecting “minimal installation” instead of “normal installation”.

Updates and other software screen. Select minimal installation instead of normal installation.
Selecting minimal installation on the updates and other software screen

Post Install Actions

After installing Ubuntu, I needed to check my network configuration to ensure the MTU settings were correct and I had network connectivity to the firewall and to the WAN by pinging one of my hosts.

Wired network settings in Ubuntu GUI showing MTU of 1450
Confirm MTU is set to 1450 for VXLAN
Ubuntu terminal showing three successful pings to the vmhost. Access is available through the firewall to the WAN.
Successful ping to the vmhost outside of the VXLAN and through the firewall

Login to the pfsense webConfigurator

Now I navigate to the pfsense webConfigurator address and login to finish setting up the pfsense software.

pfsense webConfigurator page showing next steps to finish software configuration
Pfsense webConfigurator initial page on first load to finish software configuration

I set my hostname and domain to pfsense and the globomantics.local domain I will use for Pluralsight courses.

Example pfsense hostname and domain configuration screen.
Configure hostname and domain

For my network I am unchecking the box to block RFC1918 private networks. My simulated WAN is using the network 172.16.1.0/24 which falls in this range. If I left this checked I would not be able to access anything inside the network.

Uncheck the block RFC1918 private networks option in pfsense webConfigurator
Uncheck block RFC1918 private networks

After finishing these steps, I checked for updates and then finished the configuration. On my network the interfaces reset to 1500 MTU and I had to manually change them back on the shell to regain access. This was covered in the previous post. You can also set the MTU in the webConfigurator on each interface.

pfsense Interface configuration showing LAN interface enabled with MTU set to 1450
Setting the MTU in the webConfigurator

Now my first workstation is online and the initial firewall setup is complete. I am ready to set up the DMZ and configure DNS for my Globomantics network. These topics are the next couple of posts.

Installing a Network Firewall Using Pfsense in Proxmox

I need to enable communication between the VXLANs and the Internet, so the first machine I will create is a pfsense firewall in Proxmox. I will connect the WAN interface to the external network and 2 other interfaces to the VXLANs. This will grant Internet access to the VXLANs, but force the traffic to flow through the firewall.

Creating the Virtual Machine

Prerequisite: Configure Software Defined Networking

The creation of a virtual machine in Proxmox is pretty straightforward. Since this is the first machine in the lab and the first one in this guide I will go into more detail in this post. The first step is to create the machine itself and name it. I configured it to start when the host boots so the VXLNAS have immediate Internet access.

View of create virtual machine showing pfsense name. First step in creating a firewall using pfsense in Proxmox.
Create the virtual machine and give it a name

Next I selected the pfsense ISO image and added it to the CD/DVD drive. I left the system settings default and gave the machine a 40 GB disk.

Selecting pfsense ISO as the operating system installer image.
Selecting the operating system installer image from software uploaded to the server
Leaving the system settings with default settings.
Default system settings for the virtual machine
Setting the disk size to 40GB for the pfsense firewall in Proxmox
Configure disk size set to 40GB

After configuring the disk size, I had to set the CPU and memory settings. I chose to use 1 socket with 2 cores for CPU, and gave the firewall 2048MB or 2GB of RAM.

Configure the CPU to 1 socket with 2 cores in Proxmox
Setting the CPU to 1 socket with 2 cores
Setting RAM to 2048MB or 2GB in Proxmox
Memory set to 2048MB or 2GB for the firewall

Next I set the WAN interface to vmbr0 which is the external facing bridge on my host. Then I confirmed the settings to finish the initial configuration. Before booting I have to add the other 2 interfaces.

Setting the WAN interface to vmbr0 in Proxmox
Set the WAN interface to vmbr0
Screen to confirm settings prior to VM launch. "Start after created" is unchecked.
Confirm settings, uncheck start after created

Before booting the machine I added the DMZ and LAN interfaces, selecting the appropriate Vnet for each bridge. I did not make the change here but recommend configuring the MTU to 1450 now in your setup. You can change it in the pfsense web console if you forget like I did.

LANnet and DMZnet interfaces added to pfsense.
Add the LAN and DMZ interfaces prior to boot

Next, I boot up the machine and am greeted with the pfsense installer.

pfsense installer screen after configuring the virtual machine
Pfsense installer screen

Installing pfsense firewall in Proxmox

Installing pfsense on a virtual machine is also a straight forward process so I will skip the first few installer screens and list the options I selected below.

  • Select Install
  • Select the keyboard layout
  • Select preferred partition method: I went with default
  • Remaining disk options: again I stuck with default
  • When you see a “Last Change!” ZFS configuration select yes to install
  • Once the install is complete select “No” for manual configuration and reboot

After the installation is complete and pfsense reboots you should see a screen stating all links are up. Select no to set up VLANs now.

Installer screen showing all interfaces up and asking to configure VLANs.

Configure the Interfaces

I set my pfsense interfaces to the appropriate Vnets:

  • WAN = vtnet0
  • LAN = vtnet1
  • OPT1 = vtnet2
Example interface configuration assigning the WAN, LAN, and OPT1 to the right virtual interfaces.
Pfsense interface configuration

Next I had to configure the right IP addresses on the interfaces. I left WAN as DHCP, but used option 2 on the main screen to set the LAN and DMZ IPs to the right networks.

Main screen after interface assignment showing WAN and LAN IPs. This requires a change.
Main screen after initial interface configuration

After changing the LAN interface you will receive an IP address for the webConfigurator, in my case the is http://10.0.1.1. Before I switched to the web interface, I had to set the MTU to 1450 on my interfaces using the shell (option 8 from this screen) using the command below.

root: ifconfig vtnet1 inet 10.0.1.1 netmask 255.255.255.0 mtu 1450
root: ifconfig vtnet2 inet 10.10.1.1 netmask 255.255.255.0 mtu 1450
Set the interfaces for internal networks to mtu of 1450 using command ifconfig vtnet1 inet 10.0.1.1 netmask 255.255.255.0 mtu 1450

With that my firewall install is complete and I can switch to the webConfigurator to configure the DMZ network. First, I need a machine to connect to the webConfigurator, which is the subject of the next post.

Configure Software Defined Networking in Proxmox

In the last post I installed Proxmox and set up a cluster with three VM hosts. Before I start setting up virtual machines, I need a way to segment the network so I can make it match the diagram below. To meet this requirement, I need to enable communication between the hosts, but keep the networks segmented using the firewall. The best way I found to accomplish this was to configure software defined networking in Proxmox to create VXLANs for the DMZ and LAN.

Diagram of lab network with firewall, external, DMZ, and internal networks.
Overview of Lab Network Topology

Preparing the Hosts

Prerequisite: Install Proxmox and Configure a Cluster

The first step in any installation is to make sure your hosts are updated. By default, Proxmox hosts will reach out to the enterprise repository, so I need to configure the pve-no-subscription repository. To enable that, I added it to /etc/apt/sources.list like the image below.

View of /etc/apt/sources.list file with pve-no-subscription repository added.
Add the pve-no-subscription repository

After adding the repository, I run an apt update and upgrade to install the latest patches and make sure the new repository works.

# apt update && apt upgrade -y

Now I can install the needed dependencies on each host. Important note here, the next few steps are run on EVERY node in the cluster.

# apt install libpve-network-perl ifupdown2

Configure Software Defined Networking in Proxmox

After updating the hosts and installing the dependencies the last step to enable software defined networking is to add a line to the interface configuration. I added the line below to the /etc/network/interfaces file on every host.

source /etc/network/interfaces.d/*
Image of the /etc/network/interfaces file with added line from one of the hosts.
Example /etc/network/interfaces file with additional line

Once added, you should automatically see the software defined network menu in your datacenter view.

Software defined network menu in Proxmox datacenter view

Adding VXLANs to the Lab Network

Configuring a software defined network in Proxmox consists of three steps for each network. I need to configure a Zone, a Vnet, and if I want to assign an IP range, a Subnet for each VXLAN.

Adding a VXLAN zone

To add a VXLAN zone, you select that zone type in the Proxmox SDN interface. According to Proxmox SDN documentation, when adding a VXLAN, you need to set the MTU to a slightly lower value than the standard 1500. A VXLANs is a simulated layer 2 network on top of the existing network. So the extra 50 bytes allows for the VXLAN header added to each packet. You also need to configure an ID and peer IP address list.

Example VXLAN zone configuration for Lab Network
Example VXLAN zone configuration
Overview of VXLAN zones in Lab Network
DMZ and LAN VXLAN zones added to Lab Network

Adding Vnets and Subnets

Once you configure a VXLAN zone, the next step is to add the associated Vnets and Subnets to each zone. In my lab, each zone will have a single Vnet and Subnet. Here is an example configuration of the LANnet and LAN subnet.

Example Vnet configuration in Proxmox
LANnet Vnet configuration
Vnets overview for the Proxmox lab network
Vnet configuration overview for Lab Network
Example subnet configuration for the LAN network
Example subnet configuration

Apply to Configure Software Defined Networking in Proxmox Lab

The last step is to go back to the SDN overview and apply the configuration. I hit apply and then Proxmox configures the DMZ and LAN VXLANs on each host in the cluster.

Lab Network SDN overview after applying the software defined networking configuration.
Data center overview after software defined network configuration

That’s all there is to it, my lab network is ready for virtual machines. Next up, I create a virtual firewall running pfsense and configure the WAN, LAN, and DMZ interfaces.

Trying Something New – Install Proxmox and Configure a Cluster

I have never used Proxmox before for virtual machines. I was prepared to use VMWare ESXi for this project, but was looking for an option that would allow me to use features only available using vSphere which comes with a cost. After doing some research I ran across Proxmox. I was ready to try something new, and Proxmox offered all of the features I was looking for. So, I figured I would test it out on this build. The steps below walk through how to install Proxmox and configure a cluster.

Prerequisite: Creating a New Home Hacking Lab with Proxmox

Installing Proxmox and Configuring a Cluster

I installed Proxmox by downloading the ISO and imaging a USB drive. From there it was a simple process of booting the servers to the USB and installing Proxmox. As mentioned in the design, I placed these devices on a separate segment of my home network and assigned the IP range 172.16.1.0/24. Each host was assigned a hostname and IP:

  • vmhost1 – 172.16.1.10
  • vmhost2 – 172.16.1.11
  • vmhost3 – 172.16.1.12

After I installed Proxmox, I logged into each host using the web interface: https://[host IP address]:8006. From here I could configure a cluster so I could access all of the machines from a single interface and take advantage of features like VM migration and software defined networking. Creating a cluster in Proxmox is pretty straightforward. You create the cluster and then get the join information and use it to join the other hosts. Here is a picture of my cluster after all the machines were joined.

Screenshot of Proxmox cluster with three hosts, node ID, and IP address. Cluster name is LabNetwork.
Lab Network Proxmox cluster

After the creating the cluster, logging in to any host will give you a Datacenter view with all of your cluster hosts.

Proxmox datacenter view with three virtual hosts and datacenter summary showing a good cluster status.
Lab Network Proxmox datacenter view

Uploading the ISO images

After configuring the cluster, I need to upload the ISO images for each of the servers and workstations. This is a time consuming process, but part of the preparation. I uploaded all of the images I needed to the local storage on each of the hosts.

View of ISO images section of the local storage on vmhost1.
ISO images view on vmhost1

Here are the links to get all of the images I used:

That’s it, it doesn’t take much to install Proxmox and configure a cluster. Now that I have the software images uploaded, I am ready to configure software defined networking to allow me to segment the network.

Using Vagrant to Automate My Pluralsight Lab Builds

It’s time to automate my lab builds with Vagrant. I decided to try and complete 2 Pluralsight courses at the same time over the next 3 months, Suricata: Getting Started, and Scanning for Vulnerabilities with NSE. If you’ve watched any of my previous courses you know that I often do a basic walk through of the lab environment I use, and leave it to you if you want to replicate it.

I just want to say, I don’t like doing this. I apologize that up until now, I didn’t have a better solution. The reason for a brief explanation is due to time constraints. I don’t think anyone wants a 1+ hour walk through of a lab build. However, based on some of you that reached out, my current guide is not enough.

After a week of long nights after work, I have a solution that you can easily deploy using Vagrant. I created three vagrant boxes and stored them on the Vagrant cloud (https://app.vagrantup.com/mattglass). Then I wrote a Vagrant file that you can use to deploy the lab in Virtualbox. I also wrote a file to deploy each machine individually if you want. The machines download and come preconfigured to route between your LAN and an internal Virtualbox network. You just need to make some minor configuration changes to this file.

The Vagrantfile

If want to get started now, here is the file to deploy three machines:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# This script deploys the network for Suricata: Getting Started in VirualBox

# IMPORTANT: If you want to automate as much as possible, you need to 
#   reconfigure the bridge to map to your interface name and the 
#   default gateways to your networks.


Vagrant.configure("2") do |config|
  config.vm.synced_folder '.', '/vagrant', disabled: true
  
  config.ssh.username = 'vagrant'
  config.ssh.password = 'vagrant'
  config.ssh.keys_only = false
  
  # Create Ubuntu Machine
  config.vm.define "ubuntu" do |ubuntu|
    ubuntu.vm.box = "mattglass/ubuntu18-PS"
	ubuntu.vm.box_version = "0.0.2"
    ubuntu.disksize.size = '30GB'

    # Modify the bridge name to match your interface
	ubuntu.vm.network "public_network", bridge: "Intel(R) Dual Band Wireless-AC 7260", 
	  auto_config: false
    ubuntu.vm.network "private_network", virtualbox__intnet: "LAN",
	  auto_config: false


    # Modify the default gateway here to match your network
	$script = <<-SCRIPT
	echo Configuring network routing and forwarding...
    iptables -t nat -D POSTROUTING 1
	route add default gw 192.168.1.1
	route delete default gw 10.0.2.2 dev enp0s3
	SCRIPT
	
	# Applies the script above
	ubuntu.vm.provision "shell", run: "always", inline: $script

	
	# Virtualbox settings
	ubuntu.vm.provider "virtualbox" do |vb|
	  vb.gui = true
	  vb.name = "Ubuntu 18.04"
	  vb.memory = "1024"
	  vb.cpus = "2"
    end
  end
  
  config.vm.define "meta2" do |meta2|
    meta2.vm.box = "mattglass/metasploitable2-PS"
    meta2.vm.box_version = "0.0.1"

    meta2.vm.network "private_network", virtualbox__intnet: "LAN", auto_config: false
	
	$script = <<-SCRIPT
	echo Configuring network routing and forwarding...
	route add default gw 10.0.0.251
	route delete default gw 10.0.2.2 dev eth0
	SCRIPT
	
	# Applies the script above
	meta2.vm.provision "shell", run: "always", inline: $script

    meta2.vm.provider "virtualbox" do |vb|
      vb.gui = true
      vb.memory = "512"
	  vb.cpus = "1"
	  vb.name = "Metasploitable 2"
    end
  end
  
  config.vm.define "meta3" do |meta3|
    meta3.vm.box = "rapid7/metasploitable3-ub1404"
	meta3.vm.box_version = "0.1.12-weekly"
	meta3.vm.hostname = "metasploitable3-ub1404"
	
	meta3.vm.network "private_network", ip: "10.0.0.101", virtualbox__intnet: "LAN"
	
	$script = <<-SCRIPT
	echo Configuring network routing and forwarding...
	route add default gw 10.0.0.251
	route delete default gw 10.0.2.2 dev eth0
	SCRIPT
	
	# Applies the script above
	meta3.vm.provision "shell", run: "always", inline: $script
	
	meta3.vm.provider "virtualbox" do |vb|
	  vb.name = "Metasploitable3-ub1404"
	  vb.memory = "2048"  
    end
  end
end

Vagrantfile Walkthrough

If you’re new to Vagrant, then you may benefit from a more detailed explanation of each of these parts and pieces. First, the beginning of the Vagrant file. This section contains comments describing function, purpose, and important notes. The first line initiates the build (Vagrant.configure…). This line begins all Vagrant files and identifies the “config” variable used in the next few lines.

# -*- mode: ruby -*-
# vi: set ft=ruby :

# This script deploys the network for Suricata: Getting Started in VirualBox

# IMPORTANT: If you want to automate as much as possible, you need to 
#   reconfigure the bridge to map to your interface name and the 
#   default gateways to your networks.


Vagrant.configure("2") do |config|

Next are some global settings that apply to all three machines. Each machine uses the default Vagrant credentials (vagrant/vagrant). All machines use username and password for authentication instead of the Vagrant SSH keys. Metasploitable 3 uses username and password, so I set all of the machines to use the same. As a result, my environment doesn’t operate like a typical Vagrant environment, but the machines run and operate as I intended.

  config.vm.synced_folder '.', '/vagrant', disabled: true
  
  config.ssh.username = 'vagrant'
  config.ssh.password = 'vagrant'
  config.ssh.keys_only = false

Now It Makes the VMs

After the global configuration options comes the Ubuntu machine that is acting as a router between the two networks. This allows you to control access to these vulnerable VMs (although the firewall is completely open initially). You can also simulate accessing these machines from the Internet. Ubuntu is the primary machine for Suricata: Getting Started.

The first block gets my Ubuntu image from the Vagrant cloud and resizes the disk to 30GB. The next section configures the machine with 2 additional interfaces set to a bridged network and an internal Virtualbox network called LAN. Vagrant automatically configures an interface set to NAT. This VM provisions with a script to remove that gateway and ensure traffic routes to my LAN. My initial box had NAT configured using iptables, but I decided to remove that using the iptables line in the script.

Finally, there are Virtualbox specific configurations that display the GUI on load, rename the machine, configure the amount of RAM (1GB), and assign the number of CPUs.

config.vm.define "ubuntu" do |ubuntu|
    ubuntu.vm.box = "mattglass/ubuntu18-PS"
	ubuntu.vm.box_version = "0.0.2"
    ubuntu.disksize.size = '30GB'

    # Modify the bridge name to match your interface
	ubuntu.vm.network "public_network", bridge: "Intel(R) Dual Band Wireless-AC 7260", 
	  auto_config: false
    ubuntu.vm.network "private_network", virtualbox__intnet: "LAN",
	  auto_config: false


    # Modify the default gateway here to match your network
	$script = <<-SCRIPT
	echo Configuring network routing and forwarding...
    iptables -t nat -D POSTROUTING 1
	route add default gw 192.168.1.1
	route delete default gw 10.0.2.2 dev enp0s3
	SCRIPT
	
	# Applies the script above
	ubuntu.vm.provision "shell", run: "always", inline: $script

	
	# Virtualbox settings
	ubuntu.vm.provider "virtualbox" do |vb|
	  vb.gui = true
	  vb.name = "Ubuntu 18.04"
	  vb.memory = "1024"
	  vb.cpus = "2"
    end
  end

Creating the other two…

The rest of the script follows the same pattern to deploy a Metasploitable 2 and Metasploitable 3 Ubuntu VM. The Metasploitable 2 VM is my first attempt at creating a Vagrant box from an existing VM. It’s not perfect, but it does work well enough, and I apologize in advance. Metasploitable 3 deploys directly from Rapid7’s Vagrant cloud. I made a couple of changes to networking to make it work from this internal network.

  config.vm.define "meta2" do |meta2|
    meta2.vm.box = "mattglass/metasploitable2-PS"
    meta2.vm.box_version = "0.0.1"

    meta2.vm.network "private_network", virtualbox__intnet: "LAN", auto_config: false
	
	$script = <<-SCRIPT
	echo Configuring network routing and forwarding...
	route add default gw 10.0.0.251
	route delete default gw 10.0.2.2 dev eth0
	SCRIPT
	
	# Applies the script above
	meta2.vm.provision "shell", run: "always", inline: $script

    meta2.vm.provider "virtualbox" do |vb|
      vb.gui = true
      vb.memory = "512"
	  vb.cpus = "1"
	  vb.name = "Metasploitable 2"
    end
  end
  
  config.vm.define "meta3" do |meta3|
    meta3.vm.box = "rapid7/metasploitable3-ub1404"
	meta3.vm.box_version = "0.1.12-weekly"
	meta3.vm.hostname = "metasploitable3-ub1404"
	
	meta3.vm.network "private_network", ip: "10.0.0.101", virtualbox__intnet: "LAN"
	
	$script = <<-SCRIPT
	echo Configuring network routing and forwarding...
	route add default gw 10.0.0.251
	route delete default gw 10.0.2.2 dev eth0
	SCRIPT
	
	# Applies the script above
	meta3.vm.provision "shell", run: "always", inline: $script
	
	meta3.vm.provider "virtualbox" do |vb|
	  vb.name = "Metasploitable3-ub1404"
	  vb.memory = "2048"  
    end
  end
end

Enjoy the script, and I look forward to your comments on my two new courses at the end of the year. As always, feedback on how this can be improved is welcome.

Newer posts »