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