forked from pool/libselinux
0b8e4bc585
- updated selinux-ready script to handle initrd files compressed with xz OBS-URL: https://build.opensuse.org/request/show/247967 OBS-URL: https://build.opensuse.org/package/show/security:SELinux/libselinux?expand=0&rev=79
271 lines
6.1 KiB
Bash
271 lines
6.1 KiB
Bash
#!/bin/bash
|
|
|
|
KERNEL="unknown"
|
|
INITRD="unknown"
|
|
TD=""
|
|
|
|
|
|
# init needs /selinux to be there
|
|
check_dir()
|
|
{
|
|
SLDIRS="/selinux /sys/fs/selinux"
|
|
FOUND="no"
|
|
|
|
for DIR in $SLDIRS; do
|
|
if [ -d $DIR ]; then
|
|
printf "\tcheck_dir: OK. $DIR exists.\n"
|
|
FOUND="yes"
|
|
fi
|
|
done
|
|
|
|
if [ $FOUND == "yes" ]; then
|
|
return 0
|
|
else
|
|
printf "\tcheck_dir: ERR. Neither of $SLDIRS does exist. Please execute 'mkdir /sys/fs/selinux' as root\n"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_filesystem()
|
|
{
|
|
FSPATH="/proc/filesystems"
|
|
FSNAMES="securityfs selinuxfs"
|
|
OK="O"
|
|
|
|
for FSNAME in $FSNAMES; do
|
|
grep -w $FSNAME $FSPATH 1>&2 >/dev/null
|
|
|
|
if [ $? == 0 ]; then
|
|
printf "\tcheck_filesystem: OK. Filesystem '$FSNAME' exists.\n"
|
|
else
|
|
printf "\tcheck_filesystem: ERR. Filesystem '$FSNAME' is missing. Please enable SELinux while compiling the kernel.\n"
|
|
OK="1"
|
|
fi
|
|
done
|
|
if [ "$OK" == "0" ]; then
|
|
return 0;
|
|
else
|
|
return 1;
|
|
fi
|
|
}
|
|
|
|
check_boot()
|
|
{
|
|
BPARAM1="security=selinux"
|
|
BPARAM2="selinux=1"
|
|
|
|
printf "\tcheck_boot: Assuming GRUB2 as bootloader.\n"
|
|
|
|
# look for parameters of the current kernel
|
|
CURRENT_KERNEL=$(uname -r)
|
|
OTHERS=""
|
|
RETVAL="FAIL"
|
|
while read BLINE
|
|
do
|
|
K=$(echo $BLINE | awk -F' ' '{print $2}')
|
|
KERNEL=$(basename $K)
|
|
K=$(echo $KERNEL | sed s/vmlinuz-//)
|
|
|
|
if [ "$K" == "$CURRENT_KERNEL" ]; then
|
|
INITRD=initrd-$K
|
|
RETVAL="OK"
|
|
else
|
|
OTHERS="$KERNEL $OTHERS"
|
|
fi
|
|
done < <(grep -- $BPARAM1 /boot/grub2/grub.cfg 2>/dev/null | grep -- $BPARAM2)
|
|
|
|
if [ "$RETVAL" == OK ]; then
|
|
printf "\tcheck_boot: OK. Current kernel '$KERNEL' has boot-parameters '$BPARAM1 $BPARAM2'\n"
|
|
printf "\tcheck_boot: OK. Other kernels with correct parameters: $OTHERS\n"
|
|
return 0
|
|
else
|
|
printf "\tcheck_boot: ERR. Boot-parameter missing for booting the kernel.\n"
|
|
printf "\t Please use YaST2 to add 'security=selinux selinux=1' to the kernel boot-parameter list.\n"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_mkinitrd()
|
|
{
|
|
if [ "$INITRD" == "unknown" ]; then
|
|
return 1
|
|
fi
|
|
MCMD="mount.*/root/proc.*"
|
|
|
|
if ! [ -f "/boot/$INITRD" ];then
|
|
printf "\tcheck_mkinitrd: ERR. Unable to locate '/boot/$INITRD'\n"
|
|
return 2
|
|
fi
|
|
|
|
cp /boot/$INITRD $TD/ 2>/dev/null
|
|
|
|
if ! [ -f "$TD/$INITRD" ];then
|
|
printf "\tcheck_mkinitrd: ERR. Error while copying initrd file.'\n"
|
|
return 2
|
|
fi
|
|
|
|
|
|
pushd . 2>&1>/dev/null
|
|
cd $TD
|
|
mkdir initrd-extracted
|
|
cd initrd-extracted
|
|
INITRD_FORMAT=$(file $TD/$INITRD | awk -F' ' '{print $2}')
|
|
case $INITRD_FORMAT in
|
|
'XZ' )
|
|
xz -d -c $TD/$INITRD | cpio -i --force-local --no-absolute-filenames 2>/dev/null ;;
|
|
'gzip' )
|
|
gzip -d -c $TD/$INITRD | cpio -i --force-local --no-absolute-filenames 2>/dev/null ;;
|
|
* )
|
|
printf "\tcheck_mkinitrd: ERR. Error while extracting initrd file.'\n"
|
|
return 2
|
|
esac
|
|
if [ -d boot ]; then
|
|
grep -E -- $MCMD boot/* 2>&1 >/dev/null
|
|
FLG1=$?
|
|
grep -E -- load_policy boot/* 2>&1 >/dev/null
|
|
FLG2=$?
|
|
else
|
|
# looks like we're using dracut/systemd. We can only check if libselinux1
|
|
# exists
|
|
if [ -f lib64/libselinux.so.1 ]; then
|
|
# if this exists
|
|
FLG1=0
|
|
FLG2=0
|
|
fi
|
|
fi
|
|
popd 2>&1>/dev/null
|
|
|
|
if [ $FLG1 == 0 -a $FLG2 == 0 ];then
|
|
printf "\tcheck_mkinitrd: OK. Your initrd seems to be correct.\n"
|
|
return 0
|
|
else
|
|
printf "\tcheck_mkinitrd: ERR. Your initrd seems not to mount /proc of\n"
|
|
printf "\t the root filesystem during boot and/or load_policy\n"
|
|
printf "\t is missing,\n"
|
|
printf "\t this may be a reason for SELinux not working.\n"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_pam()
|
|
{
|
|
AA_PAM=0
|
|
SE_PAM=0
|
|
|
|
# test for AA pam module
|
|
grep apparmor /etc/pam.d/* 2>&1 >/dev/null
|
|
FLG=$?
|
|
if [ $FLG == 0 ]; then
|
|
AA_PAM=1
|
|
fi
|
|
|
|
# test for SELinux pam module
|
|
grep selinux /etc/pam.d/* 2>&1 >/dev/null
|
|
FLG=$?
|
|
if [ $FLG == 0 ]; then
|
|
SE_PAM=1
|
|
fi
|
|
|
|
# suggest config
|
|
if [ $SE_PAM == 1 ] && [ $AA_PAM == 0 ]; then
|
|
printf "\tcheck_pam: OK. Your PAM configuration seems to be correct.\n"
|
|
return 0
|
|
fi
|
|
printf "\tcheck_pam: ERR. Your PAM configuration seems to be incorrect.\n"
|
|
if [ $AA_PAM == 1 ]; then
|
|
printf " execute 'pam-config -d --apparmor' as root\n"
|
|
fi
|
|
if [ $SE_PAM == 0 ]; then
|
|
printf " execute 'pam-config -a --selinux' as root\n"
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
check_initupstart()
|
|
{
|
|
CFGFILE="/etc/selinux/config"
|
|
|
|
if ! [ -f $CFGFILE ]; then
|
|
printf "\tcheck_initupstart: ERR. $CFGFILE does not exist.\n"
|
|
return 1;
|
|
fi
|
|
}
|
|
|
|
check_runlevel()
|
|
{
|
|
if [ "$(systemctl is-enabled restorecond.service)" == "enabled" ]; then
|
|
printf "\tcheck_runlevel: OK. restorecond is enabled on your system\n"
|
|
return 0;
|
|
fi
|
|
printf "\tcheck_runlevel: ERR. please execute 'yast2 runlevel' and enable restorecond.\n"
|
|
return 1
|
|
}
|
|
|
|
check_packages()
|
|
{
|
|
PKGLST="checkpolicy policycoreutils selinux-tools libselinux1 libsepol1 libsemanage1 selinux-policy"
|
|
FAIL=0
|
|
|
|
for i in $PKGLST
|
|
do
|
|
rpm -q $i 1>&2 >/dev/null
|
|
if [ $? == 1 ];then
|
|
printf "\tcheck_packages: ERR. Package '$i' not installed, please run 'zypper in $i' as root\n"
|
|
FAIL=1
|
|
fi
|
|
done
|
|
|
|
if [ $FAIL == 0 ]; then
|
|
printf "\tcheck_packages: OK. All essential packages are installed\n"
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_config()
|
|
{
|
|
CF="/etc/selinux/config"
|
|
|
|
if [ -f $CF ];then
|
|
printf "\tcheck_config: OK. Config file seems to be there.\n"
|
|
# with -L because /etc/selinux/config is now a link to /etc/sysconfig/selinux-policy
|
|
if ! [ $(stat -L --printf=%a $CF) -eq "644" ]; then
|
|
printf "\tcheck_config: ERR. Config file '$CF' has wrong permissions.\n"
|
|
return 1
|
|
fi
|
|
|
|
# check that SELINUX is not disabled there
|
|
SELINUX_MODE=$(grep "^\s*SELINUX\s*=" $CF | sed "s/SELINUX\s*=\(\S*\)\s*"/\\1/)
|
|
case "$SELINUX_MODE" in
|
|
permissive | enforcing )
|
|
printf "\tcheck_config: OK. SELINUX is set to '$SELINUX_MODE'.\n"
|
|
return 0
|
|
;;
|
|
* )
|
|
printf "\tcheck_config: ERR. SELINUX is set to '$SELINUX_MODE' in '$CF'. Should be either 'permissive' or 'enforcing'\n"
|
|
return 1
|
|
;;
|
|
esac
|
|
else
|
|
printf "\tcheck_config: ERR. Config file '$CF' is missing.\n"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
TD=$(mktemp -q -d /tmp/selinux-ready.XXXXXX)
|
|
|
|
echo "Start checking your system if it is selinux-ready or not:"
|
|
check_dir
|
|
check_filesystem
|
|
check_boot
|
|
check_mkinitrd
|
|
check_packages
|
|
check_config
|
|
check_initupstart
|
|
check_pam
|
|
check_runlevel
|
|
|
|
rm -rf $TD
|