Friday, October 7, 2016

The Whole Internet Again!

Several years ago I wrote a post about how to write firewall rules to include or exclude the whole internet, but JUST the internet. I found I needed that chunk of ASA config again, so I came back to get it. Thanks to a commenter earlier this year in an old post, who noticed that I was missing a block of includes, I've updated the list. A chunk of the 203.0.0.0 space was missing. I've also excluded the RFC6598 CGN private space.

And it's still only IPv4.

 (Exclude 0.0.0.0 - 0.255.255.255)
 1.0.0.0      /8 = 1.0.0.0 - 1.255.255.255
 2.0.0.0      /7 = 2.0.0.0 - 3.255.255.255
 4.0.0.0      /6 = 4.0.0.0 - 7.255.255.255
 8.0.0.0      /7 = 8.0.0.0 - 9.255.255.255
 (Exclude 10.0.0.0 - 10.255.255.255)
 11.0.0.0     /8 = 11.0.0.0 - 11.255.255.255
 12.0.0.0     /6 = 12.0.0.0 - 15.255.255.255
 16.0.0.0     /4 = 16.0.0.0 - 31.255.255.255
 32.0.0.0     /3 = 32.0.0.0 - 63.255.255.255
 64.0.0.0     /3 = 64.0.0.0 - 95.255.255.255
 96.0.0.0     /6 = 96.0.0.0 - 99.255.255.255
 100.0.0.0   /10 = 100.0.0.0 - 100.63.255.255
 (Exclude 100.64.0.0 - 100.127.255.255)
 100.128.0.0 /9 = 100.128.0.0 - 100.255.255.255
 101.0.0.0    /8 = 101.0.0.0 - 101.255.255.255
 102.0.0.0    /7 = 102.0.0.0 - 103.255.255.255
 104.0.0.0    /5 = 104.0.0.0 - 111.255.255.255
 112.0.0.0    /5 = 112.0.0.0 - 119.255.255.255
 120.0.0.0    /6 = 120.0.0.0 - 123.255.255.255
 124.0.0.0    /7 = 124.0.0.0 - 125.255.255.255
 126.0.0.0    /8 = 126.0.0.0 - 126.255.255.255
 (Exclude 127.0.0.0 - 127.255.255.255)
 128.0.0.0    /3  = 128.0.0.0 - 159.255.255.255
 160.0.0.0    /5  = 160.0.0.0 - 167.255.255.255
 168.0.0.0    /8  = 168.0.0.0 - 168.255.255.255
 169.0.0.0    /9  = 169.0.0.0 - 169.127.255.255
 169.128.0.0  /10 = 169.128.0.0 - 169.191.255.255
 169.192.0.0  /11 = 169.192.0.0 - 169.223.255.255
 169.224.0.0  /12 = 169.224.0.0 - 169.239.255.255
 169.240.0.0  /13 = 169.240.0.0 - 169.247.255.255
 169.248.0.0  /14 = 169.248.0.0 - 169.251.255.255
 169.252.0.0  /15 = 169.252.0.0 - 169.253.255.255
 (Exclude 169.254.0.0 - 169.254.255.255)
 169.255.0.0  /16 = 169.255.0.0 - 169.255.255.255
 170.0.0.0    /7  = 170.0.0.0 - 171.255.255.255
 172.0.0.0    /12 = 172.0.0.0 - 172.15.255.255
 (Exclude 172.16.0.0 - 172.31.255.255)
 172.32.0.0   /11 = 172.32.0.0 - 172.63.255.255
 172.64.0.0   /10 = 172.64.0.0 - 172.127.255.255
 172.128.0.0  /9  = 172.128.0.0 - 172.255.255.255
 173.0.0.0    /8  = 173.0.0.0 - 173.255.255.255
 174.0.0.0    /7  = 174.0.0.0 - 175.255.255.255
 176.0.0.0    /4  = 176.0.0.0 - 191.255.255.255
 (Exclude 192.0.0.0 - 192.0.0.255)
 192.0.1.0    /24 = 192.0.1.0 - 192.0.1.255
 (Exclude 192.0.2.0 - 192.0.2.255)
 192.0.3.0    /24 = 192.0.3.0 - 192.0.3.255
 192.0.4.0    /22 = 192.0.4.0 - 198.0.7.255
 192.0.8.0    /21 = 192.0.8.0 - 192.0.15.255
 192.0.16.0   /20 = 192.0.16.0 - 192.0.31.255
 192.0.32.0   /19 = 192.0.32.0 - 192.0.63.255
 192.0.64.0   /18 = 192.0.64.0 - 192.0.127.255
 192.0.128.0  /17 = 192.0.128.0 - 192.0.255.255
 192.1.0.0    /16 = 192.1.0.0 - 192.1.255.255
 192.2.0.0    /15 = 192.2.0.0 - 192.3.255.255
 192.4.0.0    /14 = 192.4.0.0 - 192.7.255.255
 192.8.0.0    /13 = 192.8.0.0 - 192.15.255.255
 192.16.0.0   /12 = 192.16.0.0 - 192.31.255.255
 192.32.0.0   /11 = 192.32.0.0 - 192.63.255.255
 192.64.0.0   /10 = 192.64.0.0 - 192.127.255.255
 192.128.0.0  /11 = 192.128.0.0 - 192.159.255.255
 192.160.0.0  /13 = 192.160.0.0 - 192.167.255.255
 (Exclude 192.168.0.0 /16)
 192.169.0.0  /16 = 192.169.0.0 - 192.169.255.255
 192.170.0.0  /15 = 192.170.0.0 - 192.171.255.255
 192.172.0.0  /14 = 192.172.0.0 - 192.175.255.255
 192.176.0.0  /12 = 192.176.0.0 - 192.191.255.255
 192.192.0.0  /10 = 192.192.0.0 - 192.255.255.255
 193.0.0.0    /8  = 193.0.0.0 - 193.255.255.255
 194.0.0.0    /7  = 194.0.0.0 - 195.255.255.255
 196.0.0.0    /7  = 196.0.0.0 - 197.255.255.255
 198.0.0.0    /12 = 198.0.0.0 - 198.15.255.255
 198.16.0.0   /15 = 198.16.0.0 - 198.17.255.255
 (Exclude 198.18.0.0 /15)
 198.20.0.0   /14 = 198.20.0.0 - 198.23.255.255
 198.24.0.0   /13 = 198.24.0.0 - 198.31.255.255
 198.32.0.0   /12 = 198.32.0.0 - 198.47.255.255
 198.48.0.0   /15 = 198.48.0.0 - 198.49.255.255
 198.50.0.0   /16 = 198.50.0.0 - 198.50.255.255
 198.51.0.0   /18 = 198.51.0.0 - 198.51.63.244
 198.51.64.0  /19 = 198.51.64.0 - 198.51.95.255
 198.51.96.0  /22 = 198.51.96.0 - 198.51.99.255
 (Exclude 198.51.100.0/24)
 198.51.101.0 /24 = 198.51.101.0 - 198.51.101.255
 198.51.102.0 /23 = 198.51.102.0 - 198.51.103.255
 198.51.104.0 /21 = 192.51.104.0 - 198.51.111.255
 198.51.112.0 /20 = 198.51.112.0 - 198.51.127.255
 198.51.128.0 /17 = 198.51.128.0 - 198.51.255.255
 198.52.0.0   /14 = 198.52.0.0 - 192.55.255.255
 198.56.0.0   /13 = 198.56.0.0 - 198.63.255.255
 198.64.0.0   /10 = 198.64.0.0 - 198.127.255.255
 198.128.0.0  /9  = 198.128.0.0 - 192.255.255.255
 199.0.0.0    /8  = 199.0.0.0 - 199.255.255.255
 200.0.0.0    /7  = 200.0.0.0 - 201.255.255.255
 202.0.0.0    /8  = 202.0.0.0 - 202.255.255.255
 203.0.0.0    /18 = 203.0.0.0 - 203.0.63.255
 203.0.64.0   /19 = 203.0.64.0 - 203.0.95.255
 203.0.96.0   /20 = 203.0.96.0 - 203.0.111.255
 203.0.112.0  /24 = 203.0.112.0 - 203.0.112.255
 (Exclude 203.0.113.0/24)
 203.0.114.0  /23 = 203.0.114.0 - 203.0.115.255
 203.0.116.0  /22 = 203.0.116.0 - 203.0.119.255
 203.0.120.0  /21 = 203.0.120.0 - 203.0.127.255
 203.0.128.0  /17 = 203.0.128.0 - 203.0.255.255
 203.1.0.0 /16 = 203.1.0.0 - 203.1.255.255
 203.2.0.0 /15 = 203.2.0.0 - 203.3.255.255
 203.4.0.0 /14 = 203.4.0.0 - 203.7.255.255
 203.8.0.0 /13 = 203.8.0.0 - 203.15.255.255
 203.16.0.0 /12 = 203.16.0.0 - 203.31.255.255
 203.32.0.0 /11 = 203.32.0.0 - 203.63.255.255
 203.64.0.0 /10 = 203.64.0.0 - 203.127.255.255
 203.128.0.0 /9 = 203.128.0.0 - 203.255.255.255
 204.0.0.0    /6  = 204.0.0.0 - 207.255.255.255
 208.0.0.0    /4  = 208.0.0.0 - 223.255.255.255
 (Exclude 224.0.0.0 - 255.255.255.255)

Finally, created an ASA script out of that:

! ASA config-script, subnet-based. (Good for 8.2 and previous) 
! This will create a bunch of unnamed network objects that you may or may not hate. YMMV. Also why are you still running 8.2?

object-group network NET-INET-VALID
 network-object 1.0.0.0      255.0.0.0 
 network-object 2.0.0.0      254.0.0.0 
 network-object 4.0.0.0      252.0.0.0
 network-object 8.0.0.0      254.0.0.0
 network-object 11.0.0.0     255.0.0.0
 network-object 12.0.0.0     252.0.0.0
 network-object 16.0.0.0     240.0.0.0
 network-object 32.0.0.0     224.0.0.0
 network-object 64.0.0.0     224.0.0.0
 network-object 96.0.0.0     240.0.0.0
 network-object 112.0.0.0    248.0.0.0
 network-object 120.0.0.0    252.0.0.0
 network-object 124.0.0.0    254.0.0.0
 network-object 126.0.0.0    255.0.0.0
 network-object 128.0.0.0    224.0.0.0
 network-object 160.0.0.0    248.0.0.0
 network-object 168.0.0.0    255.0.0.0
 network-object 169.0.0.0    255.128.0.0
 network-object 169.128.0.0  255.192.0.0
 network-object 169.192.0.0  255.224.0.0
 network-object 169.224.0.0  255.240.0.0
 network-object 169.240.0.0  255.248.0.0
 network-object 169.248.0.0  255.252.0.0
 network-object 169.252.0.0  255.254.0.0
 network-object 169.255.0.0  255.255.0.0
 network-object 170.0.0.0    254.0.0.0  
 network-object 172.0.0.0    255.240.0.0
 network-object 172.32.0.0   255.224.0.0
 network-object 172.64.0.0   255.192.0.0
 network-object 172.128.0.0  255.128.0.0
 network-object 173.0.0.0    255.0.0.0  
 network-object 174.0.0.0    254.0.0.0  
 network-object 176.0.0.0    240.0.0.0  
 network-object 192.0.1.0    255.255.255.0
 network-object 192.0.3.0    255.255.255.0
 network-object 192.0.4.0    255.255.252.0
 network-object 192.0.8.0    255.255.248.0
 network-object 192.0.16.0   255.255.240.0
 network-object 192.0.32.0   255.255.224.0
 network-object 192.0.64.0   255.255.192.0
 network-object 192.0.128.0  255.255.128.0
 network-object 192.1.0.0    255.255.0.0
 network-object 192.2.0.0    255.254.0.0
 network-object 192.4.0.0    255.252.0.0
 network-object 192.8.0.0    255.248.0.0
 network-object 192.16.0.0   255.240.0.0
 network-object 192.32.0.0   255.224.0.0
 network-object 192.64.0.0   255.192.0.0
 network-object 192.128.0.0  255.224.0.0
 network-object 192.160.0.0  255.248.0.0
 network-object 192.169.0.0  255.255.0.0
 network-object 192.170.0.0  255.254.0.0
 network-object 192.172.0.0  255.252.0.0
 network-object 192.176.0.0  255.248.0.0 
 network-object 192.184.0.0  255.248.0.0
 network-object 192.192.0.0  255.192.0.0
 network-object 193.0.0.0    255.0.0.0
 network-object 194.0.0.0    254.0.0.0
 network-object 196.0.0.0    254.0.0.0
 network-object 198.0.0.0    255.240.0.0
 network-object 198.16.0.0   255.254.0.0
 network-object 198.20.0.0   255.252.0.0
 network-object 198.24.0.0   255.248.0.0
 network-object 198.32.0.0   255.240.0.0
 network-object 198.48.0.0   255.254.0.0
 network-object 198.50.0.0   255.255.0.0
 network-object 198.51.0.0   255.255.192.0
 network-object 198.51.64.0  255.255.224.0
 network-object 198.51.96.0  255.255.252.0
 network-object 198.51.101.0 255.255.255.0
 network-object 198.51.102.0 255.255.254.0
 network-object 198.51.104.0 255.255.248.0
 network-object 198.51.112.0 255.255.240.0
 network-object 198.51.128.0 255.255.128.0
 network-object 198.52.0.0   255.252.0.0
 network-object 198.56.0.0   255.248.0.0
 network-object 198.64.0.0   255.192.0.0
 network-object 198.128.0.0  255.128.0.0
 network-object 199.0.0.0    255.0.0.0
 network-object 200.0.0.0    254.0.0.0
 network-object 202.0.0.0    255.0.0.0
 network-object 203.0.0.0    255.255.192.0
 network-object 203.0.64.0   255.255.224.0
 network-object 203.0.96.0   255.255.240.0
 network-object 203.0.112.0  255.255.255.0
 network-object 203.0.114.0  255.255.254.0
 network-object 203.0.116.0  255.255.252.0
 network-object 203.0.120.0  255.255.248.0
 network-object 203.0.128.0  255.255.128.0
 network-object 203.1.0.0  255.255.0.0
 network-object 203.2.0.0  255.254.0.0
 network-object 203.4.0.0  255.252.0.0
 network-object 203.8.0.0  255.248.0.0
 network-object 203.16.0.0  255.240.0.0
 network-object 203.32.0.0  255.224.0.0
 network-object 203.64.0.0  255.192.0.0
 network-object 203.128.0.0  255.128.0.0
 network-object 204.0.0.0    252.0.0.0
 network-object 208.0.0.0    240.0.0.0


For ASA 8.3 or later, there's also this much simpler range-based version.

! ASA Config script, Range-based (for ASA 8.3 and up)
! 
object network NET-INET-RANGE1  
 range 1.0.0.0      9.255.255.255
object network NET-INET-RANGE2  
 range 11.0.0.0     100.63.255.255
object network NET-INET-RANGE3
 range 100.128.0.0  126.255.255.255
object network NET-INET-RANGE4
 range 128.0.0.0    169.253.255.255
object network NET-INET-RANGE5  
 range 169.255.0.0  172.15.255.255
object network NET-INET-RANGE6  
 range 172.32.0.0   191.255.255.255
object network NET-INET-RANGE7  
 range 192.0.1.0    192.0.1.255
object network NET-INET-RANGE8  
 range 192.0.3.0    192.88.98.255
object network NET-INET-RANGE9  
 range 192.88.100.0 192.167.255.255
object network NET-INET-RANGE10  
 range 192.169.0.0  198.17.255.255
object network NET-INET-RANGE11 
 range 198.20.0.0   198.51.99.255
object network NET-INET-RANGE12 
 range 198.51.101.0 203.0.112.255
object network NET-INET-RANGE13 
 range 203.0.114.0  223.255.255.255
object-group network NET-INET-VALID
 network-object object NET-INET-RANGE1
 network-object object NET-INET-RANGE2
 network-object object NET-INET-RANGE3
 network-object object NET-INET-RANGE4
 network-object object NET-INET-RANGE5
 network-object object NET-INET-RANGE6
 network-object object NET-INET-RANGE7
 network-object object NET-INET-RANGE8
 network-object object NET-INET-RANGE9
 network-object object NET-INET-RANGE10
 network-object object NET-INET-RANGE11
 network-object object NET-INET-RANGE12
 network-object object NET-INET-RANGE13

Monday, September 10, 2012

The Whole Internet?


If you're like me, you may find yourself running into security rules specified by people who write rules for stupid people. They may have a rule that says "Your firewall can have no "permit any" rules of any kind!" Now, I completely understand that. But there are certainly plenty of good reasons to not use those rules. But in a properly implemented firewall design, the occasional permit rule with an "any" in it somewhere is suitable. At least when properly guarded by a well-constructed set of deny rules.

Since the body that audits us requires that we have no permit statements with an "any" of any sort in it, I've had to create a way of permitting access to the internet. I could've, within the letter of the regulations, just created a group that contains something like

  1. permit 0.0.0.0 /1
  2. permit 128.0.0.0 /1
and called it a day. Within the letter, certainly. Not within the spirit. Besides, we all know full well that there's martians and bogons out there that we'd rather not communicate with. Our gear can't reach out and collect the bogon list, so I created an ACL that's the inverse of the martian list (see Cymru and RFC5735). Since static blocking of bogons is a Bad Idea, I ignored the bogons, and just filtered the martians.

Below I've created two different ways to filter the martians: The first is for Cisco ASAs running 8.3 and later. That permits Range network objects, and makes this a piece of cake. 8.2 and previous, you're stuck with subnets, and it's a bit of a mess. 

It turns out that the placement of some of the reserved spaces is about as sub-optimal as possible for inversion (not on power-of-2 bit boundaries), making the inverted list extremely lengthy


Rather than this lengthy and performance impacting group, it could be better to create a minimally
strict "internet" group, containing the whole range 1.0.0.0 - 223.255.255.255 (a subset of the group
below). You'd then create a martian list. The ACL would first deny the martians, then permit the broad
internet group, followed by the implicit deny all. That might not fly with the compliance folks I have to satisfy though, so I went ahead and created this mess.

I started with the martian list, using RFC5735.
!RFC 5735 Special Use IPv4 Addresses (Cymru "martians")
!
!0.0.0.0/8           "This" Network             RFC 1122, Section 3.2.1.3
!10.0.0.0/8          Private-Use Networks       RFC 1918
!127.0.0.0/8         Loopback                   RFC 1122, Section 3.2.1.3
!169.254.0.0/16      Link Local                 RFC 3927
!172.16.0.0/12       Private-Use Networks       RFC 1918
!192.0.0.0/24        IETF Protocol Assignments  RFC 5736
!192.0.2.0/24        TEST-NET-1                 RFC 5737
!192.168.0.0/16      Private-Use Networks       RFC 1918
!198.18.0.0/15       Network Interconnect
!                    Device Benchmark Testing   RFC 2544
!198.51.100.0/24     TEST-NET-2                 RFC 5737
!203.0.113.0/24      TEST-NET-3                 RFC 5737
!224.0.0.0/4         Multicast                  RFC 3171
!240.0.0.0/4         Reserved for Future Use    RFC 1112, Section 4
!255.255.255.255/32  Limited Broadcast          RFC 919, Section 7
!                                               RFC 922, Section 7

Edit: We now need to add the RFC6598 CGN Private Network
!100.64.0.0/10       CGN Private Networks       RFC 6598


Then built the complete list of subnets, using the largest possible subnets.
 (Exclude 0.0.0.0 - 0.255.255.255)
 1.0.0.0      /8 = 1.0.0.0 - 1.255.255.255
 2.0.0.0      /7 = 2.0.0.0 - 3.255.255.255
 4.0.0.0      /6 = 4.0.0.0 - 7.255.255.255
 8.0.0.0      /7 = 8.0.0.0 - 9.255.255.255
 (Exclude 10.0.0.0 - 10.255.255.255)
 11.0.0.0     /8 = 11.0.0.0 - 11.255.255.255
 12.0.0.0     /6 = 12.0.0.0 - 15.255.255.255
 16.0.0.0     /4 = 16.0.0.0 - 31.255.255.255
 32.0.0.0     /3 = 32.0.0.0 - 63.255.255.255
 64.0.0.0     /3 = 64.0.0.0 - 95.255.255.255
 96.0.0.0     /6 = 96.0.0.0 - 99.255.255.255
 100.0.0.0   /10 = 100.0.0.0 - 100.63.255.255
 (Exclude 100.64.0.0 - 100.127.255.255)
 100.128.0.0 /9 = 100.128.0.0 - 100.255.255.255
 101.0.0.0    /8 = 101.0.0.0 - 101.255.255.255
 102.0.0.0    /7 = 102.0.0.0 - 103.255.255.255
 104.0.0.0    /5 = 104.0.0.0 - 111.255.255.255
 112.0.0.0    /5 = 112.0.0.0 - 119.255.255.255
 120.0.0.0    /6 = 120.0.0.0 - 123.255.255.255
 124.0.0.0    /7 = 124.0.0.0 - 125.255.255.255
 126.0.0.0    /8 = 126.0.0.0 - 126.255.255.255
 (Exclude 127.0.0.0 - 127.255.255.255)
 128.0.0.0    /3  = 128.0.0.0 - 159.255.255.255
 160.0.0.0    /5  = 160.0.0.0 - 167.255.255.255
 168.0.0.0    /8  = 168.0.0.0 - 168.255.255.255
 169.0.0.0    /9  = 169.0.0.0 - 169.127.255.255
 169.128.0.0  /10 = 169.128.0.0 - 169.191.255.255
 169.192.0.0  /11 = 169.192.0.0 - 169.223.255.255
 169.224.0.0  /12 = 169.224.0.0 - 169.239.255.255
 169.240.0.0  /13 = 169.240.0.0 - 169.247.255.255
 169.248.0.0  /14 = 169.248.0.0 - 169.251.255.255
 169.252.0.0  /15 = 169.252.0.0 - 169.253.255.255
 (Exclude 169.254.0.0 - 169.254.255.255)
 169.255.0.0  /16 = 169.255.0.0 - 169.255.255.255
 170.0.0.0    /7  = 170.0.0.0 - 171.255.255.255
 172.0.0.0    /12 = 172.0.0.0 - 172.15.255.255
 (Exclude 172.16.0.0 - 172.31.255.255)
 172.32.0.0   /11 = 172.32.0.0 - 172.63.255.255
 172.64.0.0   /10 = 172.64.0.0 - 172.127.255.255
 172.128.0.0  /9  = 172.128.0.0 - 172.255.255.255
 173.0.0.0    /8  = 173.0.0.0 - 173.255.255.255
 174.0.0.0    /7  = 174.0.0.0 - 175.255.255.255
 176.0.0.0    /4  = 176.0.0.0 - 191.255.255.255
 (Exclude 192.0.0.0 - 192.0.0.255)
 192.0.1.0    /24 = 192.0.1.0 - 192.0.1.255
 (Exclude 192.0.2.0 - 192.0.2.255)
 192.0.3.0    /24 = 192.0.3.0 - 192.0.3.255
 192.0.4.0    /22 = 192.0.4.0 - 198.0.7.255
 192.0.8.0    /21 = 192.0.8.0 - 192.0.15.255
 192.0.16.0   /20 = 192.0.16.0 - 192.0.31.255
 192.0.32.0   /19 = 192.0.32.0 - 192.0.63.255
 192.0.64.0   /18 = 192.0.64.0 - 192.0.127.255
 192.0.128.0  /17 = 192.0.128.0 - 192.0.255.255
 192.1.0.0    /16 = 192.1.0.0 - 192.1.255.255
 192.2.0.0    /15 = 192.2.0.0 - 192.3.255.255
 192.4.0.0    /14 = 192.4.0.0 - 192.7.255.255
 192.8.0.0    /13 = 192.8.0.0 - 192.15.255.255
 192.16.0.0   /12 = 192.16.0.0 - 192.31.255.255
 192.32.0.0   /11 = 192.32.0.0 - 192.63.255.255
 192.64.0.0   /10 = 192.64.0.0 - 192.127.255.255
 192.128.0.0  /11 = 192.128.0.0 - 192.159.255.255
 192.160.0.0  /13 = 192.160.0.0 - 192.167.255.255
 (Exclude 192.168.0.0 /16)
 192.169.0.0  /16 = 192.169.0.0 - 192.169.255.255
 192.170.0.0  /15 = 192.170.0.0 - 192.171.255.255
 192.172.0.0  /14 = 192.172.0.0 - 192.175.255.255
 192.176.0.0  /12 = 192.176.0.0 - 192.191.255.255
 192.192.0.0  /10 = 192.192.0.0 - 192.255.255.255
 193.0.0.0    /8  = 193.0.0.0 - 193.255.255.255
 194.0.0.0    /7  = 194.0.0.0 - 195.255.255.255
 196.0.0.0    /7  = 196.0.0.0 - 197.255.255.255
 198.0.0.0    /12 = 198.0.0.0 - 198.15.255.255
 198.16.0.0   /15 = 198.16.0.0 - 198.17.255.255
 (Exclude 198.18.0.0 /15)
 198.20.0.0   /14 = 198.20.0.0 - 198.23.255.255
 198.24.0.0   /13 = 198.24.0.0 - 198.31.255.255
 198.32.0.0   /12 = 198.32.0.0 - 198.47.255.255
 198.48.0.0   /15 = 198.48.0.0 - 198.49.255.255
 198.50.0.0   /16 = 198.50.0.0 - 198.50.255.255
 198.51.0.0   /18 = 198.51.0.0 - 198.51.63.244
 198.51.64.0  /19 = 198.51.64.0 - 198.51.95.255
 198.51.96.0  /22 = 198.51.96.0 - 198.51.99.255
 (Exclude 198.51.100.0/24)
 198.51.101.0 /24 = 198.51.101.0 - 198.51.101.255
 198.51.102.0 /23 = 198.51.102.0 - 198.51.103.255
 198.51.104.0 /21 = 192.51.104.0 - 198.51.111.255
 198.51.112.0 /20 = 198.51.112.0 - 198.51.127.255
 198.51.128.0 /17 = 198.51.128.0 - 198.51.255.255
 198.52.0.0   /14 = 198.52.0.0 - 192.55.255.255
 198.56.0.0   /13 = 198.56.0.0 - 198.63.255.255
 198.64.0.0   /10 = 198.64.0.0 - 198.127.255.255
 198.128.0.0  /9  = 198.128.0.0 - 192.255.255.255
 199.0.0.0    /8  = 199.0.0.0 - 199.255.255.255
 200.0.0.0    /7  = 200.0.0.0 - 201.255.255.255
 202.0.0.0    /8  = 202.0.0.0 - 202.255.255.255
 203.0.0.0    /18 = 203.0.0.0 - 203.0.63.255
 203.0.64.0   /19 = 203.0.64.0 - 203.0.95.255
 203.0.96.0   /20 = 203.0.96.0 - 203.0.111.255
 203.0.112.0  /24 = 203.0.112.0 - 203.0.112.255
 (Exclude 203.0.113.0/24)
 203.0.114.0  /23 = 203.0.114.0 - 203.0.115.255
 203.0.116.0  /22 = 203.0.116.0 - 203.0.119.255
 203.0.120.0  /21 = 203.0.120.0 - 203.0.127.255
 203.0.128.0  /17 = 203.0.128.0 - 203.0.255.255
 203.1.0.0 /16 = 203.1.0.0 - 203.1.255.255
 203.2.0.0 /15 = 203.2.0.0 - 203.3.255.255
 203.4.0.0 /14 = 203.4.0.0 - 203.7.255.255
 203.8.0.0 /13 = 203.8.0.0 - 203.15.255.255
 203.16.0.0 /12 = 203.16.0.0 - 203.31.255.255
 203.32.0.0 /11 = 203.32.0.0 - 203.63.255.255
 203.64.0.0 /10 = 203.64.0.0 - 203.127.255.255
 203.128.0.0 /9 = 203.128.0.0 - 203.255.255.255
 204.0.0.0    /6  = 204.0.0.0 - 207.255.255.255
 208.0.0.0    /4  = 208.0.0.0 - 223.255.255.255
 (Exclude 224.0.0.0 - 255.255.255.255)

Finally, created an ASA script out of that:

! ASA config-script, subnet-based. (Good for 8.2 and previous)
! This will create a bunch of unnamed network objects that you may or may not hate. YMMV.

object-group network NET-INET-VALID

 network-object 1.0.0.0      255.0.0.0 
 network-object 2.0.0.0      254.0.0.0 
 network-object 4.0.0.0      252.0.0.0
 network-object 8.0.0.0      254.0.0.0
 network-object 11.0.0.0     255.0.0.0
 network-object 12.0.0.0     252.0.0.0
 network-object 16.0.0.0     240.0.0.0
 network-object 32.0.0.0     224.0.0.0
 network-object 64.0.0.0     224.0.0.0
 network-object 96.0.0.0     240.0.0.0
 network-object 112.0.0.0    248.0.0.0
 network-object 120.0.0.0    252.0.0.0
 network-object 124.0.0.0    254.0.0.0
 network-object 126.0.0.0    255.0.0.0
 network-object 128.0.0.0    224.0.0.0
 network-object 160.0.0.0    248.0.0.0
 network-object 168.0.0.0    255.0.0.0
 network-object 169.0.0.0    255.128.0.0
 network-object 169.128.0.0  255.192.0.0
 network-object 169.192.0.0  255.224.0.0
 network-object 169.224.0.0  255.240.0.0
 network-object 169.240.0.0  255.248.0.0
 network-object 169.248.0.0  255.252.0.0
 network-object 169.252.0.0  255.254.0.0
 network-object 169.255.0.0  255.255.0.0
 network-object 170.0.0.0    254.0.0.0  
 network-object 172.0.0.0    255.240.0.0
 network-object 172.32.0.0   255.224.0.0
 network-object 172.64.0.0   255.192.0.0
 network-object 172.128.0.0  255.128.0.0
 network-object 173.0.0.0    255.0.0.0  
 network-object 174.0.0.0    254.0.0.0  
 network-object 176.0.0.0    240.0.0.0  
 network-object 192.0.1.0    255.255.255.0
 network-object 192.0.3.0    255.255.255.0
 network-object 192.0.4.0    255.255.252.0
 network-object 192.0.8.0    255.255.248.0
 network-object 192.0.16.0   255.255.240.0
 network-object 192.0.32.0   255.255.224.0
 network-object 192.0.64.0   255.255.192.0
 network-object 192.0.128.0  255.255.128.0
 network-object 192.1.0.0    255.255.0.0
 network-object 192.2.0.0    255.254.0.0
 network-object 192.4.0.0    255.252.0.0
 network-object 192.8.0.0    255.248.0.0
 network-object 192.16.0.0   255.240.0.0
 network-object 192.32.0.0   255.224.0.0
 network-object 192.64.0.0   255.192.0.0
 network-object 192.128.0.0  255.224.0.0
 network-object 192.160.0.0  255.248.0.0
 network-object 192.169.0.0  255.255.0.0
 network-object 192.170.0.0  255.254.0.0
 network-object 192.172.0.0  255.252.0.0
 network-object 192.176.0.0  255.248.0.0 
 network-object 192.184.0.0  255.248.0.0
 network-object 192.192.0.0  255.192.0.0
 network-object 193.0.0.0    255.0.0.0
 network-object 194.0.0.0    254.0.0.0
 network-object 196.0.0.0    254.0.0.0
 network-object 198.0.0.0    255.240.0.0
 network-object 198.16.0.0   255.254.0.0
 network-object 198.20.0.0   255.252.0.0
 network-object 198.24.0.0   255.248.0.0
 network-object 198.32.0.0   255.240.0.0
 network-object 198.48.0.0   255.254.0.0
 network-object 198.50.0.0   255.255.0.0
 network-object 198.51.0.0   255.255.192.0
 network-object 198.51.64.0  255.255.224.0
 network-object 198.51.96.0  255.255.252.0
 network-object 198.51.101.0 255.255.255.0
 network-object 198.51.102.0 255.255.254.0
 network-object 198.51.104.0 255.255.248.0
 network-object 198.51.112.0 255.255.240.0
 network-object 198.51.128.0 255.255.128.0
 network-object 198.52.0.0   255.252.0.0
 network-object 198.56.0.0   255.248.0.0
 network-object 198.64.0.0   255.192.0.0
 network-object 198.128.0.0  255.128.0.0
 network-object 199.0.0.0    255.0.0.0
 network-object 200.0.0.0    254.0.0.0
 network-object 202.0.0.0    255.0.0.0
 network-object 203.0.0.0    255.255.192.0
 network-object 203.0.64.0   255.255.224.0
 network-object 203.0.96.0   255.255.240.0
 network-object 203.0.112.0  255.255.255.0
 network-object 203.0.114.0  255.255.254.0
 network-object 203.0.116.0  255.255.252.0
 network-object 203.0.120.0  255.255.248.0
 network-object 203.0.128.0  255.255.128.0
 network-object 203.1.0.0  255.255.0.0
 network-object 203.2.0.0  255.254.0.0
 network-object 203.4.0.0  255.252.0.0
 network-object 203.8.0.0  255.248.0.0
 network-object 203.16.0.0  255.240.0.0
 network-object 203.32.0.0  255.224.0.0
 network-object 203.64.0.0  255.192.0.0
 network-object 203.128.0.0  255.128.0.0
 network-object 204.0.0.0    252.0.0.0
 network-object 208.0.0.0    240.0.0.0


For those of you lucky enough to be running 8.3 or later, there's also this much simpler range-based version:

! ASA Config script, Range-based (for ASA 8.3 and up)
! 
object network NET-INET-RANGE1  
 range 1.0.0.0      9.255.255.255
object network NET-INET-RANGE2  
 range 11.0.0.0     100.63.255.255
object network NET-INET-RANGE3
 range 100.128.0.0  126.255.255.255
object network NET-INET-RANGE4
 range 128.0.0.0    169.253.255.255
object network NET-INET-RANGE5  
 range 169.255.0.0  172.15.255.255
object network NET-INET-RANGE6  
 range 172.32.0.0   191.255.255.255
object network NET-INET-RANGE7  
 range 192.0.1.0    192.0.1.255
object network NET-INET-RANGE8  
 range 192.0.3.0    192.88.98.255
object network NET-INET-RANGE9  
 range 192.88.100.0 192.167.255.255
object network NET-INET-RANGE10  
 range 192.169.0.0  198.17.255.255
object network NET-INET-RANGE11 
 range 198.20.0.0   198.51.99.255
object network NET-INET-RANGE12 
 range 198.51.101.0 203.0.112.255
object network NET-INET-RANGE13 
 range 203.0.114.0  223.255.255.255
object-group network NET-INET-VALID
 network-object object NET-INET-RANGE1
 network-object object NET-INET-RANGE2
 network-object object NET-INET-RANGE3
 network-object object NET-INET-RANGE4
 network-object object NET-INET-RANGE5
 network-object object NET-INET-RANGE6
 network-object object NET-INET-RANGE7
 network-object object NET-INET-RANGE8
 network-object object NET-INET-RANGE9
 network-object object NET-INET-RANGE10
 network-object object NET-INET-RANGE11
 network-object object NET-INET-RANGE12
 network-object object NET-INET-RANGE13

Tuesday, July 7, 2009

Incoming!

I ordered some tools and parts yesterday, from Adafruit. The parts are just more of the same: lights, resistors, etc. The tool is a USBtinyISP, an in-system/in-circuit programmer for most of the the 8-bit Atmel microcontrollers.

The USBtinyISP is $22, compared to the official Atmel USB ISP mk2, at $33. Neither supports JTAG or debugWire, but I find it hard to complain at those prices. They seem comparable at the feature level. The Atmel AVRISP mk2 is potentially faster, since Lady Ada's design uses a software USB implementation, which only runs at USB low-speed mode, or 1.5Mbps. The Atmel ISP is full speed, although programming only takes a few seconds either way.

The Adafruit design does support some bit-banging operations, though, and the ISP is based on a generic ATtiny 2313, so I can ransack and pillage the firmware as necessary. Perhaps debugWire can be added on this way.

I'll have a tidy review up after I receive it and get a chance to get down to business with it.

With the ISP, I can grow a bit away from the Arduino projects. I'm looking forward to programming bare ATmega and ATtiny microcontrollers, and making them do my bidding!

Monday, June 15, 2009

Low Rent Oscilloscope

A post found via Hackedgadget gives a description and code for an Arduino based oscilloscope. It looks pretty cool, and I must confess I certainly need an oscilloscope (a logic analyzer would be awesome, too) so I had a look. Before delving too deep here, have a look at the original post, please.

As discussed here before, the Arduino is based one of the Atmel ATmega-8 family of chips. The various ATmega-8 family members all seem to use the same analog-to-digital (A/D) conversion module, which can sample up to 10-bits of resolution, at sample rates from somewhere between DC and 75kHz, depending on resolution.

The oscilliscope code uses basic Arduino calls to read from the analog pin, and send the data out the Arduino serial port. The Arduino analog input functions don't allow you to specify a rate or resolution. You get 10-bits, and you get one sample per call. The Arduino docs say it takes about 100µS to get a sample, so about 10kHz sample rate, for a Nyquist frequency of 5kHz. So assuming you can get your data out of the chip fast enough, we have an oscilliscope with a 5kHz bandwidth. Honestly, that isn't so bad for $25 worth of parts and a few dozen lines of code.

Unforunately, there's some other problems. The code sets up the serial port at 9600 bps. RS232 serial port transmits (typically) 10 bits per byte. The code sends two bytes to get all 10 bits of data across.

9600/10 = 960 bytes per second
960/2 = 480 samples per second
480/2 = Nyquist frequency of 240Hz.

So this 'scope has a bandwidth of 240Hz. Despite this low frequency, this is still useful! If you re-coded both ends to support multiple analog pins you could use it as a logic analyzer for step-by-step debugging, etc. You can use it for measuring the kind of low-frequency stuff that's handy around the house. Like, you know, 50- or 60Hz house wiring.

But some comments in the original post say that they've bumped the serial rate up to 38400 bps, for a bandwidth of 960Hz. The comments indicate that they've had some trouble going beyond that. The A/D converter should have no trouble sampling beyond those rates, so it may be a matter of pipelining the conversions and the serial sends appropriately, or of modifying the underlying Arduino code (or writing your own handlers) to reduce the resolution, switch to interrupt-based A/D, etc.

I don't see many situations for a low-rent solution like this where one would need more than 8-bits of resolution. That would automatically double your sample rate over the serial port, and reduce the A/D settling time. Faster sampling, faster sending. With this (hopefully) simple change, we should see a bandwidth of 1.92kHz with a serial rate of 38400.

Additionally, the ATmega seems to have 64 bytes of buffer on the hardware UART. There seems to be no reason we couldn't use the A/D in interrupt mode, and have it stuff bytes in the buffer, for automatic sending. Careful balance of sample rate and serial rate would have to be managed. Oh, and the Arduino code environment doesn't directly support it...

Sunday, June 14, 2009

Project Complete(?)

Finished writing the code for my little project. the Arduino needed a couple tweaks to correct some code flaws: One typo, and one poor design choice. Then I tweaked the serial output code on my Processing front end. Now I have a three-slider UI to control the 24-bit RGB output of one I2C controlled LED.

150 lines of Processing code (I could get this down by about a third with some tuning, but who cares? It's Java, it's supposed to be bloated.)

50 lines of code in the Arduino, although all the handy little Arduino libraries that make the C/C++ so compact mean the binary on the controller is 3700+ bytes long.

Pictures and video later.

Saturday, June 13, 2009

Arduino Project I

I've spent the most of the evenings of the last week working on code, and experimenting with I2C communication between my Arduino and one of the BlinkMs I bought. (The other one is defective, and I'm not getting much response from Sparkfun, the company I bought it from, in getting it replaced. I'm going to start sending angry email next week.)

Having nailed down the I2C communications, I started working on a simple user interface, written in Processing. The UI displays a set of simple sliders that represent the level of each of the primary additive colors, red, green and blue. The sliders run from 0 to 254 (255 is a special marker character in the serial protocol I wrote for my Processing UI and my Arduino code to talk to each other). It also has a box in the UI panel that shows an approximation of the color. Whenever you adjust the sliders, the preview box updates, and the update string is sent out the serial port to the arduino, then the arduino sends the appropriate color change command over I2C to the BlinkM.

I'll probably adapt the Arduino code to directly run a common-cathode LED off the PWM pins as well. I can update the protocol and the UI to run both the BlinkM and the direct LED at once, with two different colors. Longer term will be to code Arduino light scripts, a sequencer (I don't like the one that is supplied with the BlinkM) etc.

Tuesday, June 2, 2009

Arduino Pazzia

I'm going to start posting my microcontroller adventures here, since these is an appropriate place to do it.

So about a month ago, I bought an Arduino from the Maker Shed, since it was on sale.

An Arduino

The Arduino is a broadly open-source project. The circuit board is open source, and available in just about any format, in several different types. The software is open source, and even includes a friendly and easy to learn development environment.

Arduino Development Environment

The core chip in the Arduino family of boards is the Atmel ATmega. The ATmega is an 8-bit microcontroller family. It's both low-power and high-performance. It's available in several versions with different amounts of flash and RAM on-board. The board I have uses the ATmega 328P, which has 32KB of flash and 2KB of SRAM.

Almost all of the pins on the chip are multipurpose IO pins. Some of them can be analog inputs, digital inputs, digital outputs, or PWM outputs with 8 bits of PWM control.

I've been playing around with the analog and digital output side with some LEDs. I did the usual Arduino "hello world" program, which is just to connect a single LED to an output and ground, and make it blink. (Most of the Arduinos actually have an LED and resistor on one output for this sort of thing)

I bought a dozen high-brightness green LEDs, and connected 6 of them up to outputs on the Arduino.

  • I got them doing the Cylon/Knight Rider LED sweep.
  • I got them doing a sine wave (at several frequencies and phases)
  • I got them doing a cool analog sweep back and forth
  • I made them into a 60-second binary timer. Tick tick tick tick...

I bought a couple RGB LEDs, which I already posted about. After a great deal of experimenting, I found a mix of resistors that got the colors balanced and workable. I've got one of them running a constant color changer, slowly sweeping each of the colors through a 100-step sine wave, with three different frequencies (all relatively prime) so that it eventually sweeps through all 24 million color combinations. Some of the stuff it does is really pretty.

I'm going to hook up the second LED, and have two! I also ordered some tiny LED modules that have on-board power control and their own tiny processor to run scripted light shows. They're controlled by the Arduino via I2C, which the Arduino environment supports natively.

I also ordered some real common-cathode RGB LEDs to play with. Much easier to deal with then these cheap-ass Radio Shack common-anode LEDs.

I've also found a 4-channel I2C controlled DAC with current controlled outputs, etc. It'd be great for an even cheaper Arduino-controlled LED light show sort of thing. I need to get some samples and see how cheap and small I can build such a thing.

Monday, March 23, 2009

ZFS second look

I thought I'd see if I could improve performance by compiling my own ZFS. I pulled the source from the ZFS-Fuse site, edited the make files for O3 instead of O2. Byte rates jumped to 90MB/sec at only 45% CPU. I don't know what options the original APT package was compiled with, but mine's faster. The binaries are four times the size of the originals, but significantly faster.

Sunday, March 22, 2009

ZFS on Linux

ZFS on linux. I love ZFS, I do. There's no argument there.

But currently in runs in userspace on Linux, and performance is terrible. Copying from one non-ZFS disk to a new single-disk ZFS volume hit 50MB/sec, which isn't bad, but which soaked up 60% CPU on a 2.0GHz dual-core Core 2 Celeron.

Unfortunately LVM and MD don't do what I want, so I think ZFS is still the direction I'm going to go. Hopefully performance will improve in future releases. Or they'll find a way to get ZFS in the kernel.

I could install OpenSolaris, but my Solaris admin skills are beyond rusty. Between that and shitty driver support, OpenSolaris makes it pretty much a no-go.

Friday, January 2, 2009

A Recent History of High Performance Computing

"High Performance Computing" is traditionally the purview of universities, governments and Big Science. The difference between what most people have at home and high-performance computing (HPC) is the difference between bicycles and the space race.

But the scene has been changing for quite some time. Clusters of cheap desktops running Linux and one or another parallel-computing software interfaces were the first to come. A showcase example was Oak Ridge National Labs "Stone Souper Computer", put together from surplus PCs and components that would otherwise have been thrown away. It was used for real work, doing the computational heavy lifting for several ecological modeling projects. Over time clustering became the primary means of acheiving high performance. A quick look at the TOP500 list shows just how prevalent clustering is.

Over the last few years, multicore CPUs have expanded this in a somewhat new direction. First, by doubling or quadrupling the number of CPU cores in a computing node, and later by adding highly-parallel processors to the clusters. By highly-parallel, I refer to the TOP500's current #1 supercomputer, the Roadrunner, which combines standard multicore AMD Opteron processors (sibling to the Athlon 64 processors common in desktop computers) with IBM PowerXCell processors, which are a slightly modified version of the Cell processor that powers every Sony Playstation3. The PowerXCell features one normal PowerPC processor, and 8 "Synergistic Processing Engines," essentially smaller sub-processors which focus on simple parallelizable tasks.

With the recent attention of the HPC market seeing the utility of many small, simple processing cores, many turned their attention to modern graphics processing units (GPUs). Modern GPUs contain dozens or even hundreds of small processing pipelines, optimized for the types of math and operations that 3D graphics require. As time progressed, these 3D graphics, especially games, required more complex computation, to such a degree that each of the pipelines started to resember a general purpose, if graphics-optimized, CPU.

Soon, hobbyists and programmers started taking advantage of this, programming their GPUs to perform computations that would normally run on a CPU. By moving the highly-parallel parts of their computation to the GPU, they could perform dozens of operations in the time that a single CPU could do one.

ATI (now AMD) and nVidia smelled money. ATI released some of their low-level programming interfaces, and a set of software extensions that allowed programmers easier access to the GPU. nVidia developed a whole programming language called CUDA, that allows developers to write C code directly for their GPUs. Now nVidia even has a version of their most powerful graphics card, with all the graphics hardware removed. Called "Tesla", it's a pure computation engine. You can fill your PC with as many Tesla cards as you have slots to stick 'em in. They have dedicated chassis full of Tesla cards with dedicated high-performance connections to PCs. Tokyo Tech University has begun adding Tesla units to their Tsubame supercomputer. The US National Center for Atmospheric Research has begun testing Tesla for accelerating particularly obnoxious computation, and found significant gains.

And really, this is sort of taking us full circle. Some of the dead technological offshoots in computing's past looked in this direction. Many hundreds, even thousands of small processors were used in the Connection Machines computers, each processor being only one bit wide. INMOS developed a radically different type of computing with their transputer, each chip a small microprocessor with a small amount of RAM and several inter-transputer network links, they were designed from the ground up as massively parallel computing engines.

The Connection Machines started with the ideas introduced in variable-width "bit-slice" processors of their predecessors, and took them to their logical extreme: A machine an arbitrary number of bits wide, and code-reconfigurable. It proved to be unsuccessful in implementation, though. With their 5th generation CM-5, Connection Machines designed a large parallel machine powered by up to 512 Sun SPARC processors

The INMOS Transputer is the evolutionary forebear to today's massively parallel supercomputers, though. Each transputer was a small processor, memory and enough glue logic to allow the device to stand mostly on its own. With network links to multiple other transputers on the same board, in the same case, or even spread throughout multiple cases, a cluster of transputers could appear to be a single virtual system, with individual threads running on each transputer. It was only ahead of its time in so far as there was a great deal of headroom left in getting higher performance out of traditional computing, and programming for parallel computing is hard.

Today, the modern single-threaded microprocessor has hit a performance barrier. Power requirements and the laws of decreasing returns have made it difficult to wring higher performance out of more transistors and higher clockspeeds. To improve returns on Moore's Law, today's CPU makers divided their transistor budget across two or more fully functional CPU cores on a single die. Dual-core CPUs are commonplace, and quad-core CPUs are about to become so, as well.

With the ubiquity of multicore computing and the aforementioned implicitly parallel nature of graphics processing, parallel programming has been thrust into the forefront of development. In order to achieve adquate performance for any demanding task, developers now must parallelize their computing tasks. What was a good idea in hardware, and optional in software before, has become ubiquitous in hardware, and required in software now.

Wednesday, December 31, 2008

MD5 considered harmful... Update

Some updates after closer reading of the research material:


First: This is somewhat more dangerous than I first thought, because a bogus certificate that appears to be signed by a valid CA will by happily accepted by browsers regardless of which CA signed the valid cert used by the valid server.


Say John usually accesses his bank, Big Mutual bank at bigmu.com. John receives a phishing email that takes him to bigmu.net instead. The name is similar, and heck, he even sees the little lock icon, telling him he's got a good SSL connection, so the certificate is good, right? Wrong, the certificate is bogus, signed by a fake intermediate CA, that appears to be signed by a valid CA, but it's not the same CA that bigmu.com normally uses. That doesn't matter, because the browser doesn't know or care who bigmu.com's CA usually is. (And even if it did, bigmu.com isn't bigmu.net, so it wouldn't associate them anyway) All it cares about is a valid certificate and a good SSL connection, and it lights up the lock icon, make the user feel happy and shiny.

Second: I didn't really talk enough about the resources required to craft the bogus certs. This has only been tested with one CA, that happens to not only hash with MD5 and uses sequential serial numbers for their certs. It took them several attempts over the space of four weekends to get certs with the desired serial number and validity period. The various attempts cost over $650 in payments to the root CA. Of course, once they've got that cert on precious intermediate CA cert, they can sign all they want for whoever they want...

MD5 considered harmful NOW.

Yesterday, a significant attack against MD5-hashed X509 certificates was announced.

http://www.win.tue.nl/hashclash/rogue-ca/

It exploits existing known weaknesses of MD5 to certain collision attacks to create bogus X509 certificates. The researchers were even able to create bogus X509 CA certs, thus breaking the chain of trust for X509 certificates.

X509 certificates are used for establishing trust and authentication in SSL communication, as well as many types of encrypted email, VPN authentication, 802.1x authentication, etc. With the new attack, someone can create fake certificates that look perfectly valid to the party attempting to verify that they're talking to someone they trust. Certification Authorities (CAs) are trusted third-parties who verify that an entity is who they say they are, and issue certificates for entities to use, saying "This server that you're talking to, named server-x belongs to this entity-y, signed CA-z".

Every hash algorithm has collisions. When you're boiling down an arbitrary amount of data into a short, fixed length signature, it's going to happen eventually that some other chunk of data will end up with the same signature. The problem is when someone learns how to make a piece of data collide with another piece of data on purpose. Especially if they can make their own fake X509 certificate look like it was signed by a trusted authority, when in reality, it wasn't.

So this attack is doubly bad... an attacker using this method can not only create fake certificates, they can create fake CA certificates which can then be used to sign other fake certificates, and look just like a trusted CA.

How bad is this? Well, it's not as immediately bad as it seems. First, the attack took quite a bit of hardware and time. 200 PS3s and a high-end multi-CPU PC took about 24 hours for each successful attempt. Clearly, this is a lot of CPU time. However, it's not infeasible to do it with a distributed search spread across a few hundred collaborating PCs (such as a botnet or a zombie army) or a similarly constructed cluster.

Secondly, it doesn't allow anyone to actively attack you just yet. It allows them to masquerade as someone you trust, though. A phishing attempt with a valid but fake Wamu.com SSL cert would certainly appear more trustworthy.

The short term fix for you and me is to be yet again more careful of what we click on. The long term fix is for CAs to stop issuing MD5 certs, stop using MD5 internally, etc. Heck, they could even make the effort of revoking their MD5 CA certs and re-issuing with SHA1 or better. Buyers of certs from CAs (and folks who self-sign their own) must stop using MD5.

Now, there's known weaknesses in SHA1, too. It's weak enough that the NIST will no longer permit it for government use in 2010. It's still several orders of magnitude stronger than MD5, though. Better to be safe, though, and require SHA256 or SHA512.

Tuesday, December 30, 2008

A new blog, covering the technology industry, and frankly whatever other highly geeky subjects I want to talk about. Nerds represent, yo!