Forum Discussion

Norris_141656's avatar
Norris_141656
Icon for Nimbostratus rankNimbostratus
Mar 10, 2014

iRule To Control Access Based on Source and Destination Addresses

Hi Guys

I am trying to work on a iRule for a virtual server that permits traffic from a couple of devices behind the the BIG-IP (192.168.1.15 and 192.168.1.20) to a couple of FTP sites out on the internet (lets say 1.1.1.1, 2.2.2.2 and 3.3.3.3). I have a virtual server named vs_ftp_out that contains 0.0.0.0/0 as the destination and 192.168.1.0/24 as the source, and FTP as the protocol.

Could I do something like this? Its a slight adaption of the datacenter firewall iApp

data-group internal /Common/dg_allowed_ftp_sources
  records {
    192.168.1.15/32
    192.168.1.20/32
    }
  type ip

data-group internal /Common/dg_allowed_ftp_destinations
  records {
    1.1.1.1/32
    2.2.2.2/32
    3.3.3.3/32
    }
  type ip

data-group internal /Common/ftp_acl
  records {
    /Common/vs_ftp_out {
        data dg_allowed_ftp_sources
        data dg_allowed_ftp_destinations
        }
     }
  type string

when CLIENT ACCEPTED {
  while {1} {
     set ftp_acl [class match -value [virtual name] equals /Common/dg_ftp_out]
        if { ! [class exists $ftp_acl] } { break }
        if { ! [class match [IP::client_addr] equals $ftp_acl] } and { ! [class match [IP::remote_addr] equals $ftp_acl] 
           } { break 
           }
        return
        }
  discard
}

Please feel free to chuckle if I have missed something glaringly obvious - I have never used F5 before and am still trying to get to grips with iRules - Doing the essentials course and reading the iRules 101 pages, which are really great btw. I am a network engineer most of the time with experience in Cisco and Juniper, so the concept and logic behind iRules is new to me.

Many Thanks

Jon

  • You seem to have a good grasp, however I don't think I was paying enough attention when I made my other update. I only mentioned /Common/dg_ftp_out as you had referenced it but not defined it. I don't really see that it's necessary - you could get away with what's below instead;-

    when CLIENT ACCEPTED {
       if {!([class match [IP::client_addr] equals dg_allowed_ftp_sources] && [class match [IP::local_addr] equals dg_allowed_ftp_destinations])} { 
          discard
          return
       }
    }
    
  • I think this would achieve the same....also you will need a /Common/dg_ftp_out

    when CLIENT ACCEPTED {
       set ftp_acl [class match -value [virtual name] equals /Common/dg_ftp_out]
       if {![class exists $ftp_acl] } { 
          discard
          return
       } elseif {![class match [IP::client_addr] equals $ftp_acl] } { 
          discard
          return
       }
    }
    
  • Hi

    Thanks for the reply - I almost get it I think...

    set ftp_acl [class match -value [virtual name] equals /Common/dg_ftp_out]

    This statement is creating a variable based on matching a virtual server name and an source or destination address inside of the dg_ftp_out group?

    if {![class exists $ftp_acl] } ( discard return }

    Then, this statement is saying that if the traffic does not match this variable, then discard it?

    elseif {![class match [IP::client_addr] equals $ftp_acl] } {

    Finally, this applies a filter on the client IP address (the sources IP address, so 192.168.1.15 or 192.168.1.20?), saying that if the client IP address is not listed in the ftp_acl variable then traffic is not to be permitted?

    With this in mind, my df_ftp_out group needs to contain the following:

    data-group internal /Common/dg_ftp_out
      records {
        /Common/vs_ftp_out {
           data dg_allowed_ftp_sources
           data dg_allowed_ftp_destinations
           }
        }
      type string
    

    I'll test this and see if it works, but can you just confirm if I have the logic correct?

    Ideally I would like to do this for most of the traffic I have to permit outbound, so that means creating a new Virtual Server and applying the same iRule but changing the data groups and protocols involved. if I can do it like this I think I can make the BIG-IP into an effective firewall, and I'll be able to document a process for adding new rules/troubleshooting for my colleagues (and me, a few months down the line) to reference.

    Many Thanks

    Jon

  • You seem to have a good grasp, however I don't think I was paying enough attention when I made my other update. I only mentioned /Common/dg_ftp_out as you had referenced it but not defined it. I don't really see that it's necessary - you could get away with what's below instead;-

    when CLIENT ACCEPTED {
       if {!([class match [IP::client_addr] equals dg_allowed_ftp_sources] && [class match [IP::local_addr] equals dg_allowed_ftp_destinations])} { 
          discard
          return
       }
    }
    
  • This does the trick, thanks heaps! Unfortunately, performance kind of sucks at the moment - I have applied the same rule to a HTTP virtual server but it takes 2mins+ to load the webpages. Then, when I remove the iRule, it is fast again.

     

    Dont worry about that though, ill get try and get to the bottom of it. Thanks again for your help!