dns.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. // SetDNS - sets the DNS of a local machine
  15. func SetDNS(nameserver string) error {
  16. bytes, err := os.ReadFile("/etc/resolv.conf")
  17. if err != nil {
  18. return err
  19. }
  20. resolvstring := string(bytes)
  21. // //check whether s contains substring text
  22. hasdns := strings.Contains(resolvstring, nameserver)
  23. if hasdns {
  24. return nil
  25. }
  26. resolv, err := os.OpenFile("/etc/resolv.conf", os.O_APPEND|os.O_WRONLY, 0644)
  27. if err != nil {
  28. return err
  29. }
  30. defer resolv.Close()
  31. _, err = resolv.WriteString("nameserver " + nameserver + "\n")
  32. return err
  33. }
  34. // UpdateDNS - updates local DNS of client
  35. func UpdateDNS(ifacename string, network string, nameserver string) error {
  36. if ifacename == "" {
  37. return fmt.Errorf("cannot set dns: interface name is blank")
  38. }
  39. if network == "" {
  40. return fmt.Errorf("cannot set dns: network name is blank")
  41. }
  42. if nameserver == "" {
  43. return fmt.Errorf("cannot set dns: nameserver is blank")
  44. }
  45. if ncutils.IsWindows() {
  46. return nil
  47. }
  48. if !IsDNSReachable(nameserver) {
  49. return fmt.Errorf(DNS_UNREACHABLE_ERROR + " : " + nameserver + ":53")
  50. }
  51. _, err := exec.LookPath("resolvectl")
  52. if err != nil {
  53. log.Println(err)
  54. log.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
  55. } else {
  56. _, err = ncutils.RunCmd("resolvectl domain "+ifacename+" ~"+network, true)
  57. if err != nil {
  58. log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
  59. } else {
  60. _, err = ncutils.RunCmd("resolvectl default-route "+ifacename+" false", true)
  61. if err != nil {
  62. log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
  63. } else {
  64. _, err = ncutils.RunCmd("resolvectl dns "+ifacename+" "+nameserver, true)
  65. if err != nil {
  66. log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
  67. }
  68. }
  69. }
  70. }
  71. return err
  72. }
  73. func IsDNSReachable(nameserver string) bool {
  74. port := "53"
  75. protocols := [2]string{"tcp", "udp"}
  76. for _, proto := range protocols {
  77. timeout := time.Second
  78. conn, err := net.DialTimeout(proto, net.JoinHostPort(nameserver, port), timeout)
  79. if err != nil {
  80. return false
  81. }
  82. if conn != nil {
  83. defer conn.Close()
  84. } else {
  85. return false
  86. }
  87. }
  88. return true
  89. }