For 1 and 2, if you're running 11.x, an iRule isn't strictly required. I'm assuming you're asking about LTM only. In that case, you could create forwarding VSs listening on TCP port 80, TCP port 443, UDP port 53 and TCP port 53, and for each of these, set the source address to the proxy client. Then, you could create three wildcard forwarding virtual servers, setting the source address in each case to the three that are allowed through. For all of these VSs, you would restrict them to the internal VLAN. If you need to identify applications regardless of port, you cannot do that with LTM alone.
If you really want to use an iRule, you could create three data groups. The first contains the ports where proxy traffic is allowed. The second defines the IP address of the proxy client. The third contains the client IP addresses that allow all ports:
tmsh create ltm virtual vs-internal-tcp-forwarder { vlans-enabled vlans replace-all-with { internal } destination 0.0.0.0:0 mask 0.0.0.0 profiles replace-all-with { tcp {} } }
tmsh create ltm data-group internal dg_internal_ports_allow_proxy type integer records add { 53 80 443 }
tmsh create ltm data-group internal dg_internal_proxy_client type ip records add { 10.16.1.241/32 }
tmsh create ltm data-group internal dg_internal_privileged_clients type ip records add { 10.16.2.1/32 10.16.32.162/32 153.10.16.2/32 }
The iRule would be:
when CLIENT_ACCEPTED {
if { !([class match [IP::client_addr] equals dg_internal_proxy_client] && [class match [TCP::server_port] equals dg_internal_ports_allow_proxy]) && ![class match [IP::client_addr] equals dg_internal_privileged_clients] } {
drop
}
}
Naturally, this must be applied to the VS "vs-internal-tcp-forwarder".
You would need to repeat this for UDP port 53, and you would need a separate VS, since iRules cannot generically look up port without a layer4-specific profile:
tmsh create ltm virtual vs-internal-tcp-forwarder { vlans-enabled vlans replace-all-with { internal } destination 0.0.0.0:0 mask 0.0.0.0 profiles replace-all-with { udp {} } }
when CLIENT_ACCEPTED {
if { !([class match [IP::client_addr] equals dg_internal_proxy_client] && [UDP::server_port] != 53) && ![class match [IP::client_addr] equals dg_internal_privileged_clients] } {
drop
}
}
For 3, if 10.16.1.136 is directly connected to the BIG-IP (that is, they share a common L2 domain), then you could utilize a "Forwarding (Layer2)" VS type and employ the same non-iRule mechanism detailed above. Otherwise, if an iRule is desired or required, it's really just a permutation of the one given above:
when CLIENT_ACCEPTED {
if { ![IP::addr [IP::client_addr] equals "192.168.0.1"] || ![IP::addr [IP::server_addr] equals "10.16.1.136"] || ![class match [TCP::port] equals dg_dmz_ports_allowed] } {
drop
}
}
4 is the same as 3, with a different data group and IP set.
I don't think I fully understand 5. What does "n/W allowed ICMP" mean? And does your description mean that traffic sourced from 192.168.0.1 behind a VLAN called DMZ going anywhere should be allowed if it matches the applications? If so:
when CLIENT_ACCEPTED {
if { ![IP::addr [IP::client_addr] equals "192.168.0.1"] || ![class match [TCP::port] equals dg_dmz_to_external_ports_allowed] } {
drop
}
}
Keep in mind that there are some interactions here. For example, the last rule would allow traffic from 192.168.0.1 to get to the "dg_dmz_to_external_ports_allowed" on any VLAN, thus by-passing 1, for example. If you need to account for these cross-cases, you'll have to enrich the iRules attached to each VS, or create a forwarding virtual server listening on all VLANs containing all of the logic above.