I've been lugging around an old Cisco 2620 Router with an NM-8AM analogue modem line card for a few years. I recently got a Cisco SPA122, and figured I might as well make a dial-up server.
The how
To get a computer with a dial-up modem "online", you need the following:
- A computer with a dial-up modem (duh!)
- A phone line (or equivalent)
- Some modems allow you do pretend the line is already connected to another modem (skipping the dial tone, dialling, answer phase).
- A dial-up "server" that answers the call and sets up the PPP session.
The Phone Line
There are projects on the internet to build a "phone line emulator" as an electronics project, but as phone lines aren't just "here's a boring wire with some voltage on it" there's actually quite a bit involved. I decided a while ago that it wasn't worth it, and figured I could find other ways of getting data to and from old computers (up to and including pulling the drives out).
Commercial ones do exist, but you'd either have to luck into one, or pay a lot of money for it.
Enter "Analogue Telephony Adaptors". These are little boxes that you plug one port into an Ethernet connection into your normal IP network, and gives you a certain number of "FXS" (old phone) ports. They are typically designed for use with old phones that can't / won't be replaced with IP Phones, or devices like Fax Machines or Alarm systems.
In my case, I obtained an SPA122 that work was going to dispose of. I used Cathode Ray Dude / Gravis' SPA122 dial-through guide to configure my SPA122 to act as the phone line emulator.
I also have an SPA8000 "Small Business Voice Gateway", but I think I need a analogue phone to clear the carrier's config from it (thanks Cisco) [1], which I don't have.
On top of that, I applied some minor tweaks to make the phone line sound more Australian, which may or may not have made things a little bit more difficult later. [2]
My end goal would be to have the SPA122 "out and about", and when you dial into it, it starts a VoIP call with the SPA8000, which then is wired into the dial-up server. The SPA8000 has 8 ports, and my Cisco 2600 also has 8 ports, so it's made to be. If I can configure the 8 ports in a ring group, that'd mean I wouldn't even need to change the phone number I dial.
The Dial-up Server
Configuring dial-in
There are several guides on the internet that walk you through setting up a dial-up server on Windows Server (Using RRAS) or Linux (getty and PPPD et al.), but all of these crucially require modems. I don't have any external modems handy, only modems on the computers that I want to connect to the network. Since I need to connect them to the internet, it doesn't make much sense to use them as a gateway.
Plus, if I did that, then why was I dragging the 2600 around with me for years?
The Cisco 2620 I have contains a NM-8AM modem card, which contains 8 Analogue Modems. It had IOS 12.2(2)T1 installed on it's weird 16MB SIMM flash card, and 16MB of RAM.
Following an example I had to dig out of the Internet Archive (thanks Cisco) I was able to configure "Dialin". Cisco allows these modems to "dialout" either to call back another router, or to setup a backup connection, but we want "dialin" so that devices can connect to this device.
That got me as far as "hell yeah, I can connect with dial up to the router", but I'd still need to configure the IP side of the equation.
With some minor tweaks, I was able to get basic routing going, and after adding a static route to my router, I was able to get out to the internet! Yay!
There was a slight issue in that every session would be disconnected after 2 minutes. Thankfully, removing the dialer in-band from the interface group solved it. [3]
As a side note, the NM-8AM is only capable of 33.6K dial-up. 56K dial-up is available on the NM-8AM-V2. Since 56K is something akin to T1 (on the download side), 33.6K is also as good as you'll get with normal modem to modem connections as well. In this case, I'm only getting 21.6K, likely due to the digital compression being done by the SPA122.
As much as this worked fine, I wanted more!
Compression
PPP Supports data compression. The router and Windows 9x onwards support the mppc compression protocol. To turn that on, simply add compress mppc into the interface Group-Async1 section (or the other interface name / group you have configured).
Note that this resulted with compression only on the computer's sending side, not on the router's sending side (which is arguably more useful to us).
You can check this by right clicking the connection (either the icon in the notification area, or in the connections "folder") and selecting Status.
I wasn't able to find a reason for this, as predictably, posts online about using specialist hardware from 2001, to set up a dial-up ISP, aren't exactly common.
However, after finding release notes for a newer version of the firmware (because Cisco have scrubbed the router out of the main sections of their websites, thanks Cisco) [4], and finding a repository of random images someone's saved (because Cisco have removed the 2600 from their firmware pages, thanks Cisco), figuring out the meaning of the release types (I suppose to lock features behind firmware availability? Still thanks Cisco), finding out which version number is actually newest (thanks Cisco), and then finding an image small enough to fit on the flash "SIMM" (why couldn't they use a CompactFlash like their other devices? thanks Cisco), I settled on installing c2600-ipbasek9-mz.124-17.bin.
You can refer to the upgrade guide which is still online, but still difficult to find (thanks Cisco).
After that upgrade was done, and a few erroneous options were removed, we had version 12.4(17) on the router. I tested it, and other than the initial screechy dial-up negotiation being more unreliable, we had functioning compression, going both ways!
Fixing the dial-up negotiation / handshaking reliability was simply a case of modem country microcom_hdms australia.
NAT
I wanted to be able to take this 2600 to another network (or even another part of my network) and not have to spend too long reconfiguring it. As the 2600 was at this stage, I had it plugged into my "workstation" VLAN which meant that anything that wanted to talk to clients behind the the 2600, would need to have a static route defined.
I could (and probably will in the future) put the router on it's own VLAN, thus forcing everything to go through my home router first.
However, I knew NAT should have been possible, and I wanted the ability to take it to a hackathon or a LAN party or something.
Now, Cisco, understandably, considers NAT to be a few different things. There's "static" NAT which is more like port-forwarding, but for whole IP addresses (one "real" inside IP maps 1:1 to a "fake" outside IP). "Dynamic" NAT refers to 1:1 inside to outside IP mapping (like static), but based on a pool of IP addresses and allocated dynamically. Finally, there's "Port Address Translation" or "overload" NAT. This is what most people (who know what NAT is) think of - one or many "real" IP addresses get their connections mapped to a single "outside" IP on-demand. Since I wanted this to be essentially plug and play, I needed to use the overload option.
The manuals and most "CCNA" resources will tell you to use the following commands to setup a single IP "pool", an ACL to scope the addresses that should be NAT'd, and which interfaces are on what side of the NAT:
access-list << ACL NUMBER >> permit << INTERNAL SUBNET >> 0.0.0.255 ip nat pool << POOL NAME >> << OUTER IP ADDRESS >> << OUTER IP ADDRESS >> prefix-length << PREFIX LENGTH >> ip nat inside source list << ACL NUMBER >> pool << POOL NAME >> overload interface << WAN INTERFACE >> ip nat outside interface << LAN INTERFACE >> ip nat inside
However, the moment I put the last command in, the clients would lose connectivity. If I tried pinging, I would get << ROUTER ADDRESS >>: Destination host unreachable.
It turns out, that << PREFIX LENGTH >> (of which I was setting to "30") is not a subnet mask specific to the address range you're giving the NAT pool but instead the subnet mask of that subnet. Since that address was on my workstation LAN, which was a /24, I should have used "24" there. Once I fixed that, it started working.
That doesn't appear to be explained on the references I found, so once again, thanks Cisco.
However, there is one issue with this config - we need to update the ip nat pool configuration each time we get a new IP address. There is actually a "DHCP-friendly" NAT configuration [5]:
access-list << ACL NUMBER >> permit << INTERNAL SUBNET >> 0.0.0.255 ip nat inside source list << ACL NUMBER >> interface << WAN INTERFACE >> overload interface << WAN INTERFACE >> ip nat outside interface << LAN INTERFACE >> ip nat inside
This looked like the following for me:
access-list 2 permit 172.16.0.0 0.0.0.255 ip nat inside source list 2 interface FastEthernet0/0 overload interface FastEthernet0/0 ip nat outside interface Group-Async1 ip nat inside
Now I don't need to update the NAT config with a different IP address!
DHCP Config
Now that we have NAT setup, lets update the config for the rest of the router:
no ip name-server no ip route 0.0.0.0 0.0.0.0 << ROUTER >> interface FastEthernet0/0 ip dhcp client hostname C2600-8AM ip address dhcp
This will set up the router's operating system to get it's IP address from DHCP, and also configure it's default route and DNS server list from the details in the DHCP lease.
Unfortunately it doesn't look like we can automatically update the config we give the PPP clients, so you'll either want to use DNS servers that are either public or accessible regardless of the network segment the router might end up on.
PPP multilink
There's one last thing I want to configure: PPP multilink. This allows a client to make multiple connections (e.g. with multiple modems) and have them "teamed" so that the total bandwidth of the connection increases.
There's two main parts to this config - we need to enable multilink on the main connection (in this case the Group-Async1 group), define a new "group" for multilink connections, and lastly specify which group multilink connections should use:
interface Group-Async1 ppp multilink interface Virtual-Template1 ip unnumbered Loopback0 ip nat inside no ip mroute-cache peer default ip address pool DIALIN compress mppc ppp authentication chap ppp multilink multilink virtual-template 1
Note that interface Virtual-Template1 is essentially a copy of the existing Group-Async1 config, minus encapsulation ppp, async mode dedicated, ppp multilink (naturally), and group-range 33-40.
I didn't have multiple modems on one device to test with, but this does satisfy Windows enough to say it's enabled in the details tab of the status window.
The whole config
I ended up with the following:
(Telnet password is password and enable password is enable)
version 12.4 no parser cache service timestamps debug datetime msec service timestamps log uptime no service password-encryption ! hostname c2600-8am ! boot-start-marker boot-end-marker ! enable secret 5 $1$kz66$ze3JXPGB87jNwY35OfN2B. enable password password ! no aaa new-model memory-size iomem 20 modem country microcom_hdms australia ip cef ! ! ! ! no ip domain lookup ip multicast-routing multilink virtual-template 1 async-bootp time-server << NTP SERVER >> async-bootp dns-server << DNS 1 >> << DNS 2 >> ! ! ! username abc password 0 abc ! ! ! ! interface Loopback0 ip address 172.16.0.1 255.255.255.0 ! interface FastEthernet0/0 ip dhcp client hostname C2600-8AM ip address dhcp ip nat outside speed auto full-duplex ! interface Virtual-Template1 ip unnumbered Loopback0 ip nat inside no ip mroute-cache peer default ip address pool DIALIN compress mppc ppp authentication chap ppp multilink ! interface Group-Async1 ip unnumbered Loopback0 ip nat inside encapsulation ppp no ip mroute-cache async mode dedicated peer default ip address pool DIALIN compress mppc ppp authentication chap ppp multilink group-range 33 40 ! ip local pool DIALIN 172.16.0.11 172.16.0.19 ip forward-protocol nd ! no ip http server no ip http secure-server ip nat inside source list 2 interface FastEthernet0/0 overload ! logging trap debugging logging source-interface FastEthernet0/0 logging << SYSLOG SERVER >> access-list 2 permit 172.16.0.0 0.0.0.255 dialer-list 1 protocol ip permit no cdp run ! control-plane ! ! line con 0 password abc autoselect ppp flowcontrol hardware line 33 40 modem InOut line aux 0 line vty 0 4 session-timeout 1200 exec-timeout 1200 0 password password login transport input none line vty 5 15 password password login transport input telnet ! ntp server << NTP SERVER >> ! end
The group-range in interface Group-Async1 needs to match the interface numbers of your NM-8AM.
The dial-up client
With all of that config done, I created a new dial-up connection on Windows 2000, told it to use the internal modem, dial the number that was set in the SPA122, and use the credentials of abc:abc.
No extra config is really required, but it might be worth checking that PPP multilink and compression is turned on.
References / Further reading
[1] | https://web.archive.org/web/20230227133112/https://community.cisco.com/t5/voice-systems-and-accessories-small-business/spa8000-user-and-password/td-p/1914812 |
[2] | https://www.maxo.com.au/support/configuration-guides/desk-phones/cisco/cisco-ata-faxing-guide See "Regional Settings" section. |
[3] | https://web.archive.org/web/20230301094910/https://community.cisco.com/t5/vpn/connection-keeps-dropping-on-dial-in-session/td-p/465242 |
[4] | https://web.archive.org/web/2/https://www.cisco.com/c/en/us/td/docs/ios/12_2/12_2x/12_2xl/release/notes/rn2600xl.html |
[5] | https://web.archive.org/web/2/https://community.cisco.com/t5/switching/dhcp-on-outside-interface-with-nat/td-p/1748357 |