Improving the security of your home server

Hi all. My name is Maxim, and I have been running a home server for almost two years now.

I'm not the only one using it at the moment. Many services are publicly available, I also provide virtual machines and many other sensitive services to my friends: disk storage, databases, etc. In this connection, the issue of security arises seriously. In this article I will talk about how I try to ensure security on my home network.

Devices

At the moment there are more than a dozen virtual machines on my network, here are the main ones:

  • Proxy is the entry point for all my websites

  • Machine for containers (pet projects, databases and other services)

  • Media server on which Deluge and Samba ball run

  • 3 machines for Kubernetes cluster

  • 2 Zabbix instances

  • 3 virtual machines that I gave away to friends

There is also a separate machine for CA, Windows 10, which is sometimes used as a workstation via RDP, OpenVPN server, etc. In this article I will consider only the main machines.

The first thing we will do is logically divide the machines into groups and isolate the networks using VLANs

Car

Subnet

Proxy, Car with containers

VLAN 10

Media server

VLAN 11

Kubernetes cluster

VLAN 17

Dedicated virtual machine 1

VLAN 20

Dedicated virtual machine 2

VLAN 21

Dedicated virtual machine 2

VLAN 22

Proxmox

VLAN 77

Zabbix, Work computer

VLAN 99

Almost all my containers are web applications, so I combined Proxy and Container Machine into one VLAN10 subnet

Of the two Zabbixes, only one serves my network, and it will be located in the admin VLAN99, I’ll also throw my work computer here

In general, all subnets that require special rules must have their own VLAN tag so that traffic can be distinguished.

Setting up a Mikrotik router

Creating a VLAN

The first thing we will do is create a bridge for our VLANs

/interface/bridge/add name=bridge-vlan

Let's add ports to our bridge

/interface/bridge/port/add bridge=bridge-vlan interface=ether2 pvid=10
/interface/bridge/port/add bridge=bridge-vlan interface=ether3 pvid=99

In this case, for ether2 is located in Proxmox and it is not necessary to register a tag, because all traffic from there will almost always be tagged, but if this is not the case, using this setting it will be assigned to VLAN10 by default

Behind ether3 there is a working computer, which, as stated above, belongs to VLAN99

Let's indicate which tags can go through our bridge:

  1. VLAN with numbers 11,17,20,21,22,77,99 can pass through the port ether2

  2. If on ether2 a frame arrives without a tag, we assume that it belongs to VLAN10

  3. All traffic coming to ether3 refers to VLAN99

/interface/bridge/vlan
add bridge=bridge-vlan tagged=bridge-vlan,ether2 vlan-ids=11,17,20,21,22,77,99
add bridge=bridge-vlan tagged=bridge-vlan untagged=ether2 vlan-ids=10
add bridge=bridge-vlan untagged=ether3 vlan-ids=99

Let's create interfaces for our VLANs
General command template

/interface/vlan/add name=vlanX vlan-id=X interface=bridge-vlan disabled=no

Where X is the VLAN number

Now you need to assign addresses to VLAN interfaces
I use this template 192.168.X.0 (where X is the VLAN number)

/ip/address/add address=192.168.10.1/27 interface=vlan10
/ip/address/add address=192.168.11.1/29 interface=vlan11
/ip/address/add address=192.168.17.1/27 interface=vlan17
/ip/address/add address=192.168.20.1/30 interface=vlan20
/ip/address/add address=192.168.21.1/29 interface=vlan21
/ip/address/add address=192.168.22.1/29 interface=vlan22
/ip/address/add address=192.168.77.1/30 interface=vlan77
/ip/address/add address=192.168.99.1/27 interface=vlan99

DHCP setup

Let's create pools of addresses that will be issued to clients

/ip/pool/add name=vlan10-pool ranges=192.168.10.2-192.168.10.30
/ip/pool/add name=vlan11-pool ranges=192.168.12.2-192.168.11.6
/ip/pool/add name=vlan17-pool ranges=192.168.17.2-192.168.17.30
/ip/pool/add name=vlan20-pool ranges=192.168.22.2
/ip/pool/add name=vlan21-pool ranges=192.168.21.2-192.168.21.6
/ip/pool/add name=vlan22-pool ranges=192.168.22.2-192.168.22.6
/ip/pool/add name=vlan77-pool ranges=192.168.77.2
/ip/pool/add name=vlan99-pool ranges=192.168.99.2-192.168.99.30

Directly creating DHCP servers

/ip/dhcp-server/add address-pool=vlan10-pool disabled=no interface=vlan10 name=vlan10-dhcp
/ip/dhcp-server/add address-pool=vlan11-pool disabled=no interface=vlan11 name=vlan11-dhcp
/ip/dhcp-server/add address-pool=vlan17-pool disabled=no interface=vlan17 name=vlan17-dhcp
/ip/dhcp-server/add address-pool=vlan20-pool disabled=no interface=vlan20 name=vlan20-dhcp
/ip/dhcp-server/add address-pool=vlan21-pool disabled=no interface=vlan21 name=vlan21-dhcp
/ip/dhcp-server/add address-pool=vlan22-pool disabled=no interface=vlan22 name=vlan22-dhcp
/ip/dhcp-server/add address-pool=vlan77-pool disabled=no interface=vlan77 name=vlan77-dhcp
/ip/dhcp-server/add address-pool=vlan99-pool disabled=no interface=vlan99 name=vlan99-dhcp

Let's write down the parameters that DHCP clients will receive (default-gateway, DNS)

/ip/dhcp-server/network/add address=192.168.10.0/27 gateway=192.168.10.1 dns-server=192.168.10.1
/ip/dhcp-server/network/add address=192.168.11.0/29 gateway=192.168.11.1 dns-server=192.168.11.1
/ip/dhcp-server/network/add address=192.168.17.0/27 gateway=192.168.17.1 dns-server=192.168.17.1
/ip/dhcp-server/network/add address=192.168.20.0/30 gateway=192.168.20.1 dns-server=192.168.20.1
/ip/dhcp-server/network/add address=192.168.21.0/29 gateway=192.168.21.1 dns-server=192.168.21.1
/ip/dhcp-server/network/add address=192.168.22.0/29 gateway=192.168.22.1 dns-server=192.168.22.1
/ip/dhcp-server/network/add address=192.168.77.0/30 gateway=192.168.77.1 dns-server=192.168.77.1
/ip/dhcp-server/network/add address=192.168.99.0/27 gateway=192.168.99.1 dns-server=192.168.99.1

Hypervisor setup

I use Proxmox as a hypervisor, setting up VLANs is very simple.

File contents /etc/network/interfaces

auto lo
iface lo inet loopback

iface enp5s0 inet manual

auto vmbr0
iface vmbr0 inet manual
        bridge-ports enp5s0
        bridge-stp off
        bridge-fd 0
        bridge-vlan-aware yes
        bridge-vids 2-4094

auto vmbr0.77
iface vmbr0.77 inet dhcp

vmbr0 – Linux Bridge, which is configured to work with VLAN. All virtual machines are attached to this bridge and can be assigned a VLAN tag.
Machines with an empty VLAN Tag will send untagged traffic.

vmbr0.77 – This is the interface through which interaction with Proxmox itself occurs. The VLAN tag () is indicated through a dot

So, VLANs are created, traffic is tagged, but the networks are still not isolated.

Firewall rules for VLAN

The firewall in Mikrotik is configured in the same way as iptables

VLAN99, in which Zabbix is ​​located, and the workstation must have access to the entire network.

Let's create a group of interfaces, in Mikrotik terminology it is called Interface Listand add VLAN99 there

/interface/list/add name=ADMIN
/interface/list/member/add interface=vlan99 list=ADMIN

We apply an allowing rule for the group

/ip/firewall/filter/add chain=forward action=accept in-interface-list=ADMIN

In my case, Proxy must have access to some services outside its network, but for it the rule will be stricter. I won't bring him.

The remaining VLANs must be isolated from each other
Let's create another group of interfaces

/interface/list/add name=VLAN

Let's add our VLAN interfaces to it

/interface/list/member/add interface=vlan10 list=VLAN
/interface/list/member/add interface=vlan11 list=VLAN
/interface/list/member/add interface=vlan17 list=VLAN
/interface/list/member/add interface=vlan20 list=VLAN
/interface/list/member/add interface=vlan21 list=VLAN
/interface/list/member/add interface=vlan22 list=VLAN
/interface/list/member/add interface=vlan77 list=VLAN
/interface/list/member/add interface=vlan99 list=VLAN

And let's create a prohibiting rule

/ip/firewall/filter/add chain=forward action=drop in-interface-list=VLAN out-interface-list=!WAN 

This allows packets to be sent from the VLAN only to the Internet.

Access to the network from outside. Setting up a VPN

Mikrotik now has the ability to create a Wireguard server. I like that it's simple, light and transparent, so that's what I'll be using.

First, let's define client groups. Each group will have a separate profile (interface)

  • Admin devices

  • Family devices

  • 2 groups for my friends’ devices to connect to the networks of their virtual machines.

/interface/wireguard/add listen-port=12111 name=wireguard-admin
/interface/wireguard/add listen-port=12112 name=wireguard-family
/interface/wireguard/add listen-port=12113 name=wireguard-tolya
/interface/wireguard/add listen-port=12114 name=wireguard-leha

Wireguard interfaces need to be assigned addresses

/ip/address/add address=10.99.0.1/29 interface=wireguard-admin
/ip/address/add address=10.12.0.1/27 interface=wireguard-family
/ip/address/add address=10.21.0.1/29 interface=wireguard-tolya
/ip/address/add address=10.22.0.1/29 interface=wireguard-leha

I’ll omit setting up peers to save letters, and let’s return to the Firewall

Firewall rules for VPN

For Wireguard to work, you need to open ports

/ip/firewall/filter/add chain=input action=accept protocol=udp dst-port=12111,12112,12113,12114 

Let's add an interface wireguard-admin to the group ADMINthereby giving access to the entire network.

Samba server and Proxy will be available to the group Family

In order not to be tied to the IP addresses of the machines, you can create a group of devices, in Mikrotik terminology – Address List

/ip/firewall/address-list/add list=Media address=<media-server-ip>/32
/ip/firewall/address-list/add list=Proxy address=<proxy-server-ip>/32

And write down the rules

/ip/firewall/filter/add chain=forward action=accept dst-address-list=Media protocol=tcp dst-port=139,445 in-interface=wireguard-family
/ip/firewall/filter/add chain=forward action=accept dst-address-list=Proxy protocol=tcp dst-port=80,443 in-interface=wireguard-family

Rented machines will be available through the appropriate Wireguard interfaces

/ip/firewall/filter/add chain=forward action=accept dst-address-list=TolyaMachines in-interface=wireguard-tolya
/ip/firewall/filter/add chain=forward action=accept dst-address-list=LehaMachines in-interface=wireguard-leha

Other Wireguard clients need to be isolated from each other

According to the classics, we create a group of interfaces WIREGUARD

/interface/list/add name=WIREGUARD

We add our Wireguard interfaces there

/interface/list/member/add interface=wireguard-admin list=WIREGUARD
/interface/list/member/add interface=wireguard-family list=WIREGUARD
/interface/list/member/add interface=wireguard-tolya list=WIREGUARD
/interface/list/member/add interface=wireguard-leha list=WIREGUARD

Create a deny rule

/ip/firewall/filter/add chain=forward action=drop in-interface-list=WIREGUARD

Websites

Some of the sites I have are accessible from the network; for this purpose, ports 80 and 443 are forwarded to Proxy.

The router runs a DNS server that resolves the names of internal services and machines.
In NGINX, for domains that should be accessible only within the network, you need to set restrictions on Source Address

To restrict IP addresses, you can use directives deny And allow
Here is part of the site configuration file

server {
	allow 192.168.0.0/16; # доступ внутри сети
	allow 10.0.0.0/8; # доступ по VPN
	deny all;
	....

If these steps are not taken, you can access the site from the Internet by domain substitution via local DNS or, for example, via CURL

curl http://SOME.INTERNAL.SERVICE --resolve 'SOME.INTERNAL.SERVICE:80:<public-ip>'

Conclusion

Using VLAN, we were able to create rules for the movement of traffic within our network and logically separate subnets, which will limit the affected area in case of hacking.

We closed all ports to the maximum and use VPN to access the internal network, similar to VLANs, it is better to use several VPN profiles and configure rules for each separately.

If, for some reason, you can’t close the port, as I did with Proxy, you need to configure the security settings of the service that services this port, in my case it is NGINX.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *