使用gopacket更改目标端口

huangapple go评论135阅读模式
英文:

Changing destination port using gopacket

问题

我目前正在尝试使用nfqueue读取数据包并对其进行修改。不幸的是,我在更改数据包的目标端口方面遇到了一些困难。请参考下面的代码片段。我的想法是将目标端口从8888改写为8000

我确实看到修改后的数据包从队列中发送出去,但是如果我想通过连接到端口8888来连接到监听在端口8000上的HTTP服务器,连接会超时。我猜测数据包中有一些格式错误。

  1. package main
  2. import (
  3. "os"
  4. "os/signal"
  5. "syscall"
  6. "github.com/chifflier/nfqueue-go/nfqueue"
  7. "github.com/coreos/go-iptables/iptables"
  8. "github.com/google/gopacket"
  9. "github.com/google/gopacket/layers"
  10. )
  11. func sendNewPacket(payload *nfqueue.Payload, layers ...gopacket.SerializableLayer) {
  12. buffer := gopacket.NewSerializeBuffer()
  13. gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, layers...)
  14. outgoingPacket := buffer.Bytes()
  15. payload.SetVerdictModified(nfqueue.NF_ACCEPT, outgoingPacket)
  16. }
  17. func realCallback(payload *nfqueue.Payload) int {
  18. packet := gopacket.NewPacket(payload.Data, layers.LayerTypeIPv4, gopacket.Default)
  19. ethLayer := packet.Layer(layers.LayerTypeEthernet)
  20. eth, _ := ethLayer.(*layers.Ethernet)
  21. if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
  22. ip, _ := ipLayer.(*layers.IPv4)
  23. if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
  24. tcp, _ := tcpLayer.(*layers.TCP)
  25. if tcp.DstPort == 8888 {
  26. tcp.DstPort = 8000
  27. sendNewPacket(payload, eth, ip, tcp)
  28. return 0
  29. }
  30. if tcp.SrcPort == 8000 {
  31. tcp.SrcPort = 8888
  32. sendNewPacket(payload, eth, ip, tcp)
  33. return 0
  34. }
  35. }
  36. }
  37. payload.SetVerdict(nfqueue.NF_ACCEPT)
  38. return 0
  39. }
  40. func main() {
  41. ipt, err := iptables.New()
  42. if err != nil {
  43. panic(err)
  44. }
  45. ipt.Append("filter", "INPUT", "-p", "tcp", "-j", "NFQUEUE", "--queue-num", "0")
  46. ipt.Append("filter", "OUTPUT", "-p", "tcp", "-j", "NFQUEUE", "--queue-num", "0")
  47. q := new(nfqueue.Queue)
  48. q.SetCallback(realCallback)
  49. q.Init()
  50. defer q.Close()
  51. q.Unbind(syscall.AF_INET)
  52. q.Bind(syscall.AF_INET)
  53. q.CreateQueue(0)
  54. c := make(chan os.Signal, 1)
  55. signal.Notify(c, os.Interrupt)
  56. go func() {
  57. for sig := range c {
  58. _ = sig
  59. q.Close()
  60. err = ipt.ClearChain("filter", "INPUT")
  61. err = ipt.ClearChain("filter", "OUTPUT")
  62. if err != nil {
  63. panic(err)
  64. }
  65. os.Exit(0)
  66. }
  67. }()
  68. q.TryRun()
  69. }
英文:

I'm currently playing around with reading packages from nfqueue and modifying them.Unfortunately, I'm a bit stuck at changing the destination port of a package. See the code snippet below. Idea is to rewrite dest port 8888 to 8000.
I do see the modified package going out from the queue, but if I want to connect to an HTTP server listening on port 8000 by connecting to port 8888, the connection times out. I assume something mal-formed in the package.

  1. package main
  2. import (
  3. "os"
  4. "os/signal"
  5. "syscall"
  6. "github.com/chifflier/nfqueue-go/nfqueue"
  7. "github.com/coreos/go-iptables/iptables"
  8. "github.com/google/gopacket"
  9. "github.com/google/gopacket/layers"
  10. )
  11. func sendNewPacket(payload *nfqueue.Payload, layers ...gopacket.SerializableLayer) {
  12. buffer := gopacket.NewSerializeBuffer()
  13. gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, layers...)
  14. outgoingPacket := buffer.Bytes()
  15. payload.SetVerdictModified(nfqueue.NF_ACCEPT, outgoingPacket)
  16. }
  17. func realCallback(payload *nfqueue.Payload) int {
  18. packet := gopacket.NewPacket(payload.Data, layers.LayerTypeIPv4, gopacket.Default)
  19. ethLayer := packet.Layer(layers.LayerTypeEthernet)
  20. eth, _ := ethLayer.(*layers.Ethernet)
  21. if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
  22. ip, _ := ipLayer.(*layers.IPv4)
  23. if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
  24. tcp, _ := tcpLayer.(*layers.TCP)
  25. if tcp.DstPort == 8888 {
  26. tcp.DstPort = 8000
  27. sendNewPacket(payload, eth, ip, tcp)
  28. return 0
  29. }
  30. if tcp.SrcPort == 8000 {
  31. tcp.SrcPort = 8888
  32. sendNewPacket(payload, eth, ip, tcp)
  33. return 0
  34. }
  35. }
  36. }
  37. payload.SetVerdict(nfqueue.NF_ACCEPT)
  38. return 0
  39. }
  40. func main() {
  41. ipt, err := iptables.New()
  42. if err != nil {
  43. panic(err)
  44. }
  45. ipt.Append("filter", "INPUT", "-p", "tcp", "-j", "NFQUEUE", "--queue-num", "0")
  46. ipt.Append("filter", "OUTPUT", "-p", "tcp", "-j", "NFQUEUE", "--queue-num", "0")
  47. q := new(nfqueue.Queue)
  48. q.SetCallback(realCallback)
  49. q.Init()
  50. defer q.Close()
  51. q.Unbind(syscall.AF_INET)
  52. q.Bind(syscall.AF_INET)
  53. q.CreateQueue(0)
  54. c := make(chan os.Signal, 1)
  55. signal.Notify(c, os.Interrupt)
  56. go func() {
  57. for sig := range c {
  58. _ = sig
  59. q.Close()
  60. err = ipt.ClearChain("filter", "INPUT")
  61. err = ipt.ClearChain("filter", "OUTPUT")
  62. if err != nil {
  63. panic(err)
  64. }
  65. os.Exit(0)
  66. }
  67. }()
  68. q.TryRun()
  69. }

答案1

得分: 0

如果你对解决方案感兴趣,可以在这里找到代码:https://github.com/kung-foo/freki

英文:

In case you are interested in the solution, code can be found here: https://github.com/kung-foo/freki

huangapple
  • 本文由 发表于 2016年12月16日 19:31:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/41183466.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定