drvvvuyia15070493 2019-01-21 12:30
浏览 196

无法将流量从“ tun”接口转发到“ lo”

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.

Current Setup

  • TUN interface is up and running at 10.0.2.0/24

iptables configuration

  • iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
  • iptables -t nat -A POSTROUTING -j MASQUERADE

VPN logic

  • When I receive an IP packet destined to an address, say 1.2.3.4, I update it's destination to 127.0.0.1 and destination port to 12345.
  • I recalculate the checksum for both TCP and IP layer

Code

  • I parse IP layer and TCP layer using gopackets
  • Update the destination port and ip address
  • Create a NAT entry in the application layer, so that I can change back the source_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

Expected Output

  • Traffic from 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 localhost

Actual Output

  • Packets are lost in-between
  • tshark -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
  • But neither lo or eth0 shows the corresponding entry for --dport 12345.
  • 写回答

1条回答 默认 最新

  • douzhantanju1849 2019-01-23 07:54
    关注

    Found the issue:

    • Network config was alright.
    • 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)                
    
    评论

报告相同问题?

悬赏问题

  • ¥15 opencv图像处理,需要四个处理结果图
  • ¥15 无线移动边缘计算系统中的系统模型
  • ¥15 深度学习中的画图问题
  • ¥15 java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条
  • ¥15 Python报错怎么解决
  • ¥15 simulink如何调用DLL文件
  • ¥15 关于用pyqt6的项目开发该怎么把前段后端和业务层分离
  • ¥30 线性代数的问题,我真的忘了线代的知识了
  • ¥15 有谁能够把华为matebook e 高通骁龙850刷成安卓系统,或者安装安卓系统
  • ¥188 需要修改一个工具,懂得汇编的人来。