Make /etc/shadow writable

In order for users to be able to log in locally or via SSH without an
authorized key, they will need to have passwords set in `/etc/shadow`.
We do not really want to make all of `/etc` writable, so we will store
the actual `shadow` file on the persistent data volume, in a separate
Btrfs subvolume, and then bind-mount it at `/etc/shadow`.

While this makes `/etc/shadow` mutable, it does not actually let the
`passwd` program modify it.  This is because `passwd` creates lock files
and backup files in `/etc`.  We will ultimately need a wrapper to
"trick" `passwd` into modifying `/etc/shadow`, without making the whole
`/etc` directory mutable.
master
Dustin 2023-03-15 11:12:26 -05:00
parent c259aad165
commit eb8f4c3b40
2 changed files with 24 additions and 0 deletions

View File

@ -28,6 +28,8 @@ format_dev() {
mount "${dev}" "${tmpdir}" || exit mount "${dev}" "${tmpdir}" || exit
btrfs subvolume create "${tmpdir}"/var || exit btrfs subvolume create "${tmpdir}"/var || exit
chcon -t var_t "${tmpdir}"/var || exit chcon -t var_t "${tmpdir}"/var || exit
btrfs subvolume create "${tmpdir}"/etc || exit
chcon -t etc_t "${tmpdir}"/etc || exit
umount "${dev}" || exit umount "${dev}" || exit
} }
@ -37,6 +39,18 @@ has_fs() {
[ -n "${fstype}" ] [ -n "${fstype}" ]
} }
setup_etc() {
dev="$1"
echo 'Initializing writable paths in /etc'
mount -o subvol=etc "${dev}" "${tmpdir}" || exit
if [ ! -f "${tmpdir}"/shadow ]; then
cp -ca /etc/shadow "${tmpdir}"/shadow || exit
fi
mount -o bind "${tmpdir}"/shadow /etc/shadow || exit
umount "${tmpdir}"
}
datapart=$(findfs PARTLABEL=dch-data) datapart=$(findfs PARTLABEL=dch-data)
if [ -b "${datapart}" ]; then if [ -b "${datapart}" ]; then
printf 'Found data partition: %s\n' "${datapart}" printf 'Found data partition: %s\n' "${datapart}"
@ -53,4 +67,5 @@ if ! has_fs "${datapart}"; then
format_dev "${datapart}" format_dev "${datapart}"
fi fi
setup_etc "${datapart}"
copy_var "${datapart}" copy_var "${datapart}"

View File

@ -61,6 +61,10 @@ seutil_read_file_contexts(aimee_storinit_t)
kernel_rw_unlabeled_dirs(aimee_storinit_t) kernel_rw_unlabeled_dirs(aimee_storinit_t)
kernel_relabelfrom_unlabeled_dirs(aimee_storinit_t) kernel_relabelfrom_unlabeled_dirs(aimee_storinit_t)
auth_manage_shadow(aimee_storinit_t)
auth_relabel_shadow(aimee_storinit_t)
files_manage_var_dirs(aimee_storinit_t) files_manage_var_dirs(aimee_storinit_t)
files_relabel_var_dirs(aimee_storinit_t) files_relabel_var_dirs(aimee_storinit_t)
files_manage_var_files(aimee_storinit_t) files_manage_var_files(aimee_storinit_t)
@ -74,6 +78,8 @@ gen_require(`
type init_var_lib_t; type init_var_lib_t;
type auditd_log_t; type auditd_log_t;
type tmp_t; type tmp_t;
type etc_t;
type shadow_t;
attribute logfile; attribute logfile;
') ')
manage_dirs_pattern(aimee_storinit_t, var_lib_t, var_lib_t) manage_dirs_pattern(aimee_storinit_t, var_lib_t, var_lib_t)
@ -124,6 +130,9 @@ manage_dirs_pattern(aimee_storinit_t, tmp_t, tmp_t)
relabel_dirs_pattern(aimee_storinit_t, tmp_t, tmp_t) relabel_dirs_pattern(aimee_storinit_t, tmp_t, tmp_t)
manage_files_pattern(aimee_storinit_t, tmp_t, tmp_t) manage_files_pattern(aimee_storinit_t, tmp_t, tmp_t)
relabel_files_pattern(aimee_storinit_t, tmp_t, tmp_t) relabel_files_pattern(aimee_storinit_t, tmp_t, tmp_t)
manage_dirs_pattern(aimee_storinit_t, etc_t, etc_t)
relabel_dirs_pattern(aimee_storinit_t, etc_t, etc_t)
allow aimee_storinit_t shadow_t:file mounton;
######################################## ########################################
# #