Difference between revisions of "Dial up server"

From Doge Microsystems
Jump to navigation Jump to search
Line 2: Line 2:
 
== Prerequisites ==
 
== Prerequisites ==
  
==== Required hardware: ====
+
==== Hardware Requirements ====
* A hardware modem (not a software modem/winmodem, must be the real deal)
+
* A hardware modem (not a software modem or "winmodem")
* A computer to install Linux on to talk to the a modem (Can be anything that a modern Linux distribution will run on. Raspberry Pi, Pi clone, x86 machine, etc)
+
* A Linux device (e.g. x86 computer, Raspberry Pi, etc.) to communicate with the a modem as the dial-in server
* A client device (windows 9x PC for example) with a modem
+
* A client device with a modem (any type)
* Some form of PSTN to connect the two modems
+
* Some form of telephony connection to link the two modems
  
==== The exact hardware I’ve used ====
+
The hardware I've chosen to use is:
* Generic x86_64 PC running Ubuntu Server 18.04
+
 
* Matrix “MX Modem” (more on this later)
+
* Generic x86_64 PC
* USB to RS-232 serial adapter (DE-9) to connect to the modem (Must support hardware flow control)
+
* Matrix MX Modem (more on this later)
 +
* USB to RS-232 serial adapter (DE-9) to connect to the modem (with hardware flow control)
 
* DE-9 to DB-25 serial adapter
 
* DE-9 to DB-25 serial adapter
 
* Linksys PAP2T analog telephone adapter (ATA)
 
* Linksys PAP2T analog telephone adapter (ATA)
* x86 based Windows 95 PC with a US Robotics Sportster 28800 ISA modem
+
* x86-based Windows 95 PC with a US Robotics Sportster 28800 ISA modem
  
==== Software used ====
+
==== Software Requirements ====
 
* Ubuntu server 18.04
 
* Ubuntu server 18.04
* PPP
+
* ppp
 
* getty
 
* getty
 
* Asterisk
 
* Asterisk
  
== Choose your modem hardware ==
+
== Choosing Modem Hardware ==
Modem hardware varies greatly but thankfully nothing special is required beyond compatible protocols between your 'ISP' and 'client' modems such as V.22, V.32, etc.<br />
+
Modem hardware varies greatly, but this project doesn't require anything beyond standard protocols between your ISP and client modems (V.22, V.32, etc.).<br />
This tutorial ''should'' work with any dial-up modem that presents itself as a serial device to the operating system including cheap USB modems, ISA modems, PCI modems and of course external rs232 serial modems.<br /><br />
+
This tutorial ''should'' work with any dial-up modem that presents itself as a serial device to the operating system, including cheap USB modems, ISA modems, PCI modems and of course external RS-232 serial modems.<br /><br />
'''Note: You will have a lot of trouble using a '[https://en.wikipedia.org/wiki/Softmodem Softmodem\winmodem]'! You are much better off using a 'real' hardware based modem.'''<br />
+
'''Note: You will have a lot of trouble using a [https://en.wikipedia.org/wiki/Softmodem softmodem/winmodem]! You are much better off using a hardware-based modem.'''<br />
 
<br />
 
<br />
I'll be using an external serial modem + USB to RS-232 adapter for this tutorial. Using dedicated serial hardware has the advantage of being easy to troubleshoot and can also scale up to dozens of lines if you have enough desk space and USB ports.<br />
+
I'll be using an external serial modem + USB-to-RS-232 adapter for this tutorial. Using dedicated serial hardware has the advantage of being easy to troubleshoot and scaling up to dozens of lines (if you have enough desk space and USB ports).<br />
My modem is a "MX Modem" made by MATRIX but I was unable to find ''any'' information about it. Obviously the next step was to crack it open to try and figure out its capabilities.<br />
+
My modem is an MX Modem made by MATRIX, but I was unable to find ''any'' information about it. Obviously the next step was to crack it open to figure out its capabilities.<br />
 
<br />
 
<br />
Inside is a XECOM XE1414C 14.4 Kbps modem in a single component package. PDF manual is [https://dogemicrosystems.ca/files/dial/XECOM_XE1414.pdf here]. <br />
+
Inside is a XECOM XE1414C 14.4 kbps modem in a single component package. The PDF manual is [https://dogemicrosystems.ca/files/dial/XECOM_XE1414.pdf here]. <br />
To connect the modem to the computer running the ISP side of things I'm using a generic USB to RS-232 adapter and a DE-9 to DB-25 adapter.<br />
+
To connect the modem to the ISP-side computer, I'm using a generic USB to RS-232 adapter and a DE-9 to DB-25 adapter.<br />
 
<gallery mode="traditional">
 
<gallery mode="traditional">
 
MX_modem_internal_XECOM.jpg|Matrix MX Modem with top cover removed
 
MX_modem_internal_XECOM.jpg|Matrix MX Modem with top cover removed
Line 37: Line 38:
 
</gallery>
 
</gallery>
  
== The PSTN ==
+
== The Telephone Network ==
We need a way to connect our modem (serving as an ISP) to clients. There are many ways to approach this:
+
We need a way to connect our ISP modem to clients. There are many ways to approach this:
* Use the actual PSTN via real phone lines
+
# Use the actual PSTN (i.e. real phone lines)
* Use a PBX to provide local connectivity
+
# Use a PBX to provide local connectivity
* Build your own circuity (not covered here, would require extra config as you would not have dial tone)
+
# Build your own circuity (not covered here as it would require extra configuration)
* Fake PSTN using VoIP ATAs and a software PBX
+
# Build a fake PSTN using VoIP ATAs and a software PBX
  
 
I've gone with the fourth option. Here's the breakdown:
 
I've gone with the fourth option. Here's the breakdown:
# Asterisk, a VoIP PBX, is configured on the dial-in server to accept connections from two SIP client accounts and route calls between them.
+
# Asterisk - a VoIP PBX - is configured on the dial-in server to accept connections from two SIP client accounts and route calls between them.
# A Linksys PAP2T ATA, which supports two phone lines, is set up as both of those SIP clients connected to the PBX.
+
# A Linksys PAP2T ATA - which supports two phone lines - is set up as both of those SIP clients connected to the PBX.
# The ISP side modem is connected to the first line and the client device is on the second line.
+
# The ISP-side modem is connected to the first line, and the client device to the second line.
  
==== Asterisk set up ====
+
==== Asterisk Setup ====
 
<ol>
 
<ol>
 
<li>Install asterisk<br /></li>
 
<li>Install asterisk<br /></li>
Line 79: Line 80:
 
<li>Edit <code>/etc/asterisk/extensions.conf</code> and make two changes:<br />
 
<li>Edit <code>/etc/asterisk/extensions.conf</code> and make two changes:<br />
 
Search for <code>[default]</code> (should be around line 672) and comment out <br /><code>include => demo</code><br />
 
Search for <code>[default]</code> (should be around line 672) and comment out <br /><code>include => demo</code><br />
After that commented out line add a new line with <br /><code>exten => _X!,1,Dial(SIP/pap2t-ispmodem, 20)</code><br />
+
Underneath that line, add a new line with <br /><code>exten => _X!,1,Dial(SIP/pap2t-ispmodem, 20)</code><br />
 
The _X! tells this dial plan rule to match any number a client dials and send the call to the pap2t-ispmodem client
 
The _X! tells this dial plan rule to match any number a client dials and send the call to the pap2t-ispmodem client
 
</li>
 
</li>
Line 86: Line 87:
 
</li>
 
</li>
 
<li>
 
<li>
Start asterisk<br />
+
Start Asterisk<br />
 
<code>sudo systemctl start asterisk</code></li>
 
<code>sudo systemctl start asterisk</code></li>
<li>Open the asterisk console to confirm your ATA lines are registered<br />
+
<li>Open the Asterisk console to confirm your ATA lines are registered<br />
 
<code>sudo asterisk -rvvvv</code><br />
 
<code>sudo asterisk -rvvvv</code><br />
 
<pre>dialupserver*CLI> sip show peers
 
<pre>dialupserver*CLI> sip show peers
Line 95: Line 96:
 
pap2t-ispmodem/pap2t-ispm 10.1.8.112                              D  No        No            5060    OK (6 ms)                                     
 
pap2t-ispmodem/pap2t-ispm 10.1.8.112                              D  No        No            5060    OK (6 ms)                                     
 
2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]</pre>
 
2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]</pre>
If you make changes to your configuration after starting asterisk you can use the <code>reload</code> command in the console to reload the configuration.
+
If you make changes to your configuration after starting Asterisk, you can use the <code>reload</code> command in the console to reload the configuration.
 
</li>
 
</li>
 
</ol>
 
</ol>
  
ATA SIP Registration example:
+
ATA SIP registration example:
 
<pre>
 
<pre>
 
     -- Registered SIP 'pap2t-ispmodem' at 10.1.8.112:5060
 
     -- Registered SIP 'pap2t-ispmodem' at 10.1.8.112:5060
Line 130: Line 131:
  
 
==== ATA Configuration ====
 
==== ATA Configuration ====
I wont go into much detail on ATA configuration since the topic has been beat to death on various forums but for modem communications here is the gist:<br />
+
I won't go into much detail on ATA configuration since the topic has been beaten to death on various forums. This is the process to get basic communication:<br />
# Set up both lines on the ATA to register with the PBX with the usernames 'pap2t-ispmodem' and 'pap2t-client' with the password 'password' (so secure)
+
# Set up both lines on the ATA to register to the PBX with usernames 'pap2t-ispmodem' and 'pap2t-client' and the password 'password'
# Use g711u codec
+
# Use the G.711 µ-law codec
# Disable every echo cancellation option in your ATA (see https://www.voip-info.org/linksys-pap2t)
+
# Disable every echo cancellation option in your ATA (see [https://www.voip-info.org/linksys-pap2t here for PAP2T instructions])
# Set the jitter buffer to be as small as possible (you want voice data on the wire ASAP)
+
# Set the jitter buffer to be as small as possible
 
<br />
 
<br />
Congrats! You now have your own voice network!<br />
+
Congratulations! You now have your own voice network.<br />
  
== The dial-in-server ==
+
== The Dial-in Server ==
 
<ol>
 
<ol>
<li>Install Debian/Ubuntu/Raspbian per the usual methods (not covered here)</li>
+
<li>Install your Debian-based Linux distribution of choice (not covered here)</li>
 
<li>Update to latest packages and reboot if required<br /></li>
 
<li>Update to latest packages and reboot if required<br /></li>
 
<pre>
 
<pre>
Line 146: Line 147:
 
sudo apt-get upgrade
 
sudo apt-get upgrade
 
sudo reboot</pre>
 
sudo reboot</pre>
<li>Connect USB to RS-232 adapter and confirm it shows up as /dev/ttyUSBXXX (<code>ls /dev/</code> to check) In my case it presents as <code>/dev/ttyUSB0</code><br />
+
<li>Connect the USB to RS-232 adapter and confirm it shows up as /dev/ttyUSBXXX (<code>ls /dev/</code> to check). In my case, it presents as <code>/dev/ttyUSB0</code><br />
 
My serial adapter is a "<code>ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adaptor</code>"
 
My serial adapter is a "<code>ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adaptor</code>"
 
</li>
 
</li>
 
<li>Install ppp (and getty if your distro doesn’t have it by default)<br />
 
<li>Install ppp (and getty if your distro doesn’t have it by default)<br />
 
<pre>sudo apt-get install ppp mgetty</pre></li>
 
<pre>sudo apt-get install ppp mgetty</pre></li>
<li>Many of the old guides were written when inittab was still around but its 2019 and systemd has taken over.<br />
+
<li>Many of the old guides were written when inittab was still around, but it's 2019 and systemd has taken over.<br />
We need to create a systemd service for mgetty so edit <code>/lib/systemd/system/mgetty.service</code> with your text editor of choice with elevated privileges (sudo)
+
We need to create a systemd service for mgetty, so edit <code>/lib/systemd/system/mgetty.service</code> with your text editor of choice as root.
 
<pre>[Unit]
 
<pre>[Unit]
 
Description=External Modem
 
Description=External Modem
Line 170: Line 171:
 
</li>
 
</li>
 
<li>
 
<li>
Configure mgetty by editing <code>/etc/mgetty/mgetty.config</code> with your text editor of choice with elevated privileges (sudo)<br />
+
Configure mgetty by editing <code>/etc/mgetty/mgetty.config</code> with your text editor of choice as root.<br />
  
Comment out everything except the debug level and append the section for configuring the serial device
+
Comment out everything except the debug level, and append the section for configuring the serial device:
 
<pre>debug 9
 
<pre>debug 9
  
Line 188: Line 189:
 
</pre>
 
</pre>
 
</li>
 
</li>
<li>Enable the mgetty service so it starts on boot<br/>
+
<li>Enable the mgetty service so it starts on boot:<br/>
 
<code>sudo systemctl enable mgetty.service</code><br />
 
<code>sudo systemctl enable mgetty.service</code><br />
 
</li>
 
</li>
 
<li>
 
<li>
Start mgetty<br />
+
Start mgetty:<br />
 
<code>sudo systemctl start mgetty.service</code></li>
 
<code>sudo systemctl start mgetty.service</code></li>
 
<li>Configure ppp by editing <code>/etc/ppp/options</code><br />
 
<li>Configure ppp by editing <code>/etc/ppp/options</code><br />
Like above comment out everything except these settings
+
Like above, comment out everything except these settings:
 
<pre># Define the DNS server for the client to use
 
<pre># Define the DNS server for the client to use
 
ms-dns 8.8.8.8
 
ms-dns 8.8.8.8
Line 231: Line 232:
 
</pre>
 
</pre>
 
</li>
 
</li>
<li>Create the user used for PAP authentication<br /><code>sudo useradd -G dialout,dip,users -m -g users -s /usr/sbin/pppd dial</code></li>
+
<li>Create the user for PAP authentication:<br /><code>sudo useradd -G dialout,dip,users -m -g users -s /usr/sbin/pppd dial</code></li>
<li>Change the password (I set it to dial)<br /><code>sudo passwd dial</code></li>
+
<li>Set a password:<br /><code>sudo passwd dial</code></li>
<li>Edit <code>/etc/ppp/pap-secrets</code> and append the username and password (quotes included)<br /> <code>dial    *              "dial"  *</code></li>
+
<li>Edit <code>/etc/ppp/pap-secrets</code> and append the username and password (same as you entered above, quotes included):<br /> <code>dial    *              "dial"  *</code></li>
<li>Enable packet forwarding for IP4 by editing <code>/etc/sysctl.conf</code><br /><code>net.ipv4.ip_forward=1</code><li>
+
<li>Enable packet forwarding for IP4 by editing <code>/etc/sysctl.conf</code>:<br /><code>net.ipv4.ip_forward=1</code><li>
 
<li>
 
<li>
  
Last step for the dial-up server is to configure the firewall to allow forwarding of traffic from PPP out onto the network (and off to the internet)<br />
+
The last step for the dial-up server is to configure the firewall to allow traffic forwarding from PPP out onto the network (and off to the Internet).<br />
 
<ol>
 
<ol>
<li>On Linux distributions with iptables you need to add a line to <code>/etc/rc.local</code> to enable masquerading. If your ethernet interface is named eth0 you would add this line: <br /><code>iptables -t nat -A POSTROUTING -s 192.168.32.0/24 -o eth0 -j MASQUERADE</code>
+
<li>On Linux distributions with iptables, you need to add a line to <code>/etc/rc.local</code> to enable masquerading. If your Ethernet interface is named eth0, you would add this line: <br /><code>iptables -t nat -A POSTROUTING -s 192.168.32.0/24 -o eth0 -j MASQUERADE</code>
 
</li>
 
</li>
 
<li>
 
<li>
On modern Ubuntu installs ufw is used instead of iptables so the procedure is a bit different. Follow this guide but you can omit <code>-o eth0</code> and use <code>-s 192.168.32.0/24</code> <br /> https://help.ubuntu.com/lts/serverguide/firewall.html.en#ip-masquerading
+
On modern Ubuntu installs, ufw is used as a frontend to iptables, so the procedure is a bit different. Follow [https://help.ubuntu.com/lts/serverguide/firewall.html.en#ip-masquerading this guide], but you can omit <code>-o eth0</code> and use <code>-s 192.168.32.0/24</code>.<br />
 
</li>
 
</li>
 
</ol>
 
</ol>
Line 249: Line 250:
  
 
== Troubleshooting ==
 
== Troubleshooting ==
When using an external modem the choice of USB to RS-232 adapter seems to be crucial. There aren't many requirements but you must use an adapter that supports hardware flow control.
+
When using an external modem, the choice of USB to RS-232 adapter seems to be crucial. There aren't many requirements, but you must use an adapter that supports hardware flow control.
If you need to purchase an adapter you can either get one that explicitly says it supports hardware flow control ($$$$) or play the eBay lottery and buy a half dozen different models and hope one of them works.
+
If you need to purchase an adapter, you can either get one that explicitly says it supports hardware flow control ($$$), or play the eBay lottery and buy a half-dozen different models and hope one of them works.
 
<br /><br />
 
<br /><br />
I ran into a bug in Debian 9.5 with my ch341 driver based USB to serial adapter where setting the baud rate was not working on some Linux kernels. (Seems to be this: https://bugzilla.redhat.com/show_bug.cgi?id=1235715)
+
I ran into a bug in Debian 9.5 with my USB to serial adapter using the ch341 driver, where setting the baud rate was not working on some Linux kernels. (Seems to be [https://bugzilla.redhat.com/show_bug.cgi?id=1235715 this bug])
 
<br /><br />
 
<br /><br />
To troubleshoot modem communication and baud rate settings use minicom (or screen) to open a session over serial and try different settings (or read your modem's manual!). Sending the command 'AT' followed by a new line should result in your modem replying 'OK'<br />
+
To troubleshoot modem communication and baud rate settings, use minicom (or screen) to open a session over serial and try different settings (or read your modem's manual!). Sending the command 'AT' followed by a new line should result in your modem replying 'OK'.<br />
If you're getting nothing at all out of your modem perform a [http://www.ni.com/tutorial/3450/en/ serial loopback test]
+
If you're getting nothing at all out of your modem, perform a [http://www.ni.com/tutorial/3450/en/ serial loopback test]
 
<br /><br />
 
<br /><br />
If mgetty is not answering incoming calls it may be having trouble communicating with your modem. Check the logs in <code>/var/log/mgetty/</code> to determine the problem. You may need to set a modem initialization string in the mgetty device config file so check your modem's manual for help on this. (If this happens you're in for a rough time)
+
If mgetty is not answering incoming calls, it may be having trouble communicating with your modem. Check the logs in <code>/var/log/mgetty/</code> to determine the problem. You may need to set a modem initialization string in the mgetty device config file, so check your modem's manual for help on this.

Revision as of 04:51, 10 February 2019

DIY dial up ISP.jpg

Prerequisites

Hardware Requirements

  • A hardware modem (not a software modem or "winmodem")
  • A Linux device (e.g. x86 computer, Raspberry Pi, etc.) to communicate with the a modem as the dial-in server
  • A client device with a modem (any type)
  • Some form of telephony connection to link the two modems

The hardware I've chosen to use is:

  • Generic x86_64 PC
  • Matrix MX Modem (more on this later)
  • USB to RS-232 serial adapter (DE-9) to connect to the modem (with hardware flow control)
  • DE-9 to DB-25 serial adapter
  • Linksys PAP2T analog telephone adapter (ATA)
  • x86-based Windows 95 PC with a US Robotics Sportster 28800 ISA modem

Software Requirements

  • Ubuntu server 18.04
  • ppp
  • getty
  • Asterisk

Choosing Modem Hardware

Modem hardware varies greatly, but this project doesn't require anything beyond standard protocols between your ISP and client modems (V.22, V.32, etc.).
This tutorial should work with any dial-up modem that presents itself as a serial device to the operating system, including cheap USB modems, ISA modems, PCI modems and of course external RS-232 serial modems.

Note: You will have a lot of trouble using a softmodem/winmodem! You are much better off using a hardware-based modem.

I'll be using an external serial modem + USB-to-RS-232 adapter for this tutorial. Using dedicated serial hardware has the advantage of being easy to troubleshoot and scaling up to dozens of lines (if you have enough desk space and USB ports).
My modem is an MX Modem made by MATRIX, but I was unable to find any information about it. Obviously the next step was to crack it open to figure out its capabilities.

Inside is a XECOM XE1414C 14.4 kbps modem in a single component package. The PDF manual is here.
To connect the modem to the ISP-side computer, I'm using a generic USB to RS-232 adapter and a DE-9 to DB-25 adapter.

The Telephone Network

We need a way to connect our ISP modem to clients. There are many ways to approach this:

  1. Use the actual PSTN (i.e. real phone lines)
  2. Use a PBX to provide local connectivity
  3. Build your own circuity (not covered here as it would require extra configuration)
  4. Build a fake PSTN using VoIP ATAs and a software PBX

I've gone with the fourth option. Here's the breakdown:

  1. Asterisk - a VoIP PBX - is configured on the dial-in server to accept connections from two SIP client accounts and route calls between them.
  2. A Linksys PAP2T ATA - which supports two phone lines - is set up as both of those SIP clients connected to the PBX.
  3. The ISP-side modem is connected to the first line, and the client device to the second line.

Asterisk Setup

  1. Install asterisk
  2. sudo apt-get install asterisk
  3. Append configuration for the two SIP clients to the end of /etc/asterisk/sip.conf
    [pap2t-ispmodem]
    context=default
    type=friend
    secret=password
    qualify=200                     ; Qualify peer is no more than 200ms away
    host=dynamic                    ; This device registers with us
    directmedia=yes                 ; Send RTP directly to the peer to reduce latency and jitter
    regexten=881
    nat=no
    
    [pap2t-client]
    context=default
    type=friend
    secret=password
    qualify=200                     ; Qualify peer is no more than 200ms away
    host=dynamic                    ; This device registers with us
    directmedia=yes                 ; Send RTP directly to the peer to reduce latency and jitter
    regexten=882
    nat=no
    
  4. Edit /etc/asterisk/extensions.conf and make two changes:
    Search for [default] (should be around line 672) and comment out
    include => demo
    Underneath that line, add a new line with
    exten => _X!,1,Dial(SIP/pap2t-ispmodem, 20)
    The _X! tells this dial plan rule to match any number a client dials and send the call to the pap2t-ispmodem client
  5. Enable the asterisk service so it starts on boot
    sudo systemctl enable asterisk
  6. Start Asterisk
    sudo systemctl start asterisk
  7. Open the Asterisk console to confirm your ATA lines are registered
    sudo asterisk -rvvvv
    dialupserver*CLI> sip show peers
    Name/username             Host                                    Dyn Forcerport Comedia    ACL Port     Status      Description                      
    pap2t-client/pap2t-client 10.1.8.112                               D  No         No             5061     OK (7 ms)                                    
    pap2t-ispmodem/pap2t-ispm 10.1.8.112                               D  No         No             5060     OK (6 ms)                                    
    2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]

    If you make changes to your configuration after starting Asterisk, you can use the reload command in the console to reload the configuration.

ATA SIP registration example:

    -- Registered SIP 'pap2t-ispmodem' at 10.1.8.112:5060
       > Saved useragent "Linksys/SPA2102-5.2.5" for peer pap2t-ispmodem
       NOTICE[4253]: chan_sip.c:24592 handle_response_peerpoke: Peer 'pap2t-ispmodem' is now Reachable. (7ms / 200ms)
    -- Registered SIP 'pap2t-client' at 10.1.8.112:5061
       > Saved useragent "Linksys/SPA2102-5.2.5" for peer pap2t-client
       NOTICE[4253]: chan_sip.c:24592 handle_response_peerpoke: Peer 'pap2t-client' is now Reachable. (5ms / 200ms)


Successful call example:

  == Using SIP RTP CoS mark 5
       > 0x7fa234059e30 -- Strict RTP learning after remote address set to: 10.1.8.112:16482
    -- Executing [88567682@default:1] Dial("SIP/pap2t-client-00000002", "SIP/pap2t-ispmodem, 20") in new stack
  == Using SIP RTP CoS mark 5
    -- Called SIP/pap2t-ispmodem
    -- SIP/pap2t-ispmodem-00000003 is ringing
       > 0x7fa1f8252350 -- Strict RTP learning after remote address set to: 10.1.8.112:16384
    -- SIP/pap2t-ispmodem-00000003 answered SIP/pap2t-client-00000002
    -- Channel SIP/pap2t-ispmodem-00000003 joined 'simple_bridge' basic-bridge <5f9983eb-3f93-49d1-90b3-c91c545c2d38>
    -- Channel SIP/pap2t-client-00000002 joined 'simple_bridge' basic-bridge <5f9983eb-3f93-49d1-90b3-c91c545c2d38>
       > Bridge 5f9983eb-3f93-49d1-90b3-c91c545c2d38: switching from simple_bridge technology to native_rtp
       > Remotely bridged 'SIP/pap2t-client-00000002' and 'SIP/pap2t-ispmodem-00000003' - media will flow directly between them
       > 0x7fa1f8252350 -- Strict RTP learning after remote address set to: 10.1.8.112:16384
       > 0x7fa234059e30 -- Strict RTP learning after remote address set to: 10.1.8.112:16482
    -- Channel SIP/pap2t-client-00000002 left 'native_rtp' basic-bridge <5f9983eb-3f93-49d1-90b3-c91c545c2d38>
    -- Channel SIP/pap2t-ispmodem-00000003 left 'native_rtp' basic-bridge <5f9983eb-3f93-49d1-90b3-c91c545c2d38>
  == Spawn extension (default, 88567682, 1) exited non-zero on 'SIP/pap2t-client-00000002'
       > 0x7fa1f8252350 -- Strict RTP learning after remote address set to: 10.1.8.112:16384


ATA Configuration

I won't go into much detail on ATA configuration since the topic has been beaten to death on various forums. This is the process to get basic communication:

  1. Set up both lines on the ATA to register to the PBX with usernames 'pap2t-ispmodem' and 'pap2t-client' and the password 'password'
  2. Use the G.711 µ-law codec
  3. Disable every echo cancellation option in your ATA (see here for PAP2T instructions)
  4. Set the jitter buffer to be as small as possible


Congratulations! You now have your own voice network.

The Dial-in Server

  1. Install your Debian-based Linux distribution of choice (not covered here)
  2. Update to latest packages and reboot if required
  3. sudo apt-get update
    sudo apt-get upgrade
    sudo reboot
  4. Connect the USB to RS-232 adapter and confirm it shows up as /dev/ttyUSBXXX (ls /dev/ to check). In my case, it presents as /dev/ttyUSB0
    My serial adapter is a "ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adaptor"
  5. Install ppp (and getty if your distro doesn’t have it by default)
    sudo apt-get install ppp mgetty
  6. Many of the old guides were written when inittab was still around, but it's 2019 and systemd has taken over.
    We need to create a systemd service for mgetty, so edit /lib/systemd/system/mgetty.service with your text editor of choice as root.
    [Unit]
    Description=External Modem
    Documentation=man:mgetty(8)
    Requires=systemd-udev-settle.service
    After=systemd-udev-settle.service
    
    [Service]
    Type=simple
    ExecStart=/sbin/mgetty /dev/ttyUSB0
    Restart=always
    PIDFile=/var/run/mgetty.pid.ttyUSB0
    
    [Install]
    WantedBy=multi-user.target
    
  7. Configure mgetty by editing /etc/mgetty/mgetty.config with your text editor of choice as root.
    Comment out everything except the debug level, and append the section for configuring the serial device:
    debug 9
    
    port ttyUSB0
     port-owner root
     port-group dialout
     port-mode 0660
     data-only yes
     ignore-carrier no
     toggle-dtr yes
     toggle-dtr-waittime 500
     rings 2
     #autobauding yes
     speed 9600
    
  8. Enable the mgetty service so it starts on boot:
    sudo systemctl enable mgetty.service
  9. Start mgetty:
    sudo systemctl start mgetty.service
  10. Configure ppp by editing /etc/ppp/options
    Like above, comment out everything except these settings:
    # Define the DNS server for the client to use
    ms-dns 8.8.8.8
    # async character map should be 0
    asyncmap 0
    # Require authentication
    auth
    # Use hardware flow control
    crtscts
    # We want exclusive access to the modem device
    lock
    # Show pap passwords in log files to help with debugging
    show-password
    # Require the client to authenticate with pap
    +pap
    # If you are having trouble with auth enable debugging
    debug
    # Heartbeat for control messages, used to determine if the client connection has dropped
    lcp-echo-interval 30
    lcp-echo-failure 4
    # Cache the client mac address in the arp system table
    proxyarp
    # Disable the IPXCP and IPX protocols.
    noipx
    
  11. Create a device option file by editing /etc/ppp/options.ttyUSB0
    local
    lock
    nocrtscts
    192.168.32.1:192.168.32.105
    netmask 255.255.255.0
    noauth
    proxyarp
    lcp-echo-failure 60
    
  12. Create the user for PAP authentication:
    sudo useradd -G dialout,dip,users -m -g users -s /usr/sbin/pppd dial
  13. Set a password:
    sudo passwd dial
  14. Edit /etc/ppp/pap-secrets and append the username and password (same as you entered above, quotes included):
    dial * "dial" *
  15. Enable packet forwarding for IP4 by editing /etc/sysctl.conf:
    net.ipv4.ip_forward=1
  16. The last step for the dial-up server is to configure the firewall to allow traffic forwarding from PPP out onto the network (and off to the Internet).
    1. On Linux distributions with iptables, you need to add a line to /etc/rc.local to enable masquerading. If your Ethernet interface is named eth0, you would add this line:
      iptables -t nat -A POSTROUTING -s 192.168.32.0/24 -o eth0 -j MASQUERADE
    2. On modern Ubuntu installs, ufw is used as a frontend to iptables, so the procedure is a bit different. Follow this guide, but you can omit -o eth0 and use -s 192.168.32.0/24.

Troubleshooting

When using an external modem, the choice of USB to RS-232 adapter seems to be crucial. There aren't many requirements, but you must use an adapter that supports hardware flow control. If you need to purchase an adapter, you can either get one that explicitly says it supports hardware flow control ($$$), or play the eBay lottery and buy a half-dozen different models and hope one of them works.

I ran into a bug in Debian 9.5 with my USB to serial adapter using the ch341 driver, where setting the baud rate was not working on some Linux kernels. (Seems to be this bug)

To troubleshoot modem communication and baud rate settings, use minicom (or screen) to open a session over serial and try different settings (or read your modem's manual!). Sending the command 'AT' followed by a new line should result in your modem replying 'OK'.
If you're getting nothing at all out of your modem, perform a serial loopback test

If mgetty is not answering incoming calls, it may be having trouble communicating with your modem. Check the logs in /var/log/mgetty/ to determine the problem. You may need to set a modem initialization string in the mgetty device config file, so check your modem's manual for help on this.