Recent versions of the Raspberry Pi Imager Tool allow customization using cloud-init config and netplan files that are seeded on the boot partition of the sd card as part of writing the image. These files can be edited before booting the pi for the first time, with customizations that will run automatically at first boot.
To automatically pre-configure the pi SD card image for use with the ConnectedIO CM4NA modem, and tailscale do the following:
- Generate an auth key from the Tailscale Admin Console (Settings -> Keys -> Generate auth key) copy and save for later
- Plug in the CM4NA Modem (both data and power) to the Pi. Mode should be AT#USBCFG=0 (default from factory)
- Choose the Pi Model (e.g. Raspberry Pi 4)
- Choose the Pi OS (recommend Raspberry Pi OS (other) -> Raspberry Pi OS Lite (64-bit)
- Continue as normal up to the Write Image confirmation page
- Click APP OPTIONS and de-select Eject media when finished (we are going to edit 2 files before ejecting)
- Save options and write to flash device as usual
- after write image completion, open the newly written drive (appears as 'bootfs' in the drive list)
- edit the file network-config, add the following section at the end of the file - change apn to your carrier apn string (e.g. 'vzwinternet' or 'cbc135')
modems:
ttyACM0:
renderer: NetworkManager
dhcp4: true
apn: "CHANGEME"
- save the file and open the file user-data and add the following lines
- Summary of changes (see complete file below)
- add the following under packages: modemmanager, minicom, python3-pip
- check
timezone: value - under the rpi: -> interfaces: section add
spi:trueandi2c:true - add the remaining sections below, fill in the auth key with value from before
#cloud-config
manage_resolv_conf: false
hostname: CHANGEME
manage_etc_hosts: true
packages:
- avahi-daemon
- modemmanager
- minicom
- python3-pip
apt:
preserve_sources_list: true
conf: |
Acquire {
Check-Date "false";
};
timezone: America/Denver # Central is America/Chicago and Eastern is America/New_York
keyboard:
model: pc105
layout: "us"
users:
- name: pi
groups: users,adm,dialout,audio,netdev,video,plugdev,cdrom,games,input,gpio,spi,i2c,render,sudo
shell: /bin/bash
lock_passwd: false
plain_text_passwd: CHANGEME
enable_ssh: true
ssh_pwauth: true
rpi:
interfaces:
serial: true
spi: true
i2c: true
runcmd:
# One-command install, from https://tailscale.com/download/
- ['sh', '-c', 'curl -fsSL https://tailscale.com/install.sh | sh']
# Generate an auth key from your Admin console
# https://login.tailscale.com/admin/settings/keys
# and replace the placeholder below
- ['tailscale', 'up', '--auth-key=CHANGEME']
bootcmd:
- [ systemctl, restart, systemd-timesyncd ]
- [ /bin/sleep, "5" ]
ntp:
enabled: true
servers:
- pool.ntp.org
power_state:
mode: reboot
delay: now
timeout: 300 # wait up to 5min for all modules to complete then reboot
condition: true
- save and close file, eject sd card and boot pi + modem. Automated process will take 2-3min.
- After final reboot, ssh into the pi and confirm modem is connected
- ip a
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 88:a2:9e:44:10:26 brd ff:ff:ff:ff:ff:ff
3: wwan0: <BROADCAST,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:00:11:12:13:14 brd ff:ff:ff:ff:ff:ff
4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 88:a2:9e:44:10:27 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.234/24 brd 192.168.1.255 scope global dynamic noprefixroute wlan0
valid_lft 84603sec preferred_lft 84603sec
inet6 fe80::8aa2:9eff:fe44:1027/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
5: tailscale0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 100.79.146.45/32 scope global tailscale0
valid_lft forever preferred_lft forever
inet6 fd7a:115c:a1e0::2038:922d/128 scope global
valid_lft forever preferred_lft forever
inet6 fe80::6f14:4721:1704:6dc9/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
6: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 3
link/ppp
inet 100.64.102.200/32 scope global ppp0
valid_lft forever preferred_lft forever
- mmcli
pi@platetestr:~ $ mmcli -L
/org/freedesktop/ModemManager1/Modem/0 [Telit] LE910-NA V2
pi@platetestr:~ $ mmcli -m 0
----------------------------------
General | path: /org/freedesktop/ModemManager1/Modem/0
| device id: ec923033531d78c859d31c1960c860f34f310205
----------------------------------
Hardware | manufacturer: Telit
| model: LE910-NA V2
| firmware revision: 20.00.505
| supported: gsm-umts, lte
| current: gsm-umts, lte
| equipment id: 358148064849321
----------------------------------
System | device: /sys/devices/platform/axi/1000120000.pcie/1f00300000.usb/xhci-hcd.1/usb3/3-2
| physdev: /sys/devices/platform/axi/1000120000.pcie/1f00300000.usb/xhci-hcd.1/usb3/3-2
| drivers: cdc_acm, cdc_ncm
| plugin: telit
| primary port: ttyACM0
| ports: ttyACM0 (at), ttyACM1 (ignored), ttyACM2 (ignored),
| ttyACM3 (at), ttyACM4 (ignored), ttyACM5 (ignored), wwan0 (net)
----------------------------------
Status | unlock retries: sim-pin (3), sim-puk (10), sim-pin2 (3), sim-puk2 (10)
| state: connected
| power state: on
| access tech: lte
| signal quality: 42% (recent)
----------------------------------
Modes | supported: allowed: 3g; preferred: none
| allowed: 4g; preferred: none
| allowed: 3g, 4g; preferred: none
| current: allowed: 3g, 4g; preferred: none
----------------------------------
Bands | supported: utran-5, utran-2, eutran-2, eutran-4, eutran-5, eutran-12,
| eutran-13, eutran-17
| current: utran-2, eutran-2
----------------------------------
IP | supported: ipv4, ipv6, ipv4v6
----------------------------------
3GPP | imei: 358148064849321
| operator id: 310410
| operator name: FloLive
| registration: roaming
| packet service state: attached
----------------------------------
3GPP EPS | ue mode of operation: csps-1
| initial bearer path: /org/freedesktop/ModemManager1/Bearer/0
| initial bearer ip type: ipv4v6
----------------------------------
SIM | primary sim path: /org/freedesktop/ModemManager1/SIM/0
----------------------------------
Bearer | paths: /org/freedesktop/ModemManager1/Bearer/1
- confirm tailscale is connected from admin console and running
tailscale status