@lkh@social.sdfeu.org, @kyonshi@dice.camp and I have been trying to connect our servers using old tech for quite a while.
The latest effort has been in connecting our servers using *Unix to Unix copy* (UUCP). The benefit is that once you have that, you can also have *remote command execution over UUCP* using `uux` and it is as terrifying as it sounds.
Let's see whether I can reconstruct my setup.
I use Debian.
lkh has a "travelling laptop" that is mostly offline, but sometimes it's online. That's when he wants to exchange stuff with us. The laptop is called Dwalin.
My server is Campaign Wiki.
The documentation for peering between news servers via UUCP is available via `man 8 send-uucp`.
This allows Dwalin to connect via ssh.
lkh sent me this.
# dwalins public key, ssh executes the remote # uucico and hands over my login: restrict,command="/usr/sbin/uucico -u Udwalin -l" ssh-rsa another-long-string-of-stuff uucp@dwalin
This is where Dwalin's password is stored. This is important because there's no actual Dwalin user on my system.
lkh sent me this.
# dwalins login on campaignwiki Udwalin some-long-string-of-stuff
I kept the defaults and added Dwalin.
# dwalins system entry, no Port or # credentials are given, since dwalin # is expected to always call in. system dwalin commands rmail rnews rsmtp called-login Udwalin local-send / local-receive /var/spool/uucppublic remote-send / remote-receive /var/spool/uucppublic time any forward ANY protocol i
I don't have a modem so I commented out all the stuff I don't need and just left this:
port TCP type tcp
This is where I set my own node name. Everything else is left to defaults.
nodename campaignwiki
In our case, lkh's Dwalin is connected to kyonshi's Erebor system and here's me sending a file to Erebor via Dwalin (since I'm not connected to Erebor directly):
uucp some-local-file 'dwalin!ereborbbs.duckdns.org!~/'
Yes, we want to exchange news. That means we need to install INN.
Look at the requisites:
perldoc /usr/lib/news/bin/send-uucp.pl
This define the sites to send news to, how to compress them and how big the batches should be.
Add the following:
dwalin gzip 1048576
Determine the newsgroups to send to Dwalin:
# newsfeed entry for dwalin dwalin\ :casa.*,campaignwiki.*,erebor.*\ :Tf,Wnb,B4096/1024:
Add the new newsgroups. We don't do control messages.
Use `ctlinnd` to control the INN daemon.
ctlinnd newgroup erebor.talk y ctlinnd newgroup erebor.test y
Give the new newsgroups a tag line.
Add the following:
erebor.talk General talk for EreborBBS erebor.test Testing connectivity with EreborBBS
Make sure the users connecting via NNTP can read the new groups, too. This is not necessary if you read news via the local spool, I think.
Add `erebor.*` to the "readonly" section.
auth "foreignokay" { auth: "ckpasswd -f /var/lib/news/newsusers" default: "<unauthenticated>" } access "authenticatedpeople" { users: "*" newsgroups: "*,!junk,!control,!control.*" } access "readonly" { users: "<unauthenticated>" read: "local.*,campaignwiki.*,casa.*,cosmic.*,erebor.*,rec.*,de.*,alt.*" }
Check `uulog`. Here's where a news article is put into the queue and a few minutes later, Dwalin calls and the enqueued article is sent:
uux dwalin news (2024-06-15 10:22:01.34 3832004) Queuing rnews (D.000R) uucico - - (2024-06-15 11:05:07.00 3842142) Incoming call (login Udwalin port stdin) uucico dwalin - (2024-06-15 11:05:07.05 3842142) Handshake successful (protocol 'i' sending packet/window 1024/16 receiving 1024/16) uucico dwalin news (2024-06-15 11:05:07.05 3842142) Sending rnews (D.000R) (1548 bytes) uucico dwalin - (2024-06-15 11:05:07.10 3842142) Protocol 'i' packets: sent 8, resent 0, received 6 uucico dwalin - (2024-06-15 11:05:07.10 3842142) Call complete (0 seconds 1548 bytes 0 bps)
Oh yes, we do.
Debian comes with Exim. Exim uses Perl's "taint" mechanism wherein user-supplied values cannot be used for commands. They must be untainted by a lookup. For example, a user supplied sender name like "alex" is tainted, but if you look it up in `/etc/passwd` it becomes untainted. Perl keeps track of this for you, if you want to. Once you run into the error, however, you need to figure out where you could be looking up the values you have. Is the local part a user on the system, is the domain a local domain? I spent way too much time on this.
This is the file generated by `update-exim4.conf`.
The result of me answering the questions:
dc_eximconfig_configtype='local' dc_other_hostnames='alexschroeder.ch;campaignwiki.org;communitywiki.org;transjovian.org;campaignwiki' dc_local_interfaces='127.0.0.1 ; ::1' dc_readhost='' dc_relay_domains='' dc_minimaldns='false' dc_relay_nets='' dc_smarthost='' CFILEMODE='644' dc_use_split_config='true' dc_hide_mailname='' dc_mailname_in_oh='true' dc_localdelivery='mail_spool'
That is to say: it only handles local mail and mail via UUCP and NNCP, not SMTP.
A new router for UUCP mail that has to come before `200_exim4-config_primary`. If it comes after the primary, then it won't work because the primary router ends with `no_more` and as the comment at the end of the file says:
The `no_more` above means that all later routers are for domains in the local_domains list
This router only accepts mail destined for domains listed in the new file `/etc/exim4/uucp` and passes it to the `rmail` transport (see below).
### uucp ### based on /usr/share/doc/exim4-base/README.Debian.gz uucp_router: debug_print = "R: uucp_router for $local_part@$domain" driver=accept require_files = +/usr/bin/uux domains = wildlsearch;/etc/exim4/uucp transport = rmail
This is a file that translates the domain names I use for recipients to UUCP names.
dwalin dwalin dwalin.uucp dwalin erebor dwalin!erebor
This means that a mail for `lkh@dwalin` gets recognised as such (because of the first column) and it will be sent to the UUCP system `dwalin` (because of the second column).
The UUCP system `dwalin` is correct because `/etc/uucp/sys` has a section for `system dwalin` (see above).
The route above says that the transport to use is `rmail`.
Define this using a new transport config file:
rmail: debug_print = "T: rmail for $pipe_addresses" driver=pipe command = /usr/bin/uux - -r -a${lookup{$sender_address_local_part}lsearch,ret=key{/etc/passwd}} -gC $domain_data!rmail $pipe_addresses return_fail_output user=uucp
This was the biggest problem for me. The examples I saw for the `-a` argument to `uux` used `$sender_address`, resulting in an error about the third argument to `uux` being tainted. You can see these error messages in the exim main log (followed by a log entry showing that exim sends me a en error message):
2024-06-15 00:37:11 1sIFXj-00CzBd-26 <= alex@alexschroeder.ch U=alex P=local S=461 2024-06-15 00:37:11 1sIFXj-00CzBd-26 ** lkh@dwalin R=uucp_router T=rsmtp: Tainted arg 3 for rsmtp transport command: '-aalex@alexschroeder.ch' 2024-06-15 00:37:11 1sIFXj-00CzBh-2Q <= <> R=1sIFXj-00CzBd-26 U=Debian-exim P=local S=1695 2024-06-15 00:37:11 1sIFXj-00CzBd-26 Completed 2024-06-15 00:37:11 1sIFXj-00CzBh-2Q => alex <alex@alexschroeder.ch> R=local_user T=mail_spool 2024-06-15 00:37:11 1sIFXj-00CzBh-2Q Completed
I guess the examples I had seen would only work for older Exim versions that didn't do taint checking.
The code I'm using means that I'm looking up the sender local part ("alex" or "root") in `/etc/passwd` and if a match is found, the untainted key is returned (instead of the value from the password list).
You can test these expressions on the command-line:
exim -d+all -be '${lookup{$sender_address_local_part}lsearch,ret=key{/etc/passwd}}'
I also used to have rsmtp there, with `use_bsmtp` and `batch_max=100`. But who knows, perhaps that doesn't work all that well. Let's use `rmail` instead.
As an ordinary user, use `mail` on the command line to send mail to `lkh@dwalin`.
Poor `lkh`. So many test mails.
As `root`, check the exim log:
root@sibirocobombus:~# tail /var/log/exim4/mainlog
Here's a mail being enqueued successfully:
2024-06-15 14:08:42 1sISD4-00GIbQ-1a <= alex@alexschroeder.ch U=alex P=local S=513 2024-06-15 14:08:42 1sISD4-00GIbQ-1a => lkh <lkh@dwalin> R=uucp_router T=rmail 2024-06-15 14:08:42 1sISD4-00GIbQ-1a Completed
Note the `uucp_router` and the `rmail` transport being used.
Check `uulog`. Here's where four mails are put into the queue and a few minutes later, Dwalin calls the enqueued messages are sent:
uux dwalin uucp (2024-06-15 09:50:47.05 3824697) Queuing rmail (D.000N) uux dwalin uucp (2024-06-15 09:53:57.11 3824786) Queuing rmail (D.000O) uux dwalin uucp (2024-06-15 09:53:57.14 3824790) Queuing rmail (D.000P) uux dwalin uucp (2024-06-15 09:53:57.16 3824794) Queuing rmail (D.000Q) uucico - - (2024-06-15 10:05:09.11 3828242) Incoming call (login Udwalin port stdin) uucico dwalin - (2024-06-15 10:05:09.16 3828242) Handshake successful (protocol 'i' sending packet/window 1024/16 receiving 1024/16) uucico dwalin uucp (2024-06-15 10:05:09.16 3828242) Sending rmail (D.000N) (552 bytes) uucico dwalin uucp (2024-06-15 10:05:09.16 3828242) Sending rmail (D.000O) (538 bytes) uucico dwalin uucp (2024-06-15 10:05:09.16 3828242) Sending rmail (D.000P) (530 bytes) uucico dwalin uucp (2024-06-15 10:05:09.16 3828242) Sending rmail (D.000Q) (545 bytes) uucico dwalin - (2024-06-15 10:05:09.21 3828242) Protocol 'i' packets: sent 14, resent 0, received 10 uucico dwalin - (2024-06-15 10:05:09.23 3828242) Call complete (0 seconds 2165 bytes 0 bps)
#Administration #UUCP