EC2: Add desktop flavour

Desktop AMIs have xrdp enabled and boot to a KDE desktop; they are
as compatible as possible with EC2 Windows AMIs, setting a random
password and printing it to the console in encrypted format to be
retrieved using the EC2 GetPasswordData API.

Two rc.d scripts are included in this commit which will not exist
in the long term: ec2_addpass will become part of the ec2-scripts
package, and ec2_desktop_extras will go away once its functionality
is included elsewhere.

MFC After:	1 month
Relnotes:	yes
Sponsored by:	Amazon
This commit is contained in:
Colin Percival committed 2026-09-07 00:54:04 -07:00
1 parent d983dc521b
commit a971034951
4 files changed
+193 -1

No files matched your search

+2 -1
View File
@@ -36,10 +36,11 @@ BASIC-CLOUDINIT_FSLIST?= ufs zfs
BASIC-CLOUDINIT_DESC?= Images for VM with cloudinit disk config support
EC2_FORMAT= raw
EC2_FSLIST?= ufs zfs
EC2_FLAVOURS?= BASE BUILDER CLOUD-INIT SMALL
EC2_FLAVOURS?= BASE BUILDER CLOUD-INIT DESKTOP SMALL
EC2-BASE_DESC= Amazon EC2 image
EC2-BUILDER_DESC= Amazon EC2 AMI Builder image
EC2-CLOUD-INIT_DESC= Amazon EC2 Cloud-Init image
EC2-DESKTOP_DESC= Amazon EC2 GUI image
EC2-SMALL_DESC= Amazon EC2 small image
GCE_FORMAT= raw
GCE_FSLIST?= ufs zfs
+73
View File
@@ -0,0 +1,73 @@
#!/bin/sh
. ${WORLDDIR}/release/tools/ec2.conf
# Build with a (just under) 20 GB partition; all of the "desktop" bits
# significantly bloat the image compared with stock FreeBSD.
export VMSIZE=20000m
# Packages to install into the image we're creating. In addition to packages
# present on all EC2 AMIs, we install:
# * amazon-ssm-agent (not enabled by default, but some users need to use
# it on systems not connected to the internet),
# * ec2-scripts, which provides a range of EC2ification startup scripts,
# * firstboot-pkg-upgrade, to install security updates at first boot,
# * firstboot-pkgs, to install packages at first boot, and
# * isc-dhcp44-client, used for IPv6 network setup, and
# * kde, to provide a useful desktop environment
# * chromium and libreoffice, to provide an office environment,
# * xorg, xrdp, and xorgxrdp, to provide the display server.
export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} amazon-ssm-agent ec2-scripts \
firstboot-pkg-upgrade firstboot-pkgs isc-dhcp44-client \
kde chromium libreoffice xorg xrdp xorgxrdp"
# Services to enable in rc.conf(5).
export VM_RC_LIST="${VM_RC_LIST} ec2_configinit ec2_ephemeral_swap \
ec2_fetchkey ec2_setpass ec2_loghostkey firstboot_pkg_upgrade \
firstboot_pkgs growfs growfs_postboot sshd dbus xrdp xrdp_sesman"
vm_extra_pre_umount() {
# Limit firstboot_pkg_upgrade to the base system.
echo 'firstboot_pkg_upgrade_repos="FreeBSD-base"' >> ${DESTDIR}/etc/rc.conf
# Don't allocate swap space when we first boot; that makes it
# impossible to grow the root filesystem later.
echo 'growfs_swap_size=0' >> ${DESTDIR}/etc/rc.conf
# Give users a KDE desktop by default.
sed -i '' -e '/exec.*startplasma/s/^# //' ${DESTDIR}/usr/local/etc/xrdp/startwm.sh
# Use UID/GID _xrdp. Disabled for now until the port supports this.
#sed -i '' -e '/SessionSockdirGroup/s/^#//' ${DESTDIR}/usr/local/etc/xrdp/sesman.ini
#sed -i '' -E -e '/runtime_(user|group)=_xrdp/s/^#//' ${DESTDIR}/usr/local/etc/xrdp/xrdp.ini
# Set login password and print in encrypted form to the console.
# This will be removed from here once it lands in the ec2-scripts port.
install -m 755 ${WORLDDIR}/release/tools/ec2_setpass ${DESTDIR}/usr/local/etc/rc.d
metalog_add_data ./usr/local/etc/rc.d/ec2_setpass 0755
# Run some additional commands on first boot which won't be
# necessary once (a) the xrdp port gains host key generation as
# an rc.d script, and (b) pkg triggers are logged in METALOG and
# run from a firstboot script.
install -m 755 ${WORLDDIR}/release/tools/ec2_desktop_extras ${DESTDIR}/usr/local/etc/rc.d
metalog_add_data ./usr/local/etc/rc.d/ec2_desktop_extras 0755
# Any EC2 ephemeral disks seen when the system first boots will
# be "new" disks; there is no "previous boot" when they might have
# been seen and used already.
touch ${DESTDIR}/var/db/ec2_ephemeral_diskseen
metalog_add_data ./var/db/ec2_ephemeral_diskseen
# Configuration common to all EC2 AMIs
ec2_common
# Standard FreeBSD network configuration
ec2_base_networking
# Add files from packages which weren't recorded in metalog
metalog_add_data ./usr/local/etc/dhclient.conf
metalog_add_data ./usr/local/etc/ssl/cert.pem
return 0
}
+60
View File
@@ -0,0 +1,60 @@
#!/bin/sh
# KEYWORD: firstboot
# PROVIDE: ec2_desktop_extras
# REQUIRE: ldconfig
# BEFORE: ec2_setpass
# BEFORE: xrdp
# Forcibly enabled; this script will not be included (in fact will be
# deleted entirely) once its functionality is included elsewhere.
ec2_desktop_extras_enable=YES
. /etc/rc.subr
name="ec2_desktop_extras"
rcvar=ec2_desktop_extras_enable
start_cmd="ec2_desktop_extras_run"
stop_cmd=":"
ec2_desktop_extras_run()
{
# These should run at first boot from pkg triggers, but those
# aren't included in VM images yet.
/usr/bin/makewhatis /usr/share/man
/usr/bin/makewhatis /usr/share/openssl/man
/usr/local/bin/fc-cache -s
/usr/local/bin/glib-compile-schemas /usr/local/share/glib-2.0/schemas
/usr/local/bin/gio-querymodules /usr/local/lib/gio/modules
/usr/local/bin/gdk-pixbuf-query-loaders --update-cache
/usr/local/bin/update-desktop-database -q
/usr/local/bin/update-mime-database /usr/local/share/mime
for d in /usr/local/share/icons/*/; do
[ -d "$d" ] || continue
/usr/local/bin/gtk-update-icon-cache -q -t -f "${d%/}"
done
# This should from from an rc.d script in xrdp.
RSAKEYS=/usr/local/etc/xrdp/rsakeys.ini
PRIVATEKEY=/usr/local/etc/xrdp/key.pem
CERTIFICATE=/usr/local/etc/xrdp/cert.pem
# make sure rsakeys and certificates are private
umask 077
# generate rsakeys.ini
[ -e "$RSAKEYS" ] || /usr/local/bin/xrdp-keygen xrdp "$RSAKEYS" && \
# generate self-signed certificate
[ -e "$PRIVATEKEY" -a -e "$CERTIFICATE" ] || \
/usr/bin/openssl req \
-x509 \
-newkey rsa:4096 \
-keyout "$PRIVATEKEY" \
-sha256 \
-nodes \
-out "$CERTIFICATE" \
-days 365 \
-subj "/CN=$(hostname)"
}
load_rc_config $name
run_rc_command "$1"
+58
View File
@@ -0,0 +1,58 @@
#!/bin/sh
# KEYWORD: firstboot
# PROVIDE: ec2_setpass
# REQUIRE: ec2_fetchkey
# BEFORE: LOGIN
# Define ec2_setpass_enable=YES in /etc/rc.conf to enable setting the
# account password and printing in encrypted format to the console.
: ${ec2_setpass_enable=NO}
# We reuse the user name from ec2_fetchkey since that creates the user
# and fetches the SSH key which is used to encrypt the password.
: ${ec2_fetchkey_user=ec2-user}
. /etc/rc.subr
name="ec2_setpass"
rcvar=ec2_setpass_enable
start_cmd="ec2_setpass_run"
stop_cmd=":"
ec2_setpass_run()
{
# If the user does not exist or has no SSH key, return.
HOMEDIR=$(pw user show ${ec2_fetchkey_user} 2>/dev/null | awk -F: '{print $9}')
SSHKEYFILE="${HOMEDIR}/.ssh/authorized_keys"
if [ -z "${HOMEDIR}" ] || ! [ -f "${SSHKEYFILE}" ]; then
return
fi
# Print the RDP certificate fingerprint
echo "HOSTNAME: freebsd"
echo "RDPCERTIFICATE-SUBJECTNAME: freebsd"
FINGERSHA1=$(openssl x509 -in /usr/local/etc/xrdp/cert.pem \
-noout -fingerprint -sha1 | cut -f 2- -d = | tr -d :)
FINGERSHA256=$(openssl x509 -in /usr/local/etc/xrdp/cert.pem \
-noout -fingerprint -sha256 | cut -f 2- -d = | tr A-F a-f)
echo "RDPCERTIFICATE-THUMBPRINT: ${FINGERSHA1}"
echo "RDPCERTIFICATE-THUMBPRINT256: ${FINGERSHA256}"
# Set a random password, and print it in encrypted format
PUBKEY=$(mktemp -t ec2_setpass)
ssh-keygen -e -m PKCS8 -f ${SSHKEYFILE} > ${PUBKEY}
PASSWD=`jot -cr 16 / z | tr '\\`' '-+' | rs -g 0`
echo "${PASSWD}" | pw usermod ${ec2_fetchkey_user} -h 0
echo "Username: ${ec2_fetchkey_user}"
echo "Password: <Password>"
printf "%s" "${PASSWD}" |
openssl pkeyutl -encrypt -pubin -inkey ${PUBKEY} -pkeyopt rsa_padding_mode:pkcs1 |
base64 -w 0
echo "</Password>"
echo 'Message: Windows is Ready to use'
}
load_rc_config $name
run_rc_command "$1"