Blogs

Scripting How-To: Perform a lookup in the policy table

By Erdem posted 08-14-2015 14:57

  

Perform a Lookup in the Policy Table

 

For SLAX version 1.0 and higher, you can use the policy-test script to perform a lookup in the policy table and returns the matching policies based on the search criteria. Given a sample packet, such as source-address, dst-address, and ports, the lookup returns the list of matching policies.

 

Source Code and GitHub Links

 

The source code below is also available from the following GitHub locations:

Example Output


   
 
01
This script performs a lookup in the policy table and returns the matching policies based on the search criteria. It accepts the following parameters
02
 
03
user@cli> run op policy-test ?
04
Possible completions:
05
 
06
  destination-address  Destination IP address of the initial session creation packet
07
  destination-port     Destination port of the packet
08
  from-zone            Ingress zone of the packet
09
  source-address       Source IP address of the initial session creation packet
10
  source-port          Source port of the packet
11
  to-zone              Egress zone of the packet
12
 
13
If a parameter is not specified it will match all. If no parameter is provided, every policy will be returned.
14
 
15
If a source/dest address is provided, but the security zone is not specified, the zone for that source/dest IP will be determined from the zone of the ingress/egress interface (doing a route lookup). Of course, if a zone is explicitely specified, it will be used instead of the one determined by the route lookup.
16
 
17
user@cli# run op policy-test source-address 10.1.1.1 destination-address 10.2.2.2
18
From-Zone    To-Zone      Name            Src-Addr        Dst-Addr        Application  Action
19
trust        untrust      ftp-permit      any             any             junos-ftp    permit
20
trust        untrust      http-https-rej  any             any             junos-https  reject
21
                                                                          junos-http
22
 
23
user@cli# run op policy-test source-address 10.1.1.1 destination-address 10.2.2.2 destination-port 443
24
From-Zone    To-Zone      Name            Src-Addr        Dst-Addr        Application  Action
25
trust        untrust      http-https-rej  any             any             junos-https  reject
26
                                                                          junos-http
SLAX Script Contents
001
/* Machine Crafted with Care (tm) by slaxWriter */
002
version 1.0;
003
 
004
ns junos = "http://xml.juniper.net/junos/*/junos";
005
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
006
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
007
 
008
 
009
/*
010
This is a simple script that looks up all the entries in the policy table that match a particular query
011
It is useful to debug polcy configurations
012
 */
013
import "../import/junos.xsl";
014
var $arguments = {
015
    <argument> {
016
        <name> "source-address";
017
        <description> "Source IP address of the initial session creation packet";
018
    }
019
    <argument> {
020
        <name> "destination-address";
021
        <description> "Destination IP address of the initial session creation packet";
022
    }
023
    <argument> {
024
        <name> "source-port";
025
        <description> "Source port of the packet";
026
    }
027
    <argument> {
028
        <name> "destination-port";
029
        <description> "Destination port of the packet";
030
    }
031
    <argument> {
032
        <name> "from-zone";
033
        <description> "Ingress zone of the packet";
034
    }
035
    <argument> {
036
        <name> "to-zone";
037
        <description> "Egress zone of the packet";
038
    }
039
}
040
/* Open a persistent connection */
041
var $connection = jcs:open();
042
param $source-address = {
043
    expr "0.0.0.0/0";
044
}
045
param $destination-address = {
046
    expr "0.0.0.0/0";
047
}
048
param $source-port = {
049
    expr "0";
050
}
051
param $destination-port = {
052
    expr "0";
053
}
054
param $protocol = {
055
    expr "0";
056
}
057
param $from-zone = {
058
    call find-zone($ip = $source-address);
059
}
060
param $to-zone = {
061
    call find-zone($ip = $destination-address);
062
}
063
/* print-policy: Displays the policy info */
064
template print-policy ($name, $from-zone, $to-zone, $source-address, $destination-address, $application,$action, $comment, $row = number("1"), $header = false()) {
065
    var $format-string = "%-12.11s %-12.11s %-15.14j1s %-15.14s %-15.14s %-12.11s %-10.9s %s \n";
066
     
067
    if ($header) {
068
        expr jcs:printf($format-string, "From-Zone", "To-Zone", "Name", "Src-Addr", "Dst-Addr","Application", "Action", "");
069
     
070
    } else {
071
        var $num-rows = {
072
            if (count($application) >= count($source-address) && count($application) >= count($destination-address)) {
073
                expr count($application);
074
             
075
            } else if (count($source-address) > count($application) && count($source-address) > count($destination-address)) {
076
                expr count($source-address);
077
             
078
            } else {
079
                expr count($destination-address);
080
            }
081
        }
082
         
083
        if ($row <= $num-rows) {
084
            expr jcs:printf($format-string, $from-zone, $to-zone, $name, $source-address[$row] ,$destination-address[$row] , $application[$row] , $action, $comment);
085
            call print-policy($row = $row + 1, $num-rows, $source-address, $destination-address,$application);
086
        }
087
    }
088
}
089
 
090
/* find-zone: Returns the zone where a given IP is */
091
template find-zone ($ip) {
092
     
093
    if ($ip == "0.0.0.0/0") {
094
        expr "any";
095
     
096
    } else {
097
        var $get-route-rpc = <command> {
098
            expr "show route ";
099
            expr $ip;
100
            expr " active-path best";
101
        }
102
        var $get-rotue = jcs:execute($connection, $get-route-rpc);
103
        var $zone = {
104
            if ($get-rotue//via) {
105
                var $get-int-rpc = <command> {
106
                    expr "show interface ";
107
                    expr $get-rotue//via;
108
                }
109
                var $get-int = jcs:execute($connection, $get-int-rpc);
110
                 
111
                expr $get-int//logical-interface-zone-name;
112
             
113
            } else {
114
                expr "any";
115
            }
116
        }
117
         
118
        expr $zone;
119
    }
120
}
121
 
122
/* rshift: Shifts bits to the right. Used to do an IP/MASK comparision */
123
template rshift ($number, $count) {
124
     
125
    /* <output>
126
    <xsl:value-of select="jcs:printf('Shifting %i %i times\n',$number, $count)"/>    
127
    </output> */
128
    if ($count <= 0) {
129
        expr $number;
130
     
131
    } else {
132
        call rshift($number = floor($number div 2), $count = ($count) - 1);
133
    }
134
}
135
 
136
/* match-ip: Returns true if the ip is in the prefix */
137
template match-ip ($prefix, $ip) {
138
    var $bytes-network = jcs:regex("([0-9]+).([0-9]+).([0-9]+).([0-9]+)/([0-9]+)", $prefix);
139
    var $subnet = {
140
        call rshift($number = $bytes-network[2] * 16777216 + $bytes-network[3] * 65536 + $bytes-network[4] * 256 + $bytes-network[5], $count = 32 -($bytes-network[6]));
141
    }
142
    var $bytes-ip = jcs:regex("([0-9]+).([0-9]+).([0-9]+).([0-9]+)", $ip);
143
    var $ipnet = {
144
        call rshift($number = $bytes-ip[2] * 16777216 + $bytes-ip[3] * 65536 + $bytes-ip[4] * 256 +$bytes-ip[5], $count = 32 - $bytes-network[6]);
145
    }
146
     
147
    if ($ipnet == $subnet) {
148
        expr true();
149
     
150
    } else {
151
        expr false();
152
    }
153
}
154
 
155
/* match-prefix-list: Returns true if the ip is in the prefix list */
156
template match-prefix-list ($ip, $prefix-list) {
157
     
158
    if (not($prefix-list)) {
159
        expr false();
160
     
161
    } else {
162
        var $match-prefix = {
163
            call match-ip($ip, $prefix = $prefix-list);
164
        }
165
         
166
        if ($match-prefix == "true") {
167
            expr true();
168
         
169
        } else {
170
            call match-prefix-list($ip, $prefix-list = $prefix-list[position() > 1]);
171
        }
172
    }
173
}
174
 
175
match / {
176
    <op-script-results> {
177
        /* First, check parameters passed */
178
        if (not(jcs:parse-ip($source-address))) {
179
            <output> jcs:printf("Bad IP address format: %s
180
", $source-address);
181
         
182
        } else if (not(jcs:parse-ip($destination-address))) {
183
            <output> jcs:printf("Bad IP address format: %s
184
", $destination-address);
185
         
186
        } else if (not($source-port >= 0 && $source-port <= 65535)) {
187
            <output> jcs:printf("Bad IP port number: %s
188
", $source-port);
189
         
190
        } else if (not($destination-port >= 0 && $destination-port <= 65535)) {
191
            <output> jcs:printf("Bad IP port number: %s
192
", $destination-port);
193
         
194
        } else {
195
            <output> {
196
                call print-policy($header = true());
197
            }
198
            var $filters = {
199
                if ($from-zone != "any") {
200
                    expr " from-zone ";
201
                    expr $from-zone;
202
                }
203
                if ($to-zone != "any") {
204
                    expr " to-zone ";
205
                    expr $to-zone;
206
                }
207
            }
208
            var $get-policies-rpc = <command> {
209
                expr " show security policies ";
210
                expr $filters;
211
                expr " detail ";
212
            }
213
            /* Get the list of possible policies */
214
            var $policies = jcs:execute($connection, $get-policies-rpc);
215
            /* Loop throught the policies to find the matching ones */
216
             
217
            for-each ($policies//policy-information) {
218
                var $match-source = {
219
                    call match-prefix-list($ip = $source-address, $prefix-list = .//source-address//address-prefix);
220
                }
221
                var $match-destination = {
222
                    call match-prefix-list($ip = $destination-address, $prefix-list = .//destination-address//address-prefix);
223
                }
224
                var $match-destination-port = {
225
                    if ($destination-port == "0") {
226
                        expr true();
227
                     
228
                    } else if (./applications/application/application-term/destination-port-range[low =="0" && high == "0"]) {
229
                        expr true();
230
                     
231
                    } else if (./applications/application/application-term/destination-port-range[low <=$destination-port && high >= $destination-port]) {
232
                        expr true();
233
                     
234
                    } else {
235
                        expr false();
236
                    }
237
                }
238
                var $match-source-port = {
239
                    if ($source-port == "0") {
240
                        expr true();
241
                     
242
                    } else if (./applications/application/application-term/source-port-range[low == "0"&& high == "0"]) {
243
                        expr true();
244
                     
245
                    } else if (./applications/application/application-term/source-port-range[low <=$source-port && high >= $source-port]) {
246
                        expr true();
247
                     
248
                    } else {
249
                        expr false();
250
                    }
251
                }
252
                 
253
                /* <output>
254
                <xsl:value-of select="jcs:printf('Policy name: %s\n',./policy-name)"/>
255
                <xsl:value-of select="jcs:printf('  match source: %s\n', $match-source)"/>
256
                <xsl:value-of select="jcs:printf('  match destination: %s\n', $match-destination)"/>
257
                <xsl:value-of select="jcs:printf('  match source port: %s\n', $match-source-port)"/>
258
                <xsl:value-of select="jcs:printf('  match destination port: %s\n', $match-destination-port)"/>
259
                </output> */
260
                if ($match-source == "true" && $match-destination == "true" && $match-source-port =="true" && $match-destination-port == "true") {
261
                    <output> {
262
                        call print-policy($from-zone = ../../context-information/source-zone-name, $to-zone = ../../context-information/destination-zone-name, $name = ./policy-name, $destination-address = ./destination-addresses/destination-address/address-name, $source-address = ./source-addresses/source-address/address-name, $application = ./applications/application/application-name, $action = ./policy-action/action-type);
263
                    }
264
                }
265
            }
266
        }
267
    }
268
}

 

XML Script Contents

 
 
 
01 <?xml version="1.0"?>
02 <script>
03 <title>policy-test.slax</title>
04 <author>rcameron</author>
05 <synopsis>
06 Given a sample packet (i.e. source-address, dst-address, ports, etc) it returns the list of matching policies
07 </synopsis>
08 <coe>op</coe>
09 <type>display</type>
10  
11 <description>
12 This script performs a lookup in the policy table and returns the matching policies based on the search criteria.
13    
14  
15 </description>
16  
17  <example>
18  <title>Example</title>
19  <output>example-1.output</output>
20  </example>
21  
22 <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
23 src="../../../../../web/leaf.js"
24 type="text/javascript"/>
25 </script>

#How-To
#opscript
#Slax
#ScriptingHow-To