Using Just a Cisco ASA to Block Specific Websites

| Comments

When doing web traffic monitoring, policing and blocking it is best to use a web proxy like Ironport WSA, BlueCoat, WebSense or something that is good at doing it. However if you are in a pinch and don’t have that you can use the firewall to block particular URLs. There are two ways to do this: using fqdn objects and regex’s.

Block URLs using FQDN objects

The Cisco ASA firewall 8.4.2 introduced something called Identity Firewall. The IDFW gives a new level of control to ACLs. You can now configured ACLs to block domain names.

Configure the ASA to resolve DNS

In order for the firewall to block a domain name it has to be able to resolve domain names. Use your own DNS server if you have it. Otherwise using a public DNS server will look something like this:

dns domain-lookup OUTSIDE
DNS server-group DefaultDNS
    name-server 4.2.2.2

Make sure you can ping a url like google.com from the firewall to verify your ASA is resolving DNS correctly.

Create the object

Suppose we want to block access to Google.com. Create an object with google.com in it.

object network OBJ-GOOGLE.COM
 fqdn google.com

Add the object to an ACL

Now it’s just a matter of adding it to the right ACL. Here is what the command looks like:

access-list ACL-INSIDE line 1 extended deny ip any object OBJ-GOOGLE.COM

This is what it should look like after you do a show access-list

access-list ACL-INSIDE line 1 extended deny ip any object OBJ-GOOGLE.COM 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any fqdn google.com (resolved) 0x827c8780 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.163 (google.com) (hitcnt=73) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.165 (google.com) (hitcnt=3) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.162 (google.com) (hitcnt=7) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.169 (google.com) (hitcnt=23) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.174 (google.com) (hitcnt=130) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.164 (google.com) (hitcnt=21) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.168 (google.com) (hitcnt=14) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.161 (google.com) (hitcnt=12) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.167 (google.com) (hitcnt=3) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.160 (google.com) (hitcnt=20) 0x8e6d59a8 
access-list ACL-INSIDE line 1 extended deny ip any host 74.125.224.166 (google.com) (hitcnt=4) 0x8e6d59a8 

Notice the ASA resolved the domain name and added all of the IPs in the ACL. This will be updated based on the TTL of the DNS request it made to resolve the IP.

And this is what the syslog looks like:

Mar 23 2012 11:58:07: %ASA-4-106023: Deny tcp src INSIDE:172.16.2.21/2414 dst OUTSIDE:74.125.224.160/443(google.com) by access-group "ACL-INSIDE" [0x1e144444,0x1e144444]

A cool thing about this solution is that it doesn’t slow down the firewall at all. It does the DNS look up probably once every few hours for when the TTL expires and then stores the IPs in memory. In other words it does not do a DNS lookup for every packet that comes through the firewall, it does it before hand.

What I also like about this solution is that this works for both HTTPS and HTTP. The firewall doesn’t inspect domain names or URLs and it doesn’t care if the packet is encrypted or not. The packet has to have a destination IP and that’s what the firewall will check.

Special Note: This does not resolve all subdomain of google like www.google.com, mail.google.com, maps.google.com etc. You’ll have to create a seperate object for each of these domains to cover all the bases.

Block URLs using REGEX’s

Important note: There is a HUGE limitation that comes with this however. This can ONLY inspect HTTP traffic. Since HTTPS traffic is encrypted, the ASA does not have the functionality to inspect that type of packets.

Example 1: Block traffic going to a specific URL

Suppose you want to block all http traffic going to “example.com” and “somewebsite.com”. This script will effectively inspect all traffic and drop-connection if the packet has either website name in the header of the http packet.

! Define the websites we wish to block
regex REG-URL1 "example\.com"
regex REG-URL2 "somewebsite\.com"

! Set a class to match if the header has any of the URLs in it
class-map type inspect http match-any CM-BLOCK-URL
match request header host regex REG-URL1
match request header host regex REG-URL2

! Create a policy map to drop the connection if it matches the class map
policy-map type inspect http PM-BLOCK-URL
parameters
class CM-BLOCK-URL
drop-connection log

! Apply the policy
policy-map global_policy
class inspection_default
inspect http PM-BLOCK-URL

service-policy global_policy global

Example 2: Only allow certain URLs into your network.

Suppose you have a webserver at 10.1.1.1 that has a DNS of “mywebsite.com” and also responds to “example.com”.  This script will block all URL requests that don’t have either of those domains in the header of the http packet. The reason for this is if a DNS server gets poisoned and starts sending thousands of HTTP requests to your website that it doesn’t belong to, we can use the ASA to block the traffic instead of killing the webserver. To understand the class-map concept here just keep in mind that the class-map will quit if it finds a match to the regex, if it doesn’t match than it completes and issues the drop-connection action.

! Identify the 3 URLs that will be permitted in
regex REG-URL1 "mywebsite\.com"
regex REG-URL2 "example\.com"

! Identify the ACL that will be subject to this inspection
access-list ACL-HTTP-INSPECT ext permit tcp any host 10.1.1.1 eq 80

class-map CM-ALLOW-HTTP
match access-list ACL-HTTP-INSPECT

! Create a class map to pass or ‘permit’ the traffic if the URL isn’t ANY of the regex’s
class-map type inspect http match-all CM-ALLOWED-URLS
match not request header host regex REG-URL1
match not request header host regex REG-URL2

! Create the policy map to drop any packets that passed the class map

policy-map type inspect http PM-ALLOW-HTTP
parameters
class CM-ALLOWED-URLS
drop-connection log

! Apply the Policy
policy-map global_policy
class CM-ALLOW-HTTP
inspect http PM-ALLOW-HTTP

service-policy global_policy global

For more information Cisco has a pretty good set of examples that you can find here:

https://supportforums.cisco.com/docs/DOC-1268 http://www.cisco.com/en/US/products/ps6120/products_configuration_example09186a0080940e04.shtml

asa, cisco, class-map, filtering, policy-map, scripts, url

Comments