├── .gitignore ├── Configuration.md ├── Diagrams.md ├── ExistingHardware.md ├── ExternalResources.md ├── RCAR.md ├── README.md ├── code └── cf-ddns.sh ├── images ├── conceptual.png └── conceptualHAproxy.png ├── omnigraffle ├── conceptual.graffle ├── conceptualOutsideAcess.graffle └── conceptualOutsideAcess.png └── operational ├── ExternalDDNS.md ├── ExternalDDNSConfiguration.md ├── NamingStandard.md ├── OperationalResources.md ├── RemoteAccess-VPN.md ├── fileservices.md ├── haproxy.md └── ipam.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /Configuration.md: -------------------------------------------------------------------------------- 1 | ## Configuration 2 | 3 | ### DHCP / DNS 4 | tba 5 | 6 | ### OpenVPN 7 | ##### TODO 8 | - create new OpenVPN VM 9 | - Set up letsencrypt certs 10 | - decomission old VM 11 | 12 | ### OwnCloud 13 | Configuration nearly complete. 14 | ##### TODO 15 | - Set up letsencrypt certs 16 | 17 | ### HAProxy 18 | OpenVPN and OwnCloud behind 80/443 19 | - vpn.vninja.com 20 | - oc.vninja.com 21 | 22 | ##### TODO 23 | - Move PoC to Production cluster 24 | - Set static IP -> check IPAM 25 | - Change configuration 26 | - Change FW port forwarding 27 | 28 | ### FreeNas 29 | ### ESXi hosts 30 | 31 | |Host|NIC|IP|Description| 32 | |---|---|---|---| 33 | |ESXi01 |vmnic0|192.168.5.10|VMnetwork| 34 | |ESXi01 |vmnic1|192.168.5.11|VMnetwork| 35 | |ESXi01 |vmnic2|n/a|vMotion| 36 | |ESXi02 |vmnic0|192.168.5.20|VMnetwork| 37 | |ESXi02 |vmnic1|192.168.5.21|VMnetwork| 38 | |ESXi02 |vmnic2|n/a|vMotion| 39 | 40 | ### Network 41 | DHCP Scope: _192.168.5.80 - 192.168.5.254_ 42 | 43 | **Reserved IPs** 44 | 45 | |Host|IP|Description|Configured| 46 | |---|---|---|---| 47 | |gateway|192.168.5.2|Netgear|yes| 48 | |telenor ap|192.168.5.4|n/a|yes| 49 | |ups|192.168.5.15|Eaton|yes| 50 | |cisco switch|192.168.5.17|Cisco|yes| 51 | |freenas|192.168.5.40|HP|yes| 52 | |Owncloud|192.168.5.41|VM|yes| 53 | 54 | 55 | **Reserved Ranges** 56 | 192.168.5.1 - 192.168.5.10 57 | 58 | |From|To|Description| 59 | |---|---|---| 60 | |192.168.5.1|192.168.5.9|Network equipment| 61 | |192.168.5.10|192.168.5.29|ESXi hosts| 62 | |192.168.5.30|192.168.5.49|Available| 63 | |192.168.5.50|192.168.5.69|Static IP assignments / VMs| 64 | 65 | 66 | 67 | Gateway: _192.168.5.2_ 68 | #### VLANS 69 | 70 | |VLAN ID|Description|Segment|Configured| 71 | |---|---|---|---| 72 | |0 |Main|192.168.5.0/24 |NO | 73 | |10 |vMotion|n/a |n/a | 74 | |20 |Lab|n/a |n/a | 75 | 76 | ## SSL Certificates 77 | https://letsencrypt.org 78 | -------------------------------------------------------------------------------- /Diagrams.md: -------------------------------------------------------------------------------- 1 | 2 | # Diagrams 3 | 4 | ## Conceptual Design Diagram 5 | 6 | ![Conceptual Design Diagram](https://github.com/h0bbel/homelab/blob/master/images/conceptual.png "Conceptual Design Diagram") 7 | 8 | [omnigraffle file](https://github.com/h0bbel/homelab/blob/master/omnigraffle/conceptual.graffle) 9 | 10 | 11 | --- 12 | ## Logical Design Diagram 13 | 14 | --- 15 | 16 | ## Physical Design Diagram 17 | -------------------------------------------------------------------------------- /ExistingHardware.md: -------------------------------------------------------------------------------- 1 | #Existing Hardware 2 | 3 | ## ESXi Hosts 4 | |Hostname|Model|CPU|Memory| 5 | |---|---|---|---| 6 | |ESXi01|Dell Inc. Precision WorkStation T7500|Intel(R) Xeon(R) CPU X5560 @ 2.80GHz|16GB| 7 | |ESXi02|Dell Inc. Precision WorkStation T7500|Intel(R) Xeon(R) CPU X5560 @ 2.80GHz|20GB| 8 | ======= 9 | |Hostname|IP|Model|CPU|Memory| 10 | |---|---|---|---|---| 11 | |ESXi01|192.168.5.9|Dell Inc. Precision WorkStation T7500|Intel(R) Xeon(R) CPU X5560 @ 2.80GHz|16GB| 12 | |ESXi02|192.168.5.13|Dell Inc. Precision WorkStation T7500|Intel(R) Xeon(R) CPU X5560 @ 2.80GHz|20GB| 13 | 14 | ##Networking Equipment 15 | 16 | |Hostname|Model|IP| 17 | |---|---|---| 18 | |ciscoswitch|Cisco SG200|192.168.5.17 19 | |router|Netgear WNR3500Lv2|192.168.5.2 20 | |telenorap|ZyXEL P8702N|192.168.5.4 21 | ======= 22 | 23 | ## FreeNAS 24 | 25 | |Hostname|Model|CPU|Memory|Storage| 26 | |---|---|---|---|---| 27 | |freenas|HP MicroServer N36L|AMD Athlon(tm) II Neo N36L Dual-Core|8GB|3.5TB 28 | -------------------------------------------------------------------------------- /ExternalResources.md: -------------------------------------------------------------------------------- 1 | # External Resources -------------------------------------------------------------------------------- /RCAR.md: -------------------------------------------------------------------------------- 1 | # Requirements, Constraints, Assumptions and Risks. 2 | 3 | ## Requirements 4 | |ID|Requirement|Source|Date| 5 | |---|---|---|---| 6 | |RE101|Clustered DHCP services|CM|14/07/2016 7 | |RE102|Clustered DNS services|CM|14/07/2016 8 | |RE103|VPN services|CM|14/07/2016 9 | |RE104|File / Sharing services|CM|14/07/2016 10 | |RE105|IP address management (IPAM)|CM|14/07/2016 11 | |RE106|Reverse Proxy services|CM|14/07/2016 12 | |RE107|Shared media storage|CM|14/07/2016 13 | |RE108|Plex Media services|CM|10/10/2016 14 | |RE109|External Dynamic DNS Service|CM|09/08/2016 15 | 16 | 17 | ## Constraints 18 | |ID|Constraint|Source|Date| 19 | |---|---|---|---| 20 | |CO101|Existing server hardware must be used|CM|14/07/2016 21 | |CO102|Existing network infrastructure must be used|CM|14/07/2016 22 | |CO103|Existing storage hardware must be used|CM|14/07/2016 23 | |CO104|No budget for licenses|CM|14/07/2016 24 | 25 | ## Assumptions 26 | |ID|Assumption|Source|Date| 27 | |---|---|---|---| 28 | |AS101||| 29 | 30 | ## Risks 31 | |ID|Risk|Source|Date| 32 | |---|---|---|---| 33 | |RI101||| 34 | 35 | --- 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Homelab - The Design 2 | 3 | ## Executive Summary 4 | 5 | The purpose of this document is to describe in necessary detail the current project description to represent a suitable model generating Conceptual, Logical and Physical designs for HomeLab. 6 | 7 | The [Conceptual Design](Conceptual.md) presents the proposed structure of the datacenter transformation project, such as the requirements, assumptions and risks involved. 8 | 9 | The [Logical Design](Logical.md) is based on the conceptual design, and provides a more detailed view of the components and relationships. 10 | 11 | This in turn results in a [Physical Design](Physical.md) that can be used to build the entire stack of services. 12 | 13 | 14 | ## "Business" Background 15 | 16 | There was a need to move away from Microsoft Windows based services for Directory, File, DNS and DHCP services, simply because those requires licenses that are soon to be unavailable. It is also imperative that no new HW is to be purchased, and the new design needs to be able to run on existing infrastructure. 17 | 18 | A secondary reason to move away from the existing infrastructure, is to become more proficient in deploying infrastructure services based on open source and Linux. 19 | 20 | *By developing the documentation in this manner, the idea is for it to work as an exercise in writing enterprise design documents.* 21 | 22 | 23 | **Participants** 24 | 25 | The people listed in the following table provided key input into this design: 26 | 27 | 28 | |Name|Email|Role| 29 | |---|---|---| 30 | |Christian Mohn|christian@drible.net|Owner| 31 | 32 | **Version History** 33 | 34 | |Date|Revision|Author|Comments| 35 | |---|---|---|---| 36 | |14.07.2016|0.0.1|CM|Initial Checkin 37 | |14.07.2016|0.0.2|CM|Sectioned into several documents / re-organized a bit 38 | |16.07.2016|0.0.3|CM|Diagrams and Naming Standard added. 39 | |09.08.2016|0.0.4|CM|External Dynamic DNS Service section 40 | |10.10.2016|0.0.5|CM|External IPAM, VPN/Jumphost and HAProxy section (Combined VPN/Jumphost in one section) 41 | |10.10.2016|0.0.6|CM|Added File Services section. Merged File Services and Shared Media Storage in to [File services](operational/fileservices.md). Added Plex Media Server as an required service. Added Log Insight link under Log Management Solution / "Nice to have services" 42 | 43 | 44 | --- 45 | 46 | #Linked documents 47 | 48 | - [Requirements, Constraints, Assumptions and Risks](RCAR.md) 49 | - [Configuration](Configuration.md) 50 | - [Diagrams](Diagrams.md) 51 | - [Existing Hardware](ExistingHardware.md) 52 | - [External Resources](ExternalResources.md) 53 | - [Operational Resources](operational/OperationalResources.md) 54 | - [External Dynamic DNS](operational/ExternalDDNS.md) 55 | - [IPAM](operational/ipam.md) 56 | - [HAProxy](operational/haproxy.md) 57 | 58 | 59 | --- 60 | 61 | ## Identified required services 62 | - **DHCP / DNS** 63 | - **[External Dynamic DNS](operational/ExternalDDNS.md)** 64 | - **[Remote Access / VPN](operational/RemoteAccess-VPN.md)** 65 | - **[File services](operational/fileservices.md)** 66 | - **[IP Address Management](operational/ipam.md)** 67 | - **[Reverse proxying of incoming http and https requests](operational/haproxy.md)** 68 | - **[Plex Media Server](operational/plex.md)** 69 | 70 | ## Nice to have services 71 | - **Directory Services** 72 | - **PXE boot for LAB network** 73 | - **Automated requests for IP addresses (static) from [IPAM](operational/ipam.md)** 74 | - **Local management interface list ala JumpSquares** 75 | - **[Log management solution](operational/loginsight.md)** -------------------------------------------------------------------------------- /code/cf-ddns.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | version='0.2' 4 | cfddns='[CloudFlareDDNS-'$version']' 5 | 6 | #Get current public ip 7 | 8 | MYIP=$(curl -s ifconfig.me/ip) 9 | OLDIP=$(cat oldip.txt) 10 | 11 | 12 | # Instructions: 13 | # Define variables for API calls. Replace these with your own values! # 14 | ################################################################################# 15 | token=12345678901234567890 # CloudFlare token # 16 | email=example@example.com # Cloudflare login account # 17 | z=example.com # Domain Name # 18 | id=1234567890 # CloudFlare Record ID # 19 | type=A # CloudFlare Record Type # 20 | ttl=1 # TTL value # 21 | content=$MYIP # IP address # 22 | ################################################################################# 23 | 24 | if [ "$1" = "-f" ] 25 | then 26 | echo 'cf-ddns called with -f, forcing update!' 27 | OLDIP='' 28 | else 29 | echo 'No parameter found, normal run' 30 | fi 31 | 32 | if [ "$MYIP" = "$OLDIP" ] 33 | 34 | then 35 | logger -s $cfddns "[INFO] No IP change detected" # Write to Syslog 36 | 37 | else 38 | logger -s $cfddns "[INFO] IP change detected, updating CloudFlare trough API. Old IP was "$OLDIP" - New IP is " $MYIP # Write to syslog 39 | 40 | 41 | ######### 42 | # Instructions: 43 | # Copy this block for the different hostnames you want to dynamically update, and insert unique id and name for the record. 44 | ######## 45 | 46 | # hostname: test.example.com 47 | id=51234567890 48 | name=test.example.com 49 | 50 | # Update record: 51 | curl -s -k -L -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d 'a=rec_edit&tkn='$token'&email='$email'&z='$z'&id='$id'&type='$type'&name='$name'&ttl='$ttl'&content='$content 'https://www.cloudflare.com/api_json.html' 52 | 53 | # hostname: test2.example.com 54 | id=1234567891 55 | name=test2.example.com 56 | 57 | # Update record 58 | curl -s -k -L -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d 'a=rec_edit&tkn='$token'&email='$email'&z='$z'&id='$id'&type='$type'&name='$name'&ttl='$ttl'&content='$content 'https://www.cloudflare.com/api_json.html' 59 | 60 | 61 | echo $MYIP > oldip.txt 62 | logger -s $cfddns [INFO] "New IP is: " $MYIP 63 | fi 64 | -------------------------------------------------------------------------------- /images/conceptual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h0bbel/homelab/e3688e4b192eda085943b01dd6e8d6b61d2c5def/images/conceptual.png -------------------------------------------------------------------------------- /images/conceptualHAproxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h0bbel/homelab/e3688e4b192eda085943b01dd6e8d6b61d2c5def/images/conceptualHAproxy.png -------------------------------------------------------------------------------- /omnigraffle/conceptual.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h0bbel/homelab/e3688e4b192eda085943b01dd6e8d6b61d2c5def/omnigraffle/conceptual.graffle -------------------------------------------------------------------------------- /omnigraffle/conceptualOutsideAcess.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h0bbel/homelab/e3688e4b192eda085943b01dd6e8d6b61d2c5def/omnigraffle/conceptualOutsideAcess.graffle -------------------------------------------------------------------------------- /omnigraffle/conceptualOutsideAcess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h0bbel/homelab/e3688e4b192eda085943b01dd6e8d6b61d2c5def/omnigraffle/conceptualOutsideAcess.png -------------------------------------------------------------------------------- /operational/ExternalDDNS.md: -------------------------------------------------------------------------------- 1 | #External Dynamic DNS Service 2 | 3 | ## Abstract 4 | 5 | In order to provide access to internal resources, from the internet, a proper external DNS service needs to be configured. 6 | 7 | After researching several possible options, [CloudFlare](CF) emerged as the clear choice. 8 | 9 | ## Requirements for External Dynamic DNS Service -> [RE109] 10 | |ID|Requirement|Source|Date| 11 | |---|---|---|---| 12 | |RE109.1|Low cost, or free service|CM|09.08.2016 13 | |RE109.2|Automated updates when external IP changes|CM|09.08.2016 14 | |RE109.3|Additional services, like free SSL and securiy|CM|12.08.2016 15 | 16 | 17 | Based on the requirements above, [CloudFlare](CF) ticks all the boxes. The free tier covers DNS hosting, and their publicly available [API](CFAPI) makes it possible to programatically update the records when required. 18 | 19 | 20 | [CF]:https://www.cloudflare.com 21 | [CFAPI]: https://api.cloudflare.com 22 | -------------------------------------------------------------------------------- /operational/ExternalDDNSConfiguration.md: -------------------------------------------------------------------------------- 1 | #External Dynamic DNS Service Configuration 2 | 3 | * External domain name DNS zone hosted by CloudFlare. 4 | * Hostnames for externally resolvable services created, and configured and automatically updated via a custom script. 5 | -------------------------------------------------------------------------------- /operational/NamingStandard.md: -------------------------------------------------------------------------------- 1 | #Naming Standard 2 | 3 | ###[Service Level][Site][Device Role][ID] 4 | 5 | _example:_ phlswh01 = Production Home Lab Switch 01 6 | 7 | Service Level|Description 8 | |---|---| 9 | |p|Production| 10 | |l|Lab| 11 | 12 | --- 13 | 14 | Site|Description 15 | |---|---| 16 | |hl|Home Lab| 17 | |wl|Work Lab| 18 | |aws|amazon web services| 19 | 20 | 21 | --- 22 | 23 | |Device Role|Description| 24 | |---|---| 25 | |swh|switch| 26 | |rtr|router| 27 | |pxy|proxy| 28 | |fle|file server| 29 | |inf|infrastructure (dhcp/dns)| 30 | |vpn|vpn termination| 31 | |web|web server| 32 | |ipm|IPAM server| 33 | |oc|ownCloud| 34 | |jh|SSH Jumphost| 35 | 36 | 37 | 38 | **Note:** 39 | application specific aliases can also be used (eg. _oc = ownCloud_) 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /operational/OperationalResources.md: -------------------------------------------------------------------------------- 1 | # Operational Resources 2 | [Naming Standard](NamingStandard.md) -------------------------------------------------------------------------------- /operational/RemoteAccess-VPN.md: -------------------------------------------------------------------------------- 1 | #Remote Access / VPN 2 | 3 | ## Abstract 4 | 5 | In order to provide access to internal resources, from the internet, proper external access services need to be established. 6 | 7 | ## Requirements for Remote Access / VPN -> [RE103] 8 | |ID|Requirement|Source|Date| 9 | |---|---|---|---| 10 | |RE103.1|Low cost, or free service|CM|10.10.2016 11 | |RE103.2|Full network access (VPN)|CM|10.10.2016 12 | |RE103.3|Limited access, (ssh tunneling / Jumphost)|CM|10.10.2016 13 | 14 | 15 | Based on the requirements above, a dual solution with a "traditional" SSL VPN setup based on OpenVPN in addition to a SSH tunneling (Jumphost) solution was selected. 16 | 17 | -------------------------------------------------------------------------------- /operational/fileservices.md: -------------------------------------------------------------------------------- 1 | #File Services 2 | 3 | ## Abstract 4 | 5 | File services are required for sharing files in the local network. 6 | 7 | 8 | ## Requirements for File Services -> [RE104] 9 | |ID|Requirement|Source|Date| 10 | |---|---|---|---| 11 | |RE104.1|Low cost, or free service|CM|10.10.2016 12 | |RE104.2|Easily accessible from various client devices, and services|CM|10.10.2016 13 | 14 | The old HP MicroServer has been retrofitted with some available SAS drives, and configured with [FreeNAS] as the main file service in the local network. 15 | 16 | Primary usage is photo storage (backed up in Amazon Photos) and media files. This fulfills [CO103](RCAR.md). 17 | 18 | 19 | 20 | 21 | ### Configuration 22 | 23 | **TODO**: Configuration details will come later 24 | 25 | [FreeNAS]:http://www.freenas.org -------------------------------------------------------------------------------- /operational/haproxy.md: -------------------------------------------------------------------------------- 1 | #Reverse proxying of incoming http and https requests 2 | 3 | ## Abstract 4 | 5 | Due to the fact that the internet connection from the lab location is hidden behind one shared public IP, there is a need to reverse proxy incoming requests for http/https (80/443) traffic. 6 | 7 | 8 | ## Requirements for IPAM -> [RE106] 9 | |ID|Requirement|Source|Date| 10 | |---|---|---|---| 11 | |RE106.1|Low cost, or free service|CM|10.10.2016 12 | |RE106.2|Automatic proxying of incoming requests, based on hostname|CM|10.10.2016 13 | 14 | 15 | Based on the requirements above, [HAproxy] was selected as the reverse proxy solution of choice. **HAProxy** is set up to redirect incoming traffic based on referrer (hostname). _hostname1.tld_ redirects to internal ip for _hostname1.local_ and _hostname2.tld_ redirects to internal ip for _hostname2.local_ 16 | 17 | ![Conceptual HAProxy Diagram](https://github.com/h0bbel/homelab/blob/master/images/conceptualHAproxy.png "Conceptual HAProxy Diagram") 18 | 19 | 20 | ### Configuration 21 | 22 | **TODO**: Configuration details will come later, the current setup works (in theory/lab), but needs to be verified. 23 | 24 | 25 | [HAProxy]:http://www.haproxy.org 26 | -------------------------------------------------------------------------------- /operational/ipam.md: -------------------------------------------------------------------------------- 1 | #IP Address Management (IPAM) 2 | 3 | ## Abstract 4 | 5 | IP Address Management is important in larger networks, but also small homelab environments can benefit from automated detection and documentation of in-use IP adresses. 6 | 7 | ## Requirements for IPAM -> [RE111] 8 | |ID|Requirement|Source|Date| 9 | |---|---|---|---| 10 | |RE105.1|Low cost, or free service|CM|10.10.2016 11 | |RE105.2|Automatic detection of new devices|CM|10.10.2016 12 | 13 | 14 | Based on the requirements above, phpipam was selected as the [IPAM](IPAM) solution of choice. 15 | 16 | Custom code was developed to provide notifications to homelab [Slack](Slack) channel. 17 | 18 | [IPAM]:http://phpipam.net 19 | [Slack]:http://slack.com --------------------------------------------------------------------------------