Overview of my homelab.


This post will be used to add context of the hardware, services, and firewall rules that I work in without having to take up space in my normal posts. This configuration doesn’t run under any best practices but works well for my personal use. This type of setup would work well in a corporate office without any internet facing services outside VPN, but is not something I would design for a PCI or HIPAA network.

Firewall Rules:

Diagram was done in https://www.draw.io/

Rules explained:

Home WIFI:

Home WIFI Network can do almost anything going out to the Internet. The Exceptions are:

  • External DNS is limited to only what is provided by my home lab.
  • Home WIFI Network can only contact the Home Lab via: DNS, SSH, HTTP, HTTPs
  • Guest WIFI

Guest WIFI Network can do almost anything going out to the Internet. The Exceptions are:

  • External DNS is limited to only my home lab.
  • Guest WIFI Network can’t connect to the home lab in any other way.

Home Lab

  • Home Lab is allowed to connect to anything in the Home Wifi, Guest Wifi, and the internet.
  • The Home Lab provides DHCP and DNS to both WIFI environments.
  • The Home Lab has no limitations to the internet at all



A Ubiquiti Edge-X router is managing my firewall rules.

A Ubiquiti Access Point provides wifi for my Home WIFI, and Guest WIFI.

NetGear 5 port 1GB switch (connected to the same network as the homelab)

The hypervisor is a custom build:

  • Shuttle SH97R6,
  • Intel Core-i7 4790k Devil’s Canyon Quad-Core 4.0GHz
  • Muskin Enhanced 16gb PC3L12800Sticks X2
  • OCZ Trion 2.5″ 480GB SSD
  • WesternDigital 4tb 7200rpm
  • Seagate 8tb External USB
  • WesternDigital 8th External USB

This modest system was built 2 years ago, and is running ProxMox as the hypervisor software. This configuration easily runs 7 dedicated VMs, and can handle 3 – 4 more before I start to notice an issue.

Vms and Services I run:

DNS: Dns is handled by Pi-hole running on two debian servers. (These servers are not dedicated to DNS but serve other purposes as well)

SSH: Almost all of my linux servers are headless so SSH is running on all of them. SSH on a non-standard port is the only gateway into my network from the outside world.

DHCP: Debian is running DHCP on all wifi networks. Within the homelab the dedicated VMs have static IPs. I do have a 50 IP range dedicated to the homelab for PXE, VM Templates, etc.

Ansible: CentOS is running as an Ansible Server. This is for linux VM deployment and cookbook testing.

Jenkins (windows instance): Jenkins is running on windows for powershell scripts and several SSH maintenance tasks that run. (Non-dedicated to this VM)

Cacti: A dedicated debian VM is running Cacti to watch for Bandwidth, VM, and hardware usage.

Active Directory: I have a couple of windows VMs that are used for Group Policy or Active Directory post. Both Windows 2012 R2. They do all DNS queries through the  Pi-hole servers.


AWS: This WordPress blog is hosted on a t2.micro instance running mysql and apache on Centos. I didn’t use RDS due to cost.

CloudFlare: A free tier of cloud flare is front of the site as well as providing dynamic DNS services as described in this bonus part of the post.


That is a pretty brief overview of my lab. Let me know if you have any questions on how or why I made a design choice. Unless it is about the equipment the answer is this project is on a budget.


Thanks for reading,


Using Powershell to notify when an email is involved in a data breach.

This week I worked with the Have I been Pwned API. I came up with a pretty use full little script that monitors Email addresses and notifies you if one of them is signed up for a compromised service. Have I been Pwned offers a service for this Here. Which is nice for individual accounts but if your at a business with hundreds of employees you don’t want to be adding accounts manually or sometimes you want to be emailed if someones account is on a pwned. That is where these scripts come in.

The scripts can be found:
Monitor script designed to work with AD can be found on pastebin here.
Monitor script using an array of emails can be found on pastebin here.
Additional functions made from this project can be found on pastebin here.
And as always My github has the full collection.

There are two versions of the monitor script, one with an array you can configure the email addresses manually. The other that pulls directly from active directory. A note: the monitor scripts do not care about the age of the breach. If haveibeenpwned.com gets information on a new breach that happened in 2001 and a users email over laps the user will be notified. After a breach has been identified it is logged and the user isn’t bothered again. The script also “stacks” breaches into one email so as not to spam your users with 100’s of emails.

An email for multiple breaches looks like:


This email is customize-able in the configuration section of the script.

Other quick notes on the use of the script before I go into configuration details. I would suggest not running the script more than once a month, or once a week at the most. The breaches can be old at times and constantly hammering the API will not do any good. There is also a sleep 5 in the script. Feel free to adjust it, I left it in to make sure larger accounts wouldn’t constantly query the API causing issues.

Configuration options for these scripts:

#Make sure the path exists or you will spam your list every time the script runs:
$path_to_notified_file = ".\db\pwnd_list.csv"

This is the database file that keeps the script from spamming your users. Make sure it is correct and writable or your users will be notified repeatedly.

Do you even want to send an email? With $email_notify set to $false the script just generates a CSV file. This lets you build a basic database of old breaches without annoying your users OR determining how many user emails have been involved in breaches.

#SMTP settings:
$email_notify = $true

Customize the Email alert the users will get:

$from = "test@example.com"
$subject = "ATTN: Account was included in a data breach"
$body_html = "Hello,
It has been noticed by an automated system that your email address was included in the following data breaches:"
$body_signature = "
It is recommended you change your passwords on those systems

Thank you
I_script_stuff Notifier Bot

#email credentials enable tested on gmail. If you don’t need credentials set $needs_email_creds to false.
$needs_email_creds = $false
#configure credential file for email password if needed:
$creds_path = “.\cred.txt”
#read-host -assecurestring | convertfrom-securestring | out-file $creds_path

The $needs_email_creds option needs you to setup a password if set to $true. This works on gmail but I haven’t tested it on other systems.
First load the $cred_path variable and then copy and paste the read-host line without the comment like so:

The script doesn’t prompt for anything. Just type your password for the email account and press enter. The password will be stored in the file.

Last bit you need to configure is SMTP server settings:

#SMTP server to use
$smtp = "smtp.gmail.com"
$smtp_port = "587"

Configured for google, you’ll need to know your own SMTP server settings.Monitor script designed to work with AD can be found on pastebin here.
Monitor script using an array of emails can be found on pastebin here.
Now your all set to monitor your corporate environment for breaches involving services your users may have signed up for on there email.


Additional functions made from this project can be found on pastebin here.


function get-breachedstatus() {
[Parameter(Mandatory = $true)][string]$email,

if($brief_report) {
$url = “https://haveibeenpwned.com/api/v2/breachedaccount/” + $email + “?truncateresponse=true”
} else {
$url = “https://haveibeenpwned.com/api/v2/breachedaccount/” + $email
$result = invoke-restmethod “$url” -UserAgent “I_script_stuff checker 0.01”
return $result
} catch {
return $false

This function is what powers the notified script. In the script it does a “truncated response” you can get some interesting information from a none truncated response:
Get-breachedstatus test@example.com

This searches the API for paste breaches and provides the dump. There is no truncated response it just is the response:

function get-pastestatus() {
[Parameter(Mandatory = $true)][string]$email
$url = "https://haveibeenpwned.com/api/v2/pasteaccount/" + $email
$result = invoke-restmethod $url -UserAgent "I_script_stuff checker 0.01"
return $result
} catch {
return $false

Get all breaches dumps the full database of breaches in case you want to cache them:

function get-allbreaches() {
$url = "https://haveibeenpwned.com/api/v2/breaches"

$result = invoke-restmethod “$url” -UserAgent “I_script_stuff checker 0.01”
return $result
} catch {
return $false

Get Domain Stauts queries a specific domain for a breach:

function get-domainstatus() {
[Parameter(Mandatory = $true)][string]$domain,
$url = "https://haveibeenpwned.com/api/v2/breach/" + $domain
$result = invoke-restmethod $url -UserAgent "I_script_stuff checker 0.01"
return $result
} catch {
return $false

You can use these functions to get started with any larger projects. Please skim the api documentation for fair use rules. Though mostly it is don’t do evil.

That is it for this week.  Thanks.