Saturday, December 15, 2012

Juniper SRX-100, GRE over IPsec and Bypass Session Table

Juniper made a very unwelcome decision to terminate packet-mode JUNOS on J-series router since 9.4 that indeed creates lots of concerns to some people, such as me, who uses J-series router as a "real" router.

Since that we need to worry about the factor of new session per second, as well as concurrent sessions when we deploy and operate the router. The new SRX firewall, according to some rumors I heard, maybe eventually retire J-series router. Juniper also advertises SRX as firewall and "security" router for branch offices.

The only reason I can image is there are some politics inside the company prevents product management team listen to customers and insist "security router" is a good selling point. However, Juniper must fully aware the burden from session table when deploy J-series and/or SRX as a pure router. Other wise the "packet-mode" and "selective packet-mode" functions will not be created.

Back in packet-mode JUNOS, it was a happy time to play with J-series router with ever capabilities, including IPsec VPN. With the flow-mode JUNOS when turning the router into packet-mode we no longer able to create IPsec VPN with remote sites, but running in flow-mode makes our NOC nervous, worrying about session table usage all the time.

According to the selective-packet-mode document, if we can establish GRE over IPsec to remote site, and put GRE interface and all down-link interface into packet-mode, we should able to bypass the session creation on those interfaces; turns out we should have very limited sessions that related to IPsec itself rather than huge amount of user sessions that travel through the box.

Since the requirement is to carry layer-3 IP traffics to remote site, rather then carry layer-2 packets. The TCP protocols should able to adjust MTU size by itself rather than rely on the fragmentation / reassembling mechanism when encapsulate user packets into GRE. So the involvement of IDP is not necessary (J- / SRX uses IDP module to reassemble GRE packet... another weird / bad decision.)

Following is the configuration and performance testing by using two SRX-100 to demo this idea.

/* == SRX-100 VPN Box @ LAB2 == */
interfaces {
    fe-0/0/0 {
        description "## PC under LAB2 ##";
        unit 0 {
            family inet {
                filter {
                    input packet-mode-ipv4;
                }
                address 10.2.0.254/24;
            }
        }
    }
    gr-0/0/0 {
        description "## GRE overhead 24 bytes ##";
        unit 1 {
            description "## GRE to HQ ##";
            tunnel {
                source 172.31.0.2;
                destination 172.31.0.1;
                path-mtu-discovery;
            }
            family inet {
                mtu 1400;
                filter {
                    input packet-mode-ipv4;
                }
                address 10.0.0.2/30;
            }
        }
    }
    fe-0/0/3 {
        description "## Internet Uplink ##";
        unit 0 {
            family inet {
                address 2.2.2.2/24;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 10.0.2.253/32 {
                    primary;
                    preferred;
                }
                address 172.31.0.2/32;
            }
        }
    }
    st0 {
        description "## IPsec overhead (proposal std/std) 62 bytes ##";
        unit 1 {
            description "## ipsec to HQ ##";
            family inet {
                mtu 1438;
            }
        }
    }
}
routing-options {
    rib inet.0 {
        static {
            /* == default route to Internet == */
            route 0.0.0.0/0 next-hop 2.2.2.254;
            /* == HQ GRE End-Point == */
            route 172.31.0.1/32 next-hop st0.1;
            /* == HQ PC == */
            route 192.168.101.0/24 next-hop 10.0.0.1;
        }
    }
}
security {
    ike {
        policy ike_pol_hq {
            mode main;
            proposal-set standard;
            pre-shared-key ascii-text "MYKEY";
        }
        gateway gw_hq {
            ike-policy ike_pol_hq;
            address 1.1.1.1;
            local-identity inet 2.2.2.2;
            external-interface fe-0/0/3.0;
        }
    }
    ipsec {
        policy ipsec_pol_hq {
            perfect-forward-secrecy {
                keys group2;
            }
            proposal-set standard;
        }
        vpn hq {
            bind-interface st0.1;
            vpn-monitor;
            ike {
                gateway gw_hq;
                ipsec-policy ipsec_pol_hq;
            }
            establish-tunnels immediately;
        }
    }
    alg {
        dns disable;
        ftp disable;
        h323 disable;
        mgcp disable;
        msrpc disable;
        sunrpc disable;
        real disable;
        rsh disable;
        rtsp disable;
        sccp disable;
        sip disable;
        sql disable;
        talk disable;
        tftp disable;
        pptp disable;
    }
    flow {
        tcp-session {
            no-syn-check;
            no-syn-check-in-tunnel;
            no-sequence-check;
        }
    }
    policies {
        from-zone trust to-zone untrust {
            policy trust-to-untrust {
                match {
                    source-address any;
                    destination-address any;
                    application any;
                }
                then {
                    permit;
                }
            }
        }
        from-zone untrust to-zone untrust {
            policy untrust-to-untrust {
                match {
                    source-address any;
                    destination-address any;
                    application any;
                }
                then {
                    permit;
                }
            }
        }
        from-zone trust to-zone trust {
            policy trust-to-trust {
                match {
                    source-address any;
                    destination-address any;
                    application any;
                }
                then {
                    permit;
                }
            }
        }
    }
    zones {
        security-zone trust {
            host-inbound-traffic {
                system-services {
                    all;
                }
                protocols {
                    all;
                }
            }
            interfaces {
                lo0.0;
                fe-0/0/0.0;
                gr-0/0/0.1;
                st0.1;
            }
        }
        security-zone untrust {
            screen untrust-screen;
            host-inbound-traffic {
                system-services {
                    ping;
                    ike;
                }
            }
            interfaces {
                fe-0/0/3.0;
            }
        }
    }
}
firewall {
    family inet {
        filter packet-mode-ipv4 {
            term all-packet-mode {
                then {
                    packet-mode;
                    accept;
                }
            }
        }
    }
}
/* == END of config on VPN Box @ LAB2 == */


/* =============================================== */


/* == SRX-100 VPN Box @ HQ == */
interfaces {
    fe-0/0/0 {
        description "## PC under HQ ##";
        unit 0 {
            family inet {
                filter {
                    input packet-mode-ipv4;
                }
                address 192.168.101.254/24;
            }
        }
    }
    gr-0/0/0 {
        description "## GRE overhead 24 bytes ##";
        unit 2 {
            description "## GRE to LAB2 ##";
            tunnel {
                source 172.31.0.1;
                destination 172.31.0.2;
                path-mtu-discovery;
            }
            family inet {
                mtu 1400;
                filter {
                    input packet-mode-ipv4;
                }
                address 10.0.0.1/30;
            }
        }
    }
    fe-0/0/3 {
        description "## Internet Uplink ##";
        unit 0 {
            family inet {
                address 1.1.1.1/24;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 10.0.1.253/32 {
                    primary;
                    preferred;
                }
                address 172.31.0.1/32;
            }
        }
    }
    st0 {
        description "## IPsec overhead (proposal std/std) 62 bytes ##";
        unit 2 {
            description "## ipsec to lab2 ##";
            family inet {
                mtu 1438;
            }
        }
    }
}
routing-options {
    rib inet.0 {
        static {
            /* == default route to Internet == */
            route 0.0.0.0/0 next-hop 1.1.1.254;
            /* == LAB2 GRE End-Point == */
            route 172.31.0.2/32 next-hop st0.2;
            /* == LAB2 PC == */
            route 10.2.0.0/24 next-hop 10.0.0.2;
        }
    }
}
security {
    ike {
        policy ike_pol_lab2 {
            mode main;
            proposal-set standard;
            pre-shared-key ascii-text "MYKEY";
        }
        gateway gw_lab2 {
            ike-policy ike_pol_lab2;
            address 2.2.2.2;
            local-identity inet 1.1.1.1;
            external-interface fe-0/0/3.0;
        }
    }
    ipsec {
        policy ipsec_pol_lab2 {
            perfect-forward-secrecy {
                keys group2;
            }
            proposal-set standard;
        }
        vpn hq {
            bind-interface st0.2;
            vpn-monitor;
            ike {
                gateway gw_lab2;
                ipsec-policy ipsec_pol_lab2;
            }
            establish-tunnels immediately;
        }
    }
    alg {
        dns disable;
        ftp disable;
        h323 disable;
        mgcp disable;
        msrpc disable;
        sunrpc disable;
        real disable;
        rsh disable;
        rtsp disable;
        sccp disable;
        sip disable;
        sql disable;
        talk disable;
        tftp disable;
        pptp disable;
    }
    flow {
        tcp-session {
            no-syn-check;
            no-syn-check-in-tunnel;
            no-sequence-check;
        }
    }
    policies {
        from-zone trust to-zone untrust {
            policy trust-to-untrust {
                match {
                    source-address any;
                    destination-address any;
                    application any;
                }
                then {
                    permit;
                }
            }
        }
        from-zone untrust to-zone untrust {
            policy untrust-to-untrust {
                match {
                    source-address any;
                    destination-address any;
                    application any;
                }
                then {
                    permit;
                }
            }
        }
        from-zone trust to-zone trust {
            policy trust-to-trust {
                match {
                    source-address any;
                    destination-address any;
                    application any;
                }
                then {
                    permit;
                }
            }
        }
    }
    zones {
        security-zone trust {
            host-inbound-traffic {
                system-services {
                    all;
                }
                protocols {
                    all;
                }
            }
            interfaces {
                lo0.0;
                fe-0/0/0.0;
                gr-0/0/0.2;
                st0.2;
            }
        }
        security-zone untrust {
            screen untrust-screen;
            host-inbound-traffic {
                system-services {
                    ping;
                    ike;
                }
            }
            interfaces {
                fe-0/0/3.0;
            }
        }
    }
}
firewall {
    family inet {
        filter packet-mode-ipv4 {
            term all-packet-mode {
                then {
                    packet-mode;
                    accept;
                }
            }
        }
    }
}
/* == END of config on VPN Box @ HQ == */

/* =============================================== */

/*== iperf tcp performance test from lab2 to hq == */

ylchang@lab2pc:~> iperf -mN -i 1 -w 1m -c 192.168.101.101
------------------------------------------------------------
Client connecting to 192.168.101.101, TCP port 5001
TCP window size: 1.00 MByte (WARNING: requested 1.00 MByte)
------------------------------------------------------------
[  3] local 10.2.0.202 port 52399 connected with 192.168.101.101 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 1.0 sec  5.88 MBytes  49.3 Mbits/sec
[  3]  1.0- 2.0 sec  4.88 MBytes  40.9 Mbits/sec
[  3]  2.0- 3.0 sec  5.00 MBytes  41.9 Mbits/sec
[  3]  3.0- 4.0 sec  5.00 MBytes  41.9 Mbits/sec
[  3]  4.0- 5.0 sec  5.12 MBytes  43.0 Mbits/sec
[  3]  5.0- 6.0 sec  5.12 MBytes  43.0 Mbits/sec
[  3]  6.0- 7.0 sec  5.00 MBytes  41.9 Mbits/sec
[  3]  7.0- 8.0 sec  5.12 MBytes  43.0 Mbits/sec
[  3]  8.0- 9.0 sec  5.12 MBytes  43.0 Mbits/sec
[  3]  9.0-10.0 sec  5.12 MBytes  43.0 Mbits/sec
[  3]  0.0-10.0 sec  51.5 MBytes  43.1 Mbits/sec
[  3] MSS size 1348 bytes (MTU 1388 bytes, unknown interface)
/*== End of iperf tcp performance test == */

With this configuration, we successfully bypass session creation when traffic travel through IPsec VPN between sites. The entire box has only 5 sessions (include the telnet session I used to login) even the user PCs creates tens of thousand connections across the sites.

No comments: