Telephony & infrastructure

Why Asterisk would not register with MCN while the softphone worked

We were setting up an MCN SIP trunk in Asterisk inside Docker on a Mac. The login and password were correct — Telephone registered fine. Asterisk kept showing Unregistered. The issue was not the account, but the address the container sent to the provider.

The short version

Telephone on the Mac talks to MCN directly. Asterisk in a container goes through Docker Desktop and NAT. HTTP often survives that quietly, but SIP cares about the Via and Contact headers — that is how the provider knows where to send the reply.

At first Asterisk put an internal Docker address like 172.x.x.x into those headers. MCN could see REGISTER, but could not answer it from the internet — that address only exists inside the container network.

Asterisk in container Docker Desktop Mac sip.mcn.ru

It started working after three changes: set the public IP in EXTERNAL_IP, kept MCN port 5060 for outgoing requests, and moved Asterisk local port to 50600.

Symptoms

Asterisk does not register

pjsip show registrations shows Unregistered. Sometimes, after a provider response, the status becomes Rejected.

The softphone works

Telephone on the Mac registers with the same SIP login, password, and sip.mcn.ru server. That rules out the account itself and shifts attention to the REGISTER request sent by Asterisk.

If the softphone registers but Asterisk does not, compare the SIP REGISTER in the log first. Usually the problem is the address and port in the headers, not the password.

What the log showed

We enabled the PJSIP logger and sent REGISTER manually:

docker compose exec asterisk asterisk -rx "pjsip set logger on"
docker compose exec asterisk asterisk -rx "pjsip send register mcn-reg"
docker compose logs --tail 220 asterisk

Before the fix

Asterisk announced itself through a private Docker IP:

REGISTER sip:sip.mcn.ru SIP/2.0
Via: SIP/2.0/UDP 172.20.0.2:5160;rport;branch=...
Contact: <sip:<sip-login>@172.20.0.2:5160>

172.20.0.2 is an address inside Docker. MCN cannot reach it from the internet.

After EXTERNAL_IP

Once we set the public IP, the headers showed a normal external address:

Via: SIP/2.0/UDP <public-ipv4>:5160;rport;branch=...
Contact: <sip:<sip-login>@<public-ipv4>:5160>

But on ports 5060 and 5160 registration still came and went. It only became stable with local port 50600.

What finally worked

There are two different ports here. Asterisk sends REGISTER to sip.mcn.ru:5060. But in Via and Contact it says it is listening on <public-ipv4>:50600.

MCN_SIP_LOGIN=<sip-login>
MCN_SIP_PASSWORD=<password-from-mcn>
MCN_SIP_SERVER=sip.mcn.ru
MCN_SIP_CONTEXT=incoming
MCN_SIP_LOCAL_PORT=50600
MCN_SIP_REMOTE_PORT=5060
EXTERNAL_IP=<public-ipv4>
INTERNAL_EXT=100

In docker-compose.yml we exposed the UDP ports, including the one Asterisk puts in the headers:

ports:
  - "50600:50600/udp"
  - "5060:5060/udp"
  - "5160:5160/udp"
  - "10000-10100:10000-10100/udp"

After that everything is normal: MCN replies 401 Unauthorized, Asterisk sends REGISTER again with Digest, then 200 OK arrives. In pjsip show registrations you get Registered.

REGISTER sip:sip.mcn.ru SIP/2.0
Via: SIP/2.0/UDP <public-ipv4>:50600;rport;branch=...
Contact: <sip:<sip-login>@<public-ipv4>:50600>

SIP/2.0 401 Unauthorized

REGISTER sip:sip.mcn.ru SIP/2.0
Authorization: Digest username="<sip-login>", realm="mcn", nonce="...", uri="sip:sip.mcn.ru", response="...", algorithm=MD5

SIP/2.0 200 OK

Startup and verification

docker compose up --wait waits until the container is healthy — meaning Asterisk started and the CLI responds. Registration with MCN happens a bit later; that is a separate step.

After startup, wait a few seconds and check the status:

docker compose up --build -d --force-recreate --wait asterisk
sleep 10
docker compose exec asterisk asterisk -rx "pjsip show registrations"

Without the pause you may see Unregistered (exp. 4s) even though a couple of seconds later it is already Registered.

More articles