PageRenderTime 24ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/firewall/lib/puppet/util/firewall.rb

https://gitlab.com/jkday/bootstrap
Ruby | 226 lines | 169 code | 17 blank | 40 comment | 27 complexity | 95bb270ea59b75eec746c7878d253f9c MD5 | raw file
Possible License(s): Apache-2.0, BSD-2-Clause
  1. require 'socket'
  2. require 'resolv'
  3. require 'puppet/util/ipcidr'
  4. # Util module for puppetlabs-firewall
  5. module Puppet::Util::Firewall
  6. # Translate the symbolic names for icmp packet types to integers
  7. def icmp_name_to_number(value_icmp, protocol)
  8. if value_icmp =~ /\d{1,2}$/
  9. value_icmp
  10. elsif protocol == 'inet'
  11. case value_icmp
  12. when "echo-reply" then "0"
  13. when "destination-unreachable" then "3"
  14. when "source-quench" then "4"
  15. when "redirect" then "6"
  16. when "echo-request" then "8"
  17. when "router-advertisement" then "9"
  18. when "router-solicitation" then "10"
  19. when "time-exceeded" then "11"
  20. when "parameter-problem" then "12"
  21. when "timestamp-request" then "13"
  22. when "timestamp-reply" then "14"
  23. when "address-mask-request" then "17"
  24. when "address-mask-reply" then "18"
  25. else nil
  26. end
  27. elsif protocol == 'inet6'
  28. case value_icmp
  29. when "destination-unreachable" then "1"
  30. when "time-exceeded" then "3"
  31. when "parameter-problem" then "4"
  32. when "echo-request" then "128"
  33. when "echo-reply" then "129"
  34. when "router-solicitation" then "133"
  35. when "router-advertisement" then "134"
  36. when "redirect" then "137"
  37. else nil
  38. end
  39. else
  40. raise ArgumentError, "unsupported protocol family '#{protocol}'"
  41. end
  42. end
  43. # Convert log_level names to their respective numbers
  44. def log_level_name_to_number(value)
  45. #TODO make this 0-7 only
  46. if value =~ /\d/
  47. value
  48. else
  49. case value
  50. when "panic" then "0"
  51. when "alert" then "1"
  52. when "crit" then "2"
  53. when "err" then "3"
  54. when "error" then "3"
  55. when "warn" then "4"
  56. when "warning" then "4"
  57. when "not" then "5"
  58. when "notice" then "5"
  59. when "info" then "6"
  60. when "debug" then "7"
  61. else nil
  62. end
  63. end
  64. end
  65. # This method takes a string and a protocol and attempts to convert
  66. # it to a port number if valid.
  67. #
  68. # If the string already contains a port number or perhaps a range of ports
  69. # in the format 22:1000 for example, it simply returns the string and does
  70. # nothing.
  71. def string_to_port(value, proto)
  72. proto = proto.to_s
  73. unless proto =~ /^(tcp|udp)$/
  74. proto = 'tcp'
  75. end
  76. m = value.to_s.match(/^(!\s+)?(\S+)/)
  77. if m[2].match(/^\d+(-\d+)?$/)
  78. return "#{m[1]}#{m[2]}"
  79. else
  80. return "#{m[1]}#{Socket.getservbyname(m[2], proto).to_s}"
  81. end
  82. end
  83. # Takes an address and returns it in CIDR notation.
  84. #
  85. # If the address is:
  86. #
  87. # - A hostname:
  88. # It will be resolved
  89. # - An IPv4 address:
  90. # It will be qualified with a /32 CIDR notation
  91. # - An IPv6 address:
  92. # It will be qualified with a /128 CIDR notation
  93. # - An IP address with a CIDR notation:
  94. # It will be normalised
  95. # - An IP address with a dotted-quad netmask:
  96. # It will be converted to CIDR notation
  97. # - Any address with a resulting prefix length of zero:
  98. # It will return nil which is equivilent to not specifying an address
  99. #
  100. def host_to_ip(value)
  101. begin
  102. value = Puppet::Util::IPCidr.new(value)
  103. rescue
  104. value = Puppet::Util::IPCidr.new(Resolv.getaddress(value))
  105. end
  106. return nil if value.prefixlen == 0
  107. value.cidr
  108. end
  109. # Takes an address mask and converts the host portion to CIDR notation.
  110. #
  111. # This takes into account you can negate a mask but follows all rules
  112. # defined in host_to_ip for the host/address part.
  113. #
  114. def host_to_mask(value)
  115. match = value.match /(!)\s?(.*)$/
  116. return host_to_ip(value) unless match
  117. cidr = host_to_ip(match[2])
  118. return nil if cidr == nil
  119. "#{match[1]} #{cidr}"
  120. end
  121. # Validates the argument is int or hex, and returns valid hex
  122. # conversion of the value or nil otherwise.
  123. def to_hex32(value)
  124. begin
  125. value = Integer(value)
  126. if value.between?(0, 0xffffffff)
  127. return '0x' + value.to_s(16)
  128. end
  129. rescue ArgumentError
  130. # pass
  131. end
  132. return nil
  133. end
  134. def persist_iptables(proto)
  135. debug("[persist_iptables]")
  136. # Basic normalisation for older Facter
  137. os_key = Facter.value(:osfamily)
  138. os_key ||= case Facter.value(:operatingsystem)
  139. when 'RedHat', 'CentOS', 'Fedora', 'Scientific', 'SL', 'SLC', 'Ascendos', 'CloudLinux', 'PSBM', 'OracleLinux', 'OVS', 'OEL', 'Amazon', 'XenServer'
  140. 'RedHat'
  141. when 'Debian', 'Ubuntu'
  142. 'Debian'
  143. else
  144. Facter.value(:operatingsystem)
  145. end
  146. # Older iptables-persistent doesn't provide save action.
  147. if os_key == 'Debian'
  148. persist_ver = Facter.value(:iptables_persistent_version)
  149. if (persist_ver and Puppet::Util::Package.versioncmp(persist_ver, '0.5.0') < 0)
  150. os_key = 'Debian_manual'
  151. end
  152. end
  153. # Fedora 15 and newer use systemd to persist iptable rules
  154. if os_key == 'RedHat' && Facter.value(:operatingsystem) == 'Fedora' && Facter.value(:operatingsystemrelease).to_i >= 15
  155. os_key = 'Fedora'
  156. end
  157. # RHEL 7 and newer also use systemd to persist iptable rules
  158. if os_key == 'RedHat' && ['RedHat','CentOS','Scientific','SL','SLC','Ascendos','CloudLinux','PSBM','OracleLinux','OVS','OEL','XenServer'].include?(Facter.value(:operatingsystem)) && Facter.value(:operatingsystemrelease).to_i >= 7
  159. os_key = 'Fedora'
  160. end
  161. cmd = case os_key.to_sym
  162. when :RedHat
  163. case proto.to_sym
  164. when :IPv4
  165. %w{/sbin/service iptables save}
  166. when :IPv6
  167. %w{/sbin/service ip6tables save}
  168. end
  169. when :Fedora
  170. case proto.to_sym
  171. when :IPv4
  172. %w{/usr/libexec/iptables/iptables.init save}
  173. when :IPv6
  174. %w{/usr/libexec/iptables/ip6tables.init save}
  175. end
  176. when :Debian
  177. case proto.to_sym
  178. when :IPv4, :IPv6
  179. if (persist_ver and Puppet::Util::Package.versioncmp(persist_ver, '1.0') > 0)
  180. %w{/usr/sbin/service netfilter-persistent save}
  181. else
  182. %w{/usr/sbin/service iptables-persistent save}
  183. end
  184. end
  185. when :Debian_manual
  186. case proto.to_sym
  187. when :IPv4
  188. ["/bin/sh", "-c", "/sbin/iptables-save > /etc/iptables/rules"]
  189. end
  190. when :Archlinux
  191. case proto.to_sym
  192. when :IPv4
  193. ["/bin/sh", "-c", "/usr/sbin/iptables-save > /etc/iptables/iptables.rules"]
  194. when :IPv6
  195. ["/bin/sh", "-c", "/usr/sbin/ip6tables-save > /etc/iptables/ip6tables.rules"]
  196. end
  197. end
  198. # Catch unsupported OSs from the case statement above.
  199. if cmd.nil?
  200. debug('firewall: Rule persistence is not supported for this type/OS')
  201. return
  202. end
  203. begin
  204. execute(cmd)
  205. rescue Puppet::ExecutionFailure => detail
  206. warning("Unable to persist firewall rules: #{detail}")
  207. end
  208. end
  209. end