如何在Tun / Tap接口上读取TCP数据包?

I'm working on a simple project that listens on a tun interface and modified the packets then re-sends them to the real interface.

I have tried songgao/water, pkg/tuntap and even writing my own based on some C code floating around but no matter what I tried, I can't receive TCP packets (ICMP/UDP works fine).

I feel like i'm missing something extremely obvious but I can't figure it for the life of me...

The code:

package main

import (
    "log"
    "os"
    "os/exec"

    "golang.org/x/net/ipv4"

    "github.com/songgao/water"
)

const (
    // I use TUN interface, so only plain IP packet, no ethernet header + mtu is set to 1300
    BUFFERSIZE = 1600
    MTU        = "1300"
)

func main() {
    iface, err := water.New(water.Config{})
    fatalIf(err)

    log.Printf("tun interface: %s", iface.Name())
    runBin("/bin/ip", "link", "set", "dev", iface.Name(), "mtu", MTU)
    runBin("/bin/ip", "addr", "add", "10.2.0.10/24", "dev", iface.Name())
    runBin("/bin/ip", "link", "set", "dev", iface.Name(), "up")

    buf := make([]byte, BUFFERSIZE)

    for {
        n, err := iface.Read(buf)
        if err != nil {
            log.Fatal(err)
        }

        header, _ := ipv4.ParseHeader(buf[:n])

        log.Printf("isTCP: %v, header: %s", header.Protocol == 6, header)
    }
}

func fatalIf(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func runBin(bin string, args ...string) {
    cmd := exec.Command(bin, args...)
    cmd.Stderr = os.Stderr
    cmd.Stdout = os.Stdout
    cmd.Stdin = os.Stdin
    fatalIf(cmd.Run())
}