1#!/bin/sh 2 3################################################################################# 4# 5# Lynis 6# ------------------ 7# 8# Copyright 2007-2013, Michael Boelen 9# Copyright 2007-2021, CISOfy 10# 11# Website : https://cisofy.com 12# Blog : http://linux-audit.com 13# GitHub : https://github.com/CISOfy/lynis 14# 15# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are 16# welcome to redistribute it under the terms of the GNU General Public License. 17# See LICENSE file for usage of this software. 18# 19################################################################################# 20# 21# File systems 22# 23################################################################################# 24# 25 # Number of days to mark a file as old 26 TMP_OLD_DAYS=90 27 LVM_VG_USED=0 28# 29################################################################################# 30# 31 InsertSection "${SECTION_FILE_SYSTEMS}" 32# 33################################################################################# 34# 35 # Test : FILE-6310 36 # Description : Checking if some mount points are separated from / 37 # Goal : Users should not be able to fill their home directory or temporary directory and creating a Denial of Service 38 Register --test-no FILE-6310 --weight L --network NO --category security --description "Checking /tmp, /home and /var directory" 39 if [ ${SKIPTEST} -eq 0 ]; then 40 Display --indent 2 --text "- Checking mount points" 41 SEPARATED_FILESYTEMS="/home /tmp /var" 42 for I in ${SEPARATED_FILESYTEMS}; do 43 LogText "Test: Checking if ${I} is mounted separately or mounted on / file system" 44 if [ -L ${I} ]; then 45 ShowSymlinkPath ${I} 46 LogText "Result: ${I} is a symlink. Manual check required to determine exact file system options" 47 ReportSuggestion "${TEST_NO}" "Symlinked mount point needs to be checked manually" "${I}" "" 48 Display --indent 4 --text "- Checking ${I} mount point" --result SYMLINK --color WHITE 49 elif [ -d ${I} ]; then 50 LogText "Result: directory ${I} exists" 51 case "${OS}" in 52 "AIX") FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($2==MP) { print $2 }}') ;; 53 "HP-UX") FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($1==MP) { print $1 }}') ;; 54 *) FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($3==MP) { print $3 }}') ;; 55 esac 56 57 if IsEmpty "${FIND}"; then 58 LogText "Result: ${I} not found in mount list. Directory most likely stored on / file system" 59 Display --indent 4 --text "- Checking ${I} mount point" --result "${STATUS_SUGGESTION}" --color YELLOW 60 ReportSuggestion "${TEST_NO}" "To decrease the impact of a full ${I} file system, place ${I} on a separate partition" 61 AddHP 9 10 62 else 63 LogText "Result: found ${I} as a separated mount point" 64 Display --indent 4 --text "- Checking ${I} mount point" --result "${STATUS_OK}" --color GREEN 65 AddHP 10 10 66 fi 67 else 68 LogText "Result: directory ${I} does not exist" 69 fi 70 done 71 fi 72# 73################################################################################# 74# 75 # Test : FILE-6311 76 # Description : Checking LVM Volume Groups 77 # Notes : No volume groups found is sent to STDERR for unclear reasons. Filtering both STDERR redirecting and grep. 78 if [ ! "${VGDISPLAYBINARY}" = "" -o ! "${LSVGBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 79 Register --test-no FILE-6311 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking LVM volume groups" 80 if [ ${SKIPTEST} -eq 0 ]; then 81 LogText "Test: Checking for LVM volume groups" 82 case ${OS} in 83 AIX) 84 FIND=$(${LSVGBINARY} -o) 85 ;; 86 Linux) 87 FIND=$(${VGDISPLAYBINARY} 2> /dev/null | ${GREPBINARY} -v "No volume groups found" | ${GREPBINARY} "VG Name" | ${AWKBINARY} '{ print $3 }' | ${SORTBINARY}) 88 ;; 89 *) 90 ReportException "${TEST_NO}:1" "Don't know this specific operating system yet, while volume group manager was found" 91 ;; 92 esac 93 if [ -n "${FIND}" ]; then 94 LogText "Result: found one or more volume groups" 95 for I in ${FIND}; do 96 LogText "Found LVM volume group: ${I}" 97 Report "lvm_volume_group[]=${I}" 98 done 99 LVM_VG_USED=1 100 Display --indent 2 --text "- Checking LVM volume groups" --result "${STATUS_FOUND}" --color GREEN 101 else 102 LogText "Result: no LVM volume groups found" 103 if IsVerbose; then Display --indent 2 --text "- Checking LVM volume groups" --result "${STATUS_NONE}" --color WHITE; fi 104 fi 105 fi 106# 107################################################################################# 108# 109 # Test : FILE-6312 110 # Description : Checking LVM volumes 111 if [ ${LVM_VG_USED} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 112 Register --test-no FILE-6312 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking LVM volumes" 113 if [ ${SKIPTEST} -eq 0 ]; then 114 LogText "Test: Checking for LVM volumes" 115 case ${OS} in 116 AIX) 117 ACTIVE_VG_LIST=$(${LSVGBINARY} -o) 118 FIND=$(for I in ${ACTIVE_VG_LIST}; do ${LSVGBINARY} -l ${I} | ${AWKBINARY} 'NR>2 { print $1 }'; done) 119 ;; 120 Linux) 121 FIND=$(${LVDISPLAYBINARY} | ${GREPBINARY} -v "No volume groups found" | ${GREPBINARY} "LV Name" | ${AWKBINARY} '{ print $3 }' | ${SORTBINARY}) 122 ;; 123 *) 124 ReportException "${TEST_NO}:1" "Need specific test for gathering volume manager data" 125 ;; 126 esac 127 if [ ! "${FIND}" = "" ]; then 128 LogText "Result: found one or more volumes" 129 for I in ${FIND}; do 130 LogText "Found LVM volume: ${I}" 131 Report "lvm_volume[]=${I}" 132 done 133 Display --indent 4 --text "- Checking LVM volumes" --result "${STATUS_FOUND}" --color GREEN 134 else 135 LogText "Result: no LVM volume groups found" 136 Display --indent 4 --text "- Checking LVM volumes" --result "${STATUS_NONE}" --color WHITE 137 fi 138 fi 139# 140################################################################################# 141# 142 # Test : FILE-6316 143 # Description : Checking /etc/fstab file permissions 144 #Register --test-no FILE-6316 --os Linux --weight L --network NO --category security --description "Checking /etc/fstab" 145 #if [ ${SKIPTEST} -eq 0 ]; then 146 # 644 147# 148################################################################################# 149# 150 # Test : FILE-6323 151 # Description : Checking Linux EXT2, EXT3, EXT4 file systems 152 Register --test-no FILE-6323 --os Linux --weight L --network NO --category security --description "Checking EXT file systems" 153 if [ ${SKIPTEST} -eq 0 ]; then 154 LogText "Test: Checking for Linux EXT file systems" 155 FIND=$(${MOUNTBINARY} -t ext2,ext3,ext4 | ${AWKBINARY} '{ print $3","$5 }') 156 if [ -n "${FIND}" ]; then 157 LogText "Result: found one or more EXT file systems" 158 for I in ${FIND}; do 159 FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d ',' -f1) 160 FILETYPE=$(echo ${I} | ${CUTBINARY} -d ',' -f2) 161 LogText "File system: ${FILESYSTEM} (type: ${FILETYPE})" 162 Report "file_systems_ext[]=${FILESYSTEM}|${FILETYPE}|" 163 done 164 else 165 LogText "Result: no EXT file systems found" 166 fi 167 fi 168# 169################################################################################# 170# 171 # Test : FILE-6324 172 # Description : Checking Linux XFS file systems 173 Register --test-no FILE-6324 --os Linux --weight L --network NO --category security --description "Checking XFS file systems" 174 if [ ${SKIPTEST} -eq 0 ]; then 175 LogText "Test: Checking for Linux XFS file systems" 176 FIND=$(${MOUNTBINARY} -t xfs | ${AWKBINARY} '{ print $3","$5 }') 177 if [ -n "${FIND}" ]; then 178 LogText "Result: found one or more XFS file systems" 179 for I in ${FIND}; do 180 FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d ',' -f1) 181 FILETYPE=$(echo ${I} | ${CUTBINARY} -d ',' -f2) 182 LogText "File system: ${FILESYSTEM} (type: ${FILETYPE})" 183 Report "file_systems_xfs[]=${FILESYSTEM}|${FILETYPE}|" 184 done 185 else 186 LogText "Result: no XFS file systems found" 187 fi 188 fi 189# 190################################################################################# 191# 192 # Test : FILE-6329 193 # Description : Query all FFS/UFS mounts from /etc/fstab 194 if [ -f /etc/fstab ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 195 Register --test-no FILE-6329 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking FFS/UFS file systems" 196 if [ ${SKIPTEST} -eq 0 ]; then 197 LogText "Test: Query /etc/fstab for available FFS/UFS mount points" 198 FIND=$(${AWKBINARY} '{ if ($3 == "ufs" || $3 == "ffs" ) { print $1":"$2":"$3":"$4":" }}' /etc/fstab) 199 if [ -z "${FIND}" ]; then 200 if IsVerbose; then Display --indent 2 --text "- Querying FFS/UFS mount points (fstab)" --result "${STATUS_NONE}" --color WHITE; fi 201 LogText "Result: unable to find any single mount point (FFS/UFS)" 202 else 203 Display --indent 2 --text "- Querying FFS/UFS mount points (fstab)" --result "${STATUS_FOUND}" --color GREEN 204 Report "filesystem[]=ufs" 205 for I in ${FIND}; do 206 LogText "FFS/UFS mount found: ${I}" 207 Report "mountpoint_ufs[]=${I}" 208 done 209 fi 210 fi 211# 212################################################################################# 213# 214 # Test : FILE-6330 215 # Description : Query ZFS mounts 216 # Note : mount -p does not work under Linux 217 Register --test-no FILE-6330 --os FreeBSD --weight L --network NO --category security --description "Checking ZFS file systems" 218 if [ ${SKIPTEST} -eq 0 ]; then 219 LogText "Test: Discover for available ZFS mount points" 220 FIND=$(${MOUNTBINARY} -p | ${AWKBINARY} '{ if ($3 == "zfs") { print $1":"$2":"$3":"$4":" }}') 221 if [ -z "${FIND}" ]; then 222 Display --indent 2 --text "- Querying ZFS mount points (mount -p)" --result "${STATUS_NONE}" --color WHITE 223 LogText "Result: unable to find any single mount point (ZFS)" 224 else 225 Display --indent 2 --text "- Querying ZFS mount points (mount -p)" --result "${STATUS_FOUND}" --color GREEN 226 Report "filesystem[]=zfs" 227 for I in ${FIND}; do 228 LogText "ZFS mount found: ${I}" 229 Report "mountpoint_zfs[]=${I}" 230 done 231 fi 232 fi 233# 234################################################################################# 235# 236 # Test : FILE-6439 237 # Description : Query all HAMMER PFS mounts from /etc/fstab 238 Register --test-no FILE-6439 --os DragonFly --weight L --network NO --category security --description "Checking HAMMER PFS mounts" 239 if [ ${SKIPTEST} -eq 0 ]; then 240 LogText "Test: Query /etc/fstab for available HAMMER PFS mount points" 241 FIND=$(${MOUNTBINARY} -p | ${AWKBINARY} '{ if ($3 == "null") { print $1":"$2":"$3":"$4":" }}') 242 if [ -z "${FIND}" ]; then 243 Display --indent 2 --text "- Querying HAMMER PFS mount points (mount -p)" --result "${STATUS_NONE}" --color WHITE 244 LogText "Result: unable to find any single PFS mount point" 245 else 246 Display --indent 2 --text "- Querying HAMMER PFS mount points (mount -p)" --result "${STATUS_FOUND}" --color GREEN 247 Report "filesystem[]=hammer" 248 for I in ${FIND}; do 249 LogText "HAMMER mount found: ${I}" 250 Report "mountpoint_hammer[]=${I}" 251 done 252 fi 253 fi 254# 255################################################################################# 256# 257 # Test : FILE-6332 258 # Description : Check swap partitions 259 if [ -f /etc/fstab ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 260 Register --test-no FILE-6332 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking swap partitions" 261 if [ ${SKIPTEST} -eq 0 ]; then 262 FOUND=0 263 LogText "Test: query swap partitions from /etc/fstab file" 264 # Check if third field contains 'swap' 265 FIND=$(${AWKBINARY} '{ if ($2=="swap" || $3=="swap") { print $1 }}' /etc/fstab | ${GREPBINARY} -v "^#") 266 for I in ${FIND}; do 267 FOUND=1 268 REAL="" 269 UUID="" 270 LogText "Swap partition found: ${I}" 271 # TODO Add a test if partition is not a normal partition (e.g. UUID=) 272 # Can be ^/dev/mapper/vg-name_lv-name 273 # Can be ^/dev/partition 274 275 # Test for UUID usage (e.g. UUID=uuid --> /dev/disk/by-uuid/<uuid>) 276 HAS_UUID=$(echo ${I} | ${GREPBINARY} "^UUID=") 277 if [ -n "${HAS_UUID}" ]; then 278 UUID=$(echo ${HAS_UUID} | ${AWKBINARY} -F= '{ print $2 }') 279 LogText "Result: Using ${UUID} as UUID" 280 if [ -n "${BLKIDBINARY}" ]; then 281 FIND2=$(${BLKIDBINARY} | ${AWKBINARY} '{ if ($2=="UUID=\"${UUID}\"") print $1 }' | ${SEDBINARY} 's/:$//') 282 if [ -n "${FIND2}" ]; then 283 REAL="${FIND2}" 284 fi 285 else 286 LogText "Result: blkid binary not found, trying by checking device listing" 287 sFILE="" 288 if [ -L /dev/disk/by-uuid/${UUID} ]; then 289 LogText "Result: found disk via /dev/disk/by-uuid listing" 290 ShowSymlinkPath /dev/disk/by-uuid/${UUID} 291 if [ -n "${sFILE}" ]; then 292 REAL="${sFILE}" 293 LogText "Result: disk is ${REAL}" 294 fi 295 else 296 LogText "Result: no symlink found to /dev/disk/by-uuid/${UUID}" 297 fi 298 fi 299 fi 300 # Set real device 301 if [ -z "${REAL}" ]; then 302 REAL="${I}" 303 fi 304 Report "swap_partition[]=${I},${REAL}," 305 done 306 if [ ${FOUND} -eq 1 ]; then 307 Display --indent 2 --text "- Query swap partitions (fstab)" --result "${STATUS_OK}" --color GREEN 308 else 309 Display --indent 2 --text "- Query swap partitions (fstab)" --result "${STATUS_NONE}" --color YELLOW 310 LogText "Result: no swap partitions found in /etc/fstab" 311 fi 312 fi 313# 314################################################################################# 315# 316 # Test : FILE-6336 317 # Description : Check swap mount options 318 # Examples : [partition] swap swap defaults 0 0 319 # [partition] none swap sw 0 0 320 if [ -f /etc/fstab ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 321 Register --test-no FILE-6336 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking swap mount options" 322 if [ ${SKIPTEST} -eq 0 ]; then 323 # Swap partitions should be mounted with 'sw' or 'swap' 324 LogText "Test: check swap partitions with incorrect mount options" 325 FIND=$(${AWKBINARY} '{ if ($3=="swap" && ($4!~/sw/ && $4!="defaults")) { print $1 }}' /etc/fstab) 326 if [ -z "${FIND}" ]; then 327 Display --indent 2 --text "- Testing swap partitions" --result "${STATUS_OK}" --color GREEN 328 LogText "Result: all swap partitions have correct options (sw or swap)" 329 else 330 Display --indent 2 --text "- Testing swap partitions" --result "${STATUS_CHECK_NEEDED}" --color YELLOW 331 LogText "Result: possible incorrect mount options used for mounting swap partition (${FIND})" 332 #ReportWarning "${TEST_NO}" "Possible incorrect mount options used for swap partition (${FIND})" 333 ReportSuggestion "${TEST_NO}" "Check your /etc/fstab file for swap partition mount options" 334 LogText "Notes: usually swap partition have 'sw' or 'swap' in the options field (4th)" 335 fi 336 fi 337# 338################################################################################# 339# 340 # Test : FILE-6344 341 # Description : Check proc mount options (Linux >=3.3 only) 342 # hidepid textual values available kernel >= 5.8 only) 343 # Examples : proc /proc proc defaults,hidepid=2 0 0 344 # Goal : Users should not be able to see processes of other users 345 if [ "${OS}" = "Linux" -a -f ${ROOTDIR}proc/version ]; then 346 LINUX_KERNEL_MAJOR=$(echo $OS_KERNELVERSION | ${AWKBINARY} -F. '{print $1}') 347 LINUX_KERNEL_MINOR=$(echo $OS_KERNELVERSION | ${AWKBINARY} -F. '{print $2}') 348 if [ -n "${LINUX_KERNEL_MAJOR}" -a -n "${LINUX_KERNEL_MINOR}" ]; then 349 if [ ${LINUX_KERNEL_MAJOR} -ge 3 -a ${LINUX_KERNEL_MINOR} -ge 3 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 350 else 351 PREQS_MET="NO"; 352 fi 353 fi 354 Register --test-no FILE-6344 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking proc mount options" 355 if [ ${SKIPTEST} -eq 0 ]; then 356 # Proc should be mounted with 'hidepid=2' or 'hidepid=1' at least 357 # https://www.kernel.org/doc/html/latest/filesystems/proc.html#chapter-4-configuring-procfs 358 LogText "Test: check proc mount with incorrect mount options" 359 FIND=$(${MOUNTBINARY} | ${EGREPBINARY} "${ROOTDIR}proc " | ${EGREPBINARY} -o "hidepid=([0-9]|[a-z][a-z]*)") 360 if [ "${FIND}" = "hidepid=4" -o "${FIND}" = "hidepid=ptraceable" ]; then # https://lwn.net/Articles/817137/ 361 Display --indent 2 --text "- Testing /proc mount (hidepid)" --result "${STATUS_OK}" --color GREEN 362 LogText "Result: proc mount mounted with ${FIND}" 363 AddHP 3 3 364 elif [ "${FIND}" = "hidepid=2" -o "${FIND}" = "hidepid=invisible" ]; then 365 Display --indent 2 --text "- Testing /proc mount (hidepid)" --result "${STATUS_OK}" --color GREEN 366 LogText "Result: proc mount mounted with ${FIND}" 367 AddHP 3 3 368 elif [ "${FIND}" = "hidepid=1" -o "${FIND}" = "hidepid=noaccess" ]; then 369 Display --indent 2 --text "- Testing /proc mount (hidepid)" --result "${STATUS_OK}" --color GREEN 370 LogText "Result: proc mount mounted with ${FIND}" 371 AddHP 2 3 372 elif [ -z "${FIND}" ]; then 373 # HIDEPID1_SUGGESTION=" (or at least hidepid=1)" 374 AddHP 0 3 375 Display --indent 2 --text "- Testing /proc mount (hidepid)" --result "${STATUS_SUGGESTION}" --color YELLOW 376 LogText "Result: /proc filesystem is not mounted with option hidepid=1 or hidepid=2" 377 # TODO ReportSuggestion "${TEST_NO}" "Consider mounting /proc via /etc/fstab with mount option hidepid=2" "/proc" "-" 378 fi 379 fi 380# 381################################################################################# 382# 383 # Test : FILE-6354 384 # Description : Search files within /tmp which are older than 3 months 385 if [ -d ${ROOTDIR}tmp ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 386 Register --test-no FILE-6354 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Searching for old files in /tmp" 387 if [ ${SKIPTEST} -eq 0 ]; then 388 LogText "Test: Searching for old files in ${ROOTDIR}tmp" 389 # Search for files only in ${ROOTDIR}tmp, with an access time older than X days 390 FIND=$(${FINDBINARY} ${ROOTDIR}tmp -xdev -type f -atime +${TMP_OLD_DAYS} 2> /dev/null | ${SEDBINARY} 's/ /!space!/g') 391 if IsEmpty "${FIND}"; then 392 Display --indent 2 --text "- Checking for old files in ${ROOTDIR}tmp" --result "${STATUS_OK}" --color GREEN 393 LogText "Result: no files found in ${ROOTDIR}tmp which are older than 3 months" 394 else 395 Display --indent 2 --text "- Checking for old files in ${ROOTDIR}tmp" --result "${STATUS_FOUND}" --color RED 396 COUNT=0 397 for ITEM in ${FIND}; do 398 FILE=$(echo ${ITEM} | ${SEDBINARY} 's/!space!/ /g') 399 LogText "Old temporary file: ${FILE}" 400 COUNT=$((COUNT + 1)) 401 done 402 LogText "Result: found old files in ${ROOTDIR}tmp, which were not modified in the last ${TMP_OLD_DAYS} days" 403 LogText "Advice: check and clean up unused files in ${ROOTDIR}tmp. Old files can fill up a disk or contain" 404 LogText "private information and should be deleted it not being used actively. Use a tool like lsof to" 405 LogText "see which programs possibly are using a particular file. Some systems can cleanup temporary" 406 LogText "directories by setting a boot option." 407 ReportSuggestion "${TEST_NO}" "Check ${COUNT} files in ${ROOTDIR}tmp which are older than ${TMP_OLD_DAYS} days" 408 fi 409 fi 410# 411################################################################################# 412# 413 # Test : FILE-6362 414 # Description : Check for sticky bit on /tmp 415 if [ -d ${ROOTDIR}tmp -a ! -L ${ROOTDIR}tmp ]; then PREQS_MET="YES"; SKIPREASON=""; else PREQS_MET="NO"; SKIPREASON="No /tmp or /tmp is symlinked"; fi 416 Register --test-no FILE-6362 --preqs-met ${PREQS_MET} --skip-reason "${SKIPREASON}" --weight L --network NO --category security --description "Checking /tmp sticky bit" 417 if [ ${SKIPTEST} -eq 0 ]; then 418 # Depending on OS, number of field with 'tmp' differs 419 FIND=$(${LSBINARY} -ld ${ROOTDIR}tmp | ${AWKBINARY} '$1 ~ /[tT]/ { print 1 }') 420 if [ "${FIND}" = "1" ]; then 421 Display --indent 2 --text "- Checking ${ROOTDIR}tmp sticky bit" --result "${STATUS_OK}" --color GREEN 422 LogText "Result: sticky bit found on ${ROOTDIR}tmp directory" 423 AddHP 3 3 424 else 425 Display --indent 2 --text "- Checking ${ROOTDIR}tmp sticky bit" --result "${STATUS_WARNING}" --color RED 426 ReportSuggestion "${TEST_NO}" "Set the sticky bit on ${ROOTDIR}tmp, to prevent users deleting (by other owned) files in the /tmp directory." "/tmp" "text:Set sticky bit" 427 AddHP 0 3 428 fi 429 unset FIND 430 else 431 LogText "Result: Sticky bit test (on /tmp) skipped. Possible reason: missing directory, or symlinked directory, or test skipped." 432 fi 433# 434################################################################################# 435# 436 # Test : FILE-6363 437 # Description : Check for sticky bit on /var/tmp 438 if [ -d ${ROOTDIR}var/tmp -a ! -L ${ROOTDIR}var/tmp ]; then PREQS_MET="YES"; SKIPREASON=""; else PREQS_MET="NO"; SKIPREASON="No /var/tmp or /var/tmp is symlinked"; fi 439 Register --test-no FILE-6363 --preqs-met ${PREQS_MET} --skip-reason "${SKIPREASON}" --weight L --network NO --category security --description "Checking /var/tmp sticky bit" 440 if [ ${SKIPTEST} -eq 0 ]; then 441 # Depending on OS, number of field with 'tmp' differs 442 FIND=$(${LSBINARY} -ld ${ROOTDIR}var/tmp | ${AWKBINARY} '$1 ~ /[tT]/ { print 1 }') 443 if [ "${FIND}" = "1" ]; then 444 Display --indent 2 --text "- Checking ${ROOTDIR}var/tmp sticky bit" --result "${STATUS_OK}" --color GREEN 445 LogText "Result: sticky bit found on ${ROOTDIR}var/tmp directory" 446 AddHP 3 3 447 else 448 Display --indent 2 --text "- Checking ${ROOTDIR}var/tmp sticky bit" --result "${STATUS_WARNING}" --color RED 449 ReportSuggestion "${TEST_NO}" "Set the sticky bit on ${ROOTDIR}var/tmp, to prevent users deleting (by other owned) files in the /var/tmp directory." "/var/tmp" "text:Set sticky bit" 450 AddHP 0 3 451 fi 452 unset FIND 453 else 454 LogText "Result: Sticky bit test (on /var/tmp) skipped. Possible reason: missing directory, or symlinked directory, or test skipped." 455 fi 456# 457################################################################################# 458# 459 # Test : FILE-6366 460 # Description : Check for noatime option 461 # More info : especially useful for profile 'desktop' and 'server-storage' 462 463 # Want to contribute to Lynis? Create this test 464 465# 466################################################################################# 467# 468 # Test : FILE-6368 469 # Description : Checking Linux root file system ACL support 470 Register --test-no FILE-6368 --os Linux --weight L --network NO --root-only YES --category security --description "Checking ACL support on root file system" 471 if [ ${SKIPTEST} -eq 0 ]; then 472 FOUND=0 473 LogText "Test: Checking acl option on ext[2-4] root file system" 474 FIND=$(${MOUNTBINARY} | ${AWKBINARY} '{ if ($3=="/" && $5~/ext[2-4]/) { print $6 } }' | ${GREPBINARY} acl) 475 if [ -n "${FIND}" ]; then 476 LogText "Result: found ACL option" 477 FOUND=1 478 else 479 LogText "Result: mount point probably mounted with defaults" 480 LogText "Test: Checking device which holds root file system" 481 # Get device on which root file system is mounted. Use /dev/root if it exists, or 482 # else check output of mount 483 if [ -b ${ROOTDIR}dev/root ]; then 484 FIND1="${ROOTDIR}dev/root" 485 else 486 # Only determine device if it is EXT2/3/4 487 #FIND1=$(mount | ${GREPBINARY} "on / " | ${AWKBINARY} '{ if ($5~/ext[2-4]/) { print $1 }}') 488 FIND1=$(${MOUNTBINARY} -t ext2,ext3,ext4 | ${GREPBINARY} "on / " | ${AWKBINARY} '{ print $1 }') 489 fi 490 # Trying to determine default mount options from EXT2/EXT3/EXT4 file systems 491 if [ -n "${FIND1}" ]; then 492 LogText "Result: found ${FIND1}" 493 LogText "Test: Checking default options on ${FIND1}" 494 FIND2=$(${TUNE2FSBINARY} -l ${FIND1} 2> /dev/null | ${GREPBINARY} "^Default mount options" | ${GREPBINARY} "acl") 495 if [ -n "${FIND2}" ]; then 496 LogText "Result: found ACL option in default mount options" 497 FOUND=1 498 else 499 LogText "Result: no ACL option found in default mount options list" 500 fi 501 else 502 LogText "Result: No file system found with root file system" 503 fi 504 fi 505 506 LogText "Test: Checking acl option on xfs root file system" 507 FIND=$(${MOUNTBINARY} | ${AWKBINARY} '{ if ($3=="/" && $5~/xfs/) { print $6 } }' | ${EGREPBINARY} 'no_acl|no_user_xattr') 508 if [ -z "${FIND}" ]; then 509 FOUND=1 510 # some other tests to do ? 511 fi 512 513 if [ ${FOUND} -eq 0 ]; then 514 LogText "Result: ACL option NOT enabled on root file system" 515 LogText "Additional information: if file access need to be more restricted, ACLs could be used. Install the acl utilities and remount the file system with the acl option" 516 LogText "Activate acl support on and active file system with mount -o remount,acl / and add the acl option to the fstab file" 517 Display --indent 2 --text "- ACL support root file system" --result "${STATUS_DISABLED}" --color YELLOW 518 AddHP 0 1 519 else 520 LogText "Result: ACL option enabled on root file system" 521 Display --indent 2 --text "- ACL support root file system" --result "${STATUS_ENABLED}" --color GREEN 522 AddHP 3 3 523 fi 524 fi 525# 526################################################################################# 527# 528 # Test : FILE-6372 529 # Description : Check / mount options for Linux 530 # Notes : 531 Register --test-no FILE-6372 --os Linux --weight L --network NO --category security --description "Checking / mount options" 532 if [ ${SKIPTEST} -eq 0 ]; then 533 if [ -f ${ROOTDIR}etc/fstab ]; then 534 FIND=$(${GREPBINARY} -w "/" ${ROOTDIR}etc/fstab | ${GREPBINARY} -v "^#" | ${CUTBINARY} -f1 -d"#" | ${AWKBINARY} '{ if ($2=="/") { print $4 }}') 535 NODEV=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ "nodev") { print "YES" } else { print "NO" } }') 536 NOEXEC=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ "noexec") { print "YES" } else { print "NO" } }') 537 NOSUID=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ "nosuid") { print "YES" } else { print "NO" } }') 538 539 if [ -n "${FIND}" ]; then 540 LogText "Result: mount system / is configured with options: ${FIND}" 541 if [ "${FIND}" = "defaults" ]; then 542 Display --indent 2 --text "- Mount options of /" --result "${STATUS_OK}" --color GREEN 543 else 544 Display --indent 2 --text "- Mount options of /" --result "${STATUS_NON_DEFAULT}" --color YELLOW 545 fi 546 else 547 LogText "Result: no mount point / or expected options found" 548 fi 549 fi 550 fi 551# 552################################################################################# 553# 554 # Test : FILE-6374 555 # Description : Check mount options for Linux 556 # Notes : This test determines if the mount point exists. If it does not exist as mount point, yet it is an directory, 557 # you might consider to make it a separate mount point with restrictions. 558 # 559 # Depending on the primary goals of a machine, some mount points might be too restrictive. Before applying any 560 # mount flags, test them on a similar or cloned test system. 561 # 562 # --------------------------------------------------------- 563 # Mount point nodev noexec nosuid 564 # /boot v v v 565 # /dev v v 566 # /dev/shm v v v 567 # /home v v 568 # /run v v 569 # /tmp v v v 570 # /var v v 571 # /var/log v v v 572 # /var/log/audit v v v 573 # /var/tmp v v v 574 # --------------------------------------------------------- 575 576 FILESYSTEMS_TO_CHECK="/boot:nodev,noexec,nosuid /dev:noexec,nosuid /dev/shm:nosuid,nodev,noexec /home:nodev,nosuid /run:nodev,nosuid /tmp:nodev,noexec,nosuid /var:nodev,nosuid /var/log:nodev,noexec,nosuid /var/log/audit:nodev,noexec,nosuid /var/tmp:nodev,noexec,nosuid" 577 Register --test-no FILE-6374 --os Linux --weight L --network NO --category security --description "Linux mount options" 578 if [ ${SKIPTEST} -eq 0 ]; then 579 if [ -f ${ROOTDIR}etc/fstab ]; then 580 for I in ${FILESYSTEMS_TO_CHECK}; do 581 FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d: -f1) 582 EXPECTED_FLAGS=$(echo ${I} | ${CUTBINARY} -d: -f2 | ${SEDBINARY} 's/,/ /g') 583 FS_FSTAB=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($2==fs) { print $3 } }' ${ROOTDIR}etc/fstab) 584 if [ "${FS_FSTAB}" = "glusterfs" ]; then 585 EXPECTED_FLAGS=$(echo ${EXPECTED_FLAGS} | ${SEDBINARY} 's/\<\(nodev\|nosuid\)\> *//g') 586 if [ -z "${EXPECTED_FLAGS}" ]; then 587 FS_FSTAB="" 588 fi 589 fi 590 if [ -z "${FS_FSTAB}" ]; then # not found in fstab, check if mounted otherwise 591 FS_FSTAB=$(mount | ${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($3==fs) { print $6 } }') 592 FOUND_FLAGS=$(mount | ${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($1~"[^#]" && $3==fs) { print $6 } }' | ${SEDBINARY} 's/,/ /g' | ${TRBINARY} '\n' ' ') 593 else 594 FOUND_FLAGS=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($1~"[^#]" && $2==fs) { print $4 } }' ${ROOTDIR}etc/fstab | ${SEDBINARY} 's/,/ /g' | ${TRBINARY} '\n' ' ') 595 fi 596 if [ -n "${FS_FSTAB}" ]; then 597 # In awk using caret/circumflex as first character between brackets, means 'not' (instead of beginning of line) 598 LogText "File system: ${FILESYSTEM}" 599 LogText "Expected flags: ${EXPECTED_FLAGS}" 600 LogText "Found flags: ${FOUND_FLAGS}" 601 PARTIALLY_HARDENED=0 602 FULLY_HARDENED=1 603 for FLAG in ${EXPECTED_FLAGS}; do 604 FLAG_AVAILABLE=$(echo ${FOUND_FLAGS} | ${GREPBINARY} ${FLAG}) 605 if [ -z "${FLAG_AVAILABLE}" ]; then 606 LogText "Result: Could not find mount option ${FLAG} on file system ${FILESYSTEM}" 607 FULLY_HARDENED=0 608 else 609 LogText "Result: GOOD, found mount option ${FLAG} on file system ${FILESYSTEM}" 610 PARTIALLY_HARDENED=1 611 fi 612 done 613 if [ ${FULLY_HARDENED} -eq 1 ]; then 614 LogText "Result: marked ${FILESYSTEM} as fully hardened" 615 Display --indent 2 --text "- Mount options of ${FILESYSTEM}" --result "${STATUS_HARDENED}" --color GREEN 616 AddHP 5 5 617 elif [ ${PARTIALLY_HARDENED} -eq 1 ]; then 618 LogText "Result: marked ${FILESYSTEM} as partially hardened" 619 Display --indent 2 --text "- Mount options of ${FILESYSTEM}" --result "${STATUS_PARTIALLY_HARDENED}" --color YELLOW 620 AddHP 4 5 621 else 622 # if 623 if ContainsString "defaults" "${FOUND_FLAGS}"; then 624 LogText "Result: marked ${FILESYSTEM} options as default (not hardened)" 625 Display --indent 2 --text "- Mount options of ${FILESYSTEM}" --result "${STATUS_DEFAULT}" --color YELLOW 626 AddHP 3 5 627 else 628 LogText "Result: marked ${FILESYSTEM} options as non-default (unclear about hardening)" 629 Display --indent 2 --text "- Mount options of ${FILESYSTEM}" --result "${STATUS_NON_DEFAULT}" --color YELLOW 630 AddHP 4 5 631 fi 632 fi 633 else 634 LogText "Result: file system ${FILESYSTEM} not found in ${ROOTDIR}etc/fstab" 635 fi 636 done 637 fi 638 NMOUNTS=$(mount | ${WCBINARY} -l) 639 NDEVMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v nodev | ${WCBINARY} -l) 640 NEXECMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v noexec | ${WCBINARY} -l) 641 NSUIDMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v nosuid | ${WCBINARY} -l) 642 NWRITEANDEXECMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v noexec | ${EGREPBINARY} -v '^\(ro[,)]' | ${WCBINARY} -l) 643 LogText "Result: Total without nodev:${NDEVMOUNTS} noexec:${NEXECMOUNTS} nosuid:${NSUIDMOUNTS} ro or noexec (W^X): ${NWRITEANDEXECMOUNTS}, of total ${NMOUNTS}" 644 Display --indent 2 --text "- Total without nodev:${NDEVMOUNTS} noexec:${NEXECMOUNTS} nosuid:${NSUIDMOUNTS} ro or noexec (W^X): ${NWRITEANDEXECMOUNTS} of total ${NMOUNTS}" 645 fi 646# 647################################################################################# 648# 649 # Test : FILE-6376 650 # Description : Bind mount the /var/tmp directory to /tmp 651 Register --test-no FILE-6376 --os Linux --weight L --network NO --category security --description "Determine if /var/tmp is bound to /tmp" 652 if [ ${SKIPTEST} -eq 0 ]; then 653 if [ -f ${ROOTDIR}etc/fstab ]; then 654 FIND=$(${AWKBINARY} '{ if ($2=="/var/tmp") { print $4 } }' ${ROOTDIR}etc/fstab) 655 BIND=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ "bind") { print "YES" } else { print "NO" } }') 656 if [ -n "${FIND}" ]; then 657 LogText "Result: mount system /var/tmp is configured with options: ${FIND}" 658 if [ "${BIND}" = "YES" ]; then 659 Display --indent 2 --text "- /var/tmp is bound to /tmp" --result "${STATUS_OK}" --color GREEN 660 LogText "Result : /var/tmp is bind to /tmp" 661 else 662 Display --indent 2 --text "- /var/tmp is not bound to /tmp" --result "${STATUS_NON_DEFAULT}" --color YELLOW 663 LogText "Result: /var/tmp is not bind to /tmp" 664 fi 665 else 666 LogText "Result: no mount point /var/tmp or expected options found" 667 if IsVerbose; then Display --indent 2 --text "- /var/tmp is not bound to /tmp" --result "INFO" --color WHITE; fi 668 fi 669 fi 670 fi 671# 672################################################################################# 673# 674 # Test : FILE-6378 TODO 675 # Description : Check for nodirtime option 676 677 # Want to contribute to Lynis? Create this test 678# 679################################################################################# 680# 681 # Test : FILE-6380 TODO 682 # Description : Check for relatime 683 684 # Want to contribute to Lynis? Create this test 685# 686################################################################################# 687# 688 # Test : FILE-6390 TODO 689 # Description : Check writeback/journalling mode (ext3) 690 # More info : data=writeback | data=ordered | data=journal 691 692 # Want to contribute to Lynis? Create this test 693 694# 695################################################################################# 696# 697 # Test : FILE-6394 698 # Description : Check vm.swappiness (Linux) 699 Register --test-no FILE-6394 --os Linux --weight L --network NO --category security --description "Determine level of swappiness." 700 if [ ${SKIPTEST} -eq 0 ]; then 701 SWAPLEVEL=$(${CAT_BINARY} /proc/sys/vm/swappiness) 702 LogText "Test: checking level of vm.swappiness: ${SWAPLEVEL}" 703 PHYSDISK=$(${LSBLKBINARY} | ${GREPBINARY} -E 'disk|SWAP' | ${GREPBINARY} -B1 SWAP | ${HEADBINARY} -n1 | ${AWKBINARY} '{print $1}') 704 if [ ${SWAPLEVEL} -gt 60 ]; then 705 LogText "Result: vm.swappiness=${SWAPLEVEL} meaning that swapping is more frequent than default." 706 # Check if swap is on a HDD or SDD for frequent swapping 707 if [ -d "/sys/block/${PHYSDISK}" ]; then 708 HDDORSDD=$(${CAT_BINARY} "/sys/block/${PHYSDISK}/queue/rotational") 709 if [ ${HDDORSDD} -eq 1 ]; then 710 ReportSuggestion "${TEST_NO}" "vm.swappiness set to: ${SWAPLEVEL} > 60 (default) - consider installing an SSD for swap partition for better performance." 711 fi 712 fi 713 elif [ ${SWAPLEVEL} -eq 0 ]; then 714 LogText "Result: vm.swappiness=${SWAPLEVEL} meaning swapping is disabled." 715 ReportSuggestion "${TEST_NO}" "vm.swappiness set to: ${SWAPLEVEL}. Consider setting value to minimum of 1 for minimizing swappiness, but not quite disabling it. Will prevent OOM killer from killing processes when running out of physical memory." 716 elif [ ${SWAPLEVEL} -eq 1 ]; then 717 LogText "Result: vm.swappiness=${SWAPLEVEL} meaning that swapping can still occur but at very minimum." 718 elif [ ${SWAPLEVEL} -eq 10 ]; then 719 LogText "Result: vm.swappiness=${SWAPLEVEL} which is the preferred setting for database servers." 720 elif [ ${SWAPLEVEL} -lt 60 ]; then 721 LogText "Result: vm.swappiness=${SWAPLEVEL} meaning that swapping is less frequent than default. This is only recommended for servers." 722 else 723 LogText "Result: vm.swappiness=${SWAPLEVEL} which is the standard level of swappiness and works well for desktop systems." 724 fi 725 if IsVerbose; then Display --indent 2 --text "- Swappiness: ${SWAPLEVEL}" --result "INFO" --color WHITE; fi 726 fi 727# 728################################################################################# 729# 730 # Test : FILE-6398 TODO 731 # Description : Check if JBD (Journal Block Device) driver is loaded 732 733 # Want to contribute to Lynis? Create this test 734 735# 736################################################################################# 737# 738 # Test : FILE-6410 739 # Description : Checking locate database (file index) 740 # Notes : Linux /var/lib/mlocate/mlocate.db or /var/lib/slocate/slocate.db 741 # or /var/cache/locate/locatedb 742 # FreeBSD /var/db/locate.database 743 if [ ! "${LOCATEBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 744 Register --test-no FILE-6410 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --category security --description "Checking Locate database" 745 if [ ${SKIPTEST} -eq 0 ]; then 746 LogText "Test: Checking locate database" 747 FOUND=0 748 LOCATE_DBS="${ROOTDIR}var/lib/mlocate/mlocate.db ${ROOTDIR}var/lib/locate/locatedb ${ROOTDIR}var/lib/locatedb ${ROOTDIR}var/lib/slocate/slocate.db ${ROOTDIR}var/cache/locate/locatedb ${ROOTDIR}var/db/locate.database" 749 for FILE in ${LOCATE_DBS}; do 750 if [ -f ${FILE} ]; then 751 LogText "Result: locate database found (${FILE})" 752 FOUND=1 753 LOCATE_DB="${FILE}" 754 else 755 LogText "Result: file ${FILE} not found" 756 fi 757 done 758 if [ ${FOUND} -eq 1 ]; then 759 Display --indent 2 --text "- Checking Locate database" --result "${STATUS_FOUND}" --color GREEN 760 Report "locate_db=${LOCATE_DB}" 761 else 762 LogText "Result: database not found" 763 Display --indent 2 --text "- Checking Locate database" --result "${STATUS_NOT_FOUND}" --color YELLOW 764 ReportSuggestion "${TEST_NO}" "The database required for 'locate' could not be found. Run 'updatedb' or 'locate.updatedb' to create this file." 765 fi 766 fi 767# 768################################################################################# 769# 770 # Test : FILE-6420 TODO 771 # Description : Check automount process 772 773 # Want to contribute to Lynis? Create this test 774 775# 776################################################################################# 777# 778 # Test : FILE-6422 TODO 779 # Description : Check automount maps (files or for example LDAP based) 780 # Notes : Warn when automounter is running 781 782 # Want to contribute to Lynis? Create this test 783 784# 785################################################################################# 786# 787 # Test : FILE-6424 TODO 788 # Description : Check automount map files 789 790 # Want to contribute to Lynis? Create this test 791 792# 793################################################################################# 794# 795 # Test : FILE-6425 TODO 796 # Description : Check mounted files systems via automounter 797 # Notes : Warn when no systems are mounted? 798 799 # Want to contribute to Lynis? Create this test 800 801# 802################################################################################# 803# 804 # Test : FILE-6430 805 # Description : Disable mounting of some filesystems 806 # Rationale : Unless there is a specific reason to use a particular file system, disable it. 807 # Data : cramfs freevxfs hfs hfsplus jffs2 squashfs udf 808 Register --test-no FILE-6430 --weight L --network NO --category security --description "Disable mounting of some filesystems" 809 if [ ${SKIPTEST} -eq 0 ]; then 810 if [ -n "${LSMODBINARY}" -a -f /proc/modules ]; then 811 Display --indent 2 --text "- Disable kernel support of some filesystems" 812 LIST_FS_NOT_SUPPORTED="cramfs freevxfs hfs hfsplus jffs2 squashfs udf" 813 FOUND=0 814 AVAILABLE_FS="" 815 AVAILABLE_MODPROBE_FS="" 816 for FS in ${LIST_FS_NOT_SUPPORTED}; do 817 # Check if filesystem is present in modprobe output 818 FIND=$(${MODPROBEBINARY} -v -n ${FS} 2>/dev/null | ${EGREPBINARY} "/${FS}.ko" | ${TAILBINARY} -1) 819 if [ -n "${FIND}" ]; then 820 LogText "Result: found ${FS} support in the kernel (output = ${FIND})" 821 Debug "Module ${FS} present in the kernel" 822 LogText "Test: Checking if ${FS} is active" 823 # Check if FS is present in lsmod output 824 FIND=$(${LSMODBINARY} | ${EGREPBINARY} "^${FS}") 825 if IsEmpty "${FIND}"; then 826 LogText "Result: module ${FS} is currently not loaded in the kernel." 827 AddHP 2 3 828 if IsDebug; then Display --indent 6 --text "- Module ${FS} not loaded (lsmod)" --result OK --color GREEN; fi 829 else 830 LogText "Result: module ${FS} is loaded in the kernel" 831 Display --indent 4 --text "- Module $FS loaded in the kernel (lsmod)" --result "FOUND" --color WHITE 832 FOUND=1 833 AVAILABLE_MODPROBE_FS="${AVAILABLE_MODPROBE_FS}${FS} " 834 fi 835 else 836 AddHP 3 3 837 if IsDebug; then Display --indent 6 --text "- Module ${FS} not present in the kernel" --result OK --color GREEN; fi 838 fi 839 FIND=$(${LSBINARY} ${ROOTDIR}etc/modprobe.d/* 2> /dev/null) 840 if [ -n "${FIND}" ]; then 841 FIND1=$(${EGREPBINARY} "blacklist ${FS}" ${ROOTDIR}etc/modprobe.d/* | ${GREPBINARY} -v "#") 842 FIND2=$(${EGREPBINARY} "install ${FS} /bin/true" ${ROOTDIR}etc/modprobe.d/* | ${GREPBINARY} -v "#") 843 if [ -n "${FIND1}" ] || [ -n "${FIND2}" ]; then 844 Display --indent 4 --text "- Module $FS is blacklisted" --result "OK" --color GREEN 845 LogText "Result: module ${FS} is blacklisted" 846 fi 847 fi 848 done 849 if [ ${FOUND} -eq 1 ]; then 850 Display --indent 4 --text "- Discovered kernel modules: ${AVAILABLE_MODPROBE_FS}" 851 ReportSuggestion "${TEST_NO}" "Consider disabling unused kernel modules" "/etc/modprobe.d/blacklist.conf" "Add 'install MODULENAME /bin/true' (without quotes)" 852 fi 853 else 854 LogText "Test skipped lsmod binary not found or /proc/modules can not be opened" 855 fi 856 unset AVAILABLE_FS AVAILABLE_MODPROBE_FS 857 fi 858# 859################################################################################# 860# 861 862WaitForKeyPress 863 864# 865#================================================================================ 866# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com 867