Mobistar iPhone tethering possible again (personal hotspot)


Mobistar has always blocked tethering on their network. Years ago their was a workaround but that was only for very old iOS versions.

Today, it is once again possible to enable tethering. This time without "hacks". Rumor has it this will be officially announced on monday but the functionality is already working. All you need is an up-to-date iOS version and the latest carrier update.

To obtain the latest carrier update, go to Settings > General > Usage. Here a popup will appear asking if you want to install the carrier update.
Select update, and as soon as you have done that, the Settings > General > Network > Personal Hotspot item should appear.


Configuration is quite simple. At the top of the page, enable the personal hotspot.
You will be asked if you want to use USB or Bluetooth/Wireless. USB requires iTunes to be installed on the computer, if you use this option, don't forget to disable the hotspot after use, otherwise the computer will use it every time the iphone is connected.
Wireless/Bluetooth are especially useful if you want to use a second device to access the internet (such as an iPad), or if you don't want to install any additional software on your computer.

The main disadvantage for now is the poor 3G coverage of the mobistar network. In most of the places all you get is Edge, which is enough to synchronize email but to slow for anything else.

Juniper SRX global security policy - revisited

Quite a while ago I wrote about creating a global policy using apply-groups. It works, but its main disadvantage was that it only logs traffic if there is at least one permit rule between the source and destination zones.

As of Junos 11.2, a global firewall rulebase can now be configured. Just like the netscreen global rulebase, this only gets evaluated if there is no match in the regular rulebase. So, it can be used to create a default logdrop rule like this:

[edit security policies global]
    policy default-logdrop {
        match {
            source-address any;
            destination-address any;
            application any;
        }
        then {
            deny;
            log {
                session-init;
            }
        }
    }

When traffic does not match any of the permit policies, it is now logged in the following format:

RT_FLOW - RT_FLOW_SESSION_DENY [junos@2636.1.1.1.2.39 source-address="10.199.6.91" source-port="5947" destination-address="194.178.10.7" destination-port="80" service-name="junos-http" protocol-id="6" icmp-type="0" policy-name="default-logdrop(global)" source-zone-name="trust" destination-zone-name="untrust" application="UNKNOWN" nested-application="UNKNOWN" username="N/A" role="N/A" packet-incoming-interface="fe-0/0/8.6"]

The global policy works fine for a default logdrop rule, but when you want to specify specific source or destination addresses in a rule, things get more interesting. The addresses need to be defined in the new global address book at [security address-book] instead of the zone-specific ones. Unfortunately, the two cannot be combined. If you try to commit this change, you'll see error messages like this:

[edit security zones security-zone untrust]
  'address-book'
    Zone specific address books are not allowed when there are global address books defined

So you will have to convert all your address books to the new style, which is quite a bit of work.

Blog Category:

Juniper SRX: NAT hairpinning

Junos 11.2 contains an interesting new feature which most people don't even know about: nat hairpinning. The idea is that when two machines are behind the same NAT device, they can still communicate using their external IP addresses. Let's use the following setup as an example:

Both the internal client and webserver are in the same subnet, which is pretty much the worst possible scenario. What happens when the client connects to the webserver using its public NAT address 100.100.100.101?
Previous versions of junos would simply see that destination address as being in the untrust zone, perform policy evaluation, source-nat and then send the packet to the next-hop. The SRX didn't know that it "owned" the IP address, so what happened next really depended on the exact setup, but the end result was that that packets were eventually dropped and no connection was possible.

There were several workarounds for scenarios like this. You could use split-scope DNS so that internal clients would use the servers internal IP address instead. Personally I think this is very ugly, suddenly there are multiple views of your DNS zones to keep in sync (as if that's going to happen) and you have to be very careful about DNS requests "leaking" to the internet. Things get even more interesting when DNSSEC gets deployed, but that's a different discussion.
Another solution would be to create explicit NAT rules for internal clients, which is exactly what the Juniper knowledge base suggests: KB19400. This is currently the most common solution, but it has drawbacks of its own, mainly the fact that there now are different NAT and firewall policies for internal and external clients.

The easiest solution would of course be if the SRX could do this automatically, after all, netscreen has done this since the dawn of time. This happens to be exactly what NAT hairpinning does. Instead of a single pass through the firewall and NAT rulebases, the initial packet is looped back through like this:

Packet 192.168.1.2->100.100.100.101 arrives at SRX

  • Ingress interface determines source zone => TRUST
  • Destination or static NAT rulebases are evaluated. Because the source-zone is trust, there is no match.
  • Route lookup to 100.100.100.101 is performed to look up destination zone => UNTRUST
  • Policy evalutation is performed from TRUST => UNTRUST
  • Source-NAT rulebase is evaluated. Matches the default source-NAT behind interface rule.

The packet is now rewritten to 100.100.100.100->100.100.100.101 and normally it would be sent out the egress interface. But instead the firewall now detects a "loop" on the egress interface and sends the packet back through the rulebase, as if it has been received on the egress interface:

  • Ingress interface determines source zone => UNTRUST
  • Destination or static NAT rulebases are evaluated. This time there is a match and the destination-IP is altered to 192.168.1.1.
  • Policy evaluation is performed from UNTRUST => TRUST
  • Source-NAT rulebase is evaluated. No match this time.

The end result is a packet with source-IP 100.100.100.100 being sent to the internal web server, resulting in a clean symmetrical flow.

For those who like to look at flow traces, I included an example below. The change in behavior here is that the is_loop_pak call detects a loop. In previous versions this call was already present in the trace but always returned false.

<192.168.1.10/3406->100.100.100.100/80;6> matched filter foo:
packet [48] ipid = 1013, @422387a4
---- flow_process_pkt: (thd 3): flow_ctxt type 13, common flag 0x0, mbuf 0x42238580, rtbl_idx = 6
 flow process pak fast ifl 91 in_ifp reth10.12
  reth10.12:192.168.1.10/3406->100.100.100.100/80, tcp, flag 2 syn
 find flow: table 0x4bbd5760, hash 53545(0xffff), sa 192.168.1.10, da 100.100.100.100, sp 3406, dp 80, proto 6, tok 36870
  no session found, start first path. in_tunnel - 0, from_cp_flag - 0
  flow_first_create_session
  flow_first_in_dst_nat: in <reth10.12>, out <N/A> dst_adr 100.100.100.100, sp 3406, dp 80
  chose interface reth10.12 as incoming nat if.
flow_first_rule_dst_xlate: DST no-xlate: 0.0.0.0(0) to 100.100.100.100(80)
flow_first_routing: vr_id 6, call flow_route_lookup(): src_ip 192.168.1.10, x_dst_ip 100.100.100.100, in ifp reth10.12, out ifp N/A sp 3406, dp 80, ip_proto 6, tos 0
Doing DESTINATION addr route-lookup
  routed (x_dst_ip 100.100.100.100) from TRUST (reth10.12 in 1) to reth4.0, Next-hop: 81.82.192.1
  policy search from zone TRUST-> zone UNTRUST (0x0,0xd4e0050,0x50)
  app 6, timeout 1800s, curr ageout 20s
flow_first_src_xlate:  nat_src_xlated: False, nat_src_xlate_failed: False
flow_first_src_xlate: src nat returns status: 1, rule/pool id: 2/32770, pst_nat: False.
  dip id = 2/1, 192.168.1.10/3406->100.100.100.100/35127 protocol 6
  choose interface reth4.0 as outgoing phy if
is_loop_pak: Found loop on ifp reth4.0, addr: 100.100.100.100, rtt_idx: 0 addr_type:0x3.
flow_first_loopback_check: Setting interface: reth4.0 as loop ifp.
jsf sess interest check. regd plugins 19
 Allocating plugin info block for 19 plugin(s) from OL
-jsf int check: plugin id  2, svc_req 0x0. rc 4
-jsf int check: plugin id  3, svc_req 0x0. rc 4
-jsf int check: plugin id  5, svc_req 0x0. rc 4
-jsf int check: plugin id  6, svc_req 0x0. rc 4
-jsf int check: plugin id  7, svc_req 0x2. rc 4
-jsf int check: plugin id  8, svc_req 0x0. rc 4
-jsf int check: plugin id 11, svc_req 0x0. rc 4
+++++++++++jsf_test_plugin_data_evh: 3
-jsf int check: plugin id 12, svc_req 0x0. rc 4
-jsf int check: plugin id 13, svc_req 0x0. rc 4
-jsf int check: plugin id 14, svc_req 0x0. rc 4
-jsf int check: plugin id 17, svc_req 0x0. rc 2
-jsf int check: plugin id 18, svc_req 0x0. rc 4
 No JSF plugins enabled for session
 Releasing plugin info block for 19 plugin(s) to OL
  service lookup identified service 6.
  flow_first_final_check: in <reth10.12>, out <reth4.0>
flow_first_final_check: flow_set_xlate_vector.
construct v4 vector for nsp2
  existing vector list 1002-45700260.
  Session (id:38229) created for first pak 1002
  flow_first_install_session======> 0x4d7b8438
 nsp 0x4d7b8438, nsp2 0x4d7b84b8
flow_xlate_pak
Inner tcp hdr, TCP chksum is not needed
  post addr xlation: 100.100.100.100->100.100.100.100.
check self-traffic on reth4.0, in_tunnel 0x0
retcode: 0x401
pak_for_self : proto 6, dst port 80, action 0x0
  flow_first_create_session
  flow_first_in_dst_nat: in <reth4.0>, out <N/A> dst_adr 100.100.100.100, sp 35127, dp 80
  chose interface reth4.0 as incoming nat if.
flow_first_rule_dst_xlate: DST xlate: 100.100.100.100(80) to 192.168.5.20(80), rule/pool id 1/1.
flow_first_routing: vr_id 9, call flow_route_lookup(): src_ip 100.100.100.100, x_dst_ip 192.168.5.20, in ifp reth4.0, out ifp N/A sp 35127, dp 80, ip_proto 6, tos 0
Doing DESTINATION addr route-lookup
  routed (x_dst_ip 192.168.5.20) from UNTRUST (reth4.0 in 1) to reth8.5, Next-hop: 192.168.5.20
  policy search from zone UNTRUST-> zone DMZ (0x110,0x89370050,0x50)
  policy has timeout 900
  app 6, timeout 1800s, curr ageout 20s
flow_first_src_xlate:  nat_src_xlated: False, nat_src_xlate_failed: False
flow_first_src_xlate: src nat returns status: 0, rule/pool id: 0/0, pst_nat: False.
  dip id = 0/0, 100.100.100.100/35127->100.100.100.100/35127 protocol 0
  choose interface reth8.5 as outgoing phy if
is_loop_pak: No loop: on ifp: reth8.5, addr: 192.168.5.20, rtt_idx:9
  check nsrp pak fwd: in_tun=0x0, VSD 1 for out ifp reth8.5
  vsd 1 is active
jsf sess interest check. regd plugins 19
 Allocating plugin info block for 19 plugin(s) from OL
-jsf int check: plugin id  2, svc_req 0x0. rc 4
-jsf int check: plugin id  3, svc_req 0x0. rc 4
-jsf int check: plugin id  5, svc_req 0x0. rc 4
-jsf int check: plugin id  6, svc_req 0x0. rc 4
-jsf int check: plugin id  7, svc_req 0x2. rc 4
-jsf int check: plugin id  8, svc_req 0x0. rc 4
-jsf int check: plugin id 11, svc_req 0x0. rc 4
+++++++++++jsf_test_plugin_data_evh: 3
-jsf int check: plugin id 12, svc_req 0x0. rc 4
-jsf int check: plugin id 13, svc_req 0x0. rc 4
-jsf int check: plugin id 14, svc_req 0x0. rc 4
-jsf int check: plugin id 17, svc_req 0x0. rc 2
-jsf int check: plugin id 18, svc_req 0x0. rc 4
 No JSF plugins enabled for session
 Releasing plugin info block for 19 plugin(s) to OL
  service lookup identified service 6.
  flow_first_final_check: in <reth4.0>, out <reth8.5>
flow_first_final_check: flow_set_xlate_vector.
construct v4 vector for nsp2
  existing vector list 1022-45d1cf98.
  Session (id:46919) created for first pak 1022
nsp:0x4d7b8438, 192.168.1.10/3406 -> 100.100.100.100/80:6,
nsp:0x4d7b84b8, 100.100.100.100/80 -> 100.100.100.100/35127:6,
nsp:0x4db7fb48, 192.168.1.10/35127 -> 100.100.100.100/80:6,
nsp:0x4db7fbc8, 192.168.5.20/80 -> 100.100.100.100/35127:6,
  existing vector list 1022-45d1cf98.
nsp:0x4d7b8438, 192.168.1.10/3406 -> 100.100.100.100/80:6,
nsp:0x4d7b84b8, 192.168.5.20/80 -> 100.100.100.100/35127:6,
  make_nsp_ready_no_resolve()
  route lookup: dest-ip 192.168.1.10 orig ifp reth10.12 output_ifp reth10.12 orig-zone 6 out-zone 6 vsd 1
  route to 192.168.1.10
Installing c2s NP session wing
Installing s2c NP session wing
  flow got session.
  flow session id 38229
 vector bits 0x1022 vector 0x45d1cf98
  vsd 1 is active
  tcp flags 0x2, flag 0x2
  Got syn, 192.168.1.10(3406)->100.100.100.100(80), nspflag 0x1021, 0x20
flow_xlate_pak
  post addr xlation: 100.100.100.100->192.168.5.20.
  post addr xlation: 100.100.100.100->192.168.5.20.
skip pre-frag: is_tunnel_if- 0, is_if_mtu_configured- 0
mbuf 0x42238580, exit nh 0x297b3c2
 ----- flow_process_pkt rc 0x0 (fp rc 0)

Blog Category:

Rant: Network Application Firewalls

I often get into discussions about "next-generation firewalls" versus "traditional firewalls". All firewall vendors are moving in this same direction, adding deeper inspection to their devices.
For sales, it's a very easy pitch. Everyone is annoyed with the limited visibility L4 firewalls have and proxies have always been a necessary evil. Along comes this one new box that will fix all these issues. Who wouldn't want one?

Marketing will say you no longer need to worry about TCP or UDP ports, just applications. But if you think about this for a few seconds, you'll know this isn't true. Applications can only be identified once a connection has been established and a certain amount of traffic has been passed back and forth. So if you want to allow HTTP on any port, you need to allow TCP connections to any port and block them once they turn out to be something different than HTTP. You just opened your entire network to portscans and all sorts of badness. This is a very easy configuration error to make - I've seen it happen several times already.

I was going to write about some of the interesting things you could do to trick the application-identification, but found an excellent presentation which pretty much sums up my thoughts:
DEFCON19 Presentation Slides
DEFCON19 Presentation Video
You may recognize the CLI - but this applies to all vendors. It's about the technology, not the individual products.

In summary:

  • application-identification only looks at the first bytes and can be tricked.
  • application-identification caches can be poisoned.
  • its not all unicorns and rainbows, sorry.

Conclusion:
Does this mean application firewalls are useless? Absolutely not. You simply need to be aware of its limitations.

In my opinion, L7 firewalls are an additional layer of defense, not a replacement for the stateful firewalls. You still need a stateful L4 box in front to attach the network segments to that don't require application-identification or need better performance. This also reduces the risk of configuration errors on the L7 device.
On the L7 firewall you need to remember to only allow applications on the ports they need and that application-identification is an expensive operation, especially for certain UDP based protocols.

Pages

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