mirror of
https://github.com/Kicksecure/security-misc.git
synced 2024-10-01 08:25:45 -04:00
f0857fd560
Mounting var with bind and mounting a subdirectory causes /var/tmp and /var/log bind mounted twice each. can be checked with lsblk. When we bind mount var only after having mounted the subdirectories, everything is mounted only one.
301 lines
7.8 KiB
Bash
Executable File
301 lines
7.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
## Copyright (C) 2019 - 2023 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>
|
|
## See the file COPYING for copying conditions.
|
|
|
|
## noexec in /tmp and/or /home can break some malware but also legitimate
|
|
## applications.
|
|
|
|
## https://www.kicksecure.com/wiki/Dev/remount-secure
|
|
## https://forums.whonix.org/t/re-mount-home-and-other-with-noexec-and-nosuid-among-other-useful-mount-options-for-better-security/7707
|
|
|
|
#set -x
|
|
set -e
|
|
set -o pipefail
|
|
set -o nounset
|
|
|
|
init() {
|
|
if test -o xtrace ; then
|
|
output_command=true
|
|
else
|
|
output_command=echo
|
|
fi
|
|
|
|
$output_command "$0: INFO: START"
|
|
|
|
if [ "$(id -u)" != "0" ]; then
|
|
$output_command "ERROR: must be run as root! sudo $0"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir --parents "/run/remount-secure"
|
|
exit_code=0
|
|
|
|
## dracut sets NEWROOT=/sysroot
|
|
[[ -v NEWROOT ]] || NEWROOT=""
|
|
if [ "$NEWROOT" = "" ]; then
|
|
$output_command "INFO: dracut detected: no"
|
|
else
|
|
$output_command "INFO: dracut detected: yes - NEWROOT: '$NEWROOT'"
|
|
fi
|
|
|
|
## Debugging.
|
|
#echo "ls -la /root/"
|
|
#ls -la / || true
|
|
#echo "ls -la /sysroot/"
|
|
#ls -la /sysroot/ || true
|
|
#echo "env"
|
|
#env || true
|
|
}
|
|
|
|
parse_options() {
|
|
## Thanks to:
|
|
## http://mywiki.wooledge.org/BashFAQ/035
|
|
|
|
while :
|
|
do
|
|
case ${1:-} in
|
|
0)
|
|
$output_command "WARNING: Not using remount-secure."
|
|
exit 0
|
|
shift
|
|
;;
|
|
1)
|
|
$output_command "INFO: level 1/3 (low)"
|
|
most_noexec_maybe=""
|
|
home_noexec_maybe=""
|
|
parsed=true
|
|
shift
|
|
;;
|
|
2)
|
|
$output_command "INFO: level 2/3 (medium)"
|
|
most_noexec_maybe=",noexec"
|
|
home_noexec_maybe=""
|
|
parsed=true
|
|
shift
|
|
;;
|
|
3)
|
|
$output_command "INFO: level 3/3 (high)"
|
|
most_noexec_maybe=",noexec"
|
|
home_noexec_maybe=",noexec"
|
|
parsed=true
|
|
shift
|
|
;;
|
|
--force)
|
|
$output_command "INFO: --force"
|
|
option_force=true
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
-*)
|
|
echo "ERROR: unknown option: $1" >&2
|
|
exit 1
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[[ -v option_force ]] || option_force=""
|
|
[[ -v parsed ]] || parsed=false
|
|
[[ -v home_noexec_maybe ]] || home_noexec_maybe=""
|
|
[[ -v most_noexec_maybe ]] || most_noexec_maybe=""
|
|
|
|
$output_command "INFO: using nosuid,nodev: yes"
|
|
|
|
if [ "$home_noexec_maybe" = "" ]; then
|
|
$output_command "INFO: using noexec for all: no"
|
|
else
|
|
$output_command "INFO: using noexec for all: yes"
|
|
return 0
|
|
fi
|
|
|
|
if [ "$most_noexec_maybe" = "" ]; then
|
|
$output_command "INFO: using noexec for most: no"
|
|
else
|
|
$output_command "INFO: using noexec for most (not all): yes"
|
|
return 0
|
|
fi
|
|
|
|
if [ "$parsed" = "true" ]; then
|
|
return 0
|
|
fi
|
|
|
|
$output_command "ERROR: syntax error. use either:
|
|
$0 0
|
|
$0 1
|
|
$0 2
|
|
$0 3"
|
|
|
|
exit 1
|
|
}
|
|
|
|
preparation() {
|
|
## Debugging.
|
|
#$output_command "INFO: 'findmnt --list' output at the START."
|
|
#$output_command "$(findmnt --list)"
|
|
#$output_command ""
|
|
true
|
|
}
|
|
|
|
remount_secure() {
|
|
$output_command ""
|
|
|
|
## ${FUNCNAME[1]} is the name of the calling function. I.e. the function
|
|
## which called this function.
|
|
status_file_name="${FUNCNAME[1]}"
|
|
## example status_file_name:
|
|
## _home
|
|
status_file_full_path="/run/remount-secure/${status_file_name}"
|
|
## example status_file_full_path:
|
|
## /run/remount-secure/_home
|
|
|
|
old_mount_options="$(findmnt --noheadings --output options -- "$mount_folder")" || true
|
|
## example old_mount_options:
|
|
## rw,nosuid,nodev,relatime,discard
|
|
|
|
$output_command "INFO: '$mount_folder' old_mount_options: '$old_mount_options'"
|
|
|
|
if echo "$old_mount_options" | grep --quiet "$intended_mount_options" ; then
|
|
$output_command "INFO: '$mount_folder' has already intended mount options. ($intended_mount_options)"
|
|
return 0
|
|
fi
|
|
|
|
## When this package is upgraded, the systemd unit will run again.
|
|
## If the user meanwhile manually relaxed mount options, this should not be undone.
|
|
|
|
if [ ! "$option_force" == "true" ]; then
|
|
if [ -e "$status_file_full_path" ]; then
|
|
$output_command "INFO: '$mount_folder' already remounted earlier. Not remounting again. Use --force if this is what you want."
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
if ! test -d "$mount_folder" ; then
|
|
$output_command "INFO: '$mount_folder' folder exists: no"
|
|
exit_code=102
|
|
return 0
|
|
fi
|
|
$output_command "INFO: '$mount_folder' folder exists: yes"
|
|
|
|
if findmnt --noheadings "$mount_folder" >/dev/null ; then
|
|
$output_command "INFO: '$mount_folder' already mounted, therefore using remount."
|
|
$output_command INFO: Executing: mount --options "remount,${intended_mount_options}" "$mount_folder"
|
|
mount --options "remount,${intended_mount_options}" "$mount_folder" || exit_code=100
|
|
else
|
|
$output_command "INFO: '$mount_folder' not yet mounted, therefore using mount bind."
|
|
$output_command INFO: Executing: mount --options "$intended_mount_options" --bind "$mount_folder" "$mount_folder"
|
|
mount --options "$intended_mount_options" --bind "$mount_folder" "$mount_folder" || exit_code=101
|
|
fi
|
|
|
|
new_mount_options="$(findmnt --noheadings --output options -- "$mount_folder")" || true
|
|
$output_command "INFO: '$mount_folder' new_mount_options: $new_mount_options"
|
|
|
|
touch "$status_file_full_path"
|
|
}
|
|
|
|
_boot() {
|
|
mount_folder="$NEWROOT/boot"
|
|
## https://lists.freedesktop.org/archives/systemd-devel/2015-February/028456.html
|
|
intended_mount_options="nosuid,nodev,noexec"
|
|
remount_secure
|
|
}
|
|
|
|
_run() {
|
|
mount_folder="/run"
|
|
## https://lists.freedesktop.org/archives/systemd-devel/2015-February/028456.html
|
|
intended_mount_options="nosuid,nodev${most_noexec_maybe}"
|
|
remount_secure
|
|
}
|
|
|
|
_dev() {
|
|
mount_folder="/dev"
|
|
## /dev should be nosuid,noexec as per:
|
|
## https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1991975
|
|
intended_mount_options="nosuid,noexec"
|
|
remount_secure
|
|
}
|
|
|
|
_dev_shm() {
|
|
mount_folder="/dev/shm"
|
|
intended_mount_options="nosuid,nodev${most_noexec_maybe}"
|
|
remount_secure
|
|
}
|
|
|
|
_tmp() {
|
|
mount_folder="$NEWROOT/tmp"
|
|
intended_mount_options="nosuid,nodev${most_noexec_maybe}"
|
|
remount_secure
|
|
}
|
|
|
|
_var_tmp() {
|
|
mount_folder="$NEWROOT/var/tmp"
|
|
intended_mount_options="nosuid,nodev${most_noexec_maybe}"
|
|
remount_secure
|
|
}
|
|
|
|
_var_log() {
|
|
mount_folder="$NEWROOT/var/log"
|
|
intended_mount_options="nosuid,nodev,noexec"
|
|
remount_secure
|
|
}
|
|
|
|
_var() {
|
|
mount_folder="$NEWROOT/var"
|
|
## noexec: Not possible. Reason:
|
|
## Debian stores executable maintainer scripts in /var/lib/dpkg/info folder.
|
|
intended_mount_options="nosuid,nodev"
|
|
remount_secure
|
|
}
|
|
|
|
_lib() {
|
|
mount_folder="$NEWROOT/lib"
|
|
## Cannot use noexec on /lib as per:
|
|
## https://forums.whonix.org/t/re-mount-home-and-other-with-noexec-and-nosuid-among-other-useful-mount-options-for-better-security/7707/25
|
|
## There are many executables in /lib. To check:
|
|
## sudo find /var/lib -type f -executable
|
|
## sudo find /var/lib -type f -executable ! -type l
|
|
intended_mount_options="nosuid,nodev"
|
|
remount_secure
|
|
}
|
|
|
|
_home() {
|
|
mount_folder="$NEWROOT/home"
|
|
intended_mount_options="nosuid,nodev${home_noexec_maybe}"
|
|
remount_secure
|
|
}
|
|
|
|
end() {
|
|
## Debugging.
|
|
#$output_command "INFO: 'findmnt --list' output at the END."
|
|
#$output_command "$(findmnt --list)"
|
|
|
|
$output_command "INFO: exit_code: $exit_code"
|
|
$output_command "$0: INFO: END"
|
|
exit $exit_code
|
|
}
|
|
|
|
main() {
|
|
init
|
|
parse_options "$@"
|
|
preparation
|
|
|
|
_boot
|
|
_run
|
|
_dev
|
|
_dev_shm
|
|
_tmp
|
|
_var_tmp
|
|
_var_log
|
|
_var
|
|
_home
|
|
|
|
end
|
|
}
|
|
|
|
main "$@"
|