Originally asked here: https://networkengineering.stackexchange.com/questions/56278/not-able-to-forward-traffic-from-tun-interface-to-lo
I am writing a small VPN server, in which for a certain ip address, I am passing the traffic through an http proxy
.
iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -j MASQUERADE
1.2.3.4
, I update it's destination to 127.0.0.1
and destination port to 12345
.TCP
and IP
layersource_ip
and source_port
in the response packets// Code to receive packet from tun interface
pkt := gopacket.NewPacket(packet, layers.LayerTypeIPv4, gopacket.DecodeOptions{
NoCopy: true,
Lazy: false,
})
if ntPkt := pkt.NetworkLayer().(*layers.IPv4); ntPkt != nil {
var err error
if tPkt := pkt.TransportLayer().(*layers.TCP); tPkt != nil {
// Adding NAT entry
h.nLock.RLock()
hash := fmt.Sprintf("%s:%d", waterutil.IPv4Source(packet).String(), waterutil.IPv4SourcePort(packet))
if _, ok := h.natTable[hash]; !ok {
h.nLock.RUnlock()
h.nLock.Lock()
h.natTable[hash] = net.TCPAddr{IP: waterutil.IPv4Destination(packet), Port: int(waterutil.IPv4DestinationPort(packet))}
h.nLock.Unlock()
} else {
h.nLock.RUnlock()
}
buf := gopacket.NewSerializeBuffer()
ntPkt.DstIP = h.proxyIP
tPkt.DstPort = layers.TCPPort(h.proxyPort)
tPkt.SetNetworkLayerForChecksum(ntPkt)
err = gopacket.SerializeLayers(buf, h.opts,
ntPkt,
tPkt)
if err != nil {
logger.E("Error while serializing, skipping the changes", err)
return nil
}
copy(packet, buf.Bytes())
}
}
// Code to write packet onto tun interface
tun0
will be forwarded onto eth0
(even if I don't add that iptable entry, default route will do the same thing)eth0
will be knowing the lo addresses, so will forward the packet to loopback address, and eventually to the proxy running on the localhosttshark -i tun0
shows the packets going out from tun0
2419 279.256438200 10.0.2.3 ? 127.0.0.1 TCP 60 [TCP Retransmission] 47129 ? 12345 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=550203836 TSecr=0 WS=256
lo
or eth0
shows the corresponding entry for --dport 12345.Found the issue:
Serialization of packets was wrong through go code
Wrong code
err = gopacket.SerializeLayers(buf, h.opts,
ntPkt,
tPkt)
err = gopacket.SerializePacket(buf, h.opts, pkt)