Skip to content

Commit 8b0b877

Browse files
committed
Added support for time ipt_module
1 parent b26d48b commit 8b0b877

File tree

5 files changed

+223
-6
lines changed

5 files changed

+223
-6
lines changed

README.markdown

+16
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,10 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov
467467

468468
* `ctstate`: Matches a packet based on its state in the firewall stateful inspection table, using the conntrack module. Valid values are: 'INVALID', 'ESTABLISHED', 'NEW', 'RELATED'. Requires the `state_match` feature.
469469

470+
* `date_start`: Start Date/Time for the rule to match, which must be in ISO 8601 "T" notation. The possible time range is '1970-01-01T00:00:00' to '2038-01-19T04:17:07'
471+
472+
* `date_stop`: End Date/Time for the rule to match, which must be in ISO 8601 "T" notation. The possible time range is '1970-01-01T00:00:00' to '2038-01-19T04:17:07'
473+
470474
* `destination`: The destination address to match. For example: `destination => '192.168.1.0/24'`. You can also negate a mask by putting ! in front. For example: `destination => '! 192.168.2.0/24'`. The destination can also be an IPv6 address if your provider supports it.
471475

472476
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.
@@ -525,6 +529,8 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov
525529

526530
If you set both `accept` and `jump` parameters, you will get an error, because only one of the options should be set. Requires the `iptables` feature.
527531

532+
* `kernel_timezone`: Use the kernel timezone instead of UTC to determine whether a packet meets the time regulations.
533+
528534
* `limit`: Rate limiting value for matched packets. The format is: 'rate/[/second/|/minute|/hour|/day]'. Example values are: '50/sec', '40/min', '30/hour', '10/day'. Requires the `rate_limiting` feature.
529535

530536
* `line`: Read-only property for caching the rule line.
@@ -535,6 +541,8 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov
535541

536542
* `mask`: Sets the mask to use when `recent` is enabled. Requires the `mask` feature.
537543

544+
* `month_days`: Only match on the given days of the month. Possible values are '1' to '31'. Note that specifying 31 will of course not match on months which do not have a 31st day; the same goes for 28- or 29-day February.
545+
538546
* `name`: The canonical name of the rule. This name is also used for ordering, so make sure you prefix the rule with a number. For example:
539547

540548
```puppet
@@ -668,6 +676,12 @@ firewall { '101 blacklist strange traffic':
668676

669677
Note that you specify flags in the order that iptables `--list` rules would list them to avoid having Puppet think you changed the flags. For example, 'FIN,SYN,RST,ACK SYN' matches packets with the SYN bit set and the ACK, RST and FIN bits cleared. Such packets are used to request TCP connection initiation. Requires the `tcp_flags` feature.
670678

679+
* `time_contiguous`: When time_stop is smaller than time_start value, match this as a single time period instead distinct intervals.
680+
681+
* `time_start`: Start time for the rule to match. The possible time range is '00:00:00' to '23:59:59'. Leading zeroes are allowed (e.g. '06:03') and correctly interpreted as base-10.
682+
683+
* `time_stop`: End time for the rule to match. The possible time range is '00:00:00' to '23:59:59'. Leading zeroes are allowed (e.g. '06:03') and correctly interpreted as base-10.
684+
671685
* `todest`: When using `jump => 'DNAT'`, you can specify the new destination address using this parameter. Requires the `dnat` feature.
672686

673687
* `toports`: For DNAT this is the port that will replace the destination port. Requires the `dnat` feature.
@@ -678,6 +692,8 @@ firewall { '101 blacklist strange traffic':
678692

679693
* `uid`: UID or Username owner matching rule. Accepts a string argument only, as iptables does not accept multiple uid in a single statement. Requires the `owner` feature.
680694

695+
* `week_days`: Only match on the given weekdays. Possible values are 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'.
696+
681697
###Type: firewallchain
682698

683699
Enables you to manage rule chains for firewalls.

lib/puppet/provider/firewall/ip6tables.rb

+14-3
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,15 @@ def self.iptables_save(*args)
123123
:uid => "--uid-owner",
124124
:physdev_in => "--physdev-in",
125125
:physdev_out => "--physdev-out",
126-
:physdev_is_bridged => "--physdev-is-bridged"
126+
:physdev_is_bridged => "--physdev-is-bridged",
127+
:date_start => "--datestart",
128+
:date_stop => "--datestop",
129+
:time_start => "--timestart",
130+
:time_stop => "--timestop",
131+
:month_days => "--monthdays",
132+
:week_days => "--weekdays",
133+
:time_contiguous => "--contiguous",
134+
:kernel_timezone => "--kerneltz",
127135
}
128136

129137
# These are known booleans that do not take a value, but we want to munge
@@ -138,7 +146,9 @@ def self.iptables_save(*args)
138146
:reap,
139147
:rttl,
140148
:socket,
141-
:physdev_is_bridged
149+
:physdev_is_bridged,
150+
:time_contiguous,
151+
:kernel_timezone
142152
]
143153

144154
# Properties that use "-m <ipt module name>" (with the potential to have multiple
@@ -158,6 +168,7 @@ def self.iptables_save(*args)
158168
:addrtype => [:src_type, :dst_type],
159169
:iprange => [:src_range, :dst_range],
160170
:owner => [:uid, :gid],
171+
:time => [:time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone]
161172
}
162173

163174
# Create property methods dynamically
@@ -201,6 +212,6 @@ def self.iptables_save(*args)
201212
:ctstate, :icmp, :hop_limit, :limit, :burst, :recent, :rseconds, :reap,
202213
:rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :todest,
203214
:tosource, :toports, :checksum_fill, :log_level, :log_prefix, :reject,
204-
:set_mark, :connlimit_above, :connlimit_mask, :connmark]
215+
:set_mark, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone]
205216

206217
end

lib/puppet/provider/firewall/iptables.rb

+14-3
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,15 @@
108108
:uid => "--uid-owner",
109109
:physdev_in => "--physdev-in",
110110
:physdev_out => "--physdev-out",
111-
:physdev_is_bridged => "--physdev-is-bridged"
111+
:physdev_is_bridged => "--physdev-is-bridged",
112+
:date_start => "--datestart",
113+
:date_stop => "--datestop",
114+
:time_start => "--timestart",
115+
:time_stop => "--timestop",
116+
:month_days => "--monthdays",
117+
:week_days => "--weekdays",
118+
:time_contiguous => "--contiguous",
119+
:kernel_timezone => "--kerneltz",
112120
}
113121

114122
# These are known booleans that do not take a value, but we want to munge
@@ -122,7 +130,9 @@
122130
:rsource,
123131
:rttl,
124132
:socket,
125-
:physdev_is_bridged
133+
:physdev_is_bridged,
134+
:time_contiguous,
135+
:kernel_timezone
126136
]
127137

128138
# Properties that use "-m <ipt module name>" (with the potential to have multiple
@@ -142,6 +152,7 @@
142152
:addrtype => [:src_type, :dst_type],
143153
:iprange => [:src_range, :dst_range],
144154
:owner => [:uid, :gid],
155+
:time => [:time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone]
145156
}
146157

147158
def self.munge_resource_map_from_existing_values(resource_map_original, compare)
@@ -226,7 +237,7 @@ def munge_resource_map_from_resource(resource_map_original, compare)
226237
:state, :ctstate, :icmp, :limit, :burst, :recent, :rseconds, :reap,
227238
:rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :todest,
228239
:tosource, :toports, :to, :checksum_fill, :random, :log_prefix, :log_level, :reject, :set_mark,
229-
:connlimit_above, :connlimit_mask, :connmark
240+
:connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone
230241
]
231242

232243
def insert

lib/puppet/type/firewall.rb

+95
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,101 @@ def insync?(is)
11021102
newvalues(:true, :false)
11031103
end
11041104

1105+
newproperty(:date_start, :required_features => :iptables) do
1106+
desc <<-EOS
1107+
Only match during the given time, which must be in ISO 8601 "T" notation.
1108+
The possible time range is 1970-01-01T00:00:00 to 2038-01-19T04:17:07
1109+
EOS
1110+
end
1111+
1112+
newproperty(:date_stop, :required_features => :iptables) do
1113+
desc <<-EOS
1114+
Only match during the given time, which must be in ISO 8601 "T" notation.
1115+
The possible time range is 1970-01-01T00:00:00 to 2038-01-19T04:17:07
1116+
EOS
1117+
end
1118+
1119+
newproperty(:time_start, :required_features => :iptables) do
1120+
desc <<-EOS
1121+
Only match during the given daytime. The possible time range is 00:00:00 to 23:59:59.
1122+
Leading zeroes are allowed (e.g. "06:03") and correctly interpreted as base-10.
1123+
EOS
1124+
1125+
munge do |value|
1126+
if value =~ /^([0-9]):/
1127+
value = "0#{value}"
1128+
end
1129+
1130+
if value =~ /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/
1131+
value = "#{value}:00"
1132+
end
1133+
1134+
value
1135+
end
1136+
end
1137+
1138+
newproperty(:time_stop, :required_features => :iptables) do
1139+
desc <<-EOS
1140+
Only match during the given daytime. The possible time range is 00:00:00 to 23:59:59.
1141+
Leading zeroes are allowed (e.g. "06:03") and correctly interpreted as base-10.
1142+
EOS
1143+
1144+
munge do |value|
1145+
if value =~ /^([0-9]):/
1146+
value = "0#{value}"
1147+
end
1148+
1149+
if value =~ /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/
1150+
value = "#{value}:00"
1151+
end
1152+
1153+
value
1154+
end
1155+
end
1156+
1157+
newproperty(:month_days, :required_features => :iptables) do
1158+
desc <<-EOS
1159+
Only match on the given days of the month. Possible values are 1 to 31.
1160+
Note that specifying 31 will of course not match on months which do not have a 31st day;
1161+
the same goes for 28- or 29-day February.
1162+
EOS
1163+
1164+
validate do |value|
1165+
month = value.to_i
1166+
if month >= 1 and month <=31
1167+
value
1168+
else
1169+
raise ArgumentError,
1170+
"month_days must be in the range of 1-31"
1171+
end
1172+
end
1173+
end
1174+
1175+
newproperty(:week_days, :required_features => :iptables) do
1176+
desc <<-EOS
1177+
Only match on the given weekdays. Possible values are Mon, Tue, Wed, Thu, Fri, Sat, Sun.
1178+
EOS
1179+
1180+
newvalues(:Mon, :Tue, :Wed, :Thu, :Fri, :Sat, :Sun)
1181+
end
1182+
1183+
newproperty(:time_contiguous, :required_features => :iptables) do
1184+
desc <<-EOS
1185+
When time_stop is smaller than time_start value, match this as a single time period instead distinct intervals.
1186+
EOS
1187+
1188+
newvalues(:true, :false)
1189+
end
1190+
1191+
newproperty(:kernel_timezone, :required_features => :iptables) do
1192+
desc <<-EOS
1193+
Use the kernel timezone instead of UTC to determine whether a packet meets the time regulations.
1194+
EOS
1195+
1196+
newvalues(:true, :false)
1197+
end
1198+
1199+
11051200
autorequire(:firewallchain) do
11061201
reqs = []
11071202
protocol = nil

spec/acceptance/firewall_time_spec.rb

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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 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+
if default['platform'] =~ /ubuntu-14\.04/ or default['platform'] =~ /debian-7/ or default['platform'] =~ /debian-8/ or default['platform'] =~ /el-7/
15+
describe "time tests ipv4" do
16+
context 'set all time parameters' do
17+
it 'applies' do
18+
pp = <<-EOS
19+
class { '::firewall': }
20+
firewall { '805 - test':
21+
proto => tcp,
22+
dport => '8080',
23+
action => accept,
24+
chain => 'OUTPUT',
25+
date_start => '2016-01-19T04:17:07',
26+
date_stop => '2038-01-19T04:17:07',
27+
time_start => '6:00',
28+
time_stop => '17:00:00',
29+
month_days => '7',
30+
week_days => 'Tue',
31+
kernel_timezone => true,
32+
}
33+
EOS
34+
35+
apply_manifest(pp, :catch_failures => true)
36+
unless fact('selinux') == 'true'
37+
apply_manifest(pp, :catch_changes => true)
38+
end
39+
end
40+
41+
it 'should contain the rule' do
42+
shell('iptables-save') do |r|
43+
expect(r.stdout).to match(/-A OUTPUT -p tcp -m multiport --dports 8080 -m comment --comment "805 - test" -m time --timestart 06:00:00 --timestop 17:00:00 --monthdays 7 --weekdays Tue --datestart 2016-01-19T04:17:07 --datestop 2038-01-19T04:17:07 --kerneltz -j ACCEPT/)
44+
end
45+
end
46+
end
47+
end
48+
49+
describe "time tests ipv6" do
50+
context 'set all time parameters' do
51+
it 'applies' do
52+
pp = <<-EOS
53+
class { '::firewall': }
54+
firewall { '805 - test':
55+
proto => tcp,
56+
dport => '8080',
57+
action => accept,
58+
chain => 'OUTPUT',
59+
date_start => '2016-01-19T04:17:07',
60+
date_stop => '2038-01-19T04:17:07',
61+
time_start => '6:00',
62+
time_stop => '17:00:00',
63+
month_days => '7',
64+
week_days => 'Tue',
65+
kernel_timezone => true,
66+
provider => 'ip6tables',
67+
}
68+
EOS
69+
70+
apply_manifest(pp, :catch_failures => true)
71+
unless fact('selinux') == 'true'
72+
apply_manifest(pp, :catch_changes => true)
73+
end
74+
end
75+
76+
it 'should contain the rule' do
77+
shell('ip6tables-save') do |r|
78+
expect(r.stdout).to match(/-A OUTPUT -p tcp -m multiport --dports 8080 -m comment --comment "805 - test" -m time --timestart 06:00:00 --timestop 17:00:00 --monthdays 7 --weekdays Tue --datestart 2016-01-19T04:17:07 --datestop 2038-01-19T04:17:07 --kerneltz -j ACCEPT/)
79+
end
80+
end
81+
end
82+
end
83+
end
84+
end

0 commit comments

Comments
 (0)