2014-04-01 23:42:54 +00:00
#!/usr/bin/env bash
set -e
2016-11-02 23:23:52 +00:00
EXITCODE = 0
2014-04-01 23:42:54 +00:00
# bits of this were adapted from lxc-checkconfig
# see also https://github.com/lxc/lxc/blob/lxc-1.0.2/src/lxc/lxc-checkconfig.in
2014-04-22 12:26:44 +00:00
possibleConfigs = (
'/proc/config.gz'
" /boot/config- $( uname -r) "
" /usr/src/linux- $( uname -r) /.config "
'/usr/src/linux/.config'
)
2015-01-23 08:36:55 +00:00
if [ $# -gt 0 ] ; then
CONFIG = " $1 "
else
2015-02-13 11:52:11 +00:00
: ${ CONFIG : = " ${ possibleConfigs [0] } " }
2015-01-23 08:36:55 +00:00
fi
2014-04-03 17:46:24 +00:00
if ! command -v zgrep & > /dev/null; then
zgrep( ) {
zcat " $2 " | grep " $1 "
}
fi
2014-04-01 23:42:54 +00:00
2015-06-03 09:26:39 +00:00
kernelVersion = " $( uname -r) "
kernelMajor = " ${ kernelVersion %%.* } "
kernelMinor = " ${ kernelVersion # $kernelMajor . } "
kernelMinor = " ${ kernelMinor %%.* } "
2014-04-01 23:42:54 +00:00
is_set( ) {
2014-04-03 17:46:24 +00:00
zgrep " CONFIG_ $1 =[y|m] " " $CONFIG " > /dev/null
2014-04-01 23:42:54 +00:00
}
2015-05-15 02:20:31 +00:00
is_set_in_kernel( ) {
zgrep " CONFIG_ $1 =y " " $CONFIG " > /dev/null
}
is_set_as_module( ) {
zgrep " CONFIG_ $1 =m " " $CONFIG " > /dev/null
}
2014-04-01 23:42:54 +00:00
color( ) {
2016-01-13 04:57:56 +00:00
local codes = ( )
2014-04-01 23:42:54 +00:00
if [ " $1 " = 'bold' ] ; then
2016-01-13 04:57:56 +00:00
codes = ( " ${ codes [@] } " '1' )
2014-04-01 23:42:54 +00:00
shift
fi
2016-01-13 04:57:56 +00:00
if [ " $# " -gt 0 ] ; then
local code =
case " $1 " in
# see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
black) code = 30 ; ;
red) code = 31 ; ;
green) code = 32 ; ;
yellow) code = 33 ; ;
blue) code = 34 ; ;
magenta) code = 35 ; ;
cyan) code = 36 ; ;
white) code = 37 ; ;
esac
if [ " $code " ] ; then
codes = ( " ${ codes [@] } " " $code " )
fi
2014-04-02 08:44:12 +00:00
fi
local IFS = ';'
2016-01-13 04:57:56 +00:00
echo -en '\033[' " ${ codes [*] } " 'm'
2014-04-02 08:44:12 +00:00
}
wrap_color( ) {
text = " $1 "
shift
color " $@ "
echo -n " $text "
color reset
echo
}
wrap_good( ) {
echo " $( wrap_color " $1 " white) : $( wrap_color " $2 " green) "
}
wrap_bad( ) {
echo " $( wrap_color " $1 " bold) : $( wrap_color " $2 " bold red) "
}
wrap_warning( ) {
wrap_color >& 2 " $* " red
2014-04-01 23:42:54 +00:00
}
check_flag( ) {
2015-05-15 02:20:31 +00:00
if is_set_in_kernel " $1 " ; then
2014-04-02 08:44:12 +00:00
wrap_good " CONFIG_ $1 " 'enabled'
2015-05-15 02:20:31 +00:00
elif is_set_as_module " $1 " ; then
wrap_good " CONFIG_ $1 " 'enabled (as module)'
2014-04-01 23:42:54 +00:00
else
2014-04-02 08:44:12 +00:00
wrap_bad " CONFIG_ $1 " 'missing'
2016-11-02 23:23:52 +00:00
EXITCODE = 1
2014-04-01 23:42:54 +00:00
fi
}
check_flags( ) {
for flag in " $@ " ; do
2016-11-02 23:23:52 +00:00
echo -n "- " ; check_flag " $flag "
2014-04-01 23:42:54 +00:00
done
2014-12-03 12:57:23 +00:00
}
2014-04-01 23:42:54 +00:00
2014-09-03 14:26:19 +00:00
check_command( ) {
if command -v " $1 " >/dev/null 2>& 1; then
wrap_good " $1 command " 'available'
else
wrap_bad " $1 command " 'missing'
2016-11-02 23:23:52 +00:00
EXITCODE = 1
2014-09-03 14:26:19 +00:00
fi
}
check_device( ) {
if [ -c " $1 " ] ; then
wrap_good " $1 " 'present'
else
wrap_bad " $1 " 'missing'
2016-11-02 23:23:52 +00:00
EXITCODE = 1
2014-09-03 14:26:19 +00:00
fi
}
2016-02-24 05:28:24 +00:00
check_distro_userns( ) {
source /etc/os-release 2>/dev/null || /bin/true
if [ [ " ${ ID } " = ~ ^( centos| rhel) $ && " ${ VERSION_ID } " = ~ ^7 ] ] ; then
# this is a CentOS7 or RHEL7 system
grep -q "user_namespace.enable=1" /proc/cmdline || {
# no user namespace support enabled
wrap_bad " (RHEL7/CentOS7" "User namespaces disabled; add 'user_namespace.enable=1' to boot command line)"
2016-11-02 23:23:52 +00:00
EXITCODE = 1
2016-02-24 05:28:24 +00:00
}
fi
}
2014-04-02 08:44:12 +00:00
if [ ! -e " $CONFIG " ] ; then
2015-06-19 05:47:48 +00:00
wrap_warning " warning: $CONFIG does not exist, searching other paths for kernel config ... "
2014-04-22 12:26:44 +00:00
for tryConfig in " ${ possibleConfigs [@] } " ; do
2014-04-02 08:44:12 +00:00
if [ -e " $tryConfig " ] ; then
CONFIG = " $tryConfig "
break
fi
done
if [ ! -e " $CONFIG " ] ; then
wrap_warning "error: cannot find kernel config"
wrap_warning " try running this script again, specifying the kernel config:"
2015-02-13 11:52:11 +00:00
wrap_warning " CONFIG=/path/to/kernel/.config $0 or $0 /path/to/kernel/.config "
2014-04-02 08:44:12 +00:00
exit 1
fi
fi
2014-04-01 23:42:54 +00:00
2014-04-02 08:44:12 +00:00
wrap_color " info: reading kernel config from $CONFIG ... " white
echo
2014-04-01 23:42:54 +00:00
echo 'Generally Necessary:'
2014-04-02 08:44:12 +00:00
echo -n '- '
2014-06-07 14:43:40 +00:00
cgroupSubsystemDir = " $( awk '/[, ](cpu|cpuacct|cpuset|devices|freezer|memory)[, ]/ && $3 == "cgroup" { print $2 }' /proc/mounts | head -n1) "
2014-04-08 04:53:42 +00:00
cgroupDir = " $( dirname " $cgroupSubsystemDir " ) "
if [ -d " $cgroupDir /cpu " -o -d " $cgroupDir /cpuacct " -o -d " $cgroupDir /cpuset " -o -d " $cgroupDir /devices " -o -d " $cgroupDir /freezer " -o -d " $cgroupDir /memory " ] ; then
2014-04-02 08:44:12 +00:00
echo " $( wrap_good 'cgroup hierarchy' 'properly mounted' ) [ $cgroupDir ] "
else
2014-04-08 04:53:42 +00:00
if [ " $cgroupSubsystemDir " ] ; then
echo " $( wrap_bad 'cgroup hierarchy' 'single mountpoint!' ) [ $cgroupSubsystemDir ] "
else
echo " $( wrap_bad 'cgroup hierarchy' 'nonexistent??' ) "
fi
2016-11-02 23:23:52 +00:00
EXITCODE = 1
2014-04-02 08:44:12 +00:00
echo " $( wrap_color '(see https://github.com/tianon/cgroupfs-mount)' yellow) "
fi
2014-07-22 16:08:41 +00:00
if [ " $( cat /sys/module/apparmor/parameters/enabled 2>/dev/null) " = 'Y' ] ; then
echo -n '- '
if command -v apparmor_parser & > /dev/null; then
echo " $( wrap_good 'apparmor' 'enabled and tools installed' ) "
else
echo " $( wrap_bad 'apparmor' 'enabled, but apparmor_parser missing' ) "
echo -n ' '
if command -v apt-get & > /dev/null; then
echo " $( wrap_color '(use "apt-get install apparmor" to fix this)' ) "
elif command -v yum & > /dev/null; then
echo " $( wrap_color '(your best bet is "yum install apparmor-parser")' ) "
else
echo " $( wrap_color '(look for an "apparmor" package for your distribution)' ) "
fi
2016-11-02 23:23:52 +00:00
EXITCODE = 1
2014-07-22 16:08:41 +00:00
fi
fi
2014-04-01 23:42:54 +00:00
flags = (
NAMESPACES { NET,PID,IPC,UTS} _NS
2015-06-19 05:47:48 +00:00
CGROUPS CGROUP_CPUACCT CGROUP_DEVICE CGROUP_FREEZER CGROUP_SCHED CPUSETS MEMCG
2016-03-01 18:01:12 +00:00
KEYS
2016-07-08 01:21:57 +00:00
VETH BRIDGE BRIDGE_NETFILTER
2014-11-04 22:47:13 +00:00
NF_NAT_IPV4 IP_NF_FILTER IP_NF_TARGET_MASQUERADE
2016-10-01 01:50:17 +00:00
NETFILTER_XT_MATCH_{ ADDRTYPE,CONNTRACK,IPVS}
2016-10-04 16:13:58 +00:00
IP_NF_NAT NF_NAT NF_NAT_NEEDED
2014-12-26 21:59:25 +00:00
# required for bind-mounting /dev/mqueue into containers
POSIX_MQUEUE
2014-04-01 23:42:54 +00:00
)
check_flags " ${ flags [@] } "
2016-11-18 11:38:07 +00:00
if [ " $kernelMajor " -lt 4 ] || [ " $kernelMajor " -eq 4 -a " $kernelMinor " -lt 8 ] ; then
check_flags DEVPTS_MULTIPLE_INSTANCES
fi
2014-04-01 23:42:54 +00:00
echo
echo 'Optional Features:'
2015-10-11 09:26:34 +00:00
{
check_flags USER_NS
2016-02-24 05:28:24 +00:00
check_distro_userns
2015-10-11 09:26:34 +00:00
}
2015-11-18 09:42:12 +00:00
{
check_flags SECCOMP
}
2015-12-15 19:15:43 +00:00
{
check_flags CGROUP_PIDS
}
2015-04-02 00:38:39 +00:00
{
2016-05-16 05:55:24 +00:00
check_flags MEMCG_SWAP MEMCG_SWAP_ENABLED
2015-04-02 00:38:39 +00:00
if is_set MEMCG_SWAP && ! is_set MEMCG_SWAP_ENABLED; then
echo " $( wrap_color '(note that cgroup swap accounting is not enabled in your kernel config, you can enable it by setting boot option "swapaccount=1")' bold black) "
fi
}
2015-06-03 09:26:39 +00:00
2016-05-16 05:55:24 +00:00
if [ " $kernelMajor " -lt 4 ] || [ " $kernelMajor " -eq 4 -a " $kernelMinor " -le 5 ] ; then
check_flags MEMCG_KMEM
fi
2015-06-03 09:26:39 +00:00
if [ " $kernelMajor " -lt 3 ] || [ " $kernelMajor " -eq 3 -a " $kernelMinor " -le 18 ] ; then
check_flags RESOURCE_COUNTERS
fi
2015-08-14 06:38:48 +00:00
if [ " $kernelMajor " -lt 3 ] || [ " $kernelMajor " -eq 3 -a " $kernelMinor " -le 13 ] ; then
netprio = NETPRIO_CGROUP
else
netprio = CGROUP_NET_PRIO
fi
2014-04-01 23:42:54 +00:00
flags = (
2016-04-25 06:08:29 +00:00
BLK_CGROUP BLK_DEV_THROTTLING IOSCHED_CFQ CFQ_GROUP_IOSCHED
2014-08-19 11:48:55 +00:00
CGROUP_PERF
2015-06-19 05:47:48 +00:00
CGROUP_HUGETLB
2015-08-14 06:38:48 +00:00
NET_CLS_CGROUP $netprio
2015-06-19 05:47:48 +00:00
CFS_BANDWIDTH FAIR_GROUP_SCHED RT_GROUP_SCHED
2016-06-28 17:42:38 +00:00
IP_VS
2016-10-01 01:50:17 +00:00
IP_VS_NFCT
IP_VS_RR
2014-04-01 23:42:54 +00:00
)
check_flags " ${ flags [@] } "
2016-10-28 10:16:04 +00:00
if ! is_set EXT4_USE_FOR_EXT2; then
check_flags EXT3_FS EXT3_FS_XATTR EXT3_FS_POSIX_ACL EXT3_FS_SECURITY
if ! is_set EXT3_FS || ! is_set EXT3_FS_XATTR || ! is_set EXT3_FS_POSIX_ACL || ! is_set EXT3_FS_SECURITY; then
echo " $( wrap_color '(enable these ext3 configs if you are using ext3 as backing filesystem)' bold black) "
fi
2015-06-19 05:45:07 +00:00
fi
check_flags EXT4_FS EXT4_FS_POSIX_ACL EXT4_FS_SECURITY
if ! is_set EXT4_FS || ! is_set EXT4_FS_POSIX_ACL || ! is_set EXT4_FS_SECURITY; then
2016-10-28 10:16:04 +00:00
if is_set EXT4_USE_FOR_EXT2; then
echo " $( wrap_color 'enable these ext4 configs if you are using ext3 or ext4 as backing filesystem' bold black) "
else
echo " $( wrap_color 'enable these ext4 configs if you are using ext4 as backing filesystem' bold black) "
fi
2015-06-19 05:45:07 +00:00
fi
2016-04-11 23:42:53 +00:00
echo '- Network Drivers:'
2016-11-02 23:23:52 +00:00
echo ' - "' $( wrap_color 'overlay' blue) '":'
check_flags VXLAN | sed 's/^/ /'
echo ' Optional (for encrypted networks):'
check_flags CRYPTO CRYPTO_AEAD CRYPTO_GCM CRYPTO_SEQIV CRYPTO_GHASH \
XFRM XFRM_USER XFRM_ALGO INET_ESP INET_XFRM_MODE_TRANSPORT | sed 's/^/ /'
echo ' - "' $( wrap_color 'ipvlan' blue) '":'
check_flags IPVLAN | sed 's/^/ /'
echo ' - "' $( wrap_color 'macvlan' blue) '":'
check_flags MACVLAN DUMMY | sed 's/^/ /'
# only fail if no storage drivers available
CODE = ${ EXITCODE }
EXITCODE = 0
STORAGE = 1
2016-04-11 23:42:53 +00:00
2014-04-01 23:42:54 +00:00
echo '- Storage Drivers:'
2016-11-02 23:23:52 +00:00
echo ' - "' $( wrap_color 'aufs' blue) '":'
check_flags AUFS_FS | sed 's/^/ /'
if ! is_set AUFS_FS && grep -q aufs /proc/filesystems; then
echo " $( wrap_color '(note that some kernels include AUFS patches but not the AUFS_FS flag)' bold black) "
fi
[ " $EXITCODE " = 0 ] && STORAGE = 0
EXITCODE = 0
echo ' - "' $( wrap_color 'btrfs' blue) '":'
check_flags BTRFS_FS | sed 's/^/ /'
check_flags BTRFS_FS_POSIX_ACL | sed 's/^/ /'
[ " $EXITCODE " = 0 ] && STORAGE = 0
EXITCODE = 0
echo ' - "' $( wrap_color 'devicemapper' blue) '":'
check_flags BLK_DEV_DM DM_THIN_PROVISIONING | sed 's/^/ /'
[ " $EXITCODE " = 0 ] && STORAGE = 0
EXITCODE = 0
echo ' - "' $( wrap_color 'overlay' blue) '":'
check_flags OVERLAY_FS | sed 's/^/ /'
[ " $EXITCODE " = 0 ] && STORAGE = 0
EXITCODE = 0
echo ' - "' $( wrap_color 'zfs' blue) '":'
echo -n " - " ; check_device /dev/zfs
echo -n " - " ; check_command zfs
echo -n " - " ; check_command zpool
[ " $EXITCODE " = 0 ] && STORAGE = 0
EXITCODE = 0
EXITCODE = $CODE
[ " $STORAGE " = 1 ] && EXITCODE = 1
2014-09-03 14:26:19 +00:00
2014-04-01 23:42:54 +00:00
echo
2016-05-20 23:05:25 +00:00
check_limit_over( )
{
if [ $( cat " $1 " ) -le " $2 " ] ; then
wrap_bad " - $1 " " $( cat $1 ) "
wrap_color " This should be set to at least $2 , for example set: sysctl -w kernel/keys/root_maxkeys=1000000 " bold black
2016-11-02 23:23:52 +00:00
EXITCODE = 1
2016-05-20 23:05:25 +00:00
else
wrap_good " - $1 " " $( cat $1 ) "
fi
}
echo 'Limits:'
check_limit_over /proc/sys/kernel/keys/root_maxkeys 10000
echo
2016-11-02 23:23:52 +00:00
exit $EXITCODE