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# Time
22#
23#################################################################################
24#
25    InsertSection "${SECTION_TIME_AND_SYNCHRONIZATION}"
26#
27#################################################################################
28#
29    CRON_DIRS="${ROOTDIR}etc/cron.d ${ROOTDIR}etc/cron.hourly ${ROOTDIR}etc/cron.daily ${ROOTDIR}etc/cron.weekly ${ROOTDIR}etc/cron.monthly ${ROOTDIR}var/spool/crontabs"
30    CHRONY_CONF_FILE=""
31    NTP_DAEMON=""
32    NTP_DAEMON_RUNNING=0
33    NTP_CONFIG_FOUND=0
34    NTP_CONFIG_TYPE_DAEMON=0
35    NTP_CONFIG_TYPE_SCHEDULED=0
36    NTP_CONFIG_TYPE_EVENTBASED=0
37    NTP_CONFIG_TYPE_STARTUP=0
38    NTPD_RUNNING=0 # Specific for ntpd
39    OPENNTPD_COMMUNICATION=0 # if ntpctl can communicate
40    SYSTEMD_NTP_ENABLED=0
41#
42#################################################################################
43#
44    # Test        : TIME-3104
45    # Description : Check for a running NTP daemon
46    if [ -f /sys/hypervisor/type ]; then
47        # TODO: Skip NTP tests if we are in a DomU xen instance
48        FIND=$(cat /sys/hypervisor/type)
49        if [ "${FIND}" = "xen" ]; then PREQS_MET="NO"; else PREQS_MET="YES"; fi
50    elif [ -f /sbin/sysctl ] && [ "$(/sbin/sysctl -n security.jail.jailed 2>/dev/null || echo 0)" -eq 1 ]; then
51        # Skip NTP tests if we're in a FreeBSD jail
52        PREQS_MET="NO"
53    else
54        PREQS_MET="YES"
55    fi
56    Register --test-no TIME-3104 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check for running NTP daemon or client"
57    if [ ${SKIPTEST} -eq 0 ]; then
58        # Linux/FreeBSD (ntpdate), OpenBSD (ntpd, rdate), Chrony, systemd-timesyncd
59        LogText "Test: Searching for a running NTP daemon or available client"
60        FOUND=0
61
62        SEARCH_FILES="${ROOTDIR}etc/chrony.conf ${ROOTDIR}etc/chrony/chrony.conf"
63        for FILE in ${SEARCH_FILES}; do
64            if [ -f ${FILE} ]; then LogText "result: found chrony configuration: ${FILE}"; CHRONY_CONF_FILE="${FILE}"; fi
65        done
66        if [ -n "${CHRONY_CONF_FILE}" ]; then
67            if IsRunning "chronyd"; then
68                FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON="chronyd"
69                Display --indent 2 --text "- NTP daemon found: chronyd" --result "${STATUS_FOUND}" --color GREEN
70            else
71                LogText "Result: found chrony configuration, but no running daemon"
72            fi
73        else
74            LogText "Result: no chrony configuration found"
75        fi
76
77        # Check time daemon (eg DragonFly BSD)
78        if IsRunning "dntpd"; then
79            FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON="dntpd"
80            Display --indent 2 --text "- NTP daemon found: dntpd" --result "${STATUS_FOUND}" --color GREEN
81        fi
82
83        # Check for OpenNTPD, ntpctl comes with a "regular" install
84        if [ -n "${NTPCTLBINARY}" ]; then
85            # In contrast to timectl, "synchronised: yes" is not grepped.
86            # Reason: openntpd syncs only if large time corrections are not required or -s is passed.
87            #         This might be not intended by the administrator (-s is NOT the default!)
88            FIND=$(${PSBINARY} ax | ${GREPBINARY} "ntpd: ntp engine" | ${GREPBINARY} -v "grep")
89            # Status code 0 is when communication over the socket is successful
90            if ${NTPCTLBINARY} -s status > /dev/null 2> /dev/null; then
91                FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON="openntpd"
92                LogText "result: found openntpd (method: ntpctl)"
93                OPENNTPD_COMMUNICATION=1
94            elif [ -n "${FIND}" ] ; then
95                # Reasons for ntpctl to fail might be someone spawned a new process thus overwriting the socket,
96                # then ended it, but another openntpd process is still running
97                FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON="openntpd"
98                LogText "result: found openntpd (method: ps)"
99            else
100                LogText "result: running openntpd not found, but ntpctl is installed"
101            fi
102
103            if [ "${NTP_DAEMON}" = "openntpd" ]; then
104                Display --indent 2 --text "- NTP daemon found: OpenNTPD" --result "${STATUS_FOUND}" --color GREEN
105            fi
106        fi
107
108        # Check running processes (ntpd from ntp.org)
109        # As checking by process name is ambiguous (openntpd has the same process name),
110        # this check will be skipped if openntpd has been found.
111        FIND=$(${PSBINARY} ax | ${GREPBINARY} "ntpd" | ${GREPBINARY} -v "dntpd" | ${GREPBINARY} -v "ntpd: " | ${GREPBINARY} -v "grep")
112        if [ "${NTP_DAEMON}" != "openntpd" ] && [  -n "${FIND}" ]; then
113            FOUND=1; NTPD_RUNNING=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1
114            NTP_DAEMON="ntpd"
115            LogText "Result: found running NTP daemon in process list"
116            Display --indent 2 --text "- NTP daemon found: ntpd" --result "${STATUS_FOUND}" --color GREEN
117        fi
118
119        # Check time daemon (eg NetBSD)
120        if IsRunning "timed"; then
121            FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON="timed"
122            Display --indent 2 --text "- NTP daemon found: timed" --result "${STATUS_FOUND}" --color GREEN
123        fi
124
125        # Check timedate daemon (systemd)
126        FIND=$(${PSBINARY} ax | ${GREPBINARY} "systemd-timesyncd" | ${GREPBINARY} -v "grep")
127        if [  -n "${FIND}" ]; then
128            FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON="systemd-timesyncd"
129            Display --indent 2 --text "- NTP daemon found: systemd (timesyncd)" --result "${STATUS_FOUND}" --color GREEN
130            LogText "Result: Found running systemd-timesyncd in process list"
131        fi
132
133        # Check crontab for OpenBSD/FreeBSD
134        # Check anacrontab for Linux
135        CRONTAB_FILES="/etc/anacrontab /etc/crontab"
136        # Regex for matching multiple time synchronisation binaries
137        # Partial sanity check for sntp and ntpdig, but this does not consider all corner cases
138        CRONTAB_REGEX='ntpdate|rdate|sntp.+-(s|j|--adj)|ntpdig.+-(S|s)'
139        for I in ${CRONTAB_FILES}; do
140            if [ -f ${I} ]; then
141                LogText "Test: checking for ntpdate, rdate, sntp or ntpdig in crontab file ${I}"
142                FIND=$(${EGREPBINARY} "${CRONTAB_REGEX}" ${I} | ${GREPBINARY} -v '^#')
143                if [ -n "${FIND}" ]; then
144                    FOUND=1; NTP_CONFIG_TYPE_SCHEDULED=1
145                    Display --indent 2 --text "- Checking NTP client in crontab file (${I})" --result "${STATUS_FOUND}" --color GREEN
146                    LogText "Result: found ntpdate, rdate, sntp or ntpdig reference in crontab file ${I}"
147                else
148                    #Display --indent 2 --text "- Checking NTP client in crontab file (${I})" --result "${STATUS_NOT_FOUND}" --color WHITE
149                    LogText "Result: no ntpdate, rdate, sntp or ntpdig reference found in crontab file ${I}"
150                fi
151            else
152                LogText "Result: crontab file ${I} not found"
153            fi
154        done
155
156        # Notes: only test for normal files. File /etc/cron.d/FIFO on solaris is a special file and test may hang
157        # Linux systems may have a .placeholder file
158        FOUND_IN_CRON=0
159
160        # Check cron jobs
161        for I in ${CRON_DIRS}; do
162            for J in "${I}"/*; do  # iterate over folders in a safe way
163                # Check: regular file, readable and not called .placeholder
164                FIND=$(echo "${J}" | ${EGREPBINARY} '/.placeholder$')
165                if [ -f "${J}" ] && [ -r "${J}" ] && [ -z "${FIND}" ]; then
166                    LogText "Test: checking for ntpdate, rdate, sntp or ntpdig in ${J}"
167                    FIND=$("${EGREPBINARY}" "${CRONTAB_REGEX}" "${J}" | "${GREPBINARY}" -v "^#")
168                    if [ -n "${FIND}" ]; then
169                        FOUND=1; FOUND_IN_CRON=1; NTP_CONFIG_TYPE_SCHEDULED=1
170                        LogText "Result: found ntpdate, rdate, sntp or ntpdig in ${J}"
171                    fi
172                fi
173            done
174        done
175
176        if [ ${FOUND_IN_CRON} -eq 1 ]; then
177            Display --indent 2 --text "- Checking NTP client in cron files" --result "${STATUS_FOUND}" --color GREEN
178            LogText "Result: found ntpdate or rdate in cron directory"
179        else
180            LogText "Result: no ntpdate or rdate found in cron directories"
181        fi
182
183        # Checking if ntpdate is performed by event
184        LogText "Test: checking for file /etc/network/if-up.d/ntpdate"
185        if [ -f /etc/network/if-up.d/ntpdate ]; then
186            LogText "Result: found ntpdate action when network interface comes up"
187            FOUND=1
188            NTP_CONFIG_TYPE_EVENTBASED=1
189            Display --indent 2 --text "- Checking event based ntpdate (if-up)" --result "${STATUS_FOUND}" --color GREEN
190        else
191            LogText "Result: file /etc/network/if-up.d/ntpdate does not exist"
192        fi
193
194        # Configuration file for *BSD
195        if [ -f /etc/rc.conf ]; then
196            LogText "Test: Checking if ntpdate is enabled at startup in *BSD"
197            FIND=$(${GREPBINARY} 'ntpdate_enable="YES"' /etc/rc.conf)
198            if [ -n "${FIND}" ]; then
199                LogText "Result: ntpdate is enabled in rc.conf"
200                FOUND=1
201                NTP_CONFIG_TYPE_STARTUP=1
202                # Only show suggestion when ntpdate is enabled, however ntpd is not running
203                if [ ${NTP_DAEMON_RUNNING} -eq 0 ]; then
204                    ReportSuggestion "${TEST_NO}" "Although ntpdate is enabled in rc.conf, it is advised to run it at least daily or use a NTP daemon"
205                fi
206            else
207                LogText "Result: ntpdate is not enabled in rc.conf"
208            fi
209        fi
210
211        if [ ${FOUND} -eq 0 ]; then
212            if [ ${ISVIRTUALMACHINE} -eq 1 ]; then
213                LogText "Result: Skipping display warning, as virtual machines usually don't need time synchronization in the VM itself"
214            else
215                Display --indent 2 --text "- Checking for a running NTP daemon or client" --result "${STATUS_WARNING}" --color RED
216                LogText "Result: Could not find a NTP daemon or client"
217                ReportSuggestion "${TEST_NO}" "Use NTP daemon or NTP client to prevent time issues."
218                AddHP 0 2
219            fi
220        else
221            Display --indent 2 --text "- Checking for a running NTP daemon or client" --result "${STATUS_OK}" --color GREEN
222            LogText "Result: Found a time syncing daemon/client."
223            AddHP 3 3
224        fi
225    fi
226#
227#################################################################################
228#
229    # Test        : TIME-3106
230    # Description : Check status of systemd time synchronization
231    if [ ${SYSTEMD_NTP_ENABLED} -eq 1 -a -n "${TIMEDATECTL}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
232    Register --test-no TIME-3106 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check systemd NTP time synchronization status"
233    if [ ${SKIPTEST} -eq 0 ]; then
234        LogText "Test: Check the status of time synchronization via timedatectl"
235        FIND=$(${TIMEDATECTL} status | ${EGREPBINARY} "(NTP|System clock) synchronized: yes")
236        if [ -z "${FIND}" ]; then
237            LogText "Result: time not synchronized via NTP"
238            ReportSuggestion "${TEST_NO}" "Check timedatectl output. Synchronization via NTP is enabled, but status reflects it is not synchronized"
239        fi
240    fi
241#
242#################################################################################
243#
244    # Test        : TIME-3112
245    # Description : Check for valid associations from ntpq peers list
246    if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
247    Register --test-no TIME-3112 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check active NTP associations ID's"
248    if [ ${SKIPTEST} -eq 0 ]; then
249        LogText "Test: Checking for NTP association ID's from ntpq peers list"
250        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} "No association ID's returned")
251        if [ -z "${FIND}" ]; then
252            Display --indent 2 --text "- Checking valid association ID's" --result "${STATUS_FOUND}" --color GREEN
253            LogText "Result: Found one or more association ID's"
254        else
255            Display --indent 2 --text "- Checking valid association ID's" --result "${STATUS_WARNING}" --color RED
256            ReportSuggestion "${TEST_NO}" "Check ntp.conf for properly configured NTP servers and a correctly functioning name service."
257        fi
258    fi
259#
260#################################################################################
261#
262    # Test        : TIME-3116
263    # Description : Check for stratum 16 peers
264    if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
265    Register --test-no TIME-3116 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check peers with stratum value of 16"
266    if [ ${SKIPTEST} -eq 0 ]; then
267        COUNT=0
268        LogText "Test: Checking stratum 16 sources from ntpq peers list"
269        FIND=$(${NTPQBINARY} -p -n | ${AWKBINARY} '{ if ($2!=".POOL." && $3=="16") { print $1 }}')
270        if [ -z "${FIND}" ]; then
271            Display --indent 2 --text "- Checking high stratum ntp peers" --result "${STATUS_OK}" --color GREEN
272            LogText "Result: All peers are lower than stratum 16"
273        else
274            for ITEM in ${FIND}; do
275                LogText "Found stratum 16 peer: ${ITEM}"
276                FIND2=$(${EGREPBINARY} "^ntp-ignore-stratum-16-peer=${ITEM}" ${PROFILE})
277                if IsEmpty "${FIND2}"; then
278                    COUNT=$((COUNT + 1))
279                    Report "ntp_stratum_16_peer[]=${ITEM}"
280                else
281                    LogText "Output: host ${ITEM} ignored by profile"
282                fi
283            done
284            # Check if one or more high stratum time servers are found
285            if [ ${COUNT} -eq 0 ]; then
286                Display --indent 2 --text "- Checking high stratum ntp peers" --result "${STATUS_OK}" --color GREEN
287                LogText "Result: all non local servers are lower than stratum 16, or whitelisted within the scan profile"
288            else
289                Display --indent 2 --text "- Checking high stratum ntp peers" --result "${STATUS_WARNING}" --color RED
290                LogText "Result: Found ${COUNT} high stratum (16) peers)"
291                ReportSuggestion "${TEST_NO}" "Check ntpq peers output for stratum 16 peers"
292            fi
293        fi
294    fi
295#
296#################################################################################
297#
298    # Test        : TIME-3120
299    # Description : Check unreliable peers from peer list
300    # Notes       : Items with # are too far away (network distance)
301    #               Items with - are not chosen due clustering algorithm
302    if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
303    Register --test-no TIME-3120 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check unreliable NTP peers"
304    if [ ${SKIPTEST} -eq 0 ]; then
305        LogText "Test: Checking unreliable ntp peers"
306        FIND=$(${NTPQBINARY} -p -n | ${EGREPBINARY} "^(-|#)" | ${AWKBINARY} '{ print $1 }' | ${SEDBINARY} 's/^-//g')
307        if [ -z "${FIND}" ]; then
308            Display --indent 2 --text "- Checking unreliable ntp peers" --result "${STATUS_NONE}" --color GREEN
309            LogText "Result: No unreliable peers found"
310        else
311            Display --indent 2 --text "- Checking unreliable ntp peers" --result "${STATUS_FOUND}" --color YELLOW
312            LogText "Result: Found one or more unreliable peers (marked with a minus or dash sign)"
313            for I in ${FIND}; do
314                LogText "Unreliable peer: ${I}"
315                Report "ntp_unreliable_peer[]=${I}"
316            done
317            ReportSuggestion "${TEST_NO}" "Check ntpq peers output for unreliable ntp peers and correct/replace them"
318        fi
319    fi
320#
321#################################################################################
322#
323    # Test        : TIME-3124
324    # Description : Check selected time source
325    if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
326    Register --test-no TIME-3124 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check selected time source"
327    if [ ${SKIPTEST} -eq 0 ]; then
328        LogText "Test: Checking selected time source"
329        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} '^*' | ${AWKBINARY} '{ if ($4=="l") { print $1 } }')
330        FIND2=$(${NTPQBINARY} -p -n | ${GREPBINARY} '^*' | ${AWKBINARY} '{ print $1 }')
331        if [ -z "${FIND}" -a -n "${FIND2}" ]; then
332            Display --indent 2 --text "- Checking selected time source" --result "${STATUS_OK}" --color GREEN
333            FIND2=$(echo ${FIND2} | ${SEDBINARY} 's/*//g')
334            LogText "Result: Found selected time source (value: ${FIND2})"
335        else
336            Display --indent 2 --text "- Checking selected time source" --result "${STATUS_WARNING}" --color RED
337            LogText "Result: Found local source as selected time source. This could indicate that no external sources are available to sync with."
338            LogText "Local source: ${FIND}"
339            ReportSuggestion "${TEST_NO}" "Check ntpq peers output for selected time source"
340        fi
341    fi
342#
343#################################################################################
344#
345    # Test        : TIME-3128
346    # Description : Check time source candidates
347    if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
348    Register --test-no TIME-3128 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check preferred time source"
349    if [ ${SKIPTEST} -eq 0 ]; then
350        LogText "Test: Checking preferred time source"
351        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} '^+' | ${AWKBINARY} '{ print $1 }')
352        if [ -z "${FIND}" ]; then
353            Display --indent 2 --text "- Checking time source candidates" --result "${STATUS_NONE}" --color YELLOW
354            LogText "Result: No other time source candidates found"
355            ReportSuggestion "${TEST_NO}" "Check ntpq peers output for time source candidates"
356        else
357            Display --indent 2 --text "- Checking time source candidates" --result "${STATUS_OK}" --color GREEN
358            LogText "Result: Found one or more candidates to synchronize time with."
359            for I in ${FIND}; do
360                I=$(echo ${I} | ${SEDBINARY} 's/+//g')
361                LogText "Candidate found: ${I}"
362            done
363        fi
364    fi
365#
366#################################################################################
367#
368    # Test        : TIME-3132
369    # Description : Check ntpq falsetickers
370    if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
371    Register --test-no TIME-3132 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check NTP falsetickers"
372    if [ ${SKIPTEST} -eq 0 ]; then
373        LogText "Test: Checking preferred time source"
374        FIND=$(${NTPQBINARY} -p -n | ${EGREPBINARY} '^x')
375        if [ -z "${FIND}" ]; then
376            Display --indent 2 --text "- Checking falsetickers" --result "${STATUS_OK}" --color GREEN
377            LogText "Result: No falsetickers found (items preceding with an 'x')"
378        else
379            Display --indent 2 --text "- Checking falsetickers" --result "${STATUS_NONE}" --color YELLOW
380            LogText "Result: Found one or more falsetickers  (items preceding with an 'x')"
381            for I in ${FIND}; do
382                I=$(echo ${I} | ${SEDBINARY} 's/x//g')
383                LogText "Falseticker found: ${I}"
384                Report "ntp_falseticker[]=${I}"
385            done
386            ReportSuggestion "${TEST_NO}" "Check ntpq peers output for falsetickers"
387        fi
388    fi
389#
390#################################################################################
391#
392    # Test        : TIME-3136
393    # Description : Check ntpq reported ntp version (Linux)
394    if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
395    Register --test-no TIME-3136 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check NTP protocol version"
396    if [ ${SKIPTEST} -eq 0 ]; then
397        LogText "Test: Checking NTP protocol version (ntpq -c ntpversion)"
398        FIND=$(${NTPQBINARY} -c ntpversion | ${AWKBINARY} '{ if ($1=="NTP" && $2=="version" && $5=="is") { print $6 } }')
399        if [ -z "${FIND}" ]; then
400            Display --indent 2 --text "- Checking NTP version" --result "${STATUS_UNKNOWN}" --color YELLOW
401            LogText "Result: No NTP version found"
402            ReportSuggestion "${TEST_NO}" "Check ntpq output for NTP protocol version"
403        else
404            Display --indent 2 --text "- Checking NTP version" --result "${STATUS_FOUND}" --color GREEN
405            LogText "Result: Found NTP version ${FIND}"
406            Report "ntp_version=${FIND}"
407        fi
408    fi
409#
410#################################################################################
411#
412    # Test        : TIME-3146
413    # Description : Check /etc/default/ntpdate (Linux)
414    # Notes       : ntpdate-debian binary
415    #if [ ${NTPD_RUNNING} -eq 1 -a -n "${NTPQBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
416    #Register --test-no TIME-3146 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check /etc/default/ntpdate"
417    #if [ ${SKIPTEST} -eq 0 ]; then
418#
419#################################################################################
420#
421    # Test        : TIME-3148
422    # Description : Check if TZ variable is set (Linux)
423    # Notes       : without TZ variable set, a lot of unneeded calls might be performed.
424    Register --test-no TIME-3148 --os Linux --weight L --network NO --category performance --description "Check TZ variable"
425    if [ ${SKIPTEST} -eq 0 ]; then
426        LogText "Test: testing for TZ variable"
427        FIND="${TZ:=notset}"
428        LogText "Result: found TZ variable with value ${FIND}"
429        if [ "${FIND}" = "notset" ]; then
430            Report "tz_variable_empty=1"
431        fi
432    fi
433#
434#################################################################################
435#
436    # Test        : TIME-3160
437    # Description : Check empty NTP step-tickers
438    # Notes       : Mostly applies to Red Hat and clones
439    FILE="${ROOTDIR}etc/ntp/step-tickers"
440    if [ "${NTPD_RUNNING}" -eq 1 -a -n "${NTPQBINARY}" -a -f "${FILE}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
441    Register --test-no TIME-3160 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check empty NTP step-tickers"
442    if [ ${SKIPTEST} -eq 0 ]; then
443        FOUND=0
444        OUTPUT=$(${AWKBINARY} '/^[a-z0-9]/ { print $1 }' ${FILE})
445        if [ -z "${OUTPUT}" ]; then
446            if [ ${OS_REDHAT_OR_CLONE} -eq 1 -a -f "${FILE}" ]; then
447                # On RedHat if step-ticker file exists but is empty, the ntpdate start script uses the servers listed in ntp.conf for the initial time synchronization
448                LogText "Result: ${FILE} exists and it is empty. On RedHat the initial time synchronization will be done with the servers listed in ntp.conf."
449                Display --indent 2 --text "- Checking NTP step-tickers file" --result "${STATUS_OK}" --color GREEN
450            else
451                LogText "Result: ${FILE} is empty. The step-tickers contain no configured NTP servers"
452                Display --indent 2 --text "- Checking NTP step-tickers file" --result "EMPTY FILE" --color YELLOW
453                ReportSuggestion "${TEST_NO}" "Use step-tickers file for quicker time synchronization"
454            fi
455        else
456            LogText "Result: ${FILE} is not empty, which is fine"
457            Display --indent 2 --text "- Checking NTP step-tickers file" --result "${STATUS_OK}" --color GREEN
458            sFIND=$(${AWKBINARY} '/^[a-z0-9]/ { print $1 }' ${FILE} | ${EGREPBINARY} -v "^127." | ${EGREPBINARY} -v "^::1")
459            for I in ${sFIND}; do
460                FIND=$(${GREPBINARY} ^${I} ${FILE} | wc -l)
461                if [ ${FIND} -gt 0 ]; then
462                    LogText "Result: $I exist in ${FILE}"
463                else
464                    LogText "Result: ${I} does NOT exist in ${FILE}"
465                    FOUND=1
466                fi
467            done
468            if [ ${FOUND} -eq 1 ]; then
469                Display --indent 4 --text "- Checking step-tickers ntp servers entries" --result "SOME MISSING" --color YELLOW
470                ReportSuggestion "${TEST_NO}" "Some time servers missing in step-tickers file"
471                AddHP 3 4
472            else
473                Display --indent 4 --text "- Checking step-tickers ntp servers entries" --result "${STATUS_OK}" --color GREEN
474                LogText "Result: all time servers are in step-tickers file"
475                AddHP 4 4
476            fi
477        fi
478        LogText "Information: step-tickers is used by ntpdate where as ntp.conf is the configuration file for the ntpd daemon. ntpdate is initially run to set the clock before ntpd to make sure time is within 1000 sec."
479        LogText "Risk: ntp will not run at boot if the time difference between the server and client by more then 1000 sec."
480    fi
481#
482#################################################################################
483#
484    # Test        : TIME-3170
485    # Description : Check file permissions and ownership of configuration files
486    # Notes       : Files should be owned by root, or the user running
487    #               Group owner should have only read access
488    #               Other should preferably have no access, or read-only at max
489
490    FILE_ARRAY="${ROOTDIR}etc/chrony.conf ${ROOTDIR}usr/pkg/etc/chrony.conf \
491        ${ROOTDIR}etc/inet/ntp.conf ${ROOTDIR}etc/ntp.conf ${ROOTDIR}usr/local/etc/ntp.conf\
492        ${ROOTDIR}etc/ntpd.conf ${ROOTDIR}etc/openntpd/ntpd.conf ${ROOTDIR}usr/local/etc/ntpd.conf"
493
494    Register --test-no TIME-3170 --weight L --network NO --category security --description "Check configuration files"
495    if [ ${SKIPTEST} -eq 0 ]; then
496        for FILE in ${FILE_ARRAY}; do
497            if [ -f ${FILE} ]; then
498                LogText "Result: found ${FILE}"
499                if IsWorldWritable ${FILE}; then
500                    ReportWarning "${TEST_NO}" "Found world writable configuration file" "${FILE}" ""
501                fi
502                Report "ntp_config_file[]=${FILE}"
503                NTP_CONFIG_FOUND=1
504            fi
505        done
506    fi
507#
508#################################################################################
509#
510    # Test        : TIME-3180
511    # Description : Report if ntpctl cannot communicate with OpenNTPD
512    if [ "${NTP_DAEMON_RUNNING}" -eq 1 ] && [ -n "${NTPCTLBINARY}" ] && [ "${NTP_DAEMON}" = "openntpd" ]; then
513        PREQS_MET="YES"
514    else
515        PREQS_MET="NO"
516    fi
517    Register --test-no TIME-3180 --preqs-met "${PREQS_MET}" --weight L --network NO --category security --description "Report if ntpctl cannot communicate with OpenNTPD"
518    if [ ${SKIPTEST} -eq 0 ]; then
519        if [ "${OPENNTPD_COMMUNICATION}" -eq 0 ]; then
520            ReportWarning "${TEST_NO}" "OpenNTPD found, but ntpctl cannot communicate with" "${NTPCTLBINARY} -s status" "Restart OpenNTPD"
521        fi
522    fi
523#
524#################################################################################
525#
526    # Test        : TIME-3181
527    # Description : Check status of OpenNTPD time synchronisation
528    if [ "${NTP_DAEMON_RUNNING}" -eq 1 ] && [ -n "${NTPCTLBINARY}" ] && [ "${NTP_DAEMON}" = "openntpd" ] && [ "${OPENNTPD_COMMUNICATION}" -eq 1 ]; then
529        PREQS_MET="YES"
530    else
531        PREQS_MET="NO"
532    fi
533
534    Register --test-no TIME-3181 --preqs-met "${PREQS_MET}" --weight L --network NO --category security --description "Check status of OpenNTPD time synchronisation"
535    if [ ${SKIPTEST} -eq 0 ]; then
536        FIND=$(${NTPCTLBINARY} -s status | ${GREPBINARY} "clock synced" )
537        if [ -z "${FIND}" ]; then
538            ReportWarning "${TEST_NO}" "OpenNTPD is not synchronising system time" "${NTPCTLBINARY} -s status" "text:Set time manually once or check network connectivity."
539        fi
540    fi
541#
542#################################################################################
543#
544    # Test        : TIME-3182
545    # Description : Check OpenNTPD has working peers
546
547    if [ "${NTP_DAEMON_RUNNING}" -eq 1 ] && [ -n "${NTPCTLBINARY}" ] && [ "${NTP_DAEMON}" = "openntpd" ] && [ "${OPENNTPD_COMMUNICATION}" -eq 1 ]; then
548        PREQS_MET="YES"
549    else
550        PREQS_MET="NO"
551    fi
552
553    Register --test-no TIME-3182 --preqs-met "${PREQS_MET}" --weight L --network NO --category security --description "Check OpenNTPD has working peers"
554    if [ ${SKIPTEST} -eq 0 ]; then
555        # Format is "xx/yy peers valid, ..."
556        FIND=$(${NTPCTLBINARY} -s status | ${EGREPBINARY} -o '[0-9]+/[0-9]+' | ${CUTBINARY} -d '/' -f 1)
557        if [ -z "${FIND}" ] || [ "${FIND}" -eq 0 ]; then
558            ReportWarning "${TEST_NO}" "OpenNTPD has no peers" "${NTPCTLBINARY} -s status"
559        fi
560    fi
561
562#
563#################################################################################
564#
565
566    # Test        : TIME-3185
567    # Description : Check systemd-timesyncd synchronized time
568
569    if [ "${NTP_DAEMON}" = "systemd-timesyncd" ]; then
570        PREQS_MET="YES"
571    else
572        PREQS_MET="NO"
573    fi
574
575
576    Register --test-no TIME-3185 --preqs-met "${PREQS_MET}" --weight L --network NO --category "security" --description "Check systemd-timesyncd synchronized time"
577    SYNCHRONIZED_FILE="/run/systemd/timesync/synchronized"
578
579    if [ ${SKIPTEST} -eq 0 ]; then
580        # On earlier systemd versions (237), '/run/systemd/timesync/synchronized' does not exist, so use '/var/lib/systemd/timesync/clock'
581        if [ ! -e "${SYNCHRONIZED_FILE}" ]; then
582            SYNCHRONIZED_FILE="/var/lib/systemd/timesync/clock"
583        fi
584        # DynamicUser=yes moves the clock file to '/var/lib/private/systemd/timesync/clock'
585        if [ ! -e "${SYNCHRONIZED_FILE}" ]; then
586            SYNCHRONIZED_FILE="/var/lib/private/systemd/timesync/clock"
587        fi
588        # Fix for debian stretch
589        if [ ! -e "${SYNCHRONIZED_FILE}" ]; then
590            SYNCHRONIZED_FILE="/var/lib/systemd/clock"
591        fi
592        if [ -e "${SYNCHRONIZED_FILE}" ]; then
593           FIND=$(( $(date +%s) - $(${STATBINARY} -L --format %Y "${SYNCHRONIZED_FILE}") ))
594           # Check if last sync was more than 2048 seconds (= the default of systemd) ago
595           if [ "${FIND}" -ge 2048 ]; then
596               COLOR=RED
597               ReportWarning "${TEST_NO}" "systemd-timesyncd did not synchronized the time recently."
598           else
599               COLOR=GREEN
600           fi
601           Display --indent 2 --text "- Last time synchronization" --result "${FIND}s" --color "${COLOR}"
602           LogText "Result: systemd-timesyncd synchronized time ${FIND} seconds ago."
603        else
604           Display --indent 2 --text "- Last time synchronization" --result "${STATUS_NOT_FOUND}" --color RED
605           ReportWarning "${TEST_NO}" "systemd-timesyncd never successfully synchronized time"
606        fi
607    fi
608    unset SYNCHRONIZED_FILE
609
610#
611#################################################################################
612#
613
614    Report "ntp_config_found=${NTP_CONFIG_FOUND}"
615    Report "ntp_config_type_daemon=${NTP_CONFIG_TYPE_DAEMON}"
616    Report "ntp_config_type_eventbased=${NTP_CONFIG_TYPE_EVENTBASED}"
617    Report "ntp_config_type_scheduled=${NTP_CONFIG_TYPE_SCHEDULED}"
618    Report "ntp_config_type_startup=${NTP_CONFIG_TYPE_STARTUP}"
619    Report "ntp_daemon=${NTP_DAEMON}"
620    Report "ntp_daemon_running=${NTP_DAEMON_RUNNING}"
621#
622#################################################################################
623#
624    # For VMs check ntpd.conf : tinker panic 0
625
626    # OS        Time daemons  Configuration file
627    # --------------------------------------------
628    # AIX       xntpd         /etc/ntp.conf
629    # HP
630    # Linux     ntpd          /etc/ntp.conf
631    #           chrony        /etc/chrony.conf
632    # OpenBSD   ntpd          /etc/ntpd.conf
633    # Solaris   xntpd         /etc/inet/ntp.conf
634
635    WaitForKeyPress
636
637#
638#================================================================================
639# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com
640