whonix: Added protected-files file used to prevent scripts from modifying files that need to be protected

A file is created in /var/lib/qubes/protected-files.  Scripts can grep this file before modifying
        known files to be protected and skip any modifications if the file path is within protected-files.

        Usage Example:
            if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then

        Also cleaned up maintainer scripts removing unneeded systemd status functions and streamlined
        the enable/disable systemd unit files functions
This commit is contained in:
Jason Mehring 2015-04-22 02:04:10 -04:00 committed by Marek Marczykowski-Górecki
parent 0c0cb5f6b2
commit 56b0685aaa
5 changed files with 132 additions and 126 deletions

View File

@ -105,80 +105,47 @@ showIn() {
fi fi
} }
setArrayAsGlobal() { changeSystemdStatus() {
local array="$1"
local export_as="$2"
local code=$(declare -p "$array")
local replaced="${code/$array/$export_as}"
eval ${replaced/declare -/declare -g}
}
systemdInfo() {
unit=${1} unit=${1}
return_global_var=${2} disable=${2-0}
# Check if unit file is currently active (running)
systemctl is-active ${unit} > /dev/null 2>&1 && active=true || unset active
declare -A INFO=() case ${disable} in
while read line; do 0)
INFO[${line%%=*}]="${line##*=}" systemctl --quiet enable ${unit} > /dev/null 2>&1 || true
done < <(systemctl show ${unit} 2> /dev/null) ;;
1)
if [ $active ]; then
systemctl --quiet stop ${unit} > /dev/null 2>&1 || true
fi
setArrayAsGlobal INFO $return_global_var if [ -f /lib/systemd/system/${unit} ]; then
return ${#INFO[@]} if fgrep -q '[Install]' /lib/systemd/system/${unit}; then
} systemctl --quiet disable ${unit} > /dev/null 2>&1 || true
else
displayFailedStatus() { # Forcibly disable
action=${1} ln -sf /dev/null /etc/systemd/system/${unit}
unit=${2} fi
# Only display if there are results. In chroot environmnet there will be
# no results to 'systemctl show' command
systemdInfo ${unit} info || {
echo
echo "==================================================="
echo "FAILED: systemd ${action} ${unit}"
echo "==================================================="
echo " LoadState = ${info[LoadState]}"
echo " LoadError = ${info[LoadError]}"
echo " ActiveState = ${info[ActiveState]}"
echo " SubState = ${info[SubState]}"
echo "UnitFileState = ${info[UnitFileState]}"
echo
}
}
# Disable systemd units
disableSystemdUnits() {
for unit in $*; do
echo "Disabling ${unit}..."
systemctl is-active ${unit} > /dev/null 2>&1 && {
systemctl stop ${unit} > /dev/null 2>&1 || displayFailedStatus stop ${unit}
}
if [ -f /lib/systemd/system/${unit} ]; then
if fgrep -q '[Install]' /lib/systemd/system/${unit}; then
systemctl disable ${unit} > /dev/null 2>&1 || displayFailedStatus disable ${unit}
else else
echo "Masking service: ${unit}" systemctl --quiet disable ${unit} > /dev/null 2>&1 || true
systemctl mask ${unit}
fi fi
else ;;
systemctl disable ${unit} > /dev/null 2>&1 || displayFailedStatus disable ${unit} esac
fi
done
} }
# Enable systemd units # Enable systemd units
enableSystemdUnits() { enableSystemdUnits() {
for unit in $*; do for unit in $*; do
systemctl is-enabled ${unit} > /dev/null 2>&1 && { changeSystemdStatus ${unit} 0 || true
echo "It appears ${unit} is already enabled!" done
#displayFailedStatus is-enabled ${unit} }
} || {
echo "Enabling: ${unit}..." # Disable systemd units
systemctl enable ${unit} > /dev/null 2>&1 || { disableSystemdUnits() {
echo "Could not enable: ${unit}" for unit in $*; do
displayFailedStatus enable ${unit} changeSystemdStatus ${unit} 1 || true
}
}
done done
} }
@ -204,6 +171,9 @@ case "${1}" in
dpkg-divert --divert /etc/init/${init}.conf.qubes-disabled --package qubes-core-agent --rename --add /etc/init/${init}.conf dpkg-divert --divert /etc/init/${init}.conf.qubes-disabled --package qubes-core-agent --rename --add /etc/init/${init}.conf
done done
# Disable sysv init network-manager
disableSystemdUnits network-manager
# Create NetworkManager configuration if we do not have it # Create NetworkManager configuration if we do not have it
if ! [ -e /etc/NetworkManager/NetworkManager.conf ]; then if ! [ -e /etc/NetworkManager/NetworkManager.conf ]; then
echo '[main]' > /etc/NetworkManager/NetworkManager.conf echo '[main]' > /etc/NetworkManager/NetworkManager.conf
@ -217,19 +187,27 @@ case "${1}" in
rm -f /lib/firmware/updates rm -f /lib/firmware/updates
fi fi
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
# ensure that hostname resolves to 127.0.1.1 resp. ::1 and that /etc/hosts is # ensure that hostname resolves to 127.0.1.1 resp. ::1 and that /etc/hosts is
# in the form expected by qubes-sysinit.sh # in the form expected by qubes-sysinit.sh
for ip in '127\.0\.1\.1' '::1'; do if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then for ip in '127\.0\.1\.1' '::1'; do
sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts || true
else sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts || true
echo "${ip//\\/} `hostname`" >> /etc/hosts else
fi echo "${ip//\\/} `hostname`" >> /etc/hosts || true
done fi
done
fi
# remove hostname from 127.0.0.1 line (in debian the hostname is by default # remove hostname from 127.0.0.1 line (in debian the hostname is by default
# resolved to 127.0.1.1) # resolved to 127.0.1.1)
sed -i "/^127\.0\.0\.1\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts if ! grep -q "^/etc/hosts$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
sed -i "/^127\.0\.0\.1\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts || true
fi
chown user:user /home_volatile/user chown user:user /home_volatile/user
@ -286,7 +264,7 @@ case "${1}" in
rngd smartd.service \ rngd smartd.service \
upower.service \ upower.service \
irqbalance.service \ irqbalance.service \
colord.service colord.service
rm -f /etc/systemd/system/getty.target.wants/getty@tty*.service rm -f /etc/systemd/system/getty.target.wants/getty@tty*.service

View File

@ -6,6 +6,9 @@
disablegw=`qubesdb-read /qubes-service/disable-default-route 2> /dev/null` disablegw=`qubesdb-read /qubes-service/disable-default-route 2> /dev/null`
disabledns=`qubesdb-read /qubes-service/disable-dns-server 2> /dev/null` disabledns=`qubesdb-read /qubes-service/disable-dns-server 2> /dev/null`
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
ip=`/usr/bin/qubesdb-read /qubes-ip 2> /dev/null` ip=`/usr/bin/qubesdb-read /qubes-ip 2> /dev/null`
if [ x$ip != x ]; then if [ x$ip != x ]; then
netmask=`/usr/bin/qubesdb-read /qubes-netmask` netmask=`/usr/bin/qubesdb-read /qubes-netmask`
@ -19,10 +22,12 @@ if [ x$ip != x ]; then
fi fi
/sbin/ethtool -K $INTERFACE sg off /sbin/ethtool -K $INTERFACE sg off
/sbin/ethtool -K $INTERFACE tx off /sbin/ethtool -K $INTERFACE tx off
echo > /etc/resolv.conf if ! grep -q "^/etc/resolv[.]conf$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if [ "x$disabledns" != "x1" ]; then echo > /etc/resolv.conf
echo "nameserver $gateway" > /etc/resolv.conf if [ "x$disabledns" != "x1" ]; then
echo "nameserver $secondary_dns" >> /etc/resolv.conf echo "nameserver $gateway" > /etc/resolv.conf
echo "nameserver $secondary_dns" >> /etc/resolv.conf
fi
fi fi
if [ -f /var/run/qubes-service/network-manager ]; then if [ -f /var/run/qubes-service/network-manager ]; then
nm_config=/etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE nm_config=/etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE

View File

@ -239,24 +239,31 @@ fi
# Revert 'Prevent unnecessary updates in VMs': # Revert 'Prevent unnecessary updates in VMs':
sed -i -e '/^exclude = kernel/d' /etc/yum.conf sed -i -e '/^exclude = kernel/d' /etc/yum.conf
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
# qubes-core-vm has been broken for some time - it overrides /etc/hosts; restore original content # qubes-core-vm has been broken for some time - it overrides /etc/hosts; restore original content
if ! grep -q localhost /etc/hosts; then if ! grep -q "^/etc/hosts$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
cat <<EOF > /etc/hosts if ! grep -q localhost /etc/hosts; then
cat <<EOF > /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 `hostname` 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 `hostname`
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
EOF EOF
fi
fi fi
# ensure that hostname resolves to 127.0.0.1 resp. ::1 and that /etc/hosts is # ensure that hostname resolves to 127.0.0.1 resp. ::1 and that /etc/hosts is
# in the form expected by qubes-sysinit.sh # in the form expected by qubes-sysinit.sh
for ip in '127\.0\.0\.1' '::1'; do if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then for ip in '127\.0\.0\.1' '::1'; do
sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts sed -i "/^${ip}\s/,+0s/\(\s`hostname`\)\+\(\s\|$\)/\2/g" /etc/hosts
else sed -i "s/^${ip}\(\s\|$\).*$/\0 `hostname`/" /etc/hosts
echo "${ip} `hostname`" >> /etc/hosts else
fi echo "${ip} `hostname`" >> /etc/hosts
done fi
done
fi
# Copy ip(|6)tables into place if they do not already exist in filesystem. # Copy ip(|6)tables into place if they do not already exist in filesystem.
# This prevents conflict with iptables-service # This prevents conflict with iptables-service

View File

@ -16,25 +16,37 @@ start()
chmod 666 /proc/u2mfn chmod 666 /proc/u2mfn
mkdir -p /var/run/xen-hotplug mkdir -p /var/run/xen-hotplug
mkdir -p /var/run/qubes
chgrp qubes /var/run/qubes
chmod 0775 /var/run/qubes
name=$(/usr/bin/qubesdb-read /name) # Location of files which contains list of protected files
if ! [ -f /etc/this-is-dvm ] ; then PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
# we don't want to set hostname for DispVM
# because it makes some of the pre-created dotfiles invalid (e.g. .kde/cache-<hostname>) # Set the hostname
# (let's be frank: nobody's gonna use xterm on DispVM) if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
hostname $name name=$(/usr/bin/qubesdb-read /name)
sed -i "s/^\(127\.0\.0\.1[\t ].*\) \($name \)\?\(.*\)/\1\2 $name/" /etc/hosts if ! [ -f /etc/this-is-dvm ] ; then
# we don't want to set hostname for DispVM
# because it makes some of the pre-created dotfiles invalid (e.g. .kde/cache-<hostname>)
# (let's be frank: nobody's gonna use xterm on DispVM)
hostname $name
sed -i "s/^\(127\.0\.0\.1[\t ].*\) \($name \)\?\(.*\)/\1\2 $name/" /etc/hosts
fi
fi fi
timezone=`/usr/bin/qubesdb-read /qubes-timezone 2> /dev/null` # Set the timezone
if [ -n "$timezone" ]; then if ! grep -q "^/etc/timezone$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
ln -f /usr/share/zoneinfo/$timezone /etc/localtime timezone=`/usr/bin/qubesdb-read /qubes-timezone 2> /dev/null`
echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock if [ -n "$timezone" ]; then
echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock ln -f /usr/share/zoneinfo/$timezone /etc/localtime
echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
fi
fi fi
yum_proxy_setup=$(/usr/bin/qubesdb-read /qubes-service/yum-proxy-setup 2> /dev/null || /usr/bin/qubesdb-read /qubes-service/updates-proxy-setup 2> /dev/null) yum_proxy_setup=$(/usr/bin/qubesdb-read /qubes-service/yum-proxy-setup 2> /dev/null || /usr/bin/qubesdb-read /qubes-service/updates-proxy-setup 2> /dev/null)
type=$(/usr/bin/qubesdb-read /qubes-vm-type) type=$(/usr/bin/qubesdb-read /qubes-vm-type)
if [ "$yum_proxy_setup" != "0" ] || [ -z "$yum_proxy_setup" -a "$type" == "TemplateVM" ]; then if [ "$yum_proxy_setup" != "0" ] || [ -z "$yum_proxy_setup" -a "$type" == "TemplateVM" ]; then
echo proxy=http://10.137.255.254:8082/ > /etc/yum.conf.d/qubes-proxy.conf echo proxy=http://10.137.255.254:8082/ > /etc/yum.conf.d/qubes-proxy.conf
else else
@ -47,10 +59,6 @@ start()
# qubesdb-read fails # qubesdb-read fails
INTERFACE=eth0 /usr/lib/qubes/setup-ip INTERFACE=eth0 /usr/lib/qubes/setup-ip
mkdir -p /var/run/qubes
chgrp qubes /var/run/qubes
chmod 0775 /var/run/qubes
if [ -e /dev/xvdb ] ; then if [ -e /dev/xvdb ] ; then
# check if private.img (xvdb) is empty - all zeros # check if private.img (xvdb) is empty - all zeros
private_size_512=`blockdev --getsz /dev/xvdb` private_size_512=`blockdev --getsz /dev/xvdb`
@ -64,11 +72,11 @@ start()
resize2fs /dev/xvdb 2> /dev/null || echo "'resize2fs /dev/xvdb' failed" resize2fs /dev/xvdb 2> /dev/null || echo "'resize2fs /dev/xvdb' failed"
if ! [ -d /rw/home ] ; then if ! [ -d /rw/home ] ; then
echo echo
echo "--> Virgin boot of the VM: Linking /home to /rw/home" echo "--> Virgin boot of the VM: Linking /home to /rw/home"
mkdir -p /rw/config mkdir -p /rw/config
cat > /rw/config/rc.local <<EOF cat > /rw/config/rc.local <<EOF
#!/bin/sh #!/bin/sh
# This script will be executed at every VM startup, you can place your own # This script will be executed at every VM startup, you can place your own

View File

@ -10,6 +10,9 @@ DEFAULT_ENABLED="meminfo-writer"
QDB_READ=qubesdb-read QDB_READ=qubesdb-read
QDB_LS=qubesdb-multiread QDB_LS=qubesdb-multiread
# Location of files which contains list of protected files
PROTECTED_FILE_LIST='/var/lib/qubes/protected-files'
read_service() { read_service() {
$QDB_READ /qubes-service/$1 2> /dev/null $QDB_READ /qubes-service/$1 2> /dev/null
} }
@ -67,26 +70,31 @@ for srv in `$QDB_LS /qubes-service/ 2>/dev/null |grep ' = 0'|cut -f 1 -d ' '`; d
done done
# Set the hostname # Set the hostname
name=`$QDB_READ /name` if ! grep -q "^/etc/hostname$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
if [ -n "$name" ]; then name=`$QDB_READ /name`
hostname $name if [ -n "$name" ]; then
if [ -e /etc/debian_version ]; then hostname $name
ipv4_localhost_re="127\.0\.1\.1" if [ -e /etc/debian_version ]; then
else ipv4_localhost_re="127\.0\.1\.1"
ipv4_localhost_re="127\.0\.0\.1" else
ipv4_localhost_re="127\.0\.0\.1"
fi
sed -i "s/^\($ipv4_localhost_re\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
sed -i "s/^\(::1\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
fi fi
sed -i "s/^\($ipv4_localhost_re\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
sed -i "s/^\(::1\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
fi fi
timezone=`$QDB_READ /qubes-timezone 2> /dev/null` # Set the timezone
if [ -n "$timezone" ]; then if ! grep -q "^/etc/timezone$" "${PROTECTED_FILE_LIST}" 2>/dev/null; then
cp -p /usr/share/zoneinfo/$timezone /etc/localtime timezone=`$QDB_READ /qubes-timezone 2> /dev/null`
if [ -e /etc/debian_version ]; then if [ -n "$timezone" ]; then
echo "$timezone" > /etc/timezone cp -p /usr/share/zoneinfo/$timezone /etc/localtime
else if [ -e /etc/debian_version ]; then
echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock echo "$timezone" > /etc/timezone
echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock else
echo "# Clock configuration autogenerated based on Qubes dom0 settings" > /etc/sysconfig/clock
echo "ZONE=\"$timezone\"" >> /etc/sysconfig/clock
fi
fi fi
fi fi