I have cloud server and private network. Two of those connected (or tunneled) using wireguard. Right now, for each new device in private network, in which I want to expose it to internet using port forwarding, I need to create new Policy Routing for that device. This can be bothersome, and I don't want to lose IP data from using masquerading. I learnt it from this website.
Then I tried to find a way to simplify that process. I found the answer here, it's says I need to use connection marking to do this. Since I am using OpenWrt 23.05.2, translation from iptables to nftables is needed. Here is my translation:
nft 'insert rule inet fw4 prerouting iifname "wg0" ct state new counter ct mark set 0x1'
nft 'insert rule inet fw4 prerouting iifname != "wg0" ct mark 0x1 counter meta mark set 0x1'
ip rule add fwmark 1 lookup wg0
(Table wg0 already created at rt_tables)
It succeeded, I can access my private server from public network with port forwarding, and see the request IP without masquerading. The problem now is the connection mark configuration isn't persistent. I tried to search fw4 documentation and seems I still can't figure it out. Can someone please help me with this problem?
The quick and dirty way would be to use includes from the linked documentation.
uci add firewall include
uci set firewall.@include[-1].type='nftables'
uci set firewall.@include[-1].path='/etc/mark_wireguard.nft'
uci set firewall.@include[-1].position='chain-pre'
uci set firewall.@include[-1].chain='mangle_prerouting'
cat << "EOF" > /etc/mark_wireguard.nft
iifname "wg0" ct state new counter ct mark set 0x1
iifname != "wg0" ct mark 0x1 counter meta mark set 0x1
EOF
uci commit firewall
fw4 restart
If you control the cloud server you can simply setup WireGuard in a site-to-site configuration basically connecting the two networks so you do not need to port forward at all.
If you are connected to your cloud server you are also connected to your home
I still need the port forwarding for exposing part of my private network to the internet (or public). Is there any better way to do this, because I don't really understand why I don't need port forwarding for this?
For the public internet you indeed need one port forward on the cloud server to your home ip.
You yourself can use wireguard to connect from the internet to your cloud server and are directly connected to your home also
Thank you so much for the answer, nft rule worked with charm and persistently. I don't know how I missed it.
Now I just need to set ip rule setting, I am thinking about hotplug, or is there any other recommendation for this setting?
Anyway, one other question. Do you have any reference about nftable chaining? For example why mangle_prerouting is work as well as prerouting chaining here. How about the name of prerouting chain, is that some kind of default chaining name, or actually there is more configuration into it?
Because both chains are within the same hook with different priorities (-150 and 0).
Better use the mangle chain, which was created just for this.
There are no predefined chains in nftables and you can use whatever names you want, but it is good practice to be able to use the name as a reference to the chain type.