SELinuxProject/selinux-kernel

RFE: add GPRS Tunnelling Protocol (GTP) suppport

pcmoore opened this issue · 1 comments

As discussed on the mailing list, we should consider adding access controls for the GPRS Tunnelling Protocol (GTP).

A nice overview of a GTP was provided by Harald Welte:

There really only is one use case for this code: The GGSN or P-GW function
in the 3GPP network architecture. There are open source implementations
like OsmoGGSN and (at least older/previos versions) of ergw, but also
non-FOSS-but-shared-source (like OpenAirInterface) and proprietary
software that use the existing kernel GTP for that.

In a GGSN (2G/3G) or P-GW (4G), you have a control plane instance
talking a control plane protocol GTP-C (GTPv1-C or GTPv2-C) with other
elements in the network, such as the SGSN (2G/3G) or S-GW (4G)

This control plane instance will then talk to the user plane instance
(which is, in the case of the kernel GTP module, netlink) to crate PDP
contexts (2G/3G) or "barers" (4G).

Those PDP contexts / bearers are constantly being created, modified and
torn down. Creation happens at the time your modern phone attaches to
the network (once you have "mobile data" enabled). Modification happens
when you start roaming around the country / coverage area as you change
between larger regions. Deletion happens once you disable "mobile data'
or go into airplane mode.

The kernel GTP "tun" device typically represents an "APN", i.e. one
specific IP network your phones/modems want to attach to. There could be
multiple in parallel (e.g. public internet, private operator network for
VoLTE, company-private networks).

So you have one tun device per APN which is mostly static configuration,
stable for months, years, ... and then you have the hightly volatile
PDP contexts / bearers within each of those APN. That's why I was
hinting from a security policy point of view, it makes sense to separate
those two, as one only happens at system boot / application start time,
and the other happens at any point during runtime of your GGSN/PGW.

If you want to see how that looks on the wire, check the OsmoGGSN
automatic test suite, where every test case generates a pcap file:
overview at https://jenkins.osmocom.org/jenkins/view/TTCN3/job/ttcn3-ggsn-test/
actual artefacts including per-test pcap files:
https://jenkins.osmocom.org/jenkins/view/TTCN3/job/ttcn3-ggsn-test/lastSuccessfulBuild/artifact/logs/ggsn-tester/
specifically, if you open
https://jenkins.osmocom.org/jenkins/view/TTCN3/job/ttcn3-ggsn-test/lastSuccessfulBuild/artifact/logs/ggsn-tester/GGSN_Tests.TC_pdp6_act_deact_gtpu_access.pcap.gz
in wirehark and filter on 'gtp', you will see the GTP-C traffic on udp
port 2123, and the GTP-U traffic on UDP port 2152. This second part is
where you would use the kernel-GTP-U implementation to avoid the
kernel-userspace-kernel roundtrip for every user IP packet.

There are many other use cases for GTP in general in other network
elements such as a S-GW (which basically acts as a proxy for GTP-U), but
those are not implemented in the existing Linux kernel GTP module.

I think OsmoGGSN is about the most simple to understand user out there,
due to its very limited code size. Check
https://git.osmocom.org/osmo-ggsn/tree/lib/gtp-kernel.c for the libgtpnl
interface and https://git.osmocom.org/osmo-ggsn/tree/ggsn/ggsn.c for the
hearth of the logic, including the calls to the gtp_kernel_tunnel_*() API.