Puppet::Type.newtype(:firewall) do
include Puppet::Util::Firewall
- @doc = "Manipulate firewall rules"
+ @doc = "This type provides the capability to manage firewall rules within
+ puppet."
+
+ feature :rate_limiting, "Rate limiting features."
+ feature :snat, "Source NATing"
+ feature :dnat, "Destination NATing"
+ feature :interface_match, "Interface matching"
+ feature :icmp_match, "Matching ICMP types"
+ feature :state_match, "Matching stateful firewall states"
+ feature :reject_type, "The ability to control reject messages"
+ feature :log_level, "The ability to control the log level"
+ feature :log_prefix, "The ability to add prefixes to log messages"
+
+ # provider specific features
+ feature :iptables, "The provider provides iptables features."
ensurable do
- desc "Create or remove this rule."
+ desc "Manage the state of this rule."
newvalue(:present) do
+ desc "Ensure the rule is present"
provider.insert
end
newvalue(:absent) do
+ desc "Ensure the rule is absent"
provider.delete
end
end
newparam(:name) do
- desc "The name of the rule."
+ desc "The canonical name of the rule."
isnamevar
- # Keep rule names simple
- validate do |value|
- if value !~ /[a-zA-Z0-9 \-_]+/
- self.fail "Not a valid rule name. Make sure it contains ASCII " \
- "alphanumeric, spaces, hyphens or underscores."
- end
-
- if value !~ /^\d+/
- self.fail 'Not a valid rule name. Rules names must start with a digit'
- end
- end
- end
-
- newproperty(:chain) do
- desc "The value for the iptables -A parameter.
- Possible values are: 'INPUT', 'FORWARD', 'OUTPUT', 'PREROUTING', 'POSTROUTING'.
- Default value is 'INPUT'"
- newvalues(:INPUT, :FORWARD, :OUTPUT, :PREROUTING, :POSTROUTING)
- defaultto "INPUT"
- end
-
- newproperty(:table) do
- desc "The value for the iptables -t parameter.
- Possible values are: 'nat', 'mangle', 'filter' and 'raw'.
- Default value is 'filter'"
- newvalues(:nat, :mangle, :filter, :raw)
- defaultto "filter"
- end
-
- newproperty(:proto) do
- desc "The value for the iptables --protocol parameter.
- Possible values are: 'tcp', 'udp', 'icmp', 'esp', 'ah', 'vrrp',
- 'igmp', 'all'.
- Default value is 'tcp'"
- newvalues(:tcp, :udp, :icmp, :esp, :ah, :vrrp, :igmp, :all)
- defaultto "tcp"
- end
-
- newproperty(:jump) do
- desc "The value for the iptables --jump parameter.
- Possible values are: 'ACCEPT', 'DROP', 'QUEUE', 'RETURN',
- REJECT', 'DNAT', 'SNAT', 'LOG', 'MASQUERADE', 'REDIRECT'.
- Default value is 'ACCEPT'"
- newvalues(:ACCEPT, :DROP, :QUEUE, :RETURN, :REJECT, :DNAT, :SNAT, :LOG,
- :MASQUERADE, :REDIRECT)
- defaultto "ACCEPT"
+ # Keep rule names simple - they must start with a number
+ newvalues(/^\d+[a-zA-Z0-9\s\-_]+$/)
end
+ # Generic matching properties
newproperty(:source, :array_matching => :all) do
- desc "The value for the iptables --source parameter.
- Accepts a single string or array."
+ desc "The source IP address to match. Accepts a string or array."
def should_to_s(value)
value = [value] unless value.is_a?(Array)
end
newproperty(:destination, :array_matching => :all) do
- desc "The value for the iptables --destination parameter.
- Accepts a single string or array."
+ desc "The destination IP address to match. Accepts a string or array."
def should_to_s(value)
value = [value] unless value.is_a?(Array)
end
newproperty(:sport, :array_matching => :all) do
- desc "The value for the iptables --source-port parameter.
- If an array is specified, values will be passed to multiport module."
+ desc "The source port to match for this filter (if the protocol supports
+ ports). Will accept a single element or an array."
munge do |value|
@resource.string_to_port(value)
end
newproperty(:dport, :array_matching => :all) do
- desc "The value for the iptables --destination-port parameter.
- If an array is specified, values will be passed to multiport module."
+ desc "The destination port to match for this filter (if the protocol
+ supports ports). Will accept a single element or an array."
munge do |value|
@resource.string_to_port(value)
end
end
- newproperty(:iniface) do
- desc "The value for the iptables --in-interface parameter"
+ newproperty(:proto) do
+ desc "The specific protocol to match for this rule."
+ newvalues(:tcp, :udp, :icmp, :esp, :ah, :vrrp, :igmp, :all)
+ defaultto "tcp"
+ end
+
+ # Iptables specific
+ newproperty(:chain, :required_features => :iptables) do
+ desc "The value for the iptables -A parameter. Normal values are: 'INPUT',
+ 'FORWARD', 'OUTPUT', 'PREROUTING', 'POSTROUTING' but you can also
+ specify a user created chain."
+
+ defaultto "INPUT"
+ newvalue(/^[a-zA-Z0-9\-_]+$/)
+ end
+
+ newproperty(:table, :required_features => :iptables) do
+ desc "The value for the iptables -t parameter."
+ newvalues(:nat, :mangle, :filter, :raw, :rawpost)
+ defaultto "filter"
end
- newproperty(:outiface) do
- desc "The value for the iptables --out-interface parameter"
+ newproperty(:jump, :required_features => :iptables) do
+ desc "The value for the iptables --jump parameter. Normal values are:
+ 'ACCEPT', 'DROP', 'QUEUE', 'RETURN', REJECT', 'DNAT', 'SNAT', 'LOG',
+ 'MASQUERADE', 'REDIRECT'. But any valid chain name is allowed."
+ newvalues(/^[a-zA-Z0-9\-_]+$/)
+ defaultto "ACCEPT"
+ end
+
+ # Interface specific matching properties
+ newproperty(:iniface, :required_features => :interface_match) do
+ desc "Match input interface."
+ newvalues(/^[a-zA-Z0-9\-_]+$/)
+ end
+
+ newproperty(:outiface, :required_features => :interface_match) do
+ desc "Match ouput interface."
+ newvalues(/^[a-zA-Z0-9\-_]+$/)
end
- newproperty(:tosource) do
- desc "The value for the iptables --to-source parameter"
+ # NAT specific properties
+ newproperty(:tosource, :required_features => :snat) do
+ desc "For SNAT this is the IP address that will replace the source IP
+ address."
end
- newproperty(:todest) do
- desc "The value for the iptables --to-destination parameter"
+ newproperty(:todest, :required_features => :dnat) do
+ desc "For DNAT this is the IP address that will replace the destination IP
+ address."
end
- newproperty(:toports) do
- desc "The value for the iptables --to-ports parameter"
+ newproperty(:toports, :required_features => :dnat) do
+ desc "For DNAT this is the port that will replace the destination port."
end
- newproperty(:reject) do
- desc "The value for the iptables --reject-with parameter"
+ # Reject ICMP type
+ newproperty(:reject, :required_features => :reject_type) do
+ desc "The ICMP response to reject a packet with."
end
- newproperty(:log_level) do
- desc "The value for the iptables --log-level parameter"
+ # Logging properties
+ newproperty(:log_level, :required_features => :log_level) do
+ desc "The syslog level to log to."
end
- newproperty(:log_prefix) do
- desc "The value for the iptables --log-level parameter"
+ newproperty(:log_prefix, :required_features => :log_prefix) do
+ desc "The syslog prefix."
end
- newproperty(:icmp) do
- desc "The value for the iptables --icmp-type parameter"
+ # ICMP matching property
+ newproperty(:icmp, :required_features => :icmp_match) do
+ desc "When matching ICMP packets, this is the type of ICMP packet to match."
munge do |value|
if value.kind_of?(String)
end
end
- newproperty(:state, :array_matching => :all) do
- desc "The value for the iptables -m state --state parameter.
- Possible values are: 'INVALID', 'ESTABLISHED', 'NEW', 'RELATED'.
- Accepts a single string or array."
+ newproperty(:state, :array_matching => :all, :required_features => :state_match) do
+ desc "Matches a packet based on its state in the firewall stateful inspection
+ table."
+
+ newvalues(:INVALID,:ESTABLISHED,:NEW,:RELATED)
def should_to_s(value)
value = [value] unless value.is_a?(Array)
end
end
- newproperty(:limit) do
- desc "The value for the iptables -m limit --limit parameter.
- Example values are: '50/sec', '40/min', '30/hour', '10/day'."
+ # Rate limiting properties
+ newproperty(:limit, :required_features => :rate_limiting) do
+ desc "Rate limiting value. Example values are: '50/sec', '40/min',
+ '30/hour', '10/day'."
end
- newproperty(:burst) do
- desc "The value for the iptables --limit-burst parameter."
-
- validate do |value|
- if value.to_s !~ /^[0-9]+$/
- self.fail "burst accepts only numeric values"
- end
- end
+ newproperty(:burst, :required_features => :rate_limiting) do
+ desc "Rate limiting burst value (per second)."
+ newvalue(/^\d+$/)
end
validate do