2014-04-01 19:42:54 -04:00
#!/usr/bin/env bash
set -e
# 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 08:26:44 -04:00
possibleConfigs = (
'/proc/config.gz'
" /boot/config- $( uname -r) "
" /usr/src/linux- $( uname -r) /.config "
'/usr/src/linux/.config'
)
2015-01-23 03:36:55 -05:00
if [ $# -gt 0 ] ; then
CONFIG = " $1 "
else
2015-02-13 06:52:11 -05:00
: ${ CONFIG : = " ${ possibleConfigs [0] } " }
2015-01-23 03:36:55 -05:00
fi
2014-04-03 13:46:24 -04:00
if ! command -v zgrep & > /dev/null; then
zgrep( ) {
zcat " $2 " | grep " $1 "
}
fi
2014-04-01 19:42:54 -04:00
2015-06-03 05:26:39 -04:00
kernelVersion = " $( uname -r) "
kernelMajor = " ${ kernelVersion %%.* } "
kernelMinor = " ${ kernelVersion # $kernelMajor . } "
kernelMinor = " ${ kernelMinor %%.* } "
2014-04-01 19:42:54 -04:00
is_set( ) {
2014-04-03 13:46:24 -04:00
zgrep " CONFIG_ $1 =[y|m] " " $CONFIG " > /dev/null
2014-04-01 19:42:54 -04:00
}
2015-05-14 22:20:31 -04: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 19:42:54 -04:00
color( ) {
2016-01-12 23:57:56 -05:00
local codes = ( )
2014-04-01 19:42:54 -04:00
if [ " $1 " = 'bold' ] ; then
2016-01-12 23:57:56 -05:00
codes = ( " ${ codes [@] } " '1' )
2014-04-01 19:42:54 -04:00
shift
fi
2016-01-12 23:57:56 -05: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 04:44:12 -04:00
fi
local IFS = ';'
2016-01-12 23:57:56 -05:00
echo -en '\033[' " ${ codes [*] } " 'm'
2014-04-02 04:44:12 -04: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 19:42:54 -04:00
}
check_flag( ) {
2015-05-14 22:20:31 -04:00
if is_set_in_kernel " $1 " ; then
2014-04-02 04:44:12 -04:00
wrap_good " CONFIG_ $1 " 'enabled'
2015-05-14 22:20:31 -04:00
elif is_set_as_module " $1 " ; then
wrap_good " CONFIG_ $1 " 'enabled (as module)'
2014-04-01 19:42:54 -04:00
else
2014-04-02 04:44:12 -04:00
wrap_bad " CONFIG_ $1 " 'missing'
2014-04-01 19:42:54 -04:00
fi
}
check_flags( ) {
for flag in " $@ " ; do
2014-04-02 04:44:12 -04:00
echo " - $( check_flag " $flag " ) "
2014-04-01 19:42:54 -04:00
done
2014-12-03 07:57:23 -05:00
}
2014-04-01 19:42:54 -04:00
2014-09-03 10:26:19 -04:00
check_command( ) {
if command -v " $1 " >/dev/null 2>& 1; then
wrap_good " $1 command " 'available'
else
wrap_bad " $1 command " 'missing'
fi
}
check_device( ) {
if [ -c " $1 " ] ; then
wrap_good " $1 " 'present'
else
wrap_bad " $1 " 'missing'
fi
}
2016-02-24 00:28:24 -05: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)"
}
fi
}
2014-04-02 04:44:12 -04:00
if [ ! -e " $CONFIG " ] ; then
2015-06-19 01:47:48 -04:00
wrap_warning " warning: $CONFIG does not exist, searching other paths for kernel config ... "
2014-04-22 08:26:44 -04:00
for tryConfig in " ${ possibleConfigs [@] } " ; do
2014-04-02 04:44:12 -04: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 06:52:11 -05:00
wrap_warning " CONFIG=/path/to/kernel/.config $0 or $0 /path/to/kernel/.config "
2014-04-02 04:44:12 -04:00
exit 1
fi
fi
2014-04-01 19:42:54 -04:00
2014-04-02 04:44:12 -04:00
wrap_color " info: reading kernel config from $CONFIG ... " white
echo
2014-04-01 19:42:54 -04:00
echo 'Generally Necessary:'
2014-04-02 04:44:12 -04:00
echo -n '- '
2014-06-07 10:43:40 -04:00
cgroupSubsystemDir = " $( awk '/[, ](cpu|cpuacct|cpuset|devices|freezer|memory)[, ]/ && $3 == "cgroup" { print $2 }' /proc/mounts | head -n1) "
2014-04-08 00:53:42 -04: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 04:44:12 -04:00
echo " $( wrap_good 'cgroup hierarchy' 'properly mounted' ) [ $cgroupDir ] "
else
2014-04-08 00:53:42 -04:00
if [ " $cgroupSubsystemDir " ] ; then
echo " $( wrap_bad 'cgroup hierarchy' 'single mountpoint!' ) [ $cgroupSubsystemDir ] "
else
echo " $( wrap_bad 'cgroup hierarchy' 'nonexistent??' ) "
fi
2014-04-02 04:44:12 -04:00
echo " $( wrap_color '(see https://github.com/tianon/cgroupfs-mount)' yellow) "
fi
2014-07-22 12:08:41 -04: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
fi
fi
2014-04-01 19:42:54 -04:00
flags = (
NAMESPACES { NET,PID,IPC,UTS} _NS
DEVPTS_MULTIPLE_INSTANCES
2015-06-19 01:47:48 -04:00
CGROUPS CGROUP_CPUACCT CGROUP_DEVICE CGROUP_FREEZER CGROUP_SCHED CPUSETS MEMCG
2016-03-01 13:01:12 -05:00
KEYS
2016-07-07 21:21:57 -04:00
VETH BRIDGE BRIDGE_NETFILTER
2014-11-04 17:47:13 -05:00
NF_NAT_IPV4 IP_NF_FILTER IP_NF_TARGET_MASQUERADE
2014-04-08 00:53:42 -04:00
NETFILTER_XT_MATCH_{ ADDRTYPE,CONNTRACK}
2014-04-01 19:42:54 -04:00
NF_NAT NF_NAT_NEEDED
2014-12-26 16:59:25 -05:00
# required for bind-mounting /dev/mqueue into containers
POSIX_MQUEUE
2014-04-01 19:42:54 -04:00
)
check_flags " ${ flags [@] } "
echo
echo 'Optional Features:'
2015-10-11 05:26:34 -04:00
{
check_flags USER_NS
2016-02-24 00:28:24 -05:00
check_distro_userns
2015-10-11 05:26:34 -04:00
}
2015-11-18 04:42:12 -05:00
{
check_flags SECCOMP
}
2015-12-15 14:15:43 -05:00
{
check_flags CGROUP_PIDS
}
2015-04-01 20:38:39 -04:00
{
2016-05-16 01:55:24 -04:00
check_flags MEMCG_SWAP MEMCG_SWAP_ENABLED
2015-04-01 20:38:39 -04: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 05:26:39 -04:00
2016-05-16 01:55:24 -04:00
if [ " $kernelMajor " -lt 4 ] || [ " $kernelMajor " -eq 4 -a " $kernelMinor " -le 5 ] ; then
check_flags MEMCG_KMEM
fi
2015-06-03 05:26:39 -04:00
if [ " $kernelMajor " -lt 3 ] || [ " $kernelMajor " -eq 3 -a " $kernelMinor " -le 18 ] ; then
check_flags RESOURCE_COUNTERS
fi
2015-08-14 02:38:48 -04: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 19:42:54 -04:00
flags = (
2016-04-25 02:08:29 -04:00
BLK_CGROUP BLK_DEV_THROTTLING IOSCHED_CFQ CFQ_GROUP_IOSCHED
2014-08-19 07:48:55 -04:00
CGROUP_PERF
2015-06-19 01:47:48 -04:00
CGROUP_HUGETLB
2015-08-14 02:38:48 -04:00
NET_CLS_CGROUP $netprio
2015-06-19 01:47:48 -04:00
CFS_BANDWIDTH FAIR_GROUP_SCHED RT_GROUP_SCHED
2016-06-28 13:42:38 -04:00
IP_VS
2014-04-01 19:42:54 -04:00
)
check_flags " ${ flags [@] } "
2015-06-19 01:45:07 -04:00
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
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
echo " $( wrap_color 'enable these ext4 configs if you are using ext4 as backing filesystem' bold black) "
fi
2016-04-11 19:42:53 -04:00
echo '- Network Drivers:'
{
echo '- "' $( wrap_color 'overlay' blue) '":'
check_flags VXLAN | sed 's/^/ /'
2016-06-22 12:44:56 -04:00
echo ' Optional (for secure networks):'
check_flags XFRM_ALGO XFRM_USER | sed 's/^/ /'
2016-07-07 21:21:57 -04:00
echo '- "' $( wrap_color 'ipvlan' blue) '":'
check_flags IPVLAN | sed 's/^/ /'
echo '- "' $( wrap_color 'macvlan' blue) '":'
check_flags MACVLAN DUMMY | sed 's/^/ /'
2016-04-11 19:42:53 -04:00
} | sed 's/^/ /'
2014-04-01 19:42:54 -04:00
echo '- Storage Drivers:'
{
2014-04-02 04:44:12 -04:00
echo '- "' $( wrap_color 'aufs' blue) '":'
2014-11-18 14:20:49 -05:00
check_flags AUFS_FS | sed 's/^/ /'
2014-04-01 19:42:54 -04:00
if ! is_set AUFS_FS && grep -q aufs /proc/filesystems; then
2014-04-02 04:44:12 -04:00
echo " $( wrap_color '(note that some kernels include AUFS patches but not the AUFS_FS flag)' bold black) "
2014-04-01 19:42:54 -04:00
fi
2014-04-02 04:44:12 -04:00
echo '- "' $( wrap_color 'btrfs' blue) '":'
2014-04-01 19:42:54 -04:00
check_flags BTRFS_FS | sed 's/^/ /'
2014-04-02 04:44:12 -04:00
echo '- "' $( wrap_color 'devicemapper' blue) '":'
2015-06-19 01:45:07 -04:00
check_flags BLK_DEV_DM DM_THIN_PROVISIONING | sed 's/^/ /'
2014-11-18 14:20:49 -05:00
2014-12-03 07:57:23 -05:00
echo '- "' $( wrap_color 'overlay' blue) '":'
2015-06-19 01:45:07 -04:00
check_flags OVERLAY_FS | sed 's/^/ /'
2014-09-03 10:26:19 -04:00
echo '- "' $( wrap_color 'zfs' blue) '":'
echo " - $( check_device /dev/zfs) "
echo " - $( check_command zfs) "
echo " - $( check_command zpool) "
2014-04-01 19:42:54 -04:00
} | sed 's/^/ /'
echo
2016-05-20 19:05:25 -04: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
else
wrap_good " - $1 " " $( cat $1 ) "
fi
}
echo 'Limits:'
check_limit_over /proc/sys/kernel/keys/root_maxkeys 10000
echo