Juniper SRX flow traceoptions: plugins

Looking at SRX flow traces, there are a lot references to internal IDs. Without knowing what all these numbers mean, its hard to tell which configuration or additional services may adversely affect a flow.
Lets use the trace output as an example:

Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:<192.168.50.251/46800->216.239.36.10/53;17> matched filter foo:
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:packet [80] ipid = 37701, @423ad69a
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:---- flow_process_pkt: (thd 1): flow_ctxt type 14, common flag 0x0, mbuf 0x423ad480, rtbl_idx = 0
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT: flow process pak fast ifl 70 in_ifp fe-0/0/1.0
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT: find flow: table 0x4cbec950, hash 38561(0xffff), sa 192.168.50.251, da 216.239.36.10, sp 46800, dp 53, proto 17, tok 6
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  flow_first_create_session
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  flow_first_in_dst_nat: in <fe-0/0/1.0>, out <N/A> dst_adr 216.239.36.10, sp 46800, dp 53
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  chose interface fe-0/0/1.0 as incoming nat if.
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:flow_first_rule_dst_xlate: DST no-xlate: 0.0.0.0(0) to 216.239.36.10(53)
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:flow_first_routing: vr_id 0, call flow_route_lookup(): src_ip 192.168.50.251, x_dst_ip 216.239.36.10, in ifp fe-0/0/1.0, out ifp N/A sp 46800, dp 53, ip_proto 17, tos 0
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:Doing DESTINATION addr route-lookup
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  routed (x_dst_ip 216.239.36.10) from trust (fe-0/0/1.0 in 0) to fe-0/0/0.0, Next-hop: 84.196.0.1
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  policy search from zone trust-> zone untrust (0x0,0xb6d00035,0x35)
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  app 16, timeout 60s, curr ageout 60s
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:flow_first_src_xlate:  nat_src_xlated: False, nat_src_xlate_failed: False
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:flow_first_src_xlate: src nat returns status: 1, rule/pool id: 1/2, pst_nat: False.
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  dip id = 2/0, 192.168.50.251/46800->84.196.14.21/22287 protocol 17
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  choose interface fe-0/0/0.0 as outgoing phy if
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:is_loop_pak: No loop: on ifp: fe-0/0/0.0, addr: 216.239.36.10, rtt_idx:0
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:jsf sess interest check. regd plugins 19
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT: Allocating plugin info block for 20 plugin(s) from OL
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id  2, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id  3, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id  5, svc_req 0x4. rc 3
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:Add plugid:5 to int table at :0, fill hole:0, holes:0
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id  6, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id  7, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id  8, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id 12, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:+++++++++++jsf_test_plugin_data_evh: 3
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id 13, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id 14, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id 15, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id 18, svc_req 0x0. rc 2
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:-jsf int check: plugin id 19, svc_req 0x0. rc 4
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT: Allocating plugin info block for 1 plugin(s) from OL
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  Attaching plugin 5, at index 0
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT: Releasing plugin info block for 20 plugin(s) to OL
Feb 19 10:25:28 10:25:27.1062565:CID-0:RT:  Plugins enabled for session = 1 (frwk svcs mask 0x0), post_nat cnt 0
...

So this packet is permitted by the policy, but "plugin 5" has been enabled for the session. The question is of course, what is this plugin? To my knowledge this information is not available in the CLI, but luckily we can ask the forwarding deamon directly using the following command:

admin@srx> request pfe execute target fwdd command "show usp plugins"
SENT: Ukern command: show usp plugins
GOT:
GOT: Number of plugins: 19
GOT: Plugin: id: 1, name: junos-syn-term
GOT: Plugin: id: 2, name: junos-screen-adapter
GOT: Plugin: id: 3, name: junos-fwauth-adapter
GOT: Plugin: id: 4, name: junos-syn-init
GOT: Plugin: id: 5, name: junos-appid-packet
GOT: Plugin: id: 6, name: junos-appfw
GOT: Plugin: id: 7, name: junos-idp
GOT: Plugin: id: 8, name: junos-uf
GOT: Plugin: id: 9, name: junos-tcp-svr-emul
GOT: Plugin: id: 10, name: junos-ssl-term
GOT: Plugin: id: 12, name: junos-captive-portal
GOT: Plugin: id: 13, name: junos-test
GOT: Plugin: id: 14, name: junos-alg
GOT: Plugin: id: 15, name: junos-utm
GOT: Plugin: id: 16, name: junos-ssl-init
GOT: Plugin: id: 17, name: junos-tcp-clt-emul
GOT: Plugin: id: 18, name: junos-uac
GOT: Plugin: id: 19, name: junos-utm-udp
LOCAL: End of file

So this mysterious plugin turns out to be appid, which I did indeed activate for testing purposes the other day. In this case it didn't cause any problems but when you see plugins being triggered, it always good to know what they are used for, they could indicate a configuration error.

Blog Category:

Juniper SRX: selectively disable TCP SYN or Sequence checking

SRX are stateful firewalls and will only allow traffic which matches an existing session. Sessions are created when a TCP SYN packet is received and it is permitted by the security policy. This of course means that the firewall needs to see both directions of a flow (client-server and server-client), otherwise these checks will block legitimate packets.
Whenever possible its best to ensure that asymmetric flows can't occur, but this is not always possible. Therefor you can disable these checks globally on the SRX:

set security flow tcp-session no-syn-check
set security flow tcp-session no-sequence-check

Obviously configuring this has a security impact and because it is a global option, it applies to all traffic flowing through the device. That's unfortunate as these checks typically only need to be enabled for a few policies. Luckily recent JunOS releases allow these checks to be enabled on a per-policy basis, like this:

policy trust-to-untrust {
    match {
        source-address any;
        destination-address any;
        application any;
    }
    then {
        permit {
            tcp-options {
                syn-check-required;
                sequence-check-required;
            }
        }
    }
}

The problem here is that Juniper implemented "syn-check-required" and "sequence-check-required" options instead of "no-syn-check-required" and "no-sequence-check-required" which would be a lot more usable in the real word. But because this is JunOS, there are ways around this of course. To disable TCP SYN or sequence checking on one policy while enabling it on all other policies, an apply-group can be used. The idea here is the following:

  1. Globally disable syn and sequence checking
  2. Using an apply-group to set "syn-check-required" and "sequence-check-required" on ALL security policies
  3. Using apply-groups-except to disable this apply-group on the few policies where syn or sequence checking is not desired

In JunOS code it looks like this:

groups {
    require_syn_seq_checking {
        security {
            policies {
                from-zone <*> to-zone <*> {
                    policy <*> {
                        then {
                            permit {
                                tcp-options {
                                    syn-check-required;
                                    sequence-check-required;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
 
security {
    policies {
        apply-groups require_syn_seq_checking;
    }
}
 
security {
    policies {
	    from-zone foo to-zone bar {
		    policy one {
			    apply-groups-except require_syn_seq_checking;
                ...
			}
		}
	}
}

Hopefully Juniper will some day implement the "no-sequence-check" option at a per-policy level, but until then, this workaround can be used.

Juniper SRX: load-balancing based on source-ip

In a poor mans multi-homing setup, you may have a firewall with two ISP connections, each connection with its own IP space. This makes load-balancing a bit tricky. You can't just do per-session load balancing because that causes the clients public IP address to change at random. For some applications, that is not a problem, but there are many that lock a user to a specific IP. A common example are banking websites, as soon as the IP address changes, the user session is terminated.
An easy workaround would be to disable load-balancing for HTTP and HTTPS sessions, but nowadays that's most of the traffic.

In searching for a solution to this problem, I thought of a very easy workaround: load-balancing based on the clients (internal) IP address. This ensures that the same client always uses the same ISP connection, so the public IP address remains the same. Assuming a random distribution of the internal IP addresses, this should provide an even distribution of sessions between the two ISPs.

As it turns out, this can be done in JunOS quite easily. All it takes is a special use of subnet masks. Assuming you have two routing-instances, one for each ISP, the following firewall filter applied on the client-facing interface will distribute the traffic across the two connections. All clients whose IP address ends in an even number, are routed via ISP1 and clients whose IP address ends in an uneven number, are sent via ISP2.

firewall {
    family inet {
        filter source-based-lb {
            term even {
                from {
                    source-address {
                        10.32.0.0/255.255.0.1;
                    }
                }
                then {
                    routing-instance fbf-prefer-isp1;
                }
            }
            term odd {
                from {
                    source-address {
                        10.32.0.1/255.255.0.1;
                    }
                }
                then {
                    routing-instance fbf-prefer-isp2;
                }
            }
            term default {
                then accept;
            }
        }
    }
}

Of course, replace 10.32. with the users IP range. I tried using 0.0.0.0/0.0.0.1 and 0.0.0.1/0.0.0.1 in the firewall filter but that seems to trigger a bug in the junos CLI.

Using Time Domain Reflectometry (TDR) to locate cable faults on EX switches

One of the little known features of the Juniper EX switches is Time domain reflectometry which can be used to locate cable faults.
This is especially useful for long cables or when a connection is made up of multiple patch cables, to figure out where the cable is damaged.

To start TDR on a port, issue the following command:

request diagnostics tdr start interface <interface>

The test will take a couple seconds. To see the results, use:
show diagnostics tdr interface <interface>

On a working link, the result looks something like this:

Interface TDR detail:
Interface name                  : ge-1/0/26
Test status                     : Passed
Link status                     :  UP
MDI pair                        : 1-2
  Cable status                  : Normal
  Distance fault                : 0 Meters
  Polartiy swap                 : Normal
  Skew time                     : 0 ns
MDI pair                        : 3-6
  Cable status                  : Normal
  Distance fault                : 0 Meters
  Polartiy swap                 : Normal
  Skew time                     : 0 ns
MDI pair                        : 4-5
  Cable status                  : Normal
  Distance fault                : 0 Meters
  Polartiy swap                 : Normal
  Skew time                     : 8 ns
MDI pair                        : 7-8
  Cable status                  : Normal
  Distance fault                : 0 Meters
  Polartiy swap                 : Normal
  Skew time                     : 0 ns
Channel pair                    : 1
  Pair swap                     : MDIX
Channel pair                    : 2
  Pair swap                     : MDIX
Downshift                       : No Downshift

When something is wrong with the cable, the results may vary of course. A cable which simply isn't connected to anything at the far end shows up like this:

Interface TDR detail:
Interface name                  : ge-1/0/16
Test status                     : Passed
Link status                     : Down
MDI pair                        : 1-2
  Cable status                  : Open
  Distance fault                : 52 Meters
  Polartiy swap                 : N/A
  Skew time                     : N/A
MDI pair                        : 3-6
  Cable status                  : Open
  Distance fault                : 50 Meters
  Polartiy swap                 : N/A
  Skew time                     : N/A
MDI pair                        : 4-5
  Cable status                  : Open
  Distance fault                : 50 Meters
  Polartiy swap                 : N/A
  Skew time                     : N/A
MDI pair                        : 7-8
  Cable status                  : Open
  Distance fault                : 52 Meters
  Polartiy swap                 : N/A
  Skew time                     : N/A
Channel pair                    : 1
  Pair swap                     : N/A
Channel pair                    : 2
  Pair swap                     : N/A
Downshift                       : N/A

Pages

Subscribe to Bart Jansens RSS Subscribe to Bart Jansens - All comments