99-origin-dns.sh 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/bin/bash -x
  2. # -*- mode: sh; sh-indentation: 2 -*-
  3. # This NetworkManager dispatcher script replicates the functionality of
  4. # NetworkManager's dns=dnsmasq however, rather than hardcoding the listening
  5. # address and /etc/resolv.conf to 127.0.0.1 it pulls the IP address from the
  6. # interface that owns the default route. This enables us to then configure pods
  7. # to use this IP address as their only resolver, where as using 127.0.0.1 inside
  8. # a pod would fail.
  9. #
  10. # To use this,
  11. # - If this host is also a master, reconfigure master dnsConfig to listen on
  12. # 8053 to avoid conflicts on port 53 and open port 8053 in the firewall
  13. # - Drop this script in /etc/NetworkManager/dispatcher.d/
  14. # - systemctl restart NetworkManager
  15. # - Configure node-config.yaml to set dnsIP: to the ip address of this
  16. # node
  17. #
  18. # Test it:
  19. # host kubernetes.default.svc.cluster.local
  20. # host google.com
  21. #
  22. # TODO: I think this would be easy to add as a config option in NetworkManager
  23. # natively, look at hacking that up
  24. cd /etc/sysconfig/network-scripts
  25. . ./network-functions
  26. [ -f ../network ] && . ../network
  27. if [[ $2 =~ ^(up|dhcp4-change|dhcp6-change)$ ]]; then
  28. # If the origin-upstream-dns config file changed we need to restart
  29. NEEDS_RESTART=0
  30. UPSTREAM_DNS='/etc/dnsmasq.d/origin-upstream-dns.conf'
  31. # We'll regenerate the dnsmasq origin config in a temp file first
  32. UPSTREAM_DNS_TMP=`mktemp`
  33. UPSTREAM_DNS_TMP_SORTED=`mktemp`
  34. CURRENT_UPSTREAM_DNS_SORTED=`mktemp`
  35. NEW_RESOLV_CONF=`mktemp`
  36. ######################################################################
  37. # couldn't find an existing method to determine if the interface owns the
  38. # default route
  39. def_route=$(/sbin/ip route list match 0.0.0.0/0 | awk '{print $3 }')
  40. def_route_int=$(/sbin/ip route get to ${def_route} | awk '{print $3}')
  41. def_route_ip=$(/sbin/ip route get to ${def_route} | awk '{print $5}')
  42. if [[ ${DEVICE_IFACE} == ${def_route_int} && \
  43. -n "${IP4_NAMESERVERS}" ]]; then
  44. if [ ! -f /etc/dnsmasq.d/origin-dns.conf ]; then
  45. cat << EOF > /etc/dnsmasq.d/origin-dns.conf
  46. no-resolv
  47. domain-needed
  48. server=/cluster.local/172.30.0.1
  49. server=/30.172.in-addr.arpa/172.30.0.1
  50. EOF
  51. # New config file, must restart
  52. NEEDS_RESTART=1
  53. fi
  54. ######################################################################
  55. # Generate a new origin dns config file
  56. for ns in ${IP4_NAMESERVERS}; do
  57. if [[ ! -z $ns ]]; then
  58. echo "server=${ns}"
  59. fi
  60. done > $UPSTREAM_DNS_TMP
  61. # Sort it in case DNS servers arrived in a different order
  62. sort $UPSTREAM_DNS_TMP > $UPSTREAM_DNS_TMP_SORTED
  63. sort $UPSTREAM_DNS > $CURRENT_UPSTREAM_DNS_SORTED
  64. # Compare to the current config file (sorted)
  65. NEW_DNS_SUM=`md5sum ${UPSTREAM_DNS_TMP_SORTED} | awk '{print $1}'`
  66. CURRENT_DNS_SUM=`md5sum ${CURRENT_UPSTREAM_DNS_SORTED} | awk '{print $1}'`
  67. if [ "${NEW_DNS_SUM}" != "${CURRENT_DNS_SUM}" ]; then
  68. # DNS has changed, copy the temp file to the proper location (-Z
  69. # sets default selinux context) and set the restart flag
  70. cp -Z $UPSTREAM_DNS_TMP $UPSTREAM_DNS
  71. NEEDS_RESTART=1
  72. fi
  73. if ! `systemctl -q is-active dnsmasq.service`; then
  74. NEEDS_RESTART=1
  75. fi
  76. ######################################################################
  77. if [ "${NEEDS_RESTART}" -eq "1" ]; then
  78. systemctl restart dnsmasq
  79. fi
  80. # Only if dnsmasq is running properly make it our only nameserver
  81. if `systemctl -q is-active dnsmasq.service`; then
  82. sed -e '/^nameserver.*$/d' /etc/resolv.conf > ${NEW_RESOLV_CONF}
  83. echo "nameserver "${def_route_ip}"" >> ${NEW_RESOLV_CONF}
  84. if ! grep -q '99-origin-dns.sh' ${NEW_RESOLV_CONF}; then
  85. echo "# nameserver updated by /etc/NetworkManager/dispatcher.d/99-origin-dns.sh" >> ${NEW_RESOLV_CONF}
  86. fi
  87. cp -Z ${NEW_RESOLV_CONF} /etc/resolv.conf
  88. fi
  89. fi
  90. # Clean up after yourself
  91. rm -f $UPSTREAM_DNS_TMP $UPSTREAM_DNS_TMP_SORTED $CURRENT_UPSTREAM_DNS_SORTED $NEW_RESOLV_CONF
  92. fi