├── README.md ├── backup-mysql.sh ├── benchmarks ├── cgd_benchmark.sh ├── compress-test.sh ├── cryptsetup_benchmark.sh ├── cryptsetup_ciphertest.sh ├── fs-bench.conf ├── fs-bench.sh ├── geli_benchmark.sh ├── password-test.sh ├── ssh-performance.sh ├── test-digests.sh ├── tmpfs-ramfs-ramdisk.sh └── vbox-nic-bench.sh ├── checksum_file.sh ├── convert-music.sh ├── count.pl ├── diff2html.sh ├── expect ├── change-passwords.exp ├── e2fsck.exp └── rpb-ts.exp ├── find_dups.sh ├── funiq.sh ├── impressum.php ├── ip.php ├── ipsec_iproute.sh ├── keyboard-backlight.sh ├── mozilla ├── README.md ├── autoconfig.js ├── mozilla.cfg └── user.js ├── munin ├── plugin-conf.d │ ├── multiping │ ├── multips │ ├── munin-node │ └── tor_traffic └── plugins │ ├── adt746x_ │ ├── du_multidirs │ └── tor_traffic ├── port-mgmt.sh ├── qemu-tap.sh ├── rsnapshot ├── rsnapshot-ready.sh ├── rsnapshot-rotate.sh ├── rsnapshot-wrapper.conf ├── rsnapshot-wrapper.sh └── validate-rsync.sh ├── sensors_adt746x.sh ├── ternet ├── flip.pl ├── flop.sh └── iptables-ternet.sh ├── vbox-sysrq.sh └── xbindkeysrc /README.md: -------------------------------------------------------------------------------- 1 | 2 | Miscellaneous scripts, braindumps, snippets. In short: nothing anyone else 3 | but me would ever need. Feel free to browse, but don't laugh! :-) 4 | 5 | -- ck, 2011-06-01 6 | -------------------------------------------------------------------------------- /backup-mysql.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2009 Christian Kujau 4 | # 5 | # We once had a one-liner to backup all our databases: 6 | # 7 | # $ mysqldump -AcfFl --flush-privileges | pbzip2 -c > backup.sql.bz2 8 | # 9 | # However, most of the databases do not change much or do not change at all 10 | # over the day, yet the resulting compressed dump had to be generated every 11 | # day, *did* change and had to be transferred in full over a 128 kbps line 12 | # to our backup host. This one is slightly more complicated, but should do 13 | # the trick. 14 | # 15 | # Notes: 16 | # - If INFORMATION_SCHEMA.TABLES would work for InnoDB tables, we could query if the 17 | # database has changed, and only backup if needed. 18 | # * https://bugs.mysql.com/bug.php?id=2681 19 | # Ability to determine when DB was last modified (generic method) 20 | # 21 | # - We had to drop the sys.metrics view. The whole sys schema may not be needed at all. 22 | # * https://mariadb.com/kb/en/sys-schema/ 23 | # * https://mariadb.com/kb/en/sys-schema/ 24 | # * https://forums.cpanel.net/threads/remove-sys-database-after-upgrade-to-from-mysql-5-7-to-mariadb-10-3.674045/ 25 | # > "MariaDB does not utilize the sys schema. If you upgrade from MySQL 5.7 to MariaDB, you must 26 | # > manually remove the sys database, because it can cause unnecessary errors during certain check table calls." 27 | # 28 | # 29 | PATH=/bin:/usr/bin:/usr/local/bin 30 | RUNAS=mysql # Privileges needed: SELECT, RELOAD, LOCK TABLES 31 | COMPRESS=zstd 32 | LOGFILE=backup-mysql.log 33 | 34 | # unset me! 35 | # DEBUG=echo 36 | 37 | if [ ! -d "$1" ]; then 38 | echo "Usage: $(basename "$0") [dir] [-c]" 39 | exit 1 40 | else 41 | DIR="$1" 42 | cd "$DIR" || exit 3 43 | fi 44 | 45 | # Don't run as root, but we need to own $DIR 46 | if [ ! "$(whoami)" = "${RUNAS}" ]; then 47 | echo "Please execute as user \"${RUNAS}\"!" 48 | exit 2 49 | fi 50 | 51 | # Be nice to others 52 | renice 20 $$ > /dev/null 53 | 54 | # The date should end up in a logfile 55 | date >> "${LOGFILE}" 56 | 57 | # We have checks too :-) 58 | if [ "$2" = "-c" ]; then 59 | for f in *.zst; do 60 | printf "%s" "Processing \"$f\" ($(stat -c 'scale=0; %s / 1024' "$f" | bc -l) KB)..." 61 | if grep -q "$(${COMPRESS} -qdc "$f" | sha1sum | awk '{print $1}')" "${f%%.zst}".sha1; then 62 | echo "checksum OK" 63 | else 64 | echo "checksum FAILED" 65 | fi 66 | done 67 | exit $? 68 | fi 69 | 70 | # DB credentials 71 | OPTIONS="--user=backup --password=XXXX" # Can't we just use ~/.my.cnf? 72 | 73 | # Main loop 74 | BEGIN=$(date +%s) 75 | for db in $(mysql ${OPTIONS} --batch --skip-column-names -e 'show databases' | sort); do 76 | case "${db}" in 77 | information_schema|performance_schema) 78 | # Access denied for user 'root'@'localhost' to database 'information_schema' when using LOCK TABLES 79 | # http://bugs.mysql.com/bug.php?id=21527 (closed) 80 | # http://bugs.mysql.com/bug.php?id=33762 (closed) 81 | # http://bugs.mysql.com/bug.php?id=49633 82 | # OPTIONS="${OPTIONS} --skip-lock-tables" 83 | continue 84 | ;; 85 | 86 | # mysql) 87 | # # - Skip mysql.event, http://bugs.mysql.com/bug.php?id=68376 88 | # # - We used to add --skip-events b/c of http://bugs.debian.org/673572 - but this triggers #68376 again! 89 | # OPTIONS="${OPTIONS} --ignore-table=mysql.event" 90 | # ;; 91 | esac 92 | 93 | # Backup! 94 | $DEBUG mysqldump ${OPTIONS} --lock-tables --skip-dump-date --result-file="DB_${db}.sql.new" --databases "${db}" 95 | 96 | # We're comparing checksums rather than the whole dump, so that we can compress 97 | # them afterwards and still be able to compare tomorrow's dump. 98 | # - If a checksum file is present, create a new one and compare them 99 | # - If no checksum file is present, create one 100 | if [ -f DB_"${db}".sql.sha1 ]; then 101 | $DEBUG sha1sum DB_"${db}".sql.new > DB_"${db}".sql.new.sha1 102 | sed 's/\.new$//' -i DB_"${db}".sql.new.sha1 103 | 104 | H_OLD=$(awk '{print $1}' DB_"${db}".sql.sha1 2>/dev/null) 105 | H_NEW=$(awk '{print $1}' DB_"${db}".sql.new.sha1 2>/dev/null) 106 | 107 | # If they are equal, delete our new one, otherwise update the old one 108 | if [ "$H_OLD" = "$H_NEW" ]; then 109 | echo "Database ${db} has not changed, nothing to do" >> "${LOGFILE}" 110 | $DEBUG rm DB_"${db}".sql.new DB_"${db}".sql.new.sha1 111 | else 112 | echo "Database ${db} has changed, discarding the old dump." >> "${LOGFILE}" 113 | $DEBUG mv -f DB_"${db}".sql.new.sha1 DB_"${db}".sql.sha1 114 | $DEBUG mv -f DB_"${db}".sql.new DB_"${db}".sql 115 | $DEBUG ${COMPRESS} --rm -9qf DB_"${db}".sql 116 | fi 117 | else 118 | # We have nothing to compare 119 | echo "No checksum found for database ${db}." >> "${LOGFILE}" 120 | $DEBUG mv -f DB_"${db}".sql.new DB_"${db}".sql 121 | $DEBUG sha1sum DB_"${db}".sql > DB_"${db}".sql.sha1 122 | $DEBUG ${COMPRESS} --rm -9qf DB_"${db}".sql 123 | fi 124 | done 125 | END=$(date +%s) 126 | echo "${0} finished after $(echo \( "${END}" - "${BEGIN}" \) / 60 | bc) minutes." >> "${LOGFILE}" 127 | echo >> "${LOGFILE}" 128 | 129 | ### OLD ### 130 | # printf "%s" "Backing up \"${db}\"...." >> "${LOGFILE}" 131 | # - Use multiple-row INSERT syntax that include several VALUES lists 132 | # - Continue even if an SQL error occurs during a table dump 133 | # - Flush the MySQL server log files before starting the dump 134 | # - Send a FLUSH PRIVILEGES statement to the server after dumping the mysql database 135 | # - Dump binary columns using hexadecimal notation 136 | # - Using --skip-dump-date (added in v5.0.52) so that the dump won't change unnecessarily. 137 | # - Included stored routines 138 | # - Include triggers for each dumped table 139 | # OPTIONS="${OPTIONS} --extended-insert --force --flush-logs --flush-privileges --hex-blob --skip-dump-date --routines --triggers" 140 | -------------------------------------------------------------------------------- /benchmarks/cgd_benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ksh -e 2 | # 3 | # (c)2019 Christian Kujau 4 | # Benchmark for NetBSD/CGD. We'd need something similar for other BSD 5 | # variants too. 6 | # 7 | CIPHERS="aes-cbc aes-xts 3des-cbc blowfish-cbc" # See cgd(4) 8 | CGD=cgd3 9 | 10 | # unset me! 11 | # DEBUG="count=1" # Read only one byte, for testing. 12 | 13 | # Short circuit into report mode 14 | if [ "$1" = "report" ] && [ -f "$2" ]; then 15 | for c in $(awk '/MODE:/ {print $2}' "$2" | uniq); do 16 | NUM=$(grep -c "MODE: $c" "$2") 17 | printf "$c \t" 18 | awk "/MODE: $c/ {print \$9, \$11, \$2}" "$2" | sed 's/(//' | \ 19 | awk "{time+=\$1} {speed+=\$2} END {print time/${NUM}, \"sec /\", speed/${NUM}/1024/1024, \"MB/s\"}" 20 | done 21 | exit $? 22 | fi 23 | 24 | # FIXME: Do we want more options on the command line? 25 | if [ ! -c /dev/r"${1}" ] || [ -z "$2" ]; then 26 | echo "Usage: $(basename "$0") [devicename] [runs]" 27 | echo " $(basename "$0") report [out.txt]" 28 | echo "" 29 | echo "Example: $(basename "$0") wd0b 5 | tee out.txt" 30 | echo " $(basename "$0") report out.txt" 31 | exit 1 32 | else 33 | # Note: in BSD, we will use character devices, not block devices. However, 34 | # for setting up the CGD, a block device is indeed required. See also: 35 | # https://www.freebsd.org/doc/en/books/arch-handbook/driverbasics-block.html 36 | # https://www.netbsd.org/docs/kernel/pseudo/ 37 | DEV="$1" 38 | NUM="$2" 39 | PRM=$(mktemp -d) # Where to store our parameter files. 40 | fi 41 | 42 | # RAW 43 | for i in $(seq 1 "$NUM"); do 44 | printf "MODE: raw I: $i\t" 45 | dd if=/dev/r"${DEV}" of=/dev/null bs=1k "$DEBUG" conv=sync 2>&1 | grep bytes 46 | done 47 | 48 | # CGD 49 | for c in $CIPHERS; do 50 | cgdconfig -g -k urandomkey -o "${PRM}"/test_"${c}" "$c" 51 | cgdconfig ${CGD} /dev/"${DEV}" "${PRM}"/test_"${c}" 52 | 53 | # Repeat NUM times... 54 | for i in $(seq 1 "$NUM"); do 55 | printf "MODE: $c I: $i\t" 56 | dd if=/dev/r${CGD}a of=/dev/null bs=1k "$DEBUG" conv=sync 2>&1 | grep bytes 57 | done 58 | 59 | cgdconfig -u /dev/${CGD}a 60 | rm -f "${PRM}"/test_"${c}" 61 | done 62 | rmdir "${PRM}" 63 | -------------------------------------------------------------------------------- /benchmarks/compress-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # (c)2011 Christian Kujau 4 | # 5 | # Compress a file with different programs and see how long it took to do this. 6 | # 7 | # > Squash Compression Benchmark 8 | # > https://quixdb.github.io/squash-benchmark/ 9 | # 10 | # > Large Text Compression Benchmark 11 | # > http://mattmahoney.net/dc/text.html 12 | # 13 | # > Lzturbo library: world's fastest compression library 14 | # > https://sites.google.com/site/powturbo/home/benchmark 15 | # 16 | # > Packbench 17 | # > https://martin-steigerwald.de/computer/programme/packbench/ 18 | # 19 | PATH=/usr/local/bin:/usr/bin:/bin 20 | PROGRAMS=${PROGRAMS:-gzip pigz bzip2 pbzip2 lbzip2 xz pxz lz4 lzma lzip brotli zstd pzstd pixz} 21 | MODES=${MODES:-9c 1c dc} # {1..9}c for compression 22 | # dc for decompression 23 | _help() { 24 | echo "Usage: $(basename "$0") [-n runs] [-f file]" 25 | echo " $(basename "$0") [-r results]" 26 | echo 27 | echo "Available environment variables that can be set:" 28 | echo "PROGRAMS (default: $PROGRAMS)" 29 | echo " MODES (default: $MODES)" 30 | echo 31 | exit 1 32 | } 33 | 34 | _report() { 35 | echo "### Fastest compressor:" 36 | grep -v /dc "${REPORT}" | sort -nk3 37 | echo 38 | 39 | echo "### Smallest size:" 40 | grep -v /dc "${REPORT}" | sort -nrk6 41 | echo 42 | 43 | echo "### Fastest decompressor:" 44 | grep /dc "${REPORT}" | sort -nk3 45 | echo 46 | exit $? 47 | } 48 | 49 | # Gather options 50 | while getopts "n:f:r:" opt; do 51 | case $opt in 52 | n) 53 | runs=${OPTARG} 54 | ;; 55 | 56 | f) 57 | FILE=${OPTARG} 58 | ;; 59 | 60 | r) 61 | REPORT=${OPTARG} 62 | ;; 63 | 64 | *) 65 | _help 66 | ;; 67 | esac 68 | done 69 | 70 | # Are we in report mode? 71 | [ -f "${REPORT}" ] && _report # The "" are important here! 72 | 73 | # Default to one run 74 | RUNS=${runs:-1} 75 | 76 | # Read file into RAM once 77 | [ -f "${FILE}" ] && cat "${FILE}" > /dev/null || _help 78 | 79 | # Iterate through all modes, programs 80 | for m in $MODES; do 81 | for p in $PROGRAMS; do 82 | if ! which "${p}" > /dev/null 2>&1; then 83 | echo "### Program ${p} not found - skipping." 84 | continue 85 | fi 86 | SIZE1=$(ls -go "${FILE}" | awk '{print $3}') 87 | START=$(date +%s) 88 | 89 | # If all programs had the same options, we would not have to do this. 90 | case $p in 91 | brotli|bro) 92 | if [ "$m" = "dc" ]; then 93 | _cmd(){ ${p} -"${m}" "${FILE}"."${p}" > /dev/null; } 94 | else 95 | qual=$(echo "$m" | sed 's/c$//') # Sigh... 96 | _cmd(){ ${p} -q "${qual}" -c "${FILE}" > "${FILE}"."${p}"; } 97 | fi 98 | ;; 99 | 100 | zstd|pzstd) 101 | # pzstd: suppress the progress bar 102 | if [ "$m" = "dc" ]; then 103 | _cmd(){ ${p} -q"${m}" "${FILE}"."${p}" > /dev/null; } 104 | else 105 | _cmd(){ ${p} -q"${m}" "${FILE}" > "${FILE}"."${p}"; } 106 | fi 107 | ;; 108 | 109 | pxz) 110 | # For some reason pxz defaults to -T1 instead of -T0 111 | if [ "$m" = "dc" ]; then 112 | _cmd(){ ${p} -T0 -dc "${FILE}"."${p}" > /dev/null; } 113 | else 114 | qual=$(echo "$m" | sed 's/c$//') # Sigh... 115 | _cmd(){ ${p} -T0 -c -"${qual}" "${FILE}" > "${FILE}"."${p}"; } 116 | fi 117 | ;; 118 | 119 | pixz) 120 | if [ "$m" = "dc" ]; then 121 | _cmd(){ ${p} -d -i "${FILE}"."${p}" -o /dev/null; } 122 | else 123 | qual=$(echo "$m" | sed 's/c$//') # Sigh... 124 | _cmd(){ ${p} -k -"${qual}" -i "${FILE}" -o "${FILE}"."${p}"; } 125 | fi 126 | ;; 127 | 128 | *) 129 | # All the sane programs out there... 130 | if [ "$m" = "dc" ]; then 131 | _cmd(){ ${p} -"${m}" "${FILE}"."${p}" > /dev/null; } 132 | else 133 | _cmd(){ ${p} -"${m}" "${FILE}" > "${FILE}"."${p}"; } 134 | fi 135 | ;; 136 | esac 137 | 138 | # We could move the counter to the outer loop, but then we'd have 139 | # to play more tricks with our statistics below. 140 | n=0 141 | while [ $n -lt "$RUNS" ]; do 142 | _cmd 143 | n=$((n+1)) 144 | done 145 | 146 | # Statistics 147 | END=$(date +%s) 148 | DIFF=$(echo "scale=2; ($END - $START) / $n" | bc -l) 149 | if [ "$m" = "dc" ]; then 150 | echo "### $p/$m: $DIFF seconds" 151 | else 152 | SIZE2=$(ls -go "$FILE"."$p" | awk '{print $3}') # More portable than stat(1) 153 | RATIO=$(echo "scale=3; 100 - ($SIZE2 / $SIZE1 * 100)" | bc -l) 154 | echo "### $p/$m: $DIFF seconds / $RATIO% smaller " 155 | fi 156 | 157 | done # END PROGRAMS 158 | echo 159 | done # END MODES 160 | -------------------------------------------------------------------------------- /benchmarks/cryptsetup_benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2013 Christian Kujau 4 | # Poor wo/man's dm-crypt benchmark 5 | # 6 | 7 | # DEBUG=echo 8 | 9 | if [ ! -b "$1" ] || [ -z "$4" ]; then 10 | echo "Usage: $0 [device] [cipher] [size] [runs]" 11 | echo "Examples:" 12 | echo "$(basename "$0") /dev/sdu1 aes-cbc-plain 128" 13 | echo "$(basename "$0") /dev/sdu1 aes-cbc-essiv:sha256 448" 14 | exit 1 15 | else 16 | DEVICE="$1" 17 | CIPHER="$2" 18 | SIZE="$3" 19 | RUNS="$4" 20 | MD=test 21 | fi 22 | 23 | cryptsetup remove $MD 2>/dev/null 24 | $DEBUG cryptsetup -c "$CIPHER" -s "$SIZE" -d /dev/urandom create $MD "$DEVICE" || exit 1 25 | ## $DEBUG cryptsetup status $MD || exit 1 26 | printf "$CIPHER / $SIZE : " 27 | TIME_S=$(date +%s) 28 | i=0 29 | while [ $i -lt "$RUNS" ]; do 30 | ## printf "$i " 31 | $DEBUG sysctl -qw vm.drop_caches=3 32 | $DEBUG dd if=/dev/mapper/$MD of=/dev/null bs=1M 2>/dev/null 33 | i=$((i+1)) 34 | done 35 | TIME_E=$(date +%s) 36 | expr "$TIME_E" - "$TIME_S" 37 | cryptsetup remove $MD 38 | -------------------------------------------------------------------------------- /benchmarks/cryptsetup_ciphertest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2013 Christian Kujau 4 | # 5 | # Create dm-crypt devices with different combinations of ciphers, modes, hash 6 | # alorithms and key sizes. 7 | # 8 | # Preferably cryptsetup(8) would be able to parse /proc/crypto and generate a 9 | # list of possible combinations, but this has not been implemented. 10 | # See https://gitlab.com/cryptsetup/cryptsetup/issues/20 for that. Instead, 11 | # we iterate through a list of more or less "common" choices and print out all 12 | # valid (and invalid) combinations. The results can later be used by 13 | # cryptsetup_benchmark.sh - so we don't benchmark invalid combinations. 14 | # 15 | # Something like this could do the trick: 16 | # ciphers=$(grep -B6 -w cipher /proc/crypto | awk '/^name/ {print $3}' | sort) 17 | # 18 | # While the kernel should auto-load any needed modules, we can try to load any 19 | # crypto related module before: 20 | # 21 | # $ find /lib/modules/$(uname -r)/ -type f -path "*kernel/crypto*" -printf "%f\n" \ 22 | # | sed 's/\.ko$//' | while read a; do modprobe -v $a; done 23 | # 24 | # Test different cipher, mode and hash combinations. The output can be 25 | # used by cryptsetup_benchmark.sh later on. 26 | # 27 | 28 | # unset me! 29 | # DEBUG=echo 30 | 31 | # RIP 32 | die() { 33 | echo "$1" 34 | exit 2 35 | } 36 | 37 | if [ ! -b "$1" ]; then 38 | echo "Usage: $0 [device]" 39 | exit 1 40 | else 41 | DEVICE="$1" 42 | MD=test 43 | # cryptsetup is needed, for obvious reasons :) 44 | which cryptsetup > /dev/null || die "cryptsetup not found!" 45 | fi 46 | 47 | 48 | $DEBUG cryptsetup remove $MD 2>/dev/null 49 | for c in aes anubis blowfish camellia cast5 cast6 cipher_null khazad salsa20 serpent twofish xtea; do 50 | for m in cbc ctr cts ecb lrw pcbc xts; do 51 | for h in plain crc32c ghash md4 md5 rmd128 rmd160 rmd256 rmd320 sha1 sha256 sha512 tgr192 wp512; do 52 | if [ $h = "plain" ]; then 53 | C=$c-$m-$h 54 | else 55 | C=$c-$m-essiv:$h 56 | fi 57 | for s in 128 256 384 448 512; do 58 | $DEBUG cryptsetup -c $C -s $s -d /dev/urandom create $MD "$DEVICE" 2>/dev/null 59 | if [ $? = 0 ]; then 60 | echo "Valid combination: cipher $C - size $s" 61 | $DEBUG cryptsetup status $MD 62 | 63 | # Remove the device again 64 | $DEBUG cryptsetup remove $MD || die "cryptsetup remove $MD failed" 65 | 66 | # Double-check if the device is really removed, bail out if not 67 | $DEBUG cryptsetup status $MD > /dev/null && die "device $MD is still online!" 68 | else 69 | echo "Invalid combination: cipher $C - size $s" 70 | fi 71 | done 72 | done 73 | done 74 | done 75 | -------------------------------------------------------------------------------- /benchmarks/fs-bench.conf: -------------------------------------------------------------------------------- 1 | # 2 | # (c)2009 Christian Kujau 3 | # 4 | # fs-bench.conf, to be used by fs-bench.sh 5 | # 6 | 7 | # global options 8 | LANG=C 9 | PATH=/bin:/usr/bin:/sbin:/usr/sbin:/opt/zfs-fuse 10 | LOG=$HOME/results-`date +%Y-%m-%d` 11 | 12 | # - bonnie dbench generic iozone tiobench 13 | # - btrfs ext2 ext3 ext4 jfs nilfs2 reiserfs reiser4 ufs xfs zfs 14 | 15 | BENCHMARKS="bonnie dbench generic" 16 | FILESYSTEMS="btrfs ext2 ext3 ext4 jfs reiserfs xfs" 17 | 18 | # Sometimes we want to skip certain fs/benchmark combinations 19 | SKIP="nilfs2:bonnie nilfs2:dbench ufs:dbench ufs:tiobench zfs:dbench" 20 | 21 | # unset me! 22 | # DEBUG=echo 23 | 24 | conf_bonnie() { 25 | NUMTESTS=2 26 | RAM=0 # disable RAM checks 27 | SIZE=2048 # should be 2x RAM 28 | NUMFILES=2:4194304:1024:1 # 2048 files, 4MB max, 1K min, 1 dir - 8GB max 29 | 30 | # SIZE=512 31 | # NUMFILES=1:40960:4096:1 # 1024 files, 40K max/min, 128 dirs - 40MB max 32 | } 33 | 34 | conf_generic() { 35 | CONTENT=/usr 36 | NUMFILES=33768 # numfiles * numdirs must not 37 | NUMDIRS=128 # exceed available inode count! 38 | 39 | # CONTENT=/usr/share 40 | # NUMFILES=32 41 | # NUMDIRS=32 42 | } 43 | 44 | conf_dbench() { 45 | TIME=600 46 | NPROC=50 47 | 48 | # TIME=60 49 | # NPROC=5 50 | } 51 | 52 | conf_iozone() { 53 | CACHESIZE=256K 54 | FILESIZE=8G 55 | NPROC=1024 56 | 57 | # FILESIZE=1G 58 | # NPROC=10 59 | } 60 | 61 | conf_stress() { 62 | CONTENT=/var 63 | RUNS=3 # default: 50 64 | CONCURRENT=2 # default: 50 65 | STAGGER=no # use "yes" to generate more load 66 | } 67 | 68 | conf_tiobench() { 69 | SIZE=2048 70 | NUMRUNS=4 71 | 72 | # SIZE=128 73 | # NUMRUNS=1 74 | } 75 | 76 | -------------------------------------------------------------------------------- /benchmarks/fs-bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2009 Christian Kujau 4 | # 5 | # Yet another filesystem benchmark script 6 | # 7 | # - bonnie++ 8 | # - dbench 9 | # - iozone3 10 | # - tiobench 11 | # - generic operations, like tar/touch/rm 12 | # 13 | # TODO: 14 | # - different mount options for each filesystems 15 | # - different benchmark options 16 | # - integrate fio? (https://github.com/axboe/fio) 17 | # 18 | # v0.1 - initial version 19 | # v0.2 - disabled 2 filesystems 20 | # ufs - https://bugs.debian.org/526586 ("mkfs.ufs: could not find special device") 21 | # nilfs2 - filesystem fills up until ENOSPC 22 | # v0.3 - run tiobench with only 1 thread, otherwise we get: 23 | # Illegal division by zero at /usr/bin/tiobench line 163 24 | # v0.4 - rewrite for ksh 25 | # v0.5 - replace "date +%s" 26 | # enable NILFS2, UFS and ZFS again 27 | # rework the generic tests 28 | # 29 | # Prerequisites: 30 | # apt-get install bc bonnie++ dbench pciutils hdparm e2fsprogs btrfs-tools \ 31 | # jfsutils reiserfsprogs reiser4progs xfsprogs tiobench ksh 32 | # 33 | CONF="/usr/local/etc/fs-bench.conf" 34 | 35 | log() { 36 | echo "$(date +'%F %H:%M:%S'): $1" 37 | [ -n "$2" ] && exit "$2" 38 | } 39 | 40 | # little helper function to warn if we might run out of diskspace during the benchmark. 41 | # Takes three arguments (count in 1024, size in bytes and a multiplier) seperated by a colon, 42 | # result will be given in KB: 43 | # $ echo "1:1024:2" | chkfree 44 | # -> 2048 45 | chkfree() { 46 | eval $(awk -F: '{p=sprintf ("%.0f", ($1 * $2 * $3)); print "ESTIM="p }') 47 | eval $(df -k "$MPT" | awk '!/Filesystem/ {print "AVAIL="$4}') 48 | if [ "$ESTIM" -ge "$AVAIL" ]; then 49 | log "WARNING: $ESTIM KB estimated but only $AVAIL KB available - $b could fail!" 50 | else 51 | log "DEBUG: $ESTIM KB estimated, $AVAIL KB available" >> "$LOG"/raw/bonnie-"$fs".log 52 | fi 53 | } 54 | 55 | # sanity checks 56 | if [ ! -b "$1" ] || [ ! -d "$2" ] || [ ! -f $CONF ]; then 57 | log "Usage: $(basename "$0") [dev] [mpt]" 58 | log "Make sure $CONF exists!" 1 59 | else 60 | DEV="$1" 61 | MPT="$(echo "$2" | sed 's/\/$//')" 62 | . "$CONF" 63 | fi 64 | 65 | # overwrite results dir? 66 | if [ -d "$LOG" ]; then 67 | printf "Directory $LOG already exists, overwrite? (y/n) " && read c 68 | if [ "$c" = "y" ]; then 69 | $DEBUG rm -rf "$LOG" 70 | else 71 | log "Aborted." 1 72 | fi 73 | fi 74 | $DEBUG mkdir -p "$LOG"/raw "$LOG"/env 75 | $DEBUG cp "$0" "$LOG"/env/$(basename "$0").txt 76 | $DEBUG cp "$CONF" "$LOG"/env/$(basename $CONF).txt 77 | $DEBUG gzip -dc /proc/config.gz > "$LOG"/env/config.txt 2>/dev/null 78 | $DEBUG cp /boot/config-$(uname -r) "$LOG"/env/config-$(uname -r).txt 2>/dev/null 79 | $DEBUG dmesg > "$LOG"/env/dmesg.txt 80 | $DEBUG lspci > "$LOG"/env/lspci.txt 81 | $DEBUG hdparm -tT "$DEV" > "$LOG"/env/hdparm.txt 82 | 83 | ######################################################## 84 | # MKFS 85 | ######################################################## 86 | mkfs_btrfs() { 87 | log "mkfs.btrfs $DEV" >> "$LOG"/raw/commands.txt 88 | $DEBUG mkfs.btrfs "$DEV" 1>/dev/null 89 | log "mount -t btrfs -o noatime $DEV $MPT" >> "$LOG"/raw/commands.txt 90 | $DEBUG mount -t btrfs -o noatime "$DEV" "$MPT" 91 | ERR=$? 92 | } 93 | 94 | mkfs_ext2() { 95 | log "mkfs.ext2 -Fq $DEV" >> "$LOG"/raw/commands.txt 96 | $DEBUG mkfs.ext2 -Fq "$DEV" 97 | log "mount -t ext2 -o noatime,user_xattr $DEV $MPT" >> "$LOG"/raw/commands.txt 98 | $DEBUG mount -t ext2 -o noatime,user_xattr "$DEV" "$MPT" 99 | ERR=$? 100 | } 101 | 102 | mkfs_ext3() { 103 | log "mkfs.ext3 -Fq $DEV" >> "$LOG"/raw/commands.txt 104 | $DEBUG mkfs.ext3 -Fq "$DEV" 105 | log "mount -t ext3 -o noatime,user_xattr $DEV $MPT" >> "$LOG"/raw/commands.txt 106 | $DEBUG mount -t ext3 -o noatime,user_xattr "$DEV" "$MPT" 107 | ERR=$? 108 | } 109 | 110 | mkfs_ext4() { 111 | log "mkfs.ext4 -Fq $DEV" >> "$LOG"/raw/commands.txt 112 | $DEBUG mkfs.ext4 -Fq "$DEV" 113 | log "mount -t ext4 -o noatime,user_xattr $DEV $MPT" >> "$LOG"/raw/commands.txt 114 | $DEBUG mount -t ext4 -o noatime,user_xattr "$DEV" "$MPT" 115 | ERR=$? 116 | } 117 | 118 | mkfs_jfs() { 119 | log "mkfs.jfs -q $DEV" >> "$LOG"/raw/commands.txt 120 | $DEBUG mkfs.jfs -q "$DEV" 1>/dev/null 121 | log "mount -t jfs -o noatime $DEV $MPT" >> "$LOG"/raw/commands.txt 122 | $DEBUG mount -t jfs -o noatime "$DEV" "$MPT" 123 | ERR=$? 124 | } 125 | 126 | mkfs_nilfs2() { 127 | log "mkfs.nilfs2 -q $DEV" >> "$LOG"/raw/commands.txt 128 | $DEBUG mkfs.nilfs2 -q "$DEV" 129 | log "mount -t nilfs2 -o noatime $DEV $MPT" >> "$LOG"/raw/commands.txt 130 | $DEBUG mount -t nilfs2 -o noatime "$DEV" "$MPT" 2>/dev/null 131 | ERR=$? 132 | } 133 | 134 | mkfs_reiserfs() { 135 | log "mkfs.reiserfs -qf $DEV" >> "$LOG"/raw/commands.txt 136 | $DEBUG mkfs.reiserfs -qf "$DEV" > /dev/null 2>&1 137 | log "mount -t reiserfs -o noatime,user_xattr $DEV $MPT" >> "$LOG"/raw/commands.txt 138 | $DEBUG mount -t reiserfs -o noatime,user_xattr "$DEV" "$MPT" 139 | ERR=$? 140 | } 141 | 142 | mkfs_reiser4() { 143 | log "mkfs.reiser4 -yf $DEV" >> "$LOG"/raw/commands.txt 144 | $DEBUG mkfs.reiser4 -yf "$DEV" 145 | log "mount -t reiser4 -o noatime $DEV $MPT" >> "$LOG"/raw/commands.txt 146 | $DEBUG mount -t reiser4 -o noatime "$DEV" "$MPT" 147 | ERR=$? 148 | } 149 | 150 | mkfs_ufs() { 151 | log "mkfs.ufs -J -O2 -U $DEV" >> "$LOG"/raw/commands.txt 152 | $DEBUG mkfs.ufs -J -O2 -U "$DEV" > /dev/null 153 | log "mount -t ufs -o ufstype=ufs2,noatime $DEV $MPT" >> "$LOG"/raw/commands.txt 154 | $DEBUG mount -t ufs -o ufstype=ufs2,noatime "$DEV" "$MPT" 155 | ERR=$? 156 | } 157 | 158 | mkfs_xfs() { 159 | log "mkfs.xfs -qf $DEV" >> "$LOG"/raw/commands.txt 160 | $DEBUG mkfs.xfs -qf "$DEV" 161 | log "mount -t xfs -o noatime $DEV $MPT" >> "$LOG"/raw/commands.txt 162 | $DEBUG mount -t xfs -o noatime "$DEV" "$MPT" 163 | ERR=$? 164 | } 165 | 166 | mkfs_zfs() { 167 | # special case different operating systems 168 | case $(uname -s) in 169 | Linux) 170 | if [ -z "$(pgrep zfs-fuse)" ]; then 171 | log "zfs-fuse not running!" 172 | false 173 | fi 174 | ;; 175 | 176 | SunOS) 177 | if [ ! -x "$(which zpool)" ]; then 178 | log "zfs not found!" 179 | false 180 | fi 181 | ;; 182 | esac 183 | log "zpool create -f -O atime=off -m $MPT ztest $DEV" >> "$LOG"/raw/commands.txt 184 | $DEBUG zpool create -f -O atime=off -m "$MPT" ztest "$DEV" 185 | ERR=$? 186 | } 187 | 188 | umountfs() { 189 | case $fs in 190 | zfs) 191 | # ...and special case Linux/ZFS again 192 | if [ "$(uname -s)" = Linux ] && [ -z "$(pgrep zfs-fuse)" ]; then 193 | log "zfs-fuse not running!" 1 194 | fi 195 | $DEBUG sync 196 | $DEBUG sleep 5 197 | log "zpool destroy -f ztest" >> "$LOG"/raw/commands.txt 198 | $DEBUG zpool destroy -f ztest >> "$LOG"/raw/zfs.log 2>&1 199 | # sometimes, this just fails (why?) 200 | if [ ! $? = 0 ]; then 201 | log "Destroying ZFS pool failed, will try again in 5 seconds!" >> "$LOG"/raw/zfs.log 202 | $DEBUG sync 203 | $DEBUG sleep 5 204 | log "zpool destroy -f ztest" >> "$LOG"/raw/commands.txt 205 | $DEBUG zpool destroy -f ztest || log "Unmounting $fs failed!" 1 206 | fi 207 | ;; 208 | 209 | *) 210 | log "umount $MPT" >> "$LOG"/raw/commands.txt 211 | $DEBUG umount "$MPT" || log "Unmounting $fs failed!" 1 212 | ;; 213 | esac 214 | } 215 | 216 | ######################################################## 217 | # BENCHMARKS 218 | ######################################################## 219 | 220 | run_bonnie() { 221 | eval conf_bonnie 222 | log "Running $b on $fs..." 223 | echo "$NUMFILES" | awk -F: '{printf $1 ":" $2 ":1.1"}' | chkfree 224 | log "bonnie++ -d $MPT -s $SIZE -n $NUMFILES -m $fs -r $RAM -x $NUMTESTS -u root" >> "$LOG"/raw/commands.txt 225 | $DEBUG bonnie++ -d "$MPT" -s "$SIZE" -n "$NUMFILES" -m "$fs" -r "$RAM" -x "$NUMTESTS" -u root 1>"$LOG"/raw/bonnie-"$fs".csv 2>"$LOG"/raw/bonnie-"$fs".err 226 | $DEBUG egrep -hv '^format' "$LOG"/raw/bonnie-*.csv | bon_csv2html > "$LOG"/bonnie.html 227 | } 228 | 229 | ######################################################## 230 | run_stress() { 231 | # 232 | # Based on https://oss.oracle.com/~mason/stress.sh 233 | # Copyright (C) 1999 Bibliotech Ltd., 631-633 Fulham Rd., London SW6 5UQ. 234 | # $Id: stress.sh,v 1.2 1999/02/10 10:58:04 rich Exp $ 235 | # 236 | eval conf_stress 237 | log "Running $b on $fs (size: $(du -sk "$CONTENT" | awk '{print $1 / 1024 " MB"}'))..." 238 | $DEBUG mkdir "$MPT"/stress || log "cannot create $MPT/stress" 1 239 | $DEBUG cd "$MPT"/stress || log "cannot cd into $MPT/stress" 1 240 | 241 | # computing MD5 sums over content directory 242 | find "$CONTENT" -type f -exec md5sum '{}' + | sort > "$MPT"/content.sums 243 | 244 | # !!FIXME!! 245 | # starting stress test processes 246 | p=1 247 | while [ $p -le "$CONCURRENT" ]; do 248 | ( 249 | # wait for all processes to start up. 250 | if [ "$STAGGER" = "yes" ]; then 251 | $DEBUG sleep $(expr 2 \* $p) 252 | else 253 | $DEBUG sleep 1 254 | fi 255 | 256 | r=1 257 | while [ $r -le "$RUNS" ]; do 258 | log "Running stresstest in $MPT/stress/$p (r: $r)..." 259 | # Remove old directories. 260 | $DEBUG rm -rf "$MPT"/stress/$p 261 | 262 | # copy content 263 | $DEBUG mkdir "$MPT"/stress/$p || log "cannot create $MPT/stress/$p" 264 | $DEBUG cp -dRx "$CONTENT"/* "$MPT"/stress/$p || log "cannot copy $CONTENT to $MPT/stress/$p" 265 | 266 | # compare the content and the copy. 267 | $DEBUG cd "$MPT"/stress/$p 268 | $DEBUG find . -type f -exec md5sum '{}' + | sort > "$MPT"/stress.$p 269 | $DEBUG diff -q "$MPT"/content.sums "$MPT"/stress.$p 270 | if [ $? != 0 ]; then 271 | log "corruption found in $MPT/stress/$p (r: $r)" 272 | continue 273 | fi 274 | $DEBUG cd "$MPT"/stress 275 | $DEBUG rm -f "$MPT"/stress.$p 276 | r=$(expr $r + 1) 277 | done 278 | ) & 279 | p=$(expr $p + 1) 280 | done 281 | } 282 | 283 | ######################################################## 284 | run_dbench() { 285 | eval conf_dbench 286 | log "Running $b on $fs..." 287 | log "dbench -x -t $TIME -D $MPT $NPROC" >> "$LOG"/raw/commands.txt 288 | $DEBUG dbench -x -t "$TIME" -D "$MPT" "$NPROC" > "$LOG"/raw/dbench-"$fs".log 289 | echo "$fs: $(egrep '^Throughput' "$LOG"/raw/dbench-"$fs".log)" >> "$LOG"/dbench.txt 290 | } 291 | 292 | run_iozone() { 293 | eval conf_iozone 294 | log "Running $b on $fs..." 295 | $DEBUG cd "$MPT" || log "cannot cd into $MPT" 1 296 | log "iozone -a -c -S $CACHESIZE -s $FILESIZE" >> "$LOG"/raw/commands.txt 297 | $DEBUG iozone -a -c -S "$CACHESIZE" -s "$FILESIZE" > "$LOG"/raw/iozone-"$fs".log 298 | } 299 | 300 | run_tiobench() { 301 | eval conf_tiobench 302 | log "Running $b on $fs..." 303 | log "tiobench --identifier fs_"$fs" --size $SIZE --numruns $NUMRUNS --dir $MPT --block 4096 --block 8192 --threads 1" >> "$LOG"/raw/commands.txt 304 | $DEBUG tiobench --identifier fs_"$fs" --size "$SIZE" --numruns "$NUMRUNS" --dir "$MPT" --block 4096 --block 8192 --threads 1 1>"$LOG"/raw/tiobench-"$fs".log 2>"$LOG"/raw/tiobench-"$fs".err 305 | 306 | # results are hard to summarize 307 | echo " File Blk Num Avg Maximum Lat% Lat% CPU" > "$LOG"/tiobench.txt 308 | echo " Size Size Thr Rate (CPU%) Latency Latency >2s >10s Eff" >> "$LOG"/tiobench.txt 309 | for t in "Sequential Reads" "Sequential Writes" "Random Reads" "Random Writes"; do 310 | echo "$t" 311 | # adjust -An for more/less than 2 different blocksizes! 312 | grep -h -A5 "$t" "$LOG"/raw/tiobench-*.log | egrep '^fs_' 313 | echo 314 | done >> "$LOG"/tiobench.txt 315 | } 316 | 317 | run_generic() { 318 | eval conf_generic 319 | SIZE=$(du -sk "$CONTENT" | awk '{print $1 / 1024}') 320 | FSP=$(echo "$fs" | awk '{printf "%9s", $1"\n"}') # string padding, reiserfs being the longest one 321 | ERR="" 322 | log "Running $b on $fs..." 323 | # - copy content to fs 324 | # - tar up local content 325 | # - copy content within same fs 326 | # - create NUMFILES in NUMDIRS 327 | 328 | # tar to 329 | GEN_BEGIN=$(date +%s) 330 | log "mkdir "$MPT"/tar >> "$LOG"/raw/commands.txt 331 | $DEBUG mkdir "$MPT"/tar 332 | log "cd "$CONTENT" >> "$LOG"/raw/commands.txt 333 | $DEBUG cd "$CONTENT" 334 | log "tar -cf - . | tar -C "$MPT"/tar -xf -" >> "$LOG"/raw/commands.txt 335 | $DEBUG tar -cf - . 2>>"$LOG"/raw/generic-"$fs".err | tar -C "$MPT"/tar -xf - 2>>"$LOG"/raw/generic-"$fs".err 336 | log "diff -r "$CONTENT" "$MPT"/tar" >> "$LOG"/raw/commands.txt 337 | DIFF="$(diff -r "$CONTENT" "$MPT"/tar 2>&1 | grep -v 'No such file or directory')" 338 | [ -z "$DIFF" ] || ERR="- FAILED" 339 | $DEBUG sync 340 | $DEBUG cd /tmp 341 | GEN_END=$(date +%s) 342 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 343 | SPEED=$(echo "scale=2; $SIZE / $GEN_DUR" | bc -l 2>/dev/null) 344 | log "$FSP.0: $GEN_DUR seconds ($SPEED MB/s) to copy $CONTENT to $MPT and running diff $ERR" > "$LOG"/raw/generic-"$fs".log 345 | ERR="" 346 | 347 | # tar from 348 | GEN_BEGIN=$(date +%s) 349 | log "cd "$MPT"/tar" >> "$LOG"/raw/commands.txt 350 | $DEBUG cd "$MPT"/tar 351 | log "tar -cf - . | dd of=/dev/null" >> "$LOG"/raw/commands.txt 352 | $DEBUG tar -cf - . 2>>"$LOG"/raw/generic-"$fs".err | dd of=/dev/null 2>>"$LOG"/raw/generic-"$fs".err 353 | [ $? = 0 ] || ERR="- FAILED" 354 | $DEBUG sync 355 | $DEBUG cd /tmp 356 | GEN_END=$(date +%s) 357 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 358 | SPEED=$(echo "scale=2; $SIZE / $GEN_DUR" | bc -l 2>/dev/null) 359 | log "$FSP.1: $GEN_DUR seconds ($SPEED MB/s) to tar up content on $MPT $ERR" >> "$LOG"/raw/generic-"$fs".log 360 | ERR="" 361 | 362 | # copy 363 | GEN_BEGIN=$(date +%s) 364 | log "mkdir "$MPT"/copy" >> "$LOG"/raw/commands.txt 365 | $DEBUG mkdir "$MPT"/copy 366 | log "cp -xfpR "$CONTENT" "$MPT"/copy" >> "$LOG"/raw/commands.txt 367 | $DEBUG cp -xfpR "$CONTENT" "$MPT"/copy 2>>"$LOG"/raw/generic-"$fs".err 368 | [ $? = 0 ] || ERR="- FAILED" 369 | $DEBUG sync 370 | GEN_END=$(date +%s) 371 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 372 | SPEED=$(echo "scale=2; $SIZE / $GEN_DUR" | bc -l 2>/dev/null) 373 | log "$FSP.2: $GEN_DUR seconds ($SPEED MB/s) to copy $CONTENT on $MPT $ERR" >> "$LOG"/raw/generic-"$fs".log 374 | ERR="" 375 | 376 | # cleanup before starting the next test 377 | SIZE_M=$(du -sk "$MPT" | awk '{print $1 / 1024}') 378 | GEN_BEGIN=$(date +%s) 379 | $DEBUG echo "DEBUG-1: $(df -i "$MPT" | grep -v Filesystem)" >> "$LOG"/raw/generic-"$fs".err 380 | 381 | log "rm -rf "$MPT"/tar "$MPT"/copy" >> "$LOG"/raw/commands.txt 382 | $DEBUG rm -rf "$MPT"/tar "$MPT"/copy 2>>"$LOG"/raw/generic-"$fs".err 383 | [ $? = 0 ] || ERR="- FAILED" 384 | 385 | $DEBUG echo "DEBUG-2: $(df -i "$MPT" | grep -v Filesystem)" >> "$LOG"/raw/generic-"$fs".err 386 | GEN_END=$(date +%s) 387 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 388 | SPEED=$(echo "scale=2; $SIZE_M / $GEN_DUR" | bc -l 2>/dev/null) 389 | log "$FSP.3: $GEN_DUR seconds ($SPEED MB/s) to remove content from $MPT $ERR" >> "$LOG"/raw/generic-"$fs".log 390 | ERR="" 391 | 392 | # create many files 393 | GEN_BEGIN=$(date +%s) 394 | $DEBUG mkdir "$MPT"/manyfiles 395 | log "for d in seq 1 $NUMDIRS; do mkdir -p $MPT/manyfiles/dir.d && cd $MPT/manyfiles/dir.d && seq 1 $NUMFILES | xargs touch; done" >> "$LOG"/raw/commands.txt 396 | for d in $(seq 1 "$NUMDIRS"); do 397 | $DEBUG mkdir -p "$MPT"/manyfiles/dir."$d" 2>>"$LOG"/raw/generic-"$fs".err 398 | $DEBUG cd "$MPT"/manyfiles/dir."$d" 2>>"$LOG"/raw/generic-"$fs".err 399 | seq 1 "$NUMFILES" | xargs touch 2>>"$LOG"/raw/generic-"$fs".err 400 | done 401 | sync 402 | GEN_END=$(date +%s) 403 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 404 | NUMDIRS_C=$(find "$MPT"/manyfiles -type d | wc -l) 405 | NUMFILES_C=$(find "$MPT"/manyfiles -type f | wc -l) 406 | [ $(expr "$NUMDIRS_C" - 1) = "$NUMDIRS" ] && [ "$NUMFILES_C" = $(expr "$NUMDIRS" \* "$NUMFILES") ] || ERR="- FAILED" 407 | log "$FSP.4: $GEN_DUR seconds to create $NUMFILES files in each of the $NUMDIRS directories $ERR" >> "$LOG"/raw/generic-"$fs".log 408 | ERR="" 409 | 410 | # cleanup before starting the next test 411 | GEN_BEGIN=$(date +%s) 412 | $DEBUG echo "DEBUG-3: $(df -i "$MPT" | grep -v Filesystem)" >> "$LOG"/raw/generic-"$fs".err 413 | log "rm -rf "$MPT"/manyfiles" >> "$LOG"/raw/commands.txt 414 | $DEBUG rm -rf "$MPT"/manyfiles 2>>"$LOG"/raw/generic-"$fs".err 415 | [ $? = 0 ] || ERR="- FAILED" 416 | 417 | $DEBUG echo "DEBUG-4: $(df -i "$MPT" | grep -v Filesystem)" >> "$LOG"/raw/generic-"$fs".err 418 | GEN_END=$(date +%s) 419 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 420 | INODES=$(echo "$NUMFILES * $NUMDIRS" | bc) 421 | SPEED=$(echo "scale=2; $INODES / $GEN_DUR" | bc -l 2>/dev/null) 422 | log "$FSP.5: $GEN_DUR seconds ($SPEED i/s) to remove $INODES inodes $ERR" >> "$LOG"/raw/generic-"$fs".log 423 | ERR="" 424 | 425 | # create many dirs (we just replace NUMDIRS with NUMFILES and vice versa) 426 | GEN_BEGIN=$(date +%s) 427 | $DEBUG mkdir -p "$MPT"/manydirs 428 | log "for d in seq 1 $NUMFILES; do mkdir -p $MPT/manydirs/dir.d && cd $MPT/manydirs/dir.d && seq 1 $NUMDIRS | xargs touch; done" >> "$LOG"/raw/commands.txt 429 | for d in $(seq 1 "$NUMFILES"); do 430 | $DEBUG mkdir -p "$MPT"/manydirs/dir."$d" 2>>"$LOG"/raw/generic-"$fs".err 431 | $DEBUG cd "$MPT"/manydirs/dir."$d" 2>>"$LOG"/raw/generic-"$fs".err 432 | seq 1 "$NUMDIRS" | xargs touch 2>>"$LOG"/raw/generic-"$fs".err 433 | done 434 | sync 435 | GEN_END=$(date +%s) 436 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 437 | NUMDIRS_C=$(find "$MPT"/manydirs -type d | wc -l) 438 | NUMFILES_C=$(find "$MPT"/manydirs -type f | wc -l) 439 | [ $(expr "$NUMDIRS_C" - 1) = "$NUMFILES" ] && [ "$NUMFILES_C" = $(expr "$NUMDIRS" \* "$NUMFILES") ] || ERR="- FAILED" 440 | log "$FSP.6: $GEN_DUR seconds to create $NUMDIRS files in each of the $NUMFILES directories $ERR" >> "$LOG"/raw/generic-"$fs".log 441 | ERR="" 442 | 443 | # cleanup 444 | GEN_BEGIN=$(date +%s) 445 | $DEBUG echo "DEBUG-5: $(df -i "$MPT" | grep -v Filesystem)" >> "$LOG"/raw/generic-"$fs".err 446 | log "rm -rf "$MPT"/manydirs" >> "$LOG"/raw/commands.txt 447 | $DEBUG rm -rf "$MPT"/manydirs 2>>"$LOG"/raw/generic-"$fs".err 448 | [ $? = 0 ] || ERR="- FAILED" 449 | 450 | $DEBUG echo "DEBUG-6: $(df -i "$MPT" | grep -v Filesystem)" >> "$LOG"/raw/generic-"$fs".err 451 | GEN_END=$(date +%s) 452 | GEN_DUR=$(echo "scale=2; $GEN_END - $GEN_BEGIN" | bc -l) 453 | INODES=$(echo "$NUMFILES * $NUMDIRS" | bc) 454 | SPEED=$(echo "scale=2; $INODES / $GEN_DUR" | bc -l 2>/dev/null) 455 | log "$FSP.7: $GEN_DUR seconds ($SPEED i/s) to remove $INODES inodes $ERR" >> "$LOG"/raw/generic-"$fs".log 456 | ERR="" 457 | 458 | # results across all tests, appended after each test 459 | egrep -h seconds "$LOG"/raw/generic-"$fs".log | sed 's/.*[0-9][0-9]://;s/\.[0-9]//' >> "$LOG"/raw/generic_all.txt 460 | # sorted results, generated new after each run 461 | for t in $(seq 0 7); do 462 | fgrep -h ".$t:" "$LOG"/raw/generic-*.log | sort -n -k4 463 | echo 464 | done | sed 's/.*:[0-9][0-9]://;s/\.[0-9]//' > "$LOG"/generic.txt 465 | } 466 | 467 | ######################################################## 468 | # MAIN 469 | ######################################################## 470 | mount | grep -q "$MPT" && log "$MPT is already mounted!" 1 471 | 472 | BEGIN=$(date +%s) 473 | # iterating through filesystems 474 | for fs in $FILESYSTEMS; do 475 | echo "========================================================" 476 | FS_BEG=$(date +%s) 477 | 478 | # mkfs, mount, umount for every benchmark 479 | for b in $BENCHMARKS; do 480 | 481 | # See, if we're to skip this one 482 | echo "$SKIP" | grep -q "$fs.$b" 483 | if [ $? = 0 ]; then 484 | log "Skipping $b on $fs!" 485 | continue 486 | fi 487 | mkfs_"$fs" 488 | if [ ! $ERR = 0 ]; then 489 | log "mkfs failed ($fs, $b)" 490 | continue 491 | fi 492 | BM_BEG=$(date +%s) 493 | 494 | # Linux: flush caches before we start 495 | log "echo 3 > /proc/sys/vm/drop_caches" >> "$LOG"/raw/commands.txt 496 | echo 3 > /proc/sys/vm/drop_caches 2>/dev/null 497 | run_"$b" 498 | $DEBUG cd / 499 | $DEBUG sync 500 | $DEBUG sleep 5 501 | $DEBUG sync 502 | umountfs 503 | BM_END=$(date +%s) 504 | BM_DUR=$(echo "scale=2; ( $BM_END - $BM_BEG ) / 60" | bc -l) 505 | log "Running $b on $fs took $BM_DUR minutes." 506 | done 507 | FS_END=$(date +%s) 508 | FS_DUR=$(echo "scale=2; ( $FS_END - $FS_BEG ) / 60" | bc -l) 509 | echo 510 | log "Running all benchmarks on $fs took $FS_DUR minutes." 511 | echo 512 | done 2>&1 | tee "$LOG"/fs-bench.log 513 | 514 | $DEBUG dmesg > "$LOG"/env/dmesg_post.txt 515 | END=$(date +%s) 516 | DUR=$(echo "scale=2; ( $END - $BEGIN ) / 60" | bc -l) 517 | log "Finished after $DUR minutes." 518 | 519 | -------------------------------------------------------------------------------- /benchmarks/geli_benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2019 Christian Kujau 4 | # Read-only Benchmark for FreeBSD/geli. 5 | # 6 | CIPHERS="aes-xts aes-cbc blowfish-cbc camellia-cbc 3des-cbc" # See geli(8) 7 | PROG=$(basename $0) 8 | set -e 9 | 10 | _help() { 11 | echo "Usage: ${PROG} [devicename] [size(MB)] [runs]" 12 | echo " ${PROG} report [out.txt]" 13 | echo "" 14 | echo "Example: ${PROG} ada0p2 5 | tee out.txt" 15 | echo " ${PROG} report out.txt" 16 | } 17 | 18 | _benchmark() { 19 | DEV="$1" 20 | SIZE="$2" 21 | NUM="$3" 22 | 23 | 24 | # RAW 25 | for i in $(seq 1 "${NUM}"); do 26 | printf "MODE: raw I: $i\t" 27 | dd if=/dev/"${DEV}" of=/dev/null bs=1k count="${SIZE}"k conv=sync 2>&1 | grep bytes 28 | done 29 | 30 | # ENCRYPTED 31 | for c in ${CIPHERS}; do 32 | geli onetime -e "${c}" /dev/"${DEV}" 33 | 34 | # Repeat NUM times... 35 | for i in $(seq 1 "${NUM}"); do 36 | printf "MODE: ${c} I: $i\t" 37 | dd if=/dev/"${DEV}.eli" of=/dev/null bs=1k count="${SIZE}"k conv=sync 2>&1 | grep bytes 38 | done 39 | 40 | geli detach /dev/"${DEV}.eli" 41 | done 42 | } 43 | 44 | case $1 in 45 | report) 46 | if [ -f "$2" ]; then 47 | for c in $(awk '/MODE:/ {print $2}' "$2" | uniq); do 48 | NUM=$(grep -c "MODE: $c" "$2") 49 | printf "${c} \t" 50 | awk "/MODE: ${c}/ {print \$9, \$11, \$2}" "$2" | sed 's/(//' | \ 51 | awk "{time+=\$1} {speed+=\$2} END {print time/${NUM}, \"sec /\", speed/${NUM}/1024/1024, \"MB/s\"}" 52 | done 53 | else 54 | _help 55 | fi 56 | ;; 57 | 58 | *) 59 | if [ -c /dev/"$1" ] && [ "$2" -gt 0 ] && [ "$3" -gt 0 ]; then 60 | _benchmark "${1}" "${2}" "${3}" 61 | else 62 | _help 63 | fi 64 | ;; 65 | esac 66 | -------------------------------------------------------------------------------- /benchmarks/password-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2014 Christian Kujau 4 | # Test various password generators and password checkers 5 | # 6 | # Needs the following programs installed: 7 | # cracklib-runtime, passwdqc, pwgen, apg, gpw, makepasswd, openssl, GNU/parallel 8 | # 9 | 10 | # Password length and number of passwords required 11 | if [ -z "$1" ]; then 12 | echo "Usage: $(basename "$0") [length] [num]" 13 | exit 1 14 | else 15 | LEN="$1" 16 | NUM="$2" 17 | 18 | # See the comment for r_pwqgen below 19 | if [ "$LEN" -gt 22 ]; then 20 | echo "WARNING: \"length\" is greater than 22, results for pwqgen may not be correct!" 21 | fi 22 | 23 | # See the comment for r_openssl below 24 | if [ "$LEN" -gt 64 ]; then 25 | echo "WARNING: \"length\" is greater than 64, results for openssl may not be correct!" 26 | fi 27 | fi 28 | 29 | stats() { 30 | # arguments: FAILED, NUM, TYPE, TIME_E, TIME_S 31 | echo "$FAILED passwords ($(echo "scale=2; $FAILED / $NUM * 100" | bc -l)%) failed for $c, runtime: $(expr "$TIME_E" - "$TIME_S") seconds." 32 | } 33 | 34 | # Password checkers 35 | r_cracklib() { 36 | parallel --pipe /usr/sbin/cracklib-check 2>/dev/null | fgrep -c -v ': OK' 37 | } 38 | 39 | r_pwqcheck() { 40 | parallel --pipe pwqcheck -1 --multi 2>/dev/null | fgrep -c -v 'OK:' 41 | } 42 | 43 | # Password generators 44 | r_pwgen() { 45 | pwgen -s -1 "$LEN" "$NUM" 46 | } 47 | 48 | # 49 | # OK, pwqgen is somewhat special: while all other programs can generate (a 50 | # certain number of) passwords of a certain length, pwqgen generates only one 51 | # password of certain randomness (in bits). With random=85 (the highest 52 | # setting), we're only guaranteed to get a password of at least 22 characters: 53 | # 54 | # $ for a in {1..10000}; do pwqgen random=85; done | awk '{print length}' | sort -n | head -1 55 | # => 22 56 | # 57 | # The absolute maximum length seems to be 35 characters: 58 | # 59 | # $ for a in {1..10000}; do pwqgen random=85; done | awk '{print length}' | sort -rn | head -1 60 | # => 35 61 | # 62 | r_pwqgen() { 63 | # The following is good enough for passwords of length 22 characters and below: 64 | for a in $(seq 1 "$NUM"); do 65 | pwqgen random=85 66 | done | cut -c-"$LEN" | egrep -o "^.{$LEN}$" 67 | 68 | # The following would be the correct solution, but also takes much longer: 69 | # i=0; while [ $i -lt $NUM ]; do 70 | # pwqgen random=85 | cut -c-"$LEN" | egrep -o "^.{$LEN}$" && i=$((i+1)) 71 | # done 72 | } 73 | 74 | r_apg() { 75 | apg -a 1 -m "$LEN" -x "$LEN" -n "$NUM" 76 | } 77 | 78 | r_gpw() { 79 | # gpw: Password Generator 80 | # https://www.multicians.org/thvv/tvvtools.html#gpw 81 | # USAGE: gpw [npasswds] [pwlength<100] 82 | gpw "$NUM" "$LEN" 83 | } 84 | 85 | r_makepasswd() { 86 | # There are actually two versions available: 87 | # 88 | # The Debian version of makepasswd resides in the "whois" package: 89 | # > whois: Why does it include mkpasswd? 90 | # > https://bugs.debian.org/116260 91 | # 92 | # > Fedora / mkpasswd 93 | # > https://koji.fedoraproject.org/koji/packageinfo?packageID=17537 94 | # 95 | # makepasswd --chars=$LEN --count=$NUM # Debian 96 | makepasswd -l "$LEN" -n "$NUM" # Fedora 97 | } 98 | 99 | r_urandom() { 100 | for a in $(seq 1 "$NUM"); do 101 | tr -dc A-Za-z0-9_ < /dev/urandom | head -c "$LEN" | xargs 102 | done 103 | } 104 | 105 | r_openssl() { 106 | # 107 | # While openssl(1) is not strictly a password generator, it can emit (pseudo-)random 108 | # strings of text. But, as pwqgen above, it has the same limitation: it generates only 109 | # one certain number of random bytes of unspecified length. We're using base64 encoding 110 | # here, to generate printable text - but this means that the last (two) characters are 111 | # two equal signs ("=="). Using -hex would limit our charset too much though. Also, 112 | # since we're reading line-by-line, we have an upper limit of 64 characters. 113 | # 114 | for a in $(seq 1 "$NUM"); do 115 | openssl rand -base64 64 | head -1 116 | done | sed 's/.=$//' | cut -c-"$LEN" 117 | } 118 | 119 | # main loop 120 | for c in cracklib pwqcheck; do 121 | for g in pwgen pwqgen apg gpw makepasswd openssl urandom; do 122 | printf "%10s - %s" $g 123 | TIME_S=$(date +%s) 124 | FAILED=$(r_$g | r_$c) 125 | TIME_E=$(date +%s) 126 | stats "$FAILED" "$NUM" $c "$TIME_E" "$TIME_S" 127 | done 128 | echo 129 | done 130 | -------------------------------------------------------------------------------- /benchmarks/ssh-performance.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2014 Christian Kujau 4 | # 5 | # Poor wo/man's SSH benchmark. Inspired by: 6 | # > OpenSSH default/preferred ciphers, hash, etc for SSH2 7 | # > https://security.stackexchange.com/a/26074 8 | # 9 | # Compare with: 10 | # > OpenBSD: cipher-speed.sh 11 | # > https://anongit.mindrot.org/openssh.git/tree/regress/cipher-speed.sh 12 | # 13 | _help() { 14 | echo "Usage: $(basename "$0") run [user@][host] [size-in-MB] [runs] | tee report.out" 15 | echo " $(basename "$0") report [report.out] [top]" 16 | echo " $(basename "$0") worst [report.out] [top]" 17 | echo 18 | echo "Note: Cipher, MAC and Kex algorithms can also be controlled by" 19 | echo " the CIPHER, MAC and KEX environment variables." 20 | exit 1 21 | } 22 | 23 | # 24 | # Benchmark 25 | # 26 | _run() { 27 | # We'll need a temporary file, but remove it later on. 28 | TEMP=$(mktemp) 29 | trap 'rm -f "$TEMP"; exit' EXIT INT TERM HUP 30 | 31 | # Enumerate all known ciphers, MAC and key exchange algorithms. 32 | # Available since OpenSSH 6.3 33 | # 34 | # === Distribution support ================ 35 | # | Debian/wheezy-backports || OpenSSH 6.6 36 | # | Ubuntu/14.04 || OpenSSH 6.6 37 | # | Fedora/20 || OpenSSH 6.3 38 | # | openSUSE/13.2 || OpenSSH 6.6 39 | # 40 | CIPHER="${CIPHER:-$(ssh -Q cipher)}" 41 | MAC="${MAC:-$(ssh -Q mac)}" 42 | KEX="${KEX:-$(ssh -Q kex)}" 43 | 44 | # Possible combinations 45 | COMB=$(expr $(echo "$CIPHER" | awk '{print NF}') \* $(echo "$MAC" | awk '{print NF}') \* $(echo "$KEX" | awk '{print NF}')) 46 | 47 | # Initialize combination counter 48 | n=1 49 | 50 | # Ready, set, Go! 51 | for c in $CIPHER; do 52 | for m in $MAC; do 53 | for k in $KEX; do 54 | 55 | # Initialize run counter 56 | r=1 57 | 58 | printf "$n/$COMB cipher: $c \t mac: $m \t kex: $k - " 59 | # [ $RUNS -lt 10 ] && printf " " # Formatting quirk... 60 | 61 | a=$(date +%s) 62 | while [ $r -le "$RUNS" ]; do 63 | printf "$r\b" >&2 # We don't need this on stdout 64 | 65 | dd if=/dev/zero bs=1024k count="$SIZE" 2>/dev/null | \ 66 | ssh -T -o CheckHostIP=no -o StrictHostKeyChecking=no \ 67 | -o Ciphers="$c" -o MACs="$m" -o KexAlgorithms="$k" "$HOST" "cat > /dev/null" 2>"$TEMP" 68 | 69 | # Did we manage to establish a connection? 70 | if [ ! $? = 0 ]; then 71 | ERR=1 72 | echo "n/a ($(cut -c-40 "$TEMP"))" 73 | break 74 | fi 75 | r=$((r+1)) 76 | done 77 | 78 | # Calculate the average time for one run; reset the error counter. 79 | b=$(date +%s) 80 | d=$(echo \( "$b" - "$a" \) / "$RUNS" | bc) 81 | [ -z "$ERR" ] && echo "$d seconds avg." || unset ERR 82 | n=$((n+1)) 83 | done 84 | done 85 | done 86 | } 87 | 88 | # 89 | # Reports 90 | # 91 | _report() { 92 | echo "### Top-$TOP overall" 93 | grep seconds "$FILE" | sort "$REVERSE" -nk9 | head -"$TOP" 94 | echo 95 | 96 | echo "### Fastest cipher" 97 | awk '/seconds/ {print $3, $9, "seconds"}' "$FILE" | sort "$REVERSE" -nk2 | head -"$TOP" | uniq -c 98 | echo 99 | 100 | echo "### Fastest MAC" 101 | awk '/seconds/ {print $5, $9, "seconds"}' "$FILE" | sort "$REVERSE" -nk2 | head -"$TOP" | uniq -c 102 | echo 103 | 104 | echo "### Fastest Kex" 105 | awk '/seconds/ {print $7, $9, "seconds"}' "$FILE" | sort "$REVERSE" -nk2 | head -"$TOP" | uniq -c 106 | echo 107 | 108 | echo "### Top-$TOP for each cipher" 109 | for c in $(awk '/seconds/ {print $3}' "$FILE" | sort -u); do 110 | echo "### Cipher: $c" 111 | fgrep seconds "$FILE" | grep "$c" | sort "$REVERSE" -nk9 | head -"$TOP" 112 | echo 113 | done 114 | 115 | echo "### Top-$TOP for each MAC" 116 | for m in $(awk '/seconds/ {print $5}' "$FILE" | sort -u); do 117 | echo "### MAC: $m" 118 | fgrep seconds "$FILE" | grep "$m" | sort "$REVERSE" -nk9 | head -"$TOP" 119 | echo 120 | done 121 | 122 | echo "### Top-$TOP for each Kex" 123 | for k in $(awk '/seconds/ {print $7}' "$FILE" | sort -u); do 124 | echo "### Kex: $k" 125 | fgrep seconds "$FILE" | grep "$k" | sort "$REVERSE" -nk9 | head -"$TOP" 126 | echo 127 | done 128 | } 129 | 130 | # Pick your poison. 131 | case $1 in 132 | run) 133 | if [ $# -ne 4 ]; then 134 | _help 135 | else 136 | HOST="$2" 137 | SIZE="$3" 138 | RUNS="$4" 139 | _run 140 | fi 141 | ;; 142 | 143 | report|worst) 144 | if [ ! -f "$2" ]; then 145 | _help 146 | else 147 | [ "$1" = "worst" ] && REVERSE="-r" # Hall of Shame 148 | FILE="$2" 149 | TOP=${3:-5} 150 | _report 151 | fi 152 | ;; 153 | 154 | *) 155 | _help 156 | ;; 157 | esac 158 | -------------------------------------------------------------------------------- /benchmarks/test-digests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2015 Christian Kujau 4 | # 5 | # Benchmark various checksum programs 6 | # 7 | # Example: 8 | # $ dd if=/dev/urandom bs=1M count=200 | pv > test.img 9 | # $ ./test-digests.sh test.img 10 | tee out.log 10 | # 11 | # Print results with: 12 | # $ egrep -v '^RHash|calculated|test.img' out.log | grep MBps | sort -rnk8 13 | # $ grep ^TEST out.log | egrep -v 'rhash_benchmark|SKIPPED' | sort -nk7 14 | # 15 | if [ -f "$1" ]; then 16 | FILE="$1" 17 | RUNS=${2:-1} 18 | else 19 | echo "Usage: $(basename "$0") [file] [n]" 20 | exit 1 21 | fi 22 | 23 | # unset me! 24 | # DEBUG=echo 25 | 26 | get_time() { 27 | TEST="$1" 28 | # Only one run for rhash_benchmark 29 | [ "$TEST" = "rhash_benchmark" ] && n=1 || n=$RUNS 30 | shift 31 | 32 | TIME_A=$(date +%s) 33 | for i in $(seq 1 "$n"); do 34 | $DEBUG $@ 35 | done 36 | TIME_B=$(date +%s) 37 | echo "TEST: $TEST / DIGEST: $d / $(echo "$TIME_B" - "$TIME_A" | bc -l) seconds over $n runs" 38 | } 39 | 40 | 41 | # rhash benchmarks 42 | # NOTE: just for kicks, we'll test SHA3 too 43 | for d in md5 sha1 sha224 sha256 sha384 sha512 ripemd160 sha3-224 sha3-256 sha3-384 sha3-512; do 44 | get_time rhash_benchmark rhash -B --"$d" 45 | done 46 | 47 | # MAIN LOOP 48 | for d in md5 sha1 sha224 sha256 sha384 sha512 ripemd160; do 49 | get_time rhash rhash --"$d" --bsd "$FILE" 50 | get_time openssl openssl dgst -"$d" "$FILE" 51 | 52 | # GNU/coreutils doesn't understand RIPEMD160 53 | if [ ! $d = "ripemd160" ]; then 54 | get_time coreutils "$d"sum "$FILE" 55 | else 56 | echo "TEST: coreutils / DIGEST: $d / SKIPPED" 57 | fi 58 | 59 | # Perl's shasum only understands SHA variants. 60 | # FIXME: that's not true, at all -- we could just use the installed 61 | # modules directly, like: 62 | # > perl -le 'use Digest::SHA qw(sha1_hex); print sha1_hex(<>);' 63 | # > perl -le 'use Digest::MD5 qw(md5_hex); print md5_hex(<>);' 64 | # > perl -le 'use Digest::SHA qw(sha256_hex); print sha256_hex(<>);' 65 | # > perl -le 'use Digest::SHA3 qw(sha3_256_hex); print sha3_256_hex(<>);' 66 | case $d in 67 | sha*) 68 | # Remove the "sha" prefix from the digest names 69 | dp=${d##sha} 70 | get_time perl shasum -a "$dp" "$FILE" 71 | ;; 72 | 73 | *) 74 | echo "TEST: perl / DIGEST: $d / SKIPPED" 75 | ;; 76 | esac 77 | echo 78 | done 79 | -------------------------------------------------------------------------------- /benchmarks/tmpfs-ramfs-ramdisk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2014 Christian Kujau 4 | # Tmpfs vs Ramfs vs Ramdisk 5 | # 6 | DIR_TMPFS=/mnt/tmpfs 7 | DIR_RAMFS=/mnt/ramfs 8 | DIR_RAMDISK=/mnt/ramdisk 9 | RESULTS=/var/tmp/bonnie 10 | FS="btrfs ext2 ext3 ext4 jfs reiserfs xfs" # Adjust as needed 11 | 12 | # We need a 2nd argument as well. 13 | if [ -z "$2" ]; then 14 | echo "Usage: $0 [tmpfs|ramfs|ramdisk] [size(MB)]" 15 | exit 1 16 | else 17 | SIZE="$2" 18 | fi 19 | 20 | # Create (missing) directories 21 | mkdir -p -m0700 $DIR_TMPFS $DIR_RAMFS $DIR_RAMDISK $RESULTS || exit 22 | 23 | # Benchmark cycle 24 | benchmark() { 25 | B_DIR="$1" 26 | B_TYPE="$2" 27 | B_SIZE=$(expr "$SIZE" / 5) # -s file size 28 | B_RAM=$(expr "$SIZE" / 10) # -r RAM size 29 | B_NUMFILES=$(expr "$SIZE" / "$B_SIZE") # -n file count 30 | B_NUMTESTS=1 # -x test count 31 | bonnie++ -d "$B_DIR" -s "$B_SIZE" -n "$B_NUMFILES" -m "$B_TYPE" -r "$B_RAM" -x $B_NUMTESTS -u root \ 32 | 1>$RESULTS/bonnie-"$B_TYPE".csv 2>$RESULTS/bonnie-"$B_TYPE".err 33 | } 34 | 35 | # Switch 36 | case $1 in 37 | tmpfs) 38 | mount -t tmpfs -o size="$SIZE"M tmpfs $DIR_TMPFS 39 | 40 | benchmark $DIR_TMPFS "$1" 41 | umount $DIR_TMPFS 42 | ;; 43 | 44 | ramfs) 45 | mount -t ramfs -o size="$SIZE"M ramfs $DIR_RAMFS 46 | 47 | benchmark $DIR_RAMFS "$1" 48 | umount $DIR_RAMFS 49 | ;; 50 | 51 | ramdisk) 52 | lsmod | grep -q brd && rmmod brd 53 | modprobe brd rd_size=$(expr "$SIZE" \* 1024) 54 | 55 | # Which filesystem should we use? 56 | for fs in $FS; do 57 | case $fs in 58 | btrfs) 59 | M_OPTIONS="-f" 60 | ;; 61 | 62 | ext2|ext3|ext4) 63 | M_OPTIONS="-q -F" 64 | ;; 65 | 66 | jfs|reiserfs|xfs) 67 | M_OPTIONS="-qf" 68 | ;; 69 | esac 70 | mkfs."$fs" $M_OPTIONS /dev/ram0 > /dev/null 2>&1 || continue 71 | mount -t "$fs" /dev/ram0 $DIR_RAMDISK || continue 72 | benchmark $DIR_RAMDISK "$1"_"$fs" 73 | sleep 1 74 | umount $DIR_RAMDISK || break 75 | done 76 | sleep 1 77 | rmmod brd 78 | ;; 79 | 80 | *) 81 | echo "Usage: $0 [tmpfs|ramfs|ramdisk] [size(MB)]" 82 | exit 1 83 | ;; 84 | esac 85 | 86 | -------------------------------------------------------------------------------- /benchmarks/vbox-nic-bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2017 Christian Kujau 4 | # 5 | # 6.1. Virtual networking hardware 6 | # https://www.virtualbox.org/manual/ch06.html#nichardware 7 | # 8 | # > vboxmanage --help | grep -A2 nictype 9 | # --nictype1 Am79C970A - pcnet II 10 | # Am79C973 - pcnet III - default 11 | # 82540EM - MT Desktop - Windows Vista 12 | # 82543GC - T Server - Windows XP 13 | # 82545EM - MT Server - OVF imports 14 | # virtio - virtio-net - KVM 15 | # 16 | NICTYPES="Am79C970A Am79C973 82540EM 82543GC 82545EM virtio" 17 | 18 | if [ $# -ne 3 ]; then 19 | echo "Usage: $(basename "$0") [vm1] [vm2] [num]" 20 | echo " $(basename "$0") [report] [file.log] [num]" 21 | echo "" 22 | echo " NOTES:" 23 | echo " * An iperf3 server MUST be started on vm1 after boot." 24 | echo " * Password-less logins to and between the VMS needed." 25 | echo " * Set [num] to 0 for a dry-run" 26 | echo "" 27 | echo "" 28 | exit 1 29 | else 30 | VM1="$1" 31 | VM2="$2" 32 | NUM="$3" 33 | fi 34 | 35 | # Short-circuit for reporting mode, because we were too 36 | # lazy to think this through... 37 | if [ "$1" = "report" ]; then 38 | awk '/Running/ {print $6, $8}' "$2" | while read n1 n2; do 39 | # This only works when NUM is the same value that we have tested with! 40 | awk "/$n1 - $n2/ {sum+=\$10} END {print \"$n1 - $n2\t\", sum / 2 / $NUM, \"MB/s\"}" "$2" 41 | done 42 | exit $? 43 | fi 44 | 45 | # Dry-run? 46 | [ "$NUM" = 0 ] && DEBUG=echo 47 | 48 | die() { 49 | echo "$@" 50 | exit 2 51 | } 52 | 53 | # We really need this only for the first run, I guess 54 | ison() { 55 | # running or poweroff/aborted/...? 56 | STATE=$(VBoxManage showvminfo "$1" --machinereadable | awk -F= '/VMState=/ {print $2}' | sed 's/\"//g') 57 | if [ "$STATE" = "running" ]; then 58 | true 59 | else 60 | false 61 | fi 62 | } 63 | 64 | for nic2 in $NICTYPES; do 65 | echo "### NIC2: $nic2 -- shutting down $VM2" 66 | ison "$VM2" && ( $DEBUG VBoxManage controlvm "$VM2" acpipowerbutton || die "VBoxManage controlvm $VM2 acpipowerbutton FAILED" ) 67 | $DEBUG sleep 20 68 | 69 | echo "### NIC2: $nic2 -- setting NIC to $nic2 on $VM2" 70 | $DEBUG VBoxManage modifyvm "$VM2" --nictype1 "$nic2" || die "VBoxManage modifyvm $VM2 --nictype1 "$nic2" FAILED" 71 | $DEBUG VBoxManage showvminfo "$VM2" --machinereadable | grep -A1 -w nic1 72 | 73 | echo "### NIC2: $nic2 -- starting $VM2" 74 | $DEBUG VBoxManage startvm "$VM2" --type headless || die "VBoxManage startvm $VM2 --type headless FAILED" 75 | # $DEBUG VBoxHeadless --startvm $VM2 & 76 | # [ $? = 0 ] || die "VBoxHeadless --startvm $VM2 FAILED" 77 | $DEBUG sleep 30 78 | 79 | for nic1 in $NICTYPES; do 80 | echo "### NIC1: $nic1 -- shutting down $VM1" 81 | ison "$VM1" && ( $DEBUG VBoxManage controlvm "$VM1" acpipowerbutton || die "VBoxManage controlvm $VM1 acpipowerbutton FAILED" ) 82 | $DEBUG sleep 20 83 | 84 | echo "### NIC1: $nic1 -- setting NIC to $nic1 on $VM1" 85 | ison "$VM1" || ( $DEBUG VBoxManage modifyvm "$VM1" --nictype1 "$nic1" || die "VBoxManage modifyvm $VM1 --nictype1 "$nic1" FAILED" ) 86 | $DEBUG VBoxManage showvminfo "$VM1" --machinereadable | grep -A1 -w nic1 87 | 88 | echo "### NIC1: $nic1 -- starting $VM1" 89 | $DEBUG VBoxManage startvm "$VM1" --type headless || die "VBoxManage startvm $VM1 --type headless FAILED" 90 | # $DEBUG VBoxHeadless --startvm $VM1 & 91 | # [ $? = 0 ] || die "VBoxHeadless --startvm $VM1 FAILED" 92 | $DEBUG sleep 30 93 | 94 | echo "### Running iperf3 tests. NIC1: $nic1 NIC2: $nic2" 95 | a=1 96 | while [ $a -le "$NUM" ] || [ "$NUM" = 0 ]; do 97 | echo "### RUN $a of $NUM" 98 | # NAT # $DEBUG ssh -p2001 192.168.56.1 "iperf3 -f M -c 10.0.2.5" || die "ssh -p2001 192.168.56.1 ... FAILED" 99 | $DEBUG ssh "$VM2" "iperf3 -f M -T \"$nic1 - $nic2\" -c $VM1" || die "ssh $VM2 -- FAILED" 100 | [ -z "$DEBUG" ] && a=$((a++1)) || break 101 | done | egrep 'RUN|ssh|sender|receiver' # The "ssh" is only matched in $DEBUG mode 102 | echo 103 | done 104 | done 105 | -------------------------------------------------------------------------------- /checksum_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2013 Christian Kujau 4 | # 5 | # Generate checksums of files and store them via Extended Attributes. 6 | # 7 | # == Requirements == 8 | # Darwin: /sbin/md5 or openssl 9 | # FreeBSD: /sbin/{md5,sha{1,256,512}} and sysutils/pxattr 10 | # Linux: md5sum or sha{1,256,512}sum from GNU/coreutils 11 | # Solaris: digest(1) and runat(1) from SUNWcsu 12 | # We will also need at least an XPG4 or Korn shell on older Solaris 13 | # systems, as older shells may not understand command substitution 14 | # with parentheses, as required by POSIX. 15 | # NetBSD: cksum & {g,s}etextattr, should be included in src. 16 | # OpenBSD: No extended attribute support since July 2005: 17 | # > https://github.com/openbsd/src/commit/9dd8235" 18 | # > Extended Attributes was a piece to get to ACLs, however ACLs have 19 | # > not been worked on, so EA is pointless. Also the code is not enabled 20 | # > in GENERIC so it is not being tested or maintained. 21 | # 22 | # Each operating system has its own routines for setting/getting EAs and also 23 | # for calculating checksums. The only hardcoded value is the digest algorithm 24 | # now. 25 | # 26 | # TODO: 27 | # - Support other message digest algorithms (rmd160, sha3, ...) 28 | # - Support other checksum toolsets (coreutils, openssl, rhash) 29 | # - Rewrite file handling, process multiple files all at once. 30 | # - Or rewrite this whole thing in Python, for portability's sake? (hashlib, os/xattr) 31 | # 32 | DIGEST="md5" # md5, sha1, sha256, sha512 33 | PROG=$(basename "$0") 34 | 35 | # Adjust if needed 36 | PATH=/bin:/usr/bin:/sbin:/usr/local/bin:/opt/local/bin:/opt/csw/bin:/usr/sfw/bin 37 | 38 | print_usage() 39 | { 40 | cat </dev/null | awk '{print $NF}' 141 | ;; 142 | 143 | FreeBSD) 144 | pxattr -n user.checksum.${DIGEST} "$1" 2>/dev/null | awk '/user.checksum/ {print $NF}' 145 | ;; 146 | 147 | Linux) 148 | # NOTE: If the designated EA is not set, getfattr may not return a non-zero 149 | # exit code. This has been fixed upstream but may not have been picked up 150 | # by your distribution. 151 | # 152 | # > getfattr should indicate missing xattrs via exit value 153 | # > https://bugs.debian.org/520659 154 | # 155 | # > getfattr does not return failure when designated attribute does not exist 156 | # > https://bugzilla.redhat.com/show_bug.cgi?id=660619 157 | # 158 | getfattr --only-values --name user.checksum.${DIGEST} -- "$1" 2>/dev/null | awk '/[a-z0-9]/ {print $1}' 159 | ;; 160 | 161 | NetBSD) 162 | getextattr -q user checksum.${DIGEST} "$1" 163 | ;; 164 | 165 | SunOS) 166 | runat "$1" cat user.checksum.${DIGEST} 2>/dev/null 167 | ;; 168 | 169 | *) 170 | do_log "We don't support ${OS} :-(" 1 171 | ;; 172 | esac 173 | } 174 | 175 | # SET 176 | _set() { 177 | echo "Setting user.checksum.${DIGEST} on ${1}..." 178 | CHECKSUM_C=$(_calc "$1") 179 | 180 | case ${OS} in 181 | Darwin) 182 | xattr -w user.checksum.${DIGEST} "${CHECKSUM_C}" "$1" 183 | ;; 184 | 185 | FreeBSD) 186 | pxattr -n user.checksum.${DIGEST} -v "${CHECKSUM_C}" "$1" 187 | ;; 188 | 189 | Linux) 190 | setfattr --name user.checksum.${DIGEST} --value "${CHECKSUM_C}" -- "$1" 191 | ;; 192 | 193 | NetBSD) 194 | setextattr user checksum.${DIGEST} "${CHECKSUM_C}" "$1" 195 | ;; 196 | 197 | SunOS) 198 | runat "$1" "echo ${CHECKSUM_C} > user.checksum.${DIGEST}" 199 | ;; 200 | 201 | *) 202 | do_log "We don't support ${OS} :-(" 1 203 | ;; 204 | esac 205 | } 206 | 207 | # Main routines, with switches for each OS 208 | case ${ACTION} in 209 | ####### GET 210 | get) 211 | CHECKSUM_S=$(_get "${FILE}") 212 | 213 | # Did we find a checksum? 214 | if [ -n "${CHECKSUM_S}" ]; then 215 | # Print out checksum 216 | echo "user.checksum.${DIGEST}: ${CHECKSUM_S}" 217 | else 218 | do_log "No user.checksum.${DIGEST} found for ${FILE}!" 1 219 | fi 220 | ;; 221 | 222 | ####### SET 223 | set) 224 | _set "${FILE}" || \ 225 | do_log "ERROR: failed to set user.checksum.${DIGEST} for file ${FILE}!" 1 226 | ;; 227 | 228 | ####### GET-SET) 229 | get-set) 230 | CHECKSUM_S=$(_get "${FILE}") 231 | 232 | # Did we find a checksum? 233 | if [ -n "${CHECKSUM_S}" ]; then 234 | # Print out checksum 235 | echo "user.checksum.${DIGEST}: ${CHECKSUM_S}" 236 | else 237 | # Set checksum 238 | _set "${FILE}" 239 | fi 240 | ;; 241 | 242 | ####### CHECK-SET 243 | check-set) 244 | CHECKSUM_S=$(_get "${FILE}") 245 | 246 | # Did we find a checksum? 247 | if [ -n "${CHECKSUM_S}" ]; then 248 | # Verify checksum 249 | $0 check "${FILE}" # Calling ourselves! 250 | else 251 | # Set checksum 252 | _set "${FILE}" 253 | fi 254 | ;; 255 | 256 | ####### CHECK 257 | check) 258 | CHECKSUM_C=$(_calc "${FILE}") 259 | CHECKSUM_S=$(_get "${FILE}") 260 | 261 | # Bail out if there is no checksum to compare 262 | [ -z "${CHECKSUM_C}" ] || [ -z "${CHECKSUM_S}" ] && \ 263 | do_log "ERROR: failed to calculate/get the ${DIGEST} checksum for file ${FILE}!" 1 264 | 265 | # Compare checksums 266 | if [ "${CHECKSUM_S}" = "${CHECKSUM_C}" ]; then 267 | echo "FILE: ${FILE} - OK" 268 | true 269 | else 270 | echo "FILE: ${FILE} - FAILED" 271 | false 272 | fi 273 | ;; 274 | 275 | ####### REMOVE 276 | remove) 277 | echo "Removing user.checksum.${DIGEST} from ${FILE}..." 278 | case ${OS} in 279 | Darwin) 280 | xattr -d user.checksum.${DIGEST} "${FILE}" 281 | ;; 282 | 283 | FreeBSD) 284 | pxattr -x user.checksum.${DIGEST} "${FILE}" 285 | ;; 286 | 287 | NetBSD) 288 | rmextattr user checksum.${DIGEST} "${FILE}" 289 | ;; 290 | 291 | Linux) 292 | setfattr --remove user.checksum.${DIGEST} -- "${FILE}" 293 | ;; 294 | 295 | SunOS) 296 | runat "${FILE}" rm user.checksum.${DIGEST} 297 | ;; 298 | 299 | *) 300 | do_log "We don't support ${OS} :-(" 1 301 | ;; 302 | esac 303 | ;; 304 | 305 | ####### TEST 306 | test) 307 | # We need a temporary file, even on macOS 308 | TEMP=$(mktemp -p . 2>/dev/null || mktemp ./tmp.XXXXXXX 2>/dev/null) 309 | trap "rm -f ${TEMP}" EXIT INT TERM HUP 310 | 311 | if [ ! -f "${TEMP}" ]; then 312 | do_log "Failed to create temporary file ${TEMP}!" 1 313 | else 314 | date > "${TEMP}" 315 | fi 316 | 317 | # More, and more elaborate tests needed. 318 | for action in get get-set check-set check remove remove check-set remove check; do 319 | echo "### ACTION: ${action}" 320 | $0 ${action} "${TEMP}" 321 | echo $? && echo 322 | done 323 | 324 | echo "### ACTION: set - alter - check" 325 | $0 set "${TEMP}" 326 | echo "Modifying ${TEMP}..." 327 | echo . >> "${TEMP}" 328 | $0 check "${TEMP}" 329 | echo "RC: $?" 330 | ;; 331 | 332 | ####### HELP 333 | *) 334 | print_usage 335 | exit 1 336 | ;; 337 | esac 338 | -------------------------------------------------------------------------------- /convert-music.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2014 Christian Kujau 4 | # 5 | # Convert music from/to various formats 6 | # 7 | # TODO: Add more conversions, much more :-) 8 | # 9 | # > Convert flac to (almost) anything 10 | # > https://forums.gentoo.org/viewtopic-t-554188.html 11 | # 12 | # > .ogg to .mp3 13 | # > https://forums.gentoo.org/viewtopic-t-463068.html 14 | # 15 | if [ ! $# -eq 2 ] || [ ! -f "$2" ]; then 16 | echo "Usage: $(basename "$0") [conversion] [file]" 17 | echo "Conversions: flac2mp3, m4a2mp3, ogg2mp3" 18 | exit 1 19 | else 20 | CONVERSION="$1" 21 | FILE="$2" 22 | PATH=${PATH}:/opt/lame/bin 23 | fi 24 | 25 | # LAME defaults 26 | # -m j - joint stereo (default) 27 | # -q 0 - quality (0 best, 9 fastest, default: 5) 28 | # --vbr-new - invokes newest VBR algorithm 29 | # -V 0 - enable VBR (0 best, 9 fastest, default: 4) 30 | # -s 44.1 - sample rate 31 | # --add-id3v2 - force addition of version 2 tag 32 | # --ignore-tag-errors - ignore errors in values passed for tags 33 | # --pad-id3v2 - ? 34 | LAMEARGS="-m j -q 5 --vbr-new -V 4 -s 44.1 --add-id3v2 --ignore-tag-errors" 35 | 36 | case ${CONVERSION} in 37 | flac2mp3) 38 | # Convert FLAC to MP3 39 | # https://wiki.archlinux.org/index.php/Convert_FLAC_to_MP3 40 | # Software needed: flac, lame 41 | OUTPUT=${FILE%.flac}.mp3 42 | TRACK=$(metaflac --show-tag=TRACKNUMBER "${FILE}" | sed s/.*=//) 43 | TITLE=$(metaflac --show-tag=TITLE "${FILE}" | sed s/.*=//) 44 | ARTIST=$(metaflac --show-tag=ARTIST "${FILE}" | sed s/.*=//) 45 | ALBUM=$(metaflac --show-tag=ALBUM "${FILE}" | sed s/.*=//) 46 | DATE=$(metaflac --show-tag=DATE "${FILE}" | sed s/.*=//) 47 | GENRE=$(metaflac --show-tag=GENRE "${FILE}" | sed s/.*=//) 48 | # 49 | # lame options: 50 | # -m j joint stereo 51 | # -q 0 slowest & best possible version of all algorithms 52 | # --vbr-new newest VBR algorithm 53 | # -V 0 highest quality 54 | # -s 44.1 sampling frequency 55 | # 56 | # Note: if GENRE is empty, use "12" (other). If TRACKNUMBER is empty, use "0". 57 | flac --stdout --decode "${FILE}" | \ 58 | lame -m j -q 0 --vbr-new -V 0 -s 44.1 --add-id3v2 --pad-id3v2 \ 59 | --ignore-tag-errors --tn "${TRACK:-0}" --tt "${TITLE}" \ 60 | --ta "${ARTIST}" --tl "${ALBUM}" --ty "${DATE}" --tg "${GENRE:-12}" - "${OUTPUT}" 61 | ;; 62 | 63 | m4a2mp3) 64 | # Software needed: faad, lame 65 | OUTPUT=${FILE%.m4a}.mp3 66 | TRACK=$(faad --info "${FILE}" 2>&1 | grep ^track | sed 's/^.*: //') 67 | TITLE=$(faad --info "${FILE}" 2>&1 | grep ^title | sed 's/^.*: //') 68 | ARTIST=$(faad --info "${FILE}" 2>&1 | grep ^artist | sed 's/^.*: //') 69 | ALBUM=$(faad --info "${FILE}" 2>&1 | grep ^album | sed 's/^.*: //') 70 | DATE=$(faad --info "${FILE}" 2>&1 | grep ^date | sed 's/^.*: //') 71 | GENRE=$(faad --info "${FILE}" 2>&1 | grep ^genre | sed 's/^.*: //') 72 | 73 | faad --stdio "${FILE}" | lame "${LAMEARGS}" --tn "${TRACK:-0}" --tt "${TITLE}" \ 74 | --ta "${ARTIST}" --tl "${ALBUM}" --ty "${DATE}" --tg "${GENRE:-12}" - "${OUTPUT}" 75 | ;; 76 | 77 | ogg2mp3) 78 | OUTPUT=${FILE%.ogg}.mp3 79 | eval $(ogginfo -qv "${FILE}" | awk '/ARTIST/ || /TITLE/' | sed 's/^ //') 80 | # echo "ARTIST: ${ARTIST} TITLE: ${TITLE}" 81 | if [ -z "${ARTIST}" ] || [ -z "${TITLE}" ]; then 82 | echo "WARNING: Not enough metadata, trying to gather track information from filename! (${FILE})" 83 | TRACK=$(ls "${FILE}" | awk -F\ '{print $1}') 84 | TITLE=$(ls "${FILE}" | sed 's/^[0-9]* - //;s/\.ogg//') 85 | 86 | # Try to find the ARLBUM via the directory name 87 | cd "$(dirname "${FILE}")" || exit 88 | ALBUM="$(basename $(pwd))" 89 | echo "TRACK: $TRACK TITLE: ${TITLE} ALBUM: ${ALBUM}" 90 | fi 91 | oggdec --quiet "${FILE}" --output - | lame "${LAMEARGS}" --tn "${TRACK:-0}" --tt "${TITLE}" \ 92 | --tl "${ALBUM}" - "${OUTPUT}" 93 | ;; 94 | 95 | *) 96 | echo "$(basename "$0"): conversion ${CONVERSION} unknown" 97 | exit 1 98 | ;; 99 | esac 100 | -------------------------------------------------------------------------------- /count.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # (c)2011 Christian Kujau 4 | # Make Perl count :-) 5 | # 6 | use strict; 7 | 8 | my $c=0; 9 | my $e=$ARGV[0]; 10 | my $l=length($e); 11 | 12 | while ($c <= $e) { 13 | my $s=sprintf("%0${l}d", $c); 14 | printf "$s\n"; 15 | $c ++; 16 | } 17 | -------------------------------------------------------------------------------- /diff2html.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Convert diff output to colorized HTML. 4 | # (C) Mitch Frazier, 2008-08-27 5 | # https://web.archive.org/web/20190828131321/https://www.linuxjournal.com/content/convert-diff-output-colorized-html 6 | # 7 | cat < 9 | 10 | Colorized Diff 11 | 12 | 23 | 24 |
 25 | XX
 26 | 
 27 | printf ''
 28 | 
 29 | first=1
 30 | diffseen=0
 31 | lastonly=0
 32 | 
 33 | OIFS=$IFS
 34 | IFS='
 35 | '
 36 | 
 37 | # The -r option keeps the backslash from being an escape char.
 38 | read -r s
 39 | 
 40 | while [ $? -eq 0 ]; do
 41 | 	# Get beginning of line to determine what type of diff line it is.
 42 | 	t1=${s:0:1}
 43 | 	t2=${s:0:2}
 44 | 	t3=${s:0:3}
 45 | 	t4=${s:0:4}
 46 | 	t7=${s:0:7}
 47 | 
 48 | 	# Determine HTML class to use.
 49 | 	if    [ "$t7" = 'Only in' ]; then
 50 | 		cls='only'
 51 | 
 52 | 		if [ $diffseen -eq 0 ]; then
 53 | 			diffseen=1
 54 | 			printf ''
 55 | 		else
 56 | 			if [ $lastonly -eq 0 ]; then
 57 | 				echo ""
 58 | 			fi
 59 | 		fi
 60 | 
 61 | 		if [ $lastonly -eq 0 ]; then
 62 | 			echo "
" 63 | fi 64 | lastonly=1 65 | 66 | elif [ "$t4" = 'diff' ]; then 67 | cls='diff' 68 | if [ $diffseen -eq 0 ]; then 69 | diffseen=1 70 | printf '' 71 | else 72 | echo "
" 73 | fi 74 | 75 | echo "
" 76 | lastonly=0 77 | 78 | elif [ "$t3" = '+++' ]; then 79 | cls='plus3' 80 | lastonly=0 81 | 82 | elif [ "$t3" = '---' ]; then 83 | cls='minus3' 84 | lastonly=0 85 | 86 | elif [ "$t2" = '@@' ]; then 87 | cls='at2' 88 | lastonly=0 89 | 90 | elif [ "$t1" = '+' ]; then 91 | cls='plus' 92 | lastonly=0 93 | 94 | elif [ "$t1" = '-' ]; then 95 | cls='minus' 96 | lastonly=0 97 | 98 | else 99 | cls= 100 | lastonly=0 101 | fi 102 | 103 | # Convert &, <, > to HTML entities. 104 | s=$(sed -e 's/\&/\&/g' -e 's//\>/g' <<<"$s") 105 | if [ $first -eq 1 ]; then 106 | first=0 107 | else 108 | echo 109 | fi 110 | 111 | # Output the line. 112 | if [ "$cls" ]; then 113 | printf ''"${s}"'' 114 | else 115 | printf "${s}" 116 | fi 117 | read -r s 118 | done 119 | IFS=$OIFS 120 | 121 | if [ $diffseen -eq 0 ] && [ "$onlyseen" -eq 0 ]; then 122 | printf '' 123 | else 124 | echo "
" 125 | fi 126 | echo 127 | 128 | cat < 130 | 131 | 132 | XX 133 | 134 | # vim: tabstop=4: shiftwidth=4: noexpandtab: 135 | # kate: tab-width 4; indent-width 4; replace-tabs false; 136 | -------------------------------------------------------------------------------- /expect/change-passwords.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect -f 2 | # 3 | # Change password on a remote host via SSH & expect(1) 4 | # 5 | # -------------------------------------------------------------- 6 | # Copyright (c) 2006 nixCraft project 7 | # This script is licensed under GNU GPL version 2.0 or above 8 | # This script is part of nixCraft shell script collection (NSSC) 9 | # Visit https://bash.cyberciti.biz/ for more information. 10 | # -------------------------------------------------------------- 11 | # 12 | # (c)2011 Christian Kujau 13 | # * hostname added 14 | # * removed the 'run as root' part 15 | # 16 | if {$argc!=3} { 17 | send_user "Usage: $argv0 \[user@\]target user password\n" 18 | exit 19 | } 20 | 21 | set timeout -1 22 | match_max 100000 23 | 24 | # host 25 | # set host [lindex $argv 0] 26 | 27 | # user 28 | set user [lindex $argv 1] 29 | 30 | # password 31 | set password [lindex $argv 2] 32 | 33 | # login to host 34 | spawn ssh [lindex $argv 0] 35 | 36 | # Note: you may have to change the "expect" strings to something more generic, 37 | # like 'assword:'. I've only put in the whole password-chat string because of 38 | # some silly PAM-module, giving hints when a password change was requested and 39 | # in turn confusing expect(1) with those strings. 40 | send -- "passwd $user\r" 41 | expect "Enter new password:" 42 | send "$password\r" 43 | expect "Re-type new password:" 44 | send "$password\r" 45 | send -- "exit\r" 46 | # send "\r" 47 | expect eof 48 | -------------------------------------------------------------------------------- /expect/e2fsck.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect -f 2 | # 3 | # (c)2009 Christian Kujau 4 | # 5 | # Run e2fsck via expect, see 6 | # http://nerdbynature.de/s9y/2009/10/18/e2fsck-expect 7 | # 8 | set timeout -1 9 | spawn /sbin/e2fsck -v $argv 10 | expect { 11 | "Clear? " { send "y" ; exp_continue } 12 | "Abort? " { send "n" ; exp_continue } 13 | "Recreate? " { send "y" ; exp_continue } 14 | "Fix? " { send "y" ; exp_continue } 15 | "Ignore error? " { send "y" ; exp_continue } 16 | "Force rewrite? " { send "y" ; exp_continue } 17 | "Root inode not allocated. Allocate?" { send "y" ; exp_continue } 18 | "/lost+found not found. Create?" { send "y" ; exp_continue } 19 | } 20 | -------------------------------------------------------------------------------- /expect/rpb-ts.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env expect -f 2 | # 3 | # (c)2011 Christian Kujau 4 | # 5 | # 1) Login to a terminalserver (Bay Networks Remote Annex 2000) 6 | # 2) Execute a command on a Remote Power Boot Switch (WTI RPB+) 7 | # 8 | if {$argc!=4} { 9 | send_user " Usage: $argv0 \[server\] \[port\] \[password\] \[command\]\n" 10 | send_user "Commands: /s /d /\[1-5\]\[on|off|boot\]\n" 11 | send_user " Example: $argv0 ts 3 s3cr3t \"/2 boot\"\n" 12 | exit 13 | } 14 | 15 | set timeout -1 16 | set server [lindex $argv 0] 17 | set port [lindex $argv 1] 18 | set password [lindex $argv 2] 19 | set command [lindex $argv 3] 20 | 21 | spawn telnet "$server" 22 | 23 | send -- "$port\r" 24 | expect "Port password:" 25 | send -- "$password\r" 26 | expect "Attached to port $port" 27 | send -- "\n\r" 28 | expect "RPB+>" 29 | # sleep 1 30 | send -- "$command\r" 31 | expect "RPB+>" 32 | close 33 | -------------------------------------------------------------------------------- /find_dups.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2015 Christian Kujau 4 | # 5 | # Find duplicate files in a directory. That is, files 6 | # with duplicate content. 7 | # 8 | # Note: this problem had been solved already by a smarter person with 9 | # https://github.com/adrianlopezroche/fdupes, but this program may 10 | # not be installed or available on all platforms. This shell version 11 | # may still be useful after all :-) 12 | # 13 | # ---- 14 | # Benchmark over 2519 files: 15 | # $ find_dups.sh . 16 | # Duplicate files: 17 | # 38cbf1962697767b098115b85de24fe6 ./f2598273.jpg 18 | # 38cbf1962697767b098115b85de24fe6 ./f2598272.jpg 19 | # 20 | # All files: 2519 21 | # Files with same size: 373 22 | # Duplicate files: 2 23 | # Time to complete: 1 seconds 24 | # 25 | # Running again, brute-force mode: 26 | # 38cbf1962697767b098115b85de24fe6 ./f2598272.jpg 27 | # 38cbf1962697767b098115b85de24fe6 ./f2598273.jpg 28 | # 29 | # Time to complete: 9 seconds (brute force) 30 | # ---- 31 | # 32 | # One-line-version, but w/o the statistics: 33 | # 34 | # find "$DIR" -type f -printf "%s\n" | sort -n | uniq -d | \ 35 | # xargs -I'{}' -n1 find "$DIR" -type f -size '{}'c -print0 | \ 36 | # xargs -0 md5sum | uniq -w32 -D 37 | # 38 | _help() { 39 | echo "Usage: $(basename "$0") [smart|brute] [directories]" 40 | exit 1 41 | } 42 | 43 | if [ ! -d "$2" ]; then 44 | _help 45 | else 46 | MODE=$1 47 | shift 48 | DIRS=$@ 49 | fi 50 | 51 | TEMP=$(mktemp) 52 | trap "rm -f $TEMP $TEMP.fallout $TEMP.fallout.md5 $TEMP.fallout.dup; exit" EXIT INT TERM HUP 53 | 54 | case $MODE in 55 | smart) 56 | BEGIN=$(date +%s) 57 | printf "### Gather size & name of all files... " 58 | find "$DIRS" -type f -exec stat -c %s:%n '{}' + > "$TEMP" 59 | cat "$TEMP" | wc -l # No UUOC here, but we don't want the leading spaces from wc(1) 60 | 61 | printf "### Gather files of the same size... " 62 | cut -d: -f1 "$TEMP" | sort | uniq -d | while read s; do 63 | grep ^"$s" "$TEMP" 64 | done | sort -u > "$TEMP".fallout # The "sort -u" at the end is crucial :) 65 | cat "$TEMP".fallout | wc -l 66 | 67 | printf "### Calculate the md5 checksums... " 68 | cut -d: -f2 "$TEMP".fallout | while read f; do 69 | md5sum "$f" >> "$TEMP".fallout.md5 70 | done 71 | cat "$TEMP".fallout.md5 2>/dev/null | wc -l # Ignore a missing fallout.md5 if no dupes are found. 72 | 73 | # Duplicate files, if any 74 | echo 75 | echo "Duplicate files:" 76 | cut -d\ -f1 "$TEMP".fallout.md5 2>/dev/null | sort | uniq -d | while read d; do 77 | grep ^"$d" "$TEMP".fallout.md5 78 | echo 79 | done | tee "$TEMP".fallout.dup 80 | END=$(date +%s) 81 | 82 | # Statistics 83 | echo 84 | echo " All files: $(cat "$TEMP" | wc -l)" 85 | echo "Files with same size: $(cat "$TEMP".fallout | wc -l)" 86 | echo " Duplicate files: $(expr $(grep -Ec '^[[:alnum:]]' "$TEMP".fallout.dup) / 2)" 87 | echo " Time to complete: $(expr "$END" - "$BEGIN") seconds" 88 | echo 89 | ;; 90 | 91 | brute) 92 | BEGIN=$(date +%s) 93 | find "$DIRS" -type f -exec md5sum '{}' + > "$TEMP" 94 | sort -k1 "$TEMP" | uniq -w32 -D > "$TEMP".dup # Print _all_ duplicate lines 95 | 96 | echo 97 | echo "Duplicate files:" && cat "$TEMP".dup 98 | END=$(date +%s) 99 | echo 100 | echo " All files: $(cat "$TEMP" | wc -l)" 101 | echo " Duplicate files: $(expr $(grep -Ec '^[[:alnum:]]' "$TEMP".dup) / 2)" 102 | echo " Time to complete: $(expr "$END" - "$BEGIN") seconds" 103 | ;; 104 | 105 | *) 106 | _help 107 | ;; 108 | esac 109 | -------------------------------------------------------------------------------- /funiq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (C) David Lambert, 2008-10-01 4 | # Fuzzy uniq (or Parsing Connect:Direct stats part 3) 5 | # https://cdunix.blogspot.com/2008/10/fuzzy-uniq-or-parsing-connectdirect.html 6 | # 7 | # Get percentage of similarity from command line option, or 85 for default 8 | # 9 | 10 | # Percentage of similarity 11 | if [ -n "$1" ]; then 12 | SIM=$1 13 | else 14 | SIM=85 15 | fi 16 | 17 | awk 'BEGIN {CURRPAIRS=0;PAIRMATCHES=0;PREVPAIRS=0} 18 | { 19 | # load array of character pairs for current comparison string 20 | for (i=1;i= SIM) print $0 54 | 55 | # move array of character pairs to store as previous string 56 | for (SUB in PREV) delete PREV[SUB] 57 | for (SUB in CURR) PREV[SUB]=CURR[SUB] 58 | for (SUB in CURR) delete CURR[SUB] 59 | PREVPAIRS=CURRPAIRS 60 | }' REQSIM=${SIM} $@ 61 | -------------------------------------------------------------------------------- /impressum.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Generate a German imprint for websites. 6 | * Note: the MDStV (Staatsvertrag ueber Mediendienste) has been decommisioned 7 | * on 2008-03-01 and has been replaced with the TMG (Telemediengesetz). 8 | * 9 | */ 10 | 11 | /* 12 | * You have to fill "vars.php" with something useful! 13 | * 14 | * Example: 15 | * 16 | * 22 | * 23 | */ 24 | include_once 'vars.php'; 25 | 26 | echo " 27 | 30 | 31 | 32 | $host: Impressum 33 | 34 | 35 |

36 | $name
37 | $city

38 |

Die Postaddresse kann via Email erfragt werden oder via whois fuer die Domain $host abgefragt 40 | werden.

41 |

E-Mail: $mail@$host
42 | WWW: http://$host/

43 |

Inhaltlich Verantwortlicher gemaess Telemediengesetz: $name (Anschrift wie oben)

44 |

Hinweise:

45 |
    46 |
  1. Trotz sorgfaeltiger inhaltlicher Kontrolle uebernehme ich keine Haftung fuer die Inhalte externer Links. Fuer den Inhalt der 47 | verlinkten Seiten sind ausschliesslich deren Betreiber verantwortlich.
  2. 48 |
  3. Diese Webseite erlaubt das Veroeffentlichen von Kommentaren zu den Nachrichten. Dies dient zur Diskussion unter den Lesern der 49 | Website. Die Kommentare stellen ausdruecklich nur die Meinung des Verfassers dar.
  4. 50 |
  5. Ich behalte mir das Loeschen von Kommentaren ohne weiteren Kommentar, Grund oder Begruendung vor.
  6. 51 |
52 | 53 | " 54 | ?> 55 | -------------------------------------------------------------------------------- /ip.php: -------------------------------------------------------------------------------- 1 | 4 | * Display REMOTE_ADDR, HTTP_X_FORWARDED_FOR, HTTP_USER_AGENT of the client 5 | * 6 | */ 7 | $ip1 = $_SERVER['REMOTE_ADDR']; 8 | 9 | // Call with "plain" to get just the IP address 10 | if (isset($_GET['plain']) || $_GET['plain'] == "1") { 11 | echo "$ip1"; 12 | exit; 13 | } else { 14 | 15 | $ip2 = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : ""; 16 | $host1 = !empty($ip1) ? gethostbyaddr($ip1) : ""; 17 | $host2 = !empty($ip2) ? gethostbyaddr($ip2) : ""; 18 | $ua = $_SERVER['HTTP_USER_AGENT']; 19 | 20 | echo " 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
REMOTE_ADDR$ip1 ($host1)
HTTP_X_FORWARDED_FOR$ip2 ($host2)
HTTP_USER_AGENT$ua
\n"; 38 | } 39 | ?> 40 | -------------------------------------------------------------------------------- /ipsec_iproute.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | # 3 | # (c)2019 Christian Kujau 4 | # Start/stop an IPsec tunnel with iproute2 5 | # 6 | # Inspired by: 7 | # > vishvananda/tunnel.sh 8 | # > https://gist.github.com/vishvananda/7094676 9 | # 10 | # > “On the fly” IPsec VPN with iproute2 11 | # > https://backreference.org/2014/11/12/on-the-fly-ipsec-vpn-with-iproute2/ 12 | # 13 | if [ $# -ne 7 ] || [ ! -f "${HOME}/.xfrm-keys" ]; then 14 | echo "Usage: $(basename "$0") [SRC LOCAL DEV] [DST REMOTE DEV] [start|stop|status]" 15 | echo " Note: We also need a key file in \$HOME/.xfrm-keys, with NN bit keys and" 16 | echo " a 32 bit id, generated like this:" 17 | echo "" 18 | echo "CIPHER=\"[blowfish|rfc3686(ctr(aes))|...]\"" 19 | echo " KEY1=0x\$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | xxd -c 256 -p)" 20 | echo " KEY2=0x\$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | xxd -c 256 -p)" 21 | echo " ID=0x\$(dd if=/dev/urandom bs=1 count=4 2>/dev/null | xxd -c 256 -p)" 22 | echo "" 23 | exit 1 24 | else 25 | SRC=$1 26 | LOCAL=$2 27 | DEVL=$3 28 | DST=$4 29 | REMOTE=$5 30 | DEVR=$6 31 | ACTION=$7 32 | fi 33 | 34 | # Read keys 35 | eval $(grep -Ev '^\#' "${HOME}/.xfrm-keys") 36 | if [ -z "${CIPHER}" ] || [ -z "${KEY1}" ] || [ -z "${KEY2}" ] || [ -z "${ID}" ]; then 37 | echo "Could not read cipher/keys from ${HOME}/.xfrm-keys!" 38 | exit 1 39 | fi 40 | 41 | # unset me! 42 | # DEBUG=echo 43 | # echo "DEBUG: SRC: ${SRC} LOCAL: ${LOCAL} DEVL: ${DEVL} / DST: ${DST} REMOTE: ${REMOTE} DEVR: ${DEVR}" 44 | 45 | case ${ACTION} in 46 | start) 47 | # XFRM 48 | ${DEBUG} ip xfrm state add src "${SRC}" dst "${DST}" proto esp spi "${ID}" reqid "${ID}" mode tunnel auth sha256 "$KEY1" enc "$CIPHER" "$KEY2" 49 | ${DEBUG} ip xfrm state add src "${DST}" dst "${SRC}" proto esp spi "${ID}" reqid "${ID}" mode tunnel auth sha256 "$KEY1" enc "$CIPHER" "$KEY2" 50 | ${DEBUG} ip xfrm policy add src "${LOCAL}" dst "${REMOTE}" dir out tmpl src "${SRC}" dst "${DST}" proto esp reqid "${ID}" mode tunnel 51 | ${DEBUG} ip xfrm policy add src "${REMOTE}" dst "${LOCAL}" dir in tmpl src "${DST}" dst "${SRC}" proto esp reqid "${ID}" mode tunnel 52 | 53 | # Routing 54 | ${DEBUG} ip addr add "${LOCAL}/32" dev lo 55 | ${DEBUG} ip route add "${REMOTE}/32" dev "${DEVL}" src "${LOCAL}" 56 | 57 | # And again on the remote side 58 | ssh "${DST}" /bin/sh -x << EOF 59 | # XFRM 60 | ${DEBUG} ip xfrm state add src ${SRC} dst ${DST} proto esp spi ${ID} reqid ${ID} mode tunnel auth sha256 $KEY1 enc "$CIPHER" $KEY2 61 | ${DEBUG} ip xfrm state add src ${DST} dst ${SRC} proto esp spi ${ID} reqid ${ID} mode tunnel auth sha256 $KEY1 enc "$CIPHER" $KEY2 62 | ${DEBUG} ip xfrm policy add src ${REMOTE} dst ${LOCAL} dir out tmpl src ${DST} dst ${SRC} proto esp reqid ${ID} mode tunnel 63 | ${DEBUG} ip xfrm policy add src ${LOCAL} dst ${REMOTE} dir in tmpl src ${SRC} dst ${DST} proto esp reqid ${ID} mode tunnel 64 | # Routing 65 | ${DEBUG} ip addr add ${REMOTE}/32 dev lo 66 | ${DEBUG} ip route add ${LOCAL}/32 dev ${DEVR} src ${REMOTE} 67 | EOF 68 | ;; 69 | 70 | stop) 71 | # Remote 72 | ssh "${DST}" /bin/sh -x << EOF 73 | # Routing 74 | ${DEBUG} ip route del ${LOCAL}/32 dev ${DEVR} src ${REMOTE} 75 | ${DEBUG} ip addr del ${REMOTE}/32 dev lo 76 | # XFRM 77 | ${DEBUG} ip xfrm policy del src ${LOCAL} dst ${REMOTE} dir in 78 | ${DEBUG} ip xfrm policy del src ${REMOTE} dst ${LOCAL} dir out 79 | ${DEBUG} ip xfrm state del src ${DST} dst ${SRC} proto esp spi ${ID} 80 | ${DEBUG} ip xfrm state del src ${SRC} dst ${DST} proto esp spi ${ID} 81 | EOF 82 | # Routing 83 | ${DEBUG} ip route del "${REMOTE}"/32 dev "${DEVL}" src "${LOCAL}" 84 | ${DEBUG} ip addr del "${LOCAL}"/32 dev lo 85 | 86 | # XFRM 87 | ${DEBUG} ip xfrm policy del src "${REMOTE}" dst "${LOCAL}" dir in 88 | ${DEBUG} ip xfrm policy del src "${LOCAL}" dst "${REMOTE}" dir out 89 | ${DEBUG} ip xfrm state del src "${DST}" dst "${SRC}" proto esp spi "${ID}" 90 | ${DEBUG} ip xfrm state del src "${SRC}" dst "${DST}" proto esp spi "${ID}" 91 | ;; 92 | 93 | status) 94 | ${DEBUG} ip xfrm state && ip xfrm policy 95 | echo 96 | ssh "${DST}" /bin/sh -x << EOF 97 | ${DEBUG} ip xfrm state && ip xfrm policy 98 | EOF 99 | ;; 100 | esac 101 | -------------------------------------------------------------------------------- /keyboard-backlight.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Originally written by Francisco Diéguez Souto (frandieguez@ubuntu.com) 4 | # This script is licensed under MIT License. 5 | # 6 | # This program just modifies the value of backlight keyboard for Apple Laptops 7 | # You must run it as root user or via sudo. 8 | # As a shortcut you could allow to admin users to run via sudo without password 9 | # prompt. To do this you must add sudoers file the next contents: 10 | # 11 | # Cmnd_Alias CMDS = /usr/local/bin/keyboard-backlight.sh 12 | # %admin ALL = (ALL) NOPASSWD: CMDS 13 | # 14 | # After this you can use this script as follows: 15 | # 16 | # Increase backlight keyboard: 17 | # $ sudo keyboard-backlight.sh up 18 | # Decrease backlight keyboard: 19 | # $ sudo keyboard-backlight.sh down 20 | # Increase to total value backlight keyboard: 21 | # $ sudo keyboard-backlight.sh total 22 | # Turn off backlight keyboard: 23 | # $ sudo keyboard-backlight.sh off 24 | # 25 | # You can customize the amount of backlight by step by changing the INCREMENT 26 | # variable as you want it. 27 | # 28 | 29 | BACKLIGHT="/sys/class/leds/smc::kbd_backlight/brightness" # TBD 30 | BRIGHTNESS=$(cat ${BACKLIGHT}) 31 | INCREMENT=20 32 | 33 | if [ "$(id -ru)" -ne 0 ]; then 34 | echo "Please run this program as superuser!" 35 | exit 1 36 | fi 37 | 38 | die() { 39 | echo "Brightness is already $1" 40 | exit 1 41 | } 42 | 43 | case $1 in 44 | up) 45 | # BRIGHTNESS will be capped at 255 anyway 46 | if [ "${BRIGHTNESS}" -lt 255 ]; then 47 | echo $(( BRIGHTNESS + INCREMENT )) > ${BACKLIGHT} 48 | else 49 | die "${BRIGHTNESS}" 50 | fi 51 | ;; 52 | 53 | down) 54 | if [ "${BRIGHTNESS}" -gt 0 ]; then 55 | VALUE=$(( BRIGHTNESS - INCREMENT )) 56 | 57 | # BRIGHTNESS cannot be negative 58 | [ "$VALUE" -lt 0 ] && VALUE=0 59 | echo $VALUE > ${BACKLIGHT} 60 | else 61 | die "${BRIGHTNESS}" 62 | fi 63 | ;; 64 | 65 | total) 66 | echo 255 > ${BACKLIGHT} 67 | ;; 68 | 69 | off) 70 | echo 0 > ${BACKLIGHT} 71 | ;; 72 | 73 | [0-9]*) 74 | VALUE=$1 75 | if [ "$VALUE" -ge 0 ] && [ "$VALUE" -le 255 ]; then 76 | echo "$VALUE" > ${BACKLIGHT} 77 | else 78 | echo "Invalid argument ($VALUE). Please provide a value from 0 to 255!" 79 | exit 1 80 | fi 81 | ;; 82 | 83 | *) 84 | echo "Use: $(basename "$0") [up|down|total|off|value]" 85 | exit 1 86 | ;; 87 | esac 88 | 89 | echo "Brightness set to $(cat ${BACKLIGHT})" 90 | -------------------------------------------------------------------------------- /mozilla/README.md: -------------------------------------------------------------------------------- 1 | # Mozilla default settings 2 | ## Per-user 3 | 4 | Place a file called `user.js` into the [profile directory](http://kb.mozillazine.org/Profile_folder): 5 | 6 | ``` 7 | Linux: ~/.mozilla/firefox/NAME/ 8 | MacOS: ~/Library/Application Support/Firefox/Profiles/NAME/ 9 | Windows: %APPDATA%\Mozilla\Firefox\Profiles\NAME\ 10 | ``` 11 | 12 | Note: values are set with `user_pref` 13 | 14 | ## Per-site 15 | 16 | Place a file called `autoconfig.js` into the [installation directory](http://kb.mozillazine.org/Installation_directory): 17 | 18 | ``` 19 | Linux: /usr/lib{,64}/firefox/browser/defaults/preferences/ 20 | MacOS: /Applications/Firefox.app/Contents/Resources/defaults/ => Firefox 34+ 21 | /Applications/Firefox.app/Contents/MacOS/defaults/pref/ => until Firefox 33.x 22 | Windows: %ProgramFiles%\Mozilla Firefox\defaults\pref\ 23 | ``` 24 | 25 | This file should have the following content: 26 | 27 | ``` 28 | // Do not obscure the content with ROT-13 29 | pref("general.config.obscure_value", 0); 30 | pref("general.config.filename", "mozilla.cfg"); 31 | ``` 32 | 33 | The `mozilla.cfg` must be stored where the actual Mozilla binary is located: 34 | 35 | ``` 36 | Linux: /usr/lib{,64}/firefox/ 37 | MacOS: /Applications/Firefox.app/Contents/MacOS/ 38 | Windows: %ProgramFiles%\Mozilla Firefox\ 39 | ``` 40 | 41 | Notes: 42 | * Values in `mozilla.cfg` can be set with `defaultPref` or `lockPref` 43 | * In Debian, Firefox is called Iceweasel and its defaults are stored 44 | elsewhere: both `autoconfig.js` and `mozilla.cfg` can reside in 45 | `/etc/iceweasel/pref`, but the latter needs to be symlinked to `/usr/lib/iceweasel` 46 | 47 | # Links 48 | - http://kb.mozillazine.org/User.js_file 49 | - http://kb.mozillazine.org/Prefs.js_file 50 | - http://kb.mozillazine.org/About:config_entries 51 | - http://kb.mozillazine.org/Locking_preferences 52 | - http://kb.mozillazine.org/Security_Policies 53 | -------------------------------------------------------------------------------- /mozilla/autoconfig.js: -------------------------------------------------------------------------------- 1 | /* 2 | * autoconfig.js 3 | * http://kb.mozillazine.org/Locking_preferences 4 | * https://developer.mozilla.org/docs/Mozilla/Firefox/Enterprise_deployment 5 | * 6 | * Note: the file specified here will be expected to be located in the 7 | * installation directory, e.g. /usr/lib/firefox. Instead of putting our 8 | * configuration file there, we'll have to create a symlink to that location. 9 | * $ sudo ln -s /etc/firefox/mozilla.cfg /usr/lib/firefox/mozilla.cfg 10 | * 11 | * pref - users can make changes, but will be reset on the next start 12 | * defaultPref - users can make changes, will be saved between sessions 13 | * lockPref - no changes can be made, required by some configuration items 14 | * clearPref - can be used to erase configuration items 15 | * 16 | */ 17 | pref("general.config.obscure_value", 0); // Do not obscure the content with ROT-13 18 | pref("general.config.filename", "mozilla.cfg"); 19 | -------------------------------------------------------------------------------- /mozilla/mozilla.cfg: -------------------------------------------------------------------------------- 1 | // 2 | // mozilla.cfg 3 | // 4 | 5 | // http://kb.mozillazine.org/App.update.auto 6 | // true - Download and install updates automatically (default) 7 | // false - Ask the user what he wants to do when an update is available 8 | lockPref("app.update.auto", false); 9 | lockPref("app.update.enabled", false); 10 | 11 | // http://kb.mozillazine.org/Browser.backspace_action 12 | // 0 - go back to previous page 13 | // 1 - page up 14 | // Any other value will unmap the backspace key. 15 | defaultPref("browser.backspace_action", 0); 16 | 17 | // http://kb.mozillazine.org/Browser.cache.check_doc_frequency 18 | // Note: browser.cache.disk.enable or browser.cache.memory.enable must be set to "true" 19 | // 0 - Check for a new version of a page once per session 20 | // 1 - Check for a new version every time a page is loaded 21 | // 2 - Never check for a new version 22 | // 3 - Check for a new version when the page is out of date (default) 23 | lockPref("browser.cache.check_doc_frequency", 1); 24 | 25 | // http://kb.mozillazine.org/Browser.cache.disk.enable 26 | // true - Store cache on the hard drive (default) 27 | // false - Don't store cache on the hard drive 28 | lockPref("browser.cache.disk.enable", false); 29 | 30 | // http://kb.mozillazine.org/Browser.cache.disk.capacity 31 | // Note: browser.cache.disk.enable must be set to "true" 32 | // Amount of disk space allowed for the browser's cache (in KB, default: 50000) 33 | lockPref("browser.cache.disk.capacity", 0); 34 | lockPref("browser.cache.disk.smart_size.enabled", false); 35 | 36 | // http://kb.mozillazine.org/Browser.cache.disk_cache_ssl 37 | // Note: browser.cache.disk.enable must be set to "true" 38 | // true - Cache to disk content retrieved by SSL (default) 39 | // false - Don't cache to disk content retrieved by SSL 40 | lockPref("browser.cache.disk_cache_ssl", false); 41 | 42 | // http://kb.mozillazine.org/Unable_to_save_or_download_files 43 | // true - Use browser.download.downloadDir (default) 44 | // false - Do not use browser.download.downloadDir 45 | // pref("browser.download.useDownloadDir", false); 46 | 47 | // Find and manage downloaded files 48 | // https://support.mozilla.org/en-US/kb/find-and-manage-downloaded-files 49 | // true - Use old download manager 50 | // false - Use new download manger (default) 51 | // pref("browser.download.useToolkitUI", true); 52 | 53 | // http://kb.mozillazine.org/Location_Bar_search 54 | // true - Add browser.fixup.alternate.prefix & browser.fixup.alternate.suffix 55 | // to "invalid" URLs 56 | // false - Don't add "www" and ".com" to "invalid" URLs 57 | lockPref("browser.fixup.alternate.enabled", false); 58 | 59 | // How do I go Back/Forward and Pinch to zoom in Firefox using my MacBook Pro? 60 | // https://support.mozilla.org/en-US/questions/903953 61 | // lockPref("browser.gesture.swipe.down", NULL); 62 | // lockPref("browser.gesture.swipe.left", NULL); 63 | // lockPref("browser.gesture.swipe.right", NULL); 64 | // lockPref("browser.gesture.swipe.up", NULL); 65 | 66 | // http://kb.mozillazine.org/Browser.link.open_newwindow 67 | // 1 - Open links, that would normally open in a new window, in the current tab/window 68 | // 2 - Open links, that would normally open in a new window, in a new window 69 | // 3 - Open links, that would normally open in a new window, in a new tab in the current window (default) 70 | // pref("browser.link.open_newwindow", 3); 71 | 72 | // http://kb.mozillazine.org/Browser.link.open_newwindow.restriction 73 | // 0 - Divert all links according to browser.link.open_newwindow 74 | // 1 - Do not divert any links (browser.link.open_newwindow will have no effect) 75 | // 2 - Divert all links according to browser.link.open_newwindow, unless the new 76 | // window specifies how it should be displayed (default) 77 | defaultPref("browser.link.open_newwindow.restriction", 0); 78 | 79 | // When changing "browser.newtab.url" is there any way to prevent the 80 | // address bar from getting focus? 81 | // https://support.mozilla.org/en-US/questions/929071 82 | lockPref("browser.newtab.preload", false); 83 | lockPref("browser.newtab.url", "about:blank"); 84 | lockPref("browser.newtabpage.directory.ping", ""); 85 | lockPref("browser.newtabpage.directory.source", ""); 86 | lockPref("browser.newtabpage.enabled", false); 87 | lockPref("browser.newtabpage.enhanced", false); 88 | lockPref("browser.newtabpage.introShown", true); 89 | 90 | // https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/Preference_reference/browser.pagethumbnails.capturing_disabled 91 | // true - The application doesn't create screenshots of visited web pages 92 | // false - The application creates screenshots of visited web pages (default) 93 | lockPref("browser.pagethumbnails.capturing_disabled", true); 94 | 95 | // Disable Firefox Pocket 96 | // browser.pocket.enabled doesn't fully disable the Pocket integration 97 | // https://bugzilla.mozilla.org/show_bug.cgi?id=1171569 98 | lockPref("browser.pocket.api", ""); 99 | lockPref("browser.pocket.enabled", false); 100 | 101 | // Disable Firefox Hello 102 | lockPref("loop.enabled", false); 103 | lockPref("loop.server", ""); 104 | lockPref("loop.facebook.shareUrl", ""); 105 | // Enable text chat by default 106 | // https://bugzilla.mozilla.org/show_bug.cgi?id=1171942 107 | lockPref("loop.textChat.enabled", false); 108 | 109 | // http://kb.mozillazine.org/Browser.safebrowsing.enabled 110 | // http://kb.mozillazine.org/Browser.safebrowsing.malware.enabled 111 | // true - Compare visited URLs against a blacklist or submit URLs to a third party 112 | // to determine whether a site is legitimate (default) 113 | // false - Disable Safe Browsing 114 | lockPref("browser.safebrowsing.downloads.enabled", false); 115 | lockPref("browser.safebrowsing.enabled", false); 116 | lockPref("browser.safebrowsing.gethashURL", ""); 117 | lockPref("browser.safebrowsing.malware.enabled", false); 118 | lockPref("browser.safebrowsing.malware.reportURL", ""); 119 | lockPref("browser.safebrowsing.reportURL", ""); 120 | lockPref("browser.safebrowsing.updateURL", ""); 121 | 122 | // Disable detection of captive portals 123 | // https://groups.google.com/d/topic/mozilla.support.firefox/TJgV_uODg_I 124 | // lockPref("captivedetect.canonicalURL", ""); 125 | 126 | // Get rid of all things Yahoo 127 | lockPref("browser.contentHandlers.types.0.uri", ""); 128 | lockPref("gecko.handlerService.schemes.mailto.0.uriTemplate", ""); 129 | 130 | // http://kb.mozillazine.org/About:config_entries#Browser. 131 | // true - Automatically check for updates to search plugins. 132 | // false - Don't. 133 | // lockPref("browser.search.update", false); 134 | 135 | // http://kb.mozillazine.org/Browser.send_pings 136 | // true - Send a POST request to URI listed in the ping attribute of HTML elements 137 | // false - ignore the ping attribute (default) 138 | lockPref("browser.send_pings", false); 139 | 140 | // https://bugzilla.mozilla.org/show_bug.cgi?id=648683 141 | // Expose tabs on-demand preference 142 | lockPref("browser.sessionstore.restore_on_demand", true); 143 | 144 | // http://kb.mozillazine.org/Browser.startup.homepage 145 | lockPref("browser.startup.homepage", "about:"); 146 | 147 | // http://kb.mozillazine.org/Browser.startup.page 148 | // 0 - Start with about:blank 149 | // 1 - Start with browser.startup.homepage (default) 150 | // 2 - Load the last visited page 151 | // 3 - Resume the previous browser session 152 | lockPref("browser.startup.page", 3); 153 | 154 | // http://kb.mozillazine.org/Browser.tabs.closeButtons 155 | // Note: this has been removed in Firefox 31 156 | // 0 - Display a close button on the active tab only 157 | // 1 - Display close buttons on all tabs (default) 158 | // 2 - Don’t display any close buttons 159 | // 3 - Display a single close button at the end of the tab strip 160 | // pref("browser.tabs.closeButtons", 3); 161 | 162 | // http://kb.mozillazine.org/About:config_entries#Browser. 163 | // true - Open new tabs to the right of the parent tab (default) 164 | // false - New tabs are opened at the far right of the tabs bar. 165 | defaultPref("browser.tabs.insertRelatedAfterCurrent", false); 166 | 167 | // http://kb.mozillazine.org/Browser.underline_anchors 168 | // true - Links are underlined by default (default) 169 | // false - Links are not underlined by default 170 | defaultPref("browser.underline_anchors", false); 171 | 172 | // Disable the unified complete URL bar. Note: this pref may get removed soon! 173 | // Stop bundling the old autocomplete search components in Firefox 174 | // https://bugzilla.mozilla.org/show_bug.cgi?id=995095 175 | lockPref("browser.urlbar.unifiedcomplete", false); 176 | 177 | // about:healthreport 178 | // Delete healthreport.sqlite in your Firefox profile too! 179 | lockPref("datareporting.healthreport.service.enabled", false); 180 | lockPref("datareporting.healthreport.uploadEnabled", false); 181 | lockPref("datareporting.policy.dataSubmissionEnabled", false); 182 | 183 | // https://hg.mozilla.org/mozilla-central/file/tip/services/datareporting 184 | // https://support.mozilla.org/en-US/questions/954790 185 | lockPref("datareporting.policy.dataSubmissionEnabled", false); 186 | lockPref("datareporting.policy.dataSubmissionPolicyAccepted", false); 187 | lockPref("datareporting.policy.dataSubmissionPolicyBypassAcceptance", false); 188 | 189 | // https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/Preference_reference/dom.event.clipboardevents.enabled 190 | lockPref("dom.event.clipboardevents.enabled", false); 191 | 192 | // http://kb.mozillazine.org/Dom.storage.enabled 193 | // Note: disabling this will essentially disable in-browser key-value storage 194 | // and break many websites. Because of that, we'll leave it enabled for now. 195 | // pref("dom.storage.enabled", false); 196 | 197 | // Disable the annoying "...is now in fullscreen" message 198 | // https://support.mozilla.org/en-US/questions/937742 199 | // pref("full-screen-api.approval-required", false); 200 | 201 | // Gecko user agent string reference 202 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference 203 | // https://panopticlick.eff.org/ 204 | // 205 | // pref("general.useragent.override", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:23.0) Gecko/20100101 Firefox/23.0"); 206 | // pref("general.useragent.override", "Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0"); 207 | 208 | // Disable Location-Aware Browsing 209 | // https://www.mozilla.org/en-US/firefox/geolocation/ 210 | lockPref("geo.enabled", false); 211 | lockPref("geo.wifi.uri", ""); 212 | 213 | // http://kb.mozillazine.org/Keyword.enabled 214 | // true - If Mozilla cannot determine a URL from information entered in the Location Bar, 215 | // append the information to the URL in keyword.URL and redirect the user there (default) 216 | // false - Display an error message indicating the entered information is not a valid URL 217 | lockPref("keyword.enabled", false); 218 | 219 | // Privacy-related changes coming to CSS :visited 220 | // https://hacks.mozilla.org/2010/03/privacy-related-changes-coming-to-css-vistited/ 221 | // true - show visited links in a different color (default) 222 | // false - don't show visited links in a different color 223 | lockPref("layout.css.visited_links_enabled", false); 224 | 225 | // http://kb.mozillazine.org/Layout.spellcheckDefault 226 | // 0 - Disable spellchecker 227 | // 1 - Enable spellchecker for multi-line controls (default) 228 | // 2 - Enable spellchecker for multi-line controls and single-line controls 229 | pref("layout.spellcheckDefault", 0); 230 | 231 | // http://kb.mozillazine.org/Layout.word_select.stop_at_punctuation 232 | // true - "Word" selection includes surrounding punctuation and only stops at whitespace, so 233 | // that for example double-clicking example.com/the/path and the other above-mentioned 234 | // shortcuts select the entire URL 235 | // false - Word selection using the above mentioned shortcuts ends at punctuation characters 236 | pref("layout.word_select.stop_at_punctuation", false); 237 | 238 | // Test HTML5 videos on YouTube, on a Nightly version of Firefox 239 | // https://oneanddone.mozilla.org/en-US/tasks/89/ 240 | // pref("media.fragmented-mp4.enabled", true); 241 | // pref("media.fragmented-mp4.exposed", true); 242 | // pref("media.fragmented-mp4.ffmpeg.enabled", true); 243 | // pref("media.fragmented-mp4.gmp.enabled", true); 244 | // pref("media.mediasource.enabled", true); 245 | // pref("media.mediasource.mp4.enabled", true); 246 | // pref("media.mediasource.webm.enabled", true); 247 | 248 | // How to protect yourself from exposing your IP with WebRTC. 249 | // https://mullvad.net/en/webrtc/ 250 | // Note: disabling this will essentially disable WebRTC and 251 | // we'll leave it enabled for now. 252 | // pref("media.peerconnection.enabled", false); 253 | 254 | // http://kb.mozillazine.org/Network.cookie.cookieBehavior 255 | // 0 - All cookies are allowed (default) 256 | // 1 - Only cookies from the originating server are allowed 257 | // 2 - No cookies are allowed 258 | // 3 - Third-party cookies are allowed only if that site has stored cookies 259 | // already from a previous visit 260 | pref("network.cookie.cookieBehavior", 1); 261 | 262 | // http://kb.mozillazine.org/Network.cookie.lifetime.days 263 | // Number of days to keep cookies (default: 90) 264 | pref("network.cookie.lifetime.days", 1); 265 | 266 | // http://kb.mozillazine.org/Network.cookie.lifetimePolicy 267 | // 0 - The cookie's lifetime is supplied by the server (default) 268 | // 1 - The user is prompted for the cookie's lifetime 269 | // 2 - The cookie expires at the end of the session (when the browser closes) 270 | // 3 - The cookie lasts for the number of days specified by network.cookie.lifetime.days 271 | pref("network.cookie.lifetimePolicy", 3); 272 | 273 | // http://kb.mozillazine.org/Network.dns.disablePrefetch 274 | // https://trac.torproject.org/projects/tor/wiki/doc/Preventing_Tor_DNS_Leaks 275 | lockPref("network.dns.disablePrefetch", true); 276 | 277 | // http://kb.mozillazine.org/Network.http.pipelining 278 | defaultPref("network.http.pipelining", true); 279 | defaultPref("network.http.pipelining.aggressive", true); 280 | defaultPref("network.http.pipelining.ssl", true); 281 | defaultPref("network.http.proxy.pipelining", true); 282 | 283 | // http://kb.mozillazine.org/Network.http.sendRefererHeader 284 | // 0 - Never send the Referer header or set document.referrer 285 | // 1 - Send the Referer header when clicking on a link, and set document.referrer for the following page 286 | // 2 - Same as 1, but includes loading of images (default) 287 | // Note: see the RefControl add-on for sending Referer Header on a per-site basis 288 | // https://addons.mozilla.org/en-US/firefox/addon/refcontrol/ 289 | defaultPref("network.http.sendRefererHeader", 0); 290 | 291 | // http://kb.mozillazine.org/Network.http.sendSecureXSiteReferrer 292 | // Note: network.http.sendRefererHeader must be set to 1 or 2 for this to work 293 | // true - Send the Referer header when navigating from a https site to another https site 294 | // false - Don't send the Referer header when navigating from a https site to another https site 295 | defaultPref("network.http.sendSecureXSiteReferrer", false); 296 | 297 | // http://kb.mozillazine.org/Network.prefetch-next 298 | lockPref("network.prefetch-next", false); 299 | 300 | // http://kb.mozillazine.org/Network.proxy.type 301 | // 0 - Direct connection, no proxy 302 | // 1 - Manual proxy configuration 303 | // 2 - Proxy auto-configuration (PAC) 304 | // 4 - Auto-detect proxy settings 305 | // 5 - Use system proxy settings (default) 306 | defaultPref("network.proxy.type", 5); 307 | 308 | // http://kb.mozillazine.org/Network.proxy.autoconfig_url 309 | // When using local PAC files: 310 | // Linux: file:///home/NAME/.proxy.pac 311 | // MacOS: file:///Users/NAME/.proxy.pac 312 | // Windows: file:///C:/Documents%20and%20Settings/NAME/proxy.pac 313 | defaultPref("network.proxy.autoconfig_url", "http://proxy.example.org/proxy.pac"); 314 | 315 | // http://kb.mozillazine.org/Network.proxy.(protocol) 316 | // http://kb.mozillazine.org/Network.proxy.(protocol)_port 317 | defaultPref("network.proxy.http", "10.0.0.1"); 318 | defaultPref("network.proxy.http_port", 8080); 319 | defaultPref("network.proxy.ssl", "10.0.0.1"); 320 | defaultPref("network.proxy.ssl_port", 8080); 321 | defaultPref("network.proxy.ftp", "10.0.0.1"); 322 | defaultPref("network.proxy.ftp_port", 8080); 323 | defaultPref("network.proxy.socks", "10.0.0.1"); 324 | defaultPref("network.proxy.socks_port", 8080); 325 | 326 | // http://kb.mozillazine.org/Network.proxy.share_proxy_settings 327 | // true - Save the HTTP proxy as the proxy for the other protocols 328 | // false - Save the proxy protocol settings separately (default) 329 | defaultPref("network.proxy.share_proxy_settings", true); 330 | 331 | // http://kb.mozillazine.org/Network.proxy.no_proxies_on 332 | defaultPref("network.proxy.no_proxies_on", "localhost, 127.0.0.1"); 333 | 334 | // http://kb.mozillazine.org/Network.proxy.socks_version 335 | defaultPref("network.proxy.socks_version", 5); 336 | 337 | // http://kb.mozillazine.org/Network.proxy.socks_remote_dns 338 | // true - Have the (SOCKS v5) proxy server perform DNS lookups 339 | // false - Perform DNS lookups on the client 340 | lockPref("network.proxy.socks_remote_dns", true); 341 | 342 | // http://kb.mozillazine.org/Network.security.ports.banned 343 | // http://kb.mozillazine.org/Network.security.ports.banned.override 344 | // A comma delimited list of port numbers to additionally block / allow 345 | // default: A general port blacklist. Connections to these ports will not be allowed unless the protocol overrides. 346 | // https://hg.mozilla.org/mozilla-central/file/tip/netwerk/base/nsIOService.cpp#l75 347 | // pref("network.security.ports.banned", "21,80"); 348 | // pref("network.security.ports.banned.override", "8080,8443"); 349 | 350 | // http://kb.mozillazine.org/Issues_related_to_plugins 351 | defaultPref("plugins.click_to_play", true); 352 | 353 | // Disable HTML5 autoplay 354 | // Note: this needs to be set to TRUE if we want media to be autoplayed. Think 355 | // about custom Greasemonkey scripts that want to notify us with play(). 356 | defaultPref("media.autoplay.enabled", false); 357 | 358 | // 0 - never activate 359 | // 1 - ask to activate 360 | // 2 - always activate (default) 361 | defaultPref("plugin.state.flash", 1); 362 | 363 | // Clear some history objects on shutdown 364 | lockPref("privacy.clearOnShutdown.cache", true); 365 | lockPref("privacy.clearOnShutdown.cookies", true); 366 | lockPref("privacy.clearOnShutdown.downloads", true); 367 | lockPref("privacy.clearOnShutdown.formdata", false); 368 | lockPref("privacy.clearOnShutdown.history", false); 369 | lockPref("privacy.clearOnShutdown.offlineApps", true); 370 | lockPref("privacy.clearOnShutdown.passwords", false); 371 | lockPref("privacy.clearOnShutdown.sessions", true); 372 | lockPref("privacy.sanitize.sanitizeOnShutdown", true); 373 | defaultPref("privacy.clearOnShutdown.siteSettings", false); 374 | 375 | // Clear some history objects on demand 376 | lockPref("privacy.cpd.cache", true); 377 | lockPref("privacy.cpd.cookies", true); 378 | lockPref("privacy.cpd.downloads", true); 379 | lockPref("privacy.cpd.formdata", false); 380 | lockPref("privacy.cpd.history", false); 381 | lockPref("privacy.cpd.offlineApps", true); 382 | lockPref("privacy.cpd.passwords", false); 383 | lockPref("privacy.cpd.sessions", true); 384 | defaultPref("privacy.cpd.siteSettings", false); 385 | 386 | // http://kb.mozillazine.org/Privacy.donottrackheader.enabled 387 | // true - Send information about the user's tracking preferences to all websites. 388 | // Prior to Firefox 21.0 and SeaMonkey 2.18, this is always "Do Not Track"; 389 | // in Firefox 21.0 and later as well as SeaMonkey 2.18 and later, the header 390 | // sent depends on the privacy.donottrackheader.value setting 391 | // false - Do not send any tracking preferences to any website (default) 392 | lockPref("privacy.donottrackheader.enabled", true); 393 | 394 | // http://kb.mozillazine.org/Privacy.donottrackheader.value 395 | // Note: privacy.donottrackheader.enabled must be set to "true" 396 | // 0 - A header stating consent to being tracked is sent 397 | // 1 - A header stating the request not to be tracked is sent (default) 398 | lockPref("privacy.donottrackheader.value", 1); 399 | 400 | // https://wiki.mozilla.org/Security/Tracking_protection 401 | lockPref("privacy.trackingprotection.enabled", true); 402 | 403 | // Bug #873349 / "Add a whitelist for mixed content blocking" was closed with 404 | // WONTFIX. However, we still may be able to allow mixed content, especially 405 | // in coroprate environments. Default is "true" and we leave it that way. 406 | // https://bugzilla.mozilla.org/show_bug.cgi?id=873349 407 | defaultPref("security.mixed_content.block_active_content", true); 408 | 409 | // Disable weak DHE export ciphers 410 | // https://weakdh.org/sysadmin.html 411 | // pref("security.ssl3.dhe_rsa_aes_128_sha", false) 412 | // pref("security.ssl3.dhe_rsa_aes_256_sha", false) 413 | 414 | // Add a pref to disable SSL Session cache (Disable sending session IDs and 415 | // sending session tickets) 416 | // https://bugzilla.mozilla.org/show_bug.cgi?id=967977 417 | defaultPref("security.ssl.disable_session_identifiers", true); 418 | 419 | // http://kb.mozillazine.org/Security.tls.version.* 420 | // 0 - SSL 3.0 is the minimum required / maximum supported encryption protocol. 421 | // 1 - TLS 1.0 is the minimum required / maximum supported encryption protocol. 422 | // 2 - TLS 1.1 is the minimum required / maximum supported encryption protocol. 423 | // 3 - TLS 1.2 is the minimum required / maximum supported encryption protocol. 424 | // pref("security.tls.version.min", 2) 425 | // pref("security.tls.version.max", 3) 426 | 427 | // Stay Social with Firefox 428 | // https://blog.mozilla.org/blog/2013/05/14/stay-social-with-firefox/ 429 | // 430 | // How do I get rid of unwanted social API in Firefox? 431 | // https://support.mozilla.org/en-US/questions/942293 432 | lockPref("social.directories", ""); 433 | lockPref("social.enabled", false); 434 | lockPref("social.manifest.cliqz", ""); 435 | lockPref("social.manifest.facebook", ""); 436 | lockPref("social.manifest.mixi", ""); 437 | lockPref("social.manifest.msnnow", ""); 438 | lockPref("social.remote-install.enabled", false); 439 | lockPref("social.share.activationPanelEnabled", false); 440 | lockPref("social.shareDirectory", ""); 441 | lockPref("social.toast-notifications.enabled", false); 442 | lockPref("social.whitelist", ""); 443 | 444 | // How can I disable the "Improve Firefox" suggestion which appeared after FF8 update? 445 | // No any choise helps to avoid the popup appearance next time 446 | // http://support.mozilla.org/en-US/questions/898549 447 | lockPref("toolkit.telemetry.enabled", false); 448 | lockPref("toolkit.telemetry.prompted", 2); 449 | lockPref("toolkit.telemetry.rejected", true); 450 | 451 | // 452 | // I usually disable the "Menu bar" in Firefox but it will become visible 453 | // when the "Alt" key is pressed (ui.key.generalAccessKey et al.). One can 454 | // disable the "Menu bar" altogether by creating chrome/userChrome.css with the 455 | // following content: 456 | // 457 | // #toolbar-menubar { 458 | // display:none !important; 459 | // } 460 | // 461 | // But now the "Menu bar" will be hidden forever. So, lets just disable it 462 | // when pressing "Alt", it can still be shown via "right-click". 463 | // http://kb.mozillazine.org/About:config_entries#UI. 464 | // 465 | lockPref("ui.key.menuAccessKeyFocuses", false); 466 | 467 | // No More Passwords over HTTP, Please! 468 | // https://blog.mozilla.org/tanvi/2016/01/28/no-more-passwords-over-http-please/ 469 | // defaultPref("security.insecure_password.ui.enabled", true); 470 | // defaultPref("security.insecure_field_warning.contextual.enabled", true); 471 | 472 | // http://kb.mozillazine.org/About:config_entries#Browser. 473 | // true - The domain name including the top level domain is highlighted in the address 474 | // bar by coloring it black and the other parts grey (default) 475 | // false - All parts of the url are given the same color: black 476 | lockPref("browser.urlbar.formatting.enabled", false); 477 | 478 | // http://kb.mozillazine.org/About:config_entries#Browser. 479 | // true - Hide certain parts of the url (default) 480 | // false - All parts of the url are shown 481 | lockPref("browser.urlbar.trimURLs", false); 482 | 483 | // END 484 | -------------------------------------------------------------------------------- /mozilla/user.js: -------------------------------------------------------------------------------- 1 | // 2 | // user.js 3 | // 4 | user_pref("network.proxy.type", 2); 5 | user_pref("network.proxy.autoconfig_url", "file:///Users/bob/.proxy.pac"); 6 | user_pref("plugins.click_to_play", false); 7 | -------------------------------------------------------------------------------- /munin/plugin-conf.d/multiping: -------------------------------------------------------------------------------- 1 | [multiping] 2 | env.hosts 10.0.0.2,10.0.0.3 3 | env.names foo.example.com,bar.example.com 4 | env.ping_args -A -c 5 -w 2 5 | -------------------------------------------------------------------------------- /munin/plugin-conf.d/multips: -------------------------------------------------------------------------------- 1 | [multips] 2 | user root 3 | env.names php apache 4 | env.regex_php ^[0-9]* /usr/bin/php-cgi 5 | -------------------------------------------------------------------------------- /munin/plugin-conf.d/munin-node: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/munin/plugin-conf.d/munin-node 3 | # 4 | # user # Set the user to run the plugin as. 5 | # group # Set the group to run the plugin as. 6 | # command # Run instead of the plugin. %c expands to 7 | # what would normally be run. 8 | # env. # Sets in the plugin's environment, see the 9 | # individual plugins to find out which variables they 10 | # care about. 11 | # 12 | [df*] 13 | env.exclude none unknown iso9660 squashfs udf romfs ramfs devtmpfs debugfs tmpfs binfmt_misc rpc_pipefs ecryptfs 14 | env.warning 92 15 | env.critical 98 16 | 17 | [exim_mailqueue] 18 | group adm, (Debian-exim) 19 | 20 | [exim_mailstats] 21 | group adm, (Debian-exim) 22 | env.logdir /var/log/exim4/ 23 | env.logname mainlog 24 | 25 | [if_*] 26 | user root 27 | 28 | [ip_*] 29 | user root 30 | 31 | [mysql*] 32 | user root 33 | env.mysqlopts --defaults-file=/etc/mysql/debian.cnf 34 | env.mysqluser debian-sys-maint 35 | env.mysqlconnection DBI:mysql:mysql;mysql_read_default_file=/etc/mysql/debian.cnf 36 | 37 | [postfix*] 38 | user root 39 | env.logfile mail.log 40 | env.logdir /var/log/syslog 41 | 42 | [postgres_*] 43 | user postgres 44 | env.PGUSER postgres 45 | env.PGPORT 5432 46 | 47 | # Run as root when /proc is mounted with hidepid options 48 | # [processes] 49 | # user root 50 | 51 | [sendmail*] 52 | user root 53 | env.mspqueue /var/spool/clientmqueue 54 | 55 | [smart_*] 56 | user root 57 | -------------------------------------------------------------------------------- /munin/plugin-conf.d/tor_traffic: -------------------------------------------------------------------------------- 1 | [tor_traffic] 2 | user tor 3 | env.conf /usr/local/etc/torrc 4 | env.port 9051 5 | env.password s3cr3t 6 | -------------------------------------------------------------------------------- /munin/plugins/adt746x_: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2009 Christian Kujau 4 | # 5 | # The therm_adt746x kernel module is not using standard i2c routines 6 | # and we cannot use lm_sensors to request fan or temperature status. 7 | # Instead, when the module is loaded a few /sys objects will be created 8 | # and can be polled as usual. 9 | # 10 | # Examples: 11 | # /sys/devices/temperatures/sensor1_limit: 45 12 | # /sys/devices/temperatures/sensor1_location: CPU TOPSIDE 13 | # /sys/devices/temperatures/sensor1_temperature: 46 14 | # /sys/devices/temperatures/sensor2_limit: 65 15 | # /sys/devices/temperatures/sensor2_location: GPU ON DIE 16 | # /sys/devices/temperatures/sensor2_temperature: 61 17 | # 18 | # Plugin wildcard names: 19 | # 20 | # adt746x_fan - To monitor fans 21 | # adt746x_temp - To monitor temperatures 22 | # 23 | # TODO: 24 | # - honor munin-node config to adjust warning/critical values 25 | # 26 | if [ "$1" = "autoconf" ]; then 27 | echo yes 28 | exit 0 29 | fi 30 | 31 | # See how we were called (fan/temp) 32 | SENSOR=`basename "$0" | awk -F_ '{print $NF}'` 33 | 34 | case $SENSOR in 35 | fan) 36 | if [ "$1" = "config" ]; then 37 | echo 'graph_title Fans' 38 | echo 'graph_vtitle RPM' 39 | echo 'graph_args --base 1000 --lower-limit 0' 40 | echo 'graph_category sensors' 41 | echo 'graph_info This graph shows the fanspeed' 42 | echo 'fan1.label Master' 43 | echo 'fan1.warning 1500:' 44 | echo 'fan1.critical 1000:' 45 | exit 0 46 | fi 47 | echo "fan1.value `sed 's/.*(//;s/ rpm)$//' < /sys/devices/temperatures/sensor1_fan_speed`" 48 | ;; 49 | 50 | temp) 51 | if [ "$1" = "config" ]; then 52 | echo 'graph_title Temperatures' 53 | echo 'graph_vtitle Celsius' 54 | echo 'graph_args --base 1000 --lower-limit 0' 55 | echo 'graph_category sensors' 56 | echo 'temp1.label CPU TOPSIDE' 57 | echo 'temp1.warning 48' 58 | echo 'temp1.critical 50' 59 | echo 'temp2.label GPU ON DIE' 60 | echo 'temp2.warning 63' 61 | echo 'temp2.critical 65' 62 | exit 0 63 | fi 64 | echo "temp1.value `cat /sys/devices/temperatures/sensor1_temperature`" 65 | echo "temp2.value `cat /sys/devices/temperatures/sensor2_temperature`" 66 | ;; 67 | esac 68 | -------------------------------------------------------------------------------- /munin/plugins/du_multidirs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2009 Christian Kujau 4 | # Based on the 'homedirs' plugin, initially written in Perl by Philipp Gruber 5 | # 6 | # We still need a cronjob to update CACHEFILE once in a while, e.g.: 7 | # 0 * * * * root /usr/bin/du -sk /dir /dir2 dir3/* > /var/run/munin/du_multidirs.cache 8 | # 9 | CACHE=/var/run/munin/du_multidirs.cache 10 | 11 | if [ "$1" = "autoconf" ]; then 12 | echo yes 13 | exit 0 14 | fi 15 | 16 | if [ ! -f "${CACHE}" ]; then 17 | echo "Cache ${CACHE} not found!" 18 | exit 1 19 | fi 20 | 21 | 22 | if [ "$1" = "config" ]; then 23 | echo 'graph_title Directory usage (in MB)' 24 | echo 'graph_args --lower-limit 1 --base 1024' 25 | # echo 'graph_args --lower-limit 0.01 --logarithmic' 26 | echo 'graph_vlabel Bytes' 27 | echo 'graph_category disk' 28 | echo 'graph_info This graph shows the size of several directories' 29 | 30 | # Munin doesn't like slashes, dots, hyphens and pretty much any symbols in 31 | # its variables. 32 | awk -F\ '!/lost\+found/ {print $2}' "${CACHE}" | sort | while read -r u; do 33 | u2=$(echo "${u}" | sed 's/[[:punct:]]/_/g;s/ /_/g') 34 | echo "${u2}".label "${u}" 35 | # echo "${u2}".warning 0 36 | # echo "${u2}".critical 0 37 | done 38 | exit 0 39 | fi 40 | 41 | awk '!/lost\+found/ {gsub(/\//,"_"); print $2".value "$1 * 1024 }' "${CACHE}" | sort -r -n -k2 42 | -------------------------------------------------------------------------------- /munin/plugins/tor_traffic: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2010 Christian Kujau 4 | # Get accounting information from a running Tor server. 5 | # 6 | # TC: A Tor control protocol 7 | # https://gitweb.torproject.org/torspec.git/tree/control-spec.txt 8 | # 9 | [ -z "$conf" ] && conf=/etc/torrc 10 | [ -z "$port" ] && port=9051 11 | 12 | if [ "`awk '/^CookieAuthentication/ {print $2}' "$conf"`" = 1 ]; then 13 | # CookieAuthentication should be set 14 | COOKIE="`awk '/^CookieAuthFile/ {print $2}' "$conf"`" 15 | # PASSWORD="`xxd -c 32 -g 0 "$COOKIE" | awk '{print $2}'`" 16 | PASSWORD="`cat "$COOKIE"`" 17 | else 18 | # HashedControlPassword should be set 19 | PASSWORD=$password 20 | fi 21 | 22 | if [ "$1" = config ]; then 23 | echo "graph_title Tor Traffic" 24 | echo "graph_args --base 1000" 25 | echo "graph_vlabel bytes in / out" 26 | echo "graph_category network" 27 | echo "down.label Download" 28 | echo "down.type GAUGE" 29 | echo "up.label Upload" 30 | echo "up.type GAUGE" 31 | exit 0 32 | fi 33 | 34 | [ -z "$PASSWORD" ] && exit 1 35 | printf "AUTHENTICATE \"${PASSWORD}\"\nGETINFO accounting/bytes\nQUIT" | nc localhost $port | \ 36 | awk -F= '/accounting\/bytes/ {print $2}' | \ 37 | tr -d '\015' | \ 38 | awk '{print "down.value "$1 "\nup.value "$2}' 39 | -------------------------------------------------------------------------------- /port-mgmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2014 Christian Kujau 4 | # MacPorts cleanup 5 | # 6 | PATH=/bin:/usr/bin:/opt/local/bin 7 | LAST="${HOME}/.ports.clean" 8 | umask 0022 9 | 10 | case $1 in 11 | a) 12 | port echo active | awk '{print $1 $2}' 13 | ;; 14 | 15 | i) 16 | port echo inactive | awk '{print $1 $2}' 17 | ;; 18 | 19 | u) 20 | port selfupdate 21 | port echo outdated 22 | port upgrade -u outdated 23 | if [ -f "${LAST}" ]; then 24 | A=$(stat -f %m "${LAST}") 25 | B=$(date +%s) 26 | # Cleanup every 1209600 seconds (14 days) 27 | if [ $(( B - A )) -gt 1209600 ]; then 28 | echo "port clean all..." 29 | echo nice -n20 port clean -f --all all > /dev/null 30 | fi 31 | else 32 | touch "${LAST}" 33 | fi 34 | ;; 35 | 36 | *) 37 | echo "Usage: $(basename "$0") [i|a|u]" 38 | echo "i - list inactive" 39 | echo "a - list active" 40 | echo "u - upgrade" 41 | exit 1 42 | ;; 43 | esac 44 | -------------------------------------------------------------------------------- /qemu-tap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2015 Christian Kujau 4 | # 5 | # Based on: 6 | # > How do I bridge a connection from Wi-Fi to TAP on Mac OS X? (for the emulator QEMU) 7 | # > https://superuser.com/a/766251 8 | # 9 | INTERFACE="en1" 10 | 11 | # set to echo/sudo 12 | DEBUG="sudo" 13 | 14 | # See how we were called 15 | case $(basename "$0") in 16 | qemu-ifup) 17 | # Needed for the symlink 18 | umask 0022 19 | ${DEBUG} ln -sf /dev/tap0 /dev/tap 20 | ${DEBUG} sysctl -w net.inet.ip.forwarding=1 21 | ${DEBUG} sysctl -w net.link.ether.inet.proxyall=1 22 | ${DEBUG} sysctl -w net.inet.ip.fw.enable=1 23 | ${DEBUG} ifconfig bridge0 create 24 | ${DEBUG} ifconfig bridge0 addm ${INTERFACE} addm tap0 25 | ${DEBUG} ifconfig bridge0 up 26 | ${DEBUG} natd -interface en1 27 | ${DEBUG} ipfw add divert natd ip from any to any via ${INTERFACE} 28 | ;; 29 | 30 | qemu-ifdown) 31 | ${DEBUG} ipfw del 00100 32 | ${DEBUG} ipfw del "$(sudo ipfw list | grep "ip from any to any via ${INTERFACE}" | sed -e 's/ .*//g')" 33 | ${DEBUG} killall -9 natd 34 | ${DEBUG} sysctl -w net.inet.ip.forwarding=0 35 | ${DEBUG} sysctl -w net.link.ether.inet.proxyall=0 36 | ${DEBUG} sysctl -w net.inet.ip.fw.enable=1 37 | ${DEBUG} ifconfig bridge0 deletem ${INTERFACE} deletem tap0 38 | ${DEBUG} ifconfig bridge0 down 39 | ${DEBUG} ifconfig bridge0 destroy 40 | ;; 41 | 42 | *) 43 | echo "$0: call me as qemu-ifup or qemu-ifdown!" 44 | exit 1 45 | ;; 46 | esac 47 | -------------------------------------------------------------------------------- /rsnapshot/rsnapshot-ready.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2009 Christian Kujau 4 | # 5 | # Check for certain directories to be in place. If they are, 6 | # create a file which says that we're ready to be backed up. 7 | # 8 | PATH=/bin:/usr/bin:/usr/sbin 9 | FILE=/var/run/rsnapshot.ready 10 | 11 | # unset me! 12 | # DEBUG=echo 13 | 14 | if [ $# = 0 ]; then 15 | echo "Usage: $(basename "$0") [dir1] [dir2] [...]" 16 | exit 1 17 | fi 18 | 19 | for d in $@; do 20 | # normalize 21 | DIR=$(echo "$d" | sed 's/\/$//') 22 | test -n "$DEBUG" && echo "DIR: $DIR" 23 | 24 | # check if we're mounted 25 | mount | grep "$DIR type" > /dev/null 26 | if [ $? = 0 ]; then 27 | $DEBUG date > "$FILE" 28 | else 29 | # remove FILE if a single mountpoint was not mounted and bail out 30 | $DEBUG rm -f "$FILE" 31 | break 32 | fi 33 | done 34 | -------------------------------------------------------------------------------- /rsnapshot/rsnapshot-rotate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2011 Christian Kujau 4 | # Forcefully rotate rsnapshot backups, intentionally discarding older copies 5 | # 6 | CONF="/etc/rsnapshot" 7 | 8 | if [ ! $# = 1 ]; then 9 | HOSTS=$(find ${CONF} -maxdepth 1 -name "*.conf" | sed 's/.*\/rsnapshot-//;s/\.conf//' | xargs echo | sed 's/ /|/g') 10 | echo "Usage: $(basename "$0") [${HOSTS}]" 11 | exit 1 12 | else 13 | CONF="${CONF}/rsnapshot-${1}.conf" 14 | DIR="$(awk '/^snapshot_root/ {print $2}' "${CONF}")" 15 | 16 | # Safety belt 17 | [ -f "${CONF}" ] || exit 2 18 | [ -d "${DIR}" ] || exit 3 19 | fi 20 | 21 | set -e 22 | # Don't let rsnapshot-wrapper remount our backup store while we are running. 23 | NOMOUNT=$(awk -F= '/^NOMOUNT/ {print $2}' /usr/local/etc/rsnapshot-wrapper.conf) 24 | touch "${NOMOUNT}" 25 | 26 | for interval in daily weekly monthly; do 27 | COUNT=$(find "${DIR}"/${interval}.[0-9] -maxdepth 0 2>/dev/null | wc -l) 28 | j=0 29 | while [ "${j}" -le "${COUNT}" ]; do 30 | echo "(${j}/${COUNT}) rsnapshot -c ${CONF} ${interval}..." 31 | rsnapshot -c "${CONF}" "${interval}" 32 | j=$((j+1)) 33 | done 34 | done 35 | 36 | # Since this is not a normal operation and may take a long time, we will 37 | # remove the NOMOUNT flag again, otherwise we may forget to remove it. 38 | rm -f "${NOMOUNT}" 39 | -------------------------------------------------------------------------------- /rsnapshot/rsnapshot-wrapper.conf: -------------------------------------------------------------------------------- 1 | # 2 | # rsnapshot-wrapper.conf 3 | # 4 | PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/opt/csw/bin:/opt/local/bin 5 | CONFDIR=/etc/rsnapshot 6 | LOG=/var/log/rsnapshot/rsnapshot-wrapper.log 7 | PIDFILE=/var/run/rsnapshot-wrapper.pid 8 | NICE=5 9 | 10 | # Custom preexec/postexec scripts one might make use of. 11 | # Examples: 12 | MOUNTPOINTS="/mnt/a /mnt/b" 13 | preexec() { 14 | for m in $MOUNTPOINTS; do 15 | # Linux, Solaris 16 | $DEBUG mount -o remount,rw "$m" 17 | # $DEBUG zfs mount -o remount,rw "$m" 18 | if [ ! $? = 0 ]; then 19 | log "**** $m could not be mounted rw!" 1 20 | break 21 | fi 22 | done 23 | } 24 | 25 | postexec() { 26 | for m in $MOUNTPOINTS; do 27 | # Linux, Solaris 28 | $DEBUG mount -o remount,ro "$m" 29 | # $DEBUG zfs mount -o remount,ro "$m" 30 | if [ ! $? = 0 ]; then 31 | log "**** $m could not be mounted ro!" 1 32 | break 33 | fi 34 | done 35 | } 36 | -------------------------------------------------------------------------------- /rsnapshot/rsnapshot-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2009 Christian Kujau 4 | # 5 | # Rsnapshot wrapper script. For this to work, the rsnapshot.conf 6 | # file for each host must include the following directives: 7 | # 8 | # ##HOST=FQDN NAME=alias PORT=NN OS=Unix TAG=ABC RDY=/var/run/rsnapshot.ready 9 | # 10 | # * The line must begin with two hashmarks (##) and no space after that. 11 | # * NAME is just an alias for the hostname, usually the same as HOST (optional) 12 | # * HOST should be the FQDN of the machine to be backed up. 13 | # * PORT should be the SSH port of the machine to connect to. 14 | # * OS should be an identifier for the expected operating system on 15 | # the remote machine: 16 | # - For Unix/Linux the output of "hostid" is parsed 17 | # - For Darwin the output of "uname -s" is parsed 18 | # - For Windows, the output of "cygcheck.exe -s" is parsed 19 | # - For BusyBox, the output of "busybox" is parsed 20 | # * TAG is the expected output of the output above 21 | # * RDY is a filename which must exist on the remote machine 22 | # otherwise the backup will not be run. 23 | # 24 | # TODO: 25 | # - run rsnapshot for just one config. 26 | # - implement (real) DEBUG mode 27 | # - recover from incomplete backups. That's really something 28 | # rsnapshot itsself could do, but can't right now. 29 | # - Remove -4 from the SSH & Rsync commands to make it IPv6 ready again 30 | # 31 | LANG=C 32 | PATH=/usr/bin:/usr/sbin:/bin:/sbin 33 | CONF=/usr/local/etc/rsnapshot-wrapper.conf 34 | 35 | # unset me! 36 | # DEBUG=echo 37 | 38 | log() { 39 | echo "$(date +%F\ %H:%M:%S\ %Z): $1" 40 | [ -n "$2" ] && exit "$2" 41 | } 42 | 43 | backup() { 44 | INTERVAL="$1" 45 | log "**** =======================================================" 46 | log "**** $INTERVAL backup started (PID: $$)..." 47 | 48 | # Not all systems have GNU/date, but Rsnapshot needs Perl anyway 49 | BEGIN_G=$(perl -e 'print time') 50 | for c in $CONFDIR/*.conf; do 51 | BEGIN=$(perl -e 'print time') 52 | 53 | # We're parsing our configuration file for: 54 | # 55 | # - ROOT, RLOG - standard rsnapshot options 56 | # - HOST, PORT, OS - FQDN, SSH port, operating system 57 | # - NAME - hostname alias, used for logfile tagging 58 | # - TAG - either the system's hostid or whatever "OS" 59 | # is set to (e.g. "Windows", "BusyBox") 60 | # - RDY - we shall only backup if this file exists on the remote host 61 | # 62 | # We're using them to identify the system correctly and will only 63 | # backup if the client wants us to. 64 | # 65 | unset ROOT RLOG NAME HOST PORT OS TAG RDY MSG 66 | eval $(awk '/^snapshot_root/ {print "ROOT="$2}; /^logfile/ {print "RLOG="$2}' "$c") 67 | eval $(awk -F\# '/^##HOST=/ {print $3}' "$c") 68 | 69 | # Set NAME to HOST if it wasn't set explicitly in the configuration file 70 | [ -z "$NAME" ] && NAME="$HOST" 71 | 72 | # As "test -w" would return true even when ROOT is mounted r/o, so let's touch(1) it. 73 | if [ -d "$ROOT" ] && touch "$ROOT" 2>/dev/null; then 74 | : 75 | else 76 | log "**** $ROOT is not a writable directory!" 77 | continue 78 | fi 79 | 80 | # Only run if the last backup was successful 81 | # FIXME: match on successful backups too, so that backups are run again once 82 | # the problem has been fixed. 83 | # egrep "${NAME}/${OS}.*finished" "$LOG" | tail -1 | grep "with errors" > /dev/null 84 | # if [ $? = 0 ]; then 85 | # log "**** The last backup of $NAME/$OS had errors - skipping!" | tee -a "$RLOG" 86 | # continue 87 | # fi 88 | 89 | # Only run if there's no successful run today 90 | egrep "$(date +%Y-%m-%d).*"$CYCLE".*(completed successfully|completed, but with some warnings)" "$RLOG" > /dev/null 91 | if [ $? = 0 ]; then 92 | log "**** $NAME/$OS already has a $INTERVAL backup from today, skipping." | tee -a "$RLOG" 93 | continue 94 | fi 95 | 96 | # See if the remote system is up & running 97 | nc -w1 -z "$HOST" "$PORT" > /dev/null 98 | if [ ! $? = 0 ]; then 99 | log "**** Host $NAME not responding on port $PORT, skipping!" 100 | continue 101 | fi 102 | 103 | # We need to know if we're about to backup the correct system, but 104 | # we can't rely on the system's hostname (think of multiboot systems 105 | # with the same FQDN and the same SSH hostkeys installed). The hostid 106 | # should be good enough. Unfortunately, some systems won't provide one 107 | # and we have to figure out something else. 108 | case "$OS" in 109 | Darwin) 110 | # We need TAG=Darwin for this to work! 111 | TAG2=$(ssh -4 -p"$PORT" "$HOST" "uname -s" 2>/dev/null) 112 | ;; 113 | 114 | Windows) 115 | # We need TAG=Windows for this to work! 116 | TAG2="$(ssh -4 -p"$PORT" "$HOST" "cygcheck.exe -s" 2>/dev/null | awk '/^Windows/ {print $1}')" 117 | ;; 118 | 119 | BusyBox) 120 | # We need TAG=BusyBox for this to work! 121 | TAG2="$(ssh -4 -p"$PORT" "$HOST" "ls --help" 2>&1 | awk '/BusyBox/ {print $1}')" 122 | ;; 123 | 124 | *) 125 | # Most Unix/Linux systems have "hostid" 126 | TAG2="$(ssh -4 -p"$PORT" "$HOST" "hostid" 2>/dev/null)" 127 | ;; 128 | esac 129 | 130 | # See if TAG2 matches the configured TAG 131 | if [ ! "$TAG" = "$TAG2" ]; then 132 | log "**** $NAME/$OS: we expected tag \""$TAG"\" but discovered \""$TAG2"\" instead, skipping!" 133 | continue 134 | fi 135 | 136 | # See if the remote site wants us to check if we're allowed to backup 137 | if [ -n "$RDY" ]; then 138 | 139 | # See if the remote site wants us to backup 140 | TEMP=$($DEBUG mktemp) 141 | $DEBUG rsync -4 --port="$PORT" "$HOST":"$RDY" "$TEMP" 2>/dev/null 142 | if [ ! $? = 0 ]; then 143 | log "**** File \""$NAME":"$RDY"\" ($OS) not found, skipping!" 144 | $DEBUG rm -f "$TEMP" 145 | continue 146 | else 147 | $DEBUG rm -f "$TEMP" 148 | fi 149 | else 150 | # The remote side specified no ready-file, we'll run the backup anyway. 151 | : 152 | fi 153 | 154 | # Bail out if we're unable to create a logfile 155 | if [ ! -f "$RLOG" ]; then 156 | $DEBUG touch "$RLOG" 157 | if [ ! $? = 0 ]; then 158 | log "**** Cannot create $RLOG, skipping." 159 | continue 160 | fi 161 | fi 162 | 163 | # All tests passed, let's do this now 164 | log "**** $NAME/$OS ($INTERVAL) started..." | tee -a "$RLOG" 165 | if [ -z "$DEBUG" ]; then 166 | rsnapshot -c "$c" "$INTERVAL" >> "$RLOG" 2>&1 167 | else 168 | echo rsnapshot -c "$c" "$INTERVAL" 169 | fi 170 | 171 | # See if we were successful 172 | tail -1 "$RLOG" | grep 'completed successfully' 1>/dev/null || MSG="with errors " 173 | 174 | END=$(perl -e 'print time') 175 | DIFF=$(echo "scale=2; ( $END - $BEGIN ) / 60" | bc -l) 176 | log "**** $NAME/$OS ($INTERVAL) finished ${MSG}after $DIFF minutes." 177 | done 178 | END_G=$(perl -e 'print time') 179 | DIFF_G=$(echo "scale=2; ( $END_G - $BEGIN_G ) / 60" | bc -l) 180 | log "**** $INTERVAL backup finished after $DIFF_G minutes" 181 | 182 | # Sync disks 183 | sync 184 | } 185 | 186 | # We need a configuration too 187 | if [ ! -f "$CONF" ]; then 188 | log "Configuration file ($CONF) missing, cannot continue!" 1 189 | else 190 | . "$CONF" 191 | 192 | # We need these to run 193 | if [ ! -d "$CONFDIR" ] || [ -z "$LOG" ] || [ -z "$PIDFILE" ]; then 194 | log "**** Please check CONFDIR, LOG, PIDFILE in $CONF!" 1 195 | fi 196 | 197 | # We also need configuration file(s) 198 | ls "$CONFDIR"/*.conf > /dev/null 2>&1 199 | if [ ! $? = 0 ]; then 200 | log "**** There are no configuration files in $CONFDIR!" 1 201 | fi 202 | fi 203 | 204 | run_only_once() { 205 | PID=$(cat "$PIDFILE" 2>/dev/null) 206 | if [ -n "$PID" ]; then 207 | ps -p"$PID" > /dev/null 208 | if [ $? = 0 ]; then 209 | log "**** There's another instance of $(basename "$0") running (PID: $PID)" 1 210 | else 211 | echo $$ > "$PIDFILE" 212 | fi 213 | else 214 | echo $$ > "$PIDFILE" 215 | fi 216 | } 217 | 218 | # Be nice to others 219 | [ -n "$NICE" ] && renice "$NICE" $$ > /dev/null 220 | [ -n "$IDLE" ] && ionice -c 3 -p $$ > /dev/null 221 | 222 | # Main 223 | case $1 in 224 | hourly|daily|weekly|monthly) 225 | run_only_once 226 | CYCLE="$1" 227 | preexec 2>&1 | tee -a "$LOG" 228 | backup "$CYCLE" 2>&1 | tee -a "$LOG" 229 | postexec 2>&1 | tee -a "$LOG" 230 | ;; 231 | 232 | stats) 233 | # Not Y3K safe :-) 234 | for h in $(awk '/^2[0-9][0-9][0-9].*\((hourly|daily|weekly|monthly)\) finished/ {print $5}' "$LOG" | sort -u); do 235 | MINUTES=$(egrep "${h}.*finished" "$LOG" | awk '{sum+=$9} END {printf "%0.1f\n", sum/NR}') 236 | echo "Host $h took an average of $MINUTES minutes to complete." 237 | done | sort -nk7 238 | 239 | echo "----" 240 | for t in hourly daily weekly monthly; do 241 | grep "$t" "$LOG" > /dev/null || continue 242 | MINUTES=$(egrep "${t} backup finished after" "$LOG" | awk '{sum+=$9} END {printf "%0.1f\n", sum/NR}') 243 | echo "The $t backup took an average of $MINUTES minutes to complete." 244 | done 245 | ;; 246 | 247 | *) 248 | echo "Usage: $(basename "$0") [hourly|daily|weekly|monthly]" 249 | echo " $(basename "$0") [stats]" 250 | exit 1 251 | ;; 252 | esac 253 | -------------------------------------------------------------------------------- /rsnapshot/validate-rsync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c) Public Domain 4 | # 5 | # Tries to verify if SSH_ORIGINAL_COMMAND is really 6 | # rsync/uname/whatever and return false if not. 7 | # 8 | case "$SSH_ORIGINAL_COMMAND" in 9 | rsync\ --server*|uname\ -s|hostid) 10 | $SSH_ORIGINAL_COMMAND 11 | ;; 12 | 13 | *) 14 | exit 1 15 | ;; 16 | esac 17 | -------------------------------------------------------------------------------- /sensors_adt746x.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2009 Christian Kujau 4 | # therm_adt746x cannot be queried via i2c, so 5 | # we're not using lm_sensors but this little script 6 | # 7 | renice 10 $$ > /dev/null 8 | BASE=/sys/devices/temperatures 9 | 10 | case $1 in 11 | -s|--short) 12 | echo "CPU: $(cat ${BASE}/sensor1_temperature) ($(awk '/^clock/ {print $3}' /proc/cpuinfo \ 13 | | sed 's/\.[0-9]*//')) Fan: $(sed 's/.*(//;s/ rpm)$//' \ 14 | < ${BASE}/sensor1_fan_speed) GPU: $(cat ${BASE}/sensor2_temperature)" 15 | ;; 16 | 17 | -b) 18 | # If pmu_battery is present 19 | find /sys/ -type f | grep battery | grep -Ev 'uevent|srcversion|initstate|refcnt|sections/\.|autosuspend_delay_ms|note.gnu.build' | \ 20 | xargs grep . | sed 's/.*pmu-battery.[0-9]\///;s/:/ /' 21 | ;; 22 | 23 | -h) 24 | echo "Usage: $(basename "$0") [-s] ....print short summary" 25 | echo " [-b] ....print battery status" 26 | echo " [-h] ....print this help text" 27 | echo "With no arguments supplied, we will print out a long summary." 28 | ;; 29 | 30 | *) 31 | for p in ${BASE}/sensor1_location \ 32 | ${BASE}/sensor1_fan_speed \ 33 | ${BASE}/sensor1_temperature \ 34 | ${BASE}/sensor1_limit \ 35 | ${BASE}/sensor2_location \ 36 | ${BASE}/sensor2_temperature \ 37 | ${BASE}/sensor2_limit; do 38 | echo "$(basename $p) $(cat $p)" 39 | done 40 | # As a bonus, print our current clockspeed 41 | awk '/^clock/ {print $1" "$3}' /proc/cpuinfo 42 | ;; 43 | esac 44 | -------------------------------------------------------------------------------- /ternet/flip.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # (c) Pete Stevens 4 | # http://www.ex-parrot.com/~pete/upside-down-ternet.html 5 | # 6 | $|=1; 7 | $count = 0; 8 | $pid = $$; 9 | $tmp = "/var/www/ternet"; 10 | while (<>) { 11 | chomp $_; 12 | if ($_ =~ /(.*\.jpg)/i) { 13 | $url = $1; 14 | system("/usr/bin/wget", "-q", "-O","$tmp/$pid-$count.jpg", "$url"); 15 | system("/usr/bin/mogrify", "-flip","$tmp/$pid-$count.jpg"); 16 | print "http://127.0.0.1/ternet/$pid-$count.jpg\n"; 17 | } 18 | elsif ($_ =~ /(.*\.gif)/i) { 19 | $url = $1; 20 | system("/usr/bin/wget", "-q", "-O","$tmp/$pid-$count.gif", "$url"); 21 | system("/usr/bin/mogrify", "-flip","$tmp/$pid-$count.gif"); 22 | print "http://127.0.0.1/ternet/$pid-$count.gif\n"; 23 | } 24 | elsif ($_ =~ /(.*\.png)/i) { 25 | $url = $1; 26 | system("/usr/bin/wget", "-q", "-O","$tmp/$pid-$count.png", "$url"); 27 | system("/usr/bin/mogrify", "-flip","$tmp/$pid-$count.png"); 28 | print "http://127.0.0.1/ternet/$pid-$count.png\n"; 29 | } 30 | else { 31 | print "$_\n";; 32 | } 33 | $count++; 34 | } 35 | -------------------------------------------------------------------------------- /ternet/flop.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ksh 2 | # 3 | # (C) Mule, 2009-08-07 4 | # The Lolcats, they are everywhere! 5 | # https://web.archive.org/web/20170702162404/http://www.breakingsystemsforfunandprofit.com/the-lolcats-they-are-everywhere/ 6 | # 7 | DIR=/var/www/ternet 8 | 9 | while read -r URL; do 10 | SURL=$(echo "${URL}" | cut -d" " -f1) 11 | if echo "${SURL}" | grep -Eqi "\.(jp(e)?g|gif|png|tiff|bmp|ico)$"; then 12 | umask 002 13 | PIC=$$-${RANDOM} 14 | wget -q -O ${DIR}/${PIC}.tmp "${SURL}" 15 | convert -quiet ${DIR}/${PIC}.tmp -flop ${DIR}/${PIC}.png 16 | rm -f ${DIR}/${PIC}.tmp 17 | echo http://127.0.0.1/ternet/${PIC}.png 18 | else 19 | echo "${URL}" 20 | fi 21 | done 22 | -------------------------------------------------------------------------------- /ternet/iptables-ternet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (C) MMCM 4 | # External proxy for transparent proxying 5 | # https://forum.archive.openwrt.org/viewtopic.php?id=18582 6 | # 7 | SRC=10.0.0.0/24 8 | IFACE=br-lan 9 | ROUTER=10.0.0.1 10 | PROXY=10.0.0.30 11 | PROXY_PORT=3128 12 | 13 | case $1 in 14 | start) 15 | iptables -t nat -A prerouting_rule -i $IFACE ! -s $PROXY -p tcp --dport 80 -j DNAT --to $PROXY:$PROXY_PORT 16 | iptables -t nat -A postrouting_rule -o $IFACE -s $SRC -d $PROXY -j SNAT --to $ROUTER 17 | iptables -A forwarding_rule -i $IFACE -o $IFACE -s $SRC -d $PROXY -p tcp --dport $PROXY_PORT -j ACCEPT 18 | ;; 19 | 20 | stop) 21 | iptables -t nat -D prerouting_rule -i $IFACE ! -s $PROXY -p tcp --dport 80 -j DNAT --to $PROXY:$PROXY_PORT 22 | iptables -t nat -D postrouting_rule -o $IFACE -s $SRC -d $PROXY -j SNAT --to $ROUTER 23 | iptables -D forwarding_rule -i $IFACE -o $IFACE -s $SRC -d $PROXY -p tcp --dport $PROXY_PORT -j ACCEPT 24 | ;; 25 | 26 | *) 27 | echo "Usage: $(basename "$0") [start|stop]" 28 | exit 1 29 | ;; 30 | esac 31 | -------------------------------------------------------------------------------- /vbox-sysrq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # (c)2011 Christian Kujau 4 | # Send SysRq to VirtualBox virtual machines 5 | # 6 | # The schema for sending sysrq keycodes is: 7 | # 1d 38 54 [request type press] [request type release] d4 b8 9d 8 | # 9 | # The 'request type press' are the hex scancodes for a specific character. 10 | # 11 | # For example, to send "s", the 'request type press' is "1f". To release the same 12 | # key, 0x80 is added to the scancode: 0x1f + 0x80 = 0x9f. Thus, the sequence for 13 | # sending sysrq-s is "1f 9f" 14 | # 15 | # Links: 16 | # Keyboard scancodes: Ordinary scancodes 17 | # https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html#ss1.4 18 | # 19 | # Use Magic Sysrq-key in guest 20 | # https://www.halfdog.net/Misc/TipsAndTricks/VirtualBox.html#MagicSysrq 21 | # 22 | # Switching Linux terminals in VirtualBox using VBoxManage 23 | # https://web.archive.org/web/20130102094426/http://blog.frameos.org/2011/06/08/changing-linux-terminals-in-virtualbox-using-vboxmanage 24 | # 25 | if [ ! $# -eq 2 ]; then 26 | echo "Usage: $(basename "$0") [vm] [sysrq]" 27 | echo " [vm] help" 28 | exit 1 29 | else 30 | VM="$1" 31 | SYSRQ="$2" 32 | fi 33 | 34 | # https://www.kernel.org/doc/Documentation/admin-guide/sysrq.rst 35 | PRESS=$(echo " 36 | b|30 # reBoot 37 | c|2E # Crash 38 | e|12 # terminate-all-tasks 39 | f|21 # memory-full-oom-kill 40 | h|23 # help 41 | i|17 # kill-all-tasks 42 | j|24 # thaw-filesystems 43 | k|25 # saK 44 | l|26 # show-backtrace-all-active-cpus 45 | m|32 # show-memory-usage 46 | n|31 # nice-all-RT-tasks 47 | o|18 # powerOff 48 | p|19 # show-registers 49 | q|10 # show-all-timers 50 | r|13 # unRaw 51 | s|1F # Sync 52 | t|14 # show-task-states 53 | u|16 # Unmount 54 | w|11 # show-blocked-tasks 55 | z|2C # dump-ftrace-buffer 56 | " | grep -E "^${SYSRQ}" | cut -c3,4) 57 | 58 | if [ -n "${PRESS}" ]; then 59 | RELEASE=$(printf "%X\n" $((0x${PRESS} + 0x80))) # or: 'obase=16; ibase=16; $PRESS + 80 | bc' 60 | set -x 61 | VBoxManage controlvm "$VM" keyboardputscancode 1d 38 54 "${PRESS}" "${RELEASE}" d4 b8 9d 62 | else 63 | echo 64 | echo "Unknown sysrq key! (${SYSRQ})" 65 | grep -E '^.\|' "$0" 66 | echo 67 | exit 1 68 | fi 69 | -------------------------------------------------------------------------------- /xbindkeysrc: -------------------------------------------------------------------------------- 1 | # 2 | # Really good Xbindkeys howto: 3 | # https://wiki.archlinux.org/index.php/Xbindkeys 4 | # 5 | 6 | # Note: sudoers needs !requiretty for this to work! 7 | "sudo /usr/local/sbin/keyboard-backlight.sh off" 8 | m:0x0 + c:237 9 | XF86KbdBrightnessDown 10 | 11 | "sudo /usr/local/sbin/keyboard-backlight.sh total" 12 | m:0x0 + c:238 13 | XF86KbdBrightnessUp 14 | --------------------------------------------------------------------------------