Using Powershell to delimit firewall ACLs
I am a relative newbie to Powershell, but really love it. I am new enough where, when presented with a somewhat complex problem, I just frustratingly flail arround. I have a couple of projects where I can use knowledge gained from this thread, but the immediate one involves parsing out some Cisco firewall ACLs. Once I get them parsed, I can do anything with them...use ft to make them more digestible within PS, import directly into a DB or Excel.
But I cannot quite figure out how to get there. The way I have been trying to attack it is to think how I can get everything between, for example, spaces 3 and 5 in a string after a particular substring occurs. Might be barking up the wrong tree. Is there any way that I can delimit substrings with powershell? My application is to delimit Cisco ACL strings in order to further process them, export them, etc. Here are some example entries:access-list inside_access_in extended permit tcp object-group SiteLocal-Network object-group Server-DataCenter-IntranetServers Object-group Sharepoint
access-list inside_access_in extended permit udp object-group SiteLocal-Network object-group Server-DataCenter-DomainControllers eq domain
access-list inside_access_in extended permit tcp object-group SiteLocal-MSSMSServer object-group Server-w2k3s-DataCenter-08 eq 445
access-list inside_access_in extended permit tcp object-group SiteLocal-DomainControllers object-group Server-DataCenter-SQL range 1024 65535
access-list SalesOffice_DataCenter_vpn extended permit ip 10.1.1.0 255.255.252.0 10.2.2.0 255.255.252.0
access-list inside_access_in extended deny ip any any
access-list outside_access_in remark Allow ping to work
Here is a format I would like and the way I have been trying to attack it:ACL | Permit_Rem | Prot | Source | Dest | Eq
ACL = everything prior to permit/deny/remark
Permit_Rem = permit/deny/remark (if value != "permit" or "deny," assume "remark" insert 4x "|" delimiters then process Eq field)
Prot = tcp/udp/ip
Source = everything 1-3 spaces from tcp/udp/ip
Dest = everything 3-5 spaces from tcp/udp/ip
Eq = everything from 5th space to end
Here are some manually delimited entries:
access-list inside_access_in extended | permit | tcp | object-group SiteLocal-Network | object-group Server-DataCenter-IntranetServers | Object-group Sharepoint
access-list inside_access_in extended | permit | udp | object-group SiteLocal-Network | object-group Server-DataCenter-DomainControllers | eq domain
access-list inside_access_in extended | permit | tcp | object-group SiteLocal-MSSMSServer | object-group Server-w2k3s-DataCenter-08 | eq 445
access-list inside_access_in extended | permit | tcp | object-group SiteLocal-DomainControllers | object-group Server-DataCenter-SQL | range 1024 65535
access-list SalesOffice_DataCenter_vpn extended | permit | ip | 10.1.1.0 255.255.252.0 | 10.2.2.0 255.255.252.0 |
access-list inside_access_in extended | deny | ip | any | any |
access-list outside_access_in | remark | | | | Allow ping to workNotes:
1) The above combines "Permit" and "Remark" fields into "Permit_Rem" field. Posisble values are Permit, Deny, and "Remark
2) Possible values for Prot (Protocol) are TCP, UDP, and IP
3) Source and Dest fields both can use "object group + name" OR "network + subnet" notation
4) Eq field can use remark text, "object group + name", " eq + name or port number", or " range + two port numbers" as valueThanks very much for your help.
Answers
I believe this will take care of the first example.
Feed it the ACL text strings as $acl_entry. It should spit out an array of psobjects with a property for each field.
$regex1 = "^(.+)\s*((?:permit)|(?:deny))\s*(($:tcp)|(?:udp)|(?:ip))\s*"
$regex1 += "(object-group\s*\S+)\s*(object-group\s*\S+)\s*(object-group\s*\S+)"$acl_col=@()
if ($acl_entry -match $regex1){
$ace = ""|select ACL,Permit_Rem,Prot,Source,Dest,Eq
$ace.acl = $matches[1]
$ace.permit_rem = $matches[2]
$ace.prot = $matches[3]
$ace.source = $matches[4]
$ace.dest = $matches[5]
$ace.eq = $matches[6]
$acl_col += $ace
}
$acl_col
"You have a problem. You've decided to fix it with a regular expression. Now you have two problems"
-source unknow- Marked As Answer byIamMredMSFT, OwnerMonday, January 11, 2010 3:01 AM
- Edited bymjolinor Saturday, November 21, 2009 3:50 AMsynapse misfire
All Replies
I believe this will take care of the first example.
Feed it the ACL text strings as $acl_entry. It should spit out an array of psobjects with a property for each field.
$regex1 = "^(.+)\s*((?:permit)|(?:deny))\s*(($:tcp)|(?:udp)|(?:ip))\s*"
$regex1 += "(object-group\s*\S+)\s*(object-group\s*\S+)\s*(object-group\s*\S+)"$acl_col=@()
if ($acl_entry -match $regex1){
$ace = ""|select ACL,Permit_Rem,Prot,Source,Dest,Eq
$ace.acl = $matches[1]
$ace.permit_rem = $matches[2]
$ace.prot = $matches[3]
$ace.source = $matches[4]
$ace.dest = $matches[5]
$ace.eq = $matches[6]
$acl_col += $ace
}
$acl_col
"You have a problem. You've decided to fix it with a regular expression. Now you have two problems"
-source unknow- Marked As Answer byIamMredMSFT, OwnerMonday, January 11, 2010 3:01 AM
- Edited bymjolinor Saturday, November 21, 2009 3:50 AMsynapse misfire