I’ve been playing around with dial-up modems for about a year now and while I found it relatively easy to get software configured to run a dial-up ISP, I had trouble finding documentation to configure things so you can dial into a BBS or a text adventure game. Ultimately, I realized that I wanted something that enabled me to dial into a machine, and have the machine connect my local terminal up to something over telnet without too much user interaction. This would be a versatile solution to allow easy connection to existing remote servers or anything I wanted to run locally. Unexpectedly, a lot of current software does not have native remote-access via modem.

I found a post on reddit from someone who claimed to have accomplished what I wanted and they were kind enough to share some of their config with me, so I must credit /u/babtras for the heavy lifting.

Basically, mgetty can be leveraged to handle incoming calls from a modem and pass things off to another application. Normally, or at least in the old days, you would want to point to /bin/login so that the dial-in user could log onto the system with their user account, but instead we can run telnet and have the user connect to a BBS or any of the many things you can access over telnet.

Note that with the configuration below, the user will not automatically be forwarded to a telnet session as soon as they call in and must enter some text for connection. This is useful as we can create a makeshift “menu” so the user can choose from multiple destinations, but could be annoying if you expect things to work seamlessly. From what I understand this is a limitation of using mgetty which has configuration focused on users, but if someone knows how to work around this please let me know!

I opted to use a Raspberry Pi running Raspbian Lite and a Hayes Courier modem connected to the Pi using a DB25/DE9 adapter and a USB/serial adapter. This modem, and another that I will be testing with, are connected to a PBX to facilitate telephony between them. You could probably accomplish the same thing with a multi-line ATA or a phone line simulator.

A Pair of US Robotics Couriers.

A Pair of US Robotics Couriers.

To set up the Pi the first thing we need to do is install mgetty and telnet (when did they decide to not include telnet on new installs?):

$ sudo apt install -y mgetty telnet

Now we want to create a systemd service so that mgetty will continue to handle sessions as users dial in (note the @ in the filename):

$ sudo nano /lib/systemd/system/mgetty@.service

We can use the following service template, which I have shamelessly stolen from Doge Microsystems:

[Unit]
Description=External Modem %I
Documentation=man:mgetty(8)
Requires=systemd-udev-settle.service
After=systemd-udev-settle.service

[Service]
Type=simple
ExecStart=/sbin/mgetty /dev/%i
Restart=always
PIDFile=/var/run/mgetty.pid.%i

[Install]
WantedBy=multi-user.target

Now we want to edit /etc/mgetty/mgetty.config and replace the entire contents with the following (note that the speed may depend on your particular modem):

debug 9
speed 115200
issue-file /etc/issue.mgetty
login-prompt Selection [fozz] [zork] or [recamp]:

port ttyUSB0
rings 1
debug 3
data-only y

Next, we edit /etc/mgetty/login.config and replace the entire contents with the below. This “tricks” mgetty into considering “fozz,” “zork,” and “recamp” as users and spawning telnet sessions when our dial-in user enters them instead of the usual /bin/login:

fozz - - /usr/bin/telnet bbs.fozztexx.com
zork - - /usr/bin/telnet multizork.icculus.org
recamp - - /usr/bin/telnet bbs.retrocampus.com

Note that the existing default config in this file would allow callers to log in to the system using a username/password corresponding to an existing user account. Only include this line if you know what you are doing:

*      -       -       /bin/login @

Our config is done so now we can enable and start the mgetty service for the modem by referencing the USB/Serial adapter it is plugged into (this is likely ttyUSB0, if it isn’t be sure to also update /etc/mgetty/mgetty.config):

$ sudo systemctl enable mgetty@ttyUSB0.service
$ sudo systemctl start mgetty@ttyUSB0.service

That’s it! Now you can place a modem-to-modem call and see if your client machine is able to connect to the server and ultimately some other entity over telnet.