cheatsheet.zwischenspeicher.info

Some tech documentation and snippets, finally organized.
Posts tagged as script

Wireshark-readable tcpdump to remote disk

This line captures all packets on the network interface eth0 with source or destination TARGET_IP. To obtain a format readable by wireshark, tcpdump must be configured to not truncate packets. This is achieved by setting the -s flag to 0 or 65535 (maximum packet length in bytes).

The output is piped through ssh to OUTFILE on a remote host.

$ tcpdump -i eth0 -w - -s 0 host TARGET_IP |\
    ssh USER@HOST "cat > dump.pcap"

[Ctrl]+[c] to stop the capture...

To avoid packet dropping at high traffic volume, it may be reasonable to put the capturing computer as transparent bridge into the IP stream and use a logging host on an independent network, connected to an additional (third) network interface ethZ.

In one go:

#!/bin/sh

NIC1=ethX
NIC2=ethY
BRIDGE_IP=BRIDGE_IP
MASK=SUBNETMASK

TARGET_IP=TARGET_IP
SSHD=USER@LOGGINGHOST

#iptables-restore < /etc/iptables/bridge.v4

ifdown "$NIC1"
ifdown "$NIC2"
brctl addbr br0
brctl addif br0 "$NIC1"
brctl addif br0 "$NIC2"
ifconfig "$NIC1" 0.0.0.0
ifconfig "$NIC2" 0.0.0.0
ifconfig br0 "$BRIDGE_IP" netmask "$MASK" up

tcpdump -i "$NIC1" -w - -s 65535 host "$TARGET_IP" |\
    ssh "$SSHD" "cat > dump_`date +%H.%M.%S`.pcap"

Note: When running this script on a headless/remote machine (e.g. an OpenWRT router), double check its iptables rules and possible sshd restrictions to not lock you out or even brick the box.

Dynamic IP workaround

When running on a NATed computer (e.g. a NAS), this shell script checks an external service for the router's WAN IP in an configurable interval. Whenever it detects a change, an e-mail with the new IP address will be sent via msmtp. As long as the $APIURL is valid, only the $MAILTO definition needs to be adapted.

#!/bin/sh

MAILTO="YOUR_E-MAIL_ADDRESS"
MSG="Subject: Home IP\n\nCurrent IP: "
APIURL="http://api.ipify.org/"
INTERVAL="1800"
GETIP="/usr/bin/curl -s "$APIURL""
SENDCMD="/usr/bin/msmtp"

IP=`$GETIP`
printf "$MSG""$IP" | "$SENDCMD" "$MAILTO"
sleep "$INTERVAL"

while : ; do
    IPNEW=`$GETIP`
    if [ "$IPNEW" = "$IP" ] ; then
        sleep "$INTERVAL"
        IPNEW=`$GETIP`
    else
        IP="$IPNEW"
        echo "$MSG""$IP" | "$SENDCMD" "$MAILTO"
    fi
done

And here a simple msmtp configuration with TLS enabled – be aware that the mail password is stored on the host computer in plaintext.

### File: ~/.msmtprc or /etc/msmtprc

defaults
auth            on
tls             on
tls_starttls    off
tls_trust_file  /etc/ssl/certs/ca-certificates.crt
logfile         ~/.msmtp.log

account         ACCOUNT_1
host            SMTP_SERVER
user            USER_NAME
password        PASSWORD
from            FROM_ADDRESS

account default : ACCOUNT_1

Auto-upgrade for Debian based systems

A reliable auto-updater for home use. It can be executed e.g. at boot from /etc/rc.local to keep apt based systems up-to-date. Some output will be logged to /var/log/safe-upgrade.log, in case of upgraded or held packages as well as errors a report will be sent to root@localhost.

Update August, 2020: Command line option "--full" for Dist-Upgrade.
Update June, 2022: sleep-loop for delayed connections (dial-up, WiFi).

#!/bin/sh
#
# safe-upgrade.sh
#
# automated "safe-upgrade" for apt-based distributions with logging
# to /var/log/safe-upgrade.log and a mail to root@localhost in case
# of upgraded packages or problems
# optional command line parameter "--full" will run a dist-upgrade

pingtest=debian.org
hostname=`hostname`
logfile=/var/log/safe-upgrade.log
mailto=root@localhost

if [ X"$@" = X"--full" ] ; then
        task=dist-upgrade
else
        task=upgrade
fi

sleep 15
echo ----- `date` ----- >> "$logfile"
ping -c 1 "$pingtest" > /dev/null 2>> "$logfile" ||\
    {
        echo "System upgrade cancelled: No internet connection." |\
        tee -a "$logfile" |\
        mailx -s "$hostname"\ update\ \*\*\*ERROR\*\*\* "$mailto"
        exit 0
    }
DEBIAN_FRONTEND=noninteractive
apt-get -q=2 update 2>&1 |\
    tee -a "$logfile" |\
    mailx -E -s "$hostname"\ update\ \*\*\*ERROR\*\*\* "$mailto"
apt-get "$task" -y -q 2>&1 |\
    grep -ve "^(\{0,1\}Reading" \
         -e "^Building" \
         -e "^Calculating" |\
    tee -a "$logfile" |\
    grep -ve "^0 upgraded.*0 not upgraded\.$" |\
    mailx -E -s "$hostname"\ upgrade\ log "$mailto" &&
echo ----- DONE ----- >> "$logfile"
exit 0

To tame the daily growing log file, add the following lines to /etc/logrotate.conf or into an own file in /etc/logrotate.d/. This will keep compressed archives of the last three months' log files.

### File: /etc/logrotate.conf

/var/log/safe-upgrade.log {
    monthly
    create
    rotate 3
}

If you want the script to be executed by cron, it is necessary to set the $PATH variable - in the script itself, or in the crontab. This example runs every three hours at 45':

### File: root crontab, open to edit with "crontab -e"

# m h  dom mon dow   command
45 */3 * * * PATH='/usr/sbin:/usr/bin:/sbin:/bin' /path/to/safe-upgrade.sh