mirror of
https://github.com/tasket/Qubes-VM-hardening.git
synced 2024-10-01 06:35:42 -04:00
Merge branch 'systemd'
This commit is contained in:
commit
0990062511
20
README.md
20
README.md
@ -1,10 +1,26 @@
|
||||
# Qubes-VM-hardening
|
||||
Enhancing Qubes VM security and privacy
|
||||
|
||||
## rc.local: Protect sh, bash and GUI init files
|
||||
|
||||
### Pre-requisites:
|
||||
Enabling authentication for sudo (see link below for Qubes doc).
|
||||
|
||||
---
|
||||
|
||||
|
||||
## vm-sudo-protect.service
|
||||
* Protect /home script files
|
||||
* Remove /rw scripts at VM start
|
||||
|
||||
## Testing systemd version...
|
||||
Install the two files `vm-sudo-protect.sh` and `vm-sudo-protect.service` into template then use `systemctl` to enable the service.
|
||||
|
||||
Activate by specifying as a Qubes service for each VM; There are two levels...
|
||||
1. `vm-sudo-protect` - similar to the rc.local script. Protects scripts within /home and may be used with wide array of VMs including standalone, netVMs and Whonix.
|
||||
2. `vm-sudo-protect-root` - new feature which **erases** /rw/config, /rw/usrlocal and /rw/bind-dirs. Use with caution! This feature can also replace files on a global or per-VM basis... see script for details. Not recommended for standalone or VMs that rely on /rw root dirs such as netVMs or Whonix.
|
||||
|
||||
---
|
||||
|
||||
## rc.local (old version)
|
||||
|
||||
### Description:
|
||||
Placed in /etc/rc.local (or equivalent) of a template VM, this makes the shell init files immutable so PATH and alias cannot be used to hijack commands like su and sudo, nor can impostor apps autostart whenever a VM starts. I combed the dash and bash docs -- as well as Gnome, KDE, Xfce and X11 docs -- to address all the user-writable startup files that apply. Feel free to comment or create an issue if you see an omission or other problem.
|
||||
|
19
lib/systemd/system/vm-sudo-protect.service
Normal file
19
lib/systemd/system/vm-sudo-protect.service
Normal file
@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=Script protections to enhance VM security
|
||||
After=qubes-sysinit.service
|
||||
Before=qubes-mount-dirs.service
|
||||
ConditionPathExists=|/var/run/qubes-service/vm-sudo-protect
|
||||
ConditionPathExists=|/var/run/qubes-service/vm-sudo-protect-root
|
||||
ConditionPathExists=|/var/run/qubes-service/vm-sudo-protect-cli
|
||||
DefaultDependencies=false
|
||||
OnFailure=shutdown.target
|
||||
OnFailureJobMode=replace-irreversibly
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=no
|
||||
#Environment="privdirs=/rw/config /rw/usrlocal /rw/bind-dirs"
|
||||
ExecStart=/usr/lib/qubes/init/vm-sudo-protect.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=sysinit.target
|
20
rc.local
20
rc.local
@ -1,20 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
# Debian: /etc/rc.local
|
||||
|
||||
#########################################################
|
||||
## Protect sh, bash, X and desktop init scripts ##
|
||||
## to prevent privilege escalation attacks ##
|
||||
## and malware persistence - for Qubes Linux templates ##
|
||||
chfiles=".bashrc .bash_profile .bash_login .bash_logout .profile \
|
||||
.xprofile .xinitrc .xserverrc .xsession"
|
||||
chdirs="bin .config/autostart .config/plasma-workspace/env \
|
||||
.config/plasma-workspace/shutdown .config/autostart-scripts"
|
||||
|
||||
cd /home/user
|
||||
mkdir -p $chdirs ||true
|
||||
touch $chfiles || true
|
||||
chattr -R -f +i $chfiles $chdirs || true
|
||||
#touch /home/user/FIXED || true
|
||||
|
||||
# end of script
|
||||
exit 0
|
129
usr/lib/qubes/init/vm-sudo-protect.sh
Normal file
129
usr/lib/qubes/init/vm-sudo-protect.sh
Normal file
@ -0,0 +1,129 @@
|
||||
#!/bin/sh
|
||||
|
||||
## Protect startup of Qubes VMs from /rw scripts ##
|
||||
## https://github.com/tasket/Qubes-VM-hardening ##
|
||||
|
||||
|
||||
# Source Qubes library.
|
||||
. /usr/lib/qubes/init/functions
|
||||
|
||||
# Define sh, bash, X and desktop init scripts in /home/user
|
||||
# to be protected
|
||||
chfiles=".bashrc .bash_profile .bash_login .bash_logout .profile \
|
||||
.xprofile .xinitrc .xserverrc .xsession"
|
||||
chdirs="bin .config/autostart .config/plasma-workspace/env \
|
||||
.config/plasma-workspace/shutdown .config/autostart-scripts"
|
||||
vmname=`qubesdb-read /name`
|
||||
rw=/mnt/rwtmp
|
||||
|
||||
# Function: Make user scripts immutable.
|
||||
make_immutable() {
|
||||
#initialize_home $rw/home ifneeded
|
||||
cd $rw/home/user
|
||||
mkdir -p $chdirs
|
||||
touch $chfiles
|
||||
chattr -R -f +i $chfiles $chdirs
|
||||
cd /root
|
||||
touch $rw/home/user/FIXED #debug
|
||||
}
|
||||
|
||||
# Mount private volume in temp location
|
||||
mkdir -p $rw
|
||||
if [ -e /dev/xvdb ] && mount /dev/xvdb $rw ; then
|
||||
echo Good rw mount.
|
||||
else
|
||||
echo Mount failed!
|
||||
xterm -hold -display :0 -title "VM PROTECTION: MOUNT FAILED!" \
|
||||
-e "bash -i"
|
||||
exit 1
|
||||
fi
|
||||
if qsvc vm-sudo-protect-cli; then
|
||||
xterm -hold -display :0 -title "VM PROTECTION: SERVICE PROMPT" \
|
||||
-e "echo Private volume is mounted at $rw; bash -i"
|
||||
fi
|
||||
|
||||
|
||||
# Protection measures for /rw dirs:
|
||||
# Activated by presence of vm-sudo-protect-root Qubes service.
|
||||
# * Hashes in vms/vms.all.SHA and vms/$vmname.SHA files will be checked.
|
||||
# * Remove /rw root startup files (config, usrlocal, bind-dirs).
|
||||
# * Contents of vms/vms.all and vms/$vmname folders will be copied.
|
||||
defdir="/etc/default/vms"
|
||||
privdirs=${privdirs:-"$rw/config $rw/usrlocal $rw/bind-dirs"}
|
||||
|
||||
if qsvc vm-sudo-protect-root && is_rwonly_persistent; then
|
||||
|
||||
# Check hashes
|
||||
checkcode=0
|
||||
echo "File hash checks:" >/tmp/vm-protect-sum-error
|
||||
for vmset in vms.all $vmname; do
|
||||
if [ -f $defdir/$vmset.SHA ]; then
|
||||
sha256sum --strict -c $defdir/$vmset.SHA >>/tmp/vm-protect-sum-error 2>&1
|
||||
checkcode=$((checkcode+$?))
|
||||
fi
|
||||
done
|
||||
cat /tmp/vm-protect-sum-error # For logging
|
||||
|
||||
# Stop system startup on checksum mismatch:
|
||||
if [ $checkcode != 0 ]; then
|
||||
xterm -hold -display :0 -title "VM PROTECTION: CHECKSUM MISMATCH!" \
|
||||
-e "cat /tmp/vm-protect-sum-error; echo Private volume is mounted at $rw; bash -i"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Files mutable for del/copy operations
|
||||
cd $rw/home/user
|
||||
chattr -R -f -i $chfiles $chdirs $privdirs
|
||||
cd /root
|
||||
|
||||
# Deactivate private.img config dirs
|
||||
for dir in $privdirs; do
|
||||
bakdir=`dirname $dir`/BAK-`basename $dir`
|
||||
bak2dir=`dirname $dir`/BAK2-`basename $dir`
|
||||
if [ -d $bakdir ] && [ ! -d $bak2dir ]; then
|
||||
mv $bakdir $bak2dir
|
||||
fi
|
||||
rm -rf $bakdir
|
||||
mv $dir $bakdir
|
||||
done
|
||||
mkdir -p $privdirs
|
||||
|
||||
for vmset in vms.all $vmname; do
|
||||
|
||||
# Process whitelists...
|
||||
cat $defdir/$vmset.whitelist \
|
||||
| while read wlfile; do
|
||||
# Must begin with '/rw/'
|
||||
if echo $wlfile |grep -q "^\/rw\/"; then #Was [ $wlfile =~ ^\/rw\/ ];
|
||||
srcfile="`echo $wlfile |sed -r \"s|^/rw/(.+)$|$rw/BAK-\1|\"`"
|
||||
dstfile="`echo $wlfile |sed -r \"s|^/rw/(.+)$|$rw/\1|\"`"
|
||||
dstdir="`dirname \"$dstfile\"`"
|
||||
if [ ! -e "$srcfile" ]; then
|
||||
echo "Whitelist entry not present in filesystem."
|
||||
continue
|
||||
# For very large dirs: mv whole dir when entry ends with '/'
|
||||
elif echo $wlfile |grep -q "\/$"; then
|
||||
echo "Whitelist mv $srcfile"
|
||||
mkdir -p "$dstdir"
|
||||
mv "$srcfile" "$dstdir"
|
||||
else
|
||||
echo "Whitelist cp $srcfile"
|
||||
cp -a --link "$srcfile" "$dstdir"
|
||||
fi
|
||||
elif [ -n "$wlfile" ]; then
|
||||
echo "Whitelist path must begin with /rw/."
|
||||
fi
|
||||
done
|
||||
|
||||
# Copy default files...
|
||||
if [ -d $defdir/$vmset/rw ]; then
|
||||
cp -af "$defdir/$vmset/rw/*" $rw
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
make_immutable
|
||||
umount $rw
|
||||
exit 0
|
Loading…
Reference in New Issue
Block a user