PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/firewall/lib/puppet/type/firewall.rb

https://github.com/RichardKnop/puppet
Ruby | 811 lines | 615 code | 160 blank | 36 comment | 62 complexity | 2a591254b2df7528eafaa6dff5459ace MD5 | raw file
Possible License(s): Apache-2.0
  1. # See: #10295 for more details.
  2. #
  3. # This is a workaround for bug: #4248 whereby ruby files outside of the normal
  4. # provider/type path do not load until pluginsync has occured on the puppetmaster
  5. #
  6. # In this case I'm trying the relative path first, then falling back to normal
  7. # mechanisms. This should be fixed in future versions of puppet but it looks
  8. # like we'll need to maintain this for some time perhaps.
  9. $LOAD_PATH.unshift(File.join(File.dirname(__FILE__),"..",".."))
  10. require 'puppet/util/firewall'
  11. Puppet::Type.newtype(:firewall) do
  12. include Puppet::Util::Firewall
  13. @doc = <<-EOS
  14. This type provides the capability to manage firewall rules within
  15. puppet.
  16. **Autorequires:**
  17. If Puppet is managing the iptables or ip6tables chains specified in the
  18. `chain` or `jump` parameters, the firewall resource will autorequire
  19. those firewallchain resources.
  20. If Puppet is managing the iptables or iptables-persistent packages, and
  21. the provider is iptables or ip6tables, the firewall resource will
  22. autorequire those packages to ensure that any required binaries are
  23. installed.
  24. EOS
  25. feature :rate_limiting, "Rate limiting features."
  26. feature :snat, "Source NATing"
  27. feature :dnat, "Destination NATing"
  28. feature :interface_match, "Interface matching"
  29. feature :icmp_match, "Matching ICMP types"
  30. feature :owner, "Matching owners"
  31. feature :state_match, "Matching stateful firewall states"
  32. feature :reject_type, "The ability to control reject messages"
  33. feature :log_level, "The ability to control the log level"
  34. feature :log_prefix, "The ability to add prefixes to log messages"
  35. feature :mark, "Set the netfilter mark value associated with the packet"
  36. feature :tcp_flags, "The ability to match on particular TCP flag settings"
  37. feature :pkttype, "Match a packet type"
  38. feature :socket, "Match open sockets"
  39. feature :isfragment, "Match fragments"
  40. feature :address_type, "The ability match on source or destination address type"
  41. feature :iprange, "The ability match on source or destination IP range "
  42. # provider specific features
  43. feature :iptables, "The provider provides iptables features."
  44. ensurable do
  45. desc <<-EOS
  46. Manage the state of this rule. The default action is *present*.
  47. EOS
  48. newvalue(:present) do
  49. provider.insert
  50. end
  51. newvalue(:absent) do
  52. provider.delete
  53. end
  54. defaultto :present
  55. end
  56. newparam(:name) do
  57. desc <<-EOS
  58. The canonical name of the rule. This name is also used for ordering
  59. so make sure you prefix the rule with a number:
  60. 000 this runs first
  61. 999 this runs last
  62. Depending on the provider, the name of the rule can be stored using
  63. the comment feature of the underlying firewall subsystem.
  64. EOS
  65. isnamevar
  66. # Keep rule names simple - they must start with a number
  67. newvalues(/^\d+[[:alpha:][:digit:][:punct:][:space:]]+$/)
  68. end
  69. newproperty(:action) do
  70. desc <<-EOS
  71. This is the action to perform on a match. Can be one of:
  72. * accept - the packet is accepted
  73. * reject - the packet is rejected with a suitable ICMP response
  74. * drop - the packet is dropped
  75. If you specify no value it will simply match the rule but perform no
  76. action unless you provide a provider specific parameter (such as *jump*).
  77. EOS
  78. newvalues(:accept, :reject, :drop)
  79. end
  80. # Generic matching properties
  81. newproperty(:source) do
  82. desc <<-EOS
  83. The source address. For example:
  84. source => '192.168.2.0/24'
  85. The source can also be an IPv6 address if your provider supports it.
  86. EOS
  87. munge do |value|
  88. begin
  89. @resource.host_to_ip(value)
  90. rescue Exception => e
  91. self.fail("host_to_ip failed for #{value}, exception #{e}")
  92. end
  93. end
  94. end
  95. # Source IP range
  96. newproperty(:src_range, :required_features => :iprange) do
  97. desc <<-EOS
  98. The source IP range. For example:
  99. src_range => '192.168.1.1-192.168.1.10'
  100. The source IP range is must in 'IP1-IP2' format.
  101. EOS
  102. newvalues(/^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)-((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)/)
  103. end
  104. newproperty(:destination) do
  105. desc <<-EOS
  106. The destination address to match. For example:
  107. destination => '192.168.1.0/24'
  108. The destination can also be an IPv6 address if your provider supports it.
  109. EOS
  110. munge do |value|
  111. begin
  112. @resource.host_to_ip(value)
  113. rescue Exception => e
  114. self.fail("host_to_ip failed for #{value}, exception #{e}")
  115. end
  116. end
  117. end
  118. # Destination IP range
  119. newproperty(:dst_range, :required_features => :iprange) do
  120. desc <<-EOS
  121. The destination IP range. For example:
  122. dst_range => '192.168.1.1-192.168.1.10'
  123. The destination IP range is must in 'IP1-IP2' format.
  124. EOS
  125. newvalues(/^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)-((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)/)
  126. end
  127. newproperty(:sport, :array_matching => :all) do
  128. desc <<-EOS
  129. The source port to match for this filter (if the protocol supports
  130. ports). Will accept a single element or an array.
  131. For some firewall providers you can pass a range of ports in the format:
  132. <start_number>-<ending_number>
  133. For example:
  134. 1-1024
  135. This would cover ports 1 to 1024.
  136. EOS
  137. munge do |value|
  138. @resource.string_to_port(value, :proto)
  139. end
  140. def is_to_s(value)
  141. should_to_s(value)
  142. end
  143. def should_to_s(value)
  144. value = [value] unless value.is_a?(Array)
  145. value.join(',')
  146. end
  147. end
  148. newproperty(:dport, :array_matching => :all) do
  149. desc <<-EOS
  150. The destination port to match for this filter (if the protocol supports
  151. ports). Will accept a single element or an array.
  152. For some firewall providers you can pass a range of ports in the format:
  153. <start_number>-<ending_number>
  154. For example:
  155. 1-1024
  156. This would cover ports 1 to 1024.
  157. EOS
  158. munge do |value|
  159. @resource.string_to_port(value, :proto)
  160. end
  161. def is_to_s(value)
  162. should_to_s(value)
  163. end
  164. def should_to_s(value)
  165. value = [value] unless value.is_a?(Array)
  166. value.join(',')
  167. end
  168. end
  169. newproperty(:port, :array_matching => :all) do
  170. desc <<-EOS
  171. The destination or source port to match for this filter (if the protocol
  172. supports ports). Will accept a single element or an array.
  173. For some firewall providers you can pass a range of ports in the format:
  174. <start_number>-<ending_number>
  175. For example:
  176. 1-1024
  177. This would cover ports 1 to 1024.
  178. EOS
  179. munge do |value|
  180. @resource.string_to_port(value, :proto)
  181. end
  182. def is_to_s(value)
  183. should_to_s(value)
  184. end
  185. def should_to_s(value)
  186. value = [value] unless value.is_a?(Array)
  187. value.join(',')
  188. end
  189. end
  190. newproperty(:dst_type, :required_features => :address_type) do
  191. desc <<-EOS
  192. The destination address type. For example:
  193. dst_type => 'LOCAL'
  194. Can be one of:
  195. * UNSPEC - an unspecified address
  196. * UNICAST - a unicast address
  197. * LOCAL - a local address
  198. * BROADCAST - a broadcast address
  199. * ANYCAST - an anycast packet
  200. * MULTICAST - a multicast address
  201. * BLACKHOLE - a blackhole address
  202. * UNREACHABLE - an unreachable address
  203. * PROHIBIT - a prohibited address
  204. * THROW - undocumented
  205. * NAT - undocumented
  206. * XRESOLVE - undocumented
  207. EOS
  208. newvalues(:UNSPEC, :UNICAST, :LOCAL, :BROADCAST, :ANYCAST, :MULTICAST,
  209. :BLACKHOLE, :UNREACHABLE, :PROHIBIT, :THROW, :NAT, :XRESOLVE)
  210. end
  211. newproperty(:src_type, :required_features => :address_type) do
  212. desc <<-EOS
  213. The source address type. For example:
  214. src_type => 'LOCAL'
  215. Can be one of:
  216. * UNSPEC - an unspecified address
  217. * UNICAST - a unicast address
  218. * LOCAL - a local address
  219. * BROADCAST - a broadcast address
  220. * ANYCAST - an anycast packet
  221. * MULTICAST - a multicast address
  222. * BLACKHOLE - a blackhole address
  223. * UNREACHABLE - an unreachable address
  224. * PROHIBIT - a prohibited address
  225. * THROW - undocumented
  226. * NAT - undocumented
  227. * XRESOLVE - undocumented
  228. EOS
  229. newvalues(:UNSPEC, :UNICAST, :LOCAL, :BROADCAST, :ANYCAST, :MULTICAST,
  230. :BLACKHOLE, :UNREACHABLE, :PROHIBIT, :THROW, :NAT, :XRESOLVE)
  231. end
  232. newproperty(:proto) do
  233. desc <<-EOS
  234. The specific protocol to match for this rule. By default this is
  235. *tcp*.
  236. EOS
  237. newvalues(:tcp, :udp, :icmp, :"ipv6-icmp", :esp, :ah, :vrrp, :igmp, :ipencap, :ospf, :gre, :all)
  238. defaultto "tcp"
  239. end
  240. # tcp-specific
  241. newproperty(:tcp_flags, :required_features => :tcp_flags) do
  242. desc <<-EOS
  243. Match when the TCP flags are as specified.
  244. Is a string with a list of comma-separated flag names for the mask,
  245. then a space, then a comma-separated list of flags that should be set.
  246. The flags are: SYN ACK FIN RST URG PSH ALL NONE
  247. Note that you specify them in the order that iptables --list-rules
  248. would list them to avoid having puppet think you changed the flags.
  249. Example: FIN,SYN,RST,ACK SYN matches packets with the SYN bit set and the
  250. ACK,RST and FIN bits cleared. Such packets are used to request
  251. TCP connection initiation.
  252. EOS
  253. end
  254. # Iptables specific
  255. newproperty(:chain, :required_features => :iptables) do
  256. desc <<-EOS
  257. Name of the chain to use. Can be one of the built-ins:
  258. * INPUT
  259. * FORWARD
  260. * OUTPUT
  261. * PREROUTING
  262. * POSTROUTING
  263. Or you can provide a user-based chain.
  264. The default value is 'INPUT'.
  265. EOS
  266. defaultto "INPUT"
  267. newvalue(/^[a-zA-Z0-9\-_]+$/)
  268. end
  269. newproperty(:table, :required_features => :iptables) do
  270. desc <<-EOS
  271. Table to use. Can be one of:
  272. * nat
  273. * mangle
  274. * filter
  275. * raw
  276. * rawpost
  277. By default the setting is 'filter'.
  278. EOS
  279. newvalues(:nat, :mangle, :filter, :raw, :rawpost)
  280. defaultto "filter"
  281. end
  282. newproperty(:jump, :required_features => :iptables) do
  283. desc <<-EOS
  284. The value for the iptables --jump parameter. Normal values are:
  285. * QUEUE
  286. * RETURN
  287. * DNAT
  288. * SNAT
  289. * LOG
  290. * MASQUERADE
  291. * REDIRECT
  292. * MARK
  293. But any valid chain name is allowed.
  294. For the values ACCEPT, DROP and REJECT you must use the generic
  295. 'action' parameter. This is to enfore the use of generic parameters where
  296. possible for maximum cross-platform modelling.
  297. If you set both 'accept' and 'jump' parameters, you will get an error as
  298. only one of the options should be set.
  299. EOS
  300. validate do |value|
  301. unless value =~ /^[a-zA-Z0-9\-_]+$/
  302. raise ArgumentError, <<-EOS
  303. Jump destination must consist of alphanumeric characters, an
  304. underscore or a yphen.
  305. EOS
  306. end
  307. if ["accept","reject","drop"].include?(value.downcase)
  308. raise ArgumentError, <<-EOS
  309. Jump destination should not be one of ACCEPT, REJECT or DROP. Use
  310. the action property instead.
  311. EOS
  312. end
  313. end
  314. end
  315. # Interface specific matching properties
  316. newproperty(:iniface, :required_features => :interface_match) do
  317. desc <<-EOS
  318. Input interface to filter on.
  319. EOS
  320. newvalues(/^[a-zA-Z0-9\-\._\+]+$/)
  321. end
  322. newproperty(:outiface, :required_features => :interface_match) do
  323. desc <<-EOS
  324. Output interface to filter on.
  325. EOS
  326. newvalues(/^[a-zA-Z0-9\-\._\+]+$/)
  327. end
  328. # NAT specific properties
  329. newproperty(:tosource, :required_features => :snat) do
  330. desc <<-EOS
  331. When using jump => "SNAT" you can specify the new source address using
  332. this parameter.
  333. EOS
  334. end
  335. newproperty(:todest, :required_features => :dnat) do
  336. desc <<-EOS
  337. When using jump => "DNAT" you can specify the new destination address
  338. using this paramter.
  339. EOS
  340. end
  341. newproperty(:toports, :required_features => :dnat) do
  342. desc <<-EOS
  343. For DNAT this is the port that will replace the destination port.
  344. EOS
  345. end
  346. # Reject ICMP type
  347. newproperty(:reject, :required_features => :reject_type) do
  348. desc <<-EOS
  349. When combined with jump => "REJECT" you can specify a different icmp
  350. response to be sent back to the packet sender.
  351. EOS
  352. end
  353. # Logging properties
  354. newproperty(:log_level, :required_features => :log_level) do
  355. desc <<-EOS
  356. When combined with jump => "LOG" specifies the system log level to log
  357. to.
  358. EOS
  359. munge do |value|
  360. if value.kind_of?(String)
  361. value = @resource.log_level_name_to_number(value)
  362. else
  363. value
  364. end
  365. if value == nil && value != ""
  366. self.fail("Unable to determine log level")
  367. end
  368. value
  369. end
  370. end
  371. newproperty(:log_prefix, :required_features => :log_prefix) do
  372. desc <<-EOS
  373. When combined with jump => "LOG" specifies the log prefix to use when
  374. logging.
  375. EOS
  376. end
  377. # ICMP matching property
  378. newproperty(:icmp, :required_features => :icmp_match) do
  379. desc <<-EOS
  380. When matching ICMP packets, this is the type of ICMP packet to match.
  381. A value of "any" is not supported. To achieve this behaviour the
  382. parameter should simply be omitted or undefined.
  383. EOS
  384. validate do |value|
  385. if value == "any"
  386. raise ArgumentError,
  387. "Value 'any' is not valid. This behaviour should be achieved " \
  388. "by omitting or undefining the ICMP parameter."
  389. end
  390. end
  391. munge do |value|
  392. if value.kind_of?(String)
  393. # ICMP codes differ between IPv4 and IPv6.
  394. case @resource[:provider]
  395. when :iptables
  396. protocol = 'inet'
  397. when :ip6tables
  398. protocol = 'inet6'
  399. else
  400. self.fail("cannot work out protocol family")
  401. end
  402. value = @resource.icmp_name_to_number(value, protocol)
  403. else
  404. value
  405. end
  406. if value == nil && value != ""
  407. self.fail("cannot work out icmp type")
  408. end
  409. value
  410. end
  411. end
  412. newproperty(:state, :array_matching => :all, :required_features =>
  413. :state_match) do
  414. desc <<-EOS
  415. Matches a packet based on its state in the firewall stateful inspection
  416. table. Values can be:
  417. * INVALID
  418. * ESTABLISHED
  419. * NEW
  420. * RELATED
  421. EOS
  422. newvalues(:INVALID,:ESTABLISHED,:NEW,:RELATED)
  423. # States should always be sorted. This normalizes the resource states to
  424. # keep it consistent with the sorted result from iptables-save.
  425. def should=(values)
  426. @should = super(values).sort_by {|sym| sym.to_s}
  427. end
  428. def is_to_s(value)
  429. should_to_s(value)
  430. end
  431. def should_to_s(value)
  432. value = [value] unless value.is_a?(Array)
  433. value.join(',')
  434. end
  435. end
  436. # Rate limiting properties
  437. newproperty(:limit, :required_features => :rate_limiting) do
  438. desc <<-EOS
  439. Rate limiting value for matched packets. The format is:
  440. rate/[/second/|/minute|/hour|/day].
  441. Example values are: '50/sec', '40/min', '30/hour', '10/day'."
  442. EOS
  443. end
  444. newproperty(:burst, :required_features => :rate_limiting) do
  445. desc <<-EOS
  446. Rate limiting burst value (per second) before limit checks apply.
  447. EOS
  448. newvalue(/^\d+$/)
  449. end
  450. newproperty(:uid, :required_features => :owner) do
  451. desc <<-EOS
  452. UID or Username owner matching rule. Accepts a string argument
  453. only, as iptables does not accept multiple uid in a single
  454. statement.
  455. EOS
  456. end
  457. newproperty(:gid, :required_features => :owner) do
  458. desc <<-EOS
  459. GID or Group owner matching rule. Accepts a string argument
  460. only, as iptables does not accept multiple gid in a single
  461. statement.
  462. EOS
  463. end
  464. newproperty(:set_mark, :required_features => :mark) do
  465. desc <<-EOS
  466. Set the Netfilter mark value associated with the packet. Accepts either of:
  467. mark/mask or mark. These will be converted to hex if they are not already.
  468. EOS
  469. munge do |value|
  470. int_or_hex = '[a-fA-F0-9x]'
  471. match = value.to_s.match("(#{int_or_hex}+)(/)?(#{int_or_hex}+)?")
  472. mark = @resource.to_hex32(match[1])
  473. # Values that can't be converted to hex.
  474. # Or contain a trailing slash with no mask.
  475. if mark.nil? or (mark and match[2] and match[3].nil?)
  476. raise ArgumentError, "MARK value must be integer or hex between 0 and 0xffffffff"
  477. end
  478. # Old iptables does not support a mask. New iptables will expect one.
  479. iptables_version = Facter.fact('iptables_version').value
  480. mask_required = (iptables_version and Puppet::Util::Package.versioncmp(iptables_version, '1.4.1') >= 0)
  481. if mask_required
  482. if match[3].nil?
  483. value = "#{mark}/0xffffffff"
  484. else
  485. mask = @resource.to_hex32(match[3])
  486. if mask.nil?
  487. raise ArgumentError, "MARK mask must be integer or hex between 0 and 0xffffffff"
  488. end
  489. value = "#{mark}/#{mask}"
  490. end
  491. else
  492. unless match[3].nil?
  493. raise ArgumentError, "iptables version #{iptables_version} does not support masks on MARK rules"
  494. end
  495. value = mark
  496. end
  497. value
  498. end
  499. end
  500. newproperty(:pkttype, :required_features => :pkttype) do
  501. desc <<-EOS
  502. Sets the packet type to match.
  503. EOS
  504. newvalues(:unicast, :broadcast, :multicast)
  505. end
  506. newproperty(:isfragment, :required_features => :isfragment) do
  507. desc <<-EOS
  508. Set to true to match tcp fragments (requires type to be set to tcp)
  509. EOS
  510. newvalues(:true, :false)
  511. end
  512. newproperty(:socket, :required_features => :socket) do
  513. desc <<-EOS
  514. If true, matches if an open socket can be found by doing a coket lookup
  515. on the packet.
  516. EOS
  517. newvalues(:true, :false)
  518. end
  519. newparam(:line) do
  520. desc <<-EOS
  521. Read-only property for caching the rule line.
  522. EOS
  523. end
  524. autorequire(:firewallchain) do
  525. reqs = []
  526. protocol = nil
  527. case value(:provider)
  528. when :iptables
  529. protocol = "IPv4"
  530. when :ip6tables
  531. protocol = "IPv6"
  532. end
  533. unless protocol.nil?
  534. [value(:chain), value(:jump)].each do |chain|
  535. reqs << "#{chain}:#{value(:table)}:#{protocol}" unless chain.nil?
  536. end
  537. end
  538. reqs
  539. end
  540. # Classes would be a better abstraction, pending:
  541. # http://projects.puppetlabs.com/issues/19001
  542. autorequire(:package) do
  543. case value(:provider)
  544. when :iptables, :ip6tables
  545. %w{iptables iptables-persistent}
  546. else
  547. []
  548. end
  549. end
  550. validate do
  551. debug("[validate]")
  552. # TODO: this is put here to skip validation if ensure is not set. This
  553. # is because there is a revalidation stage called later where the values
  554. # are not set correctly. I tried tracing it - but have put in this
  555. # workaround instead to skip. Must get to the bottom of this.
  556. if ! value(:ensure)
  557. return
  558. end
  559. # First we make sure the chains and tables are valid combinations
  560. if value(:table).to_s == "filter" &&
  561. value(:chain) =~ /PREROUTING|POSTROUTING/
  562. self.fail "PREROUTING and POSTROUTING cannot be used in table 'filter'"
  563. end
  564. if value(:table).to_s == "nat" && value(:chain) =~ /INPUT|FORWARD/
  565. self.fail "INPUT and FORWARD cannot be used in table 'nat'"
  566. end
  567. if value(:table).to_s == "raw" &&
  568. value(:chain) =~ /INPUT|FORWARD|POSTROUTING/
  569. self.fail "INPUT, FORWARD and POSTROUTING cannot be used in table raw"
  570. end
  571. # Now we analyse the individual properties to make sure they apply to
  572. # the correct combinations.
  573. if value(:iniface)
  574. unless value(:chain).to_s =~ /INPUT|FORWARD|PREROUTING/
  575. self.fail "Parameter iniface only applies to chains " \
  576. "INPUT,FORWARD,PREROUTING"
  577. end
  578. end
  579. if value(:outiface)
  580. unless value(:chain).to_s =~ /OUTPUT|FORWARD|POSTROUTING/
  581. self.fail "Parameter outiface only applies to chains " \
  582. "OUTPUT,FORWARD,POSTROUTING"
  583. end
  584. end
  585. if value(:uid)
  586. unless value(:chain).to_s =~ /OUTPUT|POSTROUTING/
  587. self.fail "Parameter uid only applies to chains " \
  588. "OUTPUT,POSTROUTING"
  589. end
  590. end
  591. if value(:gid)
  592. unless value(:chain).to_s =~ /OUTPUT|POSTROUTING/
  593. self.fail "Parameter gid only applies to chains " \
  594. "OUTPUT,POSTROUTING"
  595. end
  596. end
  597. if value(:set_mark)
  598. unless value(:jump).to_s =~ /MARK/ &&
  599. value(:chain).to_s =~ /PREROUTING|OUTPUT/ &&
  600. value(:table).to_s =~ /mangle/
  601. self.fail "Parameter set_mark only applies to " \
  602. "the PREROUTING or OUTPUT chain of the mangle table and when jump => MARK"
  603. end
  604. end
  605. if value(:dport)
  606. unless value(:proto).to_s =~ /tcp|udp|sctp/
  607. self.fail "[%s] Parameter dport only applies to sctp, tcp and udp " \
  608. "protocols. Current protocol is [%s] and dport is [%s]" %
  609. [value(:name), should(:proto), should(:dport)]
  610. end
  611. end
  612. if value(:jump).to_s == "DNAT"
  613. unless value(:table).to_s =~ /nat/
  614. self.fail "Parameter jump => DNAT only applies to table => nat"
  615. end
  616. unless value(:todest)
  617. self.fail "Parameter jump => DNAT must have todest parameter"
  618. end
  619. end
  620. if value(:jump).to_s == "SNAT"
  621. unless value(:table).to_s =~ /nat/
  622. self.fail "Parameter jump => SNAT only applies to table => nat"
  623. end
  624. unless value(:tosource)
  625. self.fail "Parameter jump => DNAT must have tosource parameter"
  626. end
  627. end
  628. if value(:jump).to_s == "REDIRECT"
  629. unless value(:toports)
  630. self.fail "Parameter jump => REDIRECT missing mandatory toports " \
  631. "parameter"
  632. end
  633. end
  634. if value(:jump).to_s == "MASQUERADE"
  635. unless value(:table).to_s =~ /nat/
  636. self.fail "Parameter jump => MASQUERADE only applies to table => nat"
  637. end
  638. end
  639. if value(:log_prefix) || value(:log_level)
  640. unless value(:jump).to_s == "LOG"
  641. self.fail "Parameter log_prefix and log_level require jump => LOG"
  642. end
  643. end
  644. if value(:burst) && ! value(:limit)
  645. self.fail "burst makes no sense without limit"
  646. end
  647. if value(:action) && value(:jump)
  648. self.fail "Only one of the parameters 'action' and 'jump' can be set"
  649. end
  650. end
  651. end