Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
router:nat [2025/02/06 09:27] – willy | router:nat [Unknown date] (current) – removed - external edit (Unknown date) 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Routing on the Home Server ====== | ||
- | |||
- | Your internal network is almost ready to go. You have a DNS and DHCP server setup, what you need now is to ensure that all packets going out of your home network are properly routed and modified to reach the internet. Also, even more important, that any response packet coming from the internet is properly redirected to the originator. | ||
- | |||
- | Brief excursus: an IP packet contains within it's source and destination address. For example if want to browse // | ||
- | < | ||
- | source: 10.0.0.100 # my IP | ||
- | destination: | ||
- | </ | ||
- | |||
- | Now, my packet goes to the home server (which is my gateway) and needs to be sent to www.kde.org. But remember that 10.0.0.0 is a **private** subnet? Well, www.kde.org will **not** know how to send that packet back to your home network! This means that the home server will need to perform an action called **Network Address Translation (NAT)** and put it's IP address as source. The packet will then become (assuming ISP1 is the default gateway): | ||
- | < | ||
- | source: 192.168.0.10 # my IP on the ISP1 network interface of the server | ||
- | destination: | ||
- | </ | ||
- | and will need to keep track of your outgoing packet so that it can match the reply and replace the reply **destination** address (which will be 192.168.0.10) with the real destination address (10.0.0.100). | ||
- | |||
- | |||
- | ===== Network Access Translation ===== | ||
- | |||
- | There are many different kind of NATs, but only two are relevant here: | ||
- | * Source NAT (SNAT) | ||
- | * Masquerading | ||
- | |||
- | SNAT is faster and more efficient, but it require a **static ip** on your outgoing network interface of the home server. | ||
- | |||
- | Masquerading does not depend on a fixed IP, but is slightly slower and require slightly more resources, because it queries the interface for it's current IP for each packet routed. | ||
- | |||
- | Since in your setup the upstream network interfaces have **static** IP address, i will show you SNAT. | ||
- | |||
- | Enabling SNAT with **nft** is pretty easy and can be achieved with the following commands on the server: | ||
- | <code bash> | ||
- | nft add table nat | ||
- | nft add chain nat postrouting { type nat hook postrouting priority 100\;} | ||
- | nft add rule nat postrouting oifname " | ||
- | </ | ||
- | |||
- | These rules: | ||
- | * Create a new table called nat | ||
- | * Create a new chain called postrouting | ||
- | * Append to it a rule that will apply SNAT to all packets coming from the LAN interface (iifname) and routes them on the WAN interface (oifname) replacing it's IP address as 192.168.0.10 | ||
- | |||
- | I am showing you how to use **nftables** tool, which replaced // | ||
- | |||
- | |||
- | ===== Default route ===== | ||
- | |||
- | In order to test your home network access, you need to have a default route on your home server, | ||
- | In [[router: | ||
- | |||
- | So if you followed my suggestion and you want to test home internet access now, setup a default route at runtime with the following command: | ||
- | <code bash> | ||
- | ip route add default via 192.168.0.1 | ||
- | </ | ||
- | |||
- | to remove, later on, that rule: | ||
- | <code bash> | ||
- | ip route del default via 192.168.0.1 | ||
- | </ | ||
- | |||
- | |||
- | ===== Custom destination routing ===== | ||
- | |||
- | Let's assume you have more tha one upstream ISP to which your home network is connected to, and you want to ensure that specific destinations are routed always trough a specific ISP. | ||
- | |||
- | Let's assume that the remote IP 130.130.130.130 (i am writing random numbers here) sohuld go out trough your ISP n.2 instread of the ISP n.1, where the normal NAT occurs. | ||
- | |||
- | You can achieve that with the following nft rule: | ||
- | <code bash> | ||
- | nft add rule nat postrouting oifname " | ||
- | </ | ||
- | |||
- | this rule will take any packet with destination 130.130.130.130.and apply source-nat to the ISP n.2 interface instrad of the default ISP n.1. | ||
- | |||
- | This is the base to ensure that traffic goes trough specific interfaces, which could be useful fo redoundancy or load balancing (static). | ||
- | |||
- | One practical example would be to ensure that some heavy-traffic (like backup or big downloads) get routed trough an ISP that doesn' | ||
- | |||
- | |||
- | ===== IP Forwarding ===== | ||
- | |||
- | One last step is to enable IP forwarding, since you will need this both for containerized services and the home network. Create a new file called **/ | ||
- | <file - ip_forward.conf> | ||
- | net.ipv4.ip_forward=1 | ||
- | net.ipv4.conf.default.rp_filter=1 | ||
- | </ | ||
- | |||
- | Now either reboot or manually enable: | ||
- | <code bash> | ||
- | sysctl net.ipv4.ip_forward=1 | ||
- | sysctl net.ipv4.conf.default.rp_filter=1 | ||
- | </ | ||
- | |||
- | Now go to a device in your home network and test if it can access internet. | ||
- | |||
- | |||
- | ===== Forced DNS forwarding ===== | ||
- | |||
- | You have set-up ad-blocking DNS when i told you, cool. Now you discovered that many branded-devices just ignore the DNS provided by DHCP and forcefully use their own DNS servers, making your ad-blocking useless. Not cool. | ||
- | |||
- | Luckly, it's easy to fix. You need to add a specific rule to **nft** to force all traffic on ports 53(old DNS) and 853(new DoT) to be routed to your ad-blocking DNS: | ||
- | <code bash> | ||
- | nft add chain nat prerouting { type nat hook prerouting priority 100\;} | ||
- | nft add rule nat prerouting iifname " | ||
- | nft add rule nat prerouting iifname " | ||
- | nft add rule nat prerouting iifname " | ||
- | nft add rule nat prerouting iifname " | ||
- | </ | ||
- | |||
- | The first line is needed to create the // | ||
- | |||
- | |||
- | ===== TLDR: save and autostart ===== | ||
- | |||
- | You can check your rulesets with: | ||
- | <code bash> | ||
- | nft list ruleset | ||
- | </ | ||
- | |||
- | The easiest way to save your rules is to manually stop the service: | ||
- | <code bash> | ||
- | / | ||
- | </ | ||
- | |||
- | Your rules are not saved and can be reviewed into **/ | ||
- | <file - rules-save> | ||
- | table ip nat { | ||
- | chain postrouting { | ||
- | type nat hook postrouting priority 100; policy accept; | ||
- | oifname " | ||
- | oifname " | ||
- | } | ||
- | |||
- | chain prerouting { | ||
- | type nat hook prerouting priority 100; policy accept; | ||
- | iifname " | ||
- | iifname " | ||
- | iifname " | ||
- | iifname " | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Now, just start the service and add it to the default runlevel: | ||
- | <code bash> | ||
- | / | ||
- | rc-update add nftables default | ||
- | </ | ||
- | |||
- | |||