feat(hosts): add the Raspberry Pi Zero 2 W Psion sidecar
CI / flake (push) Skipped
CI / flake (pull_request) Successful in 4m16s
CI / flake (push) Skipped
CI / flake (pull_request) Successful in 4m16s
A headless aarch64 companion for a Psion 5MX: PPP over RS232 with NAT out to wifi and a telnet login, plus a cleartext POP3/SMTP proxy for the Psion's mail client. - hosts/PiZero2W/: host config, serial-ppp.nix, email-proxy.nix, an SD-image variant, and a hardware-configuration.nix placeholder. - Host table entry on nixos-hardware's raspberry-pi-3 profile; the Zero 2 W is the Pi 3's BCM2837 SoC. nixpkgs' linuxPackages_rpi02w is deprecated and warns that the linux-rpi series is being removed in favour of nixos-hardware. - The host owns its firmware partition (hardware.raspberry-pi.firmware), which is what puts the disable-bt and uart0/ctsrts overlays in config.txt so /dev/ttyAMA0 is the RS232 header rather than Bluetooth. uboot.enable keeps the U-Boot -> extlinux boot path the rewritten config.txt would otherwise lose. - packages.aarch64-linux.zero2w-sd-image: the host's own configuration as an installable card. The board has no Ethernet and no free serial port, so a generic image would leave no way in. - The mail proxy comes from the legacy-email-proxy flake, which provides the package and the NixOS module; nothing about it is vendored here. - docs/hosts/pizero2w.md, plus README host table and shared-layer notes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1ff333a896
commit
a94a749f29
@@ -0,0 +1,89 @@
|
||||
# The serial half of the Psion sidecar: a PPP link to a Psion 5MX over
|
||||
# /dev/ttyAMA0 (RS232 level shifter on the GPIO header, 115200 8N1 with
|
||||
# RTS/CTS), masqueraded out of wifi, plus a telnet login for the Psion's
|
||||
# terminal client.
|
||||
#
|
||||
# Cleartext telnet and unauthenticated PPP are safe *only* because the link is
|
||||
# a two-node cable: the peer is a machine from 1999 that speaks no TLS. Nothing
|
||||
# here is exposed to wlan0.
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
# Point-to-point addresses for the serial link; nothing else routes here.
|
||||
piAddress = "10.0.0.1";
|
||||
psionAddress = "10.0.0.2";
|
||||
in
|
||||
{
|
||||
# pppd needs exclusive use of the port. NixOS starts a getty on any serial
|
||||
# console named in boot.kernelParams; ttyAMA0 is not one today, but disable it
|
||||
# explicitly so a later kernel-param change cannot silently steal the line.
|
||||
systemd.services."serial-getty@ttyAMA0".enable = false;
|
||||
|
||||
services.pppd = {
|
||||
enable = true;
|
||||
peers.psion.config = ''
|
||||
/dev/ttyAMA0
|
||||
115200
|
||||
${piAddress}:${psionAddress}
|
||||
|
||||
# Hardware flow control, matching the Psion's modem profile.
|
||||
crtscts
|
||||
|
||||
# A null-modem cable has no carrier detect and no peer to authenticate.
|
||||
local
|
||||
noauth
|
||||
|
||||
# The systemd unit is Type=notify, so pppd must stay in the foreground.
|
||||
nodetach
|
||||
lock
|
||||
|
||||
# Wait for the Psion rather than failing when it is unplugged, and keep
|
||||
# waiting for the next time it is plugged back in.
|
||||
passive
|
||||
persist
|
||||
maxfail 0
|
||||
holdoff 1
|
||||
|
||||
# Hand the Psion resolvers over the link, so its Internet profile can set
|
||||
# "get DNS from server = True" instead of hard-coding them.
|
||||
ms-dns 1.1.1.1
|
||||
ms-dns 8.8.8.8
|
||||
'';
|
||||
};
|
||||
|
||||
# The Psion's route to the internet. The original write-up used pppd's
|
||||
# proxyarp instead; NAT keeps the Psion out of the LAN broadcast domain and
|
||||
# does not depend on what the wifi router tolerates.
|
||||
networking.nat = {
|
||||
enable = true;
|
||||
externalInterface = "wlan0";
|
||||
internalIPs = [ "${psionAddress}/32" ];
|
||||
};
|
||||
|
||||
# Everything the Psion connects to (telnet here, POP3/SMTP in
|
||||
# ./email-proxy.nix) is reachable over the PPP link and nowhere else.
|
||||
networking.firewall.trustedInterfaces = [ "ppp0" ];
|
||||
|
||||
# The Psion's terminal client speaks telnet over TCP, which it renders far
|
||||
# better than the raw serial console. Socket-activated, one process per
|
||||
# connection; busybox's telnetd in inetd mode hands straight over to login.
|
||||
systemd.sockets.telnetd = {
|
||||
description = "Telnet login socket for the Psion";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
listenStreams = [ "${piAddress}:23" ];
|
||||
socketConfig = {
|
||||
Accept = true;
|
||||
# ppp0 (and with it 10.0.0.1) only exists while the Psion is connected;
|
||||
# FreeBind lets the socket be listening before that.
|
||||
FreeBind = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."telnetd@" = {
|
||||
description = "Telnet login for the Psion";
|
||||
serviceConfig = {
|
||||
ExecStart = "-${pkgs.busybox}/bin/busybox telnetd -i -l ${pkgs.shadow}/bin/login";
|
||||
StandardInput = "socket";
|
||||
StandardError = "journal";
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user