noquick.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package wireguard
  2. import (
  3. "errors"
  4. "os"
  5. "os/exec"
  6. "strconv"
  7. "strings"
  8. "github.com/gravitl/netmaker/models"
  9. "github.com/gravitl/netmaker/netclient/config"
  10. "github.com/gravitl/netmaker/netclient/ncutils"
  11. "golang.zx2c4.com/wireguard/wgctrl"
  12. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  13. )
  14. // ApplyWithoutWGQuick - Function for running the equivalent of "wg-quick up" for linux if wg-quick is missing
  15. func ApplyWithoutWGQuick(node *models.Node, ifacename string, confPath string) error {
  16. ipExec, err := exec.LookPath("ip")
  17. if err != nil {
  18. return err
  19. }
  20. wgclient, err := wgctrl.New()
  21. if err != nil {
  22. return err
  23. }
  24. defer wgclient.Close()
  25. privkey, err := RetrievePrivKey(node.Network)
  26. if err != nil {
  27. return err
  28. }
  29. key, err := wgtypes.ParseKey(privkey)
  30. if err != nil {
  31. return err
  32. }
  33. conf := wgtypes.Config{}
  34. nodeport := int(node.ListenPort)
  35. if node.UDPHolePunch == "yes" &&
  36. node.IsServer == "no" &&
  37. node.IsIngressGateway != "yes" &&
  38. node.IsStatic != "yes" {
  39. conf = wgtypes.Config{
  40. PrivateKey: &key,
  41. }
  42. } else {
  43. conf = wgtypes.Config{
  44. PrivateKey: &key,
  45. ListenPort: &nodeport,
  46. }
  47. }
  48. netmaskArr := strings.Split(node.NetworkSettings.AddressRange, "/")
  49. var netmask = "32"
  50. if len(netmaskArr) == 2 {
  51. netmask = netmaskArr[1]
  52. }
  53. setKernelDevice(ifacename, node.Address, netmask)
  54. _, err = wgclient.Device(ifacename)
  55. if err != nil {
  56. if !os.IsNotExist(err) {
  57. return errors.New("Unknown config error: " + err.Error())
  58. }
  59. }
  60. err = wgclient.ConfigureDevice(ifacename, conf)
  61. if err != nil {
  62. if os.IsNotExist(err) {
  63. ncutils.PrintLog("Could not configure device: "+err.Error(), 0)
  64. }
  65. }
  66. if _, err := ncutils.RunCmd(ipExec+" link set down dev "+ifacename, false); err != nil {
  67. ncutils.PrintLog("attempted to remove interface before editing", 1)
  68. return err
  69. }
  70. if node.PostDown != "" {
  71. runcmds := strings.Split(node.PostDown, "; ")
  72. _ = ncutils.RunCmds(runcmds, false)
  73. }
  74. // set MTU of node interface
  75. if _, err := ncutils.RunCmd(ipExec+" link set mtu "+strconv.Itoa(int(node.MTU))+" up dev "+ifacename, true); err != nil {
  76. ncutils.PrintLog("failed to create interface with mtu "+strconv.Itoa(int(node.MTU))+"-"+ifacename, 1)
  77. return err
  78. }
  79. if node.PostUp != "" {
  80. runcmds := strings.Split(node.PostUp, "; ")
  81. _ = ncutils.RunCmds(runcmds, true)
  82. }
  83. if node.Address6 != "" && node.IsDualStack == "yes" {
  84. ncutils.PrintLog("adding address: "+node.Address6, 1)
  85. _, _ = ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+node.Address6+"/64", true)
  86. }
  87. return nil
  88. }
  89. // RemoveWithoutWGQuick - Function for running the equivalent of "wg-quick down" for linux if wg-quick is missing
  90. func RemoveWithoutWGQuick(ifacename string) error {
  91. ipExec, err := exec.LookPath("ip")
  92. if err != nil {
  93. return err
  94. }
  95. out, err := ncutils.RunCmd(ipExec+" link del "+ifacename, false)
  96. dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
  97. if err != nil && !dontprint {
  98. ncutils.PrintLog("error running command: "+ipExec+" link del "+ifacename, 1)
  99. ncutils.PrintLog(out, 1)
  100. }
  101. network := strings.ReplaceAll(ifacename, "nm-", "")
  102. nodeconf, err := config.ReadConfig(network)
  103. if nodeconf != nil && err == nil {
  104. if nodeconf.Node.PostDown != "" {
  105. runcmds := strings.Split(nodeconf.Node.PostDown, "; ")
  106. _ = ncutils.RunCmds(runcmds, false)
  107. }
  108. } else if err != nil {
  109. ncutils.PrintLog("error retrieving config: "+err.Error(), 1)
  110. }
  111. return err
  112. }
  113. func setKernelDevice(ifacename, address, mask string) error {
  114. ipExec, err := exec.LookPath("ip")
  115. if err != nil {
  116. return err
  117. }
  118. // == best effort ==
  119. ncutils.RunCmd("ip link delete dev "+ifacename, false)
  120. ncutils.RunCmd(ipExec+" link add dev "+ifacename+" type wireguard", true)
  121. ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+address+"/"+mask, true) // this was a bug waiting to happen
  122. return nil
  123. }