Why
I wanted to do subnetting in my house's LAN in order to have 2 separate networks, one for my NAS, and another one for the rest of devices. I managed to split my network into 2 smaller ones by subnetting it with the mask 255.255.255.128, however, that wasn't enough, because what it did was isolate both networks completely, which was not what I wanted, as I needed the devices to be able to reach my NAS in its separate network (and I also didn't want my NAS to be able to reach the other network) so essentially, I was looking for a one-way form of communication between these subnets, and it was not enough to just subnetting my network, that was only half of the work. The problem is that, wherever I looked for information on this topic, people always ended the conversation with something along the lines of: "just use vlans", which does seem easier indeed, however, the idea of having to buy hardware for it (a vlan switch) just to have a NAS in a separate network sounded silly to me, especially considering that my router should be able to handle traffic across subnets out of the box (it's just that it's not straightforward to do so for whatever reason). And, in the end, it was possible. If you're interested to know how, keep reading.
Goals
Requirements
How to
Step one
We need to change the default mask in our router from 255.255.255.0 to 255.255.255.128 to support 2 networks. You can do so via the ASUS dashboard. Go to asusrouter.com, log in, and then go to "Advanced settings" -> "LAN" where you will find the "Subnet Mask" field. You can change it there to 255.255.255.128 and apply the changes. After applying the changes, you should see that the range of "assignable IPs" within your network should also have changed, since now your router considers that your network is only half of what it used to be (since my router can only handle one network at a time, it takes the first subnet as its own, and doesn't know/care about the other subnet). You should be able to double-check this if you select the "DHCP Server" tab at the top (within the same "LAN" screen) where you will see 2 fields, "IP Pool Starting Address" and "IP Pool Ending Address". The starting address, after the change, in my case is 192.168.1.2, and the ending address is: 192.168.1.126, which represents the first subnet, which I'll call network A. Making network A: 192.168.1.0/25 and network B: 192.168.1.128/25.
Step two
We're going to connect a device to our network B to test a few things, first we'll check if network B has internet access, and second, we'll check the connectivity/visibility across networks A and B. Since our router will only take network A into account when it comes to assigning IP addresses, we'll need to manually assign IP addresses for devices we'd like to be in network B. For this example, I'll take my phone and assign the IP: 192.168.1.150, with mask 255.255.255.128, and gateway: 192.168.1.129. If you're not sure why I selected that IP for the gateway, please take a look at the videos I mentioned in the "requirements" part first.
After connecting a device to our network B, in my case said device couldn't access the internet or ping devices in network A (and network A devices couldn't ping network B ones either). This is because the default gateway of network B (192.168.1.129) is not assigned to our router, only the gateway for network A is (192.168.1.1). In order to fix this, we're going to ssh into our router and assign the network B gateway IP address to the same interface that has the network A gateway IP address, as shown below:
After connecting to our router via ssh, we're going to check what's the name of the interface that currently has the network A gateway IP address by running the following command:
Which in my case showed me one line that reads the following:
We're going to be looking at 2 things, the first one is the network A gateway IP address, which is 192.168.1.1, and second, what interface has it, which is my case is br0. We're going to take that interface name and use it in the following command:
Which will set the network B gateway IP to the same interface used as gateway for network A. With this change, we should now have internet in network B and also both networks should be able to communicate with each other, we can test this by pinging devices from network A to B and vice versa. However, even though those pings work, there's something strange happening (at least in my case), which is that when pinging from network A to B, the console would often show messages reading: Redirect Host followed by some other values that aren't common as output of the ping command.
The "Redirect Host" issue is happening because of a NAT rule that looks like this (which can be seen by running the command "iptables -t nat -L POSTROUTING -v --line-numbers"):
For our pings to work properly across both networks, the above rule should cover them both (and not only network A, as it is right now). In order to make the change, we're going to need to run the following commands:
We just essentially replaced the previous rule that only covered addresses from a single subnet, by one that covers address from both subnets. After this change, our pings work well in either direction, therefore we've successfully connected our 2 subnets. Now we can add filtering rules around them!
Step three (last step)
We now have 2 separate networks, both fully connected with each other. Now we can start adding the "firewall" rules, in order to only allow a one-way communication between them, so that:
Let's first take a look at the existing forward rules in our router by running:
Which in my case shows the following:
Rule #2 allows all packets in an established connection, whereas rule #7 allows both networks to start a connection anywhere. In order to prevent network B from starting connections to network A, we need to run the following command:
Take a closer look at the start of the command: iptables -I FORWARD 3 this inserts the new rule in a specific position (3rd place). This is very important because iptables rules' positions matter, as they are evaluated from top to bottom and the first one that "matches" a packet will be used.
The reason why I choose the position 3 is because is right below the rule that allows everything in an established connection. i.e rule 2: (ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED). The reason why it's important that our rule is below that one, is because our rule drops any connection that comes from network B into network A, even responses of connections that were started by network A, which is not that we want. We just want to drop attempts of starting connections from network B to A, however, if there's a connection started from network A, then we want to allow network B to respond to that connection, which is something allowed in the rule #2.
And that's it!
Cheers.
I wanted to do subnetting in my house's LAN in order to have 2 separate networks, one for my NAS, and another one for the rest of devices. I managed to split my network into 2 smaller ones by subnetting it with the mask 255.255.255.128, however, that wasn't enough, because what it did was isolate both networks completely, which was not what I wanted, as I needed the devices to be able to reach my NAS in its separate network (and I also didn't want my NAS to be able to reach the other network) so essentially, I was looking for a one-way form of communication between these subnets, and it was not enough to just subnetting my network, that was only half of the work. The problem is that, wherever I looked for information on this topic, people always ended the conversation with something along the lines of: "just use vlans", which does seem easier indeed, however, the idea of having to buy hardware for it (a vlan switch) just to have a NAS in a separate network sounded silly to me, especially considering that my router should be able to handle traffic across subnets out of the box (it's just that it's not straightforward to do so for whatever reason). And, in the end, it was possible. If you're interested to know how, keep reading.
Goals
- Having 2 separate networks (I'll call them "A" and "B").
- Network B will only have a NAS connected to it.
- Network A will have the rest of the devices in the house.
- Network A can reach network B (so that any device in the house can reach the NAS).
- Network B cannot reach network A.
Requirements
- A router that you can ssh into (I'm using an Asus RT-AC86U).
- Basic knowledge about subnetting in general. I'd recommend taking a look at this playlist (it helped me a lot), especially this video in particular.
- Patience.
How to
Step one
We need to change the default mask in our router from 255.255.255.0 to 255.255.255.128 to support 2 networks. You can do so via the ASUS dashboard. Go to asusrouter.com, log in, and then go to "Advanced settings" -> "LAN" where you will find the "Subnet Mask" field. You can change it there to 255.255.255.128 and apply the changes. After applying the changes, you should see that the range of "assignable IPs" within your network should also have changed, since now your router considers that your network is only half of what it used to be (since my router can only handle one network at a time, it takes the first subnet as its own, and doesn't know/care about the other subnet). You should be able to double-check this if you select the "DHCP Server" tab at the top (within the same "LAN" screen) where you will see 2 fields, "IP Pool Starting Address" and "IP Pool Ending Address". The starting address, after the change, in my case is 192.168.1.2, and the ending address is: 192.168.1.126, which represents the first subnet, which I'll call network A. Making network A: 192.168.1.0/25 and network B: 192.168.1.128/25.
Step two
We're going to connect a device to our network B to test a few things, first we'll check if network B has internet access, and second, we'll check the connectivity/visibility across networks A and B. Since our router will only take network A into account when it comes to assigning IP addresses, we'll need to manually assign IP addresses for devices we'd like to be in network B. For this example, I'll take my phone and assign the IP: 192.168.1.150, with mask 255.255.255.128, and gateway: 192.168.1.129. If you're not sure why I selected that IP for the gateway, please take a look at the videos I mentioned in the "requirements" part first.
After connecting a device to our network B, in my case said device couldn't access the internet or ping devices in network A (and network A devices couldn't ping network B ones either). This is because the default gateway of network B (192.168.1.129) is not assigned to our router, only the gateway for network A is (192.168.1.1). In order to fix this, we're going to ssh into our router and assign the network B gateway IP address to the same interface that has the network A gateway IP address, as shown below:
After connecting to our router via ssh, we're going to check what's the name of the interface that currently has the network A gateway IP address by running the following command:
Bash:
ip r
Which in my case showed me one line that reads the following:
192.168.1.0/25 dev br0 proto kernel scope link src 192.168.1.1
We're going to be looking at 2 things, the first one is the network A gateway IP address, which is 192.168.1.1, and second, what interface has it, which is my case is br0. We're going to take that interface name and use it in the following command:
Bash:
ip addr add 192.168.1.129/25 dev br0
Which will set the network B gateway IP to the same interface used as gateway for network A. With this change, we should now have internet in network B and also both networks should be able to communicate with each other, we can test this by pinging devices from network A to B and vice versa. However, even though those pings work, there's something strange happening (at least in my case), which is that when pinging from network A to B, the console would often show messages reading: Redirect Host followed by some other values that aren't common as output of the ping command.
The "Redirect Host" issue is happening because of a NAT rule that looks like this (which can be seen by running the command "iptables -t nat -L POSTROUTING -v --line-numbers"):
2 176 MASQUERADE all -- any br0 192.168.1.0/25 192.168.1.0/25
For our pings to work properly across both networks, the above rule should cover them both (and not only network A, as it is right now). In order to make the change, we're going to need to run the following commands:
Bash:
# This removes the existing rule that only covers network A.
# Make sure that the number at the end is the same as the number shown when running the command that shows the existing rules (as explained above).
# In my case it's the number "2".
iptables -t nat -D POSTROUTING 2
# This adds a new rule that covers all networks. Note that the interface is also mentioned here after "-o". In my case it's br0.
iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE -s 192.168.1.0/24 -d 192.168.1.0/24
We just essentially replaced the previous rule that only covered addresses from a single subnet, by one that covers address from both subnets. After this change, our pings work well in either direction, therefore we've successfully connected our 2 subnets. Now we can add filtering rules around them!
Step three (last step)
We now have 2 separate networks, both fully connected with each other. Now we can start adding the "firewall" rules, in order to only allow a one-way communication between them, so that:
- Network A can access network B.
- Network B cannot access network A (more specifically, network B cannot start a connection with network A, however, it can respond to connections started from network A).
Let's first take a look at the existing forward rules in our router by running:
Bash:
iptables -L FORWARD -v --line-numbers
Which in my case shows the following:
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 ...
2 9021 1501K ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
...
7 2256 1104K ACCEPT all -- br0 any anywhere anywhere
Rule #2 allows all packets in an established connection, whereas rule #7 allows both networks to start a connection anywhere. In order to prevent network B from starting connections to network A, we need to run the following command:
Bash:
# Inserting forward rule in the position "3" that will drop connections
# with source from network B (192.168.1.128/25) and network A as destination (192.168.1.0/25)
iptables -I FORWARD 3 -s 192.168.1.128/25 -d 192.168.1.0/25 -j DROP
Take a closer look at the start of the command: iptables -I FORWARD 3 this inserts the new rule in a specific position (3rd place). This is very important because iptables rules' positions matter, as they are evaluated from top to bottom and the first one that "matches" a packet will be used.
The reason why I choose the position 3 is because is right below the rule that allows everything in an established connection. i.e rule 2: (ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED). The reason why it's important that our rule is below that one, is because our rule drops any connection that comes from network B into network A, even responses of connections that were started by network A, which is not that we want. We just want to drop attempts of starting connections from network B to A, however, if there's a connection started from network A, then we want to allow network B to respond to that connection, which is something allowed in the rule #2.
And that's it!
Cheers.
Last edited: