# Entorno 5G Core ## Descripción del entorno Se encuentra en la máquina 192.168.159.75. La arquitectura desplegada se asemeja a la siguinte![Propuesta_Arquitectura](https://hackmd.io/_uploads/HknyUkg0R.jpg) La topología desplegada es la siguiente ![Topologia](https://hackmd.io/_uploads/HJ3cHmaJJe.png) ## Confifuración del entorno A excepción del ```dockerfile``` para crear la imagen generica que usaran los UE y los alguna otra de las entidades, el resto de archivos de configuración y asibles se encuentran en la carpeta ```horse-complete```. ### Ficheros Importantes - __/5G-lab/pqreact-lab.yaml__: describe la topologia que se va a lanzar. - __/5G-core/horse-deployment/lab-config.yaml__: ejecuta dentro de los pods los ficheros ```.py``` que se encuentran en la carpeta configuracion. - __/5G-core/configuracion/__: en este directorio se encuentran todos los archivos de python que se van a ejecutar dentro de cada uno de los podscd que lanzemos. ### Modificar imagen generic Se pueden añadir elementos al ```dockerfile``` para añadirlos a la imagen generic que generamos. Una vez actualizado el ```dockerfile``` lo siguiente será compilar/crear la imagen y añadirla al repositorio de ```kne``` para que pueda acceder a ella cuando despleguemos la arquitectura. Para ello podemos utilizar los siguientes comandos: ``` docker build -t generic . kind load docker-image generic:latest --name=kne ``` Se pueden consultar las imagenes a las que tiene acceso el cluster de kind con el siguiente comando: ``` docker exec -it kne-control-plane crictl images ``` ¡¡¡SI NO RECONOCE EL COMANDO KIND!!! A veces pasa que go se quita del `PATH` y como kind dependende de go no reconoce el comando. Se puede comrpobar si el error viene de ahi haciendo un `go version` y ver si reconoce el comando `go`. Para solucionarlo hacer `ls` en `/home/ubuntu` para ver si sigue estando la carpeta `go`. Si es así basta con lanzar los siguientes comandos para volver a meter go en el PATH: ``` export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:$(go env GOPATH)/bin ``` ## Despliegue del entorno Asumimos que ya está desplegado KNE siguiendo las indicaciones de su repositorio de [github](https://github.com/openconfig/kne/blob/main/docs/setup.md). Despues nos vamos a la guia de como [crear una topologia](https://github.com/openconfig/kne/blob/main/docs/create_topology.md) y seguimos los pasos. En nuestro caso estamos usando el `cEOS Controller`, y la imagen ya se encuentra en el cluster de kind, pero en caso de no encontrarla en el directorio `/home/ubuntu` está la imagen en formato `tar`. Para pasarla al cluster de kind bastaria con los siguientes comandos: ``` cat cEOS-lab-4.29.2F.tar | docker import - ceos kind load docker-image ceos:latest --name=kne ``` Para desplegar la topología lanzamos el siguiente comando ``` kne create pqreact-lab.yaml ``` Para lanzar los archivos de configuración de cada pod: ``` ansible-playbook horse-deployment/lab-config.yaml ``` ### Despliegue del entorno 5G Una vez lanzado todo hay que descargar y [desplegar las soluciones de 5G-core y de UE/RAN en los pods.](https://github.com/s5uishida/open5gs_5gc_ueransim_sample_config) Seguimos los pasos de ese enlace para desplegar el entorno 5G. Puntos a tener en cuenta: - Mongo por algun motivo no se crea como servicio, de modo que hay que dejarlo ejecutandose en una terminal. Para ello usamos el comando ```tmux``` que nos crea una terminal. Dentro de esta nueva terminal ejecutamos el comando ```mongod --config /etc/mongod.conf```. Para salir de esa terminal y que se quede ejecutandose hacemos ```ctrl+b``` y luego ```d```. - Importante crear en el UPF la interfaz de red ``` ip tuntap add name ogstun mode tun ip addr add 10.45.0.1/16 dev ogstun ip link set ogstun up iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE ``` Si dentro del contenedor/pod sale un error al intentar crear el tuntap, los siguientes comandos parecen solucionar el problema: ``` mkdir -p /dev/net mknod /dev/net/tun c 10 200 chmod 600 /dev/net/tun ``` - Se adjuntan a continuación capturas de las configuraciones: - 5g-core ```/open5gs/install/etc/open5gs/amf.yaml``` ![image](https://hackmd.io/_uploads/HkTa_6OWyx.png) ```/open5gs/install/etc/open5gs/nrf.yaml``` ![image](https://hackmd.io/_uploads/rJSeq6u-kx.png) ```/open5gs/install/etc/open5gs/smf.yaml``` ![image](https://hackmd.io/_uploads/S1W756_Z1x.png) - UPF ```/open5gs/install/etc/open5gs/upf.yaml``` ![image](https://hackmd.io/_uploads/HkUF56dWJx.png) - gNB1 ```/UERANSIM/config/open5gs-gnb.yaml``` ![image](https://hackmd.io/_uploads/HJGR5a_-ye.png) - UE-2 ```/UERANSIM/config/open5gs-ue.yaml``` ![image](https://hackmd.io/_uploads/H1MIjp_-Jx.png) - Para ejecutar los servicios - 5g-core ``` ./install/bin/open5gs-nrfd & sleep 2 ./install/bin/open5gs-scpd & sleep 2 ./install/bin/open5gs-amfd & sleep 2 ./install/bin/open5gs-smfd & ./install/bin/open5gs-ausfd & ./install/bin/open5gs-udmd & ./install/bin/open5gs-udrd & ./install/bin/open5gs-pcfd & ./install/bin/open5gs-nssfd & ./install/bin/open5gs-bsfd & ``` - UPF ``` ./install/bin/open5gs-upfd & ``` - gNB ``` cd UERANSIM/build ./nr-gnb -c ../config/open5gs-gnb.yaml ``` - UE ``` cd UERANSIM/build ./nr-ue -c ../config/open5gs-ue.yaml ``` - Para registrar el UE hay que lanzar el servicio web desde 5g-core. Se necesita ```nodejs``` en una versión igual o superior a la 20. Para lanzar el servicio web entramos en la carpeta ```webui```. Si es la primera vez que lo desplegamos hay que lanzar antes el siguiente comando ```npm ci```. Por último, para iniciar el servicio ```npm run dev```. - Para hacer el redireccionamiento para poder acceder desde el navegador del ordenador hay que hacer dos redireciones. La primera la hacemos haciendo un ```kubectl apply -f webui-service.yaml``` desde la carpeta 5g-lab. Para la segunda nos abrimos una terminal y ejecutamos el siguiente comando ```ssh -L localhost:8888:172.18.0.2:30300 ubuntu@192.168.159.75```. Una vez hecho esto podremos acceder desde nuestro navegador accediendo a la url ```http://localhost:8888/``` - Para el exponer el servicio web en el entorno del 5TONIC -> ``` ssh -L localhost:8888:10.244.0.80:9999 ubuntu@10.4.35.103```, donde 10.244.0.80 es la ip asignada al pod, que se obtiene con el comando ```kubectl get pods -o wide``` Una vez hecho todo esto nos metemos en una terminal del UE que estemos usando y para comprobar que funcione todo correctamente. Primero podemos ver que nos haya creado la interfaz de red y su IP asociada. Deberia salir algo similar a esto: ``` # ip addr show ... 21: uesimtun0: <POINTOPOINT,PROMISC,NOTRAILERS,UP,LOWER_UP> mtu 1400 qdisc fq_codel state UNKNOWN group default qlen 500 link/none inet 10.45.0.2/32 scope global uesimtun0 valid_lft forever preferred_lft forever inet6 fe80::3d90:4d95:c73e:89da/64 scope link stable-privacy valid_lft forever preferred_lft forever ... ``` Para comprobar la conectividad, desde la misma terminal del UE lanzamos ```ping google.com -I uesimtun0 -n``` ### Despliegue de las soluciones de IPSEC #### strongSwan ##### 1. *Clasico/Sin PQC:* Primero asegurarnos de que en el fichero ```/etc/sysctl.conf``` los siguientes parametros: ``` net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 ``` Para aplicar los cambios ```sysctl -p``` Instalamos los siguientes paquetes: ``` apt install strongswan strongswan-pki libcharon-extra-plugins libcharon-extauth-plugins libstrongswan-extra-plugins libtss2-tcti-tabrmd0 -y ``` Una vez instalados los paquetes tendremos que configurar varios archivos para poder establecer el tunel IPSec. Hay que generar un PSK para el archivo de secrets. Se puede crear con el siguiente comando: ``` head -c 24 /dev/urandom | base64 ``` Ejemplos de la configuración en el escenario para generar el tunel entre secgw-11 y secgw-12: * SecGW 11: ``` # cat /ect/ipsec.conf ... config setup charondebug="all" strictcrlpolicy=yes uniqueids=yes # Add connections here. conn UE-to-Core authby=secret left=%defaultroute leftid=10.10.0.25 leftsubnet=10.1.0.0/24 right=10.10.0.31 rightsubnet=10.0.24.0/24 ike=aes256-sha2_256-modp1024! esp=aes256-sha2_256! keyingtries=0 ikelifetime=1h lifetime=8h dpddelay=30 dpdtimeout=120 dpdaction=restart auto=start conn UE-to-UPF authby=secret left=%defaultroute leftid=10.10.0.25 leftsubnet=10.1.0.0/24 right=10.10.0.31 rightsubnet=10.0.25.0/24 ike=aes256-sha2_256-modp1024! esp=aes256-sha2_256! keyingtries=0 ikelifetime=1h lifetime=8h dpddelay=30 dpdtimeout=120 dpdaction=restart auto=start ... # cat /etc/ipsec.secrets ... 10.10.0.25 10.10.0.31 : PSK "i+GXcw0ZUtjug8mhMzMTkSE2k69H/yK5"w ``` * SecGW 12: ``` # cat /etc/ipsec.conf ... config setup charondebug="all" strictcrlpolicy=yes uniqueids=yes # Add connections here. conn siteA-to-siteB authby=secret left=%defaultroute leftid=10.10.0.31 leftsubnet=10.0.24.0/24 right=10.10.0.25 rightsubnet=10.1.0.0/24 ike=aes256-sha2_256-modp1024! esp=aes256-sha2_256! keyingtries=0 ikelifetime=1h lifetime=8h dpddelay=30 dpdtimeout=120 dpdaction=restart auto=start conn UE-to-Core authby=secret left=%defaultroute leftid=10.10.0.31 leftsubnet=10.0.25.0/24 right=10.10.0.25 rightsubnet=10.1.0.0/24 ike=aes256-sha2_256-modp1024! esp=aes256-sha2_256! keyingtries=0 ikelifetime=1h lifetime=8h dpddelay=30 dpdtimeout=120 dpdaction=restart auto=start ... # cat /etc/ipsec.secrets ... 10.10.0.31 10.10.0.25 : PSK "i+GXcw0ZUtjug8mhMzMTkSE2k69H/yK5" ``` Una vez hemos modificado los archivos de configuración, podemos iniciar el tunel IPSec con el comando ```ipsec start```. Para comprobar el estado del tunel podemos usar el comando ```ipsec status``` o ```ipsec statusall```. Para comprobar que todo funciona correctamente podemos lanzar un ping desde el gNB1 *(en este caso)* hasta el 5G-core o el UPF. Si nos ponemos a escuchar el trafico en un SecGW con un ```tcpdump -i any icmp or esp``` podemos ver como se envia el ping y este va encapsulado: ``` root@secgw-11:/home/cognet# tcpdump -i any icmp or esp tcpdump: data link type LINUX_SLL2 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 12:31:22.773690 eth1 In IP 10.1.0.29 > 10.0.24.15: ICMP echo request, id 11821, seq 1, length 64 12:31:22.773906 eth2 Out IP 10.10.0.25 > 10.10.0.31: ESP(spi=0xc00d79de,seq=0x1), length 136 12:31:22.774253 eth2 In IP 10.10.0.31 > 10.10.0.25: ESP(spi=0xc285643d,seq=0x1), length 136 12:31:22.774253 eth2 In IP 10.0.24.15 > 10.1.0.29: ICMP echo reply, id 11821, seq 1, length 64 12:31:22.774335 eth1 Out IP 10.0.24.15 > 10.1.0.29: ICMP echo reply, id 11821, seq 1, length 64 12:31:23.789321 eth1 In IP 10.1.0.29 > 10.0.24.15: ICMP echo request, id 11821, seq 2, length 64 12:31:23.789398 eth2 Out IP 10.10.0.25 > 10.10.0.31: ESP(spi=0xc00d79de,seq=0x2), length 136 12:31:23.789582 eth2 In IP 10.10.0.31 > 10.10.0.25: ESP(spi=0xc285643d,seq=0x2), length 136 12:31:23.789582 eth2 In IP 10.0.24.15 > 10.1.0.29: ICMP echo reply, id 11821, seq 2, length 64 12:31:23.789609 eth1 Out IP 10.0.24.15 > 10.1.0.29: ICMP echo reply, id 11821, seq 2, length 64 12:31:24.813283 eth1 In IP 10.1.0.29 > 10.0.24.15: ICMP echo request, id 11821, seq 3, length 64 12:31:24.813364 eth2 Out IP 10.10.0.25 > 10.10.0.31: ESP(spi=0xc00d79de,seq=0x3), length 136 ... root@secgw-12:/home/cognet# tcpdump -i any icmp or esp tcpdump: data link type LINUX_SLL2 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 12:31:22.773910 eth1 In IP 10.10.0.25 > 10.10.0.31: ESP(spi=0xc00d79de,seq=0x1), length 136 12:31:22.773910 eth1 In IP 10.1.0.29 > 10.0.24.15: ICMP echo request, id 11821, seq 1, length 64 12:31:22.774011 eth2 Out IP 10.1.0.29 > 10.0.24.15: ICMP echo request, id 11821, seq 1, length 64 12:31:22.774187 eth2 In IP 10.0.24.15 > 10.1.0.29: ICMP echo reply, id 11821, seq 1, length 64 12:31:22.774250 eth1 Out IP 10.10.0.31 > 10.10.0.25: ESP(spi=0xc285643d,seq=0x1), length 136 12:31:23.789401 eth1 In IP 10.10.0.25 > 10.10.0.31: ESP(spi=0xc00d79de,seq=0x2), length 136 12:31:23.789401 eth1 In IP 10.1.0.29 > 10.0.24.15: ICMP echo request, id 11821, seq 2, length 64 12:31:23.789457 eth2 Out IP 10.1.0.29 > 10.0.24.15: ICMP echo request, id 11821, seq 2, length 64 12:31:23.789551 eth2 In IP 10.0.24.15 > 10.1.0.29: ICMP echo reply, id 11821, seq 2, length 64 12:31:23.789580 eth1 Out IP 10.10.0.31 > 10.10.0.25: ESP(spi=0xc285643d,seq=0x2), length 136 ... ``` Si desplegamos el entorno 5G se puede ver que las comunicaciones entre el gNB y el 5G-core/UPF van encriptadas. ##### 2. *PQC:* Para usar strongSwan con PQC necesitamos instalar la versión 6.0.0 o posteriores. Para ello podemos seguir los pasos que nos indican en su [documentación](https://docs.strongswan.org/docs/latest/install/install.html). Los pasos son los siguientes: ``` apt install make cmake gcc g++ wget bzip2 libssl-dev wget https://download.strongswan.org/strongswan-x.x.x.tar.bz2 tar xjf strongswan-x.x.x.tar.bz2 cd strongswan-x.x.x ./configure --enable-ml make make install ``` Hay que habilitar `ml` que es el plugin que permite utilizar PQC en strongSwan. Para usarlo hay que lanzar el charon, que se encuntra en la carpeta `/usr/local/libexec/ipsec`. Lo ejecutamos y ya podemos usar el comando `swanctl`. Si lanzamos `swanctl --list-algs` podemos ver los algoritmos que nos permite usar para construir el tunel IPSec. ``` # swanctl --list-algs ... ke: MODP_3072[openssl] MODP_4096[openssl] MODP_6144[openssl] MODP_8192[openssl] MODP_2048[openssl] MODP_2048_224[openssl] MODP_2048_256[openssl] MODP_1536[openssl] MODP_1024[openssl] MODP_1024_160[openssl] MODP_768[openssl] MODP_CUSTOM[openssl] ECP_256[openssl] ECP_384[openssl] ECP_521[openssl] ECP_224[openssl] ECP_192[openssl] ECP_256_BP[openssl] ECP_384_BP[openssl] ECP_512_BP[openssl] ECP_224_BP[openssl] CURVE_25519[openssl] CURVE_448[openssl] ML_KEM_512[ml] ML_KEM_768[ml] ML_KEM_1024[ml] ... ``` Se pueden ver que los ultimos algoritmos son del plugin ml y son los que usaremos. Estos corresponden al [FIPS 203](https://csrc.nist.gov/pubs/fips/203/final) A continuación configuraremos el archivo `/usr/local/etc/swanctl/swanctl.conf`, donde definiremos las conexiones. Ejemplo de configuración para secgw-11: ``` connections { gw-gw { local_addrs = 10.10.0.25 remote_addrs = 10.10.0.31 local { auth = psk id = 10.10.0.25 } remote { auth = psk id = 10.10.0.31 } children { net-net { local_ts = 10.1.0.0/24 remote_ts = 10.0.24.0/24,10.0.25.0/24 #updown = /usr/local/libexec/ipsec/_updown iptables rekey_time = 5400 rekey_bytes = 500000000 rekey_packets = 1000000 esp_proposals = aes256-sha256-mlkem512 } } version = 2 mobike = no reauth_time = 10800 proposals = aes256-sha256-x25519-mlkem512 } } secrets { ike-1 { id1 = 10.10.0.25 id2 = 10.10.0.31 secret="zOD8I522Vvt6zUt5rkpHRA4kt8YM64+C" }} ``` Una vez realizada la configuración podemos cargarla con el comando `swanctl --load-all` en ambas maquinas. Para iniciar el tunel basta con lanzar en una de las máquinas el comando `swanctl -i --child net-net`. Podemos ver si se ha creado de la siguiente forma: ``` # swanctl --list-sas gw-gw: #4, ESTABLISHED, IKEv2, c4909f45747c2b01_i* b8aa46f78ad68702_r local '10.20.0.69' @ 10.20.0.69[500] remote '10.20.0.39' @ 10.20.0.39[500] AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519 established 227s ago, reauth in 9767s net-net: #6, reqid 1, INSTALLED, TUNNEL, ESP:AES_CBC-256/HMAC_SHA2_256_128/ML_KEM_512 installed 207s ago, rekeying in 5014s, expires in 5733s in c9dd30ca, 252 bytes, 3 packets, 2s ago out c3e481e7, 252 bytes, 3 packets, 2s ago local 10.2.0.0/24 remote 10.0.24.0/24 ``` Vemos que se ha creado adecuadamente el tunel y podemos ver que los tres paquetes del ping que he hecho para comprobarlo han pasado por el tunel. Para parar el tunel se utiliza el siguiente comando `swanctl -t --child net-net` ### IPERF Para realizar las pruebas desplegamos un server iperf en la maquina que hace de gateway y lanzamos el cliente iperf en el ue usando la interfaz creada por el ue. Lanzar el server iperf -> `iperf3 -s` Lanzar la petición desde el UE (cambiar la ip del `--bind`)-> `iperf3 -c 10.4.0.1 --bind 10.45.0.2 --bind-dev uesimtun0` ## Información extra Para borrar la topología lanzamos el comando ``` kubectl delete ns pqreact-lab ```