From 089371b7ab6d1a912dabaaeed1112acc1c431410 Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Sun, 9 Feb 2025 14:36:43 +0100 Subject: [PATCH] Move deployment with open5gs HSS for Cx under custom deployment scenarios --- custom_deployments/open5gs_hss_cx/.custom_env | 139 ++ .../4g-external-ims-deploy.yaml | 336 +++++ .../open5gs_hss_cx/4g-volte-deploy.yaml | 468 ++++++ custom_deployments/open5gs_hss_cx/README.md | 37 + .../open5gs_hss_cx/dns/Dockerfile | 37 + .../open5gs_hss_cx/dns/dns_init.sh | 63 + .../open5gs_hss_cx/dns/e164.arpa | 14 + .../open5gs_hss_cx/dns/epc_zone | 15 + .../open5gs_hss_cx/dns/ims_zone | 27 + .../open5gs_hss_cx/dns/named.conf | 53 + .../open5gs_hss_cx/dns/pub_3gpp_zone | 13 + .../open5gs_hss_cx/hss/hss.conf | 267 ++++ .../open5gs_hss_cx/hss/hss.yaml | 13 + .../open5gs_hss_cx/hss/hss_init.sh | 62 + .../open5gs_hss_cx/hss/make_certs.sh | 29 + .../open5gs_hss_cx/icscf/icscf.cfg | 53 + .../open5gs_hss_cx/icscf/icscf.xml | 34 + .../open5gs_hss_cx/icscf/icscf_init.sh | 96 ++ .../open5gs_hss_cx/icscf/kamailio_icscf.cfg | 639 +++++++++ .../open5gs_hss_cx/mme/make_certs.sh | 30 + .../open5gs_hss_cx/mme/mme.conf | 266 ++++ .../open5gs_hss_cx/mme/mme.yaml | 59 + .../open5gs_hss_cx/mme/mme_init.sh | 57 + .../open5gs_hss_cx/scscf/CxDataType_Rel6.xsd | 293 ++++ .../open5gs_hss_cx/scscf/CxDataType_Rel7.xsd | 301 ++++ .../open5gs_hss_cx/scscf/CxDataType_Rel8.xsd | 379 +++++ .../open5gs_hss_cx/scscf/dispatcher.list | 1 + .../open5gs_hss_cx/scscf/kamailio_scscf.cfg | 1276 +++++++++++++++++ .../open5gs_hss_cx/scscf/scscf.cfg | 85 ++ .../open5gs_hss_cx/scscf/scscf.xml | 36 + .../open5gs_hss_cx/scscf/scscf_init.sh | 83 ++ custom_deployments/open5gs_hss_cx/srsenb.yaml | 30 + upf/upf_init.sh | 4 + 33 files changed, 5295 insertions(+) create mode 100644 custom_deployments/open5gs_hss_cx/.custom_env create mode 100644 custom_deployments/open5gs_hss_cx/4g-external-ims-deploy.yaml create mode 100644 custom_deployments/open5gs_hss_cx/4g-volte-deploy.yaml create mode 100644 custom_deployments/open5gs_hss_cx/README.md create mode 100644 custom_deployments/open5gs_hss_cx/dns/Dockerfile create mode 100755 custom_deployments/open5gs_hss_cx/dns/dns_init.sh create mode 100644 custom_deployments/open5gs_hss_cx/dns/e164.arpa create mode 100644 custom_deployments/open5gs_hss_cx/dns/epc_zone create mode 100644 custom_deployments/open5gs_hss_cx/dns/ims_zone create mode 100644 custom_deployments/open5gs_hss_cx/dns/named.conf create mode 100644 custom_deployments/open5gs_hss_cx/dns/pub_3gpp_zone create mode 100644 custom_deployments/open5gs_hss_cx/hss/hss.conf create mode 100644 custom_deployments/open5gs_hss_cx/hss/hss.yaml create mode 100755 custom_deployments/open5gs_hss_cx/hss/hss_init.sh create mode 100755 custom_deployments/open5gs_hss_cx/hss/make_certs.sh create mode 100644 custom_deployments/open5gs_hss_cx/icscf/icscf.cfg create mode 100644 custom_deployments/open5gs_hss_cx/icscf/icscf.xml create mode 100755 custom_deployments/open5gs_hss_cx/icscf/icscf_init.sh create mode 100644 custom_deployments/open5gs_hss_cx/icscf/kamailio_icscf.cfg create mode 100755 custom_deployments/open5gs_hss_cx/mme/make_certs.sh create mode 100644 custom_deployments/open5gs_hss_cx/mme/mme.conf create mode 100644 custom_deployments/open5gs_hss_cx/mme/mme.yaml create mode 100755 custom_deployments/open5gs_hss_cx/mme/mme_init.sh create mode 100644 custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel6.xsd create mode 100644 custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel7.xsd create mode 100644 custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel8.xsd create mode 100644 custom_deployments/open5gs_hss_cx/scscf/dispatcher.list create mode 100644 custom_deployments/open5gs_hss_cx/scscf/kamailio_scscf.cfg create mode 100644 custom_deployments/open5gs_hss_cx/scscf/scscf.cfg create mode 100644 custom_deployments/open5gs_hss_cx/scscf/scscf.xml create mode 100755 custom_deployments/open5gs_hss_cx/scscf/scscf_init.sh create mode 100644 custom_deployments/open5gs_hss_cx/srsenb.yaml diff --git a/custom_deployments/open5gs_hss_cx/.custom_env b/custom_deployments/open5gs_hss_cx/.custom_env new file mode 100644 index 00000000..daa60656 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/.custom_env @@ -0,0 +1,139 @@ +# Set proper timezone to sync times between docker host and containers +#TZ=Europe/Berlin + +MCC=001 +MNC=01 + +TEST_NETWORK=172.22.0.0/24 +DOCKER_HOST_IP=192.168.1.223 + +# MONGODB +MONGO_IP=172.22.0.2 + +# HSS - open5gs +HSS_IP=172.22.0.3 +HSS_BIND_PORT=3875 + +# PCRF +PCRF_IP=172.22.0.4 +PCRF_BIND_PORT=3873 + +# SGW +SGWC_IP=172.22.0.5 +SGWU_IP=172.22.0.6 +SGWU_ADVERTISE_IP=172.22.0.6 + +# SMF +SMF_IP=172.22.0.7 +SMF_DNS1=8.8.8.8 +SMF_DNS2=8.8.4.4 + +# UPF +UPF_IP=172.22.0.8 +UPF_ADVERTISE_IP=172.22.0.8 + +# MME +MME_IP=172.22.0.9 + +# AMF +AMF_IP=172.22.0.10 + +# AUSF +AUSF_IP=172.22.0.11 + +# NRF +NRF_IP=172.22.0.12 + +# UDM +UDM_IP=172.22.0.13 + +# UDR +UDR_IP=172.22.0.14 + +# IMS DNS +DNS_IP=172.22.0.15 + +# RTPENGINE +RTPENGINE_IP=172.22.0.16 + +# MYSQL +MYSQL_IP=172.22.0.17 + +# ICSCF +ICSCF_IP=172.22.0.19 +ICSCF_BIND_PORT=3869 + +# SCSCF +SCSCF_IP=172.22.0.20 +SCSCF_BIND_PORT=3870 + +# PCSCF +PCSCF_IP=172.22.0.21 +PCSCF_BIND_PORT=3871 + +# SRSLTE ENB +SRS_ENB_IP=172.22.0.22 + +# UERANSIM +NR_GNB_IP=172.22.0.23 +NR_UE_IP=172.22.0.24 + +UE1_IMEI=356938035643803 +UE1_IMEISV=4370816125816151 +UE1_IMSI=001011234567895 +UE1_KI=8baf473f2f8fd09487cccbd7097c6862 +UE1_OP=11111111111111111111111111111111 +UE1_AMF=8000 + +# OAI ENB +OAI_ENB_IP=172.22.0.25 + +# OPEN5GS WEBUI +WEBUI_IP=172.22.0.26 + +# PCF +PCF_IP=172.22.0.27 + +# NSSF +NSSF_IP=172.22.0.28 + +# BSF +BSF_IP=172.22.0.29 + +# ENTITLEMENT SERVER +ENTITLEMENT_SERVER_IP=172.22.0.30 + +# OSMOMSC +OSMOMSC_IP=172.22.0.31 + +# OSMOHLR +OSMOHLR_IP=172.22.0.32 + +# SMSC +SMSC_IP=172.22.0.33 + +# SRSLTE UE +SRS_UE_IP=172.22.0.34 + +# SCP +SCP_IP=172.22.0.35 + +# METRICS +METRICS_IP=172.22.0.36 + +# SRSRAN GNB +SRS_GNB_IP=172.22.0.37 + +# GRAFANA +GRAFANA_IP=172.22.0.39 +GRAFANA_USERNAME=open5gs +GRAFANA_PASSWORD=open5gs + +# UE IPv4 Subnet Range for APN=internet +UE_IPV4_INTERNET=192.168.100.0/24 + +# UE IPv4 Subnet Range for APN=ims +UE_IPV4_IMS=192.168.101.0/24 + +# Maximum Number of UEs +MAX_NUM_UE=1024 diff --git a/custom_deployments/open5gs_hss_cx/4g-external-ims-deploy.yaml b/custom_deployments/open5gs_hss_cx/4g-external-ims-deploy.yaml new file mode 100644 index 00000000..3f9e1505 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/4g-external-ims-deploy.yaml @@ -0,0 +1,336 @@ +services: + mongo: + image: mongo:6.0 + container_name: mongo + command: --bind_ip 0.0.0.0 + env_file: + - .custom_env + volumes: + - mongodbdata:/data/db + - mongodbdata:/data/configdb + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "27017/udp" + - "27017/tcp" + networks: + default: + ipv4_address: ${MONGO_IP} + webui: + image: docker_open5gs + container_name: webui + depends_on: + - mongo + env_file: + - .custom_env + environment: + - COMPONENT_NAME=webui + volumes: + - ../../webui:/mnt/webui + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "9999/tcp" + ports: + - "9999:9999/tcp" + networks: + default: + ipv4_address: ${WEBUI_IP} + hss: + image: docker_open5gs + container_name: hss + env_file: + - .custom_env + environment: + - COMPONENT_NAME=hss + volumes: + - ./hss:/mnt/hss + - ./log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + depends_on: + - mongo + expose: + - "${HSS_BIND_PORT}/tcp" + - "${HSS_BIND_PORT}/sctp" + - "5868/tcp" + - "5868/sctp" + # ports: + # - "${HSS_BIND_PORT}:${HSS_BIND_PORT}/sctp" + # - "${HSS_BIND_PORT}:${HSS_BIND_PORT}/tcp" + networks: + default: + ipv4_address: ${HSS_IP} + sgwc: + image: docker_open5gs + depends_on: + - smf + - upf + container_name: sgwc + env_file: + - .custom_env + environment: + - COMPONENT_NAME=sgwc + volumes: + - ../../sgwc:/mnt/sgwc + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "2123/udp" + - "8805/udp" + networks: + default: + ipv4_address: ${SGWC_IP} + sgwu: + image: docker_open5gs + depends_on: + - smf + - upf + container_name: sgwu + env_file: + - .custom_env + environment: + - COMPONENT_NAME=sgwu + volumes: + - ../../sgwu:/mnt/sgwu + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "8805/udp" + - "2152/udp" + # ports: + # - "${SGWU_ADVERTISE_IP}:2152:2152/udp" + networks: + default: + ipv4_address: ${SGWU_IP} + smf: + image: docker_open5gs + container_name: smf + env_file: + - .custom_env + environment: + - COMPONENT_NAME=smf + - DEPLOY_MODE=4G + volumes: + - ../../smf:/mnt/smf + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3868/tcp" + - "3868/sctp" + - "5868/tcp" + - "5868/sctp" + - "8805/udp" + - "2123/udp" + - "7777/tcp" + - "9091/tcp" + networks: + default: + ipv4_address: ${SMF_IP} + upf: + image: docker_open5gs + depends_on: + - smf + container_name: upf + env_file: + - .custom_env + environment: + - COMPONENT_NAME=upf + volumes: + - ../../upf:/mnt/upf + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "2152/udp" + - "8805/udp" + - "9091/tcp" + cap_add: + - NET_ADMIN + privileged: true + # sysctls: + # - net.ipv4.ip_forward=1 + # - net.ipv6.conf.all.disable_ipv6=0 + network_mode: host + mme: + image: docker_open5gs + depends_on: + - hss + - sgwc + - sgwu + - smf + - upf + - osmomsc + container_name: mme + env_file: + - .custom_env + environment: + - COMPONENT_NAME=mme + volumes: + - ./mme:/mnt/mme + - ./log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3868/tcp" + - "3868/sctp" + - "5868/tcp" + - "5868/sctp" + - "36412/sctp" + - "2123/udp" + - "9091/tcp" + # ports: + # - "36412:36412/sctp" + networks: + default: + ipv4_address: ${MME_IP} + pcrf: + image: docker_open5gs + container_name: pcrf + env_file: + - .custom_env + environment: + - COMPONENT_NAME=pcrf + depends_on: + - mongo + volumes: + - ../../pcrf:/mnt/pcrf + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "${PCRF_BIND_PORT}/tcp" + - "${PCRF_BIND_PORT}/sctp" + - "5868/tcp" + - "5868/sctp" + # ports: + # - "${PCRF_BIND_PORT}:${PCRF_BIND_PORT}/sctp" + # - "${PCRF_BIND_PORT}:${PCRF_BIND_PORT}/tcp" + networks: + default: + ipv4_address: ${PCRF_IP} + dns: + build: ./dns + image: docker_dns + container_name: dns + env_file: + - .custom_env + volumes: + - ./dns:/mnt/dns + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "53/udp" + networks: + default: + ipv4_address: ${DNS_IP} + mysql: + build: ../../mysql + image: docker_mysql + container_name: mysql + env_file: + - .custom_env + volumes: + - dbdata:/var/lib/mysql + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3306/tcp" + networks: + default: + ipv4_address: ${MYSQL_IP} + osmomsc: + build: ../../osmomsc + image: docker_osmomsc + container_name: osmomsc + volumes: + - ../../osmomsc:/mnt/osmomsc + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=osmomsc + depends_on: + - osmohlr + expose: + - "29118/sctp" + - "2775/tcp" + networks: + default: + ipv4_address: ${OSMOMSC_IP} + osmohlr: + build: ../../osmohlr + image: docker_osmohlr + container_name: osmohlr + volumes: + - ../../osmohlr:/mnt/osmohlr + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=osmohlr + expose: + - "4222/tcp" + networks: + default: + ipv4_address: ${OSMOHLR_IP} + metrics: + build: ../../metrics + image: docker_metrics + container_name: metrics + env_file: + - .custom_env + volumes: + - ../../metrics:/mnt/metrics + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "9090/tcp" + ports: + - "9090:9090/tcp" + networks: + default: + ipv4_address: ${METRICS_IP} + grafana: + image: grafana/grafana:11.3.0 + container_name: grafana + env_file: + - .custom_env + volumes: + - grafana_data:/var/lib/grafana + - ../../grafana/:/etc/grafana/provisioning/ + - ../../grafana:/mnt/grafana + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + environment: + - GF_SECURITY_ADMIN_USER=${GRAFANA_USERNAME} + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD} + #- GF_INSTALL_PLUGINS=${GRAFANA_INSTALL_PLUGINS} + - GF_PATHS_PROVISIONING=/etc/grafana/provisioning + - GF_PATHS_DATA=/var/lib/grafana + - METRICS_IP=${METRICS_IP} + expose: + - "3000/tcp" + ports: + - "3000:3000/tcp" + networks: + default: + ipv4_address: ${GRAFANA_IP} +networks: + default: + name: docker_open5gs_default + ipam: + config: + - subnet: ${TEST_NETWORK} +volumes: + grafana_data: + name: grafana_data + mongodbdata: + name: docker_open5gs_mongodbdata + dbdata: + name: docker_open5gs_dbdata diff --git a/custom_deployments/open5gs_hss_cx/4g-volte-deploy.yaml b/custom_deployments/open5gs_hss_cx/4g-volte-deploy.yaml new file mode 100644 index 00000000..6e25c748 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/4g-volte-deploy.yaml @@ -0,0 +1,468 @@ +services: + mongo: + image: mongo:6.0 + container_name: mongo + command: --bind_ip 0.0.0.0 + env_file: + - .custom_env + volumes: + - mongodbdata:/data/db + - mongodbdata:/data/configdb + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "27017/udp" + - "27017/tcp" + networks: + default: + ipv4_address: ${MONGO_IP} + webui: + image: docker_open5gs + container_name: webui + depends_on: + - mongo + env_file: + - .custom_env + environment: + - COMPONENT_NAME=webui + volumes: + - ../../webui:/mnt/webui + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "9999/tcp" + ports: + - "9999:9999/tcp" + networks: + default: + ipv4_address: ${WEBUI_IP} + hss: + image: docker_open5gs + container_name: hss + env_file: + - .custom_env + environment: + - COMPONENT_NAME=hss + volumes: + - ./hss:/mnt/hss + - ./log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + depends_on: + - mongo + expose: + - "${HSS_BIND_PORT}/tcp" + - "${HSS_BIND_PORT}/sctp" + - "5868/tcp" + - "5868/sctp" + networks: + default: + ipv4_address: ${HSS_IP} + sgwc: + image: docker_open5gs + depends_on: + - smf + - upf + container_name: sgwc + env_file: + - .custom_env + environment: + - COMPONENT_NAME=sgwc + volumes: + - ../../sgwc:/mnt/sgwc + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "2123/udp" + - "8805/udp" + networks: + default: + ipv4_address: ${SGWC_IP} + sgwu: + image: docker_open5gs + depends_on: + - smf + - upf + container_name: sgwu + env_file: + - .custom_env + environment: + - COMPONENT_NAME=sgwu + volumes: + - ../../sgwu:/mnt/sgwu + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "8805/udp" + - "2152/udp" + # ports: + # - "2152:2152/udp" + networks: + default: + ipv4_address: ${SGWU_IP} + smf: + image: docker_open5gs + container_name: smf + env_file: + - .custom_env + environment: + - COMPONENT_NAME=smf + - DEPLOY_MODE=4G + volumes: + - ../../smf:/mnt/smf + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3868/udp" + - "3868/tcp" + - "3868/sctp" + - "5868/udp" + - "5868/tcp" + - "5868/sctp" + - "8805/udp" + - "2123/udp" + - "7777/tcp" + - "9091/tcp" + networks: + default: + ipv4_address: ${SMF_IP} + upf: + image: docker_open5gs + depends_on: + - smf + container_name: upf + env_file: + - .custom_env + environment: + - COMPONENT_NAME=upf + volumes: + - ../../upf:/mnt/upf + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "2152/udp" + - "8805/udp" + - "9091/tcp" + cap_add: + - NET_ADMIN + privileged: true + sysctls: + - net.ipv4.ip_forward=1 + networks: + default: + ipv4_address: ${UPF_IP} + mme: + image: docker_open5gs + depends_on: + - hss + - sgwc + - sgwu + - smf + - upf + - osmomsc + container_name: mme + env_file: + - .custom_env + environment: + - COMPONENT_NAME=mme + volumes: + - ./mme:/mnt/mme + - ./log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3868/udp" + - "3868/tcp" + - "3868/sctp" + - "5868/udp" + - "5868/tcp" + - "5868/sctp" + - "36412/sctp" + - "2123/udp" + - "9091/tcp" + # ports: + # - "36412:36412/sctp" + networks: + default: + ipv4_address: ${MME_IP} + pcrf: + image: docker_open5gs + container_name: pcrf + env_file: + - .custom_env + environment: + - COMPONENT_NAME=pcrf + depends_on: + - mongo + volumes: + - ../../pcrf:/mnt/pcrf + - ../../log:/open5gs/install/var/log/open5gs + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3868/udp" + - "3868/tcp" + - "3868/sctp" + - "5868/udp" + - "5868/tcp" + - "5868/sctp" + networks: + default: + ipv4_address: ${PCRF_IP} + dns: + build: ./dns + image: docker_dns + container_name: dns + env_file: + - .custom_env + volumes: + - ./dns:/mnt/dns + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "53/udp" + networks: + default: + ipv4_address: ${DNS_IP} + rtpengine: + build: ../../rtpengine + image: docker_rtpengine + container_name: rtpengine + privileged: true + env_file: + - .custom_env + volumes: + - ../../rtpengine:/mnt/rtpengine + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + cap_add: + - NET_ADMIN + environment: + - TABLE=0 + - INTERFACE=${RTPENGINE_IP} + - LISTEN_NG=${RTPENGINE_IP}:2223 + - PIDFILE=/run/ngcp-rtpengine-daemon.pid + - PORT_MAX=50000 + - PORT_MIN=49000 + - NO_FALLBACK=no + - TOS=184 + expose: + - "2223/udp" + - "49000-50000/udp" + networks: + default: + ipv4_address: ${RTPENGINE_IP} + mysql: + build: ../../mysql + image: docker_mysql + container_name: mysql + env_file: + - .custom_env + volumes: + - dbdata:/var/lib/mysql + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "3306/tcp" + networks: + default: + ipv4_address: ${MYSQL_IP} + icscf: + image: docker_kamailio + container_name: icscf + dns: ${DNS_IP} + volumes: + - ./icscf:/mnt/icscf + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=icscf + depends_on: + - dns + - mysql + - hss + expose: + - "3869/udp" + - "3869/tcp" + - "4060/udp" + - "4060/tcp" + networks: + default: + ipv4_address: ${ICSCF_IP} + scscf: + image: docker_kamailio + container_name: scscf + dns: ${DNS_IP} + volumes: + - ./scscf:/mnt/scscf + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=scscf + depends_on: + - dns + - mysql + - hss + expose: + - "3870/udp" + - "3870/tcp" + - "6060/udp" + - "6060/tcp" + networks: + default: + ipv4_address: ${SCSCF_IP} + pcscf: + image: docker_kamailio + container_name: pcscf + dns: ${DNS_IP} + privileged: true + cap_add: + - NET_ADMIN + volumes: + - ../../pcscf:/mnt/pcscf + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=pcscf + - DEPLOY_MODE=4G + depends_on: + - dns + - mysql + - rtpengine + - icscf + - scscf + expose: + - "3871/udp" + - "3871/tcp" + - "5060/tcp" + - "5060/udp" + - "5100-5120/tcp" + - "5100-5120/udp" + - "6100-6120/tcp" + - "6100-6120/udp" + networks: + default: + ipv4_address: ${PCSCF_IP} + smsc: + image: docker_kamailio + container_name: smsc + dns: ${DNS_IP} + volumes: + - ../../smsc:/mnt/smsc + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=smsc + depends_on: + - dns + - mysql + expose: + - "7090/udp" + - "7090/tcp" + networks: + default: + ipv4_address: ${SMSC_IP} + osmomsc: + build: ../../osmomsc + image: docker_osmomsc + container_name: osmomsc + volumes: + - ../../osmomsc:/mnt/osmomsc + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=osmomsc + depends_on: + - osmohlr + expose: + - "29118/sctp" + - "2775/tcp" + networks: + default: + ipv4_address: ${OSMOMSC_IP} + osmohlr: + build: ../../osmohlr + image: docker_osmohlr + container_name: osmohlr + volumes: + - ../../osmohlr:/mnt/osmohlr + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=osmohlr + expose: + - "4222/tcp" + networks: + default: + ipv4_address: ${OSMOHLR_IP} + metrics: + build: ../../metrics + image: docker_metrics + container_name: metrics + env_file: + - .custom_env + volumes: + - ../../metrics:/mnt/metrics + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + expose: + - "9090/tcp" + ports: + - "9090:9090/tcp" + networks: + default: + ipv4_address: ${METRICS_IP} + grafana: + image: grafana/grafana:11.3.0 + container_name: grafana + env_file: + - .custom_env + volumes: + - grafana_data:/var/lib/grafana + - ../../grafana/:/etc/grafana/provisioning/ + - ../../grafana:/mnt/grafana + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + environment: + - GF_SECURITY_ADMIN_USER=${GRAFANA_USERNAME} + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD} + #- GF_INSTALL_PLUGINS=${GRAFANA_INSTALL_PLUGINS} + - GF_PATHS_PROVISIONING=/etc/grafana/provisioning + - GF_PATHS_DATA=/var/lib/grafana + - METRICS_IP=${METRICS_IP} + expose: + - "3000/tcp" + ports: + - "3000:3000/tcp" + networks: + default: + ipv4_address: ${GRAFANA_IP} +networks: + default: + name: docker_open5gs_default + ipam: + config: + - subnet: ${TEST_NETWORK} +volumes: + grafana_data: + name: grafana_data + mongodbdata: + name: docker_open5gs_mongodbdata + dbdata: + name: docker_open5gs_dbdata diff --git a/custom_deployments/open5gs_hss_cx/README.md b/custom_deployments/open5gs_hss_cx/README.md new file mode 100644 index 00000000..a03529e8 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/README.md @@ -0,0 +1,37 @@ +## Deployment description + +This custom deployment showcases using of open5gs HSS for Cx interface (towards ICSCF/SCSCF) rather than using pyHSS. + +## Limitation + +In order to change the iFCs or any other IMS service related provisioning information one need to modify the code and re-compile open5gs i.e. no way to configure them via GUI as we have with pyHSS. + +## Additional steps + +Most of the steps to be followed are similar to the steps mentioned in the [README in the root folder](../../README.md). However, additional steps mentioned below must be taken into account while deploying this custom deployment scenario. + +### Loading environmental variables for custom deployment + +**Warning** +For custom deployments, you must modify/use only the [**.custom_env**](.custom_env) file rather than the [**.env** in the root folder](../../.env). + +``` +set -a +source .custom_env +set +a +``` + +### Scenario deployment + +Deploy the 4G EPC + IMS. + +``` +cd custom_deployments/open5gs_hss_cx +docker compose -f 4g-volte-deploy.yaml up +``` + +Deploy srsRAN eNB using SDR (OTA) + +``` +docker compose -f srsenb.yaml up -d && docker container attach srsenb +``` diff --git a/custom_deployments/open5gs_hss_cx/dns/Dockerfile b/custom_deployments/open5gs_hss_cx/dns/Dockerfile new file mode 100644 index 00000000..f6354f05 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/dns/Dockerfile @@ -0,0 +1,37 @@ +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM ubuntu:focal + +ENV DEBIAN_FRONTEND=noninteractive + +# Install updates and dependencies +RUN apt-get update && \ + apt-get -y install tcpdump screen tmux ntp ntpdate iproute2 net-tools \ + iputils-ping bind9 + +CMD /mnt/dns/dns_init.sh && \ + /usr/sbin/named -c /etc/bind/named.conf -g -u bind diff --git a/custom_deployments/open5gs_hss_cx/dns/dns_init.sh b/custom_deployments/open5gs_hss_cx/dns/dns_init.sh new file mode 100755 index 00000000..e63695a8 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/dns/dns_init.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +cp /mnt/dns/epc_zone /etc/bind +cp /mnt/dns/ims_zone /etc/bind +cp /mnt/dns/pub_3gpp_zone /etc/bind +cp /mnt/dns/e164.arpa /etc/bind +cp /mnt/dns/named.conf /etc/bind + +[ ${#MNC} == 3 ] && EPC_DOMAIN="epc.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || EPC_DOMAIN="epc.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" +[ ${#MNC} == 3 ] && IMS_DOMAIN="ims.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || IMS_DOMAIN="ims.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" +[ ${#MNC} == 3 ] && PUB_3GPP_DOMAIN="mnc${MNC}.mcc${MCC}.pub.3gppnetwork.org" || PUB_3GPP_DOMAIN="mnc0${MNC}.mcc${MCC}.pub.3gppnetwork.org" + +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/bind/epc_zone +sed -i 's|DNS_IP|'$DNS_IP'|g' /etc/bind/epc_zone +[ -z "$PCRF_PUB_IP" ] && sed -i 's|PCRF_IP|'$PCRF_IP'|g' /etc/bind/epc_zone || sed -i 's|PCRF_IP|'$PCRF_PUB_IP'|g' /etc/bind/epc_zone +[ -z "$HSS_PUB_IP" ] && sed -i 's|HSS_IP|'$HSS_IP'|g' /etc/bind/epc_zone || sed -i 's|HSS_IP|'$HSS_PUB_IP'|g' /etc/bind/epc_zone + +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/bind/ims_zone +sed -i 's|DNS_IP|'$DNS_IP'|g' /etc/bind/ims_zone +sed -i 's|PCSCF_IP|'$PCSCF_IP'|g' /etc/bind/ims_zone +sed -i 's|ICSCF_IP|'$ICSCF_IP'|g' /etc/bind/ims_zone +sed -i 's|SCSCF_IP|'$SCSCF_IP'|g' /etc/bind/ims_zone +sed -i 's|SMSC_IP|'$SMSC_IP'|g' /etc/bind/ims_zone + +sed -i 's|PUB_3GPP_DOMAIN|'$PUB_3GPP_DOMAIN'|g' /etc/bind/pub_3gpp_zone +sed -i 's|DNS_IP|'$DNS_IP'|g' /etc/bind/pub_3gpp_zone +sed -i 's|ENTITLEMENT_SERVER_IP|'$ENTITLEMENT_SERVER_IP'|g' /etc/bind/pub_3gpp_zone + +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/bind/e164.arpa +sed -i 's|DNS_IP|'$DNS_IP'|g' /etc/bind/e164.arpa + +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/bind/named.conf +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/bind/named.conf +sed -i 's|PUB_3GPP_DOMAIN|'$PUB_3GPP_DOMAIN'|g' /etc/bind/named.conf + +# Sync docker time +#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone diff --git a/custom_deployments/open5gs_hss_cx/dns/e164.arpa b/custom_deployments/open5gs_hss_cx/dns/e164.arpa new file mode 100644 index 00000000..192d01a5 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/dns/e164.arpa @@ -0,0 +1,14 @@ +$TTL 1h +@ IN SOA ns.e164.arpa. root.e164.arpa. ( + 2009010918 ;serial + 3600 ;refresh + 3600 ;retry + 3600 ;expire + 3600 ;minimum TTL +) +@ IN NS e164.arpa. +@ IN A DNS_IP + +; Wildcard to match any tel:+xxxx and change to sip:xxxx@IMS_DOMAIN +* IN NAPTR 10 100 "u" "E2U+sip" "!(^.*$)!sip:\\1@IMS_DOMAIN!" . +* IN NAPTR 20 100 "u" "E2U+sip" "!(^.*$)!sip:+\\1@IMS_DOMAIN!" . diff --git a/custom_deployments/open5gs_hss_cx/dns/epc_zone b/custom_deployments/open5gs_hss_cx/dns/epc_zone new file mode 100644 index 00000000..50890658 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/dns/epc_zone @@ -0,0 +1,15 @@ +$ORIGIN EPC_DOMAIN. +$TTL 1W +@ 1D IN SOA localhost. root.localhost. ( + 1 ; serial + 3H ; refresh + 15M ; retry + 1W ; expiry + 1D ) ; minimum + + 1D IN NS epcns +epcns 1D IN A DNS_IP + +pcrf 1D IN A PCRF_IP + +hss 1D IN A HSS_IP diff --git a/custom_deployments/open5gs_hss_cx/dns/ims_zone b/custom_deployments/open5gs_hss_cx/dns/ims_zone new file mode 100644 index 00000000..1373c02c --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/dns/ims_zone @@ -0,0 +1,27 @@ +$ORIGIN IMS_DOMAIN. +$TTL 1W +@ 1D IN SOA localhost. root.localhost. ( + 1 ; serial + 3H ; refresh + 15M ; retry + 1W ; expiry + 1D ) ; minimum + + 1D IN NS ns +ns 1D IN A DNS_IP + +pcscf 1D IN A PCSCF_IP +_sip._udp.pcscf 1D SRV 0 0 5060 pcscf +_sip._tcp.pcscf 1D SRV 0 0 5060 pcscf + +icscf 1D IN A ICSCF_IP +_sip._udp 1D SRV 0 0 4060 icscf +_sip._tcp 1D SRV 0 0 4060 icscf + +scscf 1D IN A SCSCF_IP +_sip._udp.scscf 1D SRV 0 0 6060 scscf +_sip._tcp.scscf 1D SRV 0 0 6060 scscf + +smsc 1D IN A SMSC_IP +_sip._udp.smsc 1D SRV 0 0 7090 smsc +_sip._tcp.smsc 1D SRV 0 0 7090 smsc diff --git a/custom_deployments/open5gs_hss_cx/dns/named.conf b/custom_deployments/open5gs_hss_cx/dns/named.conf new file mode 100644 index 00000000..a6ed6ab0 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/dns/named.conf @@ -0,0 +1,53 @@ +options { + directory "/var/cache/bind"; + + // If there is a firewall between you and nameservers you want + // to talk to, you may need to fix the firewall to allow multiple + // ports to talk. See http://www.kb.cert.org/vuls/id/800113 + + // If your ISP provided one or more IP addresses for stable + // nameservers, you probably want to use them as forwarders. + // Uncomment the following block, and insert the addresses replacing + // the all-0's placeholder. + + forwarders { + 8.8.8.8; + }; + + //======================================================================== + // If BIND logs error messages about the root key being expired, + // you will need to update your keys. See https://www.isc.org/bind-keys + //======================================================================== + dnssec-validation no; + allow-query { any; }; + + auth-nxdomain no; # conform to RFC1035 + listen-on-v6 { any; }; +}; + +// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; +zone "IMS_DOMAIN" { + type master; + file "/etc/bind/ims_zone"; +}; + +zone "EPC_DOMAIN" { + type master; + file "/etc/bind/epc_zone"; +}; + +zone "PUB_3GPP_DOMAIN" { + type master; + file "/etc/bind/pub_3gpp_zone"; +}; + +zone "e164.arpa" { + type master; + file "/etc/bind/e164.arpa"; +}; diff --git a/custom_deployments/open5gs_hss_cx/dns/pub_3gpp_zone b/custom_deployments/open5gs_hss_cx/dns/pub_3gpp_zone new file mode 100644 index 00000000..e7b27bc1 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/dns/pub_3gpp_zone @@ -0,0 +1,13 @@ +$ORIGIN PUB_3GPP_DOMAIN. +$TTL 1W +@ 1D IN SOA localhost. root.localhost. ( + 1 ; serial + 3H ; refresh + 15M ; retry + 1W ; expiry + 1D ) ; minimum + + 1D IN NS pubns +pubns 1D IN A DNS_IP + +aes 1D IN A ENTITLEMENT_SERVER_IP diff --git a/custom_deployments/open5gs_hss_cx/hss/hss.conf b/custom_deployments/open5gs_hss_cx/hss/hss.conf new file mode 100644 index 00000000..34c1ea09 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/hss/hss.conf @@ -0,0 +1,267 @@ +# This is a sample configuration file for freeDiameter daemon. + +# Most of the options can be omitted, as they default to reasonable values. +# Only TLS-related options must be configured properly in usual setups. + +# It is possible to use "include" keyword to import additional files +# e.g.: include "/etc/freeDiameter.d/*.conf" +# This is exactly equivalent as copy & paste the content of the included file(s) +# where the "include" keyword is found. + + +############################################################## +## Peer identity and realm + +# The Diameter Identity of this daemon. +# This must be a valid FQDN that resolves to the local host. +# Default: hostname's FQDN +#Identity = "aaa.koganei.freediameter.net"; +Identity = "hss.EPC_DOMAIN"; + +# The Diameter Realm of this daemon. +# Default: the domain part of Identity (after the first dot). +#Realm = "koganei.freediameter.net"; +Realm = "EPC_DOMAIN"; + +############################################################## +## Transport protocol configuration + +# The port this peer is listening on for incoming connections (TCP and SCTP). +# Default: 3868. Use 0 to disable. +#Port = 3868; +Port = HSS_BIND_PORT; + +# The port this peer is listening on for incoming TLS-protected connections (TCP and SCTP). +# See TLS_old_method for more information about TLS flavours. +# Note: we use TLS/SCTP instead of DTLS/SCTP at the moment. This will change in future version of freeDiameter. +# Default: 5868. Use 0 to disable. +#SecPort = 5868; + +# Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA exchange is completed +# on the unsecure connection. The alternative is RFC6733 mechanism, where TLS protects also the +# CER/CEA exchange on a dedicated secure port. +# This parameter only affects outgoing connections. +# The setting can be also defined per-peer (see Peers configuration section). +# Default: use RFC6733 method with separate port for TLS. +#TLS_old_method; + +# Disable use of TCP protocol (only listen and connect over SCTP) +# Default : TCP enabled +#No_TCP; + +# Disable use of SCTP protocol (only listen and connect over TCP) +# Default : SCTP enabled +#No_SCTP; +# This option is ignored if freeDiameter is compiled with DISABLE_SCTP option. + +# Prefer TCP instead of SCTP for establishing new connections. +# This setting may be overwritten per peer in peer configuration blocs. +# Default : SCTP is attempted first. +#Prefer_TCP; + +# Default number of streams per SCTP associations. +# This setting may be overwritten per peer basis. +# Default : 30 streams +#SCTP_streams = 30; + +############################################################## +## Endpoint configuration + +# Disable use of IP addresses (only IPv6) +# Default : IP enabled +#No_IP; + +# Disable use of IPv6 addresses (only IP) +# Default : IPv6 enabled +#No_IPv6; + +# Specify local addresses the server must bind to +# Default : listen on all addresses available. +#ListenOn = "202.249.37.5"; +#ListenOn = "2001:200:903:2::202:1"; +#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0"; +ListenOn = "HSS_IP"; + +############################################################## +## Server configuration + +# How many Diameter peers are allowed to be connecting at the same time ? +# This parameter limits the number of incoming connections from the time +# the connection is accepted until the first CER is received. +# Default: 5 unidentified clients in paralel. +#ThreadsPerServer = 5; + +############################################################## +## TLS Configuration + +# TLS is managed by the GNUTLS library in the freeDiameter daemon. +# You may find more information about parameters and special behaviors +# in the relevant documentation. +# http://www.gnu.org/software/gnutls/manual/ + +# Credentials of the local peer +# The X509 certificate and private key file to use for the local peer. +# The files must contain PKCS-1 encoded RSA key, in PEM format. +# (These parameters are passed to gnutls_certificate_set_x509_key_file function) +# Default : NO DEFAULT +#TLS_Cred = "" , ""; +#TLS_Cred = "/etc/ssl/certs/freeDiameter.pem", "/etc/ssl/private/freeDiameter.key"; +TLS_Cred = "/open5gs/install/etc/freeDiameter/hss.cert.pem", "/open5gs/install/etc/freeDiameter/hss.key.pem"; + +# Certificate authority / trust anchors +# The file containing the list of trusted Certificate Authorities (PEM list) +# (This parameter is passed to gnutls_certificate_set_x509_trust_file function) +# The directive can appear several times to specify several files. +# Default : GNUTLS default behavior +#TLS_CA = ""; +TLS_CA = "/open5gs/install/etc/freeDiameter/cacert.pem"; + +# Certificate Revocation List file +# The information about revoked certificates. +# The file contains a list of trusted CRLs in PEM format. They should have been verified before. +# (This parameter is passed to gnutls_certificate_set_x509_crl_file function) +# Note: openssl CRL format might have interoperability issue with GNUTLS format. +# Default : GNUTLS default behavior +#TLS_CRL = ""; + +# GNU TLS Priority string +# This string allows to configure the behavior of GNUTLS key exchanges +# algorithms. See gnutls_priority_init function documentation for information. +# You should also refer to the Diameter required TLS support here: +# http://tools.ietf.org/html/rfc6733#section-13.1 +# Default : "NORMAL" +# Example: TLS_Prio = "NONE:+VERS-TLS1.1:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL"; +#TLS_Prio = "NORMAL"; + +# Diffie-Hellman parameters size +# Set the number of bits for generated DH parameters +# Valid value should be 768, 1024, 2048, 3072 or 4096. +# (This parameter is passed to gnutls_dh_params_generate2 function, +# it usually should match RSA key size) +# Default : 1024 +#TLS_DH_Bits = 1024; + +# Alternatively, you can specify a file to load the PKCS#3 encoded +# DH parameters directly from. This accelerates the daemon start +# but is slightly less secure. If this file is provided, the +# TLS_DH_Bits parameters has no effect. +# Default : no default. +#TLS_DH_File = ""; + + +############################################################## +## Timers configuration + +# The Tc timer of this peer. +# It is the delay before a new attempt is made to reconnect a disconnected peer. +# The value is expressed in seconds. The recommended value is 30 seconds. +# Default: 30 +#TcTimer = 30; + +# The Tw timer of this peer. +# It is the delay before a watchdog message is sent, as described in RFC 3539. +# The value is expressed in seconds. The default value is 30 seconds. Value must +# be greater or equal to 6 seconds. See details in the RFC. +# Default: 30 +#TwTimer = 30; + +############################################################## +## Applications configuration + +# Disable the relaying of Diameter messages? +# For messages not handled locally, the default behavior is to forward the +# message to another peer if any is available, according to the routing +# algorithms. In addition the "0xffffff" application is advertised in CER/CEA +# exchanges. +# Default: Relaying is enabled. +NoRelay; + +# Number of server threads that can handle incoming messages at the same time. +# Default: 4 +#AppServThreads = 4; + +# Other applications are configured by loaded extensions. + +############################################################## +## Extensions configuration + +# The freeDiameter framework merely provides support for +# Diameter Base Protocol. The specific application behaviors, +# as well as advanced functions, are provided +# by loadable extensions (plug-ins). +# These extensions may in addition receive the name of a +# configuration file, the format of which is extension-specific. +# +# Format: +#LoadExtension = "/path/to/extension" [ : "/optional/configuration/file" ] ; +# +# Examples: +#LoadExtension = "extensions/sample.fdx"; +#LoadExtension = "extensions/sample.fdx":"conf/sample.conf"; + +# Extensions are named as follow: +# dict_* for extensions that add content to the dictionary definitions. +# dbg_* for extensions useful only to retrieve more information on the framework execution. +# acl_* : Access control list, to control which peers are allowed to connect. +# rt_* : routing extensions that impact how messages are forwarded to other peers. +# app_* : applications, these extensions usually register callbacks to handle specific messages. +# test_* : dummy extensions that are useful only in testing environments. + + +# The dbg_msg_dump.fdx extension allows you to tweak the way freeDiameter displays some +# information about some events. This extension does not actually use a configuration file +# but receives directly a parameter in the string passed to the extension. Here are some examples: +## LoadExtension = "dbg_msg_dumps.fdx" : "0x1111"; # Removes all default hooks, very quiet even in case of errors. +## LoadExtension = "dbg_msg_dumps.fdx" : "0x2222"; # Display all events with few details. +## LoadExtension = "dbg_msg_dumps.fdx" : "0x0080"; # Dump complete information about sent and received messages. +# The four digits respectively control: connections, routing decisions, sent/received messages, errors. +# The values for each digit are: +# 0 - default - keep the default behavior +# 1 - quiet - remove any specific log +# 2 - compact - display only a summary of the information +# 4 - full - display the complete information on a single long line +# 8 - tree - display the complete information in an easier to read format spanning several lines. + +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dbg_msg_dumps.fdx" : "0x8888"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_rfc5777.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_mip6i.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_nasreq.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_nas_mipv6.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_dcca.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_dcca_3gpp.fdx"; + + +############################################################## +## Peers configuration + +# The local server listens for incoming connections. By default, +# all unknown connecting peers are rejected. Extensions can override this behavior (e.g., acl_wl). +# +# In addition to incoming connections, the local peer can +# be configured to establish and maintain connections to some +# Diameter nodes and allow connections from these nodes. +# This is achieved with the ConnectPeer directive described below. +# +# Note that the configured Diameter Identity MUST match +# the information received inside CEA, or the connection will be aborted. +# +# Format: +#ConnectPeer = "diameterid" [ { parameter1; parameter2; ...} ] ; +# Parameters that can be specified in the peer's parameter list: +# No_TCP; No_SCTP; No_IP; No_IPv6; Prefer_TCP; TLS_old_method; +# No_TLS; # assume transparent security instead of TLS. DTLS is not supported yet (will change in future versions). +# Port = 5868; # The port to connect to +# TcTimer = 30; +# TwTimer = 30; +# ConnectTo = "202.249.37.5"; +# ConnectTo = "2001:200:903:2::202:1"; +# TLS_Prio = "NORMAL"; +# Realm = "realm.net"; # Reject the peer if it does not advertise this realm. +# Examples: +#ConnectPeer = "aaa.wide.ad.jp"; +#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; Port=3868; } ; +ConnectPeer = "mme.EPC_DOMAIN" { ConnectTo = "MME_IP"; Port = 3868; No_TLS; }; +ConnectPeer = "icscf.IMS_DOMAIN" { ConnectTo = "ICSCF_IP"; Port = ICSCF_BIND_PORT; No_TLS; }; +ConnectPeer = "scscf.IMS_DOMAIN" { ConnectTo = "SCSCF_IP"; Port = SCSCF_BIND_PORT; No_TLS; }; + +############################################################## diff --git a/custom_deployments/open5gs_hss_cx/hss/hss.yaml b/custom_deployments/open5gs_hss_cx/hss/hss.yaml new file mode 100644 index 00000000..bc1785e1 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/hss/hss.yaml @@ -0,0 +1,13 @@ +db_uri: mongodb://MONGO_IP/open5gs + +logger: + file: + path: /open5gs/install/var/log/open5gs/hss.log + +global: + max: + ue: MAX_NUM_UE + +hss: + freeDiameter: /open5gs/install/etc/freeDiameter/hss.conf + sms_over_ims: "sip:smsc.IMS_DOMAIN:7090" diff --git a/custom_deployments/open5gs_hss_cx/hss/hss_init.sh b/custom_deployments/open5gs_hss_cx/hss/hss_init.sh new file mode 100755 index 00000000..af0f54e2 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/hss/hss_init.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +export DB_URI="mongodb://${MONGO_IP}/open5gs" + +export IP_ADDR=$(awk 'END{print $1}' /etc/hosts) + +[ ${#MNC} == 3 ] && EPC_DOMAIN="epc.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || EPC_DOMAIN="epc.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" +[ ${#MNC} == 3 ] && IMS_DOMAIN="ims.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || IMS_DOMAIN="ims.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" + +ln -s /usr/bin/mongo /usr/bin/mongosh +sed -i "s|localhost|$MONGO_IP|" /open5gs/misc/db/open5gs-dbctl + +cp /mnt/hss/hss.yaml install/etc/open5gs +cp /mnt/hss/hss.conf install/etc/freeDiameter +cp /mnt/hss/make_certs.sh install/etc/freeDiameter + +sed -i 's|HSS_IP|'$HSS_IP'|g' install/etc/freeDiameter/hss.conf +sed -i 's|MME_IP|'$MME_IP'|g' install/etc/freeDiameter/hss.conf +sed -i 's|ICSCF_IP|'$ICSCF_IP'|g' install/etc/freeDiameter/hss.conf +sed -i 's|SCSCF_IP|'$SCSCF_IP'|g' install/etc/freeDiameter/hss.conf +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' install/etc/freeDiameter/hss.conf +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' install/etc/freeDiameter/hss.conf +sed -i 's|ICSCF_BIND_PORT|'$ICSCF_BIND_PORT'|g' install/etc/freeDiameter/hss.conf +sed -i 's|SCSCF_BIND_PORT|'$SCSCF_BIND_PORT'|g' install/etc/freeDiameter/hss.conf +sed -i 's|HSS_BIND_PORT|'$HSS_BIND_PORT'|g' install/etc/freeDiameter/hss.conf +sed -i 's|LD_LIBRARY_PATH|'$LD_LIBRARY_PATH'|g' install/etc/freeDiameter/hss.conf +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' install/etc/freeDiameter/make_certs.sh +sed -i 's|MONGO_IP|'$MONGO_IP'|g' install/etc/open5gs/hss.yaml +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' install/etc/open5gs/hss.yaml +sed -i 's|MAX_NUM_UE|'$MAX_NUM_UE'|g' install/etc/open5gs/hss.yaml + +# Generate TLS certificates +./install/etc/freeDiameter/make_certs.sh install/etc/freeDiameter + +# Sync docker time +#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone diff --git a/custom_deployments/open5gs_hss_cx/hss/make_certs.sh b/custom_deployments/open5gs_hss_cx/hss/make_certs.sh new file mode 100755 index 00000000..2faa713d --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/hss/make_certs.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +if [ 1 -ne $# ] +then + echo You must specify output directory : ./make_certs.sh ./freeDiameter + + exit; +fi + +rm -rf demoCA +mkdir demoCA +echo 01 > demoCA/serial +touch demoCA/index.txt.attr +touch demoCA/index.txt + +# Generate .rnd if it does not exist +openssl rand -out /root/.rnd -hex 256 + +# CA self certificate +openssl req -new -batch -x509 -days 3650 -nodes -newkey rsa:1024 -out $1/cacert.pem -keyout cakey.pem -subj /CN=ca.EPC_DOMAIN/C=KO/ST=Seoul/L=Nowon/O=Open5GS/OU=Tests + +#hss +openssl genrsa -out $1/hss.key.pem 1024 +openssl req -new -batch -out hss.csr.pem -key $1/hss.key.pem -subj /CN=hss.EPC_DOMAIN/C=KO/ST=Seoul/L=Nowon/O=Open5GS/OU=Tests +openssl ca -cert $1/cacert.pem -days 3650 -keyfile cakey.pem -in hss.csr.pem -out $1/hss.cert.pem -outdir . -batch + +rm -f 01.pem 02.pem 03.pem 04.pem +rm -f cakey.pem +rm -f hss.csr.pem diff --git a/custom_deployments/open5gs_hss_cx/icscf/icscf.cfg b/custom_deployments/open5gs_hss_cx/icscf/icscf.cfg new file mode 100644 index 00000000..9eacc419 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/icscf/icscf.cfg @@ -0,0 +1,53 @@ +# SIP / UDP +listen=udp:ICSCF_IP:4060 +# SIP / TCP +listen=tcp:ICSCF_IP:4060 +# SIP / TCP/TLS +#listen=tls:ICSCF_IP:4061 + +alias=IMS_DOMAIN + +#!define NETWORKNAME "IMS_DOMAIN" +#!define EPC_REALM "EPC_DOMAIN" +#!define HOSTNAME "icscf.IMS_DOMAIN" + +#!subst "/NETWORKNAME/IMS_DOMAIN/" + +#!define ENUM_SUFFIX "IMS_DOMAIN." + +# SIP-Address of capturing node, if not set, capturing is disabled. +##!define CAPTURE_NODE "sip:127.0.0.1:9060" + +# Connection URL for the database: +#!define DB_URL "mysql://icscf:heslo@MYSQL_IP/icscf" +##!define DB_URL2 "con2=>mysql://icscf:heslo@MYSQL_IP/icscf" + +# Allowed IPs for XML-RPC-Queries +##!define XMLRPC_WHITELIST_1 "127.0.0.1" +##!define XMLRPC_WHITELIST_2 "127.0.0.1" +##!define XMLRPC_WHITELIST_3 "127.0.0.1" + +# *** To run in debug mode: +# - define WITH_DEBUG +# +# *** To enable TLS support execute: +# - adjust CFGDIR/tls.cfg as needed +# - define WITH_TLS +# +# *** To enable XMLRPC support execute: +# - define WITH_XMLRPC +# - adjust route[XMLRPC] for access policy +# +# *** To enable a Homer SIP-Capter-Node: +# - define CAPTURE_NODE with a proper address +# +# *** To forwarding to PSTN for unknown users: +# - define PEERING +# +# Enabled Features for this host: +##!define WITH_DEBUG +#!define WITH_TCP +##!define WITH_TLS +#!define WITH_XMLRPC +##!define PEERING +##!define FALLBACK_AUTH diff --git a/custom_deployments/open5gs_hss_cx/icscf/icscf.xml b/custom_deployments/open5gs_hss_cx/icscf/icscf.xml new file mode 100644 index 00000000..03a94141 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/icscf/icscf.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + diff --git a/custom_deployments/open5gs_hss_cx/icscf/icscf_init.sh b/custom_deployments/open5gs_hss_cx/icscf/icscf_init.sh new file mode 100755 index 00000000..fb34bf4f --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/icscf/icscf_init.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[ ${#MNC} == 3 ] && IMS_DOMAIN="ims.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || IMS_DOMAIN="ims.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" +[ ${#MNC} == 3 ] && EPC_DOMAIN="epc.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || EPC_DOMAIN="epc.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" + +mkdir -p /etc/kamailio_icscf +cp /mnt/icscf/icscf.cfg /etc/kamailio_icscf +cp /mnt/icscf/icscf.xml /etc/kamailio_icscf +cp /mnt/icscf/kamailio_icscf.cfg /etc/kamailio_icscf + +while ! mysqladmin ping -h ${MYSQL_IP} --silent; do + sleep 5; +done + +# Sleep until permissions are set +sleep 10; + +# Create ICSCF database, populate tables and grant privileges +if [[ -z "`mysql -u root -h ${MYSQL_IP} -qfsBe "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='icscf'" 2>&1`" ]]; +then + mysql -u root -h ${MYSQL_IP} -e "create database icscf;" + mysql -u root -h ${MYSQL_IP} icscf < /usr/local/src/kamailio/misc/examples/ims/icscf/icscf.sql + + ICSCF_USER_EXISTS=`mysql -u root -h ${MYSQL_IP} -s -N -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE User = 'icscf' AND Host = '%')"` + if [[ "$ICSCF_USER_EXISTS" == 0 ]] + then + mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'icscf'@'%' IDENTIFIED WITH mysql_native_password BY 'heslo'"; + mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'provisioning'@'%' IDENTIFIED WITH mysql_native_password BY 'provi'"; + mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'icscf'@'$ICSCF_IP' IDENTIFIED WITH mysql_native_password BY 'heslo'"; + mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'provisioning'@'$ICSCF_IP' IDENTIFIED WITH mysql_native_password BY 'provi'"; + mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON icscf.* TO 'icscf'@'%'"; + mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON icscf.* TO 'icscf'@'$ICSCF_IP'"; + mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON icscf.* TO 'provisioning'@'%'"; + mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON icscf.* TO 'provisioning'@'$ICSCF_IP'"; + mysql -u root -h ${MYSQL_IP} -e "FLUSH PRIVILEGES;" + fi +fi + +DOMAIN_PRESENT=`mysql -u root -h ${MYSQL_IP} icscf -s -N -e "SELECT count(*) FROM nds_trusted_domains WHERE trusted_domain='$IMS_DOMAIN';"` +if [[ "$DOMAIN_PRESENT" == 0 ]] +then + mysql -u root -h ${MYSQL_IP} icscf -e "INSERT INTO nds_trusted_domains (trusted_domain) VALUES ('$IMS_DOMAIN');" +fi + +URI_PRESENT=`mysql -u root -h ${MYSQL_IP} icscf -s -N -e "SELECT count(*) FROM s_cscf WHERE s_cscf_uri='sip:scscf.$IMS_DOMAIN:6060';"` +if [[ "$URI_PRESENT" == 0 ]] +then + mysql -u root -h ${MYSQL_IP} icscf -e "INSERT INTO s_cscf (name, s_cscf_uri) VALUES ('First and only S-CSCF', 'sip:scscf.$IMS_DOMAIN:6060');" +fi + +SCSCF_ID=`mysql -u root -h ${MYSQL_IP} icscf -s -N -e "SELECT id FROM s_cscf WHERE s_cscf_uri='sip:scscf.$IMS_DOMAIN:6060' LIMIT 1;"` +CAP_PRESENT=`mysql -u root -h ${MYSQL_IP} icscf -s -N -e "SELECT count(*) FROM s_cscf_capabilities WHERE id_s_cscf='$SCSCF_ID';"` +if [[ "$CAP_PRESENT" == 0 ]] +then + mysql -u root -h ${MYSQL_IP} icscf -e "INSERT INTO s_cscf_capabilities (id_s_cscf, capability) VALUES ('$SCSCF_ID', 0),('$SCSCF_ID', 1);" +fi + +sed -i 's|ICSCF_IP|'$ICSCF_IP'|g' /etc/kamailio_icscf/icscf.cfg +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/kamailio_icscf/icscf.cfg +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/kamailio_icscf/icscf.cfg +sed -i 's|MYSQL_IP|'$MYSQL_IP'|g' /etc/kamailio_icscf/icscf.cfg + +sed -i 's|ICSCF_IP|'$ICSCF_IP'|g' /etc/kamailio_icscf/icscf.xml +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/kamailio_icscf/icscf.xml +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/kamailio_icscf/icscf.xml +sed -i 's|HSS_BIND_PORT|'$HSS_BIND_PORT'|g' /etc/kamailio_icscf/icscf.xml +sed -i 's|ICSCF_BIND_PORT|'$ICSCF_BIND_PORT'|g' /etc/kamailio_icscf/icscf.xml + +# Sync docker time +#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone diff --git a/custom_deployments/open5gs_hss_cx/icscf/kamailio_icscf.cfg b/custom_deployments/open5gs_hss_cx/icscf/kamailio_icscf.cfg new file mode 100644 index 00000000..22781e38 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/icscf/kamailio_icscf.cfg @@ -0,0 +1,639 @@ +#!KAMAILIO +# +# This config file implements the basic I-CSCF functionality +# - web: http://www.kamailio.org +# - git: http://sip-router.org +# +# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php +# for an explanation of possible statements, functions and parameters. +# +# Direct your questions about this file to: . +# +# For more information about the various parameters, functions and statements +# try http://sip-router.org/wiki/ . +# + +system.shutdownmode = 0 desc "System shutdown mode" +system.service = "Interrogating-CSCF" desc "Function of this server" + +include_file "icscf.cfg" + +####### Defined Values ######### +# *** Value defines - IDs used later in config + +# - flags +# FLT_ - per transaction (message) flags +# FLB_ - per branch flags + +#!define FLT_CAPTURE 1 + +#!ifdef WITH_XMLRPC +listen=tcp:127.0.0.1:4060 +#!endif + +####### Global Parameters ######### +#!ifdef WITH_DEBUG +debug=5 +log_stderror=yes +sip_warning=yes +#!else +debug=2 +log_stderror=no +sip_warning=no +#!endif + +user_agent_header="User-Agent: Kamailio I-CSCF" +server_header="Server: Kamailio I-CSCF" + +/* comment the next line to enable the auto discovery of local aliases + based on reverse DNS on IPs (default on) */ +auto_aliases=no + +# Do SRV-Loadbalancing: +dns_srv_lb=on +# Always: Also try IPv6: +dns_try_ipv6=on +# Query NAPTR-Records as well: +dns_try_naptr=no + +#!ifdef WITH_XMLRPC +#!ifndef WITH_TCP +#!define WITH_TCP +#!endif +#!ifndef TCP_PROCESSES +# Number of TCP Processes +#!define TCP_PROCESSES 3 +#!endif +#!endif + +#!ifdef WITH_TCP +# life time of TCP connection when there is no traffic +# - a bit higher than registration expires to cope with UA behind NAT +tcp_connection_lifetime=3615 +#!ifdef TCP_PROCESSES +tcp_children=TCP_PROCESSES +#!endif +#!else +disable_tcp=yes +#!endif + +check_via=no # (cmd. line: -v) +dns=no # (cmd. line: -r) +rev_dns=no # (cmd. line: -R) + +children=4 + +# ------------------ module loading ---------------------------------- +mpath="/usr/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/:/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/:/usr/lib/x86_64-linux-gnu/kamailio/modules/:/usr/local/lib64/kamailio/modules" +# (we try both the lib64 and the lib directory) +loadmodule "tm" +loadmodule "sl" +loadmodule "rr" +loadmodule "pv" +loadmodule "textops" +loadmodule "maxfwd" +loadmodule "sanity" +loadmodule "siputils" +loadmodule "kex" +loadmodule "tmx" +loadmodule "pike" +loadmodule "corex" + +# Control interfaces: +loadmodule "ctl" +loadmodule "cfg_rpc" +#!ifdef WITH_XMLRPC +loadmodule "xmlrpc" +#!endif + +# Load the according DB-Module: +loadmodule "db_mysql" +#!ifdef DB_URL2 +loadmodule "db_cluster" +#!endif + +loadmodule "cdp.so" +loadmodule "cdp_avp.so" +loadmodule "xlog.so" + +loadmodule "ims_icscf.so" + +#!ifdef CAPTURE_NODE +loadmodule "siptrace.so" +#!endif + +#!ifdef WITH_DEBUG +loadmodule "debugger.so" +#!endif + +#!ifdef WITH_TLS +loadmodule "tls.so" +#!endif + +#!ifdef PEERING +loadmodule "enum" +loadmodule "dispatcher" +#!endif + +# ----------------- setting module-specific parameters --------------- +#!ifdef DB_URL2 +# ----- db_cluster params ----- +modparam("db_cluster", "connection", DB_URL) +modparam("db_cluster", "connection", DB_URL2) +modparam("db_cluster", "cluster", "cluster1=>con1=2s2s;con2=1s1s") +#!endif + +loadmodule "jsonrpcs.so" +# ----- jsonrpcs params ----- +modparam("jsonrpcs", "pretty_format", 1) +/* set the path to RPC fifo control file */ +modparam("jsonrpcs", "fifo_name", "/var/run/kamailio/kamailio_rpc.fifo") +/* set the path to RPC unix socket control file */ +modparam("jsonrpcs", "dgram_socket", "/var/run/kamailio/kamailio_rpc.sock") + +# -- rr params -- +# add value to ;lr param to make some broken UAs happy +modparam("rr", "enable_full_lr", 1) + +# -- cdp params -- +modparam("cdp","config_file","/etc/kamailio_icscf/icscf.xml") + +# ----- icscf params ----- +# Comment the following line to enable realm routing +#!ifdef CXDX_FORCED_PEER +modparam("ims_icscf", "cxdx_forced_peer", CXDX_FORCED_PEER) +#!endif +modparam("ims_icscf","cxdx_dest_realm", EPC_REALM) + +# DB-URL, where information about S-CSCF-Server can be found: +#!ifdef DB_URL2 +modparam("ims_icscf", "db_url", "cluster://cluster1") +#!else +modparam("ims_icscf", "db_url", DB_URL) +#!endif + +#!ifdef PEERING +# Route which is executed, in case HSS returned "User-Unknown" on LIR request +modparam("ims_icscf","route_lir_user_unknown", "lir_term_user_unknown") +#!endif +#!ifdef FALLBACK_AUTH +# Route which is executed, in case HSS returned "User-Unknown" on UAR request +modparam("ims_icscf","route_uar_user_unknown", "uar_term_user_unknown") +#!endif + +#!ifdef WITH_TLS +# ----- tls params ----- +modparam("tls", "config", "/etc/kamailio_icscf/tls.cfg") +#!endif + +#!ifdef WITH_XMLRPC +# ----- xmlrpc params ----- +modparam("xmlrpc", "route", "XMLRPC"); +modparam("xmlrpc", "url_match", "^/RPC") +#!endif + +# ----- ctl params ----- +modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl") + +#!ifdef WITH_DEBUG +# ----- debugger params ----- +modparam("debugger", "cfgtrace", 1) +#!endif + +#!ifdef CAPTURE_NODE +# Destination, where to send the traffic +modparam("siptrace", "duplicate_uri", CAPTURE_NODE) +# Trace all traffic +modparam("siptrace", "trace_on", 1) +modparam("siptrace", "trace_to_database", 0) +modparam("siptrace", "trace_flag", FLT_CAPTURE) +modparam("siptrace", "hep_mode_on", 1) +#!endif + +#!ifdef PEERING +# ----- enum params ----- +modparam("enum", "domain_suffix", ENUM_SUFFIX) +#!endif + +# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 10sec +modparam("tm", "fr_timer", 10000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000) +# Don't reply automatically with "100 Trying" +modparam("tm", "auto_inv_100", 0) + +#!ifdef WITH_DEBUG +#loadmodule "debugger.so" +modparam("debugger", "mod_hash_size", 5) +modparam("debugger", "mod_level_mode", 1) +modparam("debugger", "mod_level", "cdp=3") +modparam("debugger", "mod_level", "ims_icscf=3") +#!endif + +# ------------------------- request routing logic ------------------- +# main routing logic + +route{ +#!ifdef WITH_DEBUG + xlog("I-CSCF >>>>>>>>>>>>>>>>>>>> $rm $ru ($fu => $tu ($si:$sp) to $tu, $ci)\n"); +#!endif + +# if !($rU =~ "\+.*") { +# prefix("+"); +# } + + # per request initial checks + route(REQINIT); + + if (is_method("REGISTER")) { + route(register); + } + + if (is_method("NOTIFY") && search("^(Event|o)([ \t]*):([ \t]*)reg")) { + if (!t_relay()) { + sl_reply_error(); + } + exit; + } + + if (is_method("INVITE|SUBSCRIBE|MESSAGE|INFO|PUBLISH|CANCEL")) { + route(initial_request); + } else { + # Shouldn't get here unless missconfigured (add more methods as initial) or + # somebody is routing unknown messages + append_to_reply("Allow: INVITE,SUBSCRIBE,MESSAGE,INFO,PUBLISH,CANCEL\r\n"); + send_reply("406","Initial Request Method not allowed at the I-CSCF"); + break; + } +} + +###################################################################### +# Helper routes (Basic-Checks, NAT-Handling/RTP-Control, XML-RPC) +###################################################################### +# Per SIP request initial checks +route[REQINIT] { + $var(used) = 1 - ($stat(free_size) / $stat(total_size)); + xlog("L_DBG", "Mem: Total $stat(total_size), Free $stat(free_size) [$var(used)% used]\n"); + if ($var(used) > 95) { + send_reply("503", "Server overloaded"); + exit; + } + + + # Trace this message +#!ifdef CAPTURE_NODE + sip_trace(); + setflag(FLT_CAPTURE); +#!endif + if (!mf_process_maxfwd_header("10")) { + sl_send_reply("483","Too Many Hops"); + exit; + } + if(!sanity_check("1511", "7")) { + xlog("Malformed SIP message from $si:$sp\n"); + exit; + } + + # Check for shutdown mode: + if (!has_totag() && ($sel(cfg_get.system.shutdownmode) > 0)) { + send_reply("503", "Server shutting down"); + exit; + } + + # Reply to OPTIONS: + if (is_method("OPTIONS") && (uri==myself)) { + options_reply(); + exit; + } + + # Ignore Re-Transmits: + if (t_lookup_request()) { + exit; + } + + if (is_method("INVITE|REGISTER")) { + send_reply("100", "Trying"); + } +} + +###################################################################### +# XMLRPC routing +###################################################################### +#!ifdef WITH_XMLRPC +route[XMLRPC] { + if ((method=="POST" || method=="GET") +#!ifdef XMLRPC_WHITELIST_1 +&& ((src_ip == XMLRPC_WHITELIST_1) +#!ifdef XMLRPC_WHITELIST_2 + || (src_ip == XMLRPC_WHITELIST_2) +#!endif +#!ifdef XMLRPC_WHITELIST_3 + || (src_ip == XMLRPC_WHITELIST_3) +#!endif +) +#!endif +) { + # close connection only for xmlrpclib user agents (there is a bug in + # xmlrpclib: it waits for EOF before interpreting the response). + if ($hdr(User-Agent) =~ "xmlrpclib") + set_reply_close(); + set_reply_no_connect(); + dispatch_rpc(); + exit; + } + send_reply("403", "Forbidden"); + exit; +} +#!endif + +###################################################################### +# Handling of REGISTER requests +###################################################################### +route[register] +{ + t_set_fr(5000, 5000); + #first check if we have an S-CSCF list + if (I_scscf_select("0")) { + #there is an S-CSCF list - no need to do a UAR + t_on_reply("register_reply"); + t_on_failure("register_failure"); + if (!t_relay()) { + send_reply("500","Error forwarding towards S-CSCF"); + } + } else { + #no S-CSCF list therefore must do UAR + #free this from the failed I_scscf_select call + I_scscf_drop(); + # Do an asynchronous UAR: + #0=REG/DEREG; 1=REG+Capabilities + if (!I_perform_user_authorization_request("REG_UAR_REPLY","0")) { + send_reply("500", "Error in Request"); + } + } + exit; +} + +route[REG_UAR_REPLY] +{ + #xlog("$$avp(s:uaa_return_code) = $avp(s:uaa_return_code)\n"); + #this is async so to know status we have to check the reply avp + switch ($avp(s:uaa_return_code)){ + case 1: #success + if (I_scscf_select("0")){ + t_on_failure("register_failure"); + t_on_reply("register_reply"); + #now relay to appropriate SCSCF + if (!t_relay()) { + t_reply("500", "Error forwarding to SCSCF"); + } + } else {#select failed + I_scscf_drop(); + t_reply("500", "Server error on SCSCF Select (UAR)"); + } + break; + case -1: #failure + xlog("L_ERR", "UAR failure - error response sent from module\n"); + break; + case -2: #error + xlog("L_ERR", "UAR error - sending error response now\n"); + t_reply("500", "UAR failed"); + break; + default: + xlog("L_ERR", "Unknown return code from UAR, value is [$avp(s:uaa_return_code)]\n"); + t_reply("500", "Unknown response code from UAR"); + break; + } +} + + +###################################################################### +# Replies to REGISTER requests, +###################################################################### +onreply_route[register_reply] +{ + xlog("L_DBG", "Enter register reply block"); + if (!t_check_status("(408)|(480)")){ + if (!t_check_status("(401)")){ + xlog("L_DBG", "dropping scscf list on register failure"); + I_scscf_drop(); + } else { + xlog("L_DBG", "This is a 401 - keep scscf list to do optimisation"); + } + } + break; +} + +###################################################################### +# Failed REGISTERs +###################################################################### +failure_route[register_failure] +{ + if (t_branch_timeout() || t_check_status("([5-6][0-9][0-9])")){ + if (I_scscf_select("1")) { + t_on_reply("register_reply"); + t_on_failure("register_failure"); + if (!t_relay()) { + t_reply("500","Error forwarding towards next S-CSCF"); + break; + } + break; + } else { + t_reply("500", "Server error on UAR select next S-CSCF"); + break; + } + } else { + if (!t_check_status("(401)")){ + xlog("L_DBG", "dropping scscf list on register failure"); + I_scscf_drop(); + } else { + xlog("L_DBG", "This is a 401 - keep scscf list to do optimisation"); + } + break; + } +} + +###################################################################### +# Initial requests +###################################################################### +route[initial_request] +{ +# $avp(prefix)="+"; +# $ru= $(ru{s.rm,$avp(prefix)}); + xlog("$$ru => $ru\n"); + I_perform_location_information_request("LIR_REPLY", "0"); +} + +route[LIR_REPLY] { + if ($avp(lia_return_code) == 1) { + if (I_scscf_select("0")) { + xlog("L_DBG", "ru = $ru, du = $du\n"); + t_on_reply("initial_request_reply"); + t_on_failure("initial_request_failure"); + if (!t_relay()) { + t_reply("500","Error forwarding towards S-CSCF"); + break; + } + break; + } else { + xlog("L_DBG", "dropping scscf list on initial request"); + I_scscf_drop(); + t_reply("500", "Server error on LIR select S-CSCF"); + break; + } + } else { + t_reply("500", "Server error on LIR"); + break; + } + break; +} + +###################################################################### +# Replies to initial requests +###################################################################### +onreply_route[initial_request_reply] +{ + xlog("L_DBG", "Enter initial request request block"); + if (!t_check_status("(408)")){ + xlog("L_DBG", "dropping scscf list on initial request reply"); + I_scscf_drop(); + } + break; +} + +###################################################################### +# Failed initial requests +###################################################################### +failure_route[initial_request_failure] +{ + xlog("L_DBG", "Enter initial request failure block"); + if (t_check_status("(408)")){ + xlog("L_DBG", "Got a failure for initial request"); + if (I_scscf_select("1")) { + t_on_reply("initial_request_reply"); + t_on_failure("initial_request_failure"); + if (!t_relay()) { + t_reply("500","Error forwarding towards next S-CSCF"); + break; + } + break; + } else { + t_reply("500", "Server error on LIR select next S-CSCF"); + break; + } + } else { + xlog("L_DBG", "dropping scscf list on initial request failure"); + I_scscf_drop(); + } + break; +} + +#!ifdef PEERING +###################################################################### +# HSS returned "User-Unknown" on LIR request +###################################################################### +route[lir_term_user_unknown] +{ + if (uri =~ "tel:.*") { + # Let's check, if the number can be found in ENUM: + if(!enum_query()) { + # ENUM failed, send it to the PSTN-Gateway: + route(PSTN); + break; + } + + # ENUM resolved to another domain + if ($rd != NETWORKNAME) { + t_on_reply("initial_request_reply"); + t_on_failure("initial_request_failure"); + if (!t_relay()) { + t_reply("500","Error forwarding to external domain"); + exit; + }; + exit; + } else { + t_reply("604","Does not exist anywhere - HSS User Unknown"); + exit; + }; + } else { + # we received a request for our domain (non-tel), but HSS said "User Unknown" + if ($rd != NETWORKNAME) { + t_reply("604","Does not exist anywhere - HSS User Unknown"); + exit; + } else { + # try to forward non-tel request to other domain + t_on_reply("initial_request_reply"); + t_on_failure("initial_request_failure"); + if (!t_relay()) { + t_reply("500","Error forwarding to external domain"); + exit; + }; + exit; + }; + }; +} + +###################################################################### +# Send calls to the PSTN-Gateways: +###################################################################### +route[PSTN] +{ + t_on_failure("PSTN_failure"); + # Relay the request towards the PSTN-Gateway: + if (!ds_select_dst("1", "4")) { + send_reply("503", "Service not available"); + exit; + } + # Relay the request: + if (!t_relay()) { + send_reply("503", "Service not available"); + exit; + }; + exit; +} + +###################################################################### +# manage failure routing cases, perform failover +###################################################################### +failure_route[PSTN_failure] { + # Choose another gateway, in case we + # - get a local generated "408" + # - receive a 5xx or 6xx reply from the proxy. + if (t_branch_timeout() || t_check_status("[5-6]..")) { + if (ds_next_dst()) { + # Do Failover in case problems: + t_on_failure("PSTN_failure"); + # Relay the request: + if (!t_relay()) { + send_reply("503", "Service not available"); + exit; + }; + } else { + # Add a header, to indicate the phone should try again in 30 seconds. + append_hf("Retry-After: 30\r\n"); + send_reply("503", "Service not available"); + } + exit; + } +} +#!endif + +#!ifdef FALLBACK_AUTH +###################################################################### +# HSS returned "User-Unknown" on UAR request, +# try to send it to any S-CSCF for authentication +###################################################################### +route[uar_term_user_unknown] +{ + $rd = "scscf."+NETWORKNAME; + t_on_reply("register_reply"); + t_on_failure("register_failure"); + if (!t_relay()) { + t_reply("500","Error forwarding towards S-CSCF"); + break; + } + break; +} +#!endif diff --git a/custom_deployments/open5gs_hss_cx/mme/make_certs.sh b/custom_deployments/open5gs_hss_cx/mme/make_certs.sh new file mode 100755 index 00000000..c5004188 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/mme/make_certs.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +if [ 1 -ne $# ] +then + echo You must specify output directory : ./make_certs.sh ./freeDiameter + + exit; +fi + +rm -rf demoCA +mkdir demoCA +echo 01 > demoCA/serial +touch demoCA/index.txt.attr +touch demoCA/index.txt + +# Generate .rnd if it does not exist +openssl rand -out /root/.rnd -hex 256 + +# CA self certificate +openssl req -new -batch -x509 -days 3650 -nodes -newkey rsa:1024 -out $1/cacert.pem -keyout cakey.pem -subj /CN=ca.EPC_DOMAIN/C=KO/ST=Seoul/L=Nowon/O=Open5GS/OU=Tests + +#mme +openssl genrsa -out $1/mme.key.pem 1024 +openssl req -new -batch -out mme.csr.pem -key $1/mme.key.pem -subj /CN=mme.EPC_DOMAIN/C=KO/ST=Seoul/L=Nowon/O=Open5GS/OU=Tests +openssl ca -cert $1/cacert.pem -days 3650 -keyfile cakey.pem -in mme.csr.pem -out $1/mme.cert.pem -outdir . -batch + +rm -rf demoCA +rm -f 01.pem 02.pem 03.pem 04.pem +rm -f cakey.pem +rm -f mme.csr.pem diff --git a/custom_deployments/open5gs_hss_cx/mme/mme.conf b/custom_deployments/open5gs_hss_cx/mme/mme.conf new file mode 100644 index 00000000..c1d8358c --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/mme/mme.conf @@ -0,0 +1,266 @@ +# This is a sample configuration file for freeDiameter daemon. + +# Most of the options can be omitted, as they default to reasonable values. +# Only TLS-related options must be configured properly in usual setups. + +# It is possible to use "include" keyword to import additional files +# e.g.: include "/etc/freeDiameter.d/*.conf" +# This is exactly equivalent as copy & paste the content of the included file(s) +# where the "include" keyword is found. + + +############################################################## +## Peer identity and realm + +# The Diameter Identity of this daemon. +# This must be a valid FQDN that resolves to the local host. +# Default: hostname's FQDN +#Identity = "aaa.koganei.freediameter.net"; +Identity = "mme.EPC_DOMAIN"; + +# The Diameter Realm of this daemon. +# Default: the domain part of Identity (after the first dot). +#Realm = "koganei.freediameter.net"; +Realm = "EPC_DOMAIN"; + +############################################################## +## Transport protocol configuration + +# The port this peer is listening on for incoming connections (TCP and SCTP). +# Default: 3868. Use 0 to disable. +#Port = 3868; + +# The port this peer is listening on for incoming TLS-protected connections (TCP and SCTP). +# See TLS_old_method for more information about TLS flavours. +# Note: we use TLS/SCTP instead of DTLS/SCTP at the moment. This will change in future version of freeDiameter. +# Default: 5868. Use 0 to disable. +#SecPort = 5868; + +# Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA exchange is completed +# on the unsecure connection. The alternative is RFC6733 mechanism, where TLS protects also the +# CER/CEA exchange on a dedicated secure port. +# This parameter only affects outgoing connections. +# The setting can be also defined per-peer (see Peers configuration section). +# Default: use RFC6733 method with separate port for TLS. +#TLS_old_method; + +# Disable use of TCP protocol (only listen and connect over SCTP) +# Default : TCP enabled +#No_TCP; + +# Disable use of SCTP protocol (only listen and connect over TCP) +# Default : SCTP enabled +#No_SCTP; +# This option is ignored if freeDiameter is compiled with DISABLE_SCTP option. + +# Prefer TCP instead of SCTP for establishing new connections. +# This setting may be overwritten per peer in peer configuration blocs. +# Default : SCTP is attempted first. +#Prefer_TCP; + +# Default number of streams per SCTP associations. +# This setting may be overwritten per peer basis. +# Default : 30 streams +#SCTP_streams = 30; + +############################################################## +## Endpoint configuration + +# Disable use of IP addresses (only IPv6) +# Default : IP enabled +#No_IP; + +# Disable use of IPv6 addresses (only IP) +# Default : IPv6 enabled +#No_IPv6; + +# Specify local addresses the server must bind to +# Default : listen on all addresses available. +#ListenOn = "202.249.37.5"; +#ListenOn = "2001:200:903:2::202:1"; +#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0"; +ListenOn = "MME_IP"; + + +############################################################## +## Server configuration + +# How many Diameter peers are allowed to be connecting at the same time ? +# This parameter limits the number of incoming connections from the time +# the connection is accepted until the first CER is received. +# Default: 5 unidentified clients in paralel. +#ThreadsPerServer = 5; + +############################################################## +## TLS Configuration + +# TLS is managed by the GNUTLS library in the freeDiameter daemon. +# You may find more information about parameters and special behaviors +# in the relevant documentation. +# http://www.gnu.org/software/gnutls/manual/ + +# Credentials of the local peer +# The X509 certificate and private key file to use for the local peer. +# The files must contain PKCS-1 encoded RSA key, in PEM format. +# (These parameters are passed to gnutls_certificate_set_x509_key_file function) +# Default : NO DEFAULT +#TLS_Cred = "" , ""; +#TLS_Cred = "/etc/ssl/certs/freeDiameter.pem", "/etc/ssl/private/freeDiameter.key"; +TLS_Cred = "/open5gs/install/etc/freeDiameter/mme.cert.pem", "/open5gs/install/etc/freeDiameter/mme.key.pem"; + +# Certificate authority / trust anchors +# The file containing the list of trusted Certificate Authorities (PEM list) +# (This parameter is passed to gnutls_certificate_set_x509_trust_file function) +# The directive can appear several times to specify several files. +# Default : GNUTLS default behavior +#TLS_CA = ""; +TLS_CA = "/open5gs/install/etc/freeDiameter/cacert.pem"; + +# Certificate Revocation List file +# The information about revoked certificates. +# The file contains a list of trusted CRLs in PEM format. They should have been verified before. +# (This parameter is passed to gnutls_certificate_set_x509_crl_file function) +# Note: openssl CRL format might have interoperability issue with GNUTLS format. +# Default : GNUTLS default behavior +#TLS_CRL = ""; + +# GNU TLS Priority string +# This string allows to configure the behavior of GNUTLS key exchanges +# algorithms. See gnutls_priority_init function documentation for information. +# You should also refer to the Diameter required TLS support here: +# http://tools.ietf.org/html/rfc6733#section-13.1 +# Default : "NORMAL" +# Example: TLS_Prio = "NONE:+VERS-TLS1.1:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL"; +#TLS_Prio = "NORMAL"; + +# Diffie-Hellman parameters size +# Set the number of bits for generated DH parameters +# Valid value should be 768, 1024, 2048, 3072 or 4096. +# (This parameter is passed to gnutls_dh_params_generate2 function, +# it usually should match RSA key size) +# Default : 1024 +#TLS_DH_Bits = 1024; + +# Alternatively, you can specify a file to load the PKCS#3 encoded +# DH parameters directly from. This accelerates the daemon start +# but is slightly less secure. If this file is provided, the +# TLS_DH_Bits parameters has no effect. +# Default : no default. +#TLS_DH_File = ""; + + +############################################################## +## Timers configuration + +# The Tc timer of this peer. +# It is the delay before a new attempt is made to reconnect a disconnected peer. +# The value is expressed in seconds. The recommended value is 30 seconds. +# Default: 30 +#TcTimer = 30; + +# The Tw timer of this peer. +# It is the delay before a watchdog message is sent, as described in RFC 3539. +# The value is expressed in seconds. The default value is 30 seconds. Value must +# be greater or equal to 6 seconds. See details in the RFC. +# Default: 30 +#TwTimer = 30; + +############################################################## +## Applications configuration + +# Disable the relaying of Diameter messages? +# For messages not handled locally, the default behavior is to forward the +# message to another peer if any is available, according to the routing +# algorithms. In addition the "0xffffff" application is advertised in CER/CEA +# exchanges. +# Default: Relaying is enabled. +NoRelay; + +# Number of server threads that can handle incoming messages at the same time. +# Default: 4 +#AppServThreads = 4; + +# Other applications are configured by loaded extensions. + +############################################################## +## Extensions configuration + +# The freeDiameter framework merely provides support for +# Diameter Base Protocol. The specific application behaviors, +# as well as advanced functions, are provided +# by loadable extensions (plug-ins). +# These extensions may in addition receive the name of a +# configuration file, the format of which is extension-specific. +# +# Format: +#LoadExtension = "/path/to/extension" [ : "/optional/configuration/file" ] ; +# +# Examples: +#LoadExtension = "extensions/sample.fdx"; +#LoadExtension = "extensions/sample.fdx":"conf/sample.conf"; + +# Extensions are named as follow: +# dict_* for extensions that add content to the dictionary definitions. +# dbg_* for extensions useful only to retrieve more information on the framework execution. +# acl_* : Access control list, to control which peers are allowed to connect. +# rt_* : routing extensions that impact how messages are forwarded to other peers. +# app_* : applications, these extensions usually register callbacks to handle specific messages. +# test_* : dummy extensions that are useful only in testing environments. + + +# The dbg_msg_dump.fdx extension allows you to tweak the way freeDiameter displays some +# information about some events. This extension does not actually use a configuration file +# but receives directly a parameter in the string passed to the extension. Here are some examples: +## LoadExtension = "dbg_msg_dumps.fdx" : "0x1111"; # Removes all default hooks, very quiet even in case of errors. +## LoadExtension = "dbg_msg_dumps.fdx" : "0x2222"; # Display all events with few details. +## LoadExtension = "dbg_msg_dumps.fdx" : "0x0080"; # Dump complete information about sent and received messages. +# The four digits respectively control: connections, routing decisions, sent/received messages, errors. +# The values for each digit are: +# 0 - default - keep the default behavior +# 1 - quiet - remove any specific log +# 2 - compact - display only a summary of the information +# 4 - full - display the complete information on a single long line +# 8 - tree - display the complete information in an easier to read format spanning several lines. + +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dbg_msg_dumps.fdx" : "0x8888"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_rfc5777.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_mip6i.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_nasreq.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_nas_mipv6.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_dcca.fdx"; +LoadExtension = "LD_LIBRARY_PATH/freeDiameter/dict_dcca_3gpp.fdx"; + + +############################################################## +## Peers configuration + +# The local server listens for incoming connections. By default, +# all unknown connecting peers are rejected. Extensions can override this behavior (e.g., acl_wl). +# +# In addition to incoming connections, the local peer can +# be configured to establish and maintain connections to some +# Diameter nodes and allow connections from these nodes. +# This is achieved with the ConnectPeer directive described below. +# +# Note that the configured Diameter Identity MUST match +# the information received inside CEA, or the connection will be aborted. +# +# Format: +#ConnectPeer = "diameterid" [ { parameter1; parameter2; ...} ] ; +# Parameters that can be specified in the peer's parameter list: +# No_TCP; No_SCTP; No_IP; No_IPv6; Prefer_TCP; TLS_old_method; +# No_TLS; # assume transparent security instead of TLS. DTLS is not supported yet (will change in future versions). +# Port = 5868; # The port to connect to +# TcTimer = 30; +# TwTimer = 30; +# ConnectTo = "202.249.37.5"; +# ConnectTo = "2001:200:903:2::202:1"; +# TLS_Prio = "NORMAL"; +# Realm = "realm.net"; # Reject the peer if it does not advertise this realm. +# Examples: +#ConnectPeer = "aaa.wide.ad.jp"; +#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; Port=3868; } ; +ConnectPeer = "hss.EPC_DOMAIN" { ConnectTo = "HSS_IP"; Port = HSS_BIND_PORT; No_TLS; }; + + +############################################################## diff --git a/custom_deployments/open5gs_hss_cx/mme/mme.yaml b/custom_deployments/open5gs_hss_cx/mme/mme.yaml new file mode 100644 index 00000000..85ec6eb0 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/mme/mme.yaml @@ -0,0 +1,59 @@ +logger: + file: + path: /open5gs/install/var/log/open5gs/mme.log + +global: + max: + ue: MAX_NUM_UE + +mme: + freeDiameter: /open5gs/install/etc/freeDiameter/mme.conf + s1ap: + server: + - dev: MME_IF + gtpc: + server: + - dev: MME_IF + client: + sgwc: + - address: SGWC_IP + smf: + - address: SMF_IP + sgsap: + server: + - address: OSMOMSC_IP + map: + tai: + plmn_id: + mcc: MCC + mnc: MNC + tac: 1 + lai: + plmn_id: + mcc: MCC + mnc: MNC + lac: 1 + gummei: + - plmn_id: + mcc: MCC + mnc: MNC + mme_gid: 2 + mme_code: 1 + tai: + - plmn_id: + mcc: MCC + mnc: MNC + tac: 1 + security: + integrity_order : [ EIA2, EIA1, EIA0 ] + ciphering_order : [ EEA0, EEA1, EEA2 ] + network_name: + full: Open5GS + mme_name: open5gs-mme0 + metrics: + server: + - address: MME_IP + port: 9091 + time: + t3412: + value: 540 diff --git a/custom_deployments/open5gs_hss_cx/mme/mme_init.sh b/custom_deployments/open5gs_hss_cx/mme/mme_init.sh new file mode 100755 index 00000000..67fb14b3 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/mme/mme_init.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +export IP_ADDR=$(awk 'END{print $1}' /etc/hosts) +export IF_NAME=$(ip r | awk '/default/ { print $5 }') + +[ ${#MNC} == 3 ] && EPC_DOMAIN="epc.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || EPC_DOMAIN="epc.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" + +cp /mnt/mme/mme.yaml install/etc/open5gs +cp /mnt/mme/mme.conf install/etc/freeDiameter +cp /mnt/mme/make_certs.sh install/etc/freeDiameter + +sed -i 's|MNC|'$MNC'|g' install/etc/open5gs/mme.yaml +sed -i 's|MCC|'$MCC'|g' install/etc/open5gs/mme.yaml +sed -i 's|MME_IP|'$MME_IP'|g' install/etc/open5gs/mme.yaml +sed -i 's|MME_IF|'$IF_NAME'|g' install/etc/open5gs/mme.yaml +sed -i 's|OSMOMSC_IP|'$OSMOMSC_IP'|g' install/etc/open5gs/mme.yaml +sed -i 's|SGWC_IP|'$SGWC_IP'|g' install/etc/open5gs/mme.yaml +sed -i 's|SMF_IP|'$SMF_IP'|g' install/etc/open5gs/mme.yaml +sed -i 's|MAX_NUM_UE|'$MAX_NUM_UE'|g' install/etc/open5gs/mme.yaml +sed -i 's|MME_IP|'$MME_IP'|g' install/etc/freeDiameter/mme.conf +sed -i 's|HSS_IP|'$HSS_IP'|g' install/etc/freeDiameter/mme.conf +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' install/etc/freeDiameter/mme.conf +sed -i 's|HSS_BIND_PORT|'$HSS_BIND_PORT'|g' install/etc/freeDiameter/mme.conf +sed -i 's|LD_LIBRARY_PATH|'$LD_LIBRARY_PATH'|g' install/etc/freeDiameter/mme.conf +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' install/etc/freeDiameter/make_certs.sh + +# Generate TLS certificates +./install/etc/freeDiameter/make_certs.sh install/etc/freeDiameter + +# Sync docker time +#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone diff --git a/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel6.xsd b/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel6.xsd new file mode 100644 index 00000000..3eb21b74 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel6.xsd @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + iFC is part of the registered profile + + + + + + + + iFC is part of the unregistered profile + + + + + + + + + + + + + + + + + + + + + + + Matches to REGISTER messages that are related to initial registration + + + + + + + + Matches to REGISTER messages that are related to re-registration + + + + + + + + Matches to REGISTER messages that are related to de-registration + + + + + + + + + + + + + Session Continued + + + + + + + + Session Terminated + + + + + + + + + + + + + Originating Session + + + + + + + + Terminating Session for registered user + + + + + + + + Terminating Session for unregistered user + + + + + + + + + + + + + + + + + + + + + + + + + + Identity is a Public User Identity. + + + + + + + + Identity is a distinct Public Service Identity. + + + + + + + + Identity matches a wildcarded Public Service Identity. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel7.xsd b/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel7.xsd new file mode 100644 index 00000000..b9289e27 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel7.xsd @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + iFC is part of the registered profile + + + + + + + + iFC is part of the unregistered profile + + + + + + + + + + + + + + + + + + + + + + + Matches to REGISTER messages that are related to initial registration + + + + + + + + Matches to REGISTER messages that are related to re-registration + + + + + + + + Matches to REGISTER messages that are related to de-registration + + + + + + + + + + + + + Session Continued + + + + + + + + Session Terminated + + + + + + + + + + + + + Originating Session + + + + + + + + Terminating Session for registered user + + + + + + + + Terminating Session for unregistered user + + + + + + + + Originating Session for an unregistered user + + + + + + + + + + + + + + + + + + + + + + + + + + Identity is a Public User Identity. + + + + + + + + Identity is a distinct Public Service Identity. + + + + + + + + Identity matches a wildcarded Public Service Identity. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel8.xsd b/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel8.xsd new file mode 100644 index 00000000..2e057eb2 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/CxDataType_Rel8.xsd @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + iFC is part of the registered profile + + + + + + + + iFC is part of the unregistered profile + + + + + + + + + + + + + + + + + + + + + + + Matches to REGISTER messages that are related to initial registration + + + + + + + + Matches to REGISTER messages that are related to re-registration + + + + + + + + Matches to REGISTER messages that are related to de-registration + + + + + + + + + + + + + Session Continued + + + + + + + + Session Terminated + + + + + + + + + + + + + Originating Session + + + + + + + + Terminating Session for registered user + + + + + + + + Terminating Session for unregistered user + + + + + + + + Originating Session for an unregistered user + + + + + + + + + + + + + + + + + + + + + + + + + + Identity is a Public User Identity. + + + + + + + + Identity is a distinct Public Service Identity. + + + + + + + + Identity matches a wildcarded Public Service Identity. + + + + + + + + Identity is a Wildcarded Public User Identity. + + + + + + + + Identity is a Wildcard for Public User Identities. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/custom_deployments/open5gs_hss_cx/scscf/dispatcher.list b/custom_deployments/open5gs_hss_cx/scscf/dispatcher.list new file mode 100644 index 00000000..7e4bb16f --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/dispatcher.list @@ -0,0 +1 @@ +# ng-voice Interconnect diff --git a/custom_deployments/open5gs_hss_cx/scscf/kamailio_scscf.cfg b/custom_deployments/open5gs_hss_cx/scscf/kamailio_scscf.cfg new file mode 100644 index 00000000..6e868a7c --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/kamailio_scscf.cfg @@ -0,0 +1,1276 @@ +#!KAMAILIO +# +# This config file implements the basic P-CSCF functionality +# - web: http://www.kamailio.org +# - git: http://sip-router.org +# +# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php +# for an explanation of possible statements, functions and parameters. +# +# Direct your questions about this file to: . +# +# For more information about the various parameters, functions and statements +# try http://sip-router.org/wiki/ . +# + +####### Defined Values ######### +# *** Value defines - IDs used later in config + +# - flags +# FLT_ - per transaction (message) flags +# FLB_ - per branch flags + +#!define FLT_CAPTURE 1 +#!define FLT_DIALOG 2 + +#!define DLG_TIMEOUT_AVP "i:1" +#!define RR_CUSTOM_USER_AVP "i:2" +#!define DISPATCHER_DST_AVP "i:3" +#!define DISPATCHER_GRP_AVP "i:4" +#!define DISPATCHER_CNT_AVP "i:5" +#!define DISPATCHER_SOCK_AVP "i:6" + +####### Global Parameters ######### + +include_file "scscf.cfg" + +#!ifdef WITH_DEBUG +debug=5 +log_stderror=no +sip_warning=yes +#!else +debug=2 +log_stderror=no +sip_warning=no +#!endif + +#!ifdef WITH_XMLRPC +listen=tcp:127.0.0.1:6060 +#!endif + +alias=HOSTNAME + +user_agent_header="User-Agent: Kamailio S-CSCF" +server_header="Server: Kamailio S-CSCF" + +/* comment the next line to enable the auto discovery of local aliases + based on reverse DNS on IPs (default on) */ +auto_aliases=no + +check_via=no # (cmd. line: -v) +dns=no # (cmd. line: -r) +rev_dns=no # (cmd. line: -R) + +# Do SRV-Loadbalancing: +dns_srv_lb=on +# Always: Also try IPv6: +dns_try_ipv6=on +# Always prefer IPv6: +dns_cache_flags=4 +# DNS-Based failover +use_dns_failover=on +# Query NAPTR-Records as well: +dns_try_naptr=on +# DNS cache won't be used (all dns lookups will result into a DNS request) +use_dns_cache=off + +#!ifdef WITH_XMLRPC +#!ifndef WITH_TCP +#!define WITH_TCP +#!endif +#!ifndef TCP_PROCESSES +# Number of TCP Processes +#!define TCP_PROCESSES 3 +#!endif +#!endif + +#!ifdef WITH_TCP +# life time of TCP connection when there is no traffic +# - a bit higher than registration expires to cope with UA behind NAT +tcp_connection_lifetime=3615 +#!ifdef TCP_PROCESSES +tcp_children=TCP_PROCESSES +#!endif +#!else +disable_tcp=yes +#!endif + +children=4 + +system.shutdownmode = 0 desc "System shutdown mode" +system.service = "Serving-CSCF" desc "Function of this server" + +# ------------------ module loading ---------------------------------- +mpath="/usr/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/:/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/:/usr/lib/x86_64-linux-gnu/kamailio/modules/:/usr/local/lib64/kamailio/modules" +# (we try both the lib64 and the lib directory) + +loadmodule "tm.so" +loadmodule "pv.so" +loadmodule "sl.so" +loadmodule "rr.so" +loadmodule "ims_dialog.so" +loadmodule "textops.so" +loadmodule "textopsx.so" +loadmodule "maxfwd.so" +loadmodule "xlog.so" +loadmodule "sanity.so" +loadmodule "siputils.so" +loadmodule "kex.so" +loadmodule "tmx.so" +loadmodule "pike.so" +#!ifdef DB_URL +loadmodule "presence" +#!endif + +#!ifdef DB_URL +loadmodule "db_mysql" +#!ifdef DB_URL2 +loadmodule "db_cluster" +#!endif +#!endif + +loadmodule "dispatcher" + +loadmodule "enum" +loadmodule "uac" + +# Control interfaces: +loadmodule "ctl" +loadmodule "cfg_rpc" +#!ifdef WITH_XMLRPC +loadmodule "xmlrpc" +#!endif + +loadmodule "cdp.so" +loadmodule "cdp_avp.so" + +loadmodule "ims_usrloc_scscf.so" +loadmodule "ims_registrar_scscf.so" +loadmodule "ims_auth.so" +loadmodule "ims_isc.so" + +#!ifdef WITH_RO +loadmodule "ims_charging.so" +#!endif + +#!ifdef CAPTURE_NODE +loadmodule "siptrace.so" +#!endif + +##!ifdef WITH_DEBUG +loadmodule "debugger.so" +modparam("debugger", "mod_hash_size", 5) +modparam("debugger", "mod_level_mode", 1) +modparam("debugger", "mod_level", "ims_usrloc_scscf=3") +modparam("debugger", "mod_level", "ims_registrar_scscf=3") +modparam("debugger", "mod_level", "ims_auth=3") +modparam("debugger", "mod_level", "ims_isc=3") +modparam("debugger", "mod_level", "ims_dialog=3") +modparam("debugger", "mod_level", "ims_charging=3") +##!endif + +# ----------------- setting module-specific parameters --------------- +#!ifdef DB_URL2 +# ----- db_cluster params ----- +modparam("db_cluster", "connection", DB_URL) +modparam("db_cluster", "connection", DB_URL2) +modparam("db_cluster", "cluster", "cluster1=>con1=2s2s;con2=1s1s") +#!endif + +# ----- presence params ----- +#!ifdef DB_URL +#!ifdef DB_URL2 +modparam("presence", "db_url", "cluster://cluster1") +#!else +modparam("presence", "db_url", DB_URL) +#!endif +#modparam("presence", "fallback2db", 1) +modparam("presence", "db_update_period", 20) +#!endif + +loadmodule "jsonrpcs.so" +# ----- jsonrpcs params ----- +modparam("jsonrpcs", "pretty_format", 1) +/* set the path to RPC fifo control file */ +modparam("jsonrpcs", "fifo_name", "/var/run/kamailio/kamailio_rpc.fifo") +/* set the path to RPC unix socket control file */ +modparam("jsonrpcs", "dgram_socket", "/var/run/kamailio/kamailio_rpc.sock") + +# ----- ctl params ----- +modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl") + +# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 10sec +modparam("tm", "fr_timer", 10000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000) +# Don't reply automatically with "100 Trying" +modparam("tm", "auto_inv_100", 0) + +# ----- rr params ----- +# add value to ;lr param to cope with most of the UAs +modparam("rr", "enable_full_lr", 1) +# append from tag to the RR +modparam("rr", "append_fromtag", 1) +# add a Username to RR-Header +modparam("rr", "add_username", 1) +# Take User from a custom AVP +modparam("rr", "custom_user_avp", "$avp(RR_CUSTOM_USER_AVP)") + +# -- usrloc params -- +modparam("ims_usrloc_scscf", "enable_debug_file", 0) +modparam("ims_usrloc_scscf", "matching_mode", 0) +modparam("ims_usrloc_scscf", "maxcontact", 5) +modparam("ims_usrloc_scscf", "maxcontact_3gpp", 5) +modparam("ims_registrar_scscf", "max_contacts", 5) +modparam("ims_usrloc_scscf", "maxcontact_behaviour", 2) #overwrite +#!ifdef DB_URL +#!ifdef DB_URL2 +modparam("ims_usrloc_scscf", "db_url", "cluster://cluster1") +#!else +modparam("ims_usrloc_scscf", "db_url", DB_URL) +#!endif +modparam("ims_usrloc_scscf", "db_mode", 0) +#!endif +modparam("ims_registrar_scscf", "subscription_default_expires", 654800) +modparam("ims_registrar_scscf", "subscription_min_expires", 3700) +modparam("ims_registrar_scscf", "subscription_max_expires", 605800) + +# -- CDP params -- +modparam("cdp","config_file","/etc/kamailio_scscf/scscf.xml") + +# -- ims_dialog params -- +modparam("ims_dialog", "dlg_flag", FLT_DIALOG) +modparam("ims_dialog", "timeout_avp", "$avp(DLG_TIMEOUT_AVP)") +modparam("ims_dialog", "detect_spirals", 0) +modparam("ims_dialog", "profiles_no_value", "orig ; term") +#!ifdef DB_URL +#!ifdef DB_URL2 +modparam("ims_dialog", "db_url", "cluster://cluster1") +#!else +modparam("ims_dialog", "db_url", DB_URL) +#!endif +modparam("ims_dialog", "db_mode", 0) +#!endif + +#!ifdef WITH_XMLRPC +# ----- xmlrpc params ----- +modparam("xmlrpc", "route", "XMLRPC"); +modparam("xmlrpc", "url_match", "^/RPC") +#!endif + +#!ifdef WITH_DEBUG +# ----- debugger params ----- +modparam("debugger", "cfgtrace", 1) +#!endif + +#!ifdef CAPTURE_NODE +# Destination, where to send the traffic +modparam("siptrace", "duplicate_uri", CAPTURE_NODE) +# Trace all traffic +modparam("siptrace", "trace_on", 1) +modparam("siptrace", "trace_to_database", 0) +modparam("siptrace", "trace_flag", FLT_CAPTURE) +modparam("siptrace", "hep_mode_on", 1) +#!endif + +# -- ims_auth params -- +modparam("ims_auth", "name", URI) +modparam("ims_auth", "registration_default_algorithm", REG_AUTH_DEFAULT_ALG) +#!ifdef CXDX_FORCED_PEER +modparam("ims_auth", "cxdx_forced_peer", CXDX_FORCED_PEER) +#!endif +modparam("ims_auth", "cxdx_dest_realm", EPC_REALM) +modparam("ims_auth", "av_check_only_impu", 1) + +modparam("ims_auth", "max_nonce_reuse", 20) +modparam("ims_auth", "auth_vector_timeout", 60) +modparam("ims_auth", "auth_data_timeout", 600000) +modparam("ims_auth", "auth_used_vector_timeout", 600000) +modparam("ims_auth", "av_request_at_once", 1) +modparam("ims_auth", "av_request_at_sync", 1) +modparam("ims_auth", "registration_qop", "auth") + +# -- ims_registrar_scscf params -- +#!ifdef WITH_DEBUG +modparam("ims_registrar_scscf", "default_expires", 60) +modparam("ims_registrar_scscf", "min_expires", 60) +modparam("ims_registrar_scscf", "max_expires", 60) +#!else +modparam("ims_registrar_scscf", "default_expires", 604800) +modparam("ims_registrar_scscf", "min_expires", 60) +modparam("ims_registrar_scscf", "max_expires", 604800) +#!endif +modparam("ims_registrar_scscf", "use_path", 1) +modparam("ims_registrar_scscf", "support_wildcardPSI",1) +modparam("ims_registrar_scscf", "user_data_xsd","/etc/kamailio_scscf/CxDataType_Rel7.xsd") +modparam("ims_registrar_scscf", "scscf_name", URI) +modparam("ims_registrar_scscf", "scscf_name", URI) +modparam("ims_registrar_scscf", "cxdx_dest_realm", EPC_REALM) +modparam("ims_registrar_scscf", "append_branches", 1) +modparam("ims_registrar_scscf", "user_data_always", 0) +modparam("ims_registrar_scscf", "ue_unsubscribe_on_dereg", 1) + +#!ifdef WITH_MULTIDOMAIN +# ----- domain params ----- +#!ifdef DB_URL +#!ifdef DB_URL2 +modparam("domain", "db_url", "cluster://cluster1") +#!else +modparam("domain", "db_url", DB_URL) +#!endif +modparam("domain", "db_mode", 1) +#!endif +# register callback to match myself condition with domains list +modparam("domain", "register_myself", 1) +#!endif + +# ----- ims_isc params ----- +modparam("ims_isc", "my_uri", HOSTNAME) +modparam("ims_isc", "add_p_served_user", 1) + +#!ifdef WITH_RO +# ----- ims_diameter_ro params ----- +#!ifdef DB_URL +#!ifdef DB_URL2 +#modparam("ims_charging", "db_url", "cluster://cluster1") +#!else +#modparam("ims_charging", "db_url", DB_URL) +#!endif +#modparam("ims_charging", "db_mode", 1) +#!endif +modparam("ims_charging", "origin_host", HOSTNAME); +modparam("ims_charging", "origin_realm", NETWORKNAME); +#!ifdef RO_FORCED_PEER +modparam("ims_charging", "ro_forced_peer", RO_FORCED_PEER); +#!endif +modparam("ims_charging", "destination_host", RO_DESTINATION); +modparam("ims_charging", "destination_realm", NETWORKNAME); + +modparam("ims_charging","service_context_id_root", RO_ROOT); +modparam("ims_charging","service_context_id_ext", RO_EXT); +modparam("ims_charging","service_context_id_mnc", RO_MNC); +modparam("ims_charging","service_context_id_mcc", RO_MCC); +modparam("ims_charging","service_context_id_release", RO_RELEASE); + +modparam("ims_charging","interim_update_credits",30); +modparam("ims_charging","timer_buffer",5); +#!endif + +# ----- enum params ----- +modparam("enum", "domain_suffix", ENUM_SUFFIX) + +# ----- sanity params ----- +modparam("sanity", "autodrop", 0) + +# ----------------- Settings for Dispatcher --------------- +modparam("dispatcher", "list_file", "/etc/kamailio_scscf/dispatcher.list") +# Dispatcher: Enable Failover-Support +modparam("dispatcher", "flags", 2) +# Dispatcher: Overwrite Destination address, if required. +modparam("dispatcher", "force_dst", 1) +# AVP's required for Fail-Over-Support: +#modparam("dispatcher", "dst_avp", "$avp(DISPATCHER_DST_AVP)") +#modparam("dispatcher", "grp_avp", "$avp(DISPATCHER_GRP_AVP)") +#modparam("dispatcher", "cnt_avp", "$avp(DISPATCHER_CNT_AVP)") +#modparam("dispatcher", "sock_avp", "$avp(DISPATCHER_SOCK_AVP)") + +#modparam("dispatcher", "xavp_dst", "$avp(DISPATCHER_DST_AVP)") +#modparam("dispatcher", "xavp_dst_mode", 0) +#modparam("dispatcher", "xavp_ctx", "$avp(DISPATCHER_CNT_AVP)") +#modparam("dispatcher", "xavp_ctx_mode", 0) + +# Try to recover disabled destinations every 15 seconds. +modparam("dispatcher", "ds_ping_interval", 15) +# Actively query the gateways: +modparam("dispatcher", "ds_probing_mode", 1) +modparam("dispatcher", "ds_ping_reply_codes", "class=2;code=404;code=480") + +####### Routing Logic ######## +# Main SIP request routing logic +# - processing of any incoming SIP request starts with this route + +route { +##!ifdef WITH_DEBUG + xnotice("SCSCF: $rm $ru ($fu ($si:$sp) to $tu, $ci)\n"); +##!endif + + # per request initial checks + route(REQINIT); + + # Handle Registrations: + if (is_method("REGISTER")) { + route(REGISTER); + exit; + } + + # we need to support subscription to reg event + if (is_method("SUBSCRIBE") && search("^(Event|o)([ \t]*):([ \t]*)reg")) { + route(SUBSCRIBE); + break; + } + + if (is_method("PUBLISH") && search("^(Event|o)([ \t]*):([ \t]*)reg")) { + route(PUBLISH); + break; + } + + # Evaluate Route-Header and set $route_uri + loose_route(); + + if (is_method("CANCEL|ACK")) { + t_relay(); + exit; + } + + #Set DLG flag to track dialogs using dialog2 + if (!is_method("REGISTER|SUBSCRIBE")) + setflag(FLT_DIALOG); + + if (($route_uri =~ "sip:orig@.*") || ($route_uri =~ "sip:orig@"+HOSTNAME_ESC+".*") || isc_from_as("orig")) { + xlog("Orig"); + # we need something like this to assign SCSCF to unregistered user for services + # support for AS origination on behalf of unregistered useri + # can use the registrar is_registered methods - must see if we need to check orig or term? + + # Sanitize the R-URI if domain is present in from of @MSISDN of caller + # What in case of Roaming? - Need to handle it + # if ($ru =~ ".*phone-context.*") { + # if ($ru =~ "tel:.*") { + # # Handle following request-uri + # # tel:0498765432100;phone-context=ims.mnc001.mcc001.3gppnetwork.org + # $ru = $(ru{re.subst,/tel:/sip:/g}); + # } + # # Now in sip: uri format + # if ($ru =~ ".*@.*") { + # $ru = $(ru{re.subst,/@[0-9+-]*;user=phone/@NETWORKNAME;user=phone/g}); + # #$ru = $(ru{re.subst,/;phone-context=[A-Za-z.0-9+-]*@/;phone-context=NETWORKNAME@/g}); + # } else { + # $ru = $ru + "@" + NETWORKNAME + ";user=phone"; + # #$ru = $(ru{re.subst,/;phone-context=[A-Za-z.0-9+-]*@/;phone-context=NETWORKNAME@/g}); + # } + # } + if (!is_method("REGISTER|SUBSCRIBE")) { + # sip:xxx;phone-context=xxxx@xxx format is not desired + if (($ru =~ ".*phone-context.*") && ($ru =~ "sip:.*")) { + $var(old_ruri) = $ru; + $ru = $(ru{re.subst,/sip:/tel:/g}); + $ru = $(ru{re.subst,/;phone-context=[A-Za-z.0-9+-@]*;user=phone//g}); + $ru = $ru + ";phone-context=" + NETWORKNAME; + msg_apply_changes(); + xnotice("SCSCF: Changed R-URI from $var(old_ruri) to $ru\n"); + } + } + + # Originating + route(orig); + break; + } else { + isc_from_as("term"); + if ($retcode == -2) { + # Treat as originating, since it was retargeted: + route(orig); + break; + } + if ((is_in_profile("orig") || has_totag()) && ($route_uri =~ "sip:mo@"+".*")) { + route(orig_subsequent); + break; + } + if ((is_in_profile("term") || has_totag()) && ($route_uri =~ "sip:mt@"+".*")) { + route(term_subsequent); + break; + } + + # Terminating + if (uri == myself || uri =~ "tel:.*") { + if (!term_impu_registered("location")) { + xlog("L_DBG", "We need to do an UNREG server SAR assignemnt"); + assign_server_unreg("UNREG_SAR_REPLY", "location", "term"); + exit; + } else { + sl_send_reply("403","Forbidden - Domain not served"); + exit(); + } + } + route(term); + break; + } +} + +route[UNREG_SAR_REPLY] +{ + xlog("L_DBG","saa_return code is $avp(s:saa_return_code)\n"); + switch ($avp(s:saa_return_code)){ + case 1: #success + xlog("L_DBG", "SAR success - will route message\n"); + route(term); + break; + case -1: #failure + xlog("L_ERR", "SAR failure - error response sent from module\n"); + break; + case -2: #error + xlog("L_ERR", "SAR error - error response sent from module\n"); + break; + default: + xlog("L_ERR", "Unknown return code from SAR, value is [$avp(s:saa_return_code)]\n"); + break; + } + exit; +} + + +###################################################################### +# Helper routes (Basic-Checks, NAT-Handling/RTP-Control, XML-RPC) +###################################################################### +# Per SIP request initial checks +route[REQINIT] { + $var(used) = 1 - ($stat(free_size) / $stat(total_size)); + xlog("L_DBG", "Mem: Total $stat(total_size), Free $stat(free_size) [$var(used)% used]\n"); + if ($var(used) > 95) { + send_reply("503", "Server overloaded"); + exit; + } + + # Trace this message +#!ifdef CAPTURE_NODE + sip_trace(); + setflag(FLT_CAPTURE); +#!endif + + if (!mf_process_maxfwd_header("10")) { + sl_send_reply("483","Too Many Hops"); + exit; + } + + if(!sanity_check("1511", "7")) { + xlog("Malformed SIP message from $si:$sp\n"); + exit; + } + + # Check for shutdown mode: + if (!has_totag() && ($sel(cfg_get.system.shutdownmode) > 0)) { + send_reply("503", "Server shutting down"); + exit; + } + + # Reply to OPTIONS: + if (is_method("OPTIONS") && (uri==myself)) { + options_reply(); + exit; + } + + # Ignore Re-Transmits: + if (t_lookup_request()) { + exit; + } + if (is_method("INVITE")) { + send_reply("100", "Trying"); + } + +} + + +###################################################################### +# Publish route +###################################################################### +route[PUBLISH] +{ + if (!t_newtran()) { + #absorb retransmissions + sl_reply("500","Could not create transaction"); + exit; + } + + if (can_publish_reg("location")) { + $var(ret)= publish_reg("location"); + switch ($var(ret)){ + case 1: #success + xlog("L_DBG", "Publish reg successful"); + break; + case -1: #failure + xlog("L_ERR", "Publish reg failure - sending 500 Error now\n"); + t_reply("500","Server Error publishing subscription"); + break; + default: + xlog("L_ERR", "Unknown return code from publish reg event alue is [$var(ret)]\n"); + break; + } + } else { + t_reply("403","Forbidden to PUBLISH"); + exit; + } +} + +###################################################################### +# Subscribe route +###################################################################### +route[SUBSCRIBE] +{ + if (!t_newtran()) { + #absorb retransmissions + sl_reply("500","Could not create transaction"); + exit; + } + + if (!has_totag()) { + xlog("L_DBG", "This is an initial SUBSCRIBE\n"); + if (!term_impu_registered("location")) { + xlog("L_DBG", "We need to do an UNREG server SAR assignment\n"); + assign_server_unreg("SUBSCRIBE_UNREG_SAR_REPLY", "location", "term"); + exit; + } + if (!can_subscribe_to_reg("location")){ + t_reply("403","Forbidden to SUBSCRIBE"); + exit; + } + }else{ + xlog("L_DBG", "This is a subsequent SUBSCRIBE\n"); + } + + $var(ret)= subscribe_to_reg("location"); + switch ($var(ret)){ + case 1: #success + xlog("L_DBG", "Subscribe to reg successful"); + break; + case -1: #failure + xlog("L_ERR", "Subscribe to reg failure - sending 500 Error now\n"); + t_reply("500","Server Error saving subscription"); + break; + case -2: #error + xlog("L_ERR", "Subscribe to reg error sending notify - 200 OK so subscription already sent\n"); + break; + default: + xlog("L_ERR", "Unknown return code from subscribe to reg event alue is [$var(ret)]\n"); + break; + } +} + +route[SUBSCRIBE_UNREG_SAR_REPLY] +{ + + xlog("L_DBG","saa_return code is $avp(s:saa_return_code)\n"); + switch ($avp(s:saa_return_code)){ + case 1: #success + xlog("L_DBG", "SAR success - will process subscribe\n"); + if (can_subscribe_to_reg("location")){ + $var(ret)= subscribe_to_reg("location"); + switch ($var(ret)){ + case 1: #success + xlog("L_DBG", "Subscribe to reg successful"); + break; + case -1: #failure + xlog("L_ERR", "Subscribe to reg failure - sending 500 Error now\n"); + t_reply("500","Server Error saving subscription"); + break; + case -2: #error + xlog("L_ERR", "Subscribe to reg error sending notify - 200 OK so subscription already sent\n"); + break; + default: + xlog("L_ERR", "Unknown return code from subscribe to reg event alue is [$var(ret)]\n"); + break; + } + }else{ + t_reply("403","Forbidden to SUBSCRIBE"); + exit; + } + break; + case -1: #failure + xlog("L_ERR", "SAR failure - Sending 403 Forbidden\n"); + t_reply("403","Forbidden to SUBSCRIBE"); + break; + case -2: #error + xlog("L_ERR", "SAR error - Sending 403 Forbidden\n"); + t_reply("403","Forbidden to SUBSCRIBE"); + break; + default: + xlog("L_ERR", "Unknown return code from SAR, value is [$avp(s:saa_return_code)] - sending 403 Forbidden\n"); + t_reply("403","Forbidden to SUBSCRIBE"); + break; + } + exit; +} + +###################################################################### +# XMLRPC routing +###################################################################### +#!ifdef WITH_XMLRPC +route[XMLRPC] { + if ((method=="POST" || method=="GET") +#!ifdef XMLRPC_WHITELIST_1 +&& ((src_ip == XMLRPC_WHITELIST_1) +#!ifdef XMLRPC_WHITELIST_2 + || (src_ip == XMLRPC_WHITELIST_2) +#!endif +#!ifdef XMLRPC_WHITELIST_3 + || (src_ip == XMLRPC_WHITELIST_3) +#!endif +) +#!endif +) { + # close connection only for xmlrpclib user agents (there is a bug in + # xmlrpclib: it waits for EOF before interpreting the response). + if ($hdr(User-Agent) =~ "xmlrpclib") + set_reply_close(); + set_reply_no_connect(); + dispatch_rpc(); + exit; + } + send_reply("403", "Forbidden"); + exit; +} +#!endif + +###################################################################### +# Route for handling Registrations: +###################################################################### +route[REGISTER] { + xnotice("ALGORITHM IS [$aa] and User-Agent is [$ua]\n"); + $var(alg) = $aa; + if ($aa == $null) { + $var(alg) = "MD5"; #force to MD5 for zoiper.... non-ims + } +#!ifdef WITH_AUTH + if (!ims_www_authenticate("$td")) { +#!else + if (($var(alg) == "MD5") && (!ims_www_authenticate("$td"))) { +#!endif + if ($? == -2) { + send_reply("403", "Authentication Failed"); + exit; + } else if ($? == -3) { + send_reply("400", "Bad Request"); + exit; + } else if ($? == -9) { + xlog("L_DBG", "Authentication re-sync requested\n"); + ims_www_resync_auth("REG_RESYNC_REPLY", "$td"); + exit; + } else { + #user has not been authenticated. Lets send a challenge via 401 Unauthorized + xlog("L_DBG","About to challenge! auth_ims\n"); + ims_www_challenge("REG_MAR_REPLY", "$td", "$var(alg)"); + exit; + } + } else { + xlog("L_DBG", "Auth succeeded\n"); + # We need to check if this user is registered or not + if (!impu_registered("location")) { + xlog("L_ERR", "Not REGISTERED\n"); + save("PRE_REG_SAR_REPLY","location"); + exit; + } else { + isc_match_filter_reg("1","location"); + save("REG_SAR_REPLY","location"); + exit; + } + } +} + +route[REG_MAR_REPLY] +{ + #this is async so to know status we have to check the reply avp + xlog("L_DBG","maa_return code is $avp(s:maa_return_code)\n"); + + switch ($avp(s:maa_return_code)){ + case 1: #success + xlog("L_DBG", "MAR success - 401/407 response sent from module\n"); + break; + case -1: #failure + xlog("L_ERR", "MAR failure - error response sent from module\n"); + break; + case -2: #error + xlog("L_ERR", "MAR error - sending error response now\n"); + send_reply("500", "MAR failed"); + break; + default: + xlog("L_ERR", "Unknown return code from MAR, value is [$avp(s:maa_return_code)]\n"); + send_reply("500", "Unknown response code from MAR"); + break; + } + exit; +} + +route[PRE_REG_SAR_REPLY] +{ + xlog("L_DBG","saa_return code is $avp(s:saa_return_code)\n"); + #this is async so to know status we have to check the reply avp + xlog("L_DBG","saa_return code (for scscf_save on register) is $avp(s:saa_return_code)\n"); + switch ($avp(s:saa_return_code)){ + case 1: #success + xlog("L_DBG", "SAR success - 200 response sent from module\n"); + isc_match_filter_reg("0","location"); + exit; + case -1: #failure + xlog("L_ERR", "SAR failure - error response sent from module\n"); + break; + case -2: #error + xlog("L_ERR", "SAR error - error response sent from module\n"); + break; + default: + xlog("L_ERR", "Unknown return code from SAR, value is [$avp(s:saa_return_code)]\n"); + break; + } + exit; +} + +route[REG_SAR_REPLY] +{ + xlog("L_DBG","saa_return code is $avp(s:saa_return_code)\n"); + #this is async so to know status we have to check the reply avp + xlog("L_DBG","saa_return code (for scscf_save on register) is $avp(s:saa_return_code)\n"); + switch ($avp(s:saa_return_code)){ + case 1: #success + xlog("L_DBG", "SAR success - 200 response sent from module\n"); + exit; + case -1: #failure + xlog("L_ERR", "SAR failure - error response sent from module\n"); + break; + case -2: #error + xlog("L_ERR", "SAR error - error response sent from module\n"); + break; + default: + xlog("L_ERR", "Unknown return code from SAR, value is [$avp(s:saa_return_code)]\n"); + break; + } + exit; +} + +route[REG_RESYNC_REPLY] +{ + ims_www_challenge("REG_MAR_REPLY", "$td"); +} + +###################################################################### +# Apply privacy, if requested +###################################################################### +route[apply_privacy] +{ + if (is_present_hf("Privacy") && ($hdr(Privacy)=="id")) { + remove_hf("P-Asserted-Identity"); + } +} + +###################################################################### +# Originating, Intial Requests +###################################################################### +route[orig] +{ + xlog("L_DBG","Enter orig route\n"); + set_dlg_profile("orig"); + + # we MAYBE need something like this to check if a user is barred + # if (S_originating_barred()){ + # sl_send_reply("403","Forbidden - Originating Public Identity barred"); + # exit; + # } + + if (is_method("INVITE|SUBSCRIBE")) { + $avp(RR_CUSTOM_USER_AVP)="mo"; + record_route(); + } + + # Start new transaction: + t_newtran(); + + # check if dialog saved as fwded to AS + if (isc_match_filter("orig", "location")) { + t_on_failure("isc_orig_failure"); + xlog("Orig - msg was fwded to AS\n"); + exit; + } + + if (!isc_from_as("orig")) { + remove_hf("P-Asserted-Identity"); + append_hf("P-Asserted-Identity: \r\n"); + } + +#!ifdef WITH_RO + # before we allow call - lets check credit + if (is_method("INVITE")) { + xlog("L_DBG","Sending initial CCR Request for call\n"); + $var(cc_ret) = Ro_CCR("CHARGING_CCR_ORIG_REPLY", "orig", 30, "0", "0"); + if ($var(cc_ret) < 0) { + xlog("L_ERR","CCR Request failure\n"); + sl_send_reply("402","Payment required"); + exit; + } + xlog("L_DBG","CCR Request success\n"); + exit; + } +#!endif + route(FINAL_ORIG); +} + +route[FINAL_ORIG] +{ + # Check for PSTN destinations: + if (is_method("INVITE")) { + route(PSTN_handling); + } + + t_on_reply("orig_reply"); + + t_relay(); +} + +route[CHARGING_CCR_ORIG_REPLY] +{ + xlog("L_DBG","cca_return code is $avp(s:cca_return_code)\n"); + + switch ($avp(s:cca_return_code)){ + case 1: #success + xlog("L_DBG", "CCR success - will route message\n"); + route(FINAL_ORIG); + break; + case -1: #failure + xlog("L_ERR", "CCR failure - error response sent from module\n"); + switch ($avp(s:cca_result_code)){ + case 5030: + send_reply("403", "Charging User not found"); + break; + case 5031: + send_reply("403", "Rating failed"); + break; + case 4010: + send_reply("402", "Payment required - Unsufficient funds"); + break; + case 5006: + send_reply("486", "Line limit exceeded"); + break; + default: + send_reply("402","Payment required ($avp(s:cca_result_code))"); + break; + } + case -2: #error + xlog("L_ERR", "CCR error - error response sent from module\n"); + send_reply("500", "Charging Error"); + break; + default: + xlog("L_ERR", "Unknown return code from CCR: [$avp(s:cca_return_code)] \n"); + send_reply("500", "Charging Error"); + break; + } + exit; +} + + +###################################################################### +# Replies to the Initial Requests +###################################################################### +onreply_route[orig_reply] +{ + xlog("L_DBG","Orig reply\n"); + + route(apply_privacy); + break; +} + +###################################################################### +# Originating, subsequent requests +###################################################################### +route[orig_subsequent] +{ + xlog("L_DBG","Orig_Subsequent\n"); + + if (!is_method("ACK")) { + t_on_reply("orig_subsequent_reply"); + } + t_relay(); +} + +###################################################################### +# Replies for originating, subsequent requests +###################################################################### +onreply_route[orig_subsequent_reply] +{ + xlog("L_DBG","Orig_Subsequent_reply\n"); + route(apply_privacy); + break; +} + +###################################################################### +# Failure-Route for Requests to an AS +###################################################################### +failure_route[isc_orig_failure] +{ + xlog("L_DBG","ISC_Orig_failure\n"); + + if (t_check_status("(408)|(5..)")){ + t_on_failure("isc_orig_failure"); + if (isc_match_filter("orig","location")){ + xlog("L_DBG","ISC_Orig_failure - msg was fwded to AS\n"); + exit; + } + + if (isc_from_as("origfail")) { + remove_hf("P-Asserted-Identity"); + append_hf("P-Asserted-Identity: \r\n"); + } + + t_on_reply("orig_reply"); + + t_relay(); + } +} + +###################################################################### +# Terminating requests +###################################################################### +route[term] +{ + xlog("L_DBG","Term\n"); + + set_dlg_profile("term"); + + #we need something like this to check if a user is barred + # if (S_terminating_barred()){ + # sl_send_reply("404","Not Found - Terminating user barred"); + # exit; + # } + + if (is_method("INVITE|SUBSCRIBE")) { + $avp(RR_CUSTOM_USER_AVP)="mt"; + $avp(i:20)="mt"; + record_route(); + } + + # check if dialog saved as fwded to AS + if (isc_match_filter("term","location")){ + t_on_failure("isc_term_failure"); + xlog("L_DBG","Term - msg was fwded to AS\n"); + exit; + } + +#!ifdef WITH_RO_TERM + # before we allow call - lets check credit + if (is_method("INVITE")) { + xlog("L_DBG","Sending initial CCR Request for call\n"); + $var(cc_ret) = Ro_CCR("CHARGING_CCR_TERM_REPLY", "term", 30, "0", "0"); + if ($var(cc_ret) < 0) { + xlog("L_ERR","CCR Request failure\n"); + sl_send_reply("402","Payment required"); + exit; + } + xlog("L_DBG","CCR Request success\n"); + exit; + } +#!endif + route(FINAL_TERM); +} + +route[FINAL_TERM] { + if (lookup("location")) { + if (uri==myself) { + if (!t_newtran()) { + sl_reply_error(); + exit; + } + t_reply("404","Not Found - destination user not found on this S-CSCF"); + exit; + } + } else { + # User not registered? Reply with 404. + if (!t_newtran()) { + sl_reply_error(); + exit; + } + t_reply("404","Not Found - destination user not found on this S-CSCF"); + exit; + } + route(apply_privacy); + + t_relay(); +} + + +route[CHARGING_CCR_TERM_REPLY] +{ + xlog("L_DBG","cca_return code is $avp(s:cca_return_code)\n"); + + switch ($avp(s:cca_return_code)){ + case 1: #success + xlog("L_DBG", "CCR success - will route message\n"); + route(FINAL_TERM); + break; + case -1: #failure + xlog("L_ERR", "CCR failure - error response sent from module\n"); + switch ($avp(s:cca_result_code)){ + case 5030: + send_reply("403", "Charging User not found"); + break; + case 5031: + send_reply("403", "Rating failed"); + break; + case 4010: + send_reply("402", "Payment required - Unsufficient funds"); + break; + case 5006: + send_reply("486", "Line limit exceeded"); + break; + default: + send_reply("402","Payment required ($avp(s:cca_result_code))"); + break; + } + case -2: #error + xlog("L_ERR", "CCR error - error response sent from module\n"); + send_reply("500", "Charging Error"); + break; + default: + xlog("L_ERR", "Unknown return code from CCR: [$avp(s:cca_return_code)] \n"); + send_reply("500", "Charging Error"); + break; + } + exit; +} + + +###################################################################### +# Failure Route for Terminating requests +###################################################################### +failure_route[isc_term_failure] +{ + xlog("L_DBG","ISC_term_failure\n"); + + if (t_check_status("(408)|(5..)")){ + t_on_failure("isc_term_failure"); + if (isc_match_filter("term","location")){ + xlog("L_DBG","Term - msg was fwded to AS\n"); + exit; + } + + if (lookup("location")) { + if (uri==myself) { + t_reply("404","Not Found - destination user not found on this S-CSCF"); + exit; + } + } else { + t_reply("404","Not Found - destination user not found on this S-CSCF"); + exit; + } + t_relay(); + } +} + +###################################################################### +# Terminating, subsequent requests +###################################################################### +route[term_subsequent] +{ + xlog("L_DBG","term_subsequent\n"); + route(apply_privacy); + t_relay(); +} + +###################################################################### +# Check for PSTN destinations: +###################################################################### +route[PSTN_handling] +{ + # First, we translate "tel:"-URI's to SIP-URI's: + # $ru: tel:+(34)-999-888-777 + # $fu: sip:test@foo.com + # becomes $ru: sip:+34999888777@foo.com;user=phone + if (tel2sip2("$ru", "$fd", "$ru") < 0) + xlog("L_WARN","Failed to convert $ru to a sip:-URI - M=$rm R=$ru F=$fu T=$tu IP=$si:$sp ID=$ci\n\n"); + + if ($rU =~ "\+[0-9]+") { + # Now let's check, if the number can be found in ENUM: + if(!enum_query()) { + # ENUM failed, send it to the PSTN-Gateway: + route(PSTN); + break; + } + } +} + +###################################################################### +# Send calls to the PSTN-Gateways: +###################################################################### +route[PSTN] +{ + $var(has_trf) = 0; + if (is_present_hf("Feature-Caps")) { + xlog("Feature-Caps: $hdr(Feature-Caps) => $(hdr(Feature-Caps){param.value,+g.3gpp.trf}{nameaddr.uri}{uri.host})\n"); + if ($(hdr(Feature-Caps){param.value,+g.3gpp.trf}) != $null) { + $rd = $(hdr(Feature-Caps){param.value,+g.3gpp.trf}{nameaddr.uri}{uri.host}); + if (!strempty($(ou{uri.params}))) { + $ru = $ru+";"+$(ou{uri.params}); + } + + t_on_failure("TRF_failure"); + if (t_relay_to("0x02")) { + $var(has_trf) = 1; + } else { + xlog("Relay to $du failed.\n"); + $du = $null; + } + } + } + + if ($var(has_trf) == 0) { + if (!ds_select_domain("1", "4")) { + xlog("L_WARN","No PSTN-Gateways available - M=$rm R=$ru F=$fu T=$tu IP=$si:$sp ID=$ci\n\n"); + send_reply("503", "Service not available"); + exit; + } + if (!strempty($(ou{uri.params}))) { + $ru = $ru+";"+$(ou{uri.params}); + } + t_relay(); + } + # Relay the request: + t_on_failure("PSTN_failure"); + + exit; +} + +###################################################################### +# manage failure routing cases, perform failover +###################################################################### +failure_route[TRF_failure] { + xlog("TRF_failure\n"); + # Choose another gateway, in case we + # - get a local generated "408" + # - receive a 5xx or 6xx reply from the proxy. + if (t_branch_timeout() || t_check_status("[5-6]..")) { + $du = $null; + if (!ds_select_domain("1", "4")) { + xlog("L_WARN","No PSTN-Gateways available - M=$rm R=$ru F=$fu T=$tu IP=$si:$sp ID=$ci\n\n"); + send_reply("503", "Service not available"); + exit; + } + if (!strempty($(ou{uri.params}))) { + $ru = $ru+";"+$(ou{uri.params}); + } + # Relay the request: + t_on_failure("PSTN_failure"); + + t_relay(); + exit; + } +} + +###################################################################### +# manage failure routing cases, perform failover +###################################################################### +failure_route[PSTN_failure] { + # Choose another gateway, in case we + # - get a local generated "408" + # - receive a 5xx or 6xx reply from the proxy. + if (t_branch_timeout() || t_check_status("[5-6]..")) { + if (ds_next_domain()) { + if (!strempty($(ou{uri.params}))) { + $ru = $ru+";"+$(ou{uri.params}); + } + # Do Failover in case problems: + t_on_failure("PSTN_failure"); + t_relay(); + } else { + # Add a header, to indicate the phone should try again in 30 seconds. + append_hf("Retry-After: 30\r\n"); + send_reply("503", "Service not available"); + } + exit; + } +} diff --git a/custom_deployments/open5gs_hss_cx/scscf/scscf.cfg b/custom_deployments/open5gs_hss_cx/scscf/scscf.cfg new file mode 100644 index 00000000..0c63478c --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/scscf.cfg @@ -0,0 +1,85 @@ +# SIP / UDP +listen=udp:SCSCF_IP:6060 +# SIP / TCP +listen=tcp:SCSCF_IP:6060 +# SIP / TCP/TLS +#listen=tls:SCSCF_IP:6061 + +#!define NETWORKNAME "IMS_DOMAIN" +#!define EPC_REALM "EPC_DOMAIN" +#!define NETWORKNAME_ESC "IMS_SLASH_DOMAIN" +#!define HOSTNAME "scscf.IMS_DOMAIN" +#!define HOSTNAME_ESC "scscf\.IMS_SLASH_DOMAIN" +#!define URI "sip:scscf.IMS_DOMAIN:6060" + +#!subst "/NETWORKNAME/IMS_DOMAIN/" + +alias=scscf.IMS_DOMAIN + +# ENUM-Server to query: +#!define ENUM_SUFFIX "IMS_DOMAIN." + +# SIP-Address of capturing node, if not set, capturing is disabled. +##!define CAPTURE_NODE "sip:127.0.0.1:9060" + +# Connection URL for the database: +# For use with a single database: +#!define DB_URL "mysql://scscf:heslo@MYSQL_IP/scscf" + +# For use with DB_Cluster: con1 (primary), con2 (backup) +##!define DB_URL "con1=>mysql://scscf:heslo@MYSQL_IP/scscf" +##!define DB_URL2 "con2=>mysql://scscf:heslo@MYSQL_IP/scscf" + +# Select Authorization Algorhithm: +##!define REG_AUTH_DEFAULT_ALG "AKAv1-MD5" +##!define REG_AUTH_DEFAULT_ALG "AKAv2-MD5" +##!define REG_AUTH_DEFAULT_ALG "MD5" +##!define REG_AUTH_DEFAULT_ALG "CableLabs-Digest" +##!define REG_AUTH_DEFAULT_ALG "3GPP-Digest" +##!define REG_AUTH_DEFAULT_ALG "TISPAN-HTTP_DIGEST_MD5" +# Let the HSS decide +#!define REG_AUTH_DEFAULT_ALG "HSS-Selected" + +# Number of TCP Processes +#!define TCP_PROCESSES 3 + +##!define RO_FORCED_PEER "32260@3gpp.org" +#!define RO_DESTINATION "hssocs.voiceblue.com" +#!define RO_ROOT "32260@3gpp.org" +#!define RO_EXT "ext" +#!define RO_MNC "02" +#!define RO_MCC "001" +#(see https://en.wikipedia.org/wiki/Mobile_country_code_(MCC)) +#!define RO_RELEASE "8" +# See http://tools.ietf.org/html/rfc4006#section-4.1.2 for the definition of the Service-Context + +##!define XMLRPC_WHITELIST_1 "127.0.0.1" +##!define XMLRPC_WHITELIST_2 "127.0.0.1" +##!define XMLRPC_WHITELIST_3 "127.0.0.1" + +# Several features can be enabled using '#!define WITH_FEATURE' directives: +# +# *** To run in debug mode: +# - define WITH_DEBUG +# +# *** To enable TCP support execute: +# - define WITH_TCP +# +# *** To enable XMLRPC support execute: +# - define WITH_XMLRPC +# - this will automagically enable TCP +# +# *** To enable the Ro-Interface: +# - Configure Ro-Diameter-Interface in scscf.xml +# - define WITH_RO +# +# *** To enable a Homer SIP-Capter-Node: +# - define CAPTURE_NODE with a proper address +# +# Enabled Features for this host: +##!define WITH_DEBUG +#!define WITH_TCP +##!define WITH_XMLRPC +##!define WITH_RO +##!define WITH_RO_TERM +#!define WITH_AUTH diff --git a/custom_deployments/open5gs_hss_cx/scscf/scscf.xml b/custom_deployments/open5gs_hss_cx/scscf/scscf.xml new file mode 100644 index 00000000..b12ced33 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/scscf.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/custom_deployments/open5gs_hss_cx/scscf/scscf_init.sh b/custom_deployments/open5gs_hss_cx/scscf/scscf_init.sh new file mode 100755 index 00000000..cee1f711 --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/scscf/scscf_init.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# BSD 2-Clause License + +# Copyright (c) 2020, Supreeth Herle +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[ ${#MNC} == 3 ] && IMS_DOMAIN="ims.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || IMS_DOMAIN="ims.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" +[ ${#MNC} == 3 ] && EPC_DOMAIN="epc.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || EPC_DOMAIN="epc.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" + +mkdir -p /etc/kamailio_scscf +cp /mnt/scscf/scscf.cfg /etc/kamailio_scscf +cp /mnt/scscf/scscf.xml /etc/kamailio_scscf +cp /mnt/scscf/kamailio_scscf.cfg /etc/kamailio_scscf +cp /mnt/scscf/CxDataType_Rel6.xsd /etc/kamailio_scscf +cp /mnt/scscf/CxDataType_Rel7.xsd /etc/kamailio_scscf +cp /mnt/scscf/CxDataType_Rel8.xsd /etc/kamailio_scscf +cp /mnt/scscf/dispatcher.list /etc/kamailio_scscf + +while ! mysqladmin ping -h ${MYSQL_IP} --silent; do + sleep 5; +done + +# Sleep until permissions are set +sleep 10; + +# Create SCSCF database, populate tables and grant privileges +if [[ -z "`mysql -u root -h ${MYSQL_IP} -qfsBe "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='scscf'" 2>&1`" ]]; +then + mysql -u root -h ${MYSQL_IP} -e "create database scscf;" + mysql -u root -h ${MYSQL_IP} scscf < /usr/local/src/kamailio/utils/kamctl/mysql/standard-create.sql + mysql -u root -h ${MYSQL_IP} scscf < /usr/local/src/kamailio/utils/kamctl/mysql/presence-create.sql + mysql -u root -h ${MYSQL_IP} scscf < /usr/local/src/kamailio/utils/kamctl/mysql/ims_usrloc_scscf-create.sql + mysql -u root -h ${MYSQL_IP} scscf < /usr/local/src/kamailio/utils/kamctl/mysql/ims_dialog-create.sql + mysql -u root -h ${MYSQL_IP} scscf < /usr/local/src/kamailio/utils/kamctl/mysql/ims_charging-create.sql + SCSCF_USER_EXISTS=`mysql -u root -h ${MYSQL_IP} -s -N -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE User = 'scscf' AND Host = '%')"` + if [[ "$SCSCF_USER_EXISTS" == 0 ]] + then + mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'scscf'@'%' IDENTIFIED WITH mysql_native_password BY 'heslo'"; + mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'scscf'@'$SCSCF_IP' IDENTIFIED WITH mysql_native_password BY 'heslo'"; + mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON scscf.* TO 'scscf'@'%'"; + mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON scscf.* TO 'scscf'@'$SCSCF_IP'"; + mysql -u root -h ${MYSQL_IP} -e "FLUSH PRIVILEGES;" + fi +fi + +export IMS_SLASH_DOMAIN=`echo $IMS_DOMAIN | sed 's/\./\\\./g'` + +sed -i 's|SCSCF_IP|'$SCSCF_IP'|g' /etc/kamailio_scscf/scscf.cfg +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/kamailio_scscf/scscf.cfg +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/kamailio_scscf/scscf.cfg +sed -i 's|IMS_SLASH_DOMAIN|'$IMS_SLASH_DOMAIN'|g' /etc/kamailio_scscf/scscf.cfg +sed -i 's|MYSQL_IP|'$MYSQL_IP'|g' /etc/kamailio_scscf/scscf.cfg + +sed -i 's|SCSCF_IP|'$SCSCF_IP'|g' /etc/kamailio_scscf/scscf.xml +sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/kamailio_scscf/scscf.xml +sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/kamailio_scscf/scscf.xml +sed -i 's|HSS_BIND_PORT|'$HSS_BIND_PORT'|g' /etc/kamailio_scscf/scscf.xml +sed -i 's|SCSCF_BIND_PORT|'$SCSCF_BIND_PORT'|g' /etc/kamailio_scscf/scscf.xml + +# Sync docker time +#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone diff --git a/custom_deployments/open5gs_hss_cx/srsenb.yaml b/custom_deployments/open5gs_hss_cx/srsenb.yaml new file mode 100644 index 00000000..e4d264ba --- /dev/null +++ b/custom_deployments/open5gs_hss_cx/srsenb.yaml @@ -0,0 +1,30 @@ +version: '3' +services: + srsenb: + image: docker_srslte + container_name: srsenb + stdin_open: true + tty: true + privileged: true + devices: + - "/dev/bus" + volumes: + - /dev/serial:/dev/serial:ro + - /dev/bus/usb:/dev/bus/usb:ro + - ../../srslte:/mnt/srslte + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - .custom_env + environment: + - COMPONENT_NAME=enb + expose: + - "36412/sctp" + - "2152/udp" + networks: + default: + ipv4_address: ${SRS_ENB_IP} +networks: + default: + external: + name: docker_open5gs_default diff --git a/upf/upf_init.sh b/upf/upf_init.sh index 042df632..8d5a5d37 100755 --- a/upf/upf_init.sh +++ b/upf/upf_init.sh @@ -31,6 +31,10 @@ export LANG=C.UTF-8 export IP_ADDR=$(awk 'END{print $1}' /etc/hosts) export IF_NAME=$(ip r | awk '/default/ { print $5 }') +# Remove ogstun and ogstun2 if they exist +ip link delete ogstun +ip link delete ogstun2 + python3 /mnt/upf/tun_if.py --tun_ifname ogstun --ipv4_range $UE_IPV4_INTERNET --ipv6_range 2001:230:cafe::/48 python3 /mnt/upf/tun_if.py --tun_ifname ogstun2 --ipv4_range $UE_IPV4_IMS --ipv6_range 2001:230:babe::/48 --nat_rule 'no'