diff --git a/bin/install.sh b/bin/install.sh index c6c4fb02..473d909c 100755 --- a/bin/install.sh +++ b/bin/install.sh @@ -20,6 +20,11 @@ readonly myversion=98 # Major Changes (for details, see Github): # +# - V99 (Freek) +# - fixed some missing sudos +# - adapted to support newest openSUSE +# - added the https port 8443 +# # - V98 (Johannes) # - new web hpot (Mark Baggett) # - installer no longer requires root / better priv separation @@ -293,10 +298,11 @@ LOGFILE="${LOGDIR}/install_${INSTDATE}.log" SSHHONEYPORT=2222 TELNETHONEYPORT=2223 WEBHONEYPORT=8000 +HTTPSHONEYPORT=8443 SSHREDIRECT="22" TELNETREDIRECT="23 2323" WEBREDIRECT="80 8080 7547 5555 9000" -HONEYPORTS="${SSHHONEYPORT} ${TELNETHONEYPORT} ${WEBHONEYPORT}" +HONEYPORTS="${SSHHONEYPORT} ${TELNETHONEYPORT} ${WEBHONEYPORT} ${HTTPSHONYPORT}" # create and setup log directory if [ ! -d ${LOGDIR} ]; then @@ -654,6 +660,12 @@ if [ "$ID" == "opensuse-tumbleweed" ]; then distversion=Tumbleweed fi +if [ "$ID" == "opensuse-leap" ]; then + ID="opensuse" + dist='yum' + distversion=Leap +fi + dlog "dist: ${dist}, distversion: ${distversion}" if [ "$dist" == "invalid" ]; then @@ -769,12 +781,14 @@ if [ "$FAST" == "0" ]; then if [ "$ID" == "opensuse" ]; then outlog "Updating your openSUSE Operating System will now be done." + case $distversion in + esac sudorun 'zypper --non-interactive dup --no-recommends' outlog "Installing additional packages" - sudorun 'zypper --non-interactive install --no-recommends cron gcc libffi-devel python311-devel libopenssl-devel rsyslog dialog' + sudorun 'zypper --non-interactive install --no-recommends cron gcc libffi-devel python3-devel libopenssl-devel rsyslog dialog' sudorun 'zypper --non-interactive install --no-recommends perl-libwww-perl perl-Switch perl-LWP-Protocol-https python3-requests' sudorun 'zypper --non-interactive install --no-recommends python3-pycryptodome python3-virtualenv' - sudorun 'zypper --non-interactive install --no-recommends python311-pip rng-tools curl openssh unzip' + sudorun 'zypper --non-interactive install --no-recommends python3-pip rng-tools curl openssh unzip' sudorun 'zypper --non-interactive install --no-recommends net-tools-deprecated patch logrotate' sudorun 'zypper --non-interactive install --no-recommends system-user-mail mariadb libmariadb-devel python3-PyMySQL jq' sudorun 'zypper --non-interactive install --no-recommends python3-python-snappy snappy-devel gcc-c++' @@ -886,7 +900,7 @@ if [ -x /etc/init.d/cowrie ]; then fi # in case systemd is used outlog "Stopping cowrie via systemd" -sudo systemctl stop cowrie +[ "$(sudo systemcl is-active cowrie.service)" = "active" ] && sudo systemctl stop cowrie if [ "$FAST" == "0" ]; then @@ -980,16 +994,8 @@ EOF drun "cat /etc/modprobe.d/ipv6.conf.bak" drun "cat /etc/modprobe.d/ipv6.conf" else # in openSUSE - run "grep -q 'ipv6.conf' /etc/sysctl.d/70-yast.conf" - # shellcheck disable=SC2181 - if [ ${?} -ne 0 ]; then - dlog "Disabling IPv6 in /etc/sysctl.d/70-yast.conf" - dsudorun 'echo "net.ipv4.ip_forward = 0" >> /etc/sysctl.d/70-yast.conf' - dsudorun 'echo "net.ipv6.conf.all.forwarding = 0" >> /etc/sysctl.d/70-yast.conf' - dsudorun 'echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/70-yast.conf' - else - dlog "IPv6 already disabled in /etc/sysctl.d/70-yast.conf" - fi + iface=$(ip -4 route show | grep '^default ' | head -1 | cut -f5 -d' ') + dsudorun "nmcli device modify $iface ipv6.method 'disabled'" fi ########################################################### @@ -1001,7 +1007,8 @@ if ! grep -qE '^webhpot' /etc/passwd; then if [ "$ID" != "opensuse" ]; then sudorun 'adduser --gecos "Honeypot,A113,555-1212,555-1212" --disabled-password --quiet --home /srv/web --no-create-home webhpot' else - sudorun 'useradd -c "Honeypot,A113,555-1212,555-1212" -M -U -d /srv/web webhpot' + sudorun 'useradd -c "Honeypot,A113,555-1212,555-1212" -M -U -d /srv/web webhpot' + sudorun 'passwd -d webhpot' #disable password fi outlog "Added user 'webhpot'" else @@ -1778,7 +1785,7 @@ EOF else # use_iptables = False -> use nftables dlog "using nftables, not iptables" - cat > /etc/network/ruleset.nft < ${TMPDIR}/ruleset.nft <>/etc/network/ruleset.nft + echo "# allow ping from local network" >>${TMPDIR}/ruleset.nft echo "add rule ip filter INPUT iifname \"$interface\" ip saddr ${localnet} icmp type echo-request counter accept" >>"${TMPDIR}"/ruleset.nft # insert IPs and ports for which honeypot has to be disabled @@ -1928,24 +1935,53 @@ fi if [ "$INTERACTIVE" == 1 ]; then dlog "changing port for sshd" - run "sed \"s/^[#\s]*Port 22\s*$/Port ${SSHDPORT}/\" < /etc/ssh/sshd_config > ${TMPDIR}/sshd_config" - sudorun "mv ${TMPDIR}/sshd_config /etc/ssh/sshd_config" - - dlog "checking if modification was successful" - if [ "$(grep -c "^Port ${SSHDPORT}$" /etc/ssh/sshd_config)" -ne 1 ]; then - dialog --title 'sshd port' --ok-label 'Understood.' --cr-wrap --msgbox "Congrats, you had already changed your sshd port to something other than 22. - + if [ -f /etc/ssh/sshd_config ] ; then + run "sed \"s/^[#\s]*Port 22\s*$/Port ${SSHDPORT}/\" < /etc/ssh/sshd_config > ${TMPDIR}/sshd_config" + sudorun "mv ${TMPDIR}/sshd_config /etc/ssh/sshd_config" + dlog "checking if modification was successful" + if [ "$(grep -c "^Port ${SSHDPORT}$" /etc/ssh/sshd_config)" -ne 1 ]; then + dialog --title 'sshd port' --ok-label 'Understood.' --cr-wrap --msgbox "Congrats, you had already changed your sshd port to something other than 22. Please clean up and either - change the port manually to ${SSHDPORT} in /etc/ssh/sshd_config OR - clean up the firewall rules and other stuff reflecting YOUR PORT" 13 50 - clear + clear - dlog "check unsuccessful, port ${SSHDPORT} not found in sshd_config" - drun 'cat /etc/ssh/sshd_config | grep -v "^\$" | grep -v "^#"' - else - dlog "check successful, port change to ${SSHDPORT} in sshd_config" + dlog "check unsuccessful, port ${SSHDPORT} not found in sshd_config" + drun 'cat /etc/ssh/sshd_config | grep -v "^\$" | grep -v "^#"' + else + dlog "check successful, port change to ${SSHDPORT} in sshd_config" + fi + else # when /etc/ssh/sshd_config does not exist + if [ "$(cat /etc/ssh/sshd_config.d/*.conf | grep -c "^Port ${SSHDPORT}\$")" -ne 0 ] ; then + dlog "check succesfull, port changed to ${SSHDPORT} in a file in /etc/ssh/sshd.config.d/" + else + if [ -n "$(cat /etc/ssh/sshd_config.d/*.conf)" ] && [ "$(cat /etc/ssh/sshd_config.d/*.conf | grep -c "^Port ")" -ge 1 ] ; then + dialog --title 'sshd port' --ok-label 'Understood.' --cr-wrap --msgbox "Congrats, you had already changed your sshd port to something other than 22. +Please clean up and either + - change the port manually to ${SSHDPORT} + in a file in /etc/ssh/sshd_config.d/*.conf OR + - clean up the firewall rules and + other stuff reflecting YOUR PORT" 13 50 + clear + else # a file Port*.conf does not exist + echo "Port ${SSHDPORT}" > "${TMPDIR}"/Port_${SSHDPORT}.conf + sudorun "mv ${TMPDIR}/Port_${SSHDPORT}.conf /etc/ssh/sshd_config.d/" + sudorun "chown root:root /etc/ssh/sshd_config.d/Port_${SSHDPORT}.conf" + if [ -x /usr/sbin/getenforce ] ; then + if [ "$(sudo /usr/sbin/getenforce)" = "Enforcing" ] ; then + if [ ! -x /usr/sbin/semanage ] ; then + sudorun "zypper --non-interactive in --no-recommends policycoreutils-python-utils" + else + echo "ERROR utility semanage needs to be installed, exiting!!" + exit 9 + fi + fi + sudorun "semanage port -a -t ssh_port_t -p tcp ${SSHDPORT}" + fi + fi + fi fi fi # interactive ########################################################### @@ -1964,7 +2000,7 @@ fi -dsudorun 'cat /etc/rsyslog.d/dshield.conf' +dsudorun 'cat /etc/rsyslog.d/10-dshield.conf' ########################################################### ## Further copying / configuration @@ -1987,7 +2023,8 @@ if ! grep -qE '^webhpot' /etc/passwd; then if [ "$ID" != "opensuse" ]; then sudorun 'adduser --gecos "Honeypot,A113,555-1212,555-1212" --disabled-password --quiet --home /srv/web --no-create-home webhpot' else - sudorun 'useradd -c "Honeypot,A113,555-1212,555-1212" -M -U -d /srv/web webhpot' + sudorun 'useradd -c "Honeypot,A113,555-1212,555-1212" -M -U -d /srv/web webhpot' + sudorun 'passwd -d webhpot' # disable password fi outlog "Added user 'webhpot'" else @@ -2022,8 +2059,9 @@ if [ -f ${DSHIELDDIR}/updatehoneypotip.sh ]; then run "rm ${DSHIELDDIR}/updatehoneypotip.sh" fi do_copy "$progdir"/updatehoneypotip.sh ${DSHIELDDIR} 700 -[ "$ID" = "opensuse" ] && +if [ "$ID" = "opensuse" ]; then run "patch ${DSHIELDDIR}/DShield.py $progdir/../srv/dshield/DShield.patch" +fi # check: automatic updates allowed? @@ -2164,6 +2202,7 @@ if ! grep '^cowrie:' -q /etc/passwd; then sudorun 'adduser --gecos "Honeypot,A113,555-1212,555-1212" --disabled-password --quiet --home /srv/cowrie --no-create-home cowrie' else sudorun 'useradd -c "Honeypot,A113,555-1212,555-1212" -M -U -d /srv/cowrie cowrie' + sudorun 'passwd -d cowrie' # disable password fi outlog "Added user 'cowrie'" else @@ -2176,10 +2215,15 @@ sudorun "usermod -a -G cowrie ${SYSUSERNAME}" # step 3 (Checkout the code) # (we will stay with zip instead of using GIT for the time being) dlog "downloading and unzipping cowrie" -if [ "$BETA" == 1 ]; then - run "$CURL https://www.dshield.org/cowrie-beta.zip > ${TMPDIR}/cowrie.zip" +if [ "$ID" != "opensuse" ] ; then + if [ "$BETA" == 1 ]; then + run "$CURL https://www.dshield.org/cowrie-beta.zip > ${TMPDIR}/cowrie.zip" + else + run "$CURL -m 60 --connect-timeout 5 https://www.dshield.org/cowrie.zip > ${TMPDIR}/cowrie.zip" + fi else - run "$CURL -m 60 --connect-timeout 5 https://www.dshield.org/cowrie.zip > ${TMPDIR}/cowrie.zip" + # the version of cowrie on dshield.org is too old for openSUSE + run "git clone https://github.com/cowrie/cowrie.git" ${TMPDIR}/cowrie fi # shellcheck disable=SC2181 @@ -2187,11 +2231,18 @@ if [ ${?} -ne 0 ]; then outlog "Something went wrong downloading cowrie, ZIP corrupt." exit 9 fi -if [ -f "${TMPDIR}"/cowrie.zip ]; then - run "unzip -qq -d ${TMPDIR} ${TMPDIR}/cowrie.zip " +if [ "$ID" != "opensuse" ] ; then + if [ -f "${TMPDIR}"/cowrie.zip ]; then + run "unzip -qq -d ${TMPDIR} ${TMPDIR}/cowrie.zip " + else + outlog "Can not find cowrie.zip in ${TMPDIR}" + exit 9 + fi else - outlog "Can not find cowrie.zip in ${TMPDIR}" - exit 9 + if [ ! -d "${TMPDIR}"/cowrie ] ; then + outlog "Can not find directory cowrie in ${TMPDIR}" + exit 9 + fi fi # @@ -2254,6 +2305,8 @@ if [ "$FAST" == "0" ]; then run 'sg cowrie -c "pip3 install --require-virtualenv --upgrade bcrypt"' run 'sg cowrie -c "pip3 install --require-virtualenv --upgrade requests"' run 'sg cowrie -c "pip3 install --require-virtualenv -r requirements.txt"' + run 'sg cowrie -c "pip3 install --require-virtualenv dateutils"' + run 'sg cowrie -c "pip3 install --require-virtualenv -e ."' # shellcheck disable=SC2181 if [ ${?} -ne 0 ]; then outlog "Error installing dependencies from requirements.txt. See ${LOGFILE} for details." @@ -2282,7 +2335,8 @@ outlog "Doing further cowrie configuration." # step 6 (Generate a DSA key) dlog "generating cowrie SSH host key" -sudorun "ssh-keygen -t dsa -b 1024 -N '' -f ${COWRIEDIR}/var/lib/cowrie/ssh_host_dsa_key " +# dsa is too insecure and possibly not supported anymore in ssh-keygen; so use rsa +sudorun "ssh-keygen -t rsa -b 1024 -N '' -f ${COWRIEDIR}/var/lib/cowrie/ssh_host_rsa_key " # step 5 (Install configuration file) dlog "copying cowrie.cfg and adding entries" @@ -2315,13 +2369,20 @@ dlog "creating output for text commands" sudorun "mkdir -p ${TXTCMDS}/bin" sudorun "mkdir -p ${TXTCMDS}/usr/bin" -sudorun "df > ${TXTCMDS}/bin/df" -sudorun "dmesg > ${TXTCMDS}/bin/dmesg" -sudorun "mount > ${TXTCMDS}/bin/mount" -sudorun "ulimit > ${TXTCMDS}/bin/ulimit" -sudorun "lscpu > ${TXTCMDS}/usr/bin/lscpu" -sudorun "echo '-bash: emacs: command not found' > ${TXTCMDS}/usr/bin/emacs" -sudorun "echo '-bash: locate: command not found' > ${TXTCMDS}/usr/bin/locate" +sudorun "df > ${TMPDIR}/df" +sudorun "mv ${TMPDIR}/df ${TXTCMDS}/bin/df" +sudorun "dmesg > ${TMPDIR}/dmesg" +sudorun "mv ${TMPDIR}/dmesg ${TXTCMDS}/bin/dmesg" +sudorun "mount > ${TMPDIR}/mount" +sudorun "mv ${TMPDIR}/mount ${TXTCMDS}/bin/mount" +run "ulimit > ${TMPDIR}/ulimit" +sudorun "mv ${TMPDIR}/ulimit ${TXTCMDS}/bin/ulimit" +sudorun "lscpu > ${TMPDIR}/lscpu" +sudorun "mv ${TMPDIR}/lscpu ${TXTCMDS}/usr/bin/lscpu" +sudorun "echo '-bash: emacs: command not found' > ${TMPDIR}/emacs" +sudorun "mv ${TMPDIR}/emacs ${TXTCMDS}/usr/bin/emacs" +sudorun "echo '-bash: locate: command not found' > ${TMPDIR}/locate" +sudorun "mv ${TMPDIR}/locate ${TXTCMDS}/usr/bin/locate" sudorun "chown -R cowrie:cowrie ${COWRIEDIR}" @@ -2330,7 +2391,19 @@ sudorun "chown -R cowrie:cowrie ${COWRIEDIR}" dlog "copying cowrie system files" sudo_copy "$progdir"/../lib/systemd/system/cowrie.service /lib/systemd/system/cowrie.service 644 +# file copied/added from previous version of cowrie +sudo_copy "$progdir"/../srv/cowrie/bin/cowrie /srv/cowrie/bin/cowrie +sudorun chmod cowrie:cowrie /srv/cowrie/bin/cowrie sudo_copy "$progdir"/../etc/cron.hourly/cowrie /etc/cron.hourly 755 +if [ "$ID" = opensuse ] ; then + # add some selinux policy rules to let cowrie.service succeed + #sudo_copy "$progdir"/../etc/cowrie.pp /etc/ 644 + #sudo_copy "$progdir"/../etc/cowrie1.pp /etc/ 644 + #sudorun semodule -i /etc/cowrie.pp + #sudorun semodule -i /etc/cowrie1.pp + sudorun semanage fcontext -a -t bin_t /srv/cowrie/bin/cowrie + sudorun restorecon -vR /srv/cowrie/bin/cowrie +fi # make sure to remove old cowrie start if they exist if [ -f /etc/init.d/cowrie ]; then @@ -2347,7 +2420,8 @@ sudorun 'systemctl daemon-reload' sudorun 'systemctl enable cowrie.service' dlog 'deactivate cowrie venv' -sudorun 'deactivate' +#sudorun 'deactivate' +run deactivate ########################################################### @@ -2372,7 +2446,9 @@ sudo -u webhpot find ./isc_agent -mindepth 1 -type d -exec rm -rf {} + sudo_copy "${progdir}"/../srv/web/web-honeypot.service /etc/systemd/system/web-honeypot.service 644 cd "${WEBHPOTDIR}" || exit # disable old service in case it is still enabled -sudorun "systemctl disable isc-agent.service" +if [ "$(sudo systemctl is-enabled isc-agent.service)" = "enabled" ] ; then + sudorun "systemctl disable isc-agent.service" +fi # enable new service sudorun "systemctl daemon-reload" sudorun "systemctl enable web-honeypot.service" @@ -2542,7 +2618,7 @@ run 'mkdir -p /var/tmp/dshield' # rotate dshield firewall logs sudo_copy "$progdir"/../etc/logrotate.d/dshield /etc/logrotate.d 644 -[ "$ID" = "opensuse" ] && sed -e 's/\/usr\/lib.*$/systemctl reload rsyslog/' -i /etc/logrotate.d/dshield +[ "$ID" = "opensuse" ] && sudo sed -e 's/\/usr\/lib.*$/systemctl reload rsyslog/' -i /etc/logrotate.d/dshield if [ -f "/etc/cron.daily/logrotate" ]; then sudorun "mv /etc/cron.daily/logrotate /etc/cron.hourly" fi @@ -2568,7 +2644,7 @@ fi ########################################################### if [ -f /root/bin/postinstall.sh ]; then - run "/root/bin/postinstall.sh" + sudorun "/root/bin/postinstall.sh" else outlog outlog diff --git a/bin/makecert.sh b/bin/makecert.sh index 25ba0ebb..6bbecc09 100755 --- a/bin/makecert.sh +++ b/bin/makecert.sh @@ -14,16 +14,21 @@ if [ ! -f ${d}/../etc/CA/ca.serial ]; then echo -n $serial > "${d}/../etc/CA/ca.serial" fi -if [ -f $d/../etc/dshield.sslca ] ; then - . $d/../etc/dshield.sslca -else - country="US" - state="Florida" - city="Jacksonville" - company="DShield" - depart="Decoy" +dshieldsslca="/etc/dshield.sslca" +if [ ! -f $dshieldsslca ] ; then + dshieldsslca="$d/../etc/dshield.sslca" fi -hostname=$(hostname); +if [ -f $dshieldsslca ] ; then + . $dshieldsslca +fi +if [ -z "$country" ] ; then + country="US" + state="Florida" + city="Jacksonville" + company="DShield" + depart="Decoy" +fi +hostname=$(hostname) if [ "$interactive" -eq "1" ]; then exec 3>&1 dialog --title 'Creating SSL Certificate' --separate-widget $'\n' --form\ @@ -47,6 +52,7 @@ if [ "$interactive" -eq "1" ]; then echo "city=\"$city\"" >> $d/../etc/dshield.sslca echo "company=\"$company\"" >> $d/../etc/dshield.sslca echo "depart=\"$department\"" >> $d/../etc/dshield.sslca + sudo cp $d/../etc/dshield.sslca /etc/dshield.sslca } fi if [ ! -d $d/../etc/CA/keys ]; then diff --git a/bin/status.sh b/bin/status.sh index bdaef07e..85fa5491 100755 --- a/bin/status.sh +++ b/bin/status.sh @@ -128,7 +128,7 @@ fi if echo $status | grep -q 'ok'; then echo "${GREEN}API Key configuration ok${NC}" if [ "$version" != "" ]; then - currentversion=$(echo $status | egrep -o '([0-9\.]+)' | egrep -o '[0-9\.]+') + currentversion=$(echo $status | grep -E -o '([0-9\.]+)' | grep -E -o '[0-9\.]+') if [ "$currentversion" != "$version" ]; then echo " ${RED}Software Version Mismatch diff --git a/bin/update.sh b/bin/update.sh index 174e0013..382954ed 100755 --- a/bin/update.sh +++ b/bin/update.sh @@ -49,7 +49,7 @@ hash=`echo -n $email:$apikey | openssl dgst -hmac $nonce -sha512 -hex | cut -f2 checkapikey=$(curl -s https://isc.sans.edu/api/checkapikey/$user/$nonce/$hash/$version/$piid) if echo $checkapikey | grep -q 'ok'; then echo "API Key OK" - newversion=$(echo $checkapikey | egrep -o '[^<]+'|egrep -o '[0-9]+') + newversion=$(echo $checkapikey | grep -E -o '[^<]+'|grep -E -o '[0-9]+') else echo "Bad API Key. check API key in /etc/dshield.ini" exit diff --git a/bin/updatehoneypotip.sh b/bin/updatehoneypotip.sh index 1d458941..3daec414 100755 --- a/bin/updatehoneypotip.sh +++ b/bin/updatehoneypotip.sh @@ -8,17 +8,18 @@ if [ ! "$userid" = "0" ]; then exit 9 fi -if [ ! -f /srv/dshield/etc/dshield.ini ]; then - echo "missing /srv/dshield/etc/dshield.ini file" +if [ ! -f /etc/dshield.ini ]; then + echo "missing /etc/dshield.ini file" exit 9 fi honeypotip=$(curl -s https://www4.dshield.org/api/myip?json | jq .ip | tr -d '"') -if echo -n $honeypotip | egrep -q '^[0-9\.]+$'; then - sed -i "s/^honeypotip=.*/honeypotip=$honeypotip/" /srv/dshield/etc/dshield.ini - if ! grep -q '^piid=' dshield.ini; then - piid=$(openssl rand -hex 10) - sed -i "^apikey/a piid=$piid" /srv/dshield/etc/dshield.ini +if echo -n $honeypotip | grep -E -q '^[0-9\.]+$'; then + sed -i "s/^honeypotip=.*/honeypotip=$honeypotip/" /etc/dshield.ini + if ! grep -q '^piid=' /etc/dshield.ini; then + piid=$(openssl rand -hex 10) + sed -i "^apikey/a piid=$piid" /etc/dshield.ini fi + cp /etc/dshield.ini /srv/dshield/etc/ else echo "Bad IP address" exit 9 diff --git a/docs/install-instructions/openSUSE.md b/docs/install-instructions/openSUSE.md index 9a36cbb4..ec5e53cf 100644 --- a/docs/install-instructions/openSUSE.md +++ b/docs/install-instructions/openSUSE.md @@ -7,27 +7,29 @@ This is a set of scripts to setup a Raspberry Pi as a DShield Sensor. Current design goals and prerequisites for using the automated installation procedure: - use of a __dedicated__ device (Raspberry Pi, any model as [per](https://isc.sans.edu/forums/diary/Using+a+Raspberry+Pi+honeypot+to+contribute+data+to+DShieldISC/22680/)) -- current openSUSE system for Raspberry Pi (JeOS version will suffice) +- current openSUSE system for Raspberry Pi (JeOS version for Tumbleweed or Minimal Image of Leap 16.0 will suffice) - easy installation / configuration (and therefor not that much configurable) - disposable (when something breaks (e.g. during upgrade): re-install from scratch) - minimize complexity and overhead (e.g. no virtualization like docker) - support for IPv4 only (for the internal net) - one interface only (e.g. eth0) -The current version is tested on openSUSE Tumbleweed. +The current version is tested on openSUSE Tumbleweed and Leap 16.0. ## Installation In order to use the installation script on the Raspberry Pi, you will need to first prepare it. For openSUSE it is assumed that you are using openSUSE for this preparation. -- get the openSUSE image for your Raspberry Pi for Tumbleweed [RPi3 and RPi4 from](http://download.opensuse.org/ports/aarch64/tumbleweed/appliances/openSUSE-Tumbleweed-ARM-JeOS-raspberrypi3.aarch64.raw.xz) +- get the openSUSE image for your Raspberry Pi for Tumbleweed [RPi3 and RPi4 from](https://download.opensuse.org/ports/aarch64/tumbleweed/appliances/openSUSE-Tumbleweed-ARM-JeOS-raspberrypi.aarch64.raw.xz) +- for Leap 16.0 [aarch64](https://download.opensuse.org/distribution/leap/16.0/appliances/Leap-16.0-Minimal-Image.aarch64-RaspberryPi-Build16.2.raw.xz) - put it onto a micro-SD card (e.g. using procedures described [here for RPi3](https://en.opensuse.org/HCL:Raspberry_Pi3) or [here for RPi4](https://en.opensuse.org/HCL:Raspberry_Pi4) +- similar procedure for Leap 16.0. - insert the micro-SD card in the Pi and power it on, to boot the Pi from the micro-SD card. - the system will use DHCP to get network parameters o.a. the IP address. -- if you do not have a monitor connected you will be able to use ssh to connect. -- connect to the device using a ssh client (port 22), log in with user *root*, password *linux* -- __CHANGE THE DEFAULT PASSWORD__ for the *root* user (better: use keys to authenticate and set *PermitRootLogin* to *prohibit-password* in */etc/ssh/sshd_config*) +- if you do not have a monitor and keyboard connected you will be able to use ssh to connect. However for Leap 16.0 you do need that or a connection via the serial interface to configure access via ssh. +- connect to the device using a ssh client (port 22), log in with user *root*, password *linux* or for Leap 16.0 with the configured access data. +- __CHANGE THE DEFAULT PASSWORD__ for the *root* user (better: use keys to authenticate and change yes for *PermitRootLogin* to *prohibit-password* in */etc/ssh/sshd_config.d/PermitRootLogin.conf*) *passwd* *new pw* @@ -35,26 +37,49 @@ In order to use the installation script on the Raspberry Pi, you will need to fi - make sure the Pi can reach out to the Internet using http(s), can resolve DNS, ... (DHCP) - you may use the command *yast language* to set your language as the default language, the layout of the keyboard and the timezone. -- The first thing the install script will do is update the system. - - For Tumbleweed it uses: - *zypper dup --no-interactive --no-recommends* +- give your system a proper name with: -- reboot + echo *"dshonypot" > /etc/hostname* - *shutdown -r now* +- the DSield system needs to be installed from a normal user, on the **Raspberry Pi OS** there is already the account pi, but on openSUSE you need to create such an account with: + + *useradd -c 'DShield maintenace' -m -U dsmaint* + +- set the password for this account with: + + *passwd dsmaint* + +- this account needs a lot of sudo to generate the DShield honypot. This is best served with a sudoers definition: + *echo "dsmaint ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/dsmaint* + *chmod 600 /etc/sudoers.d/dsmaint* -- if GIT isn't already installed (will be the case with the JeOS images): install GIT +- if GIT isn't already installed (it is not installed in the JeOS images): install GIT *zypper in --no-recommends git* +- git will download the DShield system and contains an install script to install that system. + - the first thing the install script will do is update the system. + - It is recommended to do this before running the install script. + - For Tumbleweed the next command line will do that, after that restart the system with: + + *zypper --non-interactive dup --no-recommends* + *reboot* + or + *shutdown -r now* + +After this restart, you need to login as user dsmaint or as root, and become the user dsmain with: + + *su - dsmaint* + - get GIT repository - git clone https://github.com/Dshield-ISC/dshield.git + **git clone https://github.com/Dshield-ISC/dshield.git** -– in case you do a reinstall of a previous system, you should have saved the files `/etc/dshield.ini` and `/etc/dshield.sslca`, copy these files in the same locations; when you run the installation script answers are filled in and you only need to acknowledge the questions - -- run the installation script +– in case you do a reinstall of a previous system, you should have saved the files `/etc/dshield.ini` and `/etc/dshield.sslca`, copy these files in the same locations; when you run the installation script answers are filled in and you only need to acknowledge the questions. + + +- run the installation script as user dsmaint: *cd dshield/bin* *./install.sh* diff --git a/srv/cowrie/bin/cowrie b/srv/cowrie/bin/cowrie new file mode 100755 index 00000000..17970876 --- /dev/null +++ b/srv/cowrie/bin/cowrie @@ -0,0 +1,240 @@ +#!/bin/bash +################################################################################ +# Don't edit this file +# +# Environment variables can be passed to change how this script runs. +# +# Set `COWRIE_VIRTUAL_ENV=my-env` to use a particular virtual environment. +# By default Cowrie will look for `cowrie-env` in the current or parent +# directory. +# +# Set `COWRIE_STDOUT=yes` to run in foreground mode and send logs to stdout +# +# Pass any other config variable as well, to further setup your environment! +# For example: `COWRIE_TELNET_ENABLED=yes` +################################################################################ + +DEFAULT_VIRTUAL_ENV=cowrie-env + +first_time_use() { + echo + echo "Join the Cowrie community at: https://www.cowrie.org/slack/" + echo +} + +python_version_warning() { + if python -V 2>&1 | grep -q '^Python 2.'; then + echo + echo "DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020." + echo "Cowrie has dropped support for Python 2.7." + echo + fi + if python -V 2>&1 | grep -q '^Python 3.5'; then + echo + echo "DEPRECATION: Python 3.5 is no longer supported by Cowrie." + echo + fi +} + +find_cowrie_directory() { + # Determine Cowrie directory + if [[ "$0" = /* ]] + then + COWRIEDIR=$(dirname $0)/.. + else + COWRIEDIR=$(dirname $PWD/$0)/.. + fi + COWRIEDIR=$(cd ${COWRIEDIR} && pwd -P 2>/dev/null || pwd) +} + +activate_venv() { + # Activate Python virtual environment + VENV="$1" + if [ ! -f "$VENV/bin/activate" ] + then + return 1 + fi + . $VENV/bin/activate + return 0 +} + +cowrie_status() { + # Print status + PID=$(cat ${PIDFILE} 2>/dev/null || echo "") + if [ -n "$PID" ]; then + if ps -p "$PID" 2>&1 >/dev/null; then + echo "cowrie is running (PID: ${PID})." + else + echo "cowrie is not running (PID: ${PID})." + echo "Removing stale PID file ${PIDFILE}" + rm -f ${PIDFILE} + fi + else + echo "cowrie is not running." + fi +} + +cowrie_start() { + # Start Cowrie + COWRIEARGS="$*" + TWISTEDARGS="${XARGS} --umask=0022 --pidfile=${PIDFILE}" + + # Run foreground or background. Foreground has no file log. + if [ "$COWRIE_STDOUT" = "yes" ]; then + TWISTEDARGS="${TWISTEDARGS} -n -l -" + else + TWISTEDARGS="${TWISTEDARGS} --logger cowrie.python.logfile.logger" + fi + + # 1. Check if any virtual environment is active + # 2. Try COWRIE_VIRTUAL_ENV if defined + # 3. Try DEFAULT_VIRTUAL_ENV + # 4. Try ../DEFAULT_VIRTUAL_ENV + # 5. Try without virtual environment + + if [ ! -z "$VIRTUAL_ENV" ]; then + echo 2>&1 "Using activated Python virtual environment \"$VIRTUAL_ENV\"" + elif activate_venv "$COWRIE_VIRTUAL_ENV"; then + echo 2>&1 "Using custom Python virtual environment \"$VIRTUAL_ENV\"" + elif activate_venv "$DEFAULT_VIRTUAL_ENV"; then + echo 2>&1 "Using default Python virtual environment \"$VIRTUAL_ENV\"" + # Look one directory higher for the virtual env to not pollute the Cowrie dir + elif activate_venv "../$DEFAULT_VIRTUAL_ENV"; then + echo 2>&1 "Using default Python virtual environment \"../$VIRTUAL_ENV\"" + else + echo 2>&1 "Not using Python virtual environment" + fi + + python_version_warning + + # Automatically check if the authbind is enabled or not + authfile="/etc/authbind/byport/22" + if [ -z ${AUTHBIND_ENABLED} ] && [ -x "$authfile" ] && command -v authbind >/dev/null; then + AUTHBIND_ENABLED=yes + else + AUTHBIND_ENABLED=no + fi + + echo "Starting cowrie: [twistd ${TWISTEDARGS} cowrie ${COWRIEARGS}]..." + if [ "$AUTHBIND_ENABLED" = "no" ] + then + exec twistd ${TWISTEDARGS} ${COWRIEARGS} cowrie + else + exec authbind --deep twistd ${TWISTEDARGS} ${COWRIEARGS} cowrie + fi +} + +cowrie_stop () { + # Stop Cowrie + PID=$(cat ${PIDFILE} 2>/dev/null || echo "") + if [ -n "$PID" ]; then + echo "Stopping cowrie..." + if kill -TERM $PID; then + echo -n + else + echo "Removing stale PID file ${PIDFILE}" + rm -f ${PIDFILE} + fi + else + echo "cowrie is not running." + fi +} + +cowrie_force_stop () { + # Force Stop Cowrie + PID=$(cat ${PIDFILE} 2>/dev/null || echo -n "") + if [ -n "$PID" ]; then + echo -n "Stopping cowrie..." + if kill -TERM $PID; then + ((t = 60)) + while ((t > 1)); do + sleep 1 + echo -n . + if kill -0 $PID 2>/dev/null; then + ((t -= 1)) + else + echo "terminated." + return + fi + done + kill -KILL $PID + echo "killed." + else + echo "Removing stale PID file ${PIDFILE}" + rm -f ${PIDFILE} + fi + else + echo "cowrie is not running." + fi +} + +cowrie_usage() { + echo "usage: $0 " +} + +# Mostly for Docker use, to quickly get a shell in the container +cowrie_shell() { + $SHELL +} + +################################################################################ +## Main script +################################################################################ + +if [ "$#" = 0 ] +then + cowrie_usage + exit 1 +fi + +find_cowrie_directory $0 +cd ${COWRIEDIR} +export PYTHONPATH=${PYTHONPATH}:${COWRIEDIR}/src + +set -e + +# Don't store pidfile on Docker persistent volume +if [ "${COWRIE_STDOUT}" = "yes" ]; then + PIDFILE="" +else + PIDFILE=var/run/cowrie.pid +fi + +if [ ! -f ${COWRIEDIR}/var/log/cowrie/cowrie.log ] +then + first_time_use +fi + +key=$1 +shift 1 +case $key in + stop) + cowrie_stop $* + ;; + force-stop) + cowrie_force_stop $* + ;; + start) + cowrie_start $* + ;; + restart) + cowrie_stop $* + cowrie_start $* + ;; + status) + cowrie_status $* + ;; + bash) + cowrie_shell $* + ;; + sh) + cowrie_shell $* + ;; + shell) + cowrie_shell $* + ;; + *) + cowrie_usage + exit 1 + ;; +esac diff --git a/srv/dshield/DShield.patch b/srv/dshield/DShield.patch index 7116c16f..4b8ddbda 100644 --- a/srv/dshield/DShield.patch +++ b/srv/dshield/DShield.patch @@ -1,11 +1,11 @@ ---- /srv/dshield/DShield.py 2021-11-06 12:42:10.524316474 +0100 -+++ /omcc/dshield/DShield.py 2021-11-02 18:19:16.653303356 +0100 +--- DShield.py 2025-10-22 00:01:58.037027995 +0200 ++++ DShield.py 2025-10-20 11:23:29.557128402 +0200 @@ -34,7 +34,7 @@ types = ['email', 'firewall', 'sshlogin', 'telnetlogin', '404report', 'httprequest', 'webhoneypot'] - logtypesregex={'generic': '^([A-Z][a-z]{2})\s+([0-9]+)\s([0-9:]+).*(IN=.*)', -- 'pi': '(^\d+) \S+ kernel:\[[0-9\. ]+\]\s+DSHIELDINPUT IN=\S+ .* (SRC=.*)', -+ 'pi': '(^\d+) \S+ kernel:\[[0-9\. ]+\]\[\s*\w*\]\s+DSHIELDINPUT IN=\S+ .* (SRC=.*)', - 'aws': '(^\d+) \S+ kernel: DSHIELDINPUT IN=\S+ .* (SRC=.*)'} + logtypesregex={'generic': r'^([A-Z][a-z]{2})\s+([0-9]+)\s([0-9:]+).*(IN=.*)', +- 'pi': r'(^\d+) \S+ kernel:\[[0-9\. ]+\]\s+DSHIELDINPUT IN=\S+ .* (SRC=.*)', ++ 'pi': r'(^\d+) \S+ kernel:\[[C0-9\. ]+\]\s+DSHIELDINPUT IN=\S+ .* (SRC=.*)', + 'iptables': r'(^\d+) \S+ kernel:\s+DSHIELDINPUT IN=\S+ .* (SRC=.*)', + 'aws': r'(^\d+) \S+ kernel: DSHIELDINPUT IN=\S+ .* (SRC=.*)'} authheader = '' -