Skip to content

Setup Example

Fabricio edited this page Mar 18, 2022 · 3 revisions

Setup used to test the application with free5GC:

I used two VMs:

  • VM1 with the application
  • VM2 with the free5GC Core

Used config files:

Note: I only show the config files I changed.

n3iwfcfg.yaml

info:
  version: 1.0.0
  description: N3IWF initial local configuration

configuration:
  N3IWFInformation:
    GlobalN3IWFID: # ID used to globally identify an N3IWF
      PLMNID: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>
        MCC: # Mobile Country Code (3 digits string, digit: 0~9)
          208
        MNC: # Mobile Network Code (2 or 3 digits string, digit: 0~9)
          93
      N3IWFID: # ID used to identify an N3IWF in PLMN (uinteger, range: 0~65535)
        135
    Name: # The name of this N3IWF
      free5GC_N3IWF
    SupportedTAList: # Tracking Area supported by this N3IWF
      - TAC: # Tracking Area Code (3 bytes hex string, range: 000000~FFFFFF)
          000001
        BroadcastPLMNList: # Refer to TS 38.413
          - PLMNID: # Public Land Mobile Network ID
              MCC: # Mobile Country Code (3 digits string, digit: 0~9)
                208
              MNC: # Mobile Network Code (2 or 3 digits string, digit: 0~9)
                93
            TAISliceSupportList: # Network Slice supported in this TAI
              - SNSSAI: # Single Network Slice Selection Assistance Information
                  SST: # Slice/Service Type (1 byte hex string, range: 0~F)
                    1
                  SD: # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
                    010203
              - SNSSAI:
                  SST:
                    1
                  SD:
                    112233
  AMFSCTPAddresses: # the IP list of N2 interfaces (SCTP) on AMF when using NGAP
    - IP:
      - 172.16.168.131

  # --- Bind Interfaces ---
  IKEBindAddress: # IP address of Nwu interface (IKE) on this N3IWF
    172.16.62.131

  IPSecInterfaceAddress: # IP address of IPSec virtual interface (IPsec tunnel enpoint on this N3IWF)
    10.0.0.1

  IPSecInterfaceMark: # IPSec virtual interface mark (Any value except to 0, default value is 7 if not defined)
    5

  GTPBindAddress: # IP address of N3 interface (GTP) on this N3IWF
     172.16.63.11

  NASTCPPort: # TCP port which the NAS listens on
    20000

  FQDN: # FQDN of this N3IWF
    n3iwf.free5gc.org


  # --- Security ---
  PrivateKey: # Private key file path

  CertificateAuthority: # Certificate Authority (CA) file path

  Certificate: # Certificate file path



  UEIPAddressRange: # IP address allocated to UE in IPSec tunnel
    10.0.0.0/24

# the kind of log output
  # debugLevel: how detailed to output, value: trace, debug, info, warn, error, fatal, panic
  # ReportCaller: enable the caller report or not, value: true or false
logger:
  N3IWF:
    debugLevel: trace
    ReportCaller: false
  NGAP:
    debugLevel: trace
    ReportCaller: false
  Aper:
    debugLevel: info
    ReportCaller: false
  PathUtil:
    debugLevel: trace
    ReportCaller: false

amfcfg.yaml

info:
  version: 1.0.0
  description: AMF initial local configuration

configuration:
  amfName: AMF # the name of this AMF
  ngapIpList:  # the IP list of N2 interfaces on this AMF
    - 172.16.168.131
    - 127.0.0.1
  sbi: # Service-based interface information
    scheme: http # the protocol for sbi (http or https)
    registerIPv4: 127.0.0.18 # IP used to register to NRF
    bindingIPv4: 127.0.0.18  # IP used to bind the service
    port: 8000 # port used to bind the service
  serviceNameList: # the SBI services provided by this AMF, refer to TS 29.518
    - namf-comm # Namf_Communication service
    - namf-evts # Namf_EventExposure service
    - namf-mt   # Namf_MT service
    - namf-loc  # Namf_Location service
    - namf-oam  # OAM service
  servedGuamiList: # Guami (Globally Unique AMF ID) list supported by this AMF
    # <GUAMI> = <MCC><MNC><AMF ID>
    - plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>
        mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
        mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
      amfId: cafe00 # AMF identifier (3 bytes hex string, range: 000000~FFFFFF)
  supportTaiList:  # the TAI (Tracking Area Identifier) list supported by this AMF
    - plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>
        mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
        mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
      tac: 1 # Tracking Area Code (uinteger, range: 0~16777215)
  plmnSupportList: # the PLMNs (Public land mobile network) list supported by this AMF
    - plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>
        mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
        mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
      snssaiList: # the S-NSSAI (Single Network Slice Selection Assistance Information) list supported by this AMF
        - sst: 1 # Slice/Service Type (uinteger, range: 0~255)
          sd: 010203 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
        - sst: 1 # Slice/Service Type (uinteger, range: 0~255)
          sd: 112233 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
  supportDnnList:  # the DNN (Data Network Name) list supported by this AMF
    - internet
  nrfUri: http://127.0.0.10:8000 # a valid URI of NRF
  security:  # NAS security parameters
    integrityOrder: # the priority of integrity algorithms
      - NIA2
      # - NIA0
    cipheringOrder: # the priority of ciphering algorithms
      - NEA0
      # - NEA2
  networkName:  # the name of this core network
    full: free5GC
    short: free
  t3502Value: 720  # timer value (seconds) at UE side
  t3512Value: 3600 # timer value (seconds) at UE side
  non3gppDeregistrationTimerValue: 3240 # timer value (seconds) at UE side
  # retransmission timer for paging message
  t3513:
    enable: true     # true or false
    expireTime: 6s   # default is 6 seconds
    maxRetryTimes: 4 # the max number of retransmission
  # retransmission timer for NAS Deregistration Request message
  t3522:
    enable: true     # true or false
    expireTime: 6s   # default is 6 seconds
    maxRetryTimes: 4 # the max number of retransmission
  # retransmission timer for NAS Registration Accept message
  t3550:
    enable: true     # true or false
    expireTime: 6s   # default is 6 seconds
    maxRetryTimes: 4 # the max number of retransmission
  # retransmission timer for NAS Authentication Request/Security Mode Command message
  t3560:
    enable: true     # true or false
    expireTime: 6s   # default is 6 seconds
    maxRetryTimes: 4 # the max number of retransmission
  # retransmission timer for NAS Notification message
  t3565:
    enable: true     # true or false
    expireTime: 6s   # default is 6 seconds
    maxRetryTimes: 4 # the max number of retransmission

# the kind of log output
  # debugLevel: how detailed to output, value: trace, debug, info, warn, error, fatal, panic
  # ReportCaller: enable the caller report or not, value: true or false
logger:
  AMF:
    debugLevel: trace
    ReportCaller: false
  NAS:
    debugLevel: trace
    ReportCaller: false
  FSM:
    debugLevel: trace
    ReportCaller: false
  NGAP:
    debugLevel: trace
    ReportCaller: false
  Aper:
    debugLevel: info
    ReportCaller: false
  PathUtil:
    debugLevel: trace
    ReportCaller: false
  OpenApi:
    debugLevel: trace
    ReportCaller: false

Adaptations in the application and corrections done in free5gc to make it work

  1. Free5gc does not send the PDU Session Establishment Accept to the UE through signaling SA child. Only creates the userplane SA child. That means that we must figure out what will be the session IP. Using free5gc defaults, that address is 60.60.0.1. First I added an option to my code to set the session IP in order to create the tunnel for user plane sesion correctly, but then I did some changes in the n3iwf/ngap/handler/handler.go and correct it.
  2. The GRE implementation does not comply with 3GPP requirements (it uses 4 bytes instead of 8 bytes with RQI). Solution: I adapted my code to it…
  3. The NAS messages should be prefixed with 2 bytes with NAS lengh information, but in free5GC NAS messages are carried directly in the TCP connection. Solution: I adapted my code.
  4. AN parameter “requested NSSAI” is not correctly formatted. Solution I adapt my code.
  5. EAP-AKA’ authentication not complete (in AMF), and several erroneous checks (in AUSF when comparing RES with XRES, wrong padding in RES processing, KSEAF calculated based on empty KAUSF key). Solution: I changed the ausf/producer/functions.go and ue_authentication.go and also amf/gmm/handler.go
  6. EAP-AKA’ packets do not have the subtype byte (e.g. AKA-Challenge, etc…) and the following 2 reserved bytes (3 bytes in total). Solution: I adapted my code.
  7. Integrity and Ciphering functions in AMF are using Bearer ID for 3GPP access, instead of non-3GPP access as stated in 33.501. Solution: I adapted my code.

Changes done in files:

AMF:

https://github.com/fasferraz/amf/commit/16cfa93455cf01f3e7ba4015b659d5857666eb09

AUSF:

https://github.com/fasferraz/ausf/commit/dd70ddd6b72ca2f606fb4b2dae18dd1b1ef33db4

https://github.com/fasferraz/ausf/commit/923de46ee7fbfd7718786a89a8bde536288fb1c9

N3IWF:

https://github.com/fasferraz/n3iwf/commit/7226b0e1dc43fdd617a7f5f334443268ae9dbc88

Configurations in free5GC VM:

ip link add ipsec0 type vti local 172.16.62.131 remote 0.0.0.0 key 5
ip address add 10.0.0.1/24 dev ipsec0
ip link set dev ipsec0 up
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
sudo systemctl stop ufw

What was tested

I tested two authentication scenarios:

  • 5G-AKA with IMSI 2089300007487

and

  • EAP-AKA' with IMSI 208930000000003

Note: By default the authentication is 5G-AKA, so if you want to change it, you need to use the Web UI to access and change this subscription parameter.

How to run the application in VM1 for each IMSI:

root@ubuntu:/home/fabricio# python3 nwu_emulator.py  -a internet -d 172.16.62.131 -M 208 -N 93 -I 208930000000003 -K 8baf473f2f8fd09487cccbd7097c6862  -P 8e27b6af0e692e750f32667a3b14605d   -s 172.16.62.130 -F
root@ubuntu:/home/fabricio# python3 nwu_emulator.py  -a internet -d 172.16.62.131 -M 208 -N 93 -I 2089300007487 -K 5122250214c33e723a5dd523fc145fc0 -P c9e8763286b5b9ffbdf56e1297d0887b   -s 172.16.62.130 -F

This was the routing table in VM1 before running the application:

root@ubuntu:/home/fabricio# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         60.60.0.2       128.0.0.0       UG    0      0        0 tun3
0.0.0.0         172.16.62.2     0.0.0.0         UG    20101  0        0 ens33
10.0.0.1        10.0.0.216      255.255.255.255 UGH   0      0        0 tun2
128.0.0.0       60.60.0.2       128.0.0.0       UG    0      0        0 tun3
172.16.62.0     0.0.0.0         255.255.255.0   U     101    0        0 ens33
172.16.168.0    0.0.0.0         255.255.255.0   U     102    0        0 ens35

root@ubuntu:/home/fabricio/Documents# 

This was the routing table in VM1 after running the application:

root@ubuntu:/home/fabricio# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         60.60.0.2       128.0.0.0       UG    0      0        0 tun3
0.0.0.0         172.16.62.2     0.0.0.0         UG    20101  0        0 ens33
10.0.0.1        10.0.0.216      255.255.255.255 UGH   0      0        0 tun2
128.0.0.0       60.60.0.2       128.0.0.0       UG    0      0        0 tun3
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ens34
172.16.62.0     0.0.0.0         255.255.255.0   U     101    0        0 ens33
172.16.63.0     0.0.0.0         255.255.255.0   U     100    0        0 ens34
172.16.168.0    0.0.0.0         255.255.255.0   U     102    0        0 ens35

Two tunnels interfaces were created in VM1 by the application:

  • One for control (signalling SA Child) and another one for userplane (userplane SA Child):
tun2: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.0.0.216  netmask 255.255.255.255  destination 10.0.0.216
        inet6 fe80::abc2:feaf:4fab:eace  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 8  bytes 550 (550.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13  bytes 725 (725.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tun3: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 60.60.0.2  netmask 255.255.255.255  destination 60.60.0.2
        inet6 fe80::7ff3:c366:a494:1bd1  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4  bytes 192 (192.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

This was the routing table in VM2 after establishing the session:

root@free5gc:/home/fabricio/free5gc/config# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.62.2     0.0.0.0         UG    20100  0        0 ens33
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 ipsec0
60.60.0.0       0.0.0.0         255.255.255.0   U     0      0        0 upfgtp
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ens33
172.16.62.0     0.0.0.0         255.255.255.0   U     100    0        0 ens33
172.16.63.0     0.0.0.0         255.255.255.0   U     102    0        0 ens39
172.16.168.0    0.0.0.0         255.255.255.0   U     101    0        0 ens38
root@free5gc:/home/fabricio/free5gc/config# 

To reach network 60.60.0.0/24 the interface upfgtp is used.

Pinging session IP 60.60.0.2 from VM2 (using interface ens39 as source):

root@free5gc:/home/fabricio/free5gc/config# ping 60.60.0.2 -I 172.16.63.11
PING 60.60.0.2 (60.60.0.2) from 172.16.63.11 : 56(84) bytes of data.
64 bytes from 60.60.0.2: icmp_seq=1 ttl=64 time=4.79 ms
64 bytes from 60.60.0.2: icmp_seq=2 ttl=64 time=1.88 ms
64 bytes from 60.60.0.2: icmp_seq=3 ttl=64 time=1.49 ms
64 bytes from 60.60.0.2: icmp_seq=4 ttl=64 time=1.72 ms
64 bytes from 60.60.0.2: icmp_seq=5 ttl=64 time=1.76 ms

Log output from free5gc in VM2 for these 5 pings:

2021-07-08T15:32:33+01:00 [TRAC][N3IWF][GTP] Read 84 bytes
2021-07-08T15:32:33+01:00 [TRAC][N3IWF][GTP] Forward NWu <- N3
2021-07-08T15:32:33+01:00 [TRAC][N3IWF][GTP] Wrote 88 bytes
2021-07-08T15:32:33+01:00 [TRAC][N3IWF][NWuUP] Read 88 bytes
2021-07-08T15:32:33+01:00 [TRAC][N3IWF][NWuUP] Forward NWu -> N3
2021-07-08T15:32:33+01:00 [TRAC][N3IWF][NWuUP] Wrote 92 bytes

2021-07-08T15:32:34+01:00 [TRAC][N3IWF][GTP] Read 84 bytes
2021-07-08T15:32:34+01:00 [TRAC][N3IWF][GTP] Forward NWu <- N3
2021-07-08T15:32:34+01:00 [TRAC][N3IWF][GTP] Wrote 88 bytes
2021-07-08T15:32:34+01:00 [TRAC][N3IWF][NWuUP] Read 88 bytes
2021-07-08T15:32:34+01:00 [TRAC][N3IWF][NWuUP] Forward NWu -> N3
2021-07-08T15:32:34+01:00 [TRAC][N3IWF][NWuUP] Wrote 92 bytes

2021-07-08T15:32:35+01:00 [TRAC][N3IWF][GTP] Read 84 bytes
2021-07-08T15:32:35+01:00 [TRAC][N3IWF][GTP] Forward NWu <- N3
2021-07-08T15:32:35+01:00 [TRAC][N3IWF][GTP] Wrote 88 bytes
2021-07-08T15:32:35+01:00 [TRAC][N3IWF][NWuUP] Read 88 bytes
2021-07-08T15:32:35+01:00 [TRAC][N3IWF][NWuUP] Forward NWu -> N3
2021-07-08T15:32:35+01:00 [TRAC][N3IWF][NWuUP] Wrote 92 bytes

2021-07-08T15:32:36+01:00 [TRAC][N3IWF][GTP] Read 84 bytes
2021-07-08T15:32:36+01:00 [TRAC][N3IWF][GTP] Forward NWu <- N3
2021-07-08T15:32:36+01:00 [TRAC][N3IWF][GTP] Wrote 88 bytes
2021-07-08T15:32:36+01:00 [TRAC][N3IWF][NWuUP] Read 88 bytes
2021-07-08T15:32:36+01:00 [TRAC][N3IWF][NWuUP] Forward NWu -> N3
2021-07-08T15:32:36+01:00 [TRAC][N3IWF][NWuUP] Wrote 92 bytes

2021-07-08T15:32:37+01:00 [TRAC][N3IWF][GTP] Read 84 bytes
2021-07-08T15:32:37+01:00 [TRAC][N3IWF][GTP] Forward NWu <- N3
2021-07-08T15:32:37+01:00 [TRAC][N3IWF][GTP] Wrote 88 bytes
2021-07-08T15:32:37+01:00 [TRAC][N3IWF][NWuUP] Read 88 bytes
2021-07-08T15:32:37+01:00 [TRAC][N3IWF][NWuUP] Forward NWu -> N3
2021-07-08T15:32:37+01:00 [TRAC][N3IWF][NWuUP] Wrote 92 bytes

Update (2022-03-18)

With new free5GC N3IWF version most bugs are solved.

Some advices when running my application:

  • Use namespace option to have a complete separated routing table (and simple)
  • Enter namespace and change tun3 MTU to something like 1300 bytes to avoid going above 1500 bytes with all IP layers, otherwise, free5GC will crash.
  • Start applications in namespace. DNS is also supported for namespace.