A következőbe futottam bele, és egyenlőre nem tudok rá racionális magyarázatot adni:
Ubuntu 12.04, kernel a hozzá adott 3.2.0-26-generic x86_64
A gépnek van 3 felhúzott hálózati interfésze: tun0, tun1, eth0 (a két tun az eth0-n megy keresztül).
A tun0 IP címe 10.5.x.x, a tun1-é 10.8.x.x, az eth0 192.168.1.4. A két tun-t szolgáltató szerverek fel vannak véve a routing táblába, valahogy így:
route add a.b.c.d gw 192.168.1.1
route add e.f.g.h gw 192.168.1.1
A default gw a tun1-re mutat. Eddig minden működik szépen.
van egy szolgáltatás, aminek nem kellene átmennie a tun1-en, hanem egyből a 192.168.1.1-en keresztül kellene elérnie e netet. Mivel ez user1 nevében fut, gondoltam megcsinálom így:
- A mangle táblában rakok egy fwmark 0x10 -et vagy TOS 0x10-et a user1 csomagjaira
- ip route -tal létrehozok egy táblát, ahol a default gw az eth0-n keresztül a 192.168.1.1
- ip rule -al létrehozok egy szabályt, hogy fwmark 0x10 vagy TOS 0x10 csomagok ez szerint az új tábla szerint menjenek.
Kipróbáltam (mind fwmark-kal, mint TOS-sal): user1-ként kiadva tesztként, hogy telnet -b 192.168.1.4 index.hu 80 a következőt láttam a tcpdump-ban:
- A SYN csomag szépen elment a 192.168.1.4 -es IP-ről eth0-n keresztül 192.168.1.1-es gw felé
- A távoli gép küldi a SYN+ACK-ot a 192.168.1.4-nek, ahogy kell (nyilván a 192.168.1.1.es gw-en keresztül, eth0-n esik be)
- A /proc/net/ip_conntrack szerint a a kapcsolat átvált SYN_SENT -ből SYN_RCVD -be
- A network socket viszont sosem kapja meg a SYN+ACK-ot, a netstat szerint elakad a handshake 1. lépésénél. Egy idő után megpróbálja megint elküldeni a SYN-t, persze megint pont ugyan így jár.
A problémát megoldottam végül úgy, hogy kiszedtem a fwmark-os netfilter szabályt, a szolgáltatást bindoltam egy dummy IP-re, az ip rule-t kicseréltem, hogy fwmark helyett source IP alapján válasszon táblát + raktam egy SNAT-ot, hogy a dummy IP-t kicseréljem 192.168.1.4- re a kimenő csomagoknál, és így most működik szépen.
Hogy miért nem működött az eredeti elképzelés, azt továbbra sem értem. Eszközt sem tudok mondani hirtelen, amivel végig lehetne követni, hogy miért nem találkozik a megérkezett SYN+ACK csomag a sockettel.