Iptables "destination" question

Hi gurus,

In terms of Iptables: does destination always mean the final destination of a packet, or can it mean a (next hop style) temporary destination that can continue to another final destination ?

I’m ensuring a certain process only uses the VPN tunnel this way:

OUTPUT chain:
Default policy: Allow (normal traffic can use the internet)
Rule 1) Any “destination” on local LAN: ALLOW
Rule 2) Any packet sent by a process owned by debian-transmission that is NOT on tun0: REJECT

The reason for Rule 1) is that I need to communicate with the process on the local lan (remote client and web gui). Wondering if the process can still send packets outside the LAN since the Gateway to the internet is on the local lan for exmple…

It seems to work… but not sure it’s bulletproof.

Thanks,
Fnorrbart

Yes, it is the “final” destination. The IP header (v4 and v6) only includes one source and one destination address. It is the responsibility of the router to determine the next hop for packets it receives.

If you’re using iptables in a stateful mode, you only need a rule on the INPUT chain for this.

Hmm interesting. I had that initially, but I got locked out. I thought it was due to the fact that it was hitting the owner module rule check first and rejecting any response to me starting an SSH session from the LAN.

I might try that again.

Is there another iptables mode I’m unaware of?

Maybe you got locked out because the rule that blocks is before the rule which allows.
Iptables checks the rules from top to bottom and as soon as something fits a specific rule then all rules that come after it are ignored.

What is the purpose of dropping traffic? Would you not be better off by actively routing traffic from the “debian-transmissian” processes over your tun device?

The mangle table has an output chain that you could mark all packets originating from a socket owned by the debian-transmission user:

iptables -t mangle -A OUTPUT -m owner --uid-owner debian-transmission -j MARK --set-mark 1

and then route all marked packets to a custom table that defaults to the tun device:

ip rule add fwmark 1 table [TUN_TABLE_NAME] priority [Some priority lower than the default]

Stateful packet inspection in iptables is implemented in the conntrack (previously state) extension. If your rules don’t make use of that extension, then iptables will only implement ACLs. Here’s an overly restrictive example to illustrate the difference, which allows incoming connections to an SSH server.

Stateful:

Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh ctstate NEW

Chain FORWARD (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Stateless:

Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:ssh

Since often in a distro’s default firewall rules the OUTPUT policy is to ACCEPT anything, there might not be a magic ctstate RELATED,ESTABLISHED rule at the top. And since it is possible to mix these styles, and as you pointed out, the order of rules matters, it can be pretty easy to break the outgoing half of your connections once you start adding DROP or REJECT rules to OUTPUT.

It depends, wether or not you have more nodes blocking.
Or the mediary destination knows how to proxy your traffic.
my home network looks as such.
computerX->gateway->router(modem).
the DHCP service(which is on the gateway) tells the clients to use the gateway as *cough gateway, and handout google as DNS and the gateway the just allows traffic to the interwebz, or rather the modem.

subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option broadcast-address 192.168.1.255;
option domain-name-servers 8.8.8.8, 8.8.4.4;
#option domain-name-servers 208.67.222.222, 208.67.220.220;
default-lease-time 600;
max-lease-time 7200;
}

iptables then allows for traffic through to my router using masquerade which hides the fact that the traffic is not comming from my gateway(or something).

#!/bin/bash
#Needs to be set for some reason when cron runs on restart
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE
iptables -A FORWARD -i wlan1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o wlan1 -j ACCEPT

The modem itself doesn’t care, since all it does is relay requests(packets) to the interwebz, and the gateway essentially just serves the packages back and
forth between the gateway and the modem.
obviously you wanna block incomming packages.
using this setup i can even in my browser enter my modem’s webpage setup e.g. 192.168.x.x, which is not in the same network, as my clients, and they
appears as if so.

Try using iptables-save/iptables-restore … it can reload multiple rules/lines atomically, so that you don’t have to worry about ordering or errors much.

Also, various distros tend to have a systemd unit that does this on boot, or from interface up/down scripts.