Skip to content

Commit 948a76c

Browse files
committed
Added support for seperate physdev-in and physdev-out parameters.
1 parent 9b70d0b commit 948a76c

5 files changed

Lines changed: 216 additions & 22 deletions

File tree

README.markdown

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,12 @@ This type enables you to manage firewall rules within Puppet.
339339

340340
* `ip6tables`: Ip6tables type provider
341341
* Required binaries: `ip6tables-save`, `ip6tables`.
342-
* Supported features: `connection_limiting`, `dnat`, `hop_limiting`, `icmp_match`, `interface_match`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfirstfrag`, `ishasmorefrags`, `islastfrag`, `log_level`, `log_prefix`, `mark`, `mask`, `owner`, `pkttype`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `tcp_flags`.
342+
* Supported features: `connection_limiting`, `dnat`, `hop_limiting`, `icmp_match`, `interface_match`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfirstfrag`, `ishasmorefrags`, `islastfrag`, `log_level`, `log_prefix`, `mark`, `mask`, `owner`, `physdev_in`, `physdev_out`, `pkttype`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `tcp_flags`.
343343

344344
* `iptables`: Iptables type provider
345345
* Required binaries: `iptables-save`, `iptables`.
346346
* Default for `kernel` == `linux`.
347-
* Supported features: `address_type`, `connection_limiting`, `dnat`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfragment`, `log_level`, `log_prefix`, `mark`, `mask`, `owner`, `pkttype`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `tcp_flags`, `netmap`.
347+
* Supported features: `address_type`, `connection_limiting`, `dnat`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfragment`, `log_level`, `log_prefix`, `mark`, `mask`, `owner`, `physdev_in`, `physdev_out`, `pkttype`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `tcp_flags`, `netmap`.
348348

349349
**Autorequires:**
350350

lib/puppet/provider/firewall/ip6tables.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ def self.iptables_save(*args)
119119
:toports => "--to-ports",
120120
:tosource => "--to-source",
121121
:uid => "-m owner --uid-owner",
122-
:bridge => "-m physdev",
122+
:physdev_in => "-m physdev --physdev-in",
123+
:physdev_out => "-m physdev --physdev-out",
123124
}
124125

125126
# These are known booleans that do not take a value, but we want to munge
@@ -169,8 +170,8 @@ def self.iptables_save(*args)
169170
# (Note: on my CentOS 6.4 ip6tables-save returns -m frag on the place
170171
# I put it when calling the command. So compability with manual changes
171172
# not provided with current parser [georg.koester])
172-
@resource_list = [:table, :source, :destination, :iniface, :outiface,
173-
:proto, :ishasmorefrags, :islastfrag, :isfirstfrag, :src_range, :dst_range,
173+
@resource_list = [:table, :source, :destination, :iniface, :outiface, :physdev_in,
174+
:physdev_out, :proto, :ishasmorefrags, :islastfrag, :isfirstfrag, :src_range, :dst_range,
174175
:tcp_flags, :gid, :uid, :mac_source, :sport, :dport, :port, :dst_type,
175176
:src_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy, :state,
176177
:ctstate, :icmp, :hop_limit, :limit, :burst, :recent, :rseconds, :reap,

lib/puppet/provider/firewall/iptables.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@
105105
:tosource => "--to-source",
106106
:to => "--to",
107107
:uid => "-m owner --uid-owner",
108-
:bridge => "-m physdev",
108+
:physdev_in => "-m physdev --physdev-in",
109+
:physdev_out => "-m physdev --physdev-out",
109110
}
110111

111112
# These are known booleans that do not take a value, but we want to munge
@@ -153,7 +154,7 @@
153154
# changes between puppet runs, the changed rules will be re-applied again.
154155
# This order can be determined by going through iptables source code or just tweaking and trying manually
155156
@resource_list = [
156-
:table, :source, :destination, :iniface, :outiface, :proto, :isfragment,
157+
:table, :source, :destination, :iniface, :outiface, :physdev_in, :physdev_out, :proto, :isfragment,
157158
:stat_mode, :stat_every, :stat_packet, :stat_probability,
158159
:src_range, :dst_range, :tcp_flags, :gid, :uid, :mac_source, :sport, :dport, :port,
159160
:dst_type, :src_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy,
@@ -262,6 +263,14 @@ def self.rule_to_hash(line, table, counter)
262263
end
263264
end
264265

266+
# Handle resource_map values depending on whether physdev-in, physdev-out, or both are specified
267+
if values.include? "--physdev-in" and values.include? "--physdev-out" then
268+
#values = values.sub("--physdev-out","-m physdev --physdev-out")
269+
@resource_map[:physdev_out] = "--physdev-out"
270+
else
271+
@resource_map[:physdev_out] = "-m physdev --physdev-out"
272+
end
273+
265274
############
266275
# Populate parser_list with used value, in the correct order
267276
############
@@ -443,6 +452,13 @@ def general_args
443452
resource_map = self.class.instance_variable_get('@resource_map')
444453
known_booleans = self.class.instance_variable_get('@known_booleans')
445454

455+
# Handle physdev args depending on whether physdev-in, physdev-out, or both are specified
456+
if (resource[:physdev_in])
457+
resource_map[:physdev_out] = "--physdev-out"
458+
else
459+
resource_map[:physdev_out] = "-m physdev --physdev-out"
460+
end
461+
446462
resource_list.each do |res|
447463
resource_value = nil
448464
if (resource[res]) then

lib/puppet/type/firewall.rb

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,17 +1033,18 @@ def should_to_s(value)
10331033
newvalues(/^([0-9a-f]{2}[:]){5}([0-9a-f]{2})$/i)
10341034
end
10351035

1036-
newproperty(:bridge, :required_features => :iptables) do
1036+
newproperty(:physdev_in, :required_features => :iptables) do
10371037
desc <<-EOS
1038-
Match if the packet is being bridged.
1038+
Match if the packet is entering a bridge from the given interface.
10391039
EOS
1040-
munge do |value|
1041-
if ! value.to_s.start_with?("--")
1042-
"--" + value.to_s
1043-
else
1044-
value
1045-
end
1046-
end
1040+
newvalues(/^[a-zA-Z0-9\-\._\+]+$/)
1041+
end
1042+
1043+
newproperty(:physdev_out, :required_features => :iptables) do
1044+
desc <<-EOS
1045+
Match if the packet is leaving a bridge via the given interface.
1046+
EOS
1047+
newvalues(/^[a-zA-Z0-9\-\._\+]+$/)
10471048
end
10481049

10491050
autorequire(:firewallchain) do
@@ -1204,11 +1205,5 @@ def should_to_s(value)
12041205
self.fail "Parameter 'stat_probability' requires 'stat_mode' to be set to 'random'"
12051206
end
12061207

1207-
if value(:bridge)
1208-
unless value(:chain).to_s =~ /FORWARD/
1209-
self.fail "Parameter bridge only applies to the FORWARD chain"
1210-
end
1211-
end
1212-
12131208
end
12141209
end
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
require 'spec_helper_acceptance'
2+
3+
describe 'firewall type', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do
4+
5+
describe 'reset' do
6+
it 'deletes all iptables rules' do
7+
shell('iptables --flush; iptables -t nat --flush; iptables -t mangle --flush')
8+
end
9+
it 'deletes all ip6tables rules' do
10+
shell('ip6tables --flush; ip6tables -t nat --flush; ip6tables -t mangle --flush')
11+
end
12+
end
13+
14+
describe 'iptables physdev tests' do
15+
context 'physdev_in eth0' do
16+
it 'applies' do
17+
pp = <<-EOS
18+
class { '::firewall': }
19+
firewall { '701 - test':
20+
chain => 'FORWARD',
21+
proto => tcp,
22+
port => '701',
23+
action => accept,
24+
physdev_in => 'eth0',
25+
}
26+
EOS
27+
28+
apply_manifest(pp, :catch_failures => true)
29+
unless fact('selinux') == 'true'
30+
apply_manifest(pp, :catch_changes => true)
31+
end
32+
end
33+
34+
it 'should contain the rule' do
35+
shell('iptables-save') do |r|
36+
expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 -m multiport --ports 701 -m comment --comment "701 - test" -j ACCEPT/)
37+
end
38+
end
39+
end
40+
41+
context 'physdev_out eth1' do
42+
it 'applies' do
43+
pp = <<-EOS
44+
class { '::firewall': }
45+
firewall { '702 - test':
46+
chain => 'FORWARD',
47+
proto => tcp,
48+
port => '702',
49+
action => accept,
50+
physdev_out => 'eth1',
51+
}
52+
EOS
53+
54+
apply_manifest(pp, :catch_failures => true)
55+
unless fact('selinux') == 'true'
56+
apply_manifest(pp, :catch_changes => true)
57+
end
58+
end
59+
60+
it 'should contain the rule' do
61+
shell('iptables-save') do |r|
62+
expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 -m multiport --ports 702 -m comment --comment "702 - test" -j ACCEPT/)
63+
end
64+
end
65+
end
66+
67+
context 'physdev_in eth0 and physdev_out eth1' do
68+
it 'applies' do
69+
pp = <<-EOS
70+
class { '::firewall': }
71+
firewall { '703 - test':
72+
chain => 'FORWARD',
73+
proto => tcp,
74+
port => '703',
75+
action => accept,
76+
physdev_in => 'eth0',
77+
physdev_out => 'eth1',
78+
}
79+
EOS
80+
81+
apply_manifest(pp, :catch_failures => true)
82+
unless fact('selinux') == 'true'
83+
apply_manifest(pp, :catch_changes => true)
84+
end
85+
end
86+
87+
it 'should contain the rule' do
88+
shell('iptables-save') do |r|
89+
expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 -m multiport --ports 703 -m comment --comment "703 - test" -j ACCEPT/)
90+
end
91+
end
92+
end
93+
end
94+
95+
#iptables version 1.3.5 is not suppored by the ip6tables provider
96+
if default['platform'] !~ /el-5/
97+
describe 'ip6tables physdev tests' do
98+
context 'physdev_in eth0' do
99+
it 'applies' do
100+
pp = <<-EOS
101+
class { '::firewall': }
102+
firewall { '701 - test':
103+
provider => 'ip6tables',
104+
chain => 'FORWARD',
105+
proto => tcp,
106+
port => '701',
107+
action => accept,
108+
physdev_in => 'eth0',
109+
}
110+
EOS
111+
112+
apply_manifest(pp, :catch_failures => true)
113+
unless fact('selinux') == 'true'
114+
apply_manifest(pp, :catch_changes => true)
115+
end
116+
end
117+
118+
it 'should contain the rule' do
119+
shell('ip6tables-save') do |r|
120+
expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 -m multiport --ports 701 -m comment --comment "701 - test" -j ACCEPT/)
121+
end
122+
end
123+
end
124+
125+
context 'physdev_out eth1' do
126+
it 'applies' do
127+
pp = <<-EOS
128+
class { '::firewall': }
129+
firewall { '702 - test':
130+
provider => 'ip6tables',
131+
chain => 'FORWARD',
132+
proto => tcp,
133+
port => '702',
134+
action => accept,
135+
physdev_out => 'eth1',
136+
}
137+
EOS
138+
139+
apply_manifest(pp, :catch_failures => true)
140+
unless fact('selinux') == 'true'
141+
apply_manifest(pp, :catch_changes => true)
142+
end
143+
end
144+
145+
it 'should contain the rule' do
146+
shell('ip6tables-save') do |r|
147+
expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 -m multiport --ports 702 -m comment --comment "702 - test" -j ACCEPT/)
148+
end
149+
end
150+
end
151+
152+
context 'physdev_in eth0 and physdev_out eth1' do
153+
it 'applies' do
154+
pp = <<-EOS
155+
class { '::firewall': }
156+
firewall { '703 - test':
157+
provider => 'ip6tables',
158+
chain => 'FORWARD',
159+
proto => tcp,
160+
port => '703',
161+
action => accept,
162+
physdev_in => 'eth0',
163+
physdev_out => 'eth1',
164+
}
165+
EOS
166+
167+
apply_manifest(pp, :catch_failures => true)
168+
unless fact('selinux') == 'true'
169+
apply_manifest(pp, :catch_changes => true)
170+
end
171+
end
172+
173+
it 'should contain the rule' do
174+
shell('ip6tables-save') do |r|
175+
expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 -m multiport --ports 703 -m comment --comment "703 - test" -j ACCEPT/)
176+
end
177+
end
178+
end
179+
end
180+
end
181+
182+
end

0 commit comments

Comments
 (0)