2FA for Extension Registration

Tonight’s Open Source Lounge had a presentation from @Pitzkey showing how outbound calling is blocked unless the MAC address from the dialing extension was already known. In the conversation that followed there was discussion how the same/similar technique could be used for multi factor authentication. Here is a crude proof of concept if anyone wants to run with it: https://gist.github.com/lgaetz/066c655867b4e679da21dbd1567b29bd

The idea is that extensions are in a special context which doesn’t allow dialing unless there is an AstDB entry that matches the extension IP (or SIP user agent string). Caller is challenged for a PIN which is emailed to the extension vm email address. Enter the PIN, IP/UA gets whitelisted and extension can call like normal until their IP/UA changes.


This will be a tech support nightmare waiting to happen.

One of the projects on my “that would be cool” list was to basically do pinsets with a totp password. Basically use an app like Google authenticator to get your 5 digit pin which is good for 30-60 seconds.

1 Like

While a totally cool idea, and one I will likely toy with, I foresee this being implemented so poorly by so many people.

Gist updated with a different approach. Instead of blocking all calls, it only blocks trunk calls until validated. This allows extensions to remain in from-internal context. Also not recognizing extensions by IP, but instead by SIP User Agent.

Still very much a hack.

I was thinking something more like captcha.

“To prove you are not a robot, listen to the following sounds. Press 1 any time you hear a fog horn. Otherwise, press 2.”

… oooooooooo … (1)

“bark bark” (2)


1 Like

Perhaps a “first factor” could be to preemptively upload a valid certificate to the phone if it supports that.

It would be nice if the chan_pjsip ‘endpoint identifier’ could be easily set to drop any IP based attempt (i.e. those with only an ‘anonymous’ identity).

Much as chan_sip does by setting


(you don’t have to use your ‘public domain’ for your phones’ REGISTER/INVITE/SUBSCRIBE/NOTIFY/OPTIONS/PUBLISH/MESSAGE connections, you can get for $8.98 a year from namecheap an unlikely guessed one like blah765squid.link that has a DNS A record (add AAAA SRV CNAME records if useful to you) that points to your PBX’ IP or domain name. You will need certs for that domain for TLS connections (or provisioning over https) but that can be trivial )

1 Like

In the US that would violate Kari’s law. You have to pass the 911 call without any prompting.

1 Like

I think everyone knows that. And any final solution would include dial plan for that.

What part of “crude proof” is difficult to understand.

Sometimes people look at something, see something missing or draw a rough conclusion. Then they offer up their thoughts. Sure this could have 911 bypass in the end but nothing shows or states that now.

Crude proof does not indicate what future development will do. I mean this went from IP based to UA based already. Spoofing a UA is easier and more widely done than an IP. Some might even view that as a backwards step.

But the point of this is Its being open to suggestions and feedback. Please dont jump down those doing that with the attitude of “well of course it will…dont be naive”. Kinda turns people off.

I would agree with you in part but the second update post stated it’s still a hack but not that it’s crude proof anymore but no mention about 911 handling. I would hate to see someone use it and not realize that and someone dies because they could not call 911. Proof of concept or hack or whatever you want to call it requires us to make sure users who might stumble on this and out it in place understand a huge limitation. I am pretty sure @lgaetz saw no offense to my post Jared.

1 Like

Thanks for the heads up on this @tonyclewis, lack of emergency awareness was an oversight. I’ve updated both gists with notes and sample code for ensuring emerg calls are not challenged as well as a clearer warning that proof of concept means not suitable for production.

An exchange on twitter last week made me realize that this concept could be used just for user pins on outbound routes to international and other high cost destinations. Since I only call internationally once or twice a year, I’m unable to remember what pin I have on the international outbound route. It would be useful for me to get a notification of what the pin is when I dial instead of searching first.

Chan_PJSIP doesn’t allow anonymous users to auth unless they either are match by an IP or there is an anonymous endpoint that has been created. Chan_PJSIP doesn’t have the concept of “allow guests” which means it won’t just default to a peer if nothing else matches. So you don’t want anonymous users trying to auth to make calls, no problem. You don’t create an anonymous endpoint and you remove/don’t allow the anonymous identifier to be used.

As for using domains, Chan_PJSIP’s username identifier will check for [email protected] then user for endpoints to match. So if you want to fully auth with [email protected] you need endpoints to match that. Which means the following will work:

; Matches on user [email protected] in the From user field
[[email protected]]

;matches on user [email protected] in the From user field
[[email protected]]

;matches on any 100 user that does not have domain1 or domain2 in the From user field.

And where does one do that in the GUI?

You don’t, I’m talking about Chan_PJSIP in general. While Chan_SIP settings in the GUI either gave you a large text field box to enter settings in line by line or it let you add global settings in the SIP Settings area that would apply to all peers. It also didn’t care what settings you put in it. Allowing users to put bad settings that did nothing in Chan_SIP but it also didn’t output warnings or anything saying it was a bad setting and it allow the peer to function anyways.

Chan_PJSIP doesn’t work that way. There are no global endpoint settings that apply to all endpoints. You want all endpoints to use the same from_domain you need to add that per endpoint or use a template. Chan_PJSIP will also throw errors about non-existing settings being in the config and then not load that endpoint at all due to that.

For me I don’t even use the username or IP options for authentication. I use the match_header option that allows me to match endpoints based on a custom header and value.

Unfortunately if your only experience with Chan_PJSIP has been via the FreePBX implementation then you are missing out on a lot of features that Chan_PJSIP actually has. The FreePBX implementation is a bit rudimentary.

For example, this is a small one, but as of current versions of 16 and 18 with Chan_PJSIP setting the trust_id_inbound=yes (default) which tells it to use the presented callerid instead of the callerid setting (if set) on the endpoint. It will now populate the CALLERID() name/number with the details in the P-Asserted-Identity header if it is present. So I no longer have to use a macro/gosub to check for a PAI header and then parse out the header to get the name and user fields.

Like I’ve said previously, once I started configuring Chan_PJSIP outside of FreePBX everything went a lot smoother. Mainly because I could use more than what FreePBX was allowing.


This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.