I have a server that have a service listening on localhost. For some reason, I cannot/don't want to make it listen on 0.0.0.0.
I set up a DNAT nftable rule to redirect traffic from the outside to this service listening on localhost using solution found here: https://serverfault.com/questions/1021798/how-to-redirect-requests-on-port-80-to-localhost3000-using-nftables
However, I'd like to be able to access this service from inside the server, but I cannot. It boils down to the fact that the packet when it originates from the network goes through the nat/prerouting hook, but when it originates from the server itself, it goes directly to filter/input.
Here is the trace nft script I'm using:
table inet trace
delete table inet trace
table inet trace {
chain input {
type filter hook input priority filter;
tcp dport 80 meta nftrace set 1;
}
chain prerouting {
type nat hook prerouting priority -100;
tcp dport 80 meta nftrace set 1;
}
}
When running nft monitor trace, here is what I get when I run curl 192.168.5.19 (the server LAN address) from inside the server itself:
trace id 4a31a955 inet trace input packet: iif "lo" @ll,0,112 0x800 ip saddr 192.168.5.19 ip daddr 192.168.5.19 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 27513 ip protocol tcp ip length 60 tcp sport 56176 tcp dport 80 tcp flags == syn tcp window 65495
trace id 4a31a955 inet trace input rule tcp dport 80 meta nftrace set 1 (verdict continue)
trace id 4a31a955 inet trace input verdict continue meta mark 0xffffffff
trace id 4a31a955 inet trace input policy accept meta mark 0xffffffff
We only see the trace for the input hook. Now when I curl the same address from somewhere else inside the LAN I get:
trace id 7502298e inet trace prerouting packet: iif "eth0" ether saddr f0:d5:bf:11:c2:59 ether daddr d8:3a:dd:77:26:e1 ip saddr 192.168.5.186 ip daddr 192.168.5.19 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 53081 ip protocol tcp ip length 60 tcp sport 41730 tcp dport 80 tcp flags == syn tcp window 32120
trace id 7502298e inet trace prerouting rule tcp dport 80 meta nftrace set 1 (verdict continue)
trace id 7502298e inet trace prerouting verdict continue
trace id 7502298e inet trace prerouting policy accept
trace id 7502298e inet socket_redirect prerouting packet: iif "eth0" ether saddr f0:d5:bf:11:c2:59 ether daddr d8:3a:dd:77:26:e1 ip saddr 192.168.5.186 ip daddr 192.168.5.19 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 53081 ip protocol tcp ip length 60 tcp sport 41730 tcp dport 80 tcp flags == syn tcp window 32120
trace id 7502298e inet socket_redirect prerouting rule ip daddr != 127.0.0.0/8 tcp dport 80 counter packets 10 bytes 580 dnat ip to 127.0.0.5:80 (verdict accept)
trace id 7502298e inet socket_redirect input packet: iif "eth0" ether saddr f0:d5:bf:11:c2:59 ether daddr d8:3a:dd:77:26:e1 ip saddr 192.168.5.186 ip daddr 127.0.0.5 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 53081 ip protocol tcp ip length 60 tcp sport 41730 tcp dport 80 tcp flags == syn tcp window 32120
trace id 7502298e inet socket_redirect input rule ct status dnat (verdict continue)
trace id 7502298e inet socket_redirect input rule counter packets 23008 bytes 10085025 (verdict continue)
trace id 7502298e inet socket_redirect input rule meta mark set 0xffffffff (verdict continue)
trace id 7502298e inet socket_redirect input rule accept (verdict accept)
trace id 7502298e inet trace input packet: iif "eth0" ether saddr f0:d5:bf:11:c2:59 ether daddr d8:3a:dd:77:26:e1 ip saddr 192.168.5.186 ip daddr 127.0.0.5 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 53081 ip protocol tcp ip length 60 tcp sport 41730 tcp dport 80 tcp flags == syn tcp window 32120
trace id 7502298e inet trace input rule tcp dport 80 meta nftrace set 1 (verdict continue)
trace id 7502298e inet trace input verdict continue meta mark 0xffffffff
trace id 7502298e inet trace input policy accept meta mark 0xffffffff
trace id fbebd8f0 inet trace input packet: iif "eth0" ether saddr f0:d5:bf:11:c2:59 ether daddr d8:3a:dd:77:26:e1 ip saddr 192.168.5.186 ip daddr 127.0.0.5 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 53082 ip protocol tcp ip length 52 tcp sport 41730 tcp dport 80 tcp flags == ack tcp window 251
...
How to make it so that the packets originating from the server itself go to the prerouting hook?
Possibly this is not possible.
I just looked at how docker does it and I cannot get any trace from the docker port forwarding when the packet originates from the server. However docker has a docker-proxy daemon that seems to do some forwarding. perhaps that's for this specific case.
Perhaps podman has found a solution.