2016-12-16 6 views
8

私は現在、nfqueueからパッケージを読んでそれらを修正して遊んでいます。残念ながら、パッケージの宛先ポートを変更するのにちょっと頑張っています。以下のコードスニペットを参照してください。目的は、宛先ポートをに書き換えることです。 変更されたパッケージがキューから出ていますが、ポート8888に接続してポート8000​​でリッスンしているHTTPサーバーに接続する場合は、接続がタイムアウトします。私はパッケージに何らかの形をしていないと思っています。あなたが溶液中で興味を持っている場合にはgopacketを使って宛先ポートを変更する

package main 

import (
    "os" 
    "os/signal" 
    "syscall" 

    "github.com/chifflier/nfqueue-go/nfqueue" 
    "github.com/coreos/go-iptables/iptables" 

    "github.com/google/gopacket" 
    "github.com/google/gopacket/layers" 
) 

func sendNewPacket(payload *nfqueue.Payload, layers ...gopacket.SerializableLayer) { 
    buffer := gopacket.NewSerializeBuffer() 
    gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, layers...) 
    outgoingPacket := buffer.Bytes() 
    payload.SetVerdictModified(nfqueue.NF_ACCEPT, outgoingPacket) 
} 

func realCallback(payload *nfqueue.Payload) int { 
    packet := gopacket.NewPacket(payload.Data, layers.LayerTypeIPv4, gopacket.Default) 
    ethLayer := packet.Layer(layers.LayerTypeEthernet) 
    eth, _ := ethLayer.(*layers.Ethernet) 
    if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil { 
     ip, _ := ipLayer.(*layers.IPv4) 
     if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { 
      tcp, _ := tcpLayer.(*layers.TCP) 
      if tcp.DstPort == 8888 { 
       tcp.DstPort = 8000 
       sendNewPacket(payload, eth, ip, tcp) 
       return 0 
      } 
      if tcp.SrcPort == 8000 { 
       tcp.SrcPort = 8888 
       sendNewPacket(payload, eth, ip, tcp) 
       return 0 
      } 
     } 
    } 
    payload.SetVerdict(nfqueue.NF_ACCEPT) 
    return 0 
} 

func main() { 
    ipt, err := iptables.New() 
    if err != nil { 
     panic(err) 
    } 
    ipt.Append("filter", "INPUT", "-p", "tcp", "-j", "NFQUEUE", "--queue-num", "0") 
    ipt.Append("filter", "OUTPUT", "-p", "tcp", "-j", "NFQUEUE", "--queue-num", "0") 
    q := new(nfqueue.Queue) 
    q.SetCallback(realCallback) 

    q.Init() 
    defer q.Close() 

    q.Unbind(syscall.AF_INET) 
    q.Bind(syscall.AF_INET) 
    q.CreateQueue(0) 

    c := make(chan os.Signal, 1) 
    signal.Notify(c, os.Interrupt) 
    go func() { 
     for sig := range c { 
      _ = sig 
      q.Close() 
      err = ipt.ClearChain("filter", "INPUT") 
      err = ipt.ClearChain("filter", "OUTPUT") 
      if err != nil { 
       panic(err) 
      } 
      os.Exit(0) 
     } 
    }() 
    q.TryRun() 
} 
+0

あなたが変更されたパケットは再び外出表示された場合、あなたの問題/質問は何ですか? – nos

+0

申し訳ありませんが、私は質問でこれを明確にします。私はポート8000​​でHTTPサーバーを実行しています。ブラウザからポート8888に接続すると、接続がタイムアウトします。 – Glaslos

+0

他の方向に向かうパケットも書き換えなければなりません。 (実際にこれを行うためのコードは必要ありませんが、iptablesで表示することもできます(例:[here](https://www.cyberciti.biz/faq/linux-port-redirection-with-iptables/) ) – nos

答えて

関連する問題