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 ANSIBLE_ARTIFACT_FOUND=0 22 AUTOMATION_TOOL_FOUND=0 23 AUTOMATION_TOOL_RUNNING="" 24 CFENGINE_AGENT_FOUND=0 25 CFENGINE_SERVER_RUNNING=0 26 BACKUP_AGENT_FOUND=0 27 PUPPET_MASTER_RUNNING=0 28 SALT_MASTER_RUNNING=0 29 SALT_MINION_RUNNING=0 30 IDS_IPS_TOOL_FOUND=0 31 FAIL2BAN_FOUND=0 32 FAIL2BAN_EMAIL=0 33 FAIL2BAN_SILENT=0 34 PERFORM_FAIL2BAN_TESTS=0 35 SNORT_FOUND=0 36 SNORT_RUNNING=0 37# 38################################################################################# 39# 40 InsertSection "${SECTION_SYSTEM_TOOLING}" 41# 42################################################################################# 43# 44# Automation 45# 46################################################################################# 47# 48 # Test : TOOL-5002 49 # Description : Check if automation tools are found 50 Register --test-no TOOL-5002 --weight L --network NO --category security --description "Checking for automation tools" 51 if [ ${SKIPTEST} -eq 0 ]; then 52 53 Display --indent 2 --text "- Checking automation tooling" 54 55 # Ansible 56 FOUND=0 57 LIST="${HOME}/.ansible ${ROOTDIR}etc/ansible ${ROOTDIR}root/.ansible ${ROOTDIR}tmp/.ansible" 58 for ITEM in ${LIST}; do if DirectoryExists ${ITEM}; then FOUND=1; break; fi; done 59 # Test for files (only if no match was found) 60 if [ ${FOUND} -eq 0 ]; then 61 LIST="${ROOTDIR}var/log/ansible.log ~/.ansible-retry" 62 for ITEM in ${LIST}; do if FileExists ${ITEM}; then FOUND=1; break; fi; done 63 fi 64 65 if [ ${FOUND} -eq 1 ]; then 66 LogText "Result: found a possible trace of Ansible" 67 AUTOMATION_TOOL_FOUND=1 68 ANSIBLE_ARTIFACT_FOUND=1 69 Report "automation_tool_running[]=ansible" 70 Display --indent 4 --text "- Ansible artifact" --result "${STATUS_FOUND}" --color GREEN 71 fi 72 73 # Cfengine 74 if [ -n "${CFAGENTBINARY}" ]; then 75 LogText "Result: CFEngine (cfagent) is installed (${CFAGENTBINARY})" 76 AUTOMATION_TOOL_FOUND=1 77 CFENGINE_AGENT_FOUND=1 78 Report "automation_tool_running[]=cf-agent" 79 Display --indent 4 --text "- Cfengine (cfagent)" --result "${STATUS_FOUND}" --color GREEN 80 fi 81 OTHER_CFENGINE_LOCATIONS="/var/cfengine/bin /var/rudder/cfengine-community/bin" 82 for I in ${OTHER_CFENGINE_LOCATIONS}; do 83 if [ -d ${I} ]; then 84 if [ -f ${I}/cf-agent ]; then 85 LogText "Result: found CFEngine agent (cf-agent) in ${I}" 86 AUTOMATION_TOOL_FOUND=1 87 CFENGINE_AGENT_FOUND=1 88 Report "automation_tool_running[]=cf-agent" 89 Display --indent 4 --text "- CFEngine (cf-agent)" --result "${STATUS_FOUND}" --color GREEN 90 fi 91 if IsRunning "cf-server"; then 92 LogText "Result: found CFEngine server" 93 AUTOMATION_TOOL_FOUND=1 94 CFENGINE_SERVER_RUNNING=1 95 Report "automation_tool_running[]=cf-server" 96 Display --indent 4 --text "- CFEngine (cf-server)" --result "${STATUS_FOUND}" --color GREEN 97 fi 98 fi 99 done 100 101 # Chef 102 CHEF_LOCATIONS="/opt/chef/bin /opt/chef-server/sv /opt/chefdk/bin" 103 for I in ${CHEF_LOCATIONS}; do 104 if [ -d ${I} ]; then 105 if [ -f ${I}/chef-client ]; then 106 CHEFCLIENTBINARY="${I}/chef-client" 107 AUTOMATION_TOOL_FOUND=1 108 Report "automation_tool_running[]=chef-client" 109 Display --indent 4 --text "- Chef client (chef-client)" --result "${STATUS_FOUND}" --color GREEN 110 LogText "Result: found chef-client (chef client daemon) in ${I}" 111 fi 112 if [ -f ${I}/erchef ]; then 113 CHEFSERVERBINARY="${I}/erchef" 114 LogText "Result: Chef Server (erchef) is installed (${CHEFSERVERBINARY})" 115 AUTOMATION_TOOL_FOUND=1 116 Report "automation_tool_running[]=chef-server" 117 Display --indent 4 --text "- Chef Server (erchef)" --result "${STATUS_FOUND}" --color GREEN 118 LogText "Result: found erchef (chef server daemon) in ${I}" 119 fi 120 fi 121 done 122 123 # Puppet 124 125 # Check for Puppet installation provided by Puppetlabs package 126 if [ -z "${PUPPETBINARY}" ]; then 127 if [ -f ${ROOTDIR}opt/puppetlabs/puppet/bin/puppet ]; then 128 PUPPETBINARY="${ROOTDIR}opt/puppetlabs/puppet/bin/puppet" 129 fi 130 fi 131 132 if [ -n "${PUPPETBINARY}" ]; then 133 LogText "Result: Puppet is installed (${PUPPETBINARY})" 134 AUTOMATION_TOOL_FOUND=1 135 Report "automation_tool_running[]=puppet-agent" 136 Display --indent 4 --text "- Puppet (agent)" --result "${STATUS_FOUND}" --color GREEN 137 fi 138 139 if IsRunning --full "puppet master"; then 140 LogText "Result: found puppet master" 141 AUTOMATION_TOOL_FOUND=1 142 PUPPET_MASTER_RUNNING=1 143 Report "automation_tool_running[]=puppet-master" 144 Display --indent 4 --text "- Puppet (master)" --result "${STATUS_FOUND}" --color GREEN 145 fi 146 147 # SaltStack 148 if [ -n "${SALTMINIONBINARY}" ]; then 149 Display --indent 4 --text "- SaltStack minion" --result "${STATUS_FOUND}" --color GREEN 150 LogText "Result: SaltStack (salt-minion) is installed (${SALTMINIONBINARY})" 151 AUTOMATION_TOOL_FOUND=1 152 Report "automation_tool_installed[]=saltstack-minion" 153 154 if IsRunning "salt-minion" --user "root salt"; then 155 Display --indent 6 --text "- Minion process" --result "${STATUS_RUNNING}" --color GREEN 156 LogText "Result: found SaltStack (master)" 157 SALT_MINION_RUNNING=1 158 Report "automation_tool_running[]=saltstack-minion" 159 else 160 Display --indent 6 --text "- Minion process" --result "${STATUS_NOT_RUNNING}" --color YELLOW 161 fi 162 163 fi 164 165 if [ -n "${SALTMASTERBINARY}" ]; then 166 Display --indent 4 --text "- SaltStack master (salt-master)" --result "${STATUS_FOUND}" --color GREEN 167 LogText "Result: SaltStack (salt-master) is installed (${SALTMASTERBINARY})" 168 AUTOMATION_TOOL_FOUND=1 169 Report "automation_tool_installed[]=saltstack-master" 170 171 if IsRunning "salt-master" --user "root salt"; then 172 Display --indent 6 --text "- Master process" --result "${STATUS_RUNNING}" --color GREEN 173 LogText "Result: found SaltStack (master)" 174 SALT_MASTER_RUNNING=1 175 Report "automation_tool_running[]=saltstack-master" 176 else 177 Display --indent 6 --text "- Master process" --result "${STATUS_NOT_RUNNING}" --color YELLOW 178 fi 179 fi 180 181 if [ ${AUTOMATION_TOOL_FOUND} -eq 1 ]; then 182 Display --indent 2 --text "- Automation tooling" --result "${STATUS_FOUND}" --color GREEN 183 else 184 Display --indent 2 --text "- Automation tooling" --result "${STATUS_NOT_FOUND}" --color YELLOW 185 ReportSuggestion "${TEST_NO}" "Determine if automation tools are present for system management" 186 fi 187 fi 188# 189################################################################################# 190# 191# Intrusion Detection and Prevention tools 192# 193################################################################################# 194# 195 # Test : TOOL-5102 196 # Description : Check for Fail2ban 197 Register --test-no TOOL-5102 --weight L --network NO --category security --description "Check for presence of Fail2ban" 198 if [ ${SKIPTEST} -eq 0 ]; then 199 200 # Fail2ban presence 201 if [ -n "${FAIL2BANBINARY}" ]; then 202 FAIL2BAN_FOUND=1 203 IDS_IPS_TOOL_FOUND=1 204 LogText "Result: Fail2ban is installed (${FAIL2BANBINARY})" 205 Report "ids_ips_tooling[]=fail2ban" 206 Display --indent 2 --text "- Checking presence of Fail2ban" --result "${STATUS_FOUND}" --color GREEN 207 else 208 LogText "Result: Fail2ban not present (fail2ban-server not found)" 209 fi 210 211 # Fail2ban configuration 212 LogText "Checking Fail2ban configuration file" 213 if [ -f /etc/fail2ban/jail.local ]; then 214 FAIL2BAN_CONFIG="/etc/fail2ban/jail.local" 215 elif [ -f /etc/fail2ban/jail.conf ]; then 216 FAIL2BAN_CONFIG="/etc/fail2ban/jail.conf" 217 else 218 FAIL2BAN_CONFIG="" 219 fi 220 221 # Continue if tooling is available and configuration file found 222 if [ ${FAIL2BAN_FOUND} -eq 1 -a -n "${FAIL2BAN_CONFIG}" ]; then 223 Report "fail2ban_config=${FAIL2BAN_CONFIG}" 224 FAIL2BANCLIENT=$(which fail2ban-client 2> /dev/null | grep -v "no [^ ]* in ") 225 if [ -n "${FAIL2BANCLIENT}" ]; then PERFORM_FAIL2BAN_TESTS=1; fi 226 fi 227 fi 228# 229################################################################################# 230# 231 # Test : TOOL-5104 232 # Description : Check for Fail2ban enabled tests 233 if [ ${PERFORM_FAIL2BAN_TESTS} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi 234 Register --test-no TOOL-5104 --weight L --network NO --preqs-met ${PREQS_MET} --category security --description "Enabled tests in Fail2ban" 235 if [ ${SKIPTEST} -eq 0 ]; then 236 FIND=$(${FAIL2BANCLIENT} -d | ${TRBINARY} -d '[]' | ${TRBINARY} -d "'" | ${AWKBINARY} -F, '{ if ($1=="add") { print $2 }}' | ${TRBINARY} -d ' ') 237 if [ -n "${FIND}" ]; then 238 for F2BSERVICE in ${FIND}; do 239 LogText "Result: service '${F2BSERVICE}' enabled" 240 Report "fail2ban_enabled_service[]=${F2BSERVICE}" 241 done 242 LogText "Result: found at least one enabled jail" 243 Display --indent 4 --text "- Checking Fail2ban jails" --result "${STATUS_ENABLED}" --color GREEN 244 AddHP 3 3 245 else 246 LogText "Result: Fail2ban installed but completely disabled" 247 Display --indent 4 --text "- Checking Fail2ban jails" --result "${STATUS_DISABLED}" --color RED 248 AddHP 0 5 249 ReportWarning "${TEST_NO}" "All jails in Fail2ban are disabled" "${FAIL2BAN_CONFIG}" 250 fi 251 fi 252# 253################################################################################# 254# 255 # These tests are temporarily disabled to split them up in different areas to check 256 # 257 # LogText "Result: found configuration file (${FAIL2BAN_CONFIG})" 258 # 259 # # Check email alert configuration 260 # LogText "Test: checking for email actions within ${FAIL2BAN_CONFIG}" 261 # 262 # FIND=$(${EGREPBINARY} "^action = \%\(action_m.*\)s" ${FAIL2BAN_CONFIG}) 263 # FIND2=$(${EGREPBINARY} "^action = \%\(action_\)s" ${FAIL2BAN_CONFIG}) 264 # 265 # if [ -n "${FIND}" ]; then 266 # FAIL2BAN_EMAIL=1 267 # LogText "Result: found at least one jail which sends an email alert" 268 # fi 269 # 270 # if [ -n "${FIND2}" ]; then 271 # FAIL2BAN_SILENT=1 272 # LogText "Result: found at least one jail which does NOT send an email alert" 273 # fi 274 # 275 # if [ ${FAIL2BAN_SILENT} -eq 0 ] && [ ${FAIL2BAN_EMAIL} -eq 0 ]; then 276 # LogText "No registered actions found in ${FAIL2BAN_CONFIG}" 277 # Display --indent 4 --text "- Checking Fail2ban actions" --result "${STATUS_NONE}" --color RED 278 # ReportWarning "${TEST_NO}" "${FAIL2BAN_CONFIG}" "There are no actions configured for Fail2ban." 279 # AddHP 0 3 280 # fi 281 # 282 # if [ ${FAIL2BAN_SILENT} -eq 0 ] && [ ${FAIL2BAN_EMAIL} -eq 1 ]; then 283 # LogText "All actions in ${FAIL2BAN_CONFIG} are configured to send email alerts" 284 # Display --indent 4 --text "- Checking Fail2ban actions" --result "${STATUS_OK}" --color GREEN 285 # AddHP 3 3 286 # fi 287 # 288 # if [ ${FAIL2BAN_SILENT} -eq 1 ] && [ ${FAIL2BAN_EMAIL} -eq 1 ]; then 289 # LogText "Some actions found in ${FAIL2BAN_CONFIG} are configured to send email alerts" 290 # Display --indent 4 --text "- Checking Fail2ban actions" --result PARTIAL --color YELLOW 291 # ReportSuggestion "${TEST_NO}" "Some Fail2ban jails are configured with non-notified actions. Consider changing these to emailed alerts." 292 # AddHP 2 3 293 # fi 294 # 295 # if [ ${FAIL2BAN_SILENT} -eq 1 ] && [ ${FAIL2BAN_EMAIL} -eq 0 ]; then 296 # LogText "None of the actions found in ${FAIL2BAN_CONFIG} are configured to send email alerts" 297 # Display --indent 4 --text "- Checking Fail2ban actions" --result "${STATUS_NONE}" --color YELLOW 298 # ReportSuggestion "${TEST_NO}" "None of the Fail2ban jails are configured to send email notifications. Consider changing these to emailed alerts." 299 # AddHP 1 3 300 # fi 301 # 302 # # Check at least one enabled jail 303 # LogText "Checking for enabled jails within ${FAIL2BAN_CONFIG}" 304 # 305 # 306 # 307 # # Confirm at least one iptables chain for fail2ban 308 # 309 # LogText "Checking for fail2ban iptables chains" 310 # 311 # if [ -n "${IPTABLESBINARY}" ]; then 312 # CHECK_CHAINS=$(${IPTABLESBINARY} -L 2>&1 | ${GREPBINARY} fail2ban) 313 # if [ -n "${CHECK_CHAINS}" ]; then 314 # LogText "Result: found at least one iptables chain for fail2ban" 315 # Display --indent 4 --text "- Checking for Fail2ban iptables chain" --result "${STATUS_OK}" --color GREEN 316 # else 317 # LogText "Result: Fail2ban installed but iptables chain not present - fail2ban will not work" 318 # Display --indent 4 --text "- Checking for Fail2ban iptables chain" --result "${STATUS_WARNING}" --color RED 319 # AddHP 0 3 320 # ReportSuggestion "${TEST_NO}" "Check config to see why iptables does not have a fail2ban chain" "${FAIL2BAN_CONFIG}" 321 # fi 322 # else 323 # Display --indent 4 --text "- Checking for Fail2ban iptables chain" --result "${STATUS_WARNING}" --color RED 324 # ReportSuggestion "${TEST_NO}" "iptables doesn't seem to be installed; Fail2ban will not work. Remove Fail2ban or install iptables" "${FAIL2BAN_CONFIG}" 325 # fi 326 # fi 327 # fi 328# 329################################################################################# 330# 331 # Test : TOOL-5120 332 # Description : Check for Snort 333 Register --test-no TOOL-5120 --weight L --network NO --category security --description "Check for presence of Snort" 334 if [ ${SKIPTEST} -eq 0 ]; then 335 336 # Snort presence 337 if [ -n "${SNORTBINARY}" ]; then 338 SNORT_FOUND=1 339 IDS_IPS_TOOL_FOUND=1 340 LogText "Result: Snort is installed (${SNORTBINARY})" 341 Report "ids_ips_tooling[]=snort" 342 Display --indent 2 --text "- Checking presence of Snort" --result "${STATUS_FOUND}" --color GREEN 343 fi 344 345 if IsRunning "snort"; then 346 SNORT_FOUND=1 347 SNORT_RUNNING=1 348 SNORT_LOG=$(${PSBINARY} | ${AWKBINARY} -F-.. '/snort/ {print $4}' | ${HEADBINARY} -1) 349 else 350 LogText "Result: Snort not present (Snort not running)" 351 fi 352 fi 353# 354################################################################################# 355# 356 # Test : TOOL-5122 357 # Description : Check for Snort configuration 358 Register --test-no TOOL-5122 --weight L --network NO --category security --description "Check Snort configuration file" 359 if [ ${SKIPTEST} -eq 0 ]; then 360 361 # Continue if tooling is available and snort is running 362 if [ -n "${SNORT_FOUND}" ] || [ -n "${SNORT_RUNNING}" ]; then 363 if [ ${SNORT_FOUND} -eq 1 ] && [ ${SNORT_RUNNING} -eq 1 ]; then 364 SNORT_CONFIG=$(${PSBINARY} | ${AWKBINARY} -F-.. '/snort/ {print $3}' | ${HEADBINARY} -1) 365 if HasData "${SNORT_CONFIG}"; then 366 LogText "Result: found Snort configuration file: ${SNORT_CONFIG}" 367 Report "snort_config=${SNORT_CONFIG}" 368 fi 369 SNORT=$(which snort 2> /dev/null) 370 fi 371 fi 372 fi 373# 374################################################################################# 375# 376 # Test : TOOL-5130 377 # Description : Check for Suricata 378 Register --test-no TOOL-5130 --weight L --network NO --category security --description "Check for active Suricata daemon" 379 if [ ${SKIPTEST} -eq 0 ]; then 380 # Suricata presence 381 if [ -n "${SURICATABINARY}" ]; then 382 Report "ids_ips_tooling[]=suricata" 383 LogText "Result: Suricata is installed (${SURICATABINARY})" 384 # Suricata status 385 # Suricata sets its process name to Suricata-Main on Linux, but this might differ on other platforms, 386 # so fall back to checking the full commandline instead if the first test fails 387 if IsRunning "Suricata-Main" || IsRunning --full "${SURICATABINARY} "; then 388 # Only satisfy test TOOL-5190 if Suricata is actually running 389 IDS_IPS_TOOL_FOUND=1 390 LogText "Result: Suricata daemon is active" 391 Display --indent 2 --text "- Checking Suricata status" --result "${STATUS_RUNNING}" --color GREEN 392 else 393 LogText "Result: Suricata daemon not active" 394 Display --indent 2 --text "- Checking Suricata status" --result "${STATUS_NOT_RUNNING}" --color YELLOW 395 fi 396 else 397 LogText "Result: Suricata not installed (suricata not found)" 398 fi 399 fi 400# 401################################################################################# 402# 403 # Test : TOOL-5160 404 # Description : Check for OSSEC 405 Register --test-no TOOL-5126 --weight L --network NO --category security --description "Check for active OSSEC daemon" 406 if [ ${SKIPTEST} -eq 0 ]; then 407 # Server side 408 if IsRunning "ossec-analysisd"; then 409 IDS_IPS_TOOL_FOUND=1 410 Report "ids_ips_tooling[]=ossec" 411 Report "ids_ips_tooling[]=ossec-analysisd" 412 LogText "Result: OSSEC analysis daemon is active" 413 Display --indent 2 --text "- Checking presence of OSSEC (analysis)" --result "${STATUS_FOUND}" --color GREEN 414 else 415 LogText "Result: OSSEC analysis daemon not active" 416 fi 417 418 # Client side 419 if IsRunning "ossec-agentd"; then 420 IDS_IPS_TOOL_FOUND=1 421 Report "ids_ips_tooling[]=ossec" 422 Report "ids_ips_tooling[]=ossec-agentd" 423 LogText "Result: OSSEC agent daemon is active" 424 Display --indent 2 --text "- Checking presence of OSSEC (agent)" --result "${STATUS_FOUND}" --color GREEN 425 else 426 LogText "Result: OSSEC agent daemon not active" 427 fi 428 fi 429# 430################################################################################# 431# 432 # Test : TOOL-5190 433 # Description : Check for an IDS/IPS tool 434 Register --test-no TOOL-5190 --weight L --network NO --category security --description "Check presence of IDS/IPS tool" 435 if [ ${SKIPTEST} -eq 0 ]; then 436 437 if [ ${IDS_IPS_TOOL_FOUND} -eq 1 ]; then 438 Display --indent 2 --text "- Checking for IDS/IPS tooling" --result "${STATUS_FOUND}" --color GREEN 439 AddHP 2 2 440 else 441 Display --indent 2 --text "- Checking for IDS/IPS tooling" --result "${STATUS_NONE}" --color YELLOW 442 #ReportSuggestion "${TEST_NO}" "Install and configure automated intrusion detection/prevention tools" 443 AddHP 0 2 444 fi 445 fi 446# 447################################################################################# 448# 449# Backup tools 450# 451################################################################################# 452# 453 # Netvault 454 # Rsync in cron 455# 456################################################################################# 457# 458 Report "automation_tool_present=${AUTOMATION_TOOL_FOUND}" 459 460 461 WaitForKeyPress 462# 463#================================================================================ 464# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com 465