dns.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package local
  2. import (
  3. "fmt"
  4. "net"
  5. "os"
  6. "strings"
  7. "time"
  8. //"github.com/davecgh/go-spew/spew"
  9. "log"
  10. "os/exec"
  11. "github.com/gravitl/netmaker/netclient/ncutils"
  12. )
  13. const DNS_UNREACHABLE_ERROR = "nameserver unreachable"
  14. func SetDNSWithRetry(iface, network, address string) {
  15. var reachable bool
  16. for counter := 0; !reachable && counter < 5; counter++ {
  17. reachable = IsDNSReachable(address)
  18. time.Sleep(time.Second << 1)
  19. }
  20. if !reachable {
  21. ncutils.Log("not setting dns, server unreachable: " + address)
  22. } else if err := UpdateDNS(iface, network, address); err != nil {
  23. ncutils.Log("error applying dns" + err.Error())
  24. }
  25. }
  26. // SetDNS - sets the DNS of a local machine
  27. func SetDNS(nameserver string) error {
  28. bytes, err := os.ReadFile("/etc/resolv.conf")
  29. if err != nil {
  30. return err
  31. }
  32. resolvstring := string(bytes)
  33. // //check whether s contains substring text
  34. hasdns := strings.Contains(resolvstring, nameserver)
  35. if hasdns {
  36. return nil
  37. }
  38. resolv, err := os.OpenFile("/etc/resolv.conf", os.O_APPEND|os.O_WRONLY, 0644)
  39. if err != nil {
  40. return err
  41. }
  42. defer resolv.Close()
  43. _, err = resolv.WriteString("nameserver " + nameserver + "\n")
  44. return err
  45. }
  46. // UpdateDNS - updates local DNS of client
  47. func UpdateDNS(ifacename string, network string, nameserver string) error {
  48. if ifacename == "" {
  49. return fmt.Errorf("cannot set dns: interface name is blank")
  50. }
  51. if network == "" {
  52. return fmt.Errorf("cannot set dns: network name is blank")
  53. }
  54. if nameserver == "" {
  55. return fmt.Errorf("cannot set dns: nameserver is blank")
  56. }
  57. if ncutils.IsWindows() {
  58. return nil
  59. }
  60. if !IsDNSReachable(nameserver) {
  61. return fmt.Errorf(DNS_UNREACHABLE_ERROR + " : " + nameserver + ":53")
  62. }
  63. _, err := exec.LookPath("resolvectl")
  64. if err != nil {
  65. log.Println(err)
  66. log.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
  67. } else {
  68. _, err = ncutils.RunCmd("resolvectl domain "+ifacename+" ~"+network, true)
  69. if err != nil {
  70. log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
  71. } else {
  72. _, err = ncutils.RunCmd("resolvectl default-route "+ifacename+" false", true)
  73. if err != nil {
  74. log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
  75. } else {
  76. _, err = ncutils.RunCmd("resolvectl dns "+ifacename+" "+nameserver, true)
  77. if err != nil {
  78. log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
  79. }
  80. }
  81. }
  82. }
  83. return err
  84. }
  85. // IsDNSReachable - checks if nameserver is reachable
  86. func IsDNSReachable(nameserver string) bool {
  87. port := "53"
  88. protocols := [2]string{"tcp", "udp"}
  89. for _, proto := range protocols {
  90. timeout := time.Second
  91. conn, err := net.DialTimeout(proto, net.JoinHostPort(nameserver, port), timeout)
  92. if err != nil {
  93. return false
  94. }
  95. if conn != nil {
  96. defer conn.Close()
  97. } else {
  98. return false
  99. }
  100. }
  101. return true
  102. }
  103. // IsDNSWorking - checks if record is returned by correct nameserver
  104. func IsDNSWorking(network string, nameserver string) bool {
  105. var isworking bool
  106. servers, err := net.LookupNS("netmaker" + "." + "network")
  107. if err != nil {
  108. return isworking
  109. }
  110. for _, ns := range servers {
  111. if strings.Contains(ns.Host, nameserver) {
  112. isworking = true
  113. }
  114. }
  115. return isworking
  116. }