Meraki MX ❤️ Cisco CUBE

Featured

Meraki products provide incredibly simple setup, excellent network visibility, and cloud management. The CUBE (Cisco Unified Border Element) is the SBC market leader. Sounds like a match made in heaven! Unfortunately, utilizing a CUBE with a Meraki MX isn’t entirely straightforward.

What’s the big deal? Three letters, NAT

NAT has been known to cause havoc with SIP. Unlike many web-based protocols, SIP requires session establishment in both directions. This means that the SIP SDPs contain both public and private IP addresses. Firewalls enabled with application-level gateway (ALG) capabilities, such as Cisco’s ASA, are able to open packets and rewrite public and private addresses. Unfortunately, Meraki MX units don’t support ALG.

What to do? Below is sample configuration highlighting one possible solution.

CUBE Config: (only showing relevant CUBE portions)

voice translation-rule 1
 rule 1 /\+18005551414/ /2100/

voice translation-rule 2
 rule 1 /^7\(.*\)/ /+\1/

voice translation-rule 3
 rule 1 /^2.../ /+18005551414/
 rule 2 /^8005551414/ /+18005551414/

voice translation-profile fix-in
 translate called 1

voice translation-profile fix-out
 translate calling 3
 translate called 2


voice service voip
 ip address trusted list
  ipv4 54.172.60.0 255.255.254.0
  ipv4 54.244.51.0 255.255.255.252
 allow-connections sip to sip
 sip
  registrar server expires max 600 min 60
  asserted-id pai
  midcall-signaling passthru
  early-offer forced

dial-peer voice 1 voip
 description ** Twilio to CUBE catchall **
 translation-profile incoming fix-in
 session protocol sipv2
 incoming called-number .
 voice-class sip bind control source-interface GigabitEthernet0/0
 voice-class sip bind media source-interface GigabitEthernet0/0
 dtmf-relay rtp-nte sip-kpml sip-notify
 codec g711ulaw
 ip qos dscp cs4 signaling
 no vad

dial-peer voice 100 voip
 description ** CUCM to CUBE **
 session protocol sipv2
 incoming called-number 71[2-9]..[2-9]......
 voice-class sip bind control source-interface GigabitEthernet0/1
 voice-class sip bind media source-interface GigabitEthernet0/1
 codec g711ulaw
 no vad

dial-peer voice 200 voip
 description ** CUBE to Twilio **
 translation-profile outgoing fix-out
 destination-pattern 71[2-9]..[2-9]......
 session protocol sipv2
 session target dns:blog-example.pstn.twilio.com
 voice-class sip bind control source-interface GigabitEthernet0/0
 voice-class sip bind media source-interface GigabitEthernet0/0
 dtmf-relay rtp-nte sip-kpml sip-notify
 codec g711ulaw
 ip qos dscp cs4 signaling
 no vad

dial-peer voice 300 voip
 description ** CUBE TO CUCM **
 destination-pattern 2100
 session protocol sipv2
 session target ipv4:192.168.202.70
 voice-class sip bind control source-interface GigabitEthernet0/1
 voice-class sip bind media source-interface GigabitEthernet0/1
 voice-class sip options-keepalive down-interval 10
 dtmf-relay rtp-nte
 codec g711ulaw
 no vad

sip-ua
  registrar ipv4:192.168.40.2 expires 3600

Depending on your dial-peer configuration, the inbound call may ring through, connect for a couple seconds, and then disconnect. If that is the case, you will see SIP messages similar to the one below repeating over and over. As you can see, the contents of the SIP message contain the internal IP address and not our public IP. The SIP provider will reject these responses and the call will never properly setup.

debug ccsip messages output:

Sent:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 54.172.60.1:5060;branch=z9hG4bK3113.d2cbcac3.0,SIP/2.0/UDP 172.18.6.78:5060;rport=5060;received=172.18.6.78;branch=z9hG4bK1072edf0-1977-4cbf-b7fd-7c483968f4a1_6772d868_289-2128576743027453437
From: "+18005551212" <sip:+[email protected]>;tag=19891870_6772d868_1072edf0-1977-4cbf-b7fd-7c483968f4a1
To: <sip:+[email protected]>;tag=3564574-69A
Date: Sat, 27 Jan 2018 17:09:31 GMT
Call-ID: [email protected]
CSeq: 1 INVITE
Allow: INVITE, OPTIONS, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY, INFO, REGISTER
Allow-Events: telephone-event
Remote-Party-ID: <sip:+[email protected]>;party=called;screen=yes;privacy=offContact: <sip:+[email protected]:5060>Record-Route: <sip:54.172.60.1:5060;lr;ftag=19891870_6772d868_1072edf0-1977-4cbf-b7fd-7c483968f4a1>
Supported: replaces
Supported: sdp-anat
Server: Cisco-SIPGateway/IOS-15.2(1)T1,
Supported: timer
Content-Type: application/sdp
Content-Disposition: session;handling=required
Content-Length: 244

v=0
o=CiscoSystemsSIP-GW-UserAgent 8316 5206 IN IP4 172.16.32.2s=SIP Call
c=IN IP4 172.16.32.2t=0 0
m=audio 19416 RTP/AVP 0 101
c=IN IP4 172.16.32.2a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20

If inbound calls simply fail, you may see a similar message in your debug. The invite is addressed to: [email protected] Because 198.51.100.2 is the public IP and not an address assigned to the CUBE router, the call is being rejected with an error of: SIP/2.0 400 Bad Request – ‘Invalid Host’.

Invalid Host - Debug

Received:
INVITE sip:+[email protected] SIP/2.0Record-Route: <sip:54.172.60.1:5060;lr;ftag=73582427_6772d868_9fdbb3ed-43cd-406f-b97e-a579a4b622cd>
CSeq: 1 INVITE
From: "+18005551212" <sip:+[email protected]>;tag=73582427_6772d868_9fdbb3ed-43cd-406f-b97e-a579a4b622cd
To: <sip:+[email protected]>
Max-Forwards: 67
Date: Tue, 30 Jan 2018 04:53:48 GMT
Min-SE: 120
Call-ID: [email protected]
Via: SIP/2.0/UDP 54.172.60.1:5060;branch=z9hG4bK874b.184a17b7.0
Via: SIP/2.0/UDP 172.18.13.220:5060;rport=5060;received=172.18.13.220;branch=z9hG4bK9fdbb3ed-43cd-406f-b97e-a579a4b622cd_6772d868_255-17278371579130503265
Contact: "+18005551212" <sip:+[email protected]:5060;transport=udp>
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE
User-Agent: Twilio Gateway
Content-Type: application/sdp
Content-Length: 236

v=0
o=root 21769210 21769210 IN IP4 34.203.250.161
s=Twilio Media Gateway
c=IN IP4 34.203.250.161
t=0 0
m=audio 18426 RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=sendrecv

Sent:
SIP/2.0 400 Bad Request - 'Invalid Host'Via: SIP/2.0/UDP 54.172.60.1:5060;branch=z9hG4bK874b.184a17b7.0,SIP/2.0/UDP 172.18.13.220:5060;rport=5060;received=172.18.13.220;branch=z9hG4bK9fdbb3ed-43cd-406f-b97e-a579a4b622cd_6772d868_255-17278371579130503265
From: "+18005551212" <sip:+[email protected]>;tag=73582427_6772d868_9fdbb3ed-43cd-406f-b97e-a579a4b622cd
To: <sip:+[email protected]>;tag=2C8060-1415
Date: Tue, 30 Jan 2018 05:06:40 GMT
Call-ID: [email protected]
CSeq: 1 INVITE
Allow-Events: telephone-event
Reason: Q.850;cause=100
Server: Cisco-SIPGateway/IOS-15.2(1)T1,
Content-Length: 0

The Fix

CUBE is able to modify the sip and sdp headers via sip profiles. This sip profile will replace the internal IP address (172.16.32.2) with the Public IP address (198.51.100.2).

CUBE SIP Profile

voice class sip-profiles 100
  request ANY sip-header From modify "172.16.32.2" "198.51.100.2"
  request ANY sip-header Via modify "172.16.32.2" "198.51.100.2"
  request ANY sip-header Remote-Party-ID modify "172.16.32.2" "198.51.100.2"
  request ANY sip-header Contact modify "172.16.32.2" "198.51.100.2"
  response ANY sip-header Contact modify "172.16.32.2" "198.51.100.2"
  response ANY sip-header Remote-Party-ID modify "172.16.32.2" "198.51.100.2"
  request ANY sdp-header Audio-Connection-Info modify "172.16.32.2" "198.51.100.2"
  request ANY sdp-header Connection-Info modify "172.16.32.2" "198.51.100.2"
  request ANY sdp-header Session-Owner modify "172.16.32.2" "198.51.100.2"
  response ANY sdp-header Session-Owner modify "172.16.32.2" "198.51.100.2"
  response ANY sdp-header Connection-Info modify "172.16.32.2" "198.51.100.2"
  response ANY sdp-header Audio-Connection-Info modify "172.16.32.2" "198.51.100.2"
  request ANY sip-header Call-Info modify "172.16.32.2" "198.51.100.2"
  request ANY sip-header P-Asserted-Identity modify "172.16.32.2" "198.51.100.2"

Once the sip profile has been created. Add it to voice service voip -> sip. It should look like this: Voice Service Voip

voice service voip
 ip address trusted list
  ipv4 54.172.60.0 255.255.254.0
  ipv4 54.244.51.0 255.255.255.252
 allow-connections sip to sip
 sip
  registrar server expires max 600 min 60
  asserted-id pai
  midcall-signaling passthru
  early-offer forced
  sip-profiles 100

If you are receiving the ‘Invalid Host’ message, create a loopback interface with the the public IP address.

Int lo0
  ip address 198.51.100.2 255.255.255.255

Since the router now has that IP address assigned to it, CUBE will accept the inbound sip message.


If you haven’t already done so, create a DMZ on the Meraki MX and assign it to one of the secondary LAN ports of the MX. Click here for details on creating a DMZ:

meraki-dmz
Next, create a 1:1 NAT entry:

I recommend being more specific on the allowed inbound connections. For testing, this was set to Any/Any.

Once these changes have been made, inbound and outbound calls should be working! The debug on working inbound call will now look like the below message. Notice, all of the IP references have been updated with the public IP addresses. The final message is an ACK from the provider.

debug ccsip messages debug after fix

Sent:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 54.172.60.1:5060;branch=z9hG4bKd934.8c68abd.0,SIP/2.0/UDP 172.18.16.217:5060;rport=5060;received=172.18.16.217;branch=z9hG4bK2841bb7d-05dc-444c-b13f-1eee59506271_6772d868_285-3463692609280011309
From: "+18005551212" <sip:+[email protected]>;tag=69538532_6772d868_2841bb7d-05dc-444c-b13f-1eee59506271
To: <sip:+[email protected]>;tag=412428-1A45Date: Tue, 30 Jan 2018 05:29:12 GMT
Call-ID: [email protected]
CSeq: 1 INVITE
Allow: INVITE, OPTIONS, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY, INFO, REGISTER
Allow-Events: kpml, telephone-event
Remote-Party-ID: <sip:+[email protected]>;party=called;screen=yes;privacy=offContact: <sip:+[email protected]:5060>Record-Route: <sip:54.172.60.1:5060;lr;ftag=69538532_6772d868_2841bb7d-05dc-444c-b13f-1eee59506271>
Supported: replaces
Supported: sdp-anat
Server: Cisco-SIPGateway/IOS-15.2(1)T1,
Supported: timer
Content-Type: application/sdp
Content-Disposition: session;handling=required
Content-Length: 250

v=0
o=CiscoSystemsSIP-GW-UserAgent 7724 6067 IN IP4 198.51.100.2s=SIP Call
c=IN IP4 198.51.100.2t=0 0
m=audio 19368 RTP/AVP 0 101
c=IN IP4 50.244.24.125
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20

Received:
ACK sip:+[email protected]:5060 SIP/2.0
Call-ID: [email protected]
CSeq: 1 ACK
From: "+18005551414" <sip:+[email protected]>;tag=69538532_6772d868_2841bb7d-05dc-444c-b13f-1eee59506271
To: <sip:+[email protected]>;tag=412428-1A45
Max-Forwards: 69
User-Agent: Twilio
Via: SIP/2.0/UDP 54.172.60.1:5060;branch=z9hG4bKd934.8c68abd.2
Via: SIP/2.0/UDP 172.18.16.217:5060;rport=5060;received=54.173.212.234;branch=z9hG4bK2841bb7d-05dc-444c-b13f-1eee59506271_6772d868_380-16474709728526618414
Content-Length: 0

With these changes in place, inbound and outbound calls should be working perfectly behind a Meraki MX!

If you have any questions or comments, please leave them below. I would love to hear how this config works in your deployment.

-Brad