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# E-mail and messaging
22#
23#################################################################################
24#
25    InsertSection "${SECTION_EMAIL_AND_MESSAGING}"
26#
27#################################################################################
28#
29    DOVECOT_RUNNING=0
30    EXIM_RUNNING=0
31    EXIM_TYPE=""
32    IMAP_DAEMON=""
33    OPENSMTPD_RUNNING=0
34    POP3_DAEMON=""
35    POSTFIX_RUNNING=0
36    QMAIL_RUNNING=0
37    SENDMAIL_RUNNING=0
38    SMTP_DAEMON=""
39#
40#################################################################################
41#
42    # Test        : MAIL-8802
43    # Description : Check Exim process status
44    Register --test-no MAIL-8802 --weight L --network NO --category security --description "Check Exim status"
45    if [ ${SKIPTEST} -eq 0  ]; then
46        LogText "Test: check Exim status"
47        if IsRunning "exim4" || IsRunning "exim"; then
48            LogText "Result: found running Exim process"
49            Display --indent 2 --text "- Exim status" --result "${STATUS_RUNNING}" --color GREEN
50            EXIM_RUNNING=1
51            SMTP_DAEMON="exim"
52            Report "smtp_daemon[]=exim"
53        else
54            LogText "Result: no running Exim processes found"
55            if IsVerbose; then Display --indent 2 --text "- Exim status" --result "${STATUS_NOT_FOUND}" --color WHITE; fi
56        fi
57    fi
58#
59#################################################################################
60#
61    # Test        : MAIL-8804
62    # Description : Exim configuration options
63    if [ ${EXIM_RUNNING} -eq 1 -a ! "${EXIMBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
64    Register --test-no MAIL-8804 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Exim configuration options"
65    if [ ${SKIPTEST} -eq 0 -a ${EXIM_RUNNING} -eq 1 ]; then
66        LogText "Test: Exim configuration options"
67
68        EXIM_ROUTERS=$(${EXIMBINARY} -bP router_list)
69
70        unset FIND FIND2 FIND3 FIND4
71
72        # Local Only
73        FIND=$(echo "${EXIM_ROUTERS}" | ${EGREPBINARY} '^nonlocal')
74        # Internet Host
75        FIND2=$(echo "${EXIM_ROUTERS}" | ${EGREPBINARY} '^dnslookup_relay_to_domains')
76        # Smarthost or Satellite
77        FIND3=$(echo "${EXIM_ROUTERS}" | ${EGREPBINARY} '^smarthost')
78
79        if [ -n "${FIND}" ]; then
80            EXIM_TYPE="LOCAL ONLY"
81        elif [ -n "${FIND2}" ]; then
82            EXIM_TYPE="INTERNET HOST"
83        elif [ -n "${FIND3}" ]; then
84            FIND4=$(echo "${EXIM_ROUTERS}" | ${EGREPBINARY} '^hub_user_smarthost')
85            if [ -n "${FIND4}" ]; then
86                EXIM_TYPE="SATELLITE"
87            else
88                EXIM_TYPE="SMARTHOST"
89            fi
90        fi
91
92        if [ -n "${EXIM_TYPE}" ]; then
93            LogText "Result: Exim Type - ${EXIM_TYPE}"
94            Display --indent 4 --text "- Type" --result "${EXIM_TYPE}" --color GREEN
95        else
96            LogText "Result: Exim Type - Not Configured"
97            Display --indent 4 --text "- Type" --result "${STATUS_NOT_CONFIGURED}" --color WHITE
98        fi
99
100        if [ "${EXIM_TYPE}" = "INTERNET HOST" -o "${EXIM_TYPE}" = "SMARTHOST" ]; then
101            LogText "Test: Exim Public Interfaces"
102            EXIM_IP=$(${EXIMBINARY} -bP local_interfaces | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/\s*<\s*\;\?//' -e 's/\s*::0\s*\;\?//' -e 's/\s*127.0.0.1\s*\;\?//' -e 's/^\s*//' -e 's/\s*$//')
103            if [ -n "${EXIM_IP}" ]; then
104                LogText "Result: ${EXIM_IP}"
105                Display --indent 4 --text "- Public Interface(s)" --result "${EXIM_IP}" --color GREEN
106            else
107                LogText "Result: None"
108                Display --indent 4 --text "- Public Interface(s)" --result "NONE" --color WHITE
109            fi
110
111            LogText "Test: Exim TLS State"
112            EXIM_TLS=$(${EXIMBINARY} -bP tls_advertise_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
113            if [ -n "${EXIM_TLS}" ]; then
114                LogText "Result: Enabled"
115                Display --indent 4 --text "- TLS" --result "${STATUS_ENABLED}" --color GREEN
116            else
117                LogText "Result: Not enabled"
118                Display --indent 4 --text "- TLS" --result "${STATUS_DISABLED}" --color WHITE
119            fi
120        fi
121
122        if [ -n "${EXIM_TYPE}" -a "${EXIM_TYPE}" != "LOCAL ONLY" ]; then
123            LogText "Test: Exim Certificate and Private Key"
124
125            case "${EXIM_TYPE}" in
126                "INTERNET HOST" | "SMARTHOST" )
127                    EXIM_CERTIFICATE=$(${EXIMBINARY} -bP tls_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
128                    EXIM_PRIVATEKEY=$(${EXIMBINARY} -bP tls_privatekey | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
129                    ;;
130                "SATELLITE" )
131                    EXIM_CERTIFICATE=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
132                    EXIM_PRIVATEKEY=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_privatekey | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
133                    ;;
134            esac
135
136            if [ -n "${EXIM_CERTIFICATE}" ]; then
137                LogText "Result: ${EXIM_CERTIFICATE}"
138                if [ -f "${EXIM_CERTIFICATE}" ]; then
139                    Display --indent 4 --text "- Certificate" --result "${STATUS_FOUND}" --color GREEN
140                    LogText "Result: Certificate found"
141                else
142                    Display --indent 4 --text "- Certificate" --result "${STATUS_NOT_FOUND}" --color YELLOW
143                    LogText "Result: Certificate not found"
144                fi
145            else
146                LogText "Result: Certificate not set"
147                Display --indent 4 --text "- Certificate" --result "${STATUS_NOT_CONFIGURED}" --color WHITE
148            fi
149
150            if [ -n "${EXIM_PRIVATEKEY}" ]; then
151                LogText "Result: ${EXIM_PRIVATEKEY}"
152                if [ -f "${EXIM_PRIVATEKEY}" ]; then
153                    LogText "Result: Private Key found"
154                    Display --indent 4 --text "- Private Key" --result "${STATUS_FOUND}" --color GREEN
155                else
156                    Display --indent 4 --text "- Private Key" --result "${STATUS_NOT_FOUND}" --color YELLOW
157                    LogText "Result: Private Key not found"
158                fi
159            else
160                LogText "Result: Private Key not set"
161                Display --indent 4 --text "- Private Key" --result "${STATUS_NOT_CONFIGURED}" --color WHITE
162            fi
163
164            LogText "Test: Exim Verify Certificates"
165
166            case "${EXIM_TYPE}" in
167                "INTERNET HOST" | "SMARTHOST" )
168                    EXIM_CERTIFICATES=$(${EXIMBINARY} -bP tls_verify_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
169                    ;;
170                "SATELLITE" )
171                    EXIM_CERTIFICATES=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_verify_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
172                    ;;
173            esac
174
175            case "${EXIM_CERTIFICATES}" in
176                "")
177                    # This condition results in a RED warning because it should never be hit
178                    LogText "Result: Verify Certificates not set"
179                    Display --indent 4 --text "- Verify Certificates not set" --result "${STATUS_WARNING}" --color RED
180                    ;;
181                "system")
182                    # This is the default setting and should be the most common
183                    LogText "Result: Verify Certificates set to system default"
184                    Display --indent 4 --text "- Verify Certificates" --result "DEFAULT" --color WHITE
185                    ;;
186                *)
187                    # This condition should only be hit when it has been set to a custom value
188                    LogText "Result: Verify Certificates set to \"${EXIM_CERTIFICATES}\""
189                    Display --indent 4 --text "- Verify Certificates" --result "CUSTOM" --color GREEN
190                    ;;
191            esac
192
193
194            case "${EXIM_TYPE}" in
195                "INTERNET HOST" | "SMARTHOST" )
196                    EXIM_VERIFY_HOSTS=$(${EXIMBINARY} -bP tls_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
197                    EXIM_TRY_VERIFY_HOSTS=$(${EXIMBINARY} -bP tls_try_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
198                    ;;
199                "SATELLITE" )
200                    EXIM_VERIFY_HOSTS=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
201                    EXIM_TRY_VERIFY_HOSTS=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_try_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\s*//' -e 's/\s*$//')
202                    ;;
203            esac
204
205            LogText "Test: Exim Try Verify Hosts"
206            if [ -n "${EXIM_TRY_VERIFY_HOSTS}" ]; then
207                LogText "Result: Try Verify Hosts enabled"
208                case "${EXIM_TYPE}" in
209                    "INTERNET HOST" )
210                        Display --indent 4 --text "- Try Verify Hosts" --result "${STATUS_ENABLED}" --color GREEN
211                        ;;
212                    "SATELLITE" | "SMARTHOST" )
213                        Display --indent 4 --text "- Try Verify Hosts" --result "${STATUS_ENABLED}" --color YELLOW
214                        ;;
215                esac
216            else
217                LogText "Result: Try Verify Hosts not enabled"
218                Display --indent 4 --text "- Try Verify Hosts" --result "${STATUS_DISABLED}" --color WHITE
219            fi
220
221            LogText "Test: Exim Verify Hosts"
222            if [ -n "${EXIM_VERIFY_HOSTS}" ]; then
223                LogText "Result: Verify Hosts enabled"
224                case "${EXIM_TYPE}" in
225                    "INTERNET HOST" )
226                        Display --indent 4 --text "- Verify Hosts" --result "${STATUS_ENABLED}" --color YELLOW
227                        ;;
228                    "SATELLITE" | "SMARTHOST" )
229                        Display --indent 4 --text "- Verify Hosts" --result "${STATUS_ENABLED}" --color GREEN
230                        ;;
231                esac
232            else
233                LogText "Result: Verify Hosts not enabled"
234                Display --indent 4 --text "- Verify Hosts" --result "${STATUS_DISABLED}" --color WHITE
235            fi
236        fi
237    fi
238
239#
240#################################################################################
241#
242    # Test        : MAIL-8814
243    # Description : Check Postfix process
244    # Notes       : qmgr and pickup run under postfix uid, without full path to binary
245    Register --test-no MAIL-8814 --weight L --network NO --category security --description "Check postfix process status"
246    if [ ${SKIPTEST} -eq 0  ]; then
247        LogText "Test: check Postfix status"
248        # Some other processes also use master, therefore it should include both master and postfix
249        FIND1=$(${PSBINARY} ax | ${GREPBINARY} "master" | ${GREPBINARY} "postfix" | ${GREPBINARY} -v "grep")
250        if [ -n "${FIND1}" ]; then
251            LogText "Result: found running Postfix process"
252            Display --indent 2 --text "- Postfix status" --result "${STATUS_RUNNING}" --color GREEN
253            POSTFIX_RUNNING=1
254            SMTP_DAEMON="postfix"
255            Report "smtp_daemon[]=postfix"
256        else
257            LogText "Result: no running Postfix processes found"
258            if IsVerbose; then Display --indent 2 --text "- Postfix status" --result "${STATUS_NOT_FOUND}" --color WHITE; fi
259        fi
260    fi
261#
262#################################################################################
263#
264    # Test        : MAIL-8816
265    # Description : Check Postfix configuration
266    if [ ${POSTFIX_RUNNING} -eq 1 -a ! "${POSTFIXBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
267    Register --test-no MAIL-8816 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check Postfix configuration"
268    if [ ${SKIPTEST} -eq 0  ]; then
269        Display --indent 4 --text "- Postfix configuration" --result "${STATUS_FOUND}" --color GREEN
270        POSTFIX_CONFIGDIR=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^config_directory' | ${AWKBINARY} '{ print $3 }')
271        POSTFIX_CONFIGFILE="${POSTFIX_CONFIGDIR}/main.cf"
272        LogText "Postfix configuration directory: ${POSTFIX_CONFIGDIR}"
273        LogText "Postfix configuration file: ${POSTFIX_CONFIGFILE}"
274    fi
275#
276#################################################################################
277#
278    # Test        : MAIL-8817
279    # Description : Check Postfix configuration for error
280    if [ ${POSTFIX_RUNNING} -eq 1 -a ! "${POSTFIXBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
281    Register --test-no MAIL-8817 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check Postfix configuration errors"
282    if [ ${SKIPTEST} -eq 0  ]; then
283        LogText "Test: using postconf to see if Postfix configuration has errors"
284        FIND=$(${POSTCONFBINARY} 2>&1 | ${GREPBINARY} "warning:")
285        if [ -n "${FIND}" ]; then
286            Report "postfix_config_error=1"
287            Display --indent 6 --text "- Postfix configuration errors" --result "${STATUS_WARNING}" --color RED
288            LogText "Result: found an error or warning in the Postfix configuration. Manual check suggested."
289            ReportSuggestion "${TEST_NO}" "Found a configuration error in Postfix" "${POSTFIX_CONFIGFILE}" "text:run postconf > /dev/null"
290        else
291            LogText "Result: all looks to be fine with Postfix configuration"
292            if IsVerbose; then Display --indent 6 --text "- Postfix configuration errors" --result "${STATUS_OK}" --color GREEN; fi
293        fi
294    fi
295#
296#################################################################################
297#
298    # Test        : MAIL-8818
299    # Description : Check Postfix configuration
300    if [ ${POSTFIX_RUNNING} -eq 1 -a ! "${POSTFIXBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
301    Register --test-no MAIL-8818 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check Postfix configuration: banner"
302    if [ ${SKIPTEST} -eq 0  ]; then
303        LogText "Test: Checking Postfix banner"
304        FIND1=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} 'postfix')
305        FIND2=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} '$mail_name')
306        FIND3=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^mail_name' | ${GREPBINARY} -i 'postfix')
307        FIND4=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} -i "${OS}")
308        if [ -n "${LINUX_VERSION}" ]; then
309            FIND5=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} -i "${LINUX_VERSION}")
310        fi
311        SHOWWARNING=0
312
313        if [ -n "${FIND1}" ]; then
314            SHOWWARNING=1
315            Report "banner_software_disclosure[]=${FIND1}"
316        elif [ -n "${FIND2}" -a -n "${FIND3}" ]; then
317            SHOWWARNING=1
318            Report "banner_software_disclosure[]=${FIND2}"
319        elif [ -n "${FIND4}" ]; then
320            SHOWWARNING=1
321            Report "banner_os_disclosure[]=${FIND4}"
322        elif [ -n "${FIND5}" ]; then
323            SHOWWARNING=1
324            Report "banner_os_disclosure[]=${FIND5}"
325        fi
326
327        if [ ${SHOWWARNING} -eq 1 ]; then
328            Display --indent 6 --text "- Postfix banner" --result "${STATUS_WARNING}" --color RED
329            LogText "Result: found OS, or mail_name in SMTP banner, and/or mail_name contains 'Postfix'."
330            ReportWarning "${TEST_NO}" "Found some information disclosure in SMTP banner (OS or software name)"
331            ReportSuggestion "${TEST_NO}" "You are advised to hide the mail_name (option: smtpd_banner) from your postfix configuration. Use postconf -e or change your main.cf file (${POSTFIX_CONFIGFILE})"
332        else
333            if IsVerbose; then Display --indent 6 --text "- Postfix banner" --result "${STATUS_OK}" --color GREEN; fi
334        fi
335    fi
336#
337#################################################################################
338#
339    # Test        : MAIL-8820
340    Register --test-no MAIL-8820 --weight L --network NO --category security --description "Postfix configuration scan"
341    if [ ${SKIPTEST} -eq 0  ]; then
342        if [ "$(postconf -h inet_interfaces 2> /dev/null)" = "all" ]; then
343            if ! SkipAtomicTest "${TEST_NO}:disable_vrfy_command"; then
344                if [ "$(postconf -h disable_vrfy_command 2> /dev/null)" = "no" ]; then
345                    ReportSuggestion "${TEST_NO}:disable_vrfy_command" "Disable the 'VRFY' command" "disable_vrfy_command=no" "text:run postconf -e disable_vrfy_command=yes to change the value"
346                fi
347            fi
348        fi
349    fi
350#
351#################################################################################
352#
353    # Test        : MAIL-8838
354    # Description : Check Dovecot process
355    Register --test-no MAIL-8838 --weight L --network NO --category security --description "Check dovecot process"
356    if [ ${SKIPTEST} -eq 0  ]; then
357        LogText "Test: check dovecot status"
358        if IsRunning "dovecot"; then
359            LogText "Result: found running dovecot process"
360            Display --indent 2 --text "- Dovecot status" --result "${STATUS_RUNNING}" --color GREEN
361            DOVECOT_RUNNING=1
362            IMAP_DAEMON="dovecot"
363            POP3_DAEMON="dovecot"
364            Report "pop3_daemon[]=dovecot"
365            Report "imap_daemon[]=dovecot"
366        else
367            LogText "Result: dovecot not found"
368            if IsVerbose; then Display --indent 2 --text "- Dovecot status" --result "${STATUS_NOT_FOUND}" --color WHITE; fi
369        fi
370    fi
371#
372#################################################################################
373#
374    # Test        : MAIL-8860
375    # Description : Check Qmail process status
376    Register --test-no MAIL-8860 --weight L --network NO --category security --description "Check Qmail status"
377    if [ ${SKIPTEST} -eq 0  ]; then
378        LogText "Test: check Qmail status"
379        if IsRunning "qmail-smtpd"; then
380            LogText "Result: found running Qmail process"
381            Display --indent 2 --text "- Qmail status" --result "${STATUS_RUNNING}" --color GREEN
382            QMAIL_RUNNING=1
383            SMTP_DAEMON="qmail"
384            Report "smtp_daemon[]=qmail"
385        else
386            LogText "Result: no running Qmail processes found"
387            if IsVerbose; then Display --indent 2 --text "- Qmail status" --result "${STATUS_NOT_FOUND}" --color WHITE; fi
388        fi
389    fi
390#
391#################################################################################
392#
393    # Test        : MAIL-8880
394    # Description : Check Sendmail process status
395    Register --test-no MAIL-8880 --weight L --network NO --category security --description "Check Sendmail status"
396    if [ ${SKIPTEST} -eq 0  ]; then
397        LogText "Test: check sendmail status"
398        if IsRunning "sendmail"; then
399            LogText "Result: found running Sendmail process"
400            Display --indent 2 --text "- Sendmail status" --result "${STATUS_RUNNING}" --color GREEN
401            SENDMAIL_RUNNING=1
402            SMTP_DAEMON="sendmail"
403            Report "smtp_daemon[]=sendmail"
404        else
405            LogText "Result: no running Sendmail processes found"
406            if IsVerbose; then Display --indent 2 --text "- Sendmail status" --result "${STATUS_NOT_FOUND}" --color WHITE; fi
407        fi
408    fi
409#
410#################################################################################
411#
412    # Test        : MAIL-8920
413    # Description : Check OpenSMTPD process status
414    if [ -n "${SMTPCTLBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
415    Register --test-no MAIL-8920 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check OpenSMTPD status"
416    if [ ${SKIPTEST} -eq 0  ]; then
417        LogText "Test: check smtpd status"
418        FIND=$(${PSBINARY} ax | ${EGREPBINARY} "(/smtpd|smtpd: \[priv\]|smtpd: smtp)" | ${GREPBINARY} -v "grep")
419        if [ ! "${FIND}" = "" ]; then
420            LogText "Result: found running smtpd process"
421            Display --indent 2 --text "- OpenSMTPD status" --result "${STATUS_RUNNING}" --color GREEN
422            OPENSMTPD_RUNNING=1
423            Report "smtp_daemon[]=opensmtpd"
424        else
425            LogText "Result: smtpd not found"
426            if IsVerbose; then Display --indent 2 --text "- OpenSMTPD status" --result "${STATUS_NOT_FOUND}" --color WHITE; fi
427        fi
428    fi
429#
430#################################################################################
431#
432
433Report "imap_daemon=${IMAP_DAEMON}"
434Report "pop3_daemon=${POP3_DAEMON}"
435Report "smtp_daemon=${SMTP_DAEMON}"
436
437
438WaitForKeyPress
439
440#
441#================================================================================
442# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com
443