* `physdev_out`: Match if the packet is leaving a bridge via the given interface. Values must match '/^[a-zA-Z0-9\-\._\+]+$/'.
+* `physdev_is_bridged`: Match if the packet is transversing a bridge. Valid values are true or false.
+
* `pkttype`: Sets the packet type to match. Valid values are: 'unicast', 'broadcast', and'multicast'. Requires the `pkttype` feature.
* `port`: The destination or source port to match for this filter (if the protocol supports ports). Will accept a single element or an array. For some firewall providers you can pass a range of ports in the format: 'start number-end number'. For example, '1-1024' would cover ports 1 to 1024.
@protocol = "IPv6"
@resource_map = {
- :burst => "--limit-burst",
- :connlimit_above => "-m connlimit --connlimit-above",
- :connlimit_mask => "--connlimit-mask",
- :connmark => "-m connmark --mark",
- :ctstate => "-m conntrack --ctstate",
- :destination => "-d",
- :dport => ["-m multiport --dports", "--dport"],
- :dst_range => '-m iprange --dst-range',
- :dst_type => "-m addrtype --dst-type",
- :gid => "-m owner --gid-owner",
- :hop_limit => "-m hl --hl-eq",
- :icmp => "-m icmp6 --icmpv6-type",
- :iniface => "-i",
- :ipsec_dir => "-m policy --dir",
- :ipsec_policy => "--pol",
- :ipset => "-m set --match-set",
- :isfirstfrag => "-m frag --fragid 0 --fragfirst",
- :ishasmorefrags => "-m frag --fragid 0 --fragmore",
- :islastfrag => "-m frag --fragid 0 --fraglast",
- :jump => "-j",
- :limit => "-m limit --limit",
- :log_level => "--log-level",
- :log_prefix => "--log-prefix",
- :mask => "--mask",
- :name => "-m comment --comment",
- :mac_source => ["-m mac --mac-source", "--mac-source"],
- :outiface => "-o",
- :pkttype => "-m pkttype --pkt-type",
- :port => '-m multiport --ports',
- :proto => "-p",
- :rdest => "--rdest",
- :reap => "--reap",
- :recent => "-m recent",
- :reject => "--reject-with",
- :rhitcount => "--hitcount",
- :rname => "--name",
- :rseconds => "--seconds",
- :rsource => "--rsource",
- :rttl => "--rttl",
- :set_mark => mark_flag,
- :socket => "-m socket",
- :source => "-s",
- :sport => ["-m multiport --sports", "--sport"],
- :src_range => '-m iprange --src-range',
- :src_type => "-m addrtype --src-type",
- :stat_every => '--every',
- :stat_mode => "-m statistic --mode",
- :stat_packet => '--packet',
- :stat_probability => '--probability',
- :state => "-m state --state",
- :table => "-t",
- :tcp_flags => "-m tcp --tcp-flags",
- :todest => "--to-destination",
- :toports => "--to-ports",
- :tosource => "--to-source",
- :uid => "-m owner --uid-owner",
- :physdev_in => "-m physdev --physdev-in",
- :physdev_out => "-m physdev --physdev-out",
+ :burst => "--limit-burst",
+ :connlimit_above => "-m connlimit --connlimit-above",
+ :connlimit_mask => "--connlimit-mask",
+ :connmark => "-m connmark --mark",
+ :ctstate => "-m conntrack --ctstate",
+ :destination => "-d",
+ :dport => ["-m multiport --dports", "--dport"],
+ :dst_range => '-m iprange --dst-range',
+ :dst_type => "-m addrtype --dst-type",
+ :gid => "-m owner --gid-owner",
+ :hop_limit => "-m hl --hl-eq",
+ :icmp => "-m icmp6 --icmpv6-type",
+ :iniface => "-i",
+ :ipsec_dir => "-m policy --dir",
+ :ipsec_policy => "--pol",
+ :ipset => "-m set --match-set",
+ :isfirstfrag => "-m frag --fragid 0 --fragfirst",
+ :ishasmorefrags => "-m frag --fragid 0 --fragmore",
+ :islastfrag => "-m frag --fragid 0 --fraglast",
+ :jump => "-j",
+ :limit => "-m limit --limit",
+ :log_level => "--log-level",
+ :log_prefix => "--log-prefix",
+ :mask => "--mask",
+ :name => "-m comment --comment",
+ :mac_source => ["-m mac --mac-source", "--mac-source"],
+ :outiface => "-o",
+ :pkttype => "-m pkttype --pkt-type",
+ :port => '-m multiport --ports',
+ :proto => "-p",
+ :rdest => "--rdest",
+ :reap => "--reap",
+ :recent => "-m recent",
+ :reject => "--reject-with",
+ :rhitcount => "--hitcount",
+ :rname => "--name",
+ :rseconds => "--seconds",
+ :rsource => "--rsource",
+ :rttl => "--rttl",
+ :set_mark => mark_flag,
+ :socket => "-m socket",
+ :source => "-s",
+ :sport => ["-m multiport --sports", "--sport"],
+ :src_range => '-m iprange --src-range',
+ :src_type => "-m addrtype --src-type",
+ :stat_every => '--every',
+ :stat_mode => "-m statistic --mode",
+ :stat_packet => '--packet',
+ :stat_probability => '--probability',
+ :state => "-m state --state",
+ :table => "-t",
+ :tcp_flags => "-m tcp --tcp-flags",
+ :todest => "--to-destination",
+ :toports => "--to-ports",
+ :tosource => "--to-source",
+ :uid => "-m owner --uid-owner",
+ :physdev_in => "-m physdev --physdev-in",
+ :physdev_out => "-m physdev --physdev-out",
+ :physdev_is_bridged => "-m physdev --physdev-is-bridged"
}
# These are known booleans that do not take a value, but we want to munge
:rdest,
:reap,
:rttl,
- :socket
+ :socket,
+ :physdev_is_bridged
]
# Create property methods dynamically
# I put it when calling the command. So compability with manual changes
# not provided with current parser [georg.koester])
@resource_list = [:table, :source, :destination, :iniface, :outiface, :physdev_in,
- :physdev_out, :proto, :ishasmorefrags, :islastfrag, :isfirstfrag, :src_range, :dst_range,
+ :physdev_out, :physdev_is_bridged, :proto, :ishasmorefrags, :islastfrag, :isfirstfrag, :src_range, :dst_range,
:tcp_flags, :gid, :uid, :mac_source, :sport, :dport, :port, :dst_type,
:src_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy, :state,
:ctstate, :icmp, :hop_limit, :limit, :burst, :recent, :rseconds, :reap,
@protocol = "IPv4"
@resource_map = {
- :burst => "--limit-burst",
- :connlimit_above => "-m connlimit --connlimit-above",
- :connlimit_mask => "--connlimit-mask",
- :connmark => "-m connmark --mark",
- :ctstate => "-m conntrack --ctstate",
- :destination => "-d",
- :dport => ["-m multiport --dports", "--dport"],
- :dst_range => "-m iprange --dst-range",
- :dst_type => "-m addrtype --dst-type",
- :gid => "-m owner --gid-owner",
- :icmp => "-m icmp --icmp-type",
- :iniface => "-i",
- :ipsec_dir => "-m policy --dir",
- :ipsec_policy => "--pol",
- :ipset => "-m set --match-set",
- :isfragment => "-f",
- :jump => "-j",
- :limit => "-m limit --limit",
- :log_level => "--log-level",
- :log_prefix => "--log-prefix",
- :mac_source => ["-m mac --mac-source", "--mac-source"],
- :mask => '--mask',
- :name => "-m comment --comment",
- :outiface => "-o",
- :pkttype => "-m pkttype --pkt-type",
- :port => '-m multiport --ports',
- :proto => "-p",
- :random => "--random",
- :rdest => "--rdest",
- :reap => "--reap",
- :recent => "-m recent",
- :reject => "--reject-with",
- :rhitcount => "--hitcount",
- :rname => "--name",
- :rseconds => "--seconds",
- :rsource => "--rsource",
- :rttl => "--rttl",
- :set_mark => mark_flag,
- :socket => "-m socket",
- :source => "-s",
- :sport => ["-m multiport --sports", "--sport"],
- :src_range => "-m iprange --src-range",
- :src_type => "-m addrtype --src-type",
- :stat_every => '--every',
- :stat_mode => "-m statistic --mode",
- :stat_packet => '--packet',
- :stat_probability => '--probability',
- :state => "-m state --state",
- :table => "-t",
- :tcp_flags => "-m tcp --tcp-flags",
- :todest => "--to-destination",
- :toports => "--to-ports",
- :tosource => "--to-source",
- :to => "--to",
- :uid => "-m owner --uid-owner",
- :physdev_in => "-m physdev --physdev-in",
- :physdev_out => "-m physdev --physdev-out",
+ :burst => "--limit-burst",
+ :connlimit_above => "-m connlimit --connlimit-above",
+ :connlimit_mask => "--connlimit-mask",
+ :connmark => "-m connmark --mark",
+ :ctstate => "-m conntrack --ctstate",
+ :destination => "-d",
+ :dport => ["-m multiport --dports", "--dport"],
+ :dst_range => "-m iprange --dst-range",
+ :dst_type => "-m addrtype --dst-type",
+ :gid => "-m owner --gid-owner",
+ :icmp => "-m icmp --icmp-type",
+ :iniface => "-i",
+ :ipsec_dir => "-m policy --dir",
+ :ipsec_policy => "--pol",
+ :ipset => "-m set --match-set",
+ :isfragment => "-f",
+ :jump => "-j",
+ :limit => "-m limit --limit",
+ :log_level => "--log-level",
+ :log_prefix => "--log-prefix",
+ :mac_source => ["-m mac --mac-source", "--mac-source"],
+ :mask => '--mask',
+ :name => "-m comment --comment",
+ :outiface => "-o",
+ :pkttype => "-m pkttype --pkt-type",
+ :port => '-m multiport --ports',
+ :proto => "-p",
+ :random => "--random",
+ :rdest => "--rdest",
+ :reap => "--reap",
+ :recent => "-m recent",
+ :reject => "--reject-with",
+ :rhitcount => "--hitcount",
+ :rname => "--name",
+ :rseconds => "--seconds",
+ :rsource => "--rsource",
+ :rttl => "--rttl",
+ :set_mark => mark_flag,
+ :socket => "-m socket",
+ :source => "-s",
+ :sport => ["-m multiport --sports", "--sport"],
+ :src_range => "-m iprange --src-range",
+ :src_type => "-m addrtype --src-type",
+ :stat_every => '--every',
+ :stat_mode => "-m statistic --mode",
+ :stat_packet => '--packet',
+ :stat_probability => '--probability',
+ :state => "-m state --state",
+ :table => "-t",
+ :tcp_flags => "-m tcp --tcp-flags",
+ :todest => "--to-destination",
+ :toports => "--to-ports",
+ :tosource => "--to-source",
+ :to => "--to",
+ :uid => "-m owner --uid-owner",
+ :physdev_in => "-m physdev --physdev-in",
+ :physdev_out => "-m physdev --physdev-out",
+ :physdev_is_bridged => "-m physdev --physdev-is-bridged"
}
# These are known booleans that do not take a value, but we want to munge
:reap,
:rsource,
:rttl,
- :socket
+ :socket,
+ :physdev_is_bridged
]
# changes between puppet runs, the changed rules will be re-applied again.
# This order can be determined by going through iptables source code or just tweaking and trying manually
@resource_list = [
- :table, :source, :destination, :iniface, :outiface, :physdev_in, :physdev_out, :proto, :isfragment,
+ :table, :source, :destination, :iniface, :outiface, :physdev_in, :physdev_out, :physdev_is_bridged, :proto, :isfragment,
:stat_mode, :stat_every, :stat_packet, :stat_probability,
:src_range, :dst_range, :tcp_flags, :gid, :uid, :mac_source, :sport, :dport, :port,
:dst_type, :src_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy,
'--pol "ipsec\1\2\3\4\5\6\7\8" '
)
+ # Handle resource_map values depending on whether physdev-in, physdev-out, ,physdev-is-bridged, or all three are specified
+ if values.include? "--physdev-in"
+ @resource_map[:physdev_in] = "-m physdev --physdev-in"
+ @resource_map[:physdev_out] = "--physdev-out"
+ @resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
+ elsif values.include? "--physdev-out"
+ @resource_map[:physdev_out] = "-m physdev --physdev-out"
+ @resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
+ else
+ @resource_map[:physdev_is_bridged] = "-m physdev --physdev-is-bridged"
+ end
+
# Trick the system for booleans
@known_booleans.each do |bool|
# append "true" because all params are expected to have values
end
end
- # Handle resource_map values depending on whether physdev-in, physdev-out, or both are specified
- if values.include? "--physdev-in" and values.include? "--physdev-out" then
- #values = values.sub("--physdev-out","-m physdev --physdev-out")
- @resource_map[:physdev_out] = "--physdev-out"
- else
- @resource_map[:physdev_out] = "-m physdev --physdev-out"
- end
-
############
# Populate parser_list with used value, in the correct order
############
resource_map = self.class.instance_variable_get('@resource_map')
known_booleans = self.class.instance_variable_get('@known_booleans')
- # Handle physdev args depending on whether physdev-in, physdev-out, or both are specified
+ # Handle physdev args depending on whether physdev-in, physdev-out, physdev-is-bridged, or all three are specified
if (resource[:physdev_in])
+ resource_map[:physdev_in] = "-m physdev --physdev-in"
resource_map[:physdev_out] = "--physdev-out"
- else
+ resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
+ elsif (resource[:physdev_out])
resource_map[:physdev_out] = "-m physdev --physdev-out"
+ resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
+ else
+ resource_map[:physdev_is_bridged] = "-m physdev --physdev-is-bridged"
end
resource_list.each do |res|
newvalues(/^[a-zA-Z0-9\-\._\+]+$/)
end
+ newproperty(:physdev_is_bridged, :required_features => :iptables) do
+ desc <<-EOS
+ Match if the packet is transversing a bridge.
+ EOS
+ newvalues(:true, :false)
+ end
+
autorequire(:firewallchain) do
reqs = []
protocol = nil
end
end
end
+
+ context 'physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '704 - test':
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '704',
+ action => accept,
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('iptables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-is-bridged -m multiport --ports 704 -m comment --comment "704 - test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'physdev_in eth0 and physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '705 - test':
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '705',
+ action => accept,
+ physdev_in => 'eth0',
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('iptables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-is-bridged -m multiport --ports 705 -m comment --comment "705 - test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'physdev_out eth1 and physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '706 - test':
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '706',
+ action => accept,
+ physdev_out => 'eth1',
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('iptables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m multiport --ports 706 -m comment --comment "706 - test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'physdev_in eth0 and physdev_out eth1 and physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '707 - test':
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '707',
+ action => accept,
+ physdev_in => 'eth0',
+ physdev_out => 'eth1',
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('iptables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m multiport --ports 707 -m comment --comment "707 - test" -j ACCEPT/)
+ end
+ end
+ end
+
end
#iptables version 1.3.5 is not suppored by the ip6tables provider
end
end
end
+
+ context 'physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '704 - test':
+ provider => 'ip6tables',
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '704',
+ action => accept,
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('ip6tables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-is-bridged -m multiport --ports 704 -m comment --comment "704 - test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'physdev_in eth0 and physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '705 - test':
+ provider => 'ip6tables',
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '705',
+ action => accept,
+ physdev_in => 'eth0',
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('ip6tables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-is-bridged -m multiport --ports 705 -m comment --comment "705 - test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'physdev_out eth1 and physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '706 - test':
+ provider => 'ip6tables',
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '706',
+ action => accept,
+ physdev_out => 'eth1',
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('ip6tables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m multiport --ports 706 -m comment --comment "706 - test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'physdev_in eth0 and physdev_out eth1 and physdev_is_bridged' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '707 - test':
+ provider => 'ip6tables',
+ chain => 'FORWARD',
+ proto => tcp,
+ port => '707',
+ action => accept,
+ physdev_in => 'eth0',
+ physdev_out => 'eth1',
+ physdev_is_bridged => true,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ unless fact('selinux') == 'true'
+ apply_manifest(pp, :catch_changes => true)
+ end
+ end
+
+ it 'should contain the rule' do
+ shell('ip6tables-save') do |r|
+ expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m multiport --ports 707 -m comment --comment "707 - test" -j ACCEPT/)
+ end
+ end
+ end
end
end