This page gives a quick introduction into the setup of the Osmocom core network with an outgoing call uplink to the PSTN via sipgate.de It does not contain a detailed explanation of all the involved components, but only a compressed installation guide. For detailed information check the Osmocom website .
Nowadays Osmocom actually recommends installation via package apt-get install osmo-bsc osmo-stp osmo-mgw osmo-msc osmo-hlr
, but as I always have something I need to fiddle with at some point, I prefer to build from source and thus have the source available for changes.
The old site on Osmocom can be found here.
Hardware
nanoBTS
For information on connection and configuring the nanoBTS please check the nanoBTS page .
Host System
As host system I’m using Debian 10 with XFCE edition in a VirtualBox VM.
The overall setup will also perfectly run on a RaspberryPI 3.
VM
- 4096MB RAM (less is sufficient)
- 2 Network adapters
- NAT adapter - for Uplink etc.
- Bridged adapter - Ethernet interface for connection to BTS etc.
- 50GB HDD, simply as I usually add various tools afterwards
- Client extensions installed
Network Configuration
Settings for /etc/network/interfaces
auto lo
iface lo inet loopback
# Uplink Interface
auto enp0s3
iface enp0s3 inet dhcp
dns-nameservers 8.8.8.8
# Bridged Adapter to BTS
auto enp0s8
iface enp0s8 inet static
address 192.168.1.20
netmask 255.255.255.0
auto enp0s8:0
iface enp0s8:0 inet static
address 192.168.1.21
netmask 255.255.255.0
Software Installation
Osmocom
For the Osmocom parts, best head over to the official documentation here
asterisk
This also contains the creation of basic configuration.
sudo apt install libncurses5-dev libjansson-dev uuid-dev sqlite3 libsqlite3-dev libxml2-dev libncurses-dev libedit-dev
cd /usr/src
git clone http://gerrit.asterisk.org/asterisk asterisk
cd asterisk
./configure
make
sudo make install
sudo make basic-pbx
ntp
As we will need acurate time, we also need everything to synchronize our VM’s time.
sudo apt install ntpdate
Configuration Files
I’ve got my setup based in /root/ as such my config files are all in /root/cfg/
Osmocom Stuff
Osmocom provides a set of default configs which work like a charm right here
As stated there you might want to enable verbose logging by adding
log stderr
logging filter all 1
logging color 1
logging print category 1
logging timestamp 1
logging print extended-timestamp 1
logging level all debug
to the config files.
sip-connector.conf
app
mncc
socket-path /tmp/bsc_mncc
sip
local 0.0.0.0 5069
remote 192.168.1.21 5060
dnsmasq.conf
We will need a DHCP server to give IPs to the basestations
listen-address=192.168.1.20
dhcp-range=192.168.1.50,192.168.1.100,12h
/etc/asterisk/asterisk.conf
Yes, my asterisk.conf
is basically empty.
[options]
; If we want to start Asterisk with a default verbosity for the verbose
; or debug logger channel types, then we use these settings (by default
; they are disabled).
;verbose = 5
;debug = 2
; User and group to run asterisk as. NOTE: This will require changes to
; directory and device permissions.
;runuser = asterisk ; The user to run as. The default is root.
;rungroup = asterisk ; The group to run as. The default is root
;defaultlanguage = en
/etc/asterisk/extensions.conf
[globals]
; General internal dialing options used in context Dial-Users.
; Only the timeout is defined here. See the Dial app documentation for
; additional options.
INTERNAL_DIAL_OPT=,30
[Dialing-Errors]
; Handle any extensions dialed internally that don't otherwise exist.
; Comment out or remove this extension if you would rather have the calls
; ignored.
exten = _X.,1,Verbose(1, "User ${CALLERID(num)} dialed an invalid number.")
same = n,Playback(pbx-invalid)
same = n,Hangup()
[incoming]
exten => xxxSIPGATEUSERNAMExxx,1,Log(Notice, "Incoming call via sipgate from ${CALLERID(num)}. exten is currently ${EXTEN}")
exten => xxxSIPGATEUSERNAMExxx,2,Answer(),
exten => xxxSIGPATEUSERNAMExxx,n,Background(welcome)
exten => xxxSIPGATEUSERNAMExxx,n,Background(silence/9)
exten => xxxSIPGATEUSERNAMExxx,n,Hangup()
exten => _1337,1,Playback(tt-weasels)
exten => _1337,n,Hangup()
exten => _9090XXXXX,1,Log(Notice, "Incoming call for ${EXTEN} from ${CALLERID(num)}.")
exten => _9090XXXXX,2,DIAL(SIP/${EXTEN}@192.168.1.20:5069)
exten => _9090XXXXX,n,Hangup()
include = Dialing-Errors
[internal]
exten => 1337,1,Answer
exten => 1337,2,Playback(tt-weasels)
exten => 1337,3,Hangup
exten => _9090XXXXX,1,DIAL(SIP/${EXTEN}@192.168.1.20:5069)
exten => 2222,1,DIAL(SIP/${EXTEN}@192.168.1.20:5069)
exten => _0!X.,1,Set(CALLERID(num)=SIPID)
exten => _0!X.,2,Dial(SIP/*31${EXTEN}@sipgate,30,trg)
exten => _0!X.,3,Hangup
include = Dialing-Errors
/etc/asterisk/sip.conf
[general]
context=internal
allowoverlap=no
domainsasrealm=yes
udpbindaddr=192.168.1.21
tcpbindaddr=192.168.1.21
transport=udp
srvlookup=yes
; login for sipgate uplink
register=xxxUSERxxx:xxxPASSxxx@sipgate.de/xxxUSERxxx
[sipgate]
type=peer
defaultuser=xxxUSERxxx
fromuser=xxxUSERxxx
secret=xxxPASSxxx
context=incoming
extension=xxxUSERxxx
host=sipgate.de
dtmfmode=rfc2833
qualify=yes
fromdomain=sipgate.de
nat=no
directmedia=no
canreinvite=no
insecure=port,invite
allow=!all,alaw,g722
[8888]
type=friend
host=dynamic
secret=123
context=internal
[7002]
type=friend
host=dynamic
secret=456
context=internal
[1111]
type=friend
host=dynamic
secret=123
conext=internal
[gsm]
type=peer
host=192.168.1.20
port=5069
context=gsm
insecure=port,invite
dtmfmode=rfc2833
disallow=all
allow=gsm
/etc/asterisk/cdr.conf
[general]
enable=yes
[custom]
; We log the unique ID as it can be useful for troubleshooting any issues
; that arise.
loguniqueid=yes
/etc/asterisk/cdr_custom.conf
[mappings]
; Our CDR log will be written to /var/log/asterisk/cdr-custom/Master.csv
; with the following schema.
Master.csv => ${CSV_QUOTE(${CDR(clid)})},${CSV_QUOTE(${CDR(src)})},${CSV_QUOTE(${CDR(dst)})},${CSV_QUOTE(${CDR(dcontext)})},${CSV_QUOTE(${CDR(channel)})},${CSV_QUOTE(${CDR(dstchannel)})},${CSV_QUOTE(${CDR(lastapp)})},${CSV_QUOTE(${CDR(lastdata)})},${CSV_QUOTE(${CDR(start)})},${CSV_QUOTE(${CDR(answer)})},${CSV_QUOTE(${CDR(end)})},${CSV_QUOTE(${CDR(duration)})},${CSV_QUOTE(${CDR(billsec)})},${CSV_QUOTE(${CDR(disposition)})},${CSV_QUOTE(${CDR(amaflags)})},${CSV_QUOTE(${CDR(accountcode)})},${CSV_QUOTE(${CDR(uniqueid)})},${CSV_QUOTE(${CDR(userfield)})},${CDR(sequence)}
/etc/asterisk/logger.conf
[general]
[logfiles]
console = verbose,notice,warning,error
;messages = notice,warning,error
;full = verbose,notice,warning,error,debug
;security = security
/etc/asterisk/modules.conf
; Asterisk configuration file
;
; Module Loader configuration file
;
[modules]
autoload=yes
;
; Any modules that need to be loaded before the Asterisk core has been
; initialized (just after the logger has been initialized) can be loaded
; using 'preload'. This will frequently be needed if you wish to map all
; module configuration files into Realtime storage, since the Realtime
; driver will need to be loaded before the modules using those configuration
; files are initialized.
;
; An example of loading ODBC support would be:
;preload => res_odbc.so
;preload => res_config_odbc.so
;
; Uncomment the following if you wish to use the Speech Recognition API
;preload => res_speech.so
;
; If you want Asterisk to fail if a module does not load, then use
; the "require" keyword. Asterisk will exit with a status code of 2
; if a required module does not load.
;
; require = chan_sip.so
; If you want you can combine with preload
; preload-require = res_odbc.so
;
; If you want, load the GTK console right away.
;
noload => pbx_gtkconsole.so
;load => pbx_gtkconsole.so
;
load => res_musiconhold.so
;
; Load one of: chan_oss, alsa, or console (portaudio).
; By default, load chan_oss only (automatically).
;
noload => chan_alsa.so
;noload => chan_oss.so
noload => chan_console.so
load => chan_sip.so
Startup Scripts
bsc_start.sh
osmo-nitb -s -c ~/cfg/openbsc.conf -l ~/cfg/hlr.sqlite3 -P -C -d DLMUX:DRTP -m -T --debug=DSQL:DLSMS:DRLL:DCC:DMM:DRR:DMSC:DHO:DGPRS:DNS:DLLC:DCTRL 2>&1
ggsn_start.sh
osmo-ggsn -c ~/cfg/ggsn.conf
sgsn_start.sh
osmo-sgsn -c ~/cfg/sgsn.conf -d DRLL:DCC:DMM:DRR:DNM:DMSC:DHO:DGPRS:DNS:DLLC:DCTRL
sip-connector_start.sh
osmo-sip-connector -c ~/cfg/osmo-sip-connector.conf
simplehlr_start.sh
php -S 0.0.0.0:80 -t /root/webserver/SimpleHLR/.
routing.sh
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A POSTROUTING -s 192.168.254.0/24 -t nat -o enp0s3 -j MASQUERADE
iptables -A POSTROUTING -t nat -o enp0s8 -j MASQUERADE
HLR Adding Subscribers
Osmo-HLR should be listening on localhost:4258, thus you can connect to it using telnet 127.0.0.1 4258
.
OsmoHLR> enable
OsmoHLR# subscriber imsi 123456789012345 create
% Created subscriber 123456789012345
ID: 1
IMSI: 123456789012345
MSISDN: none
OsmoHLR# subscriber imsi 123456789012345 update msisdn 12345
% Updated subscriber IMSI='123456789012345' to MSISDN='12345'
On my old setup, the HLR used to add an entry for each user that tried to connect, then I’d allow access manually. The same can be achieved with Osmo-HLR. Frist you need to create the entries on demand.
OsmoHLR# configure terminal
OsmoHLR(config)# hlr
OsmoHLR(config-hlr)# subscriber-create-on-demand
no-msisdn Do not automatically assign MSISDN.
<3-15> Length of an automatically assigned MSISDN.
OsmoHLR(config-hlr)# subscriber-create-on-demand no-ms
OsmoHLR(config-hlr)# subscriber-create-on-demand no-msisdn
none Do not allow any NAM (Network Access Mode) by default.
cs Allow access to circuit switched NAM by default.
ps Allow access to packet switched NAM by default.
cs+ps Allow access to circuit and packet switched NAM by default.
OsmoHLR(config-hlr)# subscriber-create-on-demand no-msisdn none
Obviously it makes sense to just add the setting to the static config file.
Then we can modify the subscriber and allow access to the cs, ps or cs+ps domains.
OsmoHLR# subscriber imsi 123456789012345 update network-access-mode
none cs ps cs+ps
And the most import command
OsmoHLR# show subscribers all
ID MSISDN IMSI IMEI NAM
----- ------------ ---------------- ---------------- -----
1 12345 123456789012345 ------------- CSPS
Running
The easiest approach is using screen or multiple terminal sessions, as you will want to be able to view the log output. You will need a screen for the BSC, GGSN, SGSN and the sip-connector. Above this all the osmocom components offer access via VTY. As such you might need access to these terminals for configuration or trouble shooting. The same applies for the asterisk cli.
BSC VTY
The BSC VTY listens on port 4242 / TCP. The easiest way to connect is by using telnet.
telnet 127.0.0.1 4242
SGSN VTY
The SGSN VTY listens on port 4245 / TCP. The easist way to connect is by using telnet.
telnet 127.0.0.1 4245
The VTY is the easiest way of checking the active PDP contexts.
:~/cfg# telnet 127.0.0.1 4245
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Welcome to the OsmoSGSN control interface
Copyright (C) 2010 Harald Welte and On-Waves
License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
OsmoSGSN> show pdp-context all
PDP Context IMSI: 262230000000001, SAPI: 3, NSAPI: 5, TI: 0
APN: internet
PDP Address: IPv4 192.168.254.2
GTP Local Control(4.0.0.0 / TEIC: 0x00000001) Data(4.0.0.0 / TEID: 0x00000001)
GTP Remote Control(4.0.0.0 / TEIC: 0x00000001) Data(4.0.0.0 / TEID: 0x00000001)
SGSN PDP Context Statistics:
User Data Messages ( In): 2 (1/s 2/m 0/h 0/d)
User Data Messages (Out): 0 (0/s 0/m 0/h 0/d)
User Data Bytes ( In): 145 (73/s 145/m 0/h 0/d)
User Data Bytes (Out): 0 (0/s 0/m 0/h 0/d)
asterisk CLI
The asterisk CLI is necessary for evaluating the state of the PSTN uplink.
:~/cfg# asterisk -r
Asterisk GIT-master-7c27e71, Copyright (C) 1999 - 2016, Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk GIT-master-7c27e71 currently running on TelCore2 (pid = 14391)
TelCore2*CLI> sip show registry
Host dnsmgr Username Refresh State Reg.Time
sipgate.de:5060 N xxxxxxxxx 105 Registered Sun, 26 Feb 2017 10:33:58
1 SIP registrations.
TelCore2*CLI>