Add ssh port.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-02-26 14:16:08 +01:00
parent 18cb2651be
commit b9a72bbfbc
14 changed files with 2524 additions and 9 deletions

View File

@ -125,6 +125,7 @@ mkdir -p boot/grub/init
echo "furthermore" > boot/grub/init/furthermore
# TODO: Possibly use a 'try' feature to not warn in case it was already unset.
echo "unset require dhclient" > boot/grub/init/network-no-dhclient
echo "require sshd optional" > boot/grub/init/local-sshd
exec > boot/grub/grub.cfg
@ -193,6 +194,7 @@ fi
set enable_src=true
set enable_network_drivers=
set enable_dhclient=true
set enable_sshd=false
export version
export machine
@ -204,6 +206,7 @@ export no_random_seed
export enable_src
export enable_network_drivers
export enable_dhclient
export enable_sshd
EOF
if [ -n "$ports" ]; then
@ -299,6 +302,11 @@ cat << EOF
module /boot/grub/init/network-no-dhclient --append-to /etc/init/network
echo done
fi
if \$enable_sshd; then
echo -n "Enabling sshd ... "
module /boot/grub/init/local-sshd --append-to /etc/init/local
echo done
fi
if [ \$no_random_seed != --no-random-seed ]; then
echo -n "Loading /boot/random.seed (256) ... "
module /boot/random.seed --random-seed
@ -458,6 +466,18 @@ else
}
fi
if \$enable_sshd; then
menuentry "Disable SSH server" {
enable_sshd=false
configfile /boot/grub/advanced.cfg
}
else
menuentry "Enable SSH server" {
enable_sshd=true
configfile /boot/grub/advanced.cfg
}
fi
menuentry "Select binary packages..." {
configfile /boot/grub/tix.cfg
}

View File

@ -1,3 +1,3 @@
set_minimal="cut dash e2fsprogs grep grub mdocml sed xargs"
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurl libcurses libssl libstdc++ nano make patch pkg-config python tar vim wget xz xorriso"
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurl libcurses libssl libstdc++ nano make patch pkg-config python ssh tar vim wget xz xorriso"
sets="basic minimal"

View File

@ -99,13 +99,33 @@
is updated to not rely on this macro. */
#undef __SORTIX_HAS_RESTARTABLE_SYSCALLS__
/* TODO: Define when initgroups(2) is implemented. Remove when libdbus is
/* TODO: Define when general user security is implemented. Remove when ssh is
updated to not rely on this macro. */
#undef __SORTIX_HAS_UID_SECURITY__
/* TODO: Define when mmap MAP_SHARED works properly. Remove when ssh is updated
to not rely on this macro. */
#undef __SORTIX_HAS_WORKING_MAP_SHARED__
/* TODO: Define when shared memory, file descriptor passing, and general user
security are implemented. Remove when ssh is updated to not rely on
this macro. */
#undef __SORTIX_HAS_WORKING_PRIVSEP__
/* TODO: Define when initgroups(2) is implemented. Remove when libdbus and ssh
are updated not rely on this macro. */
#undef __SORTIX_HAS_INITGROUPS__
/* TODO: Define when setgroups(2) is implemented. Remove when libdbus is updated
to not rely on this macro. */
/* TODO: Define when setgroups(2) is implemented. Remove when libdbus and ssh
are updated not rely on this macro. */
#undef __SORTIX_HAS_SETGROUPS__
/* TODO: Define when getgroups(2) is implemented. Remove when ssh is updated to
not rely on this macro. */
#undef __SORTIX_HAS_GETGROUPS__
/* TODO: Define when getservbyname(3) is implemented and works. Remove when ssh
is updated to not rely on this macro. */
#undef __SORTIX_HAS_GETSERVBYNAME__
#endif

1781
ports/ssh/ssh.patch Normal file

File diff suppressed because it is too large Load Diff

12
ports/ssh/ssh.port Normal file
View File

@ -0,0 +1,12 @@
NAME=ssh
BUILD_LIBRARIES='libz libssl'
VERSION=9.2p1
DISTNAME=openssh-$VERSION
COMPRESSION=tar.gz
ARCHIVE=$DISTNAME.$COMPRESSION
SHA256SUM=3f66dbf1655fb45f50e1c56da62ab01218c228807b21338d634ebcdf9d71cf46
UPSTREAM_SITE=https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable
UPSTREAM_ARCHIVE=$ARCHIVE
LICENSE='SSH-OpenSSH AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT'
BUILD_SYSTEM=configure
VERSION_REGEX='([0-9]+\.[0-9]+p[0-9]+)'

View File

@ -79,11 +79,16 @@ Optionally, you might want to modify a release .iso to meet your custom needs
per the instructions in
.Xr release-iso-modification 7 .
.Pp
If you want to ssh into your installation, it's recommended to amend the
installation .iso with your public key, pregenerated the server keys and obtain
fingerprints, and seed randomness using this procedure.
.Pp
The release modification procedure lets you customize aspects such as the
default bootloader menu option and timeout, the default hostname, the default
keyboard layout, the default graphics resolution, adding files of your choice to
the live environment, control which drivers are loaded by default, control which
live environment daemons are started by default, and so on.
live environment daemons are started by default, deploy ssh keys so secure shell
connections are trusted on the first connection, and so on.
.Pp
Warning: The live environment does not come with any random entropy and entropy
gathering is not yet implemented.
@ -358,6 +363,8 @@ A root account is made in
and
.Xr group 5 .
This question is skipped if the root account already exists.
If the live environment's root user has ssh keys and configuration, you will be
asked whether you'd like to copy the files to the new installation.
.Ss Users
You will be asked in a loop if you wish to make another user.
Answer
@ -378,6 +385,25 @@ and
.Pp
Please note that Sortix is not currently secure as a multi-user system and
filesystem permissions are not enforced.
.Ss SSH Server
You will be asked if you want to enable a
.Xr sshd 8
server for remotely logging into this machine over a secure cryptographic
channel.
Answer no if in doubt as anyone who obtains your credentials will be able to
connect to your computer and log in as you.
Password authentication is disabled by default as public key cryptography should
be used for security, but if you have a very strong password, you could enable
it when asked.
It's recommended to securely bootstrap ssh authentication using the
.Xr release-iso-modification 7
procedure to amend the installation medium with your public key, pregenerated
server private keys, and a random seed.
You are using a bad workflow if you encounter a ssh server fingerprint check.
If the installer environment contains a
.Xr sshd_config
or private sshd keys, then you will be asked if you want to copy the files into
the new installation.
.Ss Completion
This will complete the operating system installation.
Upon reboot, the new system will start normally.

View File

@ -279,6 +279,11 @@ Whether to load the source code initrd containing
.Pa /src .
(Default:
.Sy true )
.It Sy enable_sshd
Whether to start the
.Xr sshd 8
daemon.
(Default: false)
.It Sy machine
The machine type this release was built for.
.It Sy menu_title

View File

@ -17,7 +17,8 @@ The release modification procedure lets you customize aspects such as the
default bootloader menu option and timeout, the default hostname, the default
keyboard layout, the default graphics resolution, adding files of your choice to
the live environment, control which drivers are loaded by default, control which
live environment daemons are started by default, and so on.
live environment daemons are started by default, deploy ssh keys so secure shell
connections are trusted on the first connection, and so on.
.Ss Prerequisites
.Bl -bullet -compact
.It
@ -408,6 +409,110 @@ wants to manually configure network interfaces with
tix-iso-bootconfig --disable-dhclient bootconfig
tix-iso-add sortix.iso bootconfig
.Ed
.Ss Enable SSH Server By Default
To customize a release so it starts the SSH server
.Xr sshd 8
automatically using the SSH configuration found in the liveconfig directory:
.Bd -literal
tix-iso-bootconfig --liveconfig=liveconfig --enable-sshd bootconfig
tix-iso-add sortix.iso bootconfig
.Ed
.Ss SSH Into Live Environment
To customize the live environment of a release so you can ssh into its root
user, to have the hostname
.Sy example.com ,
to start a ssh server with the keys generated now, authorize the local user to
ssh into the live environment's root user, and register the sshd server's keys
by their hostnames and network addresses so the connection is trusted on the
first attempt (you can omit the network addresses if you don't know yet):
.Bd -literal
tix-iso-liveconfig \\
--hostname=example.com \\
--root-ssh-authorized-keys="$HOME/.ssh/id_rsa.pub" \\
--sshd-keygen \\
--sshd-key-known-hosts-file="$HOME/.ssh/known_hosts" \\
--sshd-key-known-hosts-hosts="example.com example.com,192.0.2.1 192.0.2.1" \\
liveconfig
tix-iso-bootconfig --liveconfig=liveconfig --enable-sshd bootconfig
tix-iso-add sortix.iso bootconfig
rm -f liveconfig/etc/ssh_host_*_key # When no longer useful.
rm -f bootconfig/boot/liveconfig.xz # When no longer useful.
rm -f sortix.iso # When no longer useful.
# And erase any media made from sortix.iso when no longer useful.
ssh root@example.org # When the system is running.
.Ed
.Pp
This example generates sshd private keys (remember to delete them when no longer
needed, see the warnings in
.Xr tix-iso-liveconfig 8 )
and shows them by running:
.Bd -literal
mkdir -p liveconfig/etc
for keytype in rsa ecdsa ed25519; do
ssh-keygen -t $keytype -f liveconfig/etc/ssh_host_${keytype}_key" -N "" \\
-C "root@$hostname"
done
for keytype in rsa ecdsa ed25519; do
ssh-keygen -l -f liveconfig/etc/ssh_host_${keytype}_key
done
.Ed
.Pp
It then constructs a
.Pa known_hosts
file for each network address and hashes it.
.Bd -literal
(for host in $network_addresses; do
for keytype in rsa ecdsa ed25519; do
printf '%s ' "$host" &&
sed -E 's/^([^ ]* [^ ]*).*/\1/' \\
liveconfig/etc/ssh_host_${keytype}_key.pub
done
done) > known_hosts
ssh-keygen -H -f known_hosts
rm -f known_hosts.old
.Ed
.Pp
.Xr ssh 1
will trust the server by the network addresses on the first connection if you
append the contents of
.Pa known_hosts
to your
.Pa ~/.ssh/known_hosts .
.Pa liveconfig/root/.ssh/authorized_keys
file is made by appending the appropriate public keys previously made with
.Xr ssh-keygen 1 .
.Ss SSH Back From Live Environment
To customize the live environment of a release so its root user can ssh back to
your user, where the local hostname is
.Sy example.com
(the address to which the new installation will be connecting), by
generating a private key for the root user
(remember to delete it when no longer
needed, see the warnings in
.Xr tix-iso-liveconfig 8 )
and adding its public key to your local
.Pa ~/.ssh/authorized_keys :
.Bd -literal
tix-iso-liveconfig --root-ssh-keygen liveconfig
ssh-keyscan -H example.com > liveconfig/root/.ssh/known_hosts
cat liveconfig/root/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
tix-iso-bootconfig --liveconfig=liveconfig --enable-sshd bootconfig
tix-iso-add sortix.iso bootconfig
rm -f output-directory/root/.ssh/id_rsa # When no longer useful.
rm -f bootconfig/boot/liveconfig.xz # When no longer useful.
rm -f sortix.iso # When no longer useful.
# And erase any media made from sortix.iso when no longer useful.
.Ed
.Pp
This example will generate a ssh key for the root user by running:
.Bd -literal
mkdir -p -m 700 liveconfig/root/.ssh
ssh-keygen -t rsa -f liveconfig/root/.ssh/id_rsa -N "" -C "root@$hostname"
.Ed
.Pp
Consider omitting the
.Fl N
option and password protect the private key to protect it in the case of a leak.
.Sh SEE ALSO
.Xr xorriso 1 ,
.Xr development 7 ,

View File

@ -30,7 +30,8 @@ The release modification procedure lets you customize aspects such as the
default bootloader menu option and timeout, the default hostname, the default
keyboard layout, the default graphics resolution, adding files of your choice to
the live environment, control which drivers are loaded by default, control which
live environment daemons are started by default, and so on.
live environment daemons are started by default, deploy ssh keys so secure shell
connections are trusted on the first connection, and so on.
.Pp
Warning: The live environment does not come with any random entropy and entropy
gathering is not yet implemented.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, 2020, 2021 Jonas 'Sortie' Termansen.
* Copyright (c) 2015, 2016, 2020, 2021, 2022, 2023 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -439,6 +439,14 @@ int main(void)
"impatient. Take the time to read the documentation and be patient "
"while you learn the new system. This is a very good time to start an "
"external music player that plays soothing classical music on loop.\n\n");
if ( !access_or_die("/tix/tixinfo/ssh", F_OK) &&
access_or_die("/root/.ssh/authorized_keys", F_OK) < 0 )
text("If you wish to ssh into your new installation, it's recommended "
"to first add your public keys to the .iso and obtain "
"fingerprints per release-iso-modification(7) before installing."
"\n\n");
const char* readies[] =
{
"Ready",
@ -1026,6 +1034,56 @@ int main(void)
textf("Group '%s' added to /etc/group.\n", "root");
break;
}
struct ssh_file
{
const char* key;
const char* path;
const char* pub;
};
const struct ssh_file ssh_files[] =
{
{"copy_ssh_authorized_keys_root", "/root/.ssh/authorized_keys", NULL},
{"copy_ssh_config_root", "/root/.ssh/config", NULL},
{"copy_ssh_id_rsa_root", "/root/.ssh/id_rsa", "/root/.ssh/id_rsa.pub"},
{"copy_ssh_known_hosts_root", "/root/.ssh/known_hosts", NULL},
};
size_t ssh_files_count = sizeof(ssh_files) / sizeof(ssh_files[0]);
bool any_ssh_keys = false;
for ( size_t i = 0; i < ssh_files_count; i++ )
{
const struct ssh_file* file = &ssh_files[i];
if ( access_or_die(file->path, F_OK) < 0 )
continue;
text("\n");
textf("Found %s\n", file->path);
if ( file->pub && !access_or_die(file->pub, F_OK) )
textf("Found %s\n", file->pub);
while ( true )
{
char question[256];
snprintf(question, sizeof(question),
"Copy %s from installer environment? (yes/no)",
file->path);
prompt(input, sizeof(input), file->key, question, "yes");
if ( strcasecmp(input, "no") == 0 )
break;
if ( strcasecmp(input, "yes") != 0 )
continue;
mkdir_or_chmod_or_die("root/.ssh", 0700);
textf("Copying %s -> %s\n", file->path, file->path + 1);
execute((const char*[])
{"cp", file->path, file->path+ 1, NULL }, "f");
if ( file->pub )
{
textf("Copying %s -> %s\n", file->pub, file->pub + 1);
execute((const char*[])
{"cp", file->pub, file->pub + 1, NULL }, "f");
}
any_ssh_keys = true;
break;
}
}
text("\n");
if ( mkdir("etc/init", 0755) < 0 )
@ -1131,6 +1189,171 @@ int main(void)
// TODO: Ask if networking should be disabled / enabled.
struct sshd_key_file
{
const char* pri;
const char* pub;
};
const struct sshd_key_file sshd_key_files[] =
{
{"/etc/ssh_host_ecdsa_key", "/etc/ssh_host_ecdsa_key.pub"},
{"/etc/ssh_host_ed25519_key", "/etc/ssh_host_ed25519_key.pub"},
{"/etc/ssh_host_rsa_key", "/etc/ssh_host_rsa_key.pub"},
};
size_t sshd_key_files_count
= sizeof(sshd_key_files) / sizeof(sshd_key_files[0]);
bool any_sshd_keys = false;
for ( size_t i = 0; i < sshd_key_files_count; i++ )
{
if ( !access_or_die(sshd_key_files[i].pri, F_OK) )
{
textf("Found %s\n", sshd_key_files[i].pri);
any_sshd_keys = true;
}
}
bool enabled_sshd = false;
if ( !access_or_die("/tix/tixinfo/ssh", F_OK) )
{
text("A ssh server has been installed. You have the option of starting "
"it on boot to allow remote login over a cryptographically secure "
"channel. Answer no if you don't know what ssh is.\n\n");
if ( !any_sshd_keys )
text("Warning: " BRAND_DISTRIBUTION_NAME " does not yet collect "
"entropy for secure random numbers. Unless you type '!' and "
"escape to a shell and put 256 bytes of actual randomness "
"into boot/random.seed, the first boot will use the "
"randomness of this installer environment to generate ssh "
"keys. This initial randomness may be as weak as the wall "
"time when you booted the installer, which is easily guessed "
"by an attacker. The same warning applies to outgoing secure "
"connections as well.\n\n");
bool might_want_sshd =
any_ssh_keys ||
any_sshd_keys ||
!access_or_die("/etc/sshd_config", F_OK);
while ( true )
{
prompt(input, sizeof(input), "enable_ssh",
"Enable ssh server? (yes/no)",
might_want_sshd ? "yes" : "no");
if ( strcasecmp(input, "no") == 0 )
break;
if ( strcasecmp(input, "yes") != 0 )
continue;
if ( !install_configurationf("etc/init/local", "a",
"require sshd optional\n") )
{
warn("etc/init/local");
continue;
}
enabled_sshd = true;
text("Added 'require sshd optional' to /etc/init/local\n");
text("The ssh server will be started when the system boots.\n");
break;
}
text("\n");
}
bool has_sshd_config = false;
if ( !access_or_die("/etc/sshd_config", F_OK) )
{
while ( true )
{
prompt(input, sizeof(input), "copy_sshd_config",
"Copy /etc/sshd_config from installer environment? (yes/no)",
"yes");
if ( strcasecmp(input, "no") == 0 )
break;
if ( strcasecmp(input, "yes") != 0 )
continue;
const char* file = "/etc/sshd_config";
textf("Copying %s -> %s\n", file, file + 1);
execute((const char*[]) {"cp", file, file + 1}, "f");
has_sshd_config = true;
break;
}
text("\n");
}
if ( enabled_sshd && !has_sshd_config )
{
text("Password authentication has been disabled by default in sshd to "
"prevent remotely guessing insecure passwords. The recommended "
"approach is to put your public key in the installation .iso and "
"generate the sshd credentials ahead of time as documented in "
"release-iso-modification(7). However, you could enable password "
"authentication if you picked a very strong password.\n\n");
bool enable_sshd_password = false;
while ( true )
{
prompt(input, sizeof(input), "enable_ssh_password",
"Enable sshd password authentication? (yes/no)", "no");
if ( strcasecmp(input, "no") == 0 )
break;
if ( strcasecmp(input, "yes") != 0 )
continue;
if ( !install_configurationf("etc/sshd_config", "a",
"PasswordAuthentication yes\n") )
{
warn("etc/sshd_config");
continue;
}
enable_sshd_password = true;
text("Added 'PasswordAuthentication yes' to /etc/sshd_config\n");
break;
}
while ( enable_sshd_password )
{
prompt(input, sizeof(input), "enable_ssh_root_password",
"Enable sshd password authentication for root? (yes/no)",
"no");
if ( strcasecmp(input, "no") == 0 )
break;
if ( strcasecmp(input, "yes") != 0 )
continue;
if ( !install_configurationf("etc/sshd_config", "a",
"PermitRootLogin yes\n") )
{
warn("etc/sshd_config");
continue;
}
text("Added 'PermitRootLogin yes' to /etc/sshd_config\n");
break;
}
text("\n");
}
if ( any_sshd_keys )
{
while ( true )
{
const char* question =
"Copy sshd private keys from installer environment? (yes/no)";
prompt(input, sizeof(input), "copy_sshd_private_keys",
question,
"yes");
if ( strcasecmp(input, "no") == 0 )
break;
if ( strcasecmp(input, "yes") != 0 )
continue;
for ( size_t i = 0; i < sshd_key_files_count; i++ )
{
const struct sshd_key_file* file = &sshd_key_files[i];
if ( access_or_die(file->pri, F_OK) < 0 )
continue;
textf("Copying %s -> %s\n", file->pri, file->pri + 1);
execute((const char*[])
{"cp", file->pri, file->pri + 1, NULL }, "f");
textf("Copying %s -> %s\n", file->pub, file->pub + 1);
execute((const char*[])
{"cp", file->pub, file->pub + 1, NULL }, "f");
}
break;
}
text("\n");
}
text("It's time to boot into the newly installed system.\n\n");
if ( strcasecmp(accept_grub, "no") == 0 )

View File

@ -25,6 +25,7 @@ enable_append_title=true
enable_dhclient=
enable_network_drivers=
enable_src=
enable_sshd=
init_target=
liveconfig=
operand=1
@ -56,10 +57,12 @@ for argument do
--disable-dhclient) enable_dhclient=false ;;
--disable-network-drivers) enable_network_drivers=false ;;
--disable-src) enable_src=false ;;
--disable-sshd) enable_sshd=false ;;
--enable-append-title) enable_append_title=true ;;
--enable-dhclient) enable_dhclient=true ;;
--enable-network-drivers) enable_network_drivers=true ;;
--enable-src) enable_src=true ;;
--enable-sshd) enable_sshd=true ;;
--init-target=*) init_target=$parameter ;;
--init-target) previous_option=init_target ;;
--liveconfig=*) liveconfig=$parameter ;;
@ -144,6 +147,7 @@ mkdir -p -- "$directory/boot/grub"
print_enable_default_bool "$enable_dhclient" dhclient dhclient
print_enable_default "$enable_network_drivers" network_drivers network-drivers
print_enable_default_bool "$enable_src" src src
print_enable_default_bool "$enable_sshd" sshd sshd
if $enable_append_title; then
printf "base_menu_title=\"\$base_menu_title - \"'%s'\n" \
"$(printf '%s\n' "$append_title" | sed "s/'/'\\\\''/g")"

View File

@ -12,10 +12,12 @@
.Op Fl \-disable-dhclient
.Op Fl \-disable-network-drivers
.Op Fl \-disable-src
.Op Fl \-disable-sshd
.Op Fl \-enable-append-title
.Op Fl \-enable-dhclient
.Op Fl \-enable-network-drivers
.Op Fl \-enable-src
.Op Fl \-enable-sshd
.Op Fl \-init-target Ns = Ns Ar target
.Op Fl \-liveconfig Ns = Ns Ar liveconfig-directory
.Op Fl \-random-seed
@ -116,6 +118,14 @@ by setting
.Sy enable_src
GRUB variable to
.Sy false .
.It Fl \-disable-sshd
Disable automatically starting the ssh server by setting the
.Sy enable_sshd
GRUB variable to
.Sy false ,
selecting the default behavior of not starting the
.Xr sshd 8
daemon.
.It Fl \-enable-append-title
Enable appending " - " followed by the value set with
.Fl \-append-title
@ -147,6 +157,14 @@ by setting
.Sy enable_src
GRUB variable to
.Sy true .
.It Fl \-enable-sshd
Enable automatically starting the ssh server by setting the
.Sy enable_sshd
GRUB variable to
.Sy true ,
causing the bootloader to load additional configuration that turns on the
.Xr sshd 8
daemon on boot.
.It Fl \-init-target Ns = Ns Ar target
Add a new first menu entry that boots the
.Ar target
@ -299,6 +317,14 @@ wants to manually configure network interfaces with
tix-iso-bootconfig --disable-dhclient bootconfig
tix-iso-add sortix.iso bootconfig
.Ed
.Ss Enable SSH Server By Default
To customize a release so it starts the SSH server
.Xr sshd 8
automatically using the SSH configuration found in the liveconfig directory:
.Bd -literal
tix-iso-bootconfig --liveconfig=liveconfig --enable-sshd bootconfig
tix-iso-add sortix.iso bootconfig
.Ed
.Sh SEE ALSO
.Xr xorriso 1 ,
.Xr kernel 7 ,

View File

@ -23,6 +23,15 @@ directory=
hostname=
kblayout=
operand=1
root_ssh_authorized_keys=
root_ssh_config=
root_ssh_keygen=false
root_ssh_known_hosts=
ssh_config=
sshd_config=
sshd_keygen=false
sshd_key_known_hosts_file=
sshd_key_known_hosts_hosts=
videomode=
dashdash=
@ -48,6 +57,22 @@ for argument do
--hostname) previous_option=hostname ;;
--kblayout=*) kblayout=$parameter ;;
--kblayout) previous_option=kblayout ;;
--root-ssh-authorized-keys=*) root_ssh_authorized_keys=$parameter ;;
--root-ssh-authorized-keys) previous_option=root_ssh_authorized_keys ;;
--root-ssh-config=*) root_ssh_config=$parameter ;;
--root-ssh-config) previous_option=root_ssh_config ;;
--root-ssh-keygen) root_ssh_keygen=true ;;
--root-ssh-known-hosts=*) root_ssh_known_hosts=$parameter ;;
--root-ssh-known-hosts) previous_option=root_ssh_known_hosts ;;
--ssh-config=*) ssh_config=$parameter ;;
--ssh-config) previous_option=ssh_config ;;
--sshd-config=*) sshd_config=$parameter ;;
--sshd-config) previous_option=sshd_config ;;
--sshd-keygen) sshd_keygen=true ;;
--sshd-key-known-hosts-file=*) sshd_key_known_hosts_file=$parameter ;;
--sshd-key-known-hosts-file) previous_option=sshd_key_known_hosts_file ;;
--sshd-key-known-hosts-hosts=*) sshd_key_known_hosts_hosts=$parameter ;;
--sshd-key-known-hosts-hosts) previous_option=sshd_key_known_hosts_hosts ;;
--videomode=*) videomode=$parameter ;;
--videomode) previous_option=videomode ;;
-*) echo "$0: unrecognized option $argument" >&2
@ -101,3 +126,72 @@ if [ -n "$videomode" ]; then
mkdir -p -- "$directory/etc"
printf "%s\n" "$videomode" > "$directory/etc/videomode"
fi
if [ -n "$ssh_config" ]; then
mkdir -p -- "$directory/etc"
cp -- "$ssh_config" "$directory/etc/ssh_config"
fi
if [ -n "$sshd_config" ]; then
mkdir -p -- "$directory/etc"
cp -- "$sshd_config" "$directory/etc/sshd_config"
fi
if $sshd_keygen; then
mkdir -p -- "$directory/etc"
for keytype in rsa ecdsa ed25519; do
if [ ! -e "$directory/etc/ssh_host_${keytype}_key" ]; then
ssh-keygen -t $keytype -f "$directory/etc/ssh_host_${keytype}_key" -N "" \
-C "root@$hostname"
fi
done
for keytype in rsa ecdsa ed25519; do
ssh-keygen -l -f "$directory/etc/ssh_host_${keytype}_key"
done
fi
if [ -n "$sshd_key_known_hosts_file" ]; then
known_hosts_tmp=$(mktemp)
for host in $sshd_key_known_hosts_hosts; do
for keytype in rsa ecdsa ed25519; do
if [ ! -e "$directory/etc/ssh_host_${keytype}_key.pub" ]; then
continue
fi
(printf '%s ' "$host" &&
sed -E 's/^([^ ]* [^ ]*).*/\1/' \
"$directory/etc/ssh_host_${keytype}_key.pub") \
>> "$known_hosts_tmp"
done
done
# TODO: ssh-keygen needs a standalone way to make such a hash.
ssh-keygen -H -f "$known_hosts_tmp" 1>/dev/null 2>/dev/null
cat -- "$known_hosts_tmp" >> "$sshd_key_known_hosts_file"
rm -f "$known_hosts_tmp"
rm -f "$known_hosts_tmp.old"
fi
if [ -n "$root_ssh_authorized_keys" ]; then
mkdir -p -- "$directory/root"
mkdir -p -m 700 -- "$directory/root/.ssh"
cp -- "$root_ssh_authorized_keys" "$directory/root/.ssh/authorized_keys"
fi
if [ -n "$root_ssh_config" ]; then
mkdir -p -- "$directory/root"
mkdir -p -m 700 -- "$directory/root/.ssh"
cp -- "$root_ssh_config" "$directory/root/.ssh/config"
fi
if [ -n "$root_ssh_known_hosts" ]; then
mkdir -p -- "$directory/root"
mkdir -p -m 700 -- "$directory/root/.ssh"
cp -- "$root_ssh_known_hosts" "$directory/root/.ssh/known_hosts"
fi
if $root_ssh_keygen; then
mkdir -p -- "$directory/root"
mkdir -p -m 700 -- "$directory/root/.ssh"
if [ ! -e "$directory/root/.ssh/id_rsa"]; then
ssh-keygen -t rsa -f "$directory/root/.ssh/id_rsa" -N "" -C "root@$hostname"
fi
fi

View File

@ -9,6 +9,15 @@
.Op Fl \-daemons Ns = Ns Ar daemons
.Op Fl \-hostname Ns = Ns Ar hostname
.Op Fl \-kblayout Ns = Ns Ar kblayout
.Op Fl \-root-ssh-authorized-keys Ns = Ns Ar file
.Op Fl \-root-ssh-config Ns = Ns Ar file
.Op Fl \-root-ssh-keygen
.Op Fl \-root-ssh-known-hosts Ns = Ns Ar file
.Op Fl \-ssh-config Ns = Ns Ar file
.Op Fl \-sshd-config Ns = Ns Ar file
.Op Fl \-sshd-keygen
.Op Fl \-sshd-key-known-hosts-file Ns = Ns Ar file
.Op Fl \-sshd-key-known-hosts-hosts Ns = Ns Ar host-list
.Op Fl \-videomode Ns = Ns Ar videomode
.Ar output-directory
.Sh DESCRIPTION
@ -67,6 +76,151 @@ to
.Pa output-directory/etc/kblayout .
(See
.Xr kblayout 5 )
.It Fl \-root-ssh-authorized-keys Ns = Ns Ar file
Copy
.Ar file
to
.Pa output-directory/root/.ssh/authorized_keys
so it becomes root's list of authorized ssh keys.
.It Fl \-root-ssh-config Ns = Ns Ar file
Copy
.Ar file
to
.Pa output-directory/root/.ssh/config
so it becomes root's
.Xr ssh_config 5 .
.It Fl \-root-ssh-keygen
Generate a ssh private and public key pair for rsa (see the warnings below) at
.Pa output-directory/root/.ssh/id_rsa
and
.Pa output-directory/root/.ssh/id_rsa.pub .
These keys are not regenerated if they already exist.
The comment in the key uses the
.Fl \-hostname
option if set, otherwise it defaults to
.Sy sortix .
The key is not password protected.
.Pp
The key is generated by running:
.Bd -literal
ssh-keygen \\
-t rsa \\
-f "$output_directory/root/.ssh/id_rsa" \\
-N "" \\
-C "root@$hostname"
.Ed
.Pp
Warning: The information in the generated
.Pa output-directory/root/.ssh/id_rsa
private key must be kept confidential and should be securely erased whereever it
goes whenever it is no longer useful in a particular place, otherwise
unauthorized may be able to impersonate this user.
These keys should be reissued whenever a root user of a new installation should
be considered distinct from other installations using the same keys.
The installer will offer to copy the keys to the newly installed system.
Once the
.Ar output-directory
is no longer useful, the
.Pa output-directory/root/.ssh/id_rsa
file inside it should be securely erased.
If a bootconfig has been made whose liveconfig contains thes private key,
.Pa bootconfig/boot/liveconfig.xz
should be securely erased when no longer useful.
If a release .iso has been made from
.Ar output-directory ,
it should be securely erased when no longer useful.
If a release .iso has been burned to a physical media, it should be securely
erased when no longer useful.
.It Fl \-root-ssh-known-hosts Ns = Ns Ar file
Copy
.Ar file
to
.Pa output-directory/root/.ssh/known_hosts
so it becomes root's list of known ssh hosts and their public keys.
.It Fl \-ssh-config Ns = Ns Ar file
Copy
.Ar file
to
.Pa output-directory/etc/ssh_config
so it becomes the
.Xr ssh_config 5
of the live environment.
.It Fl \-sshd-config Ns = Ns Ar file
Copy
.Ar file
to
.Pa output-directory/etc/sshd_config
so it becomes the
.Xr sshd_config 5
of the live environment.
.It Fl \-sshd-keygen
Generate sshd private keys for rsa, ecdsa, and ed25519 (see the below
warnings), but don't overwrite any existing keys in the
.Ar output-directory
directory.
The comment in the key uses the
.Fl \-hostname
option if set, otherwise it defaults to
.Sy sortix .
Each key is generated by running:
.Bd -literal
ssh-keygen \\
-t $keytype \\
-f "$output_directory/etc/ssh_host_${keytype}_key" \\
-N "" \\
-C "root@$hostname"
.Ed
.Pp
The fingerprints of each key is printed afterwards by running:
.Bd -literal
.Li ssh-keygen -l -f "$output_directory/etc/ssh_host_${keytype}_key"
.Ed
.Pp
Warning: The information in the generated
.Pa output_directory/etc/ssh_host_*_key
files must be kept confidential and should be securely erased whereever it goes
whenever it is no longer useful in a particular place, otherwise unauthorized
people may be able to impersonate the ssh server.
These keys should not be recycled to image more than a single system.
The installer will offer to copy the keys to the newly installed system.
Once the
.Ar output-directory
is no longer useful, the
.Pa output_directory/etc/ssh_host_*_key
files inside it should be securely erased.
If a bootconfig has been made whose liveconfig contains these keys,
.Pa bootconfig/boot/liveconfig.xz
should be securely erased when no longer useful.
If a release .iso has been made from
.Ar output-directory ,
it should be securely erased when no longer useful.
If a release .iso has been burned to a physical media, it should be securely
erased when no longer useful.
.It Fl \-sshd-key-known-hosts-file Ns = Ns Ar file
Append the ssh known_hosts entries to
.Ar file
for the
.Pa output_directory/etc/ssh_host_*_key.pub
.Xr sshd 8
keys for each hostname provided in the
.Fl \-sshd-key-known-hosts-hosts
option.
For each hostname, for each public key, a line is written to the
.Ar file
consisting of the hostname followed by a space and then followed by the public
key.
The written entries are then hashed so an attacker can't discover the hosts from
the known_hosts file, which is done by running
.Xr ssh-keygen 1
with the
.Fl H
option on the produced file.
.It Fl \-sshd-key-known-hosts-hosts Ns = Ns Ar host-list
A space delimited list of hostnames, network addresses, and hostnames followed
by a comma and then the network address, which the sshd server will be
connectible by, used to generate the known_hosts entries in the
.Fl \-sshd-key-known-hosts-file
option.
.It Fl \-videomode Ns = Ns Ar videomode
Set the live environment's graphics resolution by writing
.Ar videomode
@ -92,11 +246,55 @@ tix-iso-liveconfig \\
tix-iso-bootconfig --liveconfig=liveconfig bootconfig
tix-iso-add sortix.iso bootconfig
.Ed
.Ss SSH Into Live Environment
To customize the live environment of a release so you can ssh into its root
user, to have the hostname
.Sy example.com ,
to start a ssh server with the keys generated now, authorize the local user to
ssh into the live environment's root user, and register the sshd server's keys
by their hostnames and network addresses so the connection is trusted on the
first attempt (you can omit the network addresses if you don't know yet):
.Bd -literal
tix-iso-liveconfig \\
--hostname=example.com \\
--root-ssh-authorized-keys="$HOME/.ssh/id_rsa.pub" \\
--sshd-keygen \\
--sshd-key-known-hosts-file="$HOME/.ssh/known_hosts" \\
--sshd-key-known-hosts-hosts="example.com example.com,192.0.2.1 192.0.2.1" \\
liveconfig
tix-iso-bootconfig --liveconfig=liveconfig --enable-sshd bootconfig
tix-iso-add sortix.iso bootconfig
rm -f liveconfig/etc/ssh_host_*_key # When no longer useful.
rm -f bootconfig/boot/liveconfig.xz # When no longer useful.
rm -f sortix.iso # When no longer useful.
# And erase any media made from sortix.iso when no longer useful.
ssh root@example.org # When the system is running.
.Ed
.Ss SSH Back From Live Environment
To customize the live environment of a release so its root user can ssh back to
your user, where the local hostname is
.Sy example.com
(the address to which the new installation will be connecting):
.Bd -literal
tix-iso-liveconfig --root-ssh-keygen liveconfig
ssh-keyscan -H example.com > liveconfig/root/.ssh/known_hosts
cat liveconfig/root/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
tix-iso-bootconfig --liveconfig=liveconfig --enable-sshd bootconfig
tix-iso-add sortix.iso bootconfig
rm -f output-directory/root/.ssh/id_rsa # When no longer useful.
rm -f bootconfig/boot/liveconfig.xz # When no longer useful.
rm -f sortix.iso # When no longer useful.
# And erase any media made from sortix.iso when no longer useful.
.Ed
.Sh SEE ALSO
.Xr ssh-keygen 1 ,
.Xr xorriso 1 ,
.Xr hostname 5 ,
.Xr kblayout 5 ,
.Xr ssh_config 5 ,
.Xr sshd_config 5 ,
.Xr videomode 5 ,
.Xr release-iso-modification 7 ,
.Xr sshd 8 ,
.Xr tix-iso-add 8 ,
.Xr tix-iso-bootconfig 8