Introducción
El 5G es la quinta generación de redes móviles, diseñada para superar ampliamente a 4G en velocidad, capacidad y latencia. Su objetivo no se limita solo a navegar más rápido por internet, sino a habilitar aplicaciones totalmente nuevas, como vehículos autónomos, realidad aumentada, telemedicina en tiempo real y millones de dispositivos conectados simultáneamente en el Internet de las Cosas (IoT).
En términos técnicos, 5G se caracteriza por tres pilares principales: eMBB (enhanced Mobile Broadband) para conexiones de alta velocidad y gran capacidad, URLLC (Ultra-Reliable Low Latency Communications) para comunicaciones críticas con latencia mínima, y mMTC (massive Machine-Type Communications) para conectar de forma eficiente millones de dispositivos IoT.
A nivel de arquitectura, 5G introduce un núcleo nativo en la nube (5GC) que soporta la segmentación de red (“network slicing”), control de tráfico dinámico, virtualización de funciones de red y una separación clara entre el plano de control y el plano de usuario. Esto permite que diferentes servicios compartan la misma infraestructura física pero funcionen como redes independientes optimizadas para cada caso. En la red de acceso radioeléctrico, 5G utiliza la gNodeB como estación base y permite distintas configuraciones, ya sea como standalone, donde toda la red es 5G puro, o como non-standalone, donde se apoya en componentes de 4G.
Para quienes desean experimentar con un núcleo 5G real sin la complejidad del hardware físico, Open5GS es una de las opciones más populares. Este proyecto de código abierto implementa el core EPC/5GC y permite levantar todos los componentes necesarios, como AMF, SMF, UPF y otros elementos fundamentales del plano de control y del plano de usuario. Aunque Open5GS puede desplegarse manualmente, hacerlo mediante contenedores simplifica enormemente el proceso, y aquí es donde entra en juego el proyecto docker_open5gs, desarrollado por herlesupreeth y disponible en GitHub. Gracias a él es posible iniciar todos los servicios del núcleo 5G en cuestión de minutos utilizando Docker y Docker Compose.
El despliegue comienza preparando el entorno de contenedores. Una vez clonado el repositorio docker_open5gs, se dispondrá de una serie de archivos docker-compose y configuraciones prediseñadas que permiten iniciar cada uno de los módulos del core en contenedores independientes. Antes de iniciar los contenedores, conviene revisar los parámetros de configuración, especialmente los relacionados con direcciones IP internas y la base de datos MongoDB que Open5GS utiliza para almacenar perfiles de abonados.
Tras ejecutar Docker Compose, los servicios comienzan a levantarse y cada componente del core queda accesible. En este punto es necesario dar de alta uno o varios suscriptores para simular el comportamiento de dispositivos 5G reales. Open5GS facilita este proceso mediante una interfaz web incorporada en algunos despliegues o mediante la edición directa de la base de datos.
Cuando finalmente se conecta el simulador gNodeB con el core, se inicia el intercambio de mensajes de registro y autenticación, permitiendo que el dispositivo simulado se adhiera a la red y establezca sesiones de datos. Es en este momento cuando la red 5G virtual cobra vida y es posible medir su rendimiento, generar tráfico y estudiar su comportamiento.
Instalación de Docker y Docker Compose
Como sistema operativo que hospedará los contenedores se recomienda una distribución reciente de Linux (por ejemplo Ubuntu 22.04 o superior). Los requisitos mínimos son Docker Engine (docker-ce) versión 22.0.5 o superior y Docker Compose versión 2.14 o superior. Se procede con su instalación, en este caso, en una versión reciente de Debian. El despliegue completo necesitará de unos 20-25 GB de almacenamiento en el disco duro.
$ sudo apt install docker.io docker-compose
$ sudo usermod -aG docker $USER
Descarga de las imágenes Docker
A continuación se descargan las imágenes Docker, que se desplegarán en contenedores posteriormente: docker_open5gs, IMS, srsRAN, UERANSIM, EUPF, Sigscale OCS, Osmo-edpg/Strongswan-epdg y SWu-IKEv2.
docker pull ghcr.io/herlesupreeth/docker_open5gs:master
docker tag ghcr.io/herlesupreeth/docker_open5gs:master docker_open5gs
docker pull ghcr.io/herlesupreeth/docker_grafana:master
docker tag ghcr.io/herlesupreeth/docker_grafana:master docker_grafana
docker pull ghcr.io/herlesupreeth/docker_metrics:master
docker tag ghcr.io/herlesupreeth/docker_metrics:master docker_metrics
docker pull ghcr.io/herlesupreeth/docker_osmohlr:master
docker tag ghcr.io/herlesupreeth/docker_osmohlr:master docker_osmohlr
docker pull ghcr.io/herlesupreeth/docker_osmomsc:master
docker tag ghcr.io/herlesupreeth/docker_osmomsc:master docker_osmomsc
docker pull ghcr.io/herlesupreeth/docker_pyhss:master
docker tag ghcr.io/herlesupreeth/docker_pyhss:master docker_pyhss
docker pull ghcr.io/herlesupreeth/docker_kamailio:master
docker tag ghcr.io/herlesupreeth/docker_kamailio:master docker_kamailio
docker pull ghcr.io/herlesupreeth/docker_mysql:master
docker tag ghcr.io/herlesupreeth/docker_mysql:master docker_mysql
docker pull ghcr.io/herlesupreeth/docker_opensips:master
docker tag ghcr.io/herlesupreeth/docker_opensips:master docker_opensips
docker pull ghcr.io/herlesupreeth/docker_srslte:master
docker tag ghcr.io/herlesupreeth/docker_srslte:master docker_srslte
docker pull ghcr.io/herlesupreeth/docker_srsran:master
docker tag ghcr.io/herlesupreeth/docker_srsran:master docker_srsran
docker pull ghcr.io/herlesupreeth/docker_ueransim:master
docker tag ghcr.io/herlesupreeth/docker_ueransim:master docker_ueransim
docker pull ghcr.io/herlesupreeth/docker_eupf:master
docker tag ghcr.io/herlesupreeth/docker_eupf:master docker_eupf
docker pull ghcr.io/herlesupreeth/docker_ocs:master
docker tag ghcr.io/herlesupreeth/docker_ocs:master docker_ocs
docker pull ghcr.io/herlesupreeth/docker_osmoepdg:master
docker tag ghcr.io/herlesupreeth/docker_osmoepdg:master docker_osmoepdg
docker pull ghcr.io/herlesupreeth/docker_swu_client:master
docker tag ghcr.io/herlesupreeth/docker_swu_client:master docker_swu_client
Configuración del entorno
Para la configuración, utilizaremos una configuración de un solo host, donde eNB/gNB y (EPC+IMS)/5GC se despliegan en una única máquina anfitriona. Empezamos clonando el repositorio docker_open5gs.
$ git clone https://github.com/herlesupreeth/docker_open5gs
$ cd docker_open5gs
Obtenemos la dirección IP de nuestra máquina anfitriona en Docker, leyendo la dirección IP de la interfaz docker0, 172.17.0.1.
$ ip a show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:0f:cb:00:c1 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
Modificamos las variables de entorno desde el archivo .env. Modificamos el código de país (MCC) por el de pruebas (999) y el código de red móvil (MNC) por 01. Indicamos la dirección IP de Docker que hemos obtenido anteriormente con la variables DOCKER_HOST_IP. Al haber cambiado el MCC y el MNC también tendremos que cambiar el IMSI del UE en la variable UE1_IMSI reemplazando su inicio 00101 por 99901.
$ nano .env
Finalmente establecemos un archivo timezone para sincronizarlo con los contenedores, ya que no se encuentra el archivo creado en algunos casos.
$ sudo timedatectl set-timezone "Europe/Madrid"
$ echo "Europe/Madrid" | sudo tee /etc/timezone
Despliegue del entorno
Desplegamos en primer lugar con Docker Compose la red Core 5G. Esto iniciará los componentes del core (AMF, SMF, UPF, base de datos, etc.).
$ docker compose -f sa-deploy.yaml up
[+] Running 1/15
...
Attaching to amf, ausf, bsf, grafana, metrics, mongo, nrf, nssf, pcf, scp, smf, udm, udr, upf, webui
...
webui | > Building page: /
webui | DONE Compiled successfully in 6981ms
...
Esperamos unos minutos a que se desplieguen todas las funciones de red. El despliegue se habrá completado cuando podamos acceder a la terminal web de Open5GS en la dirección http://127.0.0.1:9999 A continuación desplegamos el gNB virtual utilizando UERANSIM gNB.
$ docker compose -f nr-gnb.yaml up -d && docker container attach nr_gnb
[+] Running 1/1
✔ Container nr_gnb Started 0.2s
root@109836ec9ab8:/UERANSIM/build# UERANSIM v3.2.6
[sctp] [info] Trying to establish SCTP connection... (172.22.0.10:38412)
[sctp] [info] SCTP connection established (172.22.0.10:38412)
[sctp] [debug] SCTP association setup ascId[21]
[ngap] [debug] Sending NG Setup Request
[ngap] [debug] NG Setup Response received
[ngap] [info] NG Setup procedure is successful
Finalmente el dispositivo móvil virtual UE (User Equipment) utilizando UERANSIM NR-UE.
$ docker compose -f nr-ue.yaml up -d && docker container attach nr_ue
[+] Running 1/1
✔ Container nr_ue Started 0.2s
root@2f2d4eb66015:/UERANSIM/build# UERANSIM v3.2.6
[nas] [info] UE switches to state [MM-DEREGISTERED/PLMN-SEARCH]
[rrc] [debug] New signal detected for cell[1], total [1] cells in coverage
[nas] [info] Selected plmn[999/01]
[rrc] [warning] Suitable cell selection failed in [1] cells. [0] out of PLMN, [1] no SI, [0] reserved, [0] barred, ftai [0]
[rrc] [warning] Acceptable cell selection failed in [1] cells. [1] no SI, [0] reserved, [0] barred, ftai [0]
[rrc] [error] Cell selection failure, no suitable or acceptable cell found
[rrc] [info] Selected cell plmn[999/01] tac[1] category[SUITABLE]
[nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[nas] [info] UE switches to state [MM-DEREGISTERED/NORMAL-SERVICE]
[nas] [debug] Initial registration required due to [MM-DEREG-NORMAL-SERVICE]
[nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[nas] [debug] Sending Initial Registration
[nas] [info] UE switches to state [MM-REGISTER-INITIATED]
[rrc] [debug] Sending RRC Setup Request
[rrc] [info] RRC connection established
[rrc] [info] UE switches to state [RRC-CONNECTED]
[nas] [info] UE switches to state [CM-CONNECTED]
[rrc] [debug] RRC Release received
[nas] [error] Initial Registration failed [FIVEG_SERVICES_NOT_ALLOWED]
[nas] [info] UE switches to state [5U3-ROAMING-NOT-ALLOWED]
[nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[nas] [info] UE switches to state [CM-IDLE]
[nas] [info] UE switches to state [MM-DEREGISTERED/NO-SUPI]
Comprobamos que la red ha rechazado al dispositivo suscriptor no ha podido ser registrado. Esto es debido a que los datos del suscriptor no se encuentran dados de alta en el HSS.
Alta de suscriptores en la base de datos del HSS
Para permitir que un UE se registre en la red, necesitas crear un “subscriber” en la base de datos de Open5GS (HSS) con detalles como IMSI, MSISDN, claves de autenticación, y configurar el APN. Se accede a la interfaz web (por defecto http://127.0.0.1:9999), con credenciales admin:1423. Los datos a añadir los encontremos ya configuramos por defecto en el archivo .env y empiezan por UE.
$ grep "^UE" .env
UE1_IMEI=356938035643803
UE1_IMEISV=4370816125816151
UE1_IMSI=999011234567895
UE1_KI=8baf473f2f8fd09487cccbd7097c6862
UE1_OP=11111111111111111111111111111111
UE1_AMF=8000
UE_IPV4_INTERNET=192.168.100.0/24
UE_IPV4_IMS=192.168.101.0/24
Iniciamos sesión en el panel web y añadimos el suscriptor mediante el botón ADD A SUBSCRIBER. Rellenamos el IMSI con UE1_IMEI, la Subscriber Key (K) con UE1_KI, la USIM Type con OP y la Operator Key (OPc/OP) con UE1_OP. Pulsamos en SAVE y volvemos a desplegar el UE.

$ docker compose -f nr-ue.yaml up -d && docker container attach nr_ue
...
[nas] [debug] Selected integrity[2] ciphering[0]
[nas] [debug] Registration accept received
[nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[nas] [debug] Sending Registration Complete
[nas] [info] Initial Registration is successful
[nas] [debug] Sending PDU Session Establishment Request
[nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[nas] [debug] Configuration Update Command received
[nas] [debug] PDU Session Establishment Accept received
[nas] [info] PDU Session establishment is successful PSI[1]
[app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 192.168.100.2] is up.
Comprobamos que el registro se ha realizado correctamente y que el UE ha obtenido la dirección IP 192.168.100.2 por la interfaz uesimtun0 en la red 5G. Podemos desplegar otro UE mediante la creación de nuevos archivos nr_ue.yaml y .env junto a la adición de las entradas a la interfaz web. Editamos las entradas correspondientes al UE como el IMEI, el IMSI, o la dirección IP del contenedor de Docker.
$ mkdir nr-ue2
$ cd nr-ue2
$ cp ../nr-ue.yaml nr-ue2.yaml
$ sed -i 's/nr_ue/nr_ue2/g' nr-ue2.yaml
$ sed -i 's/\.\/ueransim/\.\.\/ueransim/g' nr-ue2.yaml
$ cp ../.env .env
$ sed -i 's/356938035643803/356938035643813/g' .env
$ sed -i 's/4370816125816151/4370816125816161/g' .env
$ sed -i 's/999011234567895/999011234567885/g' .env
$ sed -i 's/172.22.0.24/172.22.0.43/g' .env
$ docker compose -f nr-ue2.yaml up -d && docker container attach nr_ue2
...
[app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 192.168.100.3] is up.
La conexión es correcta. Podemos disponer de conectividad con el otro UE.
root@a3edf17323a4:/UERANSIM/build# ping -I uesimtun0 -c 1 192.168.100.2
PING 192.168.100.2 (192.168.100.2) from 192.168.100.3 uesimtun0: 56(84) bytes of data.
64 bytes from 192.168.100.2: icmp_seq=1 ttl=63 time=4.72 ms
--- 192.168.100.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 4.716/4.716/4.716/0.000 ms
Conclusión
La combinación de Open5GS y docker_open5gs representa una herramienta poderosa para aprender sobre redes 5G modernas, permitiendo recrear en un entorno controlado lo que antes estaba reservado a laboratorios especializados. Esta aproximación no solo facilita la comprensión del núcleo 5G, sino que prepara a ingenieros, estudiantes y entusiastas para trabajar con tecnologías que están transformando la conectividad global.