Initial commit
Benjamin Renard

Benjamin Renard commited on 2014-01-13 16:42:54
Showing 3 changed files, with 354 additions and 0 deletions.

... ...
@@ -0,0 +1 @@
1
+*~
... ...
@@ -0,0 +1,37 @@
1
+Convert Cisco ACLs to iptables commands
2
+=======================================
3
+
4
+This script permit to convert Cisco ACLs to ipbtales commands. This script take as input
5
+the result of "show run" command from Cisco firewall, detect line starting by "access-list "
6
+and convert them to iptables command.
7
+
8
+You can add iptables arguments by using [add to iptables command] parameter.
9
+
10
+To debug, use [-d] parameter that will display how this script as parse and understand the
11
+ACL line. 
12
+
13
+Usage
14
+-----
15
+
16
+	cisco-acl-to-iptables [rule file] [add to iptables command] [-d]
17
+
18
+Copyright
19
+---------
20
+
21
+Copyright (c) 2013 Benjamin Renard
22
+
23
+License
24
+-------
25
+
26
+This program is free software; you can redistribute it and/or
27
+modify it under the terms of the GNU General Public License version 2
28
+as published by the Free Software Foundation.
29
+
30
+This program is distributed in the hope that it will be useful,
31
+but WITHOUT ANY WARRANTY; without even the implied warranty of
32
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33
+GNU General Public License for more details.
34
+
35
+You should have received a copy of the GNU General Public License
36
+along with this program; if not, write to the Free Software
37
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
... ...
@@ -0,0 +1,316 @@
1
+#!/bin/bash
2
+
3
+DEBUG=0
4
+ADD_COMMENT=1
5
+PERMIT='ACCEPT'
6
+DENY='DROP'
7
+
8
+IN=$1
9
+[ ! -f "$IN" ] && echo "Usage : $0 [rule file] [add to iptables command] [-d]" && exit 1
10
+
11
+ADD_TO_IPTABLES_CMD=$2
12
+
13
+[ "$2" == "-d" -o "$3" == "-d" ] && DEBUG=1
14
+
15
+function get_word() {
16
+	echo "$1"|awk "{print \$$2}"
17
+}
18
+
19
+function is_valid_ip() {
20
+	ip="$1"
21
+	if [ "$( echo "$ip"| egrep -c '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' )" == "1" ]
22
+	then
23
+		for i in $( seq 1 4 )
24
+		do
25
+			O=$( echo "$ip"|cut -d '.' -f $i )
26
+			[ $O -lt 0 -o $O -gt 254 ] && echo $i && return $i
27
+		done
28
+		echo 0
29
+		return 0
30
+	fi
31
+	echo 1
32
+	return 1
33
+}
34
+
35
+function convert_mask() {
36
+	mask="$1"
37
+	if [ "$( echo "$mask"| egrep -c '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' )" == "1" ]
38
+	then
39
+		NETMASK=""
40
+		for i in $( seq 1 4 )
41
+		do
42
+			O=$( echo "$mask"|cut -d '.' -f $i )
43
+			[ $O -lt 0 -o $O -gt 255 ] && echo "" && return $i
44
+			let o=255-O
45
+			NETMASK="$NETMASK.$o"
46
+		done
47
+		echo $NETMASK|sed 's/^\.//'
48
+		return 0
49
+	fi
50
+	echo ""
51
+	return 1
52
+}
53
+
54
+function convert_netmask_to_cidr() {
55
+	mask="$1"
56
+	if [ "$( echo "$mask"| egrep -c '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' )" == "1" ]
57
+	then
58
+		CIDR=0
59
+		for i in $( seq 1 4 )
60
+		do
61
+			O=$( echo "$mask"|cut -d '.' -f $i )
62
+			if [ "$O" == "0" ]
63
+			then
64
+				continue
65
+			elif [ "$O" == "128" ]
66
+			then
67
+				let CIDR=CIDR+1
68
+			elif [ "$O" == "192" ]
69
+			then
70
+				let CIDR=CIDR+2
71
+			elif [ "$O" == "224" ]
72
+			then
73
+				let CIDR=CIDR+3
74
+			elif [ "$O" == "240" ]
75
+			then
76
+				let CIDR=CIDR+4
77
+			elif [ "$O" == "248" ]
78
+			then
79
+				let CIDR=CIDR+5
80
+			elif [ "$O" == "252" ]
81
+			then
82
+				let CIDR=CIDR+6
83
+			elif [ "$O" == "254" ]
84
+			then
85
+				let CIDR=CIDR+7
86
+			elif [ "$O" == "255" ]
87
+			then
88
+				let CIDR=CIDR+8
89
+			else
90
+				echo ""
91
+				return $i
92
+			fi
93
+		done
94
+		echo $CIDR
95
+		return 0
96
+	fi
97
+	echo ""
98
+	return 1
99
+}
100
+
101
+function convert_ip_mask_to_arg() {
102
+	IP="$1"
103
+	MASK="$2"
104
+	CIDR="$( convert_netmask_to_cidr "$MASK" )"
105
+	if [ "$CIDR" == "" ]
106
+	then
107
+		echo "Error converting netmask $MASK to CIDR (Result : $CIDR | Code : $?). Stop." > /dev/stderr
108
+		echo ""
109
+		return 1
110
+	elif [ "$CIDR" == "32" ]
111
+	then
112
+		echo "$IP"
113
+	elif [ "$CIDR" == "0" -a "$IP" == "0.0.0.0" ]
114
+	then
115
+		echo "0/0"
116
+	else
117
+		echo "$IP/$CIDR"
118
+	fi
119
+}
120
+
121
+function print_acl_details() {
122
+	echo "ACL : $line
123
+Action : $ACL_ACTION
124
+Protocole : $ACL_PROTO
125
+Groupe : $ACL_GROUP
126
+Source : $ACL_SRC_NET/$ACL_SRC_MASK
127
+Source services : '$ACL_SRC_PORTS'
128
+Destination : $ACL_DST_NET/$ACL_DST_MASK
129
+Destination services : '$ACL_DST_PORTS'"
130
+}
131
+
132
+function convert_2_iptables_cmd() {
133
+	MULTIPORTS=0
134
+	CMD="iptables -I FORWARD"
135
+	[ "$ACL_PROTO" != 'ip' ] && CMD="$CMD $ADD_TO_IPTABLES_CMD -p $ACL_PROTO"
136
+	
137
+	SRC="$( convert_ip_mask_to_arg "$ACL_SRC_NET" "$ACL_SRC_MASK" )"
138
+	[ "$SRC" == "" ] && echo "ERROR : Fail to convert source" > /dev/stderr && return 1
139
+	[ "$SRC" != "0/0" ] && CMD="$CMD -s $SRC"
140
+
141
+	if [ "$ACL_SRC_PORTS" != "any" ]
142
+	then
143
+		if [ $( echo "$ACL_SRC_PORTS"|sed 's/ /\n/'|wc -l ) -gt 1 ]
144
+		then
145
+			MULTIPORTS=1
146
+			PORTS=""
147
+			for p in $ACL_SRC_PORTS
148
+			do
149
+				PORTS=",$PORTS"
150
+			done
151
+			CMD="$CMD -m multiport --sports $( echo "$PORTS"|sed 's/^,//' )"
152
+		else
153
+			CMD="$CMD --sport $ACL_SRC_PORTS"
154
+		fi
155
+	fi
156
+
157
+	DST="$( convert_ip_mask_to_arg "$ACL_DST_NET" "$ACL_DST_MASK" )"
158
+	[ "$DST" == "" ] && echo "ERROR : Fail to convert destination" > /dev/stderr && return 1
159
+	[ "$DST" != "0/0" ] && CMD="$CMD -d $DST"
160
+
161
+	if [ "$ACL_DST_PORTS" != "any" ]
162
+	then
163
+		if [ $( echo "$ACL_DST_PORTS"|sed 's/ /\n/'|wc -l ) -gt 1 ]
164
+		then
165
+			PORTS=""
166
+			for p in $ACL_DST_PORTS
167
+			do
168
+				PORTS=",$PORTS"
169
+			done
170
+			[ $MULTIPORTS -eq 0 ] && CMD="$CMD -m multiport"
171
+			CMD="$CMD --dports $( echo "$PORTS"|sed 's/^,//' )"
172
+		else
173
+			CMD="$CMD --dport $ACL_DST_PORTS"
174
+		fi
175
+	fi
176
+
177
+	if [ "$ACL_ACTION" == "permit" ]
178
+	then
179
+		CMD="$CMD -j $PERMIT"
180
+	elif [ "$ACL_ACTION" == "deny" ]
181
+	then
182
+		CMD="$CMD -j $DENY"
183
+	else
184
+		echo "ERROR : Action '$ACL_ACTION' not recognized" > /dev/stderr
185
+		return 1
186
+	fi
187
+	
188
+	echo $CMD
189
+}
190
+
191
+IFS="
192
+"
193
+for line in $( cat "$IN"|egrep "^access-list " )
194
+do
195
+	# Reset
196
+	word=""
197
+	ACL_ACTION=""
198
+	ACL_PROTO=""
199
+	ACL_GROUP=""
200
+	ACL_SRC_NET=""
201
+	ACL_SRC_MASK=""
202
+	ACL_SRC_PORTS=""
203
+	ACL_DST_NET=""
204
+	ACL_DST_MASK=""
205
+	ACL_DST_PORTS=""
206
+
207
+	field=2
208
+	ACL_GROUP="$( get_word "$line" $field )"
209
+
210
+	field=3
211
+	ACL_ACTION="$( get_word "$line" $field )"
212
+	if [ "$ACL_ACTION" != "permit" -a "$ACL_ACTION" != "deny" ]
213
+	then
214
+		echo "ERROR : Action not recognized in $( print_acl_details )"
215
+		continue
216
+	fi
217
+
218
+	field=4
219
+	ACL_PROTO="$( get_word "$line" $field )"
220
+
221
+	field=5
222
+	ACL_SRC_NET="$( get_word "$line" $field )"
223
+
224
+	if [ "$ACL_SRC_NET" == "any" ]
225
+	then
226
+		ACL_SRC_NET="0.0.0.0"
227
+		ACL_SRC_MASK="0.0.0.0"
228
+	elif [ "$ACL_SRC_NET" == "host" ]
229
+	then
230
+		let field=field+1
231
+		ACL_SRC_NET="$( get_word "$line" $field )"
232
+		[ $( is_valid_ip "$ACL_SRC_NET" ) -ne 0 ] && echo "ERROR : Source host IP address not recognized in $( print_acl_details )" && continue
233
+		ACL_SRC_MASK="255.255.255.255"
234
+	elif [ "$( is_valid_ip "$ACL_SRC_NET" )" == "0" ]
235
+	then
236
+		let field=field+1
237
+		ACL_SRC_MASK="$( get_word "$line" $field )"
238
+		ACL_SRC_MASK=$( convert_mask "$ACL_SRC_MASK" )
239
+		[ "$ACL_SRC_MASK" == "" ] && echo "ERROR : Source mask not recognized in $( print_acl_details )" && continue
240
+	else
241
+		echo "ERROR : Source net not recognized in ACL, pass : $line"
242
+		continue
243
+	fi
244
+
245
+	let field=field+1
246
+	word="$( get_word "$line" $field )"
247
+	if [ "$word" == "eq" ]
248
+	then
249
+		ACL_SRC_PORTS=""
250
+		while [ true ]
251
+		do
252
+			let field=field+1
253
+			word="$( get_word "$line" $field )"
254
+			[ "$word" == "" -o "$word" == "host" -o "$word" == "any" -o "$( is_valid_ip "$word" )" == "0" ] && break
255
+			ACL_SRC_PORTS="$ACL_SRC_PORTS $word"
256
+		done
257
+		if [ "$ACL_SRC_PORTS" == " " ]
258
+		then
259
+			ACL_SRC_PORTS="any"
260
+		else
261
+			ACL_SRC_PORTS=$( echo "$ACL_SRC_PORTS"|sed 's/^ //' )
262
+		fi
263
+	else
264
+		ACL_SRC_PORTS="any"
265
+	fi
266
+
267
+	if [ "$word" == "any" ]
268
+	then
269
+		ACL_DST_NET="0.0.0.0"
270
+		ACL_DST_MASK="0.0.0.0"
271
+	elif [ "$word" == "host" ]
272
+	then
273
+		let field=field+1
274
+		ACL_DST_NET="$( get_word "$line" $field )"
275
+		[ $( is_valid_ip "$ACL_DST_NET" ) -ne 0 ] && echo "ERROR : Destination host IP address not recognized in $( print_acl_details )" && continue
276
+		ACL_DST_MASK="255.255.255.255"
277
+	elif [ "$( is_valid_ip "$word" )" == "0" ]
278
+	then
279
+		ACL_DST_NET="$word"
280
+		let field=field+1
281
+		ACL_DST_MASK="$( get_word "$line" $field )"
282
+		if [ "$ACL_DST_MASK" == "" ]
283
+		then
284
+			ACL_DST_MASK="255.255.255.255"
285
+		else
286
+			ACL_DST_MASK=$( convert_mask "$ACL_DST_MASK" )
287
+			[ "$ACL_DST_MASK" == "" ] && echo "ERROR : Destination mask not recognized in $( print_acl_details )" && continue
288
+		fi
289
+	fi
290
+
291
+	let field=field+1
292
+	word="$( get_word "$line" $field )"
293
+	if [ "$word" == "" ]
294
+	then
295
+		ACL_DST_PORTS="any"
296
+	elif [ "$word" == "eq" ]
297
+	then
298
+		ACL_DST_PORTS=""
299
+		while [ true ]
300
+		do
301
+			let field=field+1
302
+			word="$( get_word "$line" $field )"
303
+			[ "$word" == "" ] && break
304
+			ACL_DST_PORTS="$ACL_DST_PORTS $word"
305
+		done
306
+		ACL_DST_PORTS=$( echo "$ACL_DST_PORTS"|sed 's/^ //' )
307
+	else
308
+		echo "ERROR : Destination port(s) specification not recognized (word = $word) in $( print_acl_details )"
309
+		continue
310
+	fi
311
+
312
+	[ $DEBUG -eq 1 ] && print_acl_details
313
+	[ $ADD_COMMENT -eq 1 ] && echo "# ACL : $line"
314
+	convert_2_iptables_cmd
315
+	echo
316
+done
0 317