Plugins are a modular way to extend sdm capabilities. Plugins are similar to Custom Phase Scripts, but can work both during customization and/or when burning an SSD/SD Card.
It makes sense to include some plugins into the IMG you're creating (e.g., postfix, samba) so they are installed onto every system burned from that IMG, but some are typically installed once per network (e.g., apt-cacher-ng), or not needed on every system. In that case you can use the plugin when burning the SSD/SD for that specific system.
The set of plugins provided with sdm are documented here.
Other plugins are planned. If there are any specific plugins you're interested in, let me know!
You can add your own plugins as well. Put your plugin script in /usr/local/sdm/local-plugins, and it will be automatically found. sdm looks at local-plugins first, so you can override an sdm-provided plugin with your modifications if desired.
You can also specify the plugin name with a full path. sdm will copy the plugin to /usr/local/sdm/local-plugins if it does not exist or the one specified is newer than the one in local_plugins.
Specify each plugin with a separate --plugin
switch:
sdm --plugin samba:"args" --plugin postfix:"args" . . .
Multiple --plugin
switches can be used on the command line. This includes specifying the same plugin multiple times (the apps
plugin, for example).
Another way to specify plugins is via the --plugin @/path/to/pluglist
, where pluglist
consists of plugin invocations, one per line, without the --plugin
switch. For example:
user:userlist=/rpi/etc/sdm/bls-users
system:name=0|systemd-config=timesyncd=/rpi/systemd/timesyncd.conf|eeprom=stable|sysctl=/rpi/etc/sysctl.d/01-disable-ipv6.conf|fstab=/rpi/etc/fstab.lan|motd=/dev/null
system:name=1||service-disable=apt-daily.timer,apt-daily-upgrade.timer,wpa_supplicant,avahi-daemon,avahi-daemon.socket,ModemManager,rsync,mdadm-shutdown
network:nmconn=/rpi/etc/NetworkManager/system-connections/eth0.nmconnection,/rpi/etc/NetworkManager/system-connections/homewifi.nmconnection|wifissid=myhomewifif|wifipassword=homewifipassword|wificountry=US
disables:triggerhappy|wifi|bluetooth|piwiz
quietness:consoleblank=300|noquiet=keep|nosplash=keep|noplymouth
L10n:host
When using a pluglist file the argument list should not be quoted ("
). This is only needed on the command line to keep bash from doing silly things.
Plugins are run in the order they are encountered on the command line or the plugin @file,
The complete plugin switch format is:
--plugin plugname:"key1=val1|key2=val2|key3=val3"
Enclose the keys/values in double quotes as above if there is more than one key/value or bash will be confused by the "|".
See below for plugin-specific examples and important information.
It is recommended that all files that you provide to sdm, whether on the command line or in arguments to a plugin, use full paths. For instance, to use a file in your home directory, don't use file
or ~/file
, use /home/<mylogin>/file
. Relative file paths generally work, but if you run into problems, switch to using a ful path.
It is not possible to use a tilde ("~") as an argument value for a plugin. A good example of this is for WiFi passwords for the network
plugin. In this case (and if you encounter any others) you must provide a fully-formed .nmconnection file. The tilde is used internally by sdm to separate a plugins concatenated together (in a string).
NOTE: An argument can only be used once per plugin invocation. This is not a problem with most plugins, but you might find a use for multiple uses in some plugins, such as bootconfig. This is discussed in the bootconfig
plugin.
Burn plugins are special plugins that are run after a burn has completed on a disk (--burn
) or disk image (--burnfile
). Only plugins designated as burn plugins in this document can be used with --burn-plugin
. sdm doesn't check whether a plugin is burn-plugin capable, so trying to use a non-burn-plugin as a burn-plugin will likely be interesting.
Burn plugins can also be used with --runonly plugins
to operate on an IMG or disk. The parted
plugin can be used in this manner.
sdm --runonly plugins --burn-plugin parted:"addpartition=2048,ext4" 2023-12-05-raspios-bookworm-arm64.img
sdm --runonly plugins --burn-plugin extractfs:"rootfs=/path/to/rootfs|bootfs=/path/to/bootfs" 2023-12-05-raspios-bookworm-arm64.img
There are a couple of plugin ordering issues to be aware of.
- The
user
plugin(s) should be the first plugin. Several other plugins expect this. - The
cryptroot
plugin must be after the graphics plugin in order to properly manage boot behavior during the encryption process - The
boot_behavior
final setting is order-sensitive. The last modification wins.- During the post-install phase, if
--plugin graphics
is used, thegraphics
plugin will set the boot behavior. If thegraphics
plugin is not used, this will run automatically at the end of the post-install phase.- If the display manager is lightdm,
boot_behavior
is set: B3 or B4 per the--autologin
switch - If the display manager is xdm or wdm,
boot_behavior
is set: B1 or B3 per the setting ofnodmconsole
- If the display manager is lightdm,
- Calling the
raspiconfig
plugin during burn and specifying theboot_behavior
argument will unconditionally set the new boot behavior
- During the post-install phase, if
sdm-plugin-template can be used to build your own plugin. It contains some code in Phase 0 demonstrating some of the things you can do with the plugin_getargs function and how to access the results.
Use the apps plugin to install applications. The apps plugin can be called multiple times on a command line or in a pluglist. The name can be any alphanumeric (including "-", "_", etc.) you want.
- apps — Specifies the list of apps to install or @filename to provide a list of apps (one per line) to install. Comments are indicated by a pound sign (#) and are ignored, so you can document your app list if desired. If the specified @filename is not found, sdm will look in the sdm directory (/usr/local/sdm).
- name — Specifies the name of the apps list. The default name is default. The
name
argument is a convenience and is not required. - remove — Specifies the list of apps to remove ofr @filename to provide a list of apps (one per line) to remove. The
remove
argument is processed before theapps
argument. If you try to remove an apt packge that doesn't exist it will log in /etc/sdm/apt.log and sdm will notify you at the end of the customize: '? apt reported errors; review /etc/sdm/apt.log'
--plugin apps:"remove=wolfram-engine|apps=emacs"
— Remove wolfram-engine, and install emacs--plugin apps:"apps=@my-apps" --plugin apps:"apps=@my-xapps"
— Install the list of apps in the file @my-apps, and the list of apps in @my-xapps--plugin apps:"apps=@my-apps|name=myapps" --plugin apps:"apps=@my-xapps|name=myxapps"
— Install the list of apps in the file @my-apps, and the list of apps in @my-xapps--plugin apps:"apps=@mycoreapps|name=core-apps"
--plugin apps:"apps=@myaddtlapps|name=extra-apps"
— Install the list of apps from @mycoreapps and @myaddtlapps
apt-addrepo adds Repos and gpgkeys to apt
- gpgkey — /path/to/keyname.gpg
- gpgkeyname — Provide a different filename for the key in /etc/apt/trusted.gpg.d
- name — Name of the repo file in /etc/apt/sources.list.d for a
repo
string - repo — A repo string that will be written to the named file in /etc/apt/sources.list.d
- repofile — File containing an apt repo that is copied to /etc/apt/sources.list.d
--plugin apt-addrepo:"repo=deb http://repo.feed.flightradar24.com flightradar24 raspberrypi-stable|gpgkey=/path/to/gpgkey.gpg"
--plugin apt-addrepo:"repofile=/path/to/some-repo.list"
apt-cacher-ng installs the RasPiOS apt-cacher-ng service into the IMG or onto the SSD/SD card (If used with --burn
).
NOTE: All arguments are optional
- gentargetmode — Possible values: 'Set up once', 'Set up now and update later', and 'No automated setup'. [Default: 'No automated setup']. TBH not sure what this does. If you figure it out, let me know ;)
- bindaddress — the IP address to which the server should bind. [Default: 0.0.0.0], which is all IP addresses on the server.
- cachedir — apt-cacher-ng directory. [Default: /var/cache/apt-cacher-ng]
- port — TCP port [Default: 3142]
- tunnelenable —Do not enable this. [Default: false]
- proxy —TBH not sure what this does. If you figure it out, let me know ;)
The default apt-cacher-ng server install uses port 3142. apt-cacher-ng will be enabled by sdm FirstBoot and ready to process requests after the FirstBoot process completes.
NOTE: The apt-cacher-ng plugin installs the apt-cacher-ng server. The --aptcache
command line switch configures the IMG to be an apt-cacher-ng client and use the specified apt-cacher-ng server.
The plugin configures apt as a client to use itself as the apt caching server. This is typically not what you want on every system, so consider using --plugin apt-cacher-ng
on the --burn
command line for those systems that will be actually be deployed as apt caching servers.
apt-file installs the apt-file command and builds the database. This is very handy for looking up apt-related information.
There are no --plugin
arguments for apt-file
The bootconfig
plugin configures the contents of /boot/firmware/config.txt.
-
comment — Append the comment to the end of config.txt. Comments can also be specified by an argument starting with
#
or\n
. In the latter case, the comment is transformed to\n# comment string
resulting in a blank line before the comment. -
inline — If
inline
is provided as an argument (does not take a value), the plugin will replace existing settings in config.txt (if they exist) with any new value provided to the plugin. If it doesn't exist, or ifinline
is not provided, new arguments are appended to the end of the file. -
reset — If
reset
is provided /boot/firmware/config.txt will be saved as /boot/firmware/config.txt.sdm. If no value is provided forreset
then /boot/firmware/config.txt will be set to a null file. Ifreset=/path/to/file
is provided, the specified file will replace /boot/firmware/config.txt. To work correctly,reset
must be specified before any other arguments (this is not enforced or specifically logged by sdm). -
section — The
section
argument takes a value likepi4
or[pi4]
, and appends the appropriately-bracketed section value to the end of config.txt preceded by a blank line. -
somename=somevalue — All other key/value settings are presumed to be settings in config.txt and added to it. There is no validity checking, so typos are propagated. But, on the other hand, the
bootconfig
plugin doesn't need to be updated every time a brand new setting is added to config.txt. NOTE: Eachsomename
can only be used once perbootconfig
plugin invocation. See the examples in the following section for further details.
--plugin bootconfig:"section=[pi4]|somesetting=somevalue"
--plugin bootconfig:"inline|hdmi_group=72|hdmi_force_hotplug=1|hdmi_mode=40|hdmi_ignore_edid"
— The plugin adds the correct value forhdmi_ignore_edid
(0xa5000080)--plugin bootconfig:"reset|dtparam=audio=on|camera_auto_detect=1|display_auto_detect=1|dtoverlay=vc4-kms-v3d|max_framebuffers=2|arm_64bit=1|disable_overscan=1|section=cm4|otg_mode=1|section=pi4|arm_boost=1|section=all"
— An identical replacement for the Bullseye /boot/config.txt but with no comments or blank lines
You may want to add multiple dtparam
items to config.txt, and be tempted to put all of them in a single invocation, such as:
--plugin bootconfig:"dtparam=fan_temp1=62500,fan_temp1_hyst=5000,fan_temp1_speed=128|dtparam=fan_temp0=55000,fan_temp0_hyst=5000,fan_temp0_speed=75"
This does not work. These must be broken up into separate plugin invocations:
--plugin bootconfig:"dtparam=fan_temp1=62500,fan_temp1_hyst=5000,fan_temp1_speed=128"
--plugin bootconfig:"dtparam=fan_temp0=55000,fan_temp0_hyst=5000,fan_temp0_speed=75"
Alternatively, you can use:
--plugin bootconfig:"dtparam=fan_temp1=62500,fan_temp1_hyst=5000,fan_temp1_speed=128,fan_temp0=55000,fan_temp0_hyst=5000,fan_temp0_speed=75"
RasPiOS has a line length limit of 98 for config.txt, and silently ignores characters beyond that length. The bootconfig plugin limits lines to 96 characters.
btwifiset is a service that enables WiFi SSID and password configuration over Bluetooth using a mobile app. Once the service is running, you can use the BTBerryWifi
iOS app to connect to the service running on your Pi and configure the WiFi. See https://github.com/nksan/Rpi-SetWiFi-viaBluetooth for details on btwifiset itself.
- country — The WiFi country code. This argument is mandatory
- localsrc — Locally accessible directory where the btwifiset.py can be found, instead of downloading from GitHub
- btwifidir — Directory where btwifiset will be installed. [Default: /usr/local/btwifiset]
- password — Password to use for encrypted bluetooth communication [Default: Host name on which btwifiset runs after boot]
- timeout — After timeout seconds the btwifiset service will exit [Default: 15 minutes]
- logfile — Full path to btwifiset log file [Default: Writes to syslog]
Chrony installs the chronyd time service.
- conf — /full/path/to/confname.conf that will be placed into /etc/chrony/conf.d
- conf2 — /full/path/to/confname2.conf that will be placed into /etc/chrony/conf.d
- conf3 — /full/path/to/confname3.conf that will be placed into /etc/chrony/conf.d
- sources — /full/path/to/sourcename.conf that will be placed into /etc/chrony/sources.d
- sources2 — /full/path/to/sourcename2.conf that will be placed into /etc/chrony/sources.d
- sources3 — /full/path/to/sourcename3.conf that will be placed into /etc/chrony/sources.d
- nodistsources — Removes the Debian vendor zone pool from chrony.conf
Chrony processes the files in the conf.d and sources.d directories on startup. Having 3 provides flexibility in how these are structured. See man chrony.conf
for details.
A RasPiOS system should only have one time service enabled. It's up to you to disable others. For instance, on a standard RasPiOS IMG you should add --svc-disable systemd-timesyncd
to disable the in-built time service, which is enabled by default.
NOTES:
- At least on Bookworm (didn't check earlier versions) installing chrony causes systemd-timesyncd to be removed.
- Adding
iburst
to aserver
orpool
statement in a sources file seems to result in chrony syncing the time much more quickly
The fake-hwclock provided with RasPiOS runs hourly as a cron job. clockfake does the same thing as fake-hwclock, but you control the interval, and it's always running. Lower overhead, less processes activated, and more control. Life is good.
- interval — Interval in minutes between fake hardware clock updates
Copy a directory tree from the host system into the IMG
- from — /full/path/to/sourcedir
- to — /full/path/to/destdir
- rsyncopts — Additional switches for the
rsync
command. Ifrsyncopts
is specified, ALL desired rsync switches must be included. Ifrsyncopts
is NOT provided, the default switch-a
is used - stderr — /path/to/file where stderr from the rsync command is written [D:/dev/null]
- stdout — /path/to/file where stdout from the rsync command is written [D:/dev/null]
The copydir plugin behavior is dependent on whether the from
file contains a trailing slash, just like the rsync command. The rsync man page states: A trailing slash on the source changes this behavior to avoid creating an additional directory level at the destination. You can think of a trailing / on a source as meaning "copy the contents of this directory" as opposed to "copy the directory by name", but in both cases the attributes of the containing directory are transferred to the containing directory on the destination.
Copy one or more files from the host system into the IMG
- from — /full/path/to/sourcefile on the host system
- to — /path/in/IMG to place the file in the IMG. This must be a directory, not a file. The directory must already exist
- chown — The
user:group
to set the file ownership - chmod — The mode to set the file protection (e.g., 755, 644, etc)
- mkdirif — Create the directory if it doesn't exist
- runphase — Normally files are copied to their final destinations in Phase 1. Use
runphase=postinstall
to have a single file copied in the post-install phase - filelist — The /full/path/to/file of a file on the host OS of a list of files to copy. See below.
The filelist=/full/path/to/file
option points to a file that consists of one line per file in the format:
from=/path/to/file|to=/some/dir|chown=user:group|chmod=filemode|runphase=postinstall
chown and chmod are optional. If not specified, the file attributes will not be set, and will be whatever they were on the host system. runphase
is optional, and if not specified, the file is copied in Phase 1.
copyfile copies the files into the IMG in /etc/sdm/assets/copyfile during Phase 0, and copies them into their target locations in the phase 1 or post-install phase (conditioned on runphase
) once all packages have been installed, all users have been added, etc.
--plugin copyfile:"from=/usr/local/bin/myconf.conf|to=/usr/local/etc"
The config file will be copied from /usr/local/bin/myconf.conf on the host system to /usr/local/etc/myconf.conf in the IMG during Phase1. The file will be owned by the same user:group as on the host, the file protection will be the same as well.--plugin copyfile:"filelist=/usr/local/bin/
. The list of files in the providedfilelist
will be processed per above.
Configures the rootfs for encryption. See Disk Encryption for complete details
- authkeys — Provides an SSH authorized keys file for use in the initramfs
- crypto — Specifies the encryption to use.
aes
used by default. Usexchacha
on Pi4 and earlier for best performance. - dns — DNS server address for the intramfs network client to use
- gateway — gateway address for the intramfs network client to use
- ihostname — hostname for the intramfs network client to use
- ipaddr — IP address for the intramfs network client to use
- keyfile — A keyfile used for passphrase-less booting. See Unlocking rootfs with a USB Keyfile Disk for details
- mapper — Mapper name for the rootfs encryption (shows up, for instance, in the
df
listing) - netmask — Network mask for the intramfs network client to use
- nopwd — Configure only a keyfile to unlock the rootfs. No passphrase will be configured. The
keyfile
argument is required - ssh — Enable SSH in the initramfs
- sshbash — Leave bash enabled in the SSH session rather than switching to the captive cryptroot-unlock (DEBUG only!)
- sshport — Use the specified port rather than the Default 22
- sshtimeout — Use the specified timeout rather than the Default 300 seconds
- uniquesshkey — Use a unique SSH key in the initramfs. Default is to use the host SSH key (of the system being encrypted)
authkeys
is required with ssh
These are discussed further in the above-mentioned Disk Encryption page.
--plugin cryptroot:"authkeys=/home/bls/.ssh/authorized_keys|ssh
Configures the rootfs for encryption and enables SSH into the initramfs with keys authorized in the named authorized_keys file.
The disables plugin makes it easy to disable a few complex functions.
- bluetooth — Disables bluetooth via a blacklist file in /etc/modprobe.d
- piwiz — Disables piwiz during the first system boot. You must set up everything with sdm that piwiz does or you may not like the results: User, Password, Keymap, Locale, and Timezone.
- triggerhappy — Disable the triggerhappy service. If you're not using it, this will eliminate the log spew it creates
- wifi — Disables WiFi via a blacklist file in /etc/modprobe.d
--plugin disables:"bluetooth|piwiz|triggerhappy"
— Disable Bluetooth, Triggerhappy, and piwiz, but leave WiFi enabled
Installs Docker per the Docker install guide.
This plugin has no arguments
--plugin docker-install
The dovecot-imap
installs and configures dovecot as an imap server.
These arguments are for configuring the openssl cert that is generated. They are all optional at the moment.
- email-address — Specify the email address to include in the generated SSL Cert
- common-name — Specify the common name to include in the generated SSL Cert
- org-name — Specify the org name to include in the generated SSL Cert
--plugin dovecot-imap:"email-address=root@mydomain.com|common-name=MyCommonName.com|org-name=MyOrgname"
--plugin dovecot-imap
The explore
plugin is a --burn-plugin
that can be used to explore or mount the newly-burned device after the burn has completed.
- mount — Mount the device into the host system rather than exploring the device container
--burn-plugin explore
— After the burn completes mount the device and enter the container.--burn-plugin explore:mount
— Like the previous example, but does not enter the container and operates in the context of the host system.
The extractfs
plugin is a non-general purpose --burn-plugin
that is used to copy the boot
and root
trees from an IMG into directories in the file system
- bootfs — Directory where the
boot
tree will be written - rootfs — Directory where the
root
tree will be written - img — /path/to/IMG.IMG from which the trees will be copied
--burn-plugin extractfs:"bootfs=/path/to/bootfs|rootfs=/path/to/rootfs"
Configures a Pi to be in gadget mode so it can connect via USB to a gadget mode host providing it with a network connection.
autoconnect-retries
— Sets the number of retries for the gadget to obtain a DHCP address via the USB gadget connection [D:5]dhcp-timeout
— Configures the DHCP timeout for each attempt to get a DHCP address via the USB connection [D:60]gadget-mode
— Configures the gadget mode. Default is unsharedsimple
mode.gadget-mode=shared
enables the gadget device to be shared using libcompositemac-vendor
— Specifies the first 3 segments of the MAC address. [D:dc:a6:32]static-mac
— Configures the provided static MAC address for the USB gadget device. Useful so the Pi gets the same IP address every time, but only withgadget-mode=simple
Ifstatic-mode
is specified without a value, the plugin will generate a MAC address and make it static.noipv6
— Do not configure ipv6 on the gadget USB connection
--plugin gadgetmode:"static-mac=aa:bb:cc:dd:ee:ff"
— Configure simple gadget mode with a static MAC address- `--plugin gadgetmode:"gadget-mode=libcomposite|static-mac=fa:ce:fe:ed:00" — Configure shared gadget mode with a static MAC address
- The
autoconnect-retries
anddhcp-timeout
values are set high to improve success when connected to slower devices
Clones the specified repository to the specified directory.
repo
— Full path to the git repository. Must be network-accessible either via https or some other mechanism (NFS, etc)gitdir
— Directory into which to place the clone. sdm will do amkdir -p
to ensure the directory exists. The clone is done directly into the specified directorygitsw
— Additional switches to use on thegit
commanduser
— User that will be used to run git. The user must already existpreclone
— Command to run immediately before the clone. If the command starts with@
it is the name of a script to runpostclone
— Command to run immediately after the clone. Otherwise same aspreclone
gitphase
— By default thegit
command is run in sdm Phase 1. Specifygitphase=post-install
to run git in the post-install phase.cert
— Not Yet Implementedlogspace
— Specify this flag to have the disk space logged immediately before and after thegit clone
--plugin git-clone:"repo=https://github.com/gitbls/sdm|gitdir=/home/bls/work/sdm|user=bls|logspace
— Clone the sdm repo into /home/bls/work/sdm as user bls. Disk space will be logged before and after the clone.
The graphics plugin configures various graphics-related settings. It doesn't do much for wayland at the current time, although you might use it to set the video mode in /boot/firmware/cmdline.txt.
-
graphics — Supported values for the graphics keyword are
labwc
,wayfire
andX11
.If
graphics
is set tolabwc
orwayfire
, the corresponding software (labwc or wayfire) must already be installed. sdm will use raspi-config to appropriately configure lightdm as requested.If
graphics
is set toX11
, the Core X11 packages (xserver-xorg, xserver-xorg-core, and xserver-common) are installed if not already installed. In the post-install phase, the plugin will look for a known Display Manager (lightdm, xdm, or wdm), and make appropriate adjustments (see below) -
nodmconsole — If
graphics=X11
,nodmconsole
directs sdm to NOT start the Display Manager on the console, if the Display Manager is lightdm, wdm, or xdm. -
videomode — Specifies the string to add to the video= argument in cmdline.txt. See below for an example.
Currently, labwc is the Default graphics subsystem on Bookworm with Desktop images, so graphics=labwc
is effectively redundant on those images. The plugin currently will not install labwc or wayfire on a Bookworm Lite IMG. labwc and wayfire are not supported by sdm on releases prior to Bookworm.
If graphics=X11
and the Display Manager is known, the graphics plugin makes a few adjustments. Specifically:
- If LXDE is installed, the mouse will be set to left-handed if specified on the command line. This works for wayland as well.
- For Display Managers lightdm, wdm, and xdm, sdm will cause the boot behavior you might specify to be delayed until after the First Boot.
For graphics=labwc
or graphics=wayfire
, use the labwc
or lxde
plugin to perform specific configuration such as lhmouse
and/or apply personalized configuration settings.
The videomode argument takes a string of the form: 'HDMI-A-1:1024x768M@60D'. sdm will add video=HDMI-A-1:1024x768M@60D to /boot/firmware/cmdline.txt
--plugin graphics:"graphics=X11|nodmconsole
— Installs the X11 core components and disables the Display Manager on the console--plugin graphics:"videomode=HDMI-A-1:1920x1280@60D"
— Sets the specified video mode in /boot/firmware/cmdline.txt
The hotspot plugin configures the specified wireless device or USB0 to be a hotspot. The hotspot plugin only supports Bookworm and is implemented using NetworkManager. In most situations a routed hotspot is preferable, but both are provided.
- config — Config file with all the arguments (see Example)
- device — Device name [D:wlan0]. Use
device=usb0
for a tether host. - dhcpmode — Mode for DHCP server. Controls whether NetworkManager uses its internal dnsmasq DHCP server or not. Valid settings are
none
andnm
. If set tonone
, you must configure a DHCP server for the hotspot. [D:nm] Ifdhcpmode
==none
thenwlanip
must be provided. - hsenable — If hsenable=y set the hotspot to enable as part of system boot [D:y]. Can be specified as simply
hsenable
. To disable, usehsenable=n
- hsname — Set the hotspot name [D:Hotspot]
- ipforward — For routed hotspots, controls whether IP forwarding is enabled. If specified, must be the name of the network device to which network traffic is forwarded. [D:""] For bridged hotspots
ipforward
controls the network device to which the WiFi traffic is bridged [D:eth0] - portal — Install the portal described here as a service that runs at system startup.
portalif
must be specified. - portalif — Use the specified WiFi device for the portal. A second adapter is required, so typically it will be wlan1 (but not defaulted).
- pskencrypt — Save the encrypted PSK in the .nmconnection file rather than the plaintext PSK
- type — Type of hotspot (routed or bridged) [D:routed]
- wifipassword — WiFi hotspot password [D:password]
- wifissid — WiFi hotspot SSID [D:MyPiNet]
- wlanip — IP address of the hotspot in routed mode when
dhcpmode
==none
[D:""].wlanip
is ignored in bridged mode and routed mode ifdhcpmode
==nm
(the default)
-
--plugin hotspot
— Create a routed hotspot named Hotspot on wlan0 with WiFi SSID 'MyPiNet', password 'password'. NetworkManager will use its internal DHCP server. wlan0's IP address will be set to the NetworkManager default (10.42.0.1). No IP forwarding is configured. The hotspot will be enabled. -
--plugin hotspot:"hsname=myhotspot|wifissid=myssid|wifipassword=mypassword|ipforward=eth0|hsenable|type=routed"
— Configure a routed hotspot namedmyhotspot
on wlan0 (the default), with SSIDmyssid
and passwordmypassword
, forwarding IP traffic toeth0
. -
--plugin hotspot:"device=wlan1|hsname=myhotspot|ipforward=eth0|hsenable|type=routed|dhcpmode=none|wlanip=10.6.0.1"
— Configure a routed hotspot on wlan1. wlan1's IP address will be set to 10.6.0.1, and you must configure your own DHCP server using, for instance, dnsmasq or the sdm pluginndm
Example using the ndm plugin to configure dnsmasq:
ndm:dhcpserver=dnsmasq|dnsserver=dnsmasq|dobuild|doinstall|dhcprange=10.6.0.2,10.6.0.100|domain=me|externaldns=1.1.1.1|gateway=10.6.0.1|myip=10.6.0.1|hostname=myap|dnsfqdn=myap.me|mxfqdn=myap.me|timeserver=10.6.0.1|netdev=wlan0|enablesvcs
-
--plugin hotspot:"device=usb0|hsname=myusbhotspot|ipforward=eth0|hsenable|type=routed"
— Configure a routed hotspot on usb0 so it can be a tethering host -
--plugin hotspot:"hsname=myhotspot|hsenable|type=bridged"
— Configure a bridged hotspot
The Config file consists of the above arguments (except for config
), one per line. Arguments that are not provided are defaulted as specified above.
device=wlan0
hsenable=true
hsname=myhotspot
ipforward=eth0
type=routed
wifipassword=SecretPassword
wifissid=myhotspot
The hotspot
plugin does not configure a firewall. Adding an appropriate firewall is important in risky environments.
The wireless device (specified with device
and defaults to wlan0
) cannot be both an Access Point and a WiFi client. If you need both the Access Point and WiFi client (to another WiFi network), you will need to use a second WiFi adapter.
imon installs an Internet Monitor that can monitor:
- Dynamic DNS (DDNS) Monitor — Monitors your external IP address. If it changes changes, your action script is called to take whatever you'd like, such as update your ddns IP address.
- Network Failover Monitor — If your system has two connections to the internet, imon can provide a higher availability internet connection using a primary/secondary standby model.
- Ping monitor — Retrieve ping statistics resulting from pinging an IP address at regular intervals.
- Up/down IP Address Monitor — Monitors a specified IP address, and logs outages.
There are no --plugin
arguments for imon
knockd installs the knockd service and pktables to facilitate easier knockd iptables management.
- config — Full path to your knockd.conf. If config isn't provided, /etc/knockd.conf will be the standard knockd.conf
- localsrc — Locally accessible directory where pktables, knockd-helper, and knockd.service can be found, instead of downloading them from GitHub. If there is a knockd.conf in this directory, it will be used, unless overridden with the config argument
Use the L10n
plugin to set the localization parameters: keymap
, locale
, and timezone
. You can find the valid values for these arguments with
sudo sdm --info keymap # Displays list of valid keymaps
sudo sdm --info locale # Displays list of valid locales
sudo sdm --info timezone # Displays list of valid timezones
- keymap — Specify the keymap to set
- locale — Specify the locale for the system
- timezone — Specify the timezone
- wificountry — Specify the WiFi country setting
- host — Get the above settings from the host system on which sdm is running
NOTE: To disable the RasPiOS initial boot query for these configuration items, add --plugin disables:piwiz
to your customize or burn command line. This works for both Desktop and Lite IMGs.
--plugin L10n:"keymap=us|locale=en_US.UTF-8|timezone=Americas/Los_Angeles"
--plugin L10n:"host"
Provide labwc your fully-configured desktop settings.
- all-config — Specify an existing directory created by
sdm-collect-labwc-config
. This includes all the files that can be provided withapp-config
andlabwc-config
, so those arguments are not needed ifall-config
is provided. sdm does not check for any argument conflicts, butall-config
is processed before any other arguments. - app-config — Specify existing config files for
libfm
,pcmanfm
, andlxterminal
. See the example, and see Using LXDE configuration for details - labwc-config — Specify existing config files for 'autostart', 'desktop-items', 'environment', 'menu', 'rc' 'shutdown' and 'themerc'
- lhmouse — Configure labwc for a left-handed mouse
- numlock — Configure the numlock state. Values (sdm does not validate): 'on', 'off'
- user — The settings apply to the specified user. If no
user
argument is specified, they apply to the first user created with theuser
plugin. Theuser
plugin must be specified on the command line before thelabwc
plugin - wf-panel-pi — Specify existing wf-panel-pi.ini config file for
wayfire
which is copied to the ~/.config directory of the specified user. HINT: Useposition=bottom
in this file to move the task bar to the bottom of the screen.
Use the L10n
plugin to configure the labwc keymap.
If the IMG being customized does not have labwc installed, the assets will be copied to /etc/sdm/assets in Phase 0, but not applied to the user's home directory
The best way to use this plugin is:
- Boot a RasPiOS Desktop system with labwc (the default as of 2024-10-22)
- Configure the system as you'd like it, including pcmanfm, lxterminal, and labwm itself
- Run
/usr/local/sdm/sdm-collect-labwc-config
/path/to/savedir as the logged in user (e.g., no sudo)- If no argument provided /tmp/labwc will be used
- Copy the created directory to the system where you run sdm to customize IMGs
- Provide that directory to sdm when customizing an IMG:
--plugin labwc:all-config=/path/to/dir
- `--plugin labwc:"all-config=/path/to/labwc-config-dir"
--plugin labwc:"app-config=libfm:/path/to/libfm.conf,pcmanfm=/path/to/pcmanfm.conf,lxterminal=/path/to/lxterminal.conf"
--plugin labwc:"lhmouse|user=someuser"
--plugin labwc:"labwc-config=autostart:/path/to/autostart,environment=/path/to/environment
Use the logwatch
plugin to install the logwatch package.
- sendto — Email address where logwatch report should be mailed. You must have a properly configured mail server to send the mail. See the
postfix
plugin - sendfrom — Email address for where the mail should be sent from
- `--plugin logwatch:"sendto=myname<myuser@myemail.com>|sendfrom=myhost-logwatch<myuser@myemail.com>"
Use the lxde
plugin with wayfire
to establish your preferred settings, such as left-handed mouse, and config files for libfm
, pcmanfm
, and lxterminal
. These are not well-documented. The best way to create your personalized versions is to use RasPiOS to configure the desktop as you'd like it, and then save the files. NOTE: Use the labwc
plugin for configuring labwc.
- lhmouse — Set LXDE for a left-handed mouse
- lxde-config — Specify existing config files for
libfm
,pcmanfm
, andlxterminal
. See the example, and see Using LXDE configuration for details - user — The settings apply to the specified user. If no
user
argument is specified, they apply to the first user created with theuser
plugin. Theuser
plugin must be specified on the command line before thelxde
plugin - wayfire-ini — Specify existing wayfire.ini config file for
wayfire
which is copied to the ~/.config directory of the specified user - wf-panel-pi — Specify existing wf-panel-pi.ini config file for
wayfire
which is copied to the ~/.config directory of the specified user. HINT: Useposition=bottom
in this file to move the task bar to the bottom of the screen.
--plugin lxde:"lxde-config=libfm:/path/to/libfm.conf,pcmanfm=/path/to/pcmanfm.conf,lxterminal=/path/to/lxterminal.conf"
--plugin lxde:"lhmouse|user=someuser"
Create the specified directory and optionally set directory owner and protection
- dir — Full path of the directory to create
- chmod — Directory protection
- chown — Directory owner:group
--plugin mkdir:"dir=/usr/local/foobar|chown=bls:users|chmod=740"
NOTE: The directory is created in Phase 0, so it is available as early as during customization. The owner and protection are not set until the post-install phase, since it's possible that the owner account may not be created until Phase 1.
Use the modattr
plugin to change file attributes such as the file owner and file protection.
- path — File specification (see below)
- chmod — Directory protection
- chown — Directory owner:group
- R — Perform the chmod and/or chown recursively
- recursive — Same as
R
- runphase — Specify the phase in which the attribute modifications will be done (
phase1
orpost-install
). Default isphase1
- verbose — Specify the verbosity level (
changes
,silent
, orverbose
), corresponding to the chown/chmod switches--changes
,--silent
, and--verbose
The path
argument is processed as follows:
- Single file: Attributes of that file will be modified
- Directory: Attributes of the directory will be modified, using
--recursive
ifR
orrecursive
provided - Wildcard specification: each expanded element is examined and processed as either a directory or file
--plugin modattr:"path=/path/to/file|chown=user:group|chmod=644"
— Change the file owner and protection of the specified file--plugin modattr:"path=/path/to/dir|chown=user:group|chmod=755|R"
— Change the file owner and protection recursively of the specified directory. If recursive is not specified, only the given directory will be modified.--plugin modattr:"path=/path/to/dir/*|chmod=755|R"
— Change the file protection on all files matching the providedpath
. Matches that are directories will be processed per above.
The ndm
plugin installs ndm (https://github.com/gitbls/ndm), named (bind9) and isc-dhcp-server which enables the resulting system to operate as a full DHCP/DNS server with an easy-to-use command-line interface. ndm makes it super-simple to run your own DHCP/DNS server on RasPiOS with useful logging capabilities.
- config — Existing ndm config file (dbndm.json) to build a new server with an existing ndm config file
- dhcplease — Sets the DHCP lease time in seconds (Default: ndm defaults to 86400)
- dhcpserver — Specifies which DHCP server to use (dnsmasq or isc-dhcp-server) (Default: isc-dhcp-server)
- dnsserver — Specifies which DNS server to use (bind9 or dnsmasq). (Default: bind9). If dnsmasq is chosen for either dhcpserver or dnsserver they both must be set to dnsmasq.
- dobuild — Do an
ndm build
after the system has been configured. See building, installing and enabling services - doinstall — Do an
ndm install
after the system has been configured. See building, installing and enabling services - enablesvcs — Enable the DHCP and DNS server services after configuration. See building, installing and enabling services
- importnet — Provides /path/to/import-host-list.txt, which is a list of host definitions to import. See importing a network database for details on the host definition format.
- localsrc — Specifies the directory containing the already-downloaded ndm files
In addition, these arguments, which control the ndm DHCP and DNS configuration, are also accepted. See the ndm documentation for details.
- dhcprange — Sets the range of addresses that the DHCP server will serve dynamically
- dnsfqdn — FQDN of the host on which ndm will be running [D:
hostname
.domain
] - domain — Domain name [D:my.sdm]
- externaldns — IP address of the external (internet) DNS server
- gateway — Gateway IP from LAN to the internet
- hostname — Hostname of the host on which ndm will be running
- mxfqdn — Mail server FQDN. Use the DNS server FQDN if you don't have a mail server
- myip — IP address of host on which ndm will be running. NOTE: This does NOT configure the network. Use the
network
plugin for that. - netdev — Network device that the DNS and DHCP servers listen on [D:eth0]
- timeserver — IP address of timeserver to provide to DHCP clients
The ndm
plugin will install the requested DHCP and DNS server services, and configure them appropriately per the provided arguments.
The dobuild
argument requires one of:
- An ndm config file via argument
config
- OR all of these arguments:
dhcprange
,dnsfqdn
,domain
,externaldns
,gateway
,hostname
,mxfqdn
,myip
,netdev
, andtimeserver
The doinstall
argument requires a satisfied dobuild
The enablesvcs
argument requires satisfied dobuild
and doinstall
arguments
--plugin ndm
— Installs ndm, named, and isc-dhcp-server. Both named and isc-dhcp-server services are disabled, and must be re-enabled once ndm has been used to generate the config files for these two services.--plugin ndm:"config=/path/to/dbndm.json|dhcpserver=dnsmasq|dnsserver=dnsmasq|dobuild|doinstall|netdev=eth0"
— Installs dnsmasq, performs anndm build
andndm install
, but does not enable the services.- Also see the example used in conjunction with the
hotspot
plugin
Use the network plugin to configure various network settings. Each invocation of the network
plugin performs one of two functions:
- Configure network settings using the
nmconf
andnmconn
arguments to provide ready-to-go files for NetworkManager - Configure a single connection for a single device. A device can have more than one connnection configured for it, but pay attention to
autoconnect
andautoconnect-priority
so that the proper connection is started by default.
sdm does not pay attention to, nor do anything to improve or restrict multiple connections on a single device. They will work correctly when properly configured.
All arguments except dhcpcdappend
, dhcpcdwait
, nowifi
, and wpa
are valid for NetworkManager. The only arguments valid for dhcpcd are these four plus noipv6
-
netman — Specify which network manager to use. Supported values are
dhcpcd
,network-manager
, andnm
(short for network-manager). Ifnetman
is not specified, by default sdm will use dhcpcd on Bullseye (Debian 11) and earlier, while on Bookworm (Debian 12) sdm will use NetworkManager. -
autoconnect — Takes the value
true
orfalse
. Sets the connection's autoconnect value -
autoconnect-priority — Sets the connection's
autoconnect-priority
to the provided value -
cname — Name the NetworkManager connection. Default is
ifname
, the interface name -
ctype — If cname is a WiFi device with a name other than
wlan*
, specifyctype=wifi
-
dhcpcdappend — Specifies a file that should be appended to /etc/dhcpcd.conf. Only processed if
netman=dhcpcd
-
dhcpcdwait — Specifies that dhcpcd wait for network online should be enabled. Only processed if
netman=dhcpcd
-
ifname — Specifies network device name to configure. Default is
eth0
. To configure WiFi usingwifissid
andwifipassword
ifname
must be specified and configured to a WiFi device (e.g.,wlan0
). -
ipv4-route-metric — Specify the route metric for the network
-
nmconf — Specifies a comma-separated list of NetworkManager config files that are to be copied to /etc/NetworkManager/conf.d (*.conf)
-
nmconn — Specifies a comma-separated list of NetworkManager connection definitions (each a separate file) that are to be copied to /etc/NetworkManager/system-connections (*.nmconnection)
-
nmdebug — Enables NetworkManager debug mode logging for those hard-to-diagnose NM issues
-
noipv6 — Specifies that IPv6 should be disabled for this connection. Works with both
netman=dhcpcd
andnetman=nm
-
nowifi — If
netman=dhcpcd
and WiFi settings not configured, this prevents a warning message about no WiFi configured -
powersave — Specify the WiFi powersave setting. Values: 0:Use default value; 1:Leave as is; 2:Disable powersave; 3:Enable powersave
-
ipv4-static-ip — Configure the connection with this static IP address
-
ipv4-static-gateway — Configure the connection with this static gateway
-
ipv4-static-dns — Configure the connection with this DNS server IP
-
ipv4-static-dns-search — Set DNS suffix search list for the configuration (Ex:
ipv4-static-dns-search=my.com,dyn.my.com
) -
pskencrypt — Save the encrypted PSK in the .nmconnection file rather than the plaintext PSK
-
wifissid or wifi-ssid — Specifies the WiFi SSID for the connection. If
ifname
is configured and is a WiFi device, andwifissid
,wifipassword
, andwificountry
are all set, the network plugin will configure the WiFi connection (NetworkManager) or will create /etc/wpa_supplicant/wpa_supplicant.conf (ifnetman=dhcpcd
). -
wifipassword or wifi-password — Password for the
wifissid
network. Seewifissid
-
wificountry or wifi-country — WiFi country for the
wifissid
network. Seewifissid
-
wpa — Specifies the file to be copied to /etc/wpa_supplicant/wpa_supplicant.conf. Only processed if
netman=dhcpcd
. NetworkManager does not use wpa_supplicant.conf -
zeroconf — (NetworkManager only) If eth0 does not properly connect (e.g., doesn't get a DHCP address) then bring up zeroconf (169.254.x.y) on the adapter.
This can take some time due to NetworkManager default settings and timeouts. You can use the NetworkManager settings
ipv4.dhcp-timeout
andconnection.autoconnect-retries
on the eth0 nmconnection to reduce the delay if desired.See Network Manager nmcli settings for complete details on connection settings.
--plugin network:"ifname=eth0"
— Configure network connection for deviceeth0
. It will be configured for both IPV4 and IPV6 DHCP configuration. The connection will be namedeth0
--plugin network:"ifname=eth0|cname=myeth0"
— As above, but the connection will be namedmyeth0
--plugin network:"nmconf=file1.conf,file2.conf|nmconn=/path/to/myconn1.nmconnection,/path/to/myconn2.nmconnection"
— Copy the provided NetworkManager config files and nmconnection files to their destination directories. No other network configuration is done.--plugin network:"ifname=wlp3s0|cname=wlan2|ctype=wifi|wifi-ssid=myssid|wifi-password=myssidpassword|wificountry=US"
— Configure a WiFi connection namedwlan2
configured with the provided SSID/Password/country for network devicewlp3s0
--plugin network:"ipv4-static-ip=192.168.14.32|ipv4-static-gateway=192.168.41.1|ipv4-static-dns=192.168.14.1|ipv4-static-dns-search=mydom.com"
— Configureeth0
(default if noifname
specified) with the specified static IP configuration. The DNS search mechanism will search unqualified names in the domainmydom.com
--plugin network:"netman=dhcpcd|noipv6"
— Set the network manager to dhcpcd (and disable NetworkManager), and do not request an IPv6 address.
parted is a --burn-plugin
that operates on a device, disk, or disk image and enables you to
- Expand the root partition by a specified number of MiB
- Add one or more partitions of a specified size with a specified file system type on it
Using the parted
burn plugin implicitly sets --no-expand-root
when used on a burn command.
- rootexpand — Expand the root partition by the number of MiB specified as the value for this argument. A value of 0 expands the partition to fill the disk. A value of 0 is not allowed when used with
--burnfile
- addpartition — Adds another partition at the end of the IMG. Arguments: size[fstype][,partitiontype,] where:
size
is the number of MiB for the partitionfstype
is the type of file system. Supported file systems are:btrfs
,ext2
,ext3
,ext4
[default],fat16
,fat32
,hfs
,hfs+
,ntfs
,reiserfs
,udf
, andxfs
. Some file systems may require you to install additional apt packages on the host before running this pluginpartitiontype
is one ofprimary
[default],logical
, orextended
- NOTE: Multiple partitions can be named on the command line by separating them with
+
. See example below.
--burn-plugin parted:"rootexpand=2048|addpartition=1024,ext4"
— Expand the RasPiOS root partition by 2048MiB and add a 1024MiB ext4 partition--burn-plugin parted:"rootexpand=2048|addpartition=1024,ext4+2048,btrfs"
— Expand the RasPiOS root partition by 2048MiB and add: a 1MiB ext4 partition and a 1024MiB btrfs partition--burn-plugin parted:"rootexpand=1024|addpartition=@/path/to/partition-list"
where the file partition-list has one line for each partition to be added in the form:nnnn,fstype,partitiontype,label
This is a sample file for the addpartition=@/path/to/partition-list directive. It will expand the root partition by 2048MiB (2GiB) add a 1MiB partition and ext4 file system, and a 4MiB partition and btrfs file system. This method enables easily adding multiple partitions with a single plugin invocation, so the ability to use +
for multiple partitions mentioned above does not work in a partition-list file.
1024,ext4,,ext4label
4096,btrfs,,btrfslabel
Installs pi-apps (https://github.com/Botspot/pi-apps). That's it!
- user — Specify the user that piapps should be installed for. The user must already exist. If not specified, the first created user ($myuser) will be used
--plugin piapps:"user=bls"
— Install piapps for user bls. The user was already created with theuser
plugin
pistrong installs the strongSwan IPSEC VPN server and pistrong
. pistrong provides
- A fully-documented, easy-to-use Certificate Manager for secure VPN authentication with Android, iOS, Linux, MacOS, and Windows clients
- Tools to fully configure a Client/Server Certificate Authority and/or site-to-site/host-to-host VPN Tunnels. Both can be run on the same VPN server instance
In addition to simply installing pistrong and strongSwan, this plugin enables:
- After FirstBoot system can be fully configured and operational with host/host tunnels and/or client/server VPNs with no intervention
- Two hosts can be built up from scratch with an operational site/site host/host VPN tunnel with one sdm customize and 2 sdm burn commands
- calife — Set the CA Certificate lifetime in days [Default: 3650 days]
- uclife — Set the User Certificate lifetime in days [Default: 730 days]
- certpack — Import an already-generated CertPack and install it in the customized IMG or burned disk
- enablesvc — Enable the
strongswan
service to start on first system boot - ipforward — Enable IP forwarding from the VPN server onto the LAN. Value can be
yes
orno
[Default: no] - iptables — Collect the iptables configuration from available CA and Tunnel definitions into /etc/swanctl/pistrong/iptables and enable the service pistrong-iptables-load
- makemyca — Provide a configuration answer file for MakeMyCA to enable the CA to be automatically configured with no intervention
- maketunnel — Provide a configuration answer file for makeTunnel to enable the tunnel to be automatically configured with no intervention
- hostname — Provide the hostname that will ultimately be used for the host so makeTunnel recognizes that the Tunnel configuration is for this host
- vpnmon — Enable the VPN monitor on this host, which tries to always keep the VPN tunnel connection up. Requires
vpnmonping
- vpnmonping — Specifies the IP address that the VPN monitor should test for the VPN tunnel being up. Typically this would be the LAN IP address of the VPN server at the other end of the tunnel
--plugin pistrong:"calife=7300|uclife=7300|makemyca=/path/to/makemyca.conf"
— Install strongSwan, create a CA with the specified Cert lifetimes, and configure the CA with the parameters provided in makemyca.conf--plugin pistrong:"maketunnel=/path/to/maketunnel.conf"
— Install pistrong and build a VPN tunnel with the parameters defined in maketunnel.conf--plugin pistrong:"certpack=/path/to/Tunnel-node1-node2.zip|enablesvc|vpnmon|vpnmonping=192.168.47.3"
— Install pistrong, import the VPN CertPack and install it. Enable the VPN monitor checking the LAN IP address on the other end of the tunnel specified byvpnmonping
NOTE: Documentation on the makemyca and maketunnel config files is not yet available. If you're interested in using this capability, please post an issue on the sdm GitHub.
postburn is a --burn-plugin
that enables you to:
- Copy files from the burned disk to the host OS file system
- Run a script that has access to the burned disk in either Phase 0 or Phase 1 mode
savefrom
— /path/to/file for the file(s) to be copied from the burned disk.*
is supported for use in the filenamesaveto
— /path/to/dir to define where the files will be copied torunscript
— /path/to/script of a script that will be run after the burn completes. The script must exist and be executablerunphase
— Specify context for runningrunscript
. [Default:phase1
]. Supported values:phase0
— Runsrunscript
in the context of the burned disk being mounted in the host OSphase1
— Runsrunscript
in the context of the burned disk in a container
where
— Where the script is located.host
specifies thatrunscript
path is in the host OS. Any other value:runscript
path is in the burned disk
--burn-plugin postburn:"savefrom=/etc/swanctl/pistrong/server-assets/*.zip|saveto=/my/dir"
— Copies all the *.zip files from the specified directory in the burned disk to/my/dir
on the host file system--burn-plugin postburn:"runscript=/usr/local/bin/do-something|runphase=phase0|where=host"
— Runs the host-located script/usr/local/bin/do-something
in the context of the host OS--burn-plugin postburn:"runscript=/usr/local/bin/do-something|runphase=phase1|where=host"
— Runs the host-located script/usr/local/bin/do-something
in the context of the burned disk container. Therunscript
is copied onto the burned disk in /usr/local/bin, and removed after it has been run--burn-plugin postburn:"runscript=/usr/local/bin/do-something|runphase=phase1"
— Runs the burned disk-located script/usr/local/bin/do-something
in the context of the burned disk container
postfix installs the postfix mail server. This plugin installs the postfix server but at the moment doesn't do too much to simplify configuring postfix. BUT, once you have a working /etc/postfix/main.cf, it can be fed into this plugin to effectively complete the configuration.
- enablesvc — Enable the postfix service
- maincf — The full /path/to/main.cf for an already-configured /etc/postfix/main.cf. If provided, it is placed into /etc/postfix after postfix has been installed.
- mailname — Domain name [Default: NoDomain.com]
- main_mailer_type — Type of mailer [Default: Satellite system]
- relayhost — Email relay host DNS name [Default: NoRelayHost]
--plugin postfix:"maincf=/path/to/my-postfix-main.cf
— Uses a fully-configured main.cf, and postfix will be ready to go.--plugin postfix:"relayhost=smtp.someserver.com|mailname=mydomain.com|rootmail=myemail@somedomain.com
— Set some of the postfix parameters, but more configuration will be required to make it operational. A good reference will be cited here at some point.
The quietness plugin controls the quiet and splash settings in /boot/firmware/cmdline.txt
- consoleblank — Set a console blanking timeout (Default: 300 seconds)
- quiet — Enables 'quiet' in /boot/firmware/cmdline.txt
- noquiet — Disable 'quiet' in /boot/firmware/cmdline.txt. If
noquiet=keep
is NOT specified, sdm will re-enable 'quiet' in cmdline.txt after the First Boot. - splash — Enables 'splash' in /boot/firmware/cmdline.txt
- nosplash — Disable 'splash' in /boot/firmware/cmdline.txt. If
nosplash=keep
is NOT specified, sdm will re-enable 'splash' in cmdline.txt after the First Boot. - plymouth — Enables Plymouth in /boot/firmware/cmdline.txt. Not Yet Implemented
- noplymouth — Disables the Plymouth graphical splash screen for the First Boot (only). It is re-enabled at the end of First Boot.
--plugin quietness:"consoleblank|noquiet=keep|nosplash=keep"
— Remove 'quiet' and 'splash' from cmdline.txt and do not re-enable them. Console blanking timeout set to 300 seconds (5 minutes)--plugin quietness:"consoleblank=600|noquiet|nosplash|noplymouth"
— Remove 'quiet' and 'splash' from cmdline.txt, and disable plymouth. All will be re-enabled after the First Boot. Console blanking timeout set to 600 seconds (10 minutes).
the raspiconfig
plugin is used to modify settings supported by raspi-config
. This is not necessarily the complete list (done quickly), and one or two of these may not be supportable. There's more work to do on this one!
See RaspberryPi Documentation for raspi-config for details.
- audio
- audioconf
- blanking
- boot_behaviour, boot_behavior
- boot_order
- boot_splash
- boot_wait
- camera
- composite
- glamor
- gldriver
- i2c
- leds
- legacy
- memory_split
- net_names
- onewire
- overclock
- overlayfs — Enables the readonly file system. Optional value specifies whether bootfs should be 'ro' (default) or 'rw'
- overscan
- pi4video
- pixdub
- powerled
- proxy
- rgpio
- serial
- spi
- xcompmgr
--plugin raspiconfig:"net_names=1|boot_splash=1"
--plugin raspiconfig:overlayfs=ro
— Enable the rootfs readonly file system with a read-only bootfs also--plugin raspiconfig:overlayfs
— Enable the rootfs readonly file system with a read-only bootfs also--plugin raspiconfig:overlayfs=rw
— Enable the rootfs readonly file system with a read/write bootfs
The 'overlayfs' setting enables the read-only file system. The file system is not made read-only until sdm FirstBoot has completed and the system restarts. If you need a swapfile, you'll need to configure it on another disk or partition, since the boot disk isn't writeable. At the moment sdm doesn't provide any support for swapfile management with overlayfs.
The runatboot
plugin provides a way to run an arbitrary script during the First Boot of the system. The script is run as root or user
if specified, with no other provisions or control made by sdm. Behavior, output, logging content, etc is all the responsibility of the script.
- script — /full/path/to/the/script that should be run
- args* — The arguments to provide to the script
- user — If provided use sudo to run script as the specified user. User must exist at time of First Boot
- sudoswitches — If
user
provided, include these sudo switches - output — Where to set stdout. Default is /dev/null. The directory must already exist, and the user (root or
user
if specified) must be able to write the output file in that directory - error — Where to set stderr. Default is the same as stdout (
2>&1
)
--plugin runatboot:"script=/path/to/script|args=arg1 arg2 arg3"
— Run the specified script with the 3 provided arguments--plugin runatboot:"user=me|sudoswitches=-H|script=/path/to/script|args=arg1 arg2 arg3"
— Run the specified script with the 3 provided arguments as the specified user and include-H
on the sudo command--plugin runatboot:"script=/path/to/script2|args=arg1 arg2 arg3|output=/var/log/myscript.log"
— Run the specified script with the 3 provided arguments with output and error going to /var/log/myscript.log
The runscript
plugin runs a script during customization.
- dir — Optional directory in which to run the script (as the default directory). The directory will be created if it doesn't exist. Use a /full/path/to/dir
- runphase — Specifies the phase (
1
orpost-install
) in which to run the script. Default is1
- script — /full/path/to/script on the host to run. The script will be copied into the IMG
- user — The user under which to run the script. The user must exist by the time the script is run in Phase 1 or post-install. If not specified the script is run as
root
- stdout — Specifies stdout for the script output. /full/path/to/stdout must be specified (but not checked by sdm)
- stderr — Specifies stderr for the script output. /full/path/to/stderr must be specified (but not checked by sdm)
The script is called with one argument: the current Phase (either 1
or post-install
).
The default for stdout
and stderr
if not specified are $(basename $script).out
and $(basename $script).error
. If dir
is specified the files will be written to dir
. If not, the files will be written to /etc/sdm/assets/runscript
.
--plugin runscript:"dir=/home/work|script=/path/to/my/script|user=bls"
— The directory /home/work is created and owned by user bls. The script specified is run during Phase 1, and the ouptut and error files are saved in /home/work--plugin runscript:"/path/to/my/script"
— The script is run as root during Phase 1. Output and error are saved in /etc/sdm/assets/runscript/sdm-runscript-$script.out and .error--plugin runscript:"stdout=/dev/stdout|stderr=/dev/stderr|script=/path/to/my/script"
— redirect the output of the script to the console instead of a file in the image
This simple script downloads the btop sources and builds/installs btop into the IMG being customized. All prerequisites such as make, gcc, etc must already be installed before this runscript is executed.
#!/bin/bash
#
# Download the tar file
#
btopver="1.3.2"
mkdir -p /home/work/btop
pushd /home/work/btop >/dev/null
wget https://github.com/aristocratos/btop/releases/download/v${btopver}/btop-aarch64-linux-musl.tbz -O btop-aarch64-linux-musl.tbz
#
# Expand the tar file (creates directory btop)
#
tar -xjvf btop-aarch64-linux-musl.tbz
#
# cd into the directory, build, and install btop
#
cd btop
make install
rxapp is a handy tool to securely and remotely start X11 apps via SSH without a password. You can read about it here.
rxapp is included because it is generally useful, but also as a demonstration of how to copy a file from the network (GitHub in this case) into the IMG in a plugin.
There are no --plugin
arguments for rxapp
- smbconf — Full /path/to/smb.conf for an already-configured /etc/samba/smb.conf. If provided it is placed into /etc/samba after samba has been installed.
- shares — Full /path/to/shares.conf for a file containing only the samba share definitions. If provided it is appended to /etc/samba/smb.conf after samba has been installed.
- dhcp — TBH not sure what this does. If you figure it out, let me know ;)
- do_debconf — TBH not sure what this does. If you figure it out, let me know ;)
- workgroup — Workgroup name to replace WORKGROUP in the default /etc/samba/smb.conf. If smbconf is specified, the workgroup is NOT modified.
--plugin samba:smbconf=/home/bls/mylan-smb.conf
— Use the provided fully-configured file for /etc/samba/smb.conf--plugin samba:"shares=/home/bls/mysmbshares.conf"
— Append the provided share definitions to the end of the default /etc/samba/smb.conf--plugin samba:"workgroup=myworkgroup|shares=/home/bls/mysmbshares.conf"
— Use the default /etc/samba/smb.conf, set the workgroup name to myworkgroup and append the provided share definitions to /etc/samba/smb.conf
The serial
plugin is used to configure the serial port. Although the serial
setting on the raspiconfig
plugin still works, as of 2023-12-28 it prompts, which is obviously annoying when you're in the middle of an sdm customize.
There's a second issue in that the serial setting for the Pi5 is different than for other Pis, and raspi-config checks the system on which it is running, which can likely be incorrect when doing an sdm customize.
The serial
plugin addresses these issues. You can use it during a customize if you know the target hardware. Otherwise, when you burn the disk for a target system, you can run the plugin then to set it correctly for the target hardware.
- disableshell — Explicitly disables the shell on the console serial port
- enableshell — If set, enable a shell on the console serial port. Also enables the uart
- enableuart — Enable the console serial port uart without enabling the shell
- pi5 — If set, configure the serial port for a Pi5
- pi5debug — If set, configure the debug serial port for a Pi5
--plugin serial
— Configure the serial port for a Pi other than a Pi5 and disable the login shell on it--plugin serial:pi5
— Configure the serial port for a Pi5 and disable the login shell on it--plugin serial:disableshell
— Another way to disable the login shell on the console serial port--plugin serial:enableshell
— Configure the serial port for a Pi other than a Pi5 and enable a login shell on it--plugin serial:pi5|enableshell
— Configure the serial port for a Pi5 and enable a login shell on it--plugin serial:pi5debug
— Configure the debug serial port for a Pi5
The sshd
plugin configures:
- The SSH service to be enabled or disabled. This service is enabled by default, even if the
sshd
plugin is not used. Use thesshd
service to disable the SSH service if needed - Various SSH service configuration items
These configuration items affect the SSH service.
-
enablesvc — Enable or disable the service. [Default: enabled]. Values supported:
yes
,no
, orsocket
-
Arguments that modify /etc/sshd_config
- listen-address — IP address on which to listen [Default: 0.0.0.0] (all IP addresses on the server)
- password-authentication — Enable/disable password authentication. [Default:
yes
]. Disable this (no
) to restrict logins to public key only - port — Port number SSH service should listen on [Default: 22]
- `--plugin sshd:"enablesvc=no" — Disable the SSH service
- `--plugin sshd:"port=22222|listen-address=192.168.16.16" — Enable the SSH service, which will listen on port 2222 and only on the IP address 192.168.16.16 (which must be an IP address on the target system)
- `--plugin sshd:"password-authentication=no" — Disable password authentication
The sshhostkey
plugin allows the generation new or import of existing SSH host keys.
Importing SSH host keys is useful to generate images with deterministic keys.
Generating SSH host keys during an sdm customize or burn can be beneficial because the entropy during Pi's first boot is very limited, whereas sdm can access the entropy pool of the host OS.
- generate-keys — Create a new set of keys in phase 1.
- import-keys — Copy files from the given host directory to /etc/ssh.
--plugin sshhostkey:"generate-keys
— Generate a new set of host keys.--plugin sshhostkey:"import-keys=/path/to/hostkeys"
— Copyssh_host_*_key
andssh_host_*_key.pub
files from the specified host directory to the Pi's /etc/ssh/ directory--plugin sshhostkey:"generate-keys|import-keys=/path/to/hostkeys"
— Useful to import a subset (e.g. RSA only) keys, and re-create the rest.
The sshkey
plugin creates an SSH key or imports an SSH key for a user. In either case, you can optionally create a Putty private key for it.
- sshuser — The user for whom the SSH key is targeted. The user must already exist
- authkey — Add the created SSH public key to
sshuser
's ~/.ssh/authorized_keys - import-key — Instead of creating an SSH key, import the specified SSH key from the provided file in the host OS
- keyname — Name the key that is to be created
- keytype — Type of key to create. Accepted values:
dsa
,ecdsa
,ecdsa-sk
,ed25519
,ed25519-sk
,rsa
. [Default:ecdsa
] - passphrase — Passphrase to secure the SSH key. The same passphrase is used when creating a putty key
- putty-keyname — If specified, create a putty key in ~/.ssh with the provided key name
--plugin sshkey:"sshuser=bls|keyname=mykey|keytype=ed25519|passphrase=itsasecret|putty-keyname=myputtykey"
— Create a new SSH key for userbls
, with the parameters as specified. Additionally, the Putty keymyputtykey.ppk
is created using the same passphrase--plugin sshkey:"sshuser=bls|import-key=/home/bls/.ssh/myotherkey|putty-keyname=otherputty|passphrase=anothersecret"
— Import the specified private key from the host system. Use the provided passphrase to access the imported key and create a Putty key using the same passphrase.
The syncthing
plugin installs syncthing and configures it for the user specified by runasuser
.
- connect-address — Address or host name to use when attempting to connect to this device. Must be fully specified. For example: tcp://0.0.0.0:22001. See listen-addresses for specfication details.
- enablesvc — Enable the syncthing service during sdm FirstBoot
- gui-address — GUI listen address. Default is 127.0.0.1:8384 For example: 0.0.0.0:8384 or http://0.0.0.0:8384
- gui-password — GUI authentication password used in conjunction with the
gui-user
- gui-user — GUI authentication username
- homedir — Home directory to use. Default:
runasuser
home directory - nolinger — Do not start syncthing for user until user logs in. Default: syncthing started for user at system boot once enabled by
enablesvc
or manually viasystemctl enable --user syncthing
from the user account- Can be controlled manually after system up and running. If modifying other than current user specify
username
and usesudo
- Enable linger:
loginctl enable-linger [username]
- Disable linger:
loginctl disable-linger [username]
- Enable linger:
- Can be controlled manually after system up and running. If modifying other than current user specify
- release — syncthing release to install. Default:
stable
- runasuser — Username to be used to run the syncthing service. Default: First user created with the
user
plugin - sendstats — Send statistics setting (-1: Never, 0: Ask, 1: Always). Default: Always
- synchost — Hostname that will eventually be used for this host. (Sorry that you need to specify this here)
--plugin syncthing
— Install syncthing. GUI username/password will not be set. GUI will only be accessible from browsers running on the same host as syncthing. syncthing will run as the first user created with theuser
plugin. Hostname will be set tosdm
, which can be edited in config.xml--plugin syncthing:"enablesvc|gui-address=0.0.0.0:8384|gui-password=asecret|gui-user=syncuser"
— Install syncthing. GUI username/password will be set. GUI will be accessible from browsers running on any LAN host. syncthing will run as the first user created with theuser
plugin. The syncthing listenAddress will be set to the default (tcp://0.0.0.0:22000
)--plugin syncthing:"enablesvc|gui-address=0.0.0.0:8384|gui-password=asecret|gui-user=syncuser" --plugin syncthing:"runasuser=syncuser2|enablesvc|gui-address=0.0.0.0:8385|gui-password=asecret|gui-user=syncuser2|connect-address=tcp://0.0.0.0:22001"
- Install and configure syncthing for the first user created with the
user
plugin as in the previous example - A second user,
syncuser2
will also be configured. The usersyncuser2
must be created using theuser
plugin before referencing it in thesyncthing
plugin. syncthing will listen ontcp://0.0.0.0:22001
for the second user - Each user must have a unique listenAddress
- Install and configure syncthing for the first user created with the
Final syncthing configuration is done during sdm FirstBoot. The script that will be run is in /etc/sdm/0piboot/098-enable-syncthing-runasuser
.sh
For a user's syncthing service to be started at boot enablesvc
must be set and nolinger
must NOT be set.
The system
plugin is a collection of system-related configuration settings. You are responsible for using correct file types expected by each function (e.g., .conf, .rules, etc). The plugin does no checking/modification of file types.
If the system plugin is invoked more than once in an IMG, either on customize or burn, you must include the name=somename
argument for correct operation.
- Cron control arguments
- cron-d — Comma-separated list of files to copy to /etc/cron.d
- cron-daily — Comma-separated list of files to copy to /etc/cron.daily
- cron-hourly — Comma-separated list of files to copy to /etc/cron.hourly
- cron-weekly — Comma-separated list of files to copy to /etc/cron.weekly
- cron-monthly — Comma-separated list of files to copy to /etc/cron.monthly
- cron-systemd — Takes no value. Switches from using cron to systemd-based cron timers
- eeprom — Supported values are critical, stable, and beta
- exports — Comma-separated list of files to append to /etc/exports
- fstab — Comma-separated list of files to append to /etc/fstab
- journal — Configure systemd journal. Supported values are persistent, volatile, and none. By default Bullseye uses rsyslog and
journal=volatile
while Bookworm usesjournal=persistent
.persistent
: Makes a permanent journal in /var/logvolatile
: The journal is in memory and not retained across system restartsnone
: There is no system journal
- ledheartbeat — Enable LED heartbeat flash on Pi systems that have /sys/class/leds/PWR/trigger, such as the Pi4 and Pi5.
- modprobe — Comma-separated list of files to copy to /etc/modprobe.d
- motd — Single /path/to/file to use for /etc/motd. /dev/null results in an empty motd
- name — Name of this invocation. This must be included if the
system
plugin is invoked more than once in an IMG, including between customize and burn. Best practice to avoid problems is to give each and every invocation a name. - rclocal — Comma-separated list of ordered commands to add to /etc/rc.local. An item starting with '@' is interpeted as a file whose contents will be included.
- Service control arguments
- service-disable — Comma-separated list of services to disable
- service-enable — Comma-separated list of services to enable
- service-mask — Comma-separated list of services to mask
- swap — disable or integer swapsize in MB to set
- sysctl — Comma-separated list of files to copy to /etc/sysctl.d
- systemd-config — Comma-separated list of
type:/path/to/file.conf
, where type is one of login, network, resolve, system, timesync, or user. Copies the provided file to /etc/systemd/type.conf.d NOTE: file must be specified as a full /path/to/file.conf and the file type MUST be.conf
- udev — Comma-separated list of files to copy to /etc/udev/rules.d
--plugin system:"cron-d=/path/to/crondscript|exports=/path/to/e1,/path/to/e2"
--plugin system:"systemd-config=timesync=/path/to/timesync.conf,user=/path/to/user.conf|service-disable=svc1,svc2"
--plugin system:"name=s1|cron-d=/path/to/crondscript|exports=/path/to/e1,/path/to/e2" --plugin system:"name=s2|fstab=myfstab
trim-enable will enable SSD Trim on all or only selected devices. Trim is not actually enabled on the devices until the system first boots.
This plugin can be run manually on a running sdm-customized system by
sdm --runonly plugins --plugin trim-enable:"disks=/dev/sda,/dev/sdb"
The optional switch --oklive
can be used to avoid the Prompt "Do you really want to run plugins live on the running host?"
- disks — Specifies the disks on which to enable trim.
disks=all
will enable trim on all drives. Multiple disk names can be specified by, for example,disks=/dev/sda,/dev/sdb
. If no disks are specified,disks=all
is the default.
Additional information on SSD Trim for RasPiOS and Linux can be found here, here, and here.
Install and configure the ufw firewall
ufwscript
— a list of one or more /path/to/script containing a she-bang (#!/bin/bash
) and series of one or more ufw commands to configure the firewall. The traditionalsudo
is not required, since the script is run as root. Multiple scripts, if provided, are run in lexical order.savescriptdir
— Specifies a directory where the ufw plugin will save the providedufwscript
scripts. If not provided, the scripts will be saved in/usr/local/bin
.
--plugin ufw:"/ufwscript=/path/to/script1,/path/to/script2"
— Install ufw and configure it with the two provided script files. Save the script files in the IMG in /usr/local/bin--plugin ufw
— Install ufw, do not configure any rules. ufw documentation says that all inbound network accesses are denied by default
Use the user
plugin to delete, create, or set passwords for users
- userlist — Value is a /path/to/file with a list of "commands". See the discussion below
- Syntax: userlist=/path/to/file
- log — Value is a /path/to/file on the host system where the log is to be created. NOTE: The log is written in Phase 0, while the actual user management is done in Phase 1, except for setting Samba passwords, which is done in the post-install phase.
- Syntax: log=/path/on/host/to/logfile
- adduser — Add the specified user
- Syntax:
adduser=username
- Syntax:
- deluser — Delete the specified user
- Syntax:
deluser=username
- Syntax:
- setpassword — Set the password for the specified user. The user must already exist
- Syntax:
setpassword=username|password=newpassword
- Syntax:
- addgroup — Add a new group
- Syntax:
addgroup=groupname,gid
- Syntax:
- homedir — Specify the home directory for a new user. Default is /home/username. A home directory will not be created if
nohomedir
is specified- Syntax:
homedir=/home/not-the-usual-place
- Syntax:
- uid — Force the new user's ID to be the given number Default is the next uid to be assigned
- Syntax:
uid=name-or-number
- Syntax:
- password — Specify the password for
adduser
andsetpassword
- Syntax:
password=topsecretpassword
- Syntax:
- password-hash — Specify a hashed password for
adduser
. Create the hashed password withmkpasswd --method=SHA=512 --rounds=4096 password
- password-plain — Synonym for the
password
argument - nohomedir — Do not create a home directory for this user
- Syntax:
nohomedir
- Syntax:
- noskel — Do not copy /etc/skel files to the newly-created login directory
- Syntax:
noskel
- Syntax:
- nochown — Do not set the home directory file ownership. Useful for home directories that need to be secured from their users
- Syntax:
nochown
- Syntax:
- Group — Set the initial login group
- Syntax:
Group=primary-group-name
- Syntax:
- groupadd — Augment the user's groups (see
groups
argument) with these. See discussion below- Syntax:
groupadd=groups,to,add
- Syntax:
- groups — Set the list of groups for a user. If not specified,
--groups
is used, with the default:
dialout,cdrom,floppy,audio,video,plugdev,users,adm,sudo,users,input,netdev,spi,i2c,gpio
- prompt — Prompt for the user's password
- Syntax:
prompt
- Syntax:
- rootpwd — Set the root account password to this user's password
- Syntax:
rootpwd
- Syntax:
- redact — At the end of
user
plugin processing, redact all passwords- Syntax:
redact
- Syntax:
- nosudo — Do not enable this account for password-less
sudo
. If you want to remove sudo capability completely for a user, use the commandgpasswd --delete user sudo
in an easily-created personal plugin.- Syntax:
nosudo
- Syntax:
- linger — Enable service lingering for this user
- Syntax:
linger
- Syntax:
- samba — Set a Samba username and password for this user
- Syntax:
samba
- Syntax:
- smbpasswd — Use the provided password for the Samba password instead of the user's password
- Syntax:
smbpasswd=smbpasswdforuser
- Syntax:
- shell — Set the user's shell
- Syntax:
shell=/sbin/nologin
- Syntax:
Conceptually, each invocation of the user
plugin, or each line in a userlist
file, consists of a verb or directive and some arguments. Verbs are:
adduser
— Adds the user as described by the rest of the argumentsdeluser
— Deletes the specified usersetpassword
— Set the user's passwordaddgroup
— Add a new group
So, some example lines in a userlist
(or each set of arguments for several --plugin user
command line switches) are:
deluser=pi
addgroup=myhomegroup,7654
addgroup=demousers
adduser=bls|uid=4321|password=mypassword|groupadd=myhomegroup|Group=users
adduser=demo1|prompt|nohomedir|groups=demousers|nosudo
adduser=demo2|nohomedir|groups=demousers|nosudo|prompt
adduser=demo3|nosudo
setpassword=demo3|password=thenewpassword
In the above
-
The pi account will be deleted, if it exists
-
The two groups will be added.
myhomegroup
will have gid 7654. -
The user
bls
account will be created with the specifiedGroup
, and a default login group ofusers
. The groupmyhomegroup
will be added to the default set of groups (--groups
or the plugingroup
argument). -
The user
demo1
will be created with no home directory. The groupdemousers
will be added to the default set of groups for this user. sdm will prompt for the password. -
The user
demo2
will be created, sdm will prompt for the password -
The user
demo3
will be created and a home directory /home/demo3 will be created -
sdm will set the password for demo3 as a separate step (this is not necessary, btw; one could use the
password=
argument on the demo3 line)The plugin will prompt for the user's password
The above userlist can be equivalently placed on the command line:
--plugin user:"deluser=pi" \
--plugin user:"addgroup=myhomegroup,7654" \
--plugin user:"addgroup=demousers" \
--plugin user:"adduser=bls|uid=4321|password=mypassword|groupadd=myhomegroup|Group=users" \
--plugin user:"adduser=demo1|prompt|nohomedir|groups=demousers" \
--plugin user:"adduser=demo2|nohomedir|groups=demousers|nosudo|prompt" \
--plugin user:"adduser=demo3|nosudo" \
--plugin user:"setpassword=demo3|password=thenewpassword"
Plugins are run in the order they are specified on the command line. I recommend that the user
plugin be as close to the first plugin run as possible, so that the first created user ($myuser) is available to other plugins.
- If you add any users and/or add a password for the user
pi
you probably don't want the RasPiOS services to run at first system boot that help you configure a user. That is exactly what this plugin does, so you can and should disable the RasPiOS services with--plugin disables:piwiz
. - If you want to set a username or password that contains the dollar sign (
$
) special treatment is required:
Install and configure either or both of Virtual VNC and RealVNC.
- vncbase=port — Starting port for VNC Servers (default: 5900)
- realvnc=resolution — Install RealVNC server with the specified resolution on the console. The resolution is optional.
- tigervnc=res1,res2,...resn — Install tigervnc server with virtual VNC servers for the specified resolutions
- tightvnc=res1,res2,...resn — Install tightvnc server with virtual VNC servers for the specified resolutions
- wayvnc[=res] — Enable wayvnc server. If resolution is specified, set it has the Wayland headless resolution
Only one of tigervnc or tightvnc can be installed and configured on a system by sdm.
--plugin vnc:"realvnc|tigervnc=1280x1024,1600x1200
— Install RealVNC server for the console and tigervnc virtual desktop servers for the specified resolutions.--plugin vnc:"realvnc=1600x1200"
— Install RealVNC server and configure the console for 1600x1200, just as raspi-config VNC configuration does.--plugin vnc:"tigervnc=1024x768,1600x1200,1280x1024"
— Install tigervnc virtual desktop servers for the specified resolutions. Only configure RealVNC if it is already installed (e.g., RasPiOS with Desktop IMG).
By default Virtual VNC desktops are configured with ports 5901, 5902, ... This can be modified with the --vncbase
base switch. For instance, --vncbase 6400
would place the VNC virtual desktops at ports 6401, 6402, ... Setting --vncbase
does not change the RealVNC server port.
For RasPiOS Desktop, RealVNC Server will be enabled automatically. Well, actually, it will be disabled for the first boot of the system as will the graphical desktop, and the sdm FirstBoot service will-reenable both for subsequent use.
For RasPiOS Lite, if the nodmconsole
keyword is specified to the graphics plugin AND the Display Manager is xdm or wdm, the Display Manager will not be started on the console, and neither will RealVNC Server. It can be started later, if desired, with sudo systemctl enable --now vncserver-x11-serviced
. Note, however, that you must enable the Display Manager as well for it to really be enabled. To enable the Display Manager:
- xdm:
sed -i "s/\#\:0 local \/usr\/bin\/X :0 vt7 -nolisten tcp/\:0 local \/usr\/bin\/X :0 vt7 -nolisten tcp/" /etc/X11/xdm/Xservers
- wdm:
sed -i "s/\#\:0 local \/usr\/bin\/X :0 vt7 -nolisten tcp/\:0 local \/usr\/bin\/X :0 vt7 -nolisten tcp/" /etc/X11/wdm/Xservers
wificonfig is used to enable the sdm Captive Portal to delay WiFi SSID/Password configuration until the first system boot.
- apssid=APSSID —SSID for the Access Point. Default: sdm
- apip=ap.ip.ad.dr —IP Address for the Access Point. Default: 10.1.1.1
- country=cc —Two-letter WiFi country code. The codes are found in /usr/share/zoneinfo/iso3166.tab
- defaults=/path/to/defaults —Path to defaults file. See Defaults file for details
- facility=facname —Facility name. Default: sdm
- retries=n —Maximum number of retries for the user to set the SSID/Password. Default: 5
- timeout=n —Captive Portal timeout (interval between network packets from the connecting device). Default: 900 seconds (15 minutes)
- wifilog=/path/to/wifilog —Log file for the Captive Portal. Default: /etc/sdm/wifi-config.log
wsdd is the Web Service Discovery host daemon. It's very useful in Windows/Samba environments. You can read about it at https://github.com/christgau/wsdd
Note that wsdd is available in Bookworm via apt, so this plugin is not needed on Bookworm (Debian 12) or later, although it can still be used if you prefer.
- wsddswitches=switchlist — List of switches to write into /etc/default/wsdd
- localsrc=/path/to/files — Local directory with cached copy of wsdd (files: wsdd.py wsdd.8 wsdd.defaults wsdd.service)