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()
}
あなたが変更されたパケットは再び外出表示された場合、あなたの問題/質問は何ですか? – nos
申し訳ありませんが、私は質問でこれを明確にします。私はポート8000でHTTPサーバーを実行しています。ブラウザからポート8888に接続すると、接続がタイムアウトします。 – Glaslos
他の方向に向かうパケットも書き換えなければなりません。 (実際にこれを行うためのコードは必要ありませんが、iptablesで表示することもできます(例:[here](https://www.cyberciti.biz/faq/linux-port-redirection-with-iptables/) ) – nos