cheatsheet.zwischenspeicher.info

Some tech documentation and snippets, finally organized.

Firefox word wrap / readability hack

Web pages that come with minimalistic HTML formatting or whose stylesheet(s) got caught by some filter are often difficult to read, due to their long lines - especially in maximized or full screen mode on modern wide-screen displays.

Mozilla's Firefox allows the use of a "custom default stylesheet", which makes it possible to define a maximum width for elements with continuous text. The CSS file has to be named userContent.css and resides under chrome/ in your Firefox profile folder.

These lines have proven to hardly ever interfere unfavorably with other stylesheets:

/* File: FF_PROFILE_FOLDER/chrome/userContent.css */

@-moz-document {}
body { margin-left: 40px; }
p, li, blockquote { max-width: 800px; }

The next even simpler solution centers the whole HTML body element in the browser window, but thus is more prone to corrupting pages that are styled otherwise (i.e. with fixed-width elements that exceed the defined max-width of in this case 800 Pixels):

/* File: FF_PROFILE_FOLDER/chrome/userContent.css */

@-moz-document {}
body { 
    max-width: 800px;
    margin: auto; 
}

Note that in both examples a fixed width property would make the lines run out of superordinate CSS elements respectively the browser window, if they are less wide than the defined value.

Chromium/Chrome has abandoned support for user stylesheets with version 33.

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.

APT: Prevent upgrading of particular packages

There are cases in which it is desirable to keep a certain package version, be it a forced downgrade or a custom build. Here I show several ways to achieve this.

The most simple possibility is to mark the package hold in the dpkg status file /var/lib/dpkg/status:

$ echo "PACKAGE_NAME hold" | dpkg set-selections

or, using apt-mark as wrapper:

$ apt-mark hold PACKAGE_NAME

To undo this and return the selected package to apt's default workflow, run

$ echo "PACKAGE_NAME installed" | dpkg set-selections

or, respectively:

$ apt-mark unhold PACKAGE_NAME

This is a very static solution and apt provides a much more flexible way of package handling, called pinning. It is configured in the file /etc/apt/preferences resp. in an arbitrary file in the /etc/apt/preferences.d/ directory.

Pinnig allows prioritization of package versions depending on factors like version number, repository or release name - wildcards and regular expressions are allowed. The most simple configuration for a single package, analog to the dpkg way described above, would look like this:

### File: /etc/apt/preferences 
###       OR
###       /etc/apt/preferences.d/SOMEFILE

Package:        PACKAGE_NAME
Pin:            version PACKAGE_VERSION
Pin-Priority:   1001

See the manpage apt_preferences(5) for a detailed description of all pinning possibilities.

Finally, for local builds it is possible to assign them a local version number, as I have described in this post, and pin, if necessary, based on that.

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