link_tun.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package handler
  2. import (
  3. "fmt"
  4. "github.com/bjdgyc/anylink/base"
  5. "github.com/bjdgyc/anylink/sessdata"
  6. "github.com/coreos/go-iptables/iptables"
  7. "github.com/songgao/water"
  8. )
  9. func checkTun() {
  10. // 测试tun
  11. cfg := water.Config{
  12. DeviceType: water.TUN,
  13. }
  14. ifce, err := water.New(cfg)
  15. if err != nil {
  16. base.Fatal("open tun err: ", err)
  17. }
  18. defer ifce.Close()
  19. // 测试ip命令
  20. cmdstr := fmt.Sprintf("ip link set dev %s up mtu %s multicast off", ifce.Name(), "1399")
  21. err = execCmd([]string{cmdstr})
  22. if err != nil {
  23. base.Fatal("testTun err: ", err)
  24. }
  25. //开启服务器转发
  26. if err := execCmd([]string{"sysctl -w net.ipv4.ip_forward=1"}); err != nil {
  27. base.Error(err)
  28. }
  29. if base.Cfg.IptablesNat {
  30. //添加NAT转发规则
  31. ipt, err := iptables.New()
  32. if err != nil {
  33. base.Error(err)
  34. return
  35. }
  36. natRule := []string{"-s", base.Cfg.Ipv4CIDR, "-o", base.Cfg.Ipv4Master, "-j", "MASQUERADE"}
  37. forwardRule := []string{"-j", "ACCEPT"}
  38. if natExists, _ := ipt.Exists("nat", "POSTROUTING", natRule...); !natExists {
  39. ipt.Insert("nat", "POSTROUTING", 1, natRule...)
  40. }
  41. if forwardExists, _ := ipt.Exists("filter", "FORWARD", forwardRule...); !forwardExists {
  42. ipt.Insert("filter", "FORWARD", 1, forwardRule...)
  43. }
  44. base.Info(ipt.List("nat", "POSTROUTING"))
  45. base.Info(ipt.List("filter", "FORWARD"))
  46. }
  47. }
  48. // 创建tun网卡
  49. func LinkTun(cSess *sessdata.ConnSession) error {
  50. cfg := water.Config{
  51. DeviceType: water.TUN,
  52. }
  53. ifce, err := water.New(cfg)
  54. if err != nil {
  55. base.Error(err)
  56. return err
  57. }
  58. // log.Printf("Interface Name: %s\n", ifce.Name())
  59. cSess.SetIfName(ifce.Name())
  60. cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast off", ifce.Name(), cSess.Mtu)
  61. cmdstr2 := fmt.Sprintf("ip addr add dev %s local %s peer %s/32",
  62. ifce.Name(), base.Cfg.Ipv4Gateway, cSess.IpAddr)
  63. err = execCmd([]string{cmdstr1, cmdstr2})
  64. if err != nil {
  65. base.Error(err)
  66. _ = ifce.Close()
  67. return err
  68. }
  69. cmdstr3 := fmt.Sprintf("sysctl -w net.ipv6.conf.%s.disable_ipv6=1", ifce.Name())
  70. execCmd([]string{cmdstr3})
  71. go tunRead(ifce, cSess)
  72. go tunWrite(ifce, cSess)
  73. return nil
  74. }
  75. func tunWrite(ifce *water.Interface, cSess *sessdata.ConnSession) {
  76. defer func() {
  77. base.Debug("LinkTun return", cSess.IpAddr)
  78. cSess.Close()
  79. _ = ifce.Close()
  80. }()
  81. var (
  82. err error
  83. pl *sessdata.Payload
  84. )
  85. for {
  86. select {
  87. case pl = <-cSess.PayloadIn:
  88. case <-cSess.CloseChan:
  89. return
  90. }
  91. _, err = ifce.Write(pl.Data)
  92. if err != nil {
  93. base.Error("tun Write err", err)
  94. return
  95. }
  96. putPayloadInBefore(cSess, pl)
  97. }
  98. }
  99. func tunRead(ifce *water.Interface, cSess *sessdata.ConnSession) {
  100. defer func() {
  101. base.Debug("tunRead return", cSess.IpAddr)
  102. _ = ifce.Close()
  103. }()
  104. var (
  105. err error
  106. n int
  107. )
  108. for {
  109. // data := make([]byte, BufferSize)
  110. pl := getPayload()
  111. n, err = ifce.Read(pl.Data)
  112. if err != nil {
  113. base.Error("tun Read err", n, err)
  114. return
  115. }
  116. // 更新数据长度
  117. pl.Data = (pl.Data)[:n]
  118. // data = data[:n]
  119. // ip_src := waterutil.IPv4Source(data)
  120. // ip_dst := waterutil.IPv4Destination(data)
  121. // ip_port := waterutil.IPv4DestinationPort(data)
  122. // fmt.Println("sent:", ip_src, ip_dst, ip_port)
  123. // packet := gopacket.NewPacket(data, layers.LayerTypeIPv4, gopacket.Default)
  124. // fmt.Println("read:", packet)
  125. if payloadOut(cSess, pl) {
  126. return
  127. }
  128. }
  129. }