#!/bin/sh ################################################################################# # # Lynis # ------------------ # # Copyright 2007-2013, Michael Boelen # Copyright 2007-2021, CISOfy # # Website : https://cisofy.com # Blog : http://linux-audit.com # GitHub : https://github.com/CISOfy/lynis # # Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are # welcome to redistribute it under the terms of the GNU General Public License. # See LICENSE file for usage of this software. # ################################################################################# if [ $# -eq 0 ]; then Display --indent 2 --text "${RED}Error: ${WHITE}Provide a file${NORMAL}" Display --text " "; Display --text " " ExitFatal else FILE=$(echo $1 | grep -E "^http|https") if HasData "${FILE}"; then echo "Provide a file (not a URL)" ExitFatal else if [ -f $1 ]; then AUDIT_FILE="$1" else Display --indent 2 --text "File $1 does not exist" ExitFatal fi fi Display --indent 2 --text "File to audit = ${AUDIT_FILE}" fi ##################################################### # ################################################################################################## # InsertSection "${SECTION_IMAGE}" PKGMGR="" FIND=$(grep "^FROM" ${AUDIT_FILE} | sed 's/ /:space:/g') for I in ${FIND}; do IMAGE=$(echo ${I} | sed 's/:space:/ /g' | awk '{ if ($1=="FROM") { print $2 }}') TAG=$(echo ${IMAGE} | cut -d':' -f2) Display --indent 2 --text "Found image:" --result "${IMAGE}" IS_DEBIAN=$(echo ${IMAGE} | grep -i debian) IS_FEDORA=$(echo ${IMAGE} | grep -i fedora) IS_UBUNTU=$(echo ${IMAGE} | grep -i ubuntu) IS_ALPINE=$(echo ${IMAGE} | grep -i alpine) IS_LATEST=$(echo ${TAG} | grep -i latest) if [ -n "${IS_DEBIAN}" ]; then IMAGE="debian"; fi if [ -n "${IS_FEDORA}" ]; then IMAGE="fedora"; fi if [ -n "${IS_UBUNTU}" ]; then IMAGE="ubuntu"; fi if [ -n "${IS_ALPINE}" ]; then IMAGE="alpine"; fi if [ -n "${IS_LATEST}" ]; then ReportWarning "dockerfile" "latest TAG used. Specifying a targeted OS image and version is better for reproducible results." fi case ${IMAGE} in "debian") LogText "Image = Debian based" PKGMGR="apt" ;; "fedora*") LogText " Image = Fedora based" PKGMGR="yum" ;; "ubuntu") LogText " Image = Ubuntu based" PKGMGR="apt" ;; "alpine") LogText " Image = Alpine based" PKGMGR="apk" ;; *) Display --indent 2 --text "Unknown image" --result "" --color YELLOW ;; esac done # ################################################################################################## # InsertSection "${SECTION_BASICS}" MAINTAINER=$(grep -E -i "*MAINTAINER" ${AUDIT_FILE} | sed 's/=/ /g' | cut -d'"' -f 2) if [ -z "${MAINTAINER}" ]; then ReportWarning "dockerfile" "No maintainer found. Unclear who created this file." else Display --indent 2 --text "Maintainer" --result "${MAINTAINER}" fi ENTRYPOINT=$(grep "^ENTRYPOINT" ${AUDIT_FILE} | cut -d' ' -f2 ) if [ -z "${ENTRYPOINT}" ]; then ReportWarning "dockerfile" "No ENTRYPOINT defined in Dockerfile." else Display --indent 2 --text "ENTRYPOINT" --result "${ENTRYPOINT}" fi FIND=$(grep "^CMD" ${AUDIT_FILE} | cut -d' ' -f2 ) if [ -z "${FIND}" ]; then ReportWarning "dockerfile" "No CMD defines in Dockerfile." else CMD=$(echo ${FIND}) Display --indent 2 --text "CMD" --result "${CMD}" fi FIND=$(grep "^USER" ${AUDIT_FILE} | cut -d' ' -f2 ) if [ -z "${FIND}" ]; then ReportWarning "dockerfile" "No user declared in Dockerfile. Container will execute command as root" else USER=$(echo ${FIND}) Display --indent 2 --text "User" --result "${USER}" fi # ################################################################################################## # InsertSection "${SECTION_SOFTWARE}" case $PKGMGR in "apt") FIND=$(grep -E "apt-get(.*) install" ${AUDIT_FILE}) if [ ! "${FIND}" = "" ]; then LogText "Found installation via apt-get" else LogText "No installations found via apt-get" fi ;; "apk") FIND=$(grep -E "apk(.*) add" ${AUDIT_FILE}) if [ ! "${FIND}" = "" ]; then LogText "Found installation via apk" else LogText "No installations found via apk" fi ;; *) LogText "Unknown package manager" ;; esac FIND=$(grep -E " (gcc|libc6-dev|make)" ${AUDIT_FILE} | grep -v "^#") if [ ! "${FIND}" = "" ]; then ReportWarning "dockerfile" "Possible development utilities found, which is not advised for production environment" LogText "Details: ${FIND}" fi # SSH FIND_OPENSSH=$(grep openssh ${AUDIT_FILE}) if [ ! "${FIND_OPENSSH}" = "" ]; then Display --indent 2 --text "OpenSSH" --result "FOUND" --color RED ReportSuggestion "dockerfile" "Don't use OpenSSH in container, use 'docker exec' instead" fi # ################################################################################################## # InsertSection "${SECTION_DOWNLOADS}" FILE_DOWNLOAD=0 LogText "Checking usage of cURL" FIND_CURL=$(grep curl ${AUDIT_FILE}) if [ ! "${FIND_CURL}" = "" ]; then Display --indent 4 --text "Download tool" --result "curl" FILE_DOWNLOAD=1 fi LogText "Checking usage of wget" FIND_WGET=$(grep wget ${AUDIT_FILE}) if HasData "${FIND_WGET}"; then Display --indent 4 --text "Download tool" --result "wget" FILE_DOWNLOAD=1 fi FIND=$(grep "^ADD http" ${AUDIT_FILE}) if HasData "${FIND}"; then FILE_DOWNLOAD=1 ReportWarning "dockerfile" "Found download of file via ADD. Unclear if the integrity of this file is checked, or file is signed" LogText "Details: ${FIND}" fi if [ ${FILE_DOWNLOAD} -eq 1 ]; then SSL_USED_FIND=$(grep -E "(https)" ${AUDIT_FILE}) if HasData "${SSL_USED_FIND}"; then SSL_USED="YES" COLOR="GREEN" else SSL_USED="NO" COLOR="RED" ReportSuggestion "Use SSL downloads when possible to increase security (DNSSEC, HTTPS, validation of domain, avoid MitM)" fi Display --indent 2 --text "Integrity testing performed" --result "${SSL_USED}" --color ${COLOR} HASHING_USED=$(grep -E "(sha1sum|sha256sum|sha512sum)" ${AUDIT_FILE}) Display --indent 2 --text "Hashing" --result "${HASHING_USED}" KEYS_USED=$(grep -E "(apt-key adv)" ${AUDIT_FILE}| sed 's/RUN apt-key adv//g'| sed 's/--keyserver/Key Server:/g' | sed 's/--recv/Key Value:/g') Display --indent 2 --text "Signing keys used" --result "${KEYS_USED}" Display --indent 2 --text "All downloads properly checked" --result "?" else Display --indent 2 --text "No files seems to be downloaded in this Dockerfile" fi # ################################################################################################## # InsertSection "${SECTION_PERMISSIONS}" FIND=$(grep -i "chmod 777" ${AUDIT_FILE}) if HasData "${FIND}"; then ReportWarning "dockerfile" "Warning: chmod 777 found" fi # ################################################################################################## # # Removing temp file LogText "Action: Removing temporary file ${TMP_FILE}" if [ -f ${TMP_FILE} ]; then rm -f ${TMP_FILE} fi # The End