Control Firewall Filter Terms for Certain Time Ranges
For SLAX version 1.0 and higher, you can activate or deactivate firewall filter terms based on configured time-ranges when you use a time-based event script in tandem with a commit script.
You can immediately create the configuration required for the event script without waiting for the event to occur. This automates activating firewall filter terms during specified time ranges. This is used to create a time-based stateless firewall filter.
The event script time-based-filters.slax and the commit script cs-time-based-filters.slax are paired to create time-based stateless firewall filters. The scripts employ user-defined arguments from the router configuration to automatically activate and deactivate specified filter terms at designated periods. You load the script files, enable them, and mark the filter terms with appropriate macros that provide instructions regarding the times when the firewall terms should be enabled or disabled.
System Requirements
The minimum Junos OS Release is 9.3. Additionally, this script is only supported on the following Junos OS releases:
Set Up
- Copy the script time-based-filters.slax to the /var/db/scripts/event directory on the router.
- Copy the script cs-time-based-filters.slax to the /var/db/scripts/commit directory on the router.
NOTE: On dual-routing engine (dual-RE) systems you need to perform all of the initial steps on each of the routing engines—you must copy the scripts to their respective directories and enable both the event script and the commit script on each routing engine.
1 [edit event-options event-script]
2 user@host# set file time-based-filters.slax
3 [edit system scripts commit]
4 user@host# set file cs-time-based-filters.slax
- Add time-range configuration macros to any firewall filter term that should be enabled or disabled at specific times. These are added by entering the apply-macro statement under the firewall filter term hierarchy, with a macro name of either active-time-range or inactive-time-range.
The basic outline of the time-range macro is:
1 term <rule-name> {
2 apply-macro (active-time-range | inactive-time-range) {
3 start-time <start-time>;
4 stop-time <stop-time>;
5 }
NOTE: Macros are a simple way to embed user-defined syntax, e.g. a name-value pair, inside Junos OS
configuration.
4. To add a macro, enter the configuration mode on the routing device, navigate to the hierarchy of the
firewall filter that should be time-based, and add the desired time-range macro with the time-range
defined.
5. The default state for the firewall filter term will be the opposite of the time-range state designated in the
macro. For example, if an active-time-range is specified for a firewall term, the term will be set to inactive
by default unless the current time falls within the active-time-range that is specified. Within a time-range
macro, both the start-time and stop-time statements must be configured to specify the start of the
active/inactive period.
6. Enable the scripts by adding the file statement and script filename to the appropriate hierarchy level for
the script type. Only superusers can enable scripts in the configuration.
Time Formats
Time is specified in one of the formats listed below, where HH is in 24 hour format, and MM can only be 00, 15, 30, or 45.
- HH:MM - The time applies to every day at the HH:MM specified.
- weekdays HH:MM - The time applies to only weekdays at the HH:MM specified.
- weekends HH:MM - The time applies to only weekends at the HH:MM specified.
- mon HH:MM - The time applies on the day of the week (sun, mon, tue, etc) at the HH:MM specified.
Use the following examples of firewall filter terms with configured time-range macros to determine how to set up your own time-range macros. The term name is user-defined:
This filter term will only be active from 8:00 a.m. to 5:00 p.m.:
1 term day-term {
2 apply-macro active-time-range {
3 start-time 08:00;
4 stop-time 17:00;
5 }
6 ...
7 }
This term will be inactive from 3:00 p.m. to 6:00 p.m.:
1 term not-afternoon-term {
2 apply-macro inactive-time-range {
3 start-time 15:00;
4 stop-time 18:00;
5 }
6 ...
7 }
This term will be active from Monday to Wednesday from 12:00 a.m. to 12:00 a.m. (24:00):
1 term multiple-days {
2 apply-macro active-time-range {
3 start-time "mon 00:00";
4 stop-time "wed 24:00";
5 }
6 ...
7 }
This term will be active from 5:00 p.m. to 8:00 p.m. on weekdays:
1 term night {
2 apply-macro active-time-range {
3 start-time "weekdays 17:00";
4 stop-time "weekdays 20:00";
5 }
6 ...
7 }
How to Run
The time-based filter script will run automatically at the start and stop times specified and will activate or deactivate the firewall terms whose state should be changed based on the start and stop times specified in the time-range macros in the configuration.
Term activations or deactivations will result in a syslog message to the external facility with a severity of info, for example:
1 Jul 30 13:51:02 r2d2-re0 cscript: time-based-filters script activating term weekdays
2 Jul 30 13:51:02 r2d2-re0 cscript: time-based-filters script deactivating term default
Example Implementation
For example, assume you want to set a
family inet filter with the filter name
re-protect to be time-based. You could do this by following these steps:
- Enter configuration mode and navigate to firewall family inet filter re-protect:
1 user@host> configure
2 Entering configuration mode
3 [edit]
4 user@host# edit firewall family inet filter re-protect
- Add the time-range macros to the filters. The example below creates a term rule called block-html that sets the active range of the filter from 8 a.m. to 5 p.m:
1 [edit firewall family inet filter re-protect]
2 user@host# set term block-html apply-macro active-time-range start-time 08:00
3 [edit firewall family inet filter re-protect]
4 user@host# set term block-html apply-macro active-time-range stop-time 17:00
- When finished setting up time-range macros, commit the configuration changes:
1 [edit]
2 user@host# commit and-quit
Notes and Restrictions
Below are restrictions to be aware of when using time-range macros and the time-based scripts in this section. These are in addition to the system requirements restrictions listed previously.
- Only the Coordinated Universal Time (UTC) time-zone is supported. If a different time-zone is configured the commit will fail with an error.
- You cannot include both active-time-range and inactive-time-range for the same term. Multiple ranges of the same type can be included by appending -# to the end to distinguish each range. (e.g. active-time-range-1, active-time-range-2, etc.)
- These configuration elements are reserved for use by the time-based filter script:
- groups time-based-filters-group
- event-options generate-event time-based-filters-event
- event-options policy time-based-filters-policy
- A maximum of 10 unique HH:MM times can be configured, including [event-options generate-events]. If you try to configure more than 10, a commit error will result.
- Ensure that all filter terms are not deactivated at the same time; if they are, commit will fail.
- Counters in a time-based term lose their value when the term is deactivated.
- If your system time is ever manually changed, you must do one of the following to ensure that time events are on the correct time:
- commit full
- restart event-processing or
- request system scripts event-scripts reload
- On a dual routing engine (dual-RE) system, time must be synchronized between the two REs. It is recommended that both REs be synchronized to an NTP server.
Source Code and GitHub Links
001 /*
002 * Author : Curtis Call
003 * File : cs-time-based-filters.slax
004 * Version : 1.1
005 * Last Modified : August 7, 2009
006 * Platform : all
007 * Release : 9.3 and above
008 * Minimum Revisions:
009 * JUNOS 9.3: (9.3R5 or 9.3S equivalent)
010 * JUNOS 9.4: (9.4R4)
011 * JUNOS 9.5: (9.5R3)
012 * JUNOS 9.6: (9.6R2)
013 * JUNOS 10.0: (10.0R1)
014 *
015 * Description : time-based-filters.slax and cs-time-based-filters.slax
016 * time-based-filters.slax and cs-time-based-filters.slax are an event script
017 * and commit script pair used when a time-based stateless firewall filter is
018 * desired. They function by deactivating the filter terms at designated
019 * periods and activating them at the proper time. This is all performed
020 * automatically by the scripts, the only action that the operator has to take
021 * is to load the script files, enable them, and mark the filter terms with
022 * the appropriate macros which provide instructions on when the terms should
023 * be enabled and disabled.
024 */
025
026 version 1.0;
027
028 ns junos = "http://xml.juniper.net/junos/*/junos";
029 ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
030 ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
031
032 import "../import/junos.xsl";
033
034 /* Import from the time-based-filters.slax script */
035 import "../event/time-based-filters.slax";
036
037 /*
038 * This is needed here instead of in the junos.xsl import file because there is
039 * a match / in the imported event file as well.
040 */
041 match / {
042 <commit-script-results> {
043 apply-templates commit-script-input/configuration;
044 }
045 }
046
047 /* Configuration items */
048 var $time-based-filters-event-prepend = "time-based-filters-event";
049 var $time-based-filters-policy = "time-based-filters-policy";
050 var $time-based-filters-group = "time-based-filters-group";
051
052 /* The version of the event and commit script MUST match. */
053 var $commit-script-version = "1.1";
054
055 match configuration {
056
057 /*
058 * First of all, make sure the event and commit script version match if they
059 * do not then terminate immediately.
060 */
061 if( $commit-script-version != $event-script-version ) {
062 <xsl:message terminate="yes"> "Your " _ $commit-script-name _ " version is different from your " _ $event-script-name _ " version.";
063 }
064
065 /*
066 * Error if there is a non-UTC time-zone configured. This is unsupported with
067 * this script.
068 */
069 var $valid-time-zone = { call is-utc-time-zone(); }
070 if( $valid-time-zone == $false ) {
071 <xsl:message terminate="yes"> "JUNOS devices using the cs-time-based-filters script must use the UTC time-zone.";
072 }
073
074 /*
075 * Check if this is a valid version or not (see note at top of script). If
076 * invalid version then log a xnm:warning and syslog indicating such and exit.
077 */
078 var $valid-version = { call is-valid-version(); }
079 if( $valid-version == $true ) {
080 call main();
081 }
082 else {
083 <xnm:warning> {
084 <message> "The cs-time-based-filters script is not supported in this JUNOS version.";
085 }
086 <syslog> {
087 <message> "The cs-time-based-filters script is not supported in this JUNOS version.";
088 }
089 }
090 }
091
092 template main() {
093 /* Record pointer to event-options */
094 var $event-options = event-options;
095
096 /* Record pointer to top */
097 var $configuration = .;
098
099 /* Pull in candidate configuration - for inactive elements */
100 var $get-candidate-rpc = <get-configuration database="candidate"> {
101 <configuration> {
102 <groups>;
103 <event-options>;
104 <firewall>;
105 <logical-systems>;
106 }
107 }
108 var $candidate-configuration = jcs:invoke( $get-candidate-rpc );
109
110 /* Look for macros in firewall stanza */
111 var $firewall-macros = $candidate-configuration/firewall/filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
112 var $firewall-family-macros = $candidate-configuration/firewall/family//filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
113 var $groups-firewall-macros = $candidate-configuration/groups/firewall/filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
114 var $groups-firewall-family-macros = $candidate-configuration/groups/firewall/family//filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
115 var $logical-systems-firewall-macros = $candidate-configuration/logical-systems/firewall/filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
116 var $logical-systems-firewall-family-macros = $candidate-configuration/logical-systems/firewall/family//filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
117 var $groups-logical-systems-firewall-macros = $candidate-configuration/groups/logical-systems/firewall/filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
118 var $groups-logical-systems-firewall-family-macros = $candidate-configuration/groups/logical-systems/firewall/family//filter/term[starts-with(apply-macro/name, $active-range-macro) or starts-with(apply-macro/name, $inactive-range-macro)];
119
120 /* Combine them all into a single node set */
121 var $firewall-terms = $firewall-macros | $firewall-family-macros | $groups-firewall-macros | $groups-firewall-family-macros |
122 $logical-systems-firewall-macros | $logical-systems-firewall-family-macros | $groups-logical-systems-firewall-macros |
123 $groups-logical-systems-firewall-family-macros;
124
125 /* Go through each macro - look for errors - generate time-based events if needed */
126 for-each( $firewall-terms ) {
127
128 var $term-name = name;
129 /* time range macros */
130 var $time-range-macros = ./apply-macro[starts-with(name, $active-range-macro) or starts-with(name, $inactive-range-macro)];
131
132 /* Verify the group of time range macros first, they need to either start with active or inactive... */
133
134 var $default-status = {
135 if( starts-with( $time-range-macros[1]/name , $active ) ) {
136 expr $inactive;
137 }
138 else {
139 expr $active;
140 }
141 }
142
143 var $valid-range-group = {
144 if( $default-status == $active and $time-range-macros/name[starts-with(., $active)] ) {
145 expr $false;
146 }
147 else if( $default-status == $inactive and $time-range-macros/name[starts-with(., $inactive)] ) {
148 expr $false;
149 }
150 else {
151 expr $true;
152 }
153 }
154
155 if( $valid-range-group == $false ) {
156 <xnm:error> {
157 call jcs:edit-path();
158 <message> $term-name _ " cannot have both active and inactive time ranges.";
159 }
160 }
161
162 /* Go through all time ranges, look for errors */
163 for-each( $time-range-macros ) {
164
165 var $range-status = {
166 /* The opposite of the default status */
167 if( $default-status == $active ) {
168 expr $inactive;
169 }
170 else {
171 expr $active;
172 }
173 }
174
175 /* Does it have a valid start time? */
176 var $start-time-range = data[name == $start-time-field]/value;
177 var $start-time-raw = { call get-time-from-range( $range = $start-time-range ); }
178 var $start-time = { call adjust-time( $time = $start-time-raw ); }
179 var $valid-start-time = { call is-valid-time-range( $range = $start-time-range ); }
180 if( $valid-start-time == $false ) {
181 <xnm:error> {
182 call jcs:edit-path();
183 call jcs:statement( $dot = data[name == $start-time-field]/value );
184 <message> $term-name _ " does not have a valid " _ $start-time-field _ " defined in their " _ ./name _ " macro.";
185 }
186 }
187
188
189 /* Does it have a valid stop time? */
190 var $stop-time-range = data[name == $stop-time-field]/value;
191 var $stop-time-raw = { call get-time-from-range( $range = $stop-time-range ); }
192 var $stop-time = { call adjust-time( $time = $stop-time-raw ); }
193 var $valid-stop-time = { call is-valid-time-range( $range = $stop-time-range ); }
194 if( $valid-stop-time == $false ) {
195 <xnm:error> {
196 call jcs:edit-path();
197 call jcs:statement( $dot = data[name == $stop-time-field ]/value );
198 <message> $term-name _ " does not have a valid " _ $stop-time-field _ " defined in their " _ ./name _ " macro.";
199 }
200 }
201
202 /* Is the start-time and stop-time pair valid? */
203 var $valid-range-pair = { call is-valid-range-pair( $start-range = $start-time-range, $stop-range = $stop-time-range ); }
204 if( $valid-range-pair == $false ) {
205 <xnm:error> {
206 call jcs:edit-path();
207 <message> $term-name _ " does not have a valid time range pair: " _ $start-time-range _ " " _ $stop-time-range;
208 }
209 }
210
211 /*
212 * Now check if there is already a time-based event defined for the start-time and stop-time
213 * and if they are already setup for the event script.
214 *
215 */
216
217 /* Create a node-set so we can loop through the next section */
218 var $time-events := {
219 if( $valid-range-pair == $true and $valid-start-time == $true ) {
220 <time> $start-time;
221 }
222 if( $valid-range-pair == $true and $valid-stop-time == $true ) {
223 /* Translate a 24:00 to a 00:00 */
224 if( $stop-time == "24:00" ) {
225 <time> "00:00";
226 }
227 else {
228 <time> $stop-time;
229 }
230 }
231 }
232
233 /* Create time events if needed */
234 for-each( $time-events/time ) {
235 var $time-event-name = $time-based-filters-event-prepend _ "-" _ .;
236 var $time-event-value = . _ ":00";
237 /* Does the time event already exist? Then check it's time */
238 if( $event-options/generate-event[name==$time-event-name] ) {
239 /* Check it's value, if it isn't the right time then send an error */
240 if( not( starts-with( $event-options/generate-event[name==$time-event-name]/time-of-day, $time-event-value ) ) ) {
241 <xnm:error> {
242 call jcs:edit-path($dot = $event-options/generate-event[name==$time-event-name]);
243 call jcs:statement($dot = $event-options/generate-event[name==$time-event-name]/time-of-day);
244 <message> "Needed time event is already defined but with the wrong time.";
245 }
246 }
247 }
248 else { /* It doesn't exist... create it... */
249 <change> {
250 <groups> {
251 <name> $time-based-filters-group;
252 <event-options> {
253 <generate-event> {
254 <name> $time-event-name;
255 <time-of-day> $time-event-value;
256 }
257 }
258 }
259 }
260 }
261
262 /* Verify that apply flags omit is present in the group, if not then add it */
263 if( jcs:empty( $candidate-configuration/groups[name==$time-based-filters-group]/undocumented/apply-flags/omit ) ) {
264 <change> {
265 <groups> {
266 <name> $time-based-filters-group;
267 <undocumented> {
268 <apply-flags> {
269 <omit>;
270 }
271 }
272 }
273 }
274 }
275
276 /* Verify that the apply group is present in event-options */
277 if( jcs:empty( $candidate-configuration/event-options[apply-groups == $time-based-filters-group] ) ) {
278 <change> {
279 <event-options> {
280 <apply-groups> $time-based-filters-group;
281 }
282 }
283 }
284
285 /* Is the event policy already defined? If not then create it, this could happen multiple times when first created */
286 if( jcs:empty( $event-options/policy[name == $time-based-filters-policy]/then/event-script[name == $event-script-name ] ) ) {
287 <change> {
288 <groups> {
289 <name> $time-based-filters-group;
290 <event-options> {
291 <policy> {
292 <name> $time-based-filters-policy;
293 <then> {
294 <event-script> {
295 <name> $event-script-name;
296 }
297 }
298 }
299 }
300 }
301 }
302 }
303
304 /* Is the event script line present? If not then create it */
305 if( jcs:empty( $event-options/event-script/file[name == $event-script-name] ) ) {
306 <change> {
307 <groups> {
308 <name> $time-based-filters-group;
309 <event-options> {
310 <event-script> {
311 <file> {
312 <name> $event-script-name;
313 }
314 }
315 }
316 }
317 }
318 }
319
320 /* Is the event already defined as an event in the time-based-filters event policy? */
321 if( jcs:empty( $event-options/policy[name == $time-based-filters-policy][events == $time-event-name ] ) ) {
322 /* If not already defined then define it */
323 <change> {
324 <groups> {
325 <name> $time-based-filters-group;
326 <event-options> {
327 <policy> {
328 <name> $time-based-filters-policy;
329 <events> $time-event-name;
330 }
331 }
332 }
333 }
334 }
335 }
336 }
337 }
338
339 /* Go through each time-based-access event and delete it if no longer needed */
340 for-each( $event-options/generate-event[starts-with( name, $time-based-filters-event-prepend ) ] ) {
341 var $term-matches-event = { call term-matches-event( $firewall-terms, $event-time = time-of-day ); }
342
343 /* If it matches no shift starts nor shift stops then delete it */
344 if( $term-matches-event == $false ) {
345 <change> {
346 <groups> {
347 <name> $time-based-filters-group;
348 <event-options> {
349 <generate-event delete="delete"> {
350 <name> name;
351 }
352 }
353 }
354 }
355 }
356 }
357
358 /* Go through each event in the event policy and delete it if no longer needed */
359 var $full-prepend = $time-based-filters-event-prepend _ "-";
360 for-each( $event-options/policy[name==$time-based-filters-policy]/events ) {
361 var $event-time = substring-after( ., $full-prepend);
362 var $term-matches-event = { call term-matches-event( $firewall-terms, $event-time ); }
363
364 /* Delete it if not present */
365 if( $term-matches-event == $false ) {
366 <change> {
367 <groups> {
368 <name> $time-based-filters-group;
369 <event-options> {
370 <policy> {
371 <name> $time-based-filters-policy;
372 <events delete="delete"> .;
373 }
374 }
375 }
376 }
377 }
378 }
379
380 /* Delete the entire group if it isn't needed any longer - if no firewall terms then it isn't needed */
381 if( jcs:empty( $firewall-terms ) ) {
382 if( not( jcs:empty( event-options/policy[name==$time-based-filters-policy] ) ) ) {
383 <change> {
384 <groups delete="delete"> {
385 <name> $time-based-filters-group;
386 }
387 }
388 <change> {
389 <event-options> {
390 <apply-groups delete="delete"> $time-based-filters-group;
391 }
392 }
393 }
394 }
395
396 /* Now run the event script template and make any changes to the filter terms that are needed */
397 call generate-config-changes( $firewall-terms );
398
399 }
400
401 /* Searches through firewall terms looking for a match to the time in the event time-of-day, returns $true or $false */
402 template term-matches-event( $firewall-terms, $event-time ) {
403 /* Adjust in case it starts with a 0 like 08:00, so we can try 8:00 also */
404 var $adjusted-time = {
405 if( starts-with( $event-time, "0" ) ) {
406 expr substring-after( $event-time, "0" );
407 }
408 else {
409 expr $event-time;
410 }
411 }
412 var $response = {
413 for-each( $firewall-terms/apply-macro[starts-with(name, $active-range-macro) or starts-with(name, $inactive-range-macro)]/data[name == $start-time-field or name == $stop-time-field ] ) {
414 var $macro-time = { call get-time-from-range( $range = value ); }
415
416 /* Adjust the firewall times to convert the 24:00 to a 00:00 */
417 var $adjusted-macro-time = {
418 if( $macro-time == "24:00" ) {
419 expr "00:00";
420 }
421 else {
422 expr $macro-time;
423 }
424 }
425
426 if( starts-with( $event-time, $adjusted-macro-time ) or starts-with( $adjusted-time, $adjusted-macro-time ) ) {
427 expr $true;
428 }
429 }
430 }
431 /* Return $true or $false based on the result of the $response */
432 if( contains( $response, $true ) ) {
433 expr $true;
434 }
435 else {
436 expr $false;
437 }
438 }
XML Script Contents
001 <?xml version="1.0"?>
002 <script>
003 <title>cs-time-based-filters.slax</title>
004 <author>curtisstephencall</author>
005 <synopsis>
006 Activates/Deactivates firewall filter terms based on configured time-ranges.
007 </synopsis>
008 <coe>commit</coe>
009 <type>filters</type>
010
011 <description>
012 <![CDATA[time-based-filters.slax and cs-time-based-filters.slax are an event script
013 and commit script pair used when a time-based stateless firewall filter is
014 desired. They function by deactivating the filter terms at designated
015 periods and activating them at the proper time. This is all performed
016 automatically by the scripts, the only action that the operator has to take
017 is to load the script files, enable them, and mark the filter terms with
018 the appropriate macros which provide instructions on when the terms should
019 be enabled and disabled.
020
021 * Minimum JUNOS version is 9.3. In addition, due to PR 452398 this script can
022 * only be used with the following JUNOS versions as of the dailies mentioned:
023 * JUNOS 9.3: 20090730 (9.3R5)
024 * JUNOS 9.4: 20090730 (9.4R4)
025 * JUNOS 9.5: 20090729 (9.5R3)
026 * JUNOS 9.6: 20090701 (9.6R2)
027 * JUNOS 10.0: 20090623 (10.0B1)
028
029 (Must be used in combination with time-based-filters.slax).
030
031
032 Installation
033 ------------
034 1. Copy the time-based-filters.slax script to the /var/db/scripts/event
035 directory on all REs.
036
037 2. Copy the cs-time-based-filters.slax script to the /var/db/scripts/commit
038 directory on all REs.
039
040 3. Configure: set system scripts commit file cs-time-based-filters.slax
041
042 This is all that is required to setup the time-based-filters scripts. No
043 event policy configuration is necessary, the commit script will
044 automatically generate all needed configuration.
045
046
047 Time-Based Stateless Firewall Filters
048 -------------------------------------
049 To mark a filter as a time-based filter it is necessary to add either
050 the "active-time-range" or "inactive-time-range" macro under the filter
051 term and specify a start-time and stop-time for the term.
052
053 start-time - The beginning time for the time-range
054
055 stop-time - The ending time for the time-range
056
057 Valid formats for start-time and stop-time are the following:
058
059 HH:MM - The time occurs every day at the specified HH:MM (in 24 hour format).
060
061 "weekdays HH:MM" - The time occurs Mon-Fri at the specified time
062
063 "weekends HH:MM" - The time occurs Sat-Sun at the specified time
064
065 "day HH:MM" where day = sat, sun, mon, etc - The time occurs on the given day
066 at the specified time.
067
068 MM must be 00, 15, 30, or 45. HH should be from 00 to 24. If HH is 24 then
069 MM must be 00.
070
071 Reversed time-ranges, where the stop-time occurs before the start-time (because
072 the start-time begins at night and the stop-time occurs in the morning) are not
073 allowed when using "weekdays" or "weekends".
074
075 The default status of the term is the opposite of the selected time-range. If
076 active-time-range is used, then the default status outside of the given time-range
077 is inactive. The reverse is true for an inactive-time-range.
078
079 Multiple time-ranges can be specified by appending a -# to each macro (the name
080 must be unique). They must all be of the same type within a term, either inactive
081 or active.
082
083
084 Reserved Configuration
085 ----------------------
086 The scripts reserve the following configuration elements and they will add
087 and delete them as needed:
088 groups time-based-filters-group
089 generate-event time-based-filters-event*
090 policy time-based-filters-policy
091
092
093 Restrictions & Misc
094 -------------------
095 Only the UTC time-zone is supported due to PR 459078. Using a different time-zone
096 will result in a commit error.
097
098 A maximum of 10 unique times can be supported per JUNOS device. Going beyond this
099 will result in a commit error.
100
101 Be careful that all filter terms are not deactivated at the same time, if that
102 occurs then the commit will fail.
103
104 Counters in a time-based term will lose their value when the term is deactivated.
105
106 The commit script will enforce the correct term status as part of the commit
107 process as well. This means that it is not necessary to wait until the start/stop
108 of a term's time-range to have the term's status set correct.
109
110 If you ever manually change your system time, then you need to do a "commit
111 full" or "restart event-process" or "request system scripts event-scripts reload"
112 because your time-of-day events will be off time.
113
114 This should work for filters of any address family defined under firewall or groups
115 as well as logical-systems.
116
117 Term activations or deactivations will result in a syslog message to the external
118 facility with severity info:
119 Jul 30 13:51:02 r2d2-re0 cscript: time-based-filters script activating term weekdays
120 Jul 30 13:51:02 r2d2-re0 cscript: time-based-filters script deactivating term default
121
122
123 Dual-RE Systems
124 ---------------
125 On dual-re systems you need to copy the scripts into their respective directories
126 and enable the commit script (set system scripts commit file ...) on both REs.
127
128 Time must be synchronized between the two REs. It is recommended that both REs
129 are synchronized to a NTP server.
130
131 The script will run on both REs but it will pause for a minute on the backup RE
132 to allow the master RE to make the configuration change. If there is a
133 communication problem then the backup RE will make the needed configuration change
134 but it will not synchronize its commit (unless the configuration forces it to).
135
136
137 Problems
138 --------
139 The event script will attempt an exclusive commit at the start and stop
140 times configured. If other users are editing the configuration then
141 the exclusive commit will fail and this will be logged into the syslog:
142
143 Jan 4 04:00:01 EX2 cscript: %DAEMON-3: time-based-filters.slax unable to lock configuration database.
144 Jan 4 04:00:01 EX2 cscript: %DAEMON-3: time-based-filters.slax configuration change failure on attempt #1 - retry in 5 minutes.
145
146 This is sent to the daemon facility at severity error. The script waits
147 five more minutes before trying again. This will continue every five
148 minutes until the commit succeeds or until the maximum attempts of six has
149 been reached at which point the script will terminate and log this:
150
151 Jan 4 04:25:06 EX2 cscript: %DAEMON-3: time-based-filters.slax unable to lock configuration database.
152 Jan 4 04:25:06 EX2 cscript: %DAEMON-3: time-based-filters.slax configuration changes could not be made after 6 attempts. - Script is exiting.
153
154
155 The commit script and event script work together so it is essential that
156 they are using the same version. If the commit script detects that there
157 is a different event script version in use then it will fail the commit and
158 report:
159
160 error: Your cs-time-based-filters.slax version is different from your time-based-filters.slax version.
161 error: 2 errors reported by commit scripts
162 error: commit script failure]]>
163 </description>
164 <example>
165 <title>Example time-range macros</title>
166 <description>
167 <![CDATA[This filter term should only be active from 8:00am to 5:00pm
168 term day-term {
169 apply-macro active-time-range {
170 start-time 08:00;
171 stop-time 17:00;
172 }
173 ...
174 }
175
176 This term should be inactive from 3:00pm to 6:00pm
177 term not-afternoon-term {
178 apply-macro inactive-time-range {
179 start-time 15:00;
180 stop-time 18:00;
181 }
182 ...
183 }
184
185 This term should be active from monday to wednesday from 12:00am to 12:00am
186 term multiple-days {
187 apply-macro active-time-range {
188 start-time "mon 00:00";
189 stop-time "wed 24:00";
190 }
191 ...
192 }
193
194 This term should be active from 5:00pm to 8:00pm on weekdays
195 term night {
196 apply-macro active-time-range {
197 start-time "weekdays 17:00";
198 stop-time "weekdays 20:00";
199 }
200 ...
201 }
202
203 This term should be active from 10am-12pm and 2pm-4pm
204 term multi-range {
205 apply-macro active-time-range-1 {
206 start-time 10:00;
207 stop-time 12:00;
208 }
209 apply-macro active-time-range-2 {
210 start-time 14:00;
211 stop-time 16:00;
212 }
213 ...
214 }]]>
215 </description>
216 </example>
217 <keyword>commit</keyword>
218 <keyword>slax</keyword>
219 <keyword>firewall</keyword>
220 <keyword>filters</keyword>
221 <keyword>time</keyword>
222 <keyword>time-based</keyword>
223
224 <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
225 src="../../../../../web/leaf.js"
226 type="text/javascript"/>
227 </script>