architecture plan for osmo-epdg
We need to come up with a good architectural plan of how we'd want to implement an ePDG.
In the end it is a "fancy" IPsec gateway between the 3GPP CN and the public internet. Somewhere on the level of A SGW in the LTE EPC.
Major elements are:
- handling of ESP in UDP / NAT-T for the user plane
- Linux kernel IPsec would be great to use
- handling of IKE for session setup / key exchange framework
- this could be strongswan
- handling of EAP-AKA for 3GPP specific authentication againt HSS
- this could be some strongswan plugin that then talks DIAMETER towards a HSS in order to obtain authentication tuples
- DNS based look-up/resolution of PGW for the APN specified by the user
- encapsulation of user plane traffic in GTP-U towards the PGW
- in theory, the linux kernel GTP module should be able to do this [in "SGSN" role"]
- of course there might be dificulty combining that with IPsec
- in the worst case, we might be able to leverage a standard UPF to do the encap/decap part, but I hope we don't need to go there.
- IP address allocation inside the tunnel
- signaling of internal DNS servers
- signaling of P-CSCF address (likely obtained via DIAMETER from HSS or via global config?)
In terms of code reuse, we could theoretically look at leveraging DIAMETER from open5gs, but then it uses freeDiameter, so we can likely also "just" use freeDiameter directly.
At first glance, there doesn't seem to be any IKEv2 implementation with Linux kernel IPsc support in Erlang, Go or Python, which would allow us to do the signaling / control plane in a higher-level possibly more safe programming language than C.However,
- https://github.com/qwj/python-vpn looks like a fairly recent implementation with even ESP/user plane in python (we'd want to plug kernel ESP in there)
- https://github.com/kimvais/ike is an older (abandoned?) approach for just the IKE side, no ESP
- https://docs.rs/ipsec-parser/0.7.0/ipsec_parser/ is just a basic parser in rust, no protocol logic, encoder, ...
- some yet-unreleased code to add PC/SC reader support to strongswan so it can act as a client with EAP-AKA
Updated by laforge over 2 years ago
- 3GPP TS 23.402, particularly Section 7
- note Figures 7.1.1-2, 7.2.4-1 and 7.10 for the main procedures
- 3GPP TS 24.302
- 3GPP TS 23.402, particularly Section 7
- 3GPP AAA Server
- TS 33.402
- TS 29.273 particularly Sections 7, 8 and 9
scope of implementation¶
What we need to implement is actually a combination of ePDG + "3GPP AAA Server".The ePDG has to talk the following interfaces
- SWu: IKEv2 and ESP on the SWu interface towards the UE
- SWm: DIAMETER to 3GPP AAA Server
- S2b: GTPv2C+GTPv1u to PGW
- GXb: DIAMETER to PCRF
Implementation language / environment¶
- IKEv2: No real alternative to StrongSwan/charon unless we want to start from scratch
- ESP: Linux kernel IPsec should be used
- Linux kernel GTP-U should be used back-to-back wit kernel IPsec
DIAMETER¶Basically two options:
- use C, base around freeDiameter (open5gs fork?)
- use Erlang and its built-in DIAMETER application (already used in osmo_diameter2gsup)
GTPv2C¶Basically two options:
- use C, use open5gs GTPv2C codebase
- use Erlang and the gtplib as used in ergw
Unless we want to reimplement everything from scratch in python, or go for a programming language we have limited to zero experience in (Go, Rust) this leaves us with either reusing open5gs code or Erlang code.
Basically we have to choose between writing the code in "open5gs world", or in the "Erlang world".
Starting the development of new control-plane network elements in a low-level language like C doesn't really make sense to me in 2021. The only performance critical part is the user plane, and we will use kernel ESP + kernel GTP for that.
So I think this project is an excellent opportunity to implement one "full" network element in Erlang. We rarely have this chance in other OSmocom CNI projects, as we always benefit from all the existing code/libraries we have for the classic 2G/3G netwokr elements. But here, none of that legacy would be useful. WE don't have Osmocom C language DIAMETER or GTPv2C. Merging open5gs code with libosmocore is also not an option, as it brings its own set of extensive libraries with different structures for timers, FSMs, packet buffers, etc.
Updated by laforge about 1 year ago
Just had a call with lynxis, and related to that call, the following Erlang libraries/applications should be possible to use:
- the OTP diameter application, as we use it in osmo_diameter2gsup
- https://github.com/travelping/gen_netlink as a generic netlink interface library
- https://github.com/travelping/gtp_u_kmod/blob/master/src/gtp_u_kernel.erl using gen_netlink to create/update/delete gtp tunnels in the kernel GTP driver
It would be an idea to first have a small stand-alone erlang program that uses those libraries to create kernel GTP tunnels whose creation/modification/removal can be confirmed using
libgtpnl/tools/gtp-tunnel to display the current in-kernel state.
FYI: While current mainline
gtp.ko doesn't yet support IPv6, @payuso will be working on this very soon. So it makes sense to have all our data structures prepared for that, rather than implement something new v4-only in 2023.