├── .gitignore ├── .vscode └── launch.json ├── LICENSE.md ├── README.md ├── alsa-info.sh ├── apt-dist-upgrade-chroots.sh ├── apt-dist-upgrade.sh ├── apt ├── add-apt-repository.sh ├── apt-backup.sh ├── apt-dist-upgrade-chroots.sh ├── apt-dist-upgrade.sh ├── apt-enable-pkg-src.sh ├── apt-headless.sh ├── apt-info.sh └── cleanup-boot.sh ├── bareos ├── btraceback.gdb ├── cleanup-tape.sh ├── clear-cache.sh ├── drive-stats.sh ├── end-backup.sh ├── get-client-cmd.sh ├── hwe-backup.sh ├── hwe-setcap.sh ├── hwe-status.sh ├── install-client.sh ├── keys-backup.cfg.example ├── keys-backup.sh ├── list-tapes.sh ├── logwatch │ ├── applybareosdate │ ├── bareos │ ├── logfile.bareos.conf │ └── services.bareos.conf ├── maintain-catalog.sh ├── post-upgrade.sh ├── pwgen.sh ├── release-tape.sh ├── reset-bareos.sh ├── reset-client.sh ├── restore-test.sh ├── run-post-job.sh ├── send-stats.cfg.example ├── send-stats.sh ├── setup-logwatch.sh ├── storage-init.sh ├── tape-alert.sh └── tape-info.sh ├── bind-pci.sh ├── bindiff.sh ├── broadcast-message.sh ├── burn-iso.sh ├── change-ext.sh ├── check-fsck.sh ├── check-uefi.sh ├── clean-kernel-modules.sh ├── cmd-hist.sh ├── console-colors.sh ├── cpu-ctx.sh ├── cpu-top-10.sh ├── cpu-usage.sh ├── do-chroot.sh ├── dpkg-list-commands.sh ├── dpkg-list-files.sh ├── dpkg-purge-uninstalled.sh ├── du-top-10.sh ├── du-top-20.sh ├── du-top-50.sh ├── dump-info.sh ├── dump-kconfig.sh ├── dump-mbr.sh ├── dump-mem-strings.sh ├── ecryptfs ├── config.sh.example ├── create-keyfile.sh ├── create-plain.sh ├── device │ └── README ├── format-luks.sh ├── unlock.sh └── unmount.sh ├── extract-bookmarks.sh ├── filename-cleanup.sh ├── find-broken-pdfs.sh ├── find-broken-symlinks.sh ├── find-duplicate-files.sh ├── find-edids.sh ├── find-rfc.sh ├── flatten-text.sh ├── freq-cmd.sh ├── fun ├── bsod.sh ├── fortune-rnd.sh ├── get-random-commit-msg.sh ├── matrix.sh └── screensaver.sh ├── get-datestamp.sh ├── get-driver.sh ├── get-random.sh ├── get-src-main.sh ├── get-sshd-banner.sh ├── git ├── git-autocommit.sh ├── git-graph.sh ├── git-init-repo.sh ├── git-init-user.sh ├── git-last-log.sh ├── git-list-authors.sh ├── git-log-delta-master.sh ├── git-ls-ignored.sh ├── git-make-shared.sh ├── git-pull-forced.sh ├── git-push-refs.sh ├── git-reset-hard.sh ├── git-reset-submodules.sh ├── git-rewrite-author.sh ├── git-set-fdate.sh ├── git-stats.sh ├── git-svn-setignored.sh ├── gitattributes.template ├── gitconfig.template └── github-list-starred.sh ├── gredit.sh ├── grep-syslog.sh ├── grep-whitespace.sh ├── helpers ├── datetime.sh ├── dpkg.sh ├── fs.sh ├── log4bash.sh ├── net.sh ├── spinner.sh └── sys.sh ├── hw-report.sh ├── image-cdrom.sh ├── intercept-output.sh ├── io-mem.sh ├── iommu-groups.sh ├── js-list.sh ├── kill-defunct.sh ├── last-modified.sh ├── lastlog.sh ├── linux-bench.sh ├── list-crontabs.sh ├── list-inodes.sh ├── list-kernels.sh ├── list-mountpoints.sh ├── list-vga.sh ├── ls-chmod.sh ├── ls-group.sh ├── ls-icon-names.sh ├── ls-open-logs.sh ├── ls-usb.sh ├── lsof-watch-pid.sh ├── lstty.sh ├── lvm ├── lvs.sh ├── mount-lv.sh └── umount-lv.sh ├── man2pdf.sh ├── md5.sh ├── mem-top.sh ├── mem-usage.sh ├── mount-dev.sh ├── mount-image.sh ├── mount-tmpfs.sh ├── net ├── adapter-stats.sh ├── arp-scan.sh ├── arpwatch.sh ├── block-ip.sh ├── bus-speed.sh ├── capture-mail.sh ├── capture-plaintext.sh ├── cf-update-record.sh ├── check-tor.sh ├── common_irq_affinity.sh ├── dig-do-transfer.sh ├── find-port-name.sh ├── flush-iptables.sh ├── gen-ipv6-ula.sh ├── gen-mac.sh ├── get-mac.sh ├── get-public-ip.sh ├── get-wan-ip.sh ├── grep-allowed-email.sh ├── grep-dropped-email.sh ├── grep-iptables-attackers.sh ├── grep-port-clients.sh ├── ip-info.sh ├── isup.sh ├── list-active-connections.sh ├── list-dhcp-leases.sh ├── list-nics.sh ├── net-graph.sh ├── netperf-mst.sh ├── nic-balance.sh ├── pkt-capture.sh ├── port-listeners.sh ├── set_irq_affinity.sh ├── set_irq_affinity_bynode.sh ├── set_irq_affinity_cpulist.sh ├── show-listeners.sh ├── show_irq_affinity.sh ├── show_irq_affinity_hints.sh ├── speedtest.sh ├── ssh-speed.sh ├── update-ethercodes.sh └── update-port-list.sh ├── openwrt ├── opkg-upgrade.sh ├── set-ipv6-ula.sh └── upgrade-all.sh ├── perf-report.sh ├── permissions-backup.sh ├── pi-bench.sh ├── pid-clock.sh ├── print-active.sh ├── print-cmd.sh ├── ps-chroot.sh ├── ps-ctxt.sh ├── ps-tree.sh ├── pull-pastebin.sh ├── reboot-required.sh ├── rename.sh ├── reset-usb.sh ├── rfc-reader.sh ├── rngtest.sh ├── run-local.sh ├── scan-qr.sh ├── security ├── audit-acct.sh ├── clear-lastlog.sh ├── clear-wtmp.sh ├── find-ow-perm.sh ├── find-setgid.sh ├── find-setuid.sh ├── gen-passwd.sh ├── gpg-agent-restart.sh ├── gpg-delete-key.sh ├── gpg-test-key.sh ├── kernel-bugs.sh ├── lock-gnome.sh ├── ls-auth-failures.sh ├── pulledpork-update.sh ├── secure-delete.sh ├── suricata-reload-rules.sh ├── swap-nuke.sh ├── virustotal-check.sh └── virustotal-submit.sh ├── send-mobile-alert.sh ├── setup ├── configs │ ├── bash.aliases │ ├── bash.logout │ ├── bashrc.example │ ├── gnupg │ │ ├── dirmngr.conf.example │ │ ├── gpg-agent.conf.example │ │ ├── gpg.conf.example │ │ └── scdaemon.conf.example │ ├── nanorc.example │ ├── profile.skel │ ├── ssh │ │ ├── sshd.config │ │ └── sshdusers.rsyslog │ ├── sysctl │ │ ├── 10-console-messages.conf.example │ │ ├── 10-ipv6-privacy.conf.example │ │ ├── 10-kernel-hardening.conf.example │ │ ├── 10-link-restrictions.conf.example │ │ ├── 10-lxd-inotify.conf.example │ │ ├── 10-magic-sysrq.conf.example │ │ ├── 10-network-security.conf.example │ │ ├── 10-ptrace.conf.example │ │ ├── 10-zeropage.conf.example │ │ └── sysctl.conf.example │ ├── sysctl_ixgb.conf │ └── xrdp │ │ └── 45-allow-colord.pkla ├── create-issue-banner.sh ├── fix-xrdp-colord.sh ├── init-maildir.sh ├── install-filebeat.sh ├── install-glances.sh ├── install-munin.sh ├── install-openvpn.sh ├── install-skel.sh ├── install-ssh-gpg.sh ├── install-welcome-issue.sh ├── ixgb-perf.sh ├── reddit-background.sh ├── set-timezone.sh ├── sm-ipmi-keygen.sh ├── sshd-keygen.sh └── user-nanorc.sh ├── sha1.sh ├── show-irq.sh ├── sort-hex.sh ├── speaker-test.sh ├── ssl ├── check-ocsp-staple.sh ├── check-ssl.sh ├── clean-pem.sh ├── extract-pfx.sh ├── find-expired.sh ├── gen-snakeoil.sh ├── get-serial.sh ├── print-asn1.sh ├── print-cert.sh ├── print-info.sh ├── print-req.sh ├── test-oid.sh └── verify-cert.sh ├── stopwatch.sh ├── swap-usage.sh ├── sys-bandwidth.sh ├── sys-call-table.sh ├── sysload.sh ├── systemd ├── disable-sleep.sh ├── list-enabled.sh ├── list-running.sh ├── plot-boot.sh ├── plot-services.sh └── plot-targets.sh ├── to-png.sh ├── tools ├── hdd-fan-control.pl ├── memconf.pl └── rak-the-ripper.pl ├── trade-check.sh ├── tree.sh ├── tripwire ├── db-init.sh ├── dump-config.sh ├── print-latest.sh ├── update-latest.sh └── update-policy.sh ├── umount-dev.sh ├── update-cmdfu.sh ├── update-geoip.sh ├── update-pcidb.sh ├── url-decode.sh ├── url-encode.sh ├── usbreset-ehci.sh ├── usbreset-xhci.sh ├── wikipedia.sh ├── windows ├── evtx-grab-logins.sh └── exchange-autodiscover.sh ├── x11notify.sh ├── x11vnc.sh └── xen ├── create-domain.sh ├── get-vnc-port.sh ├── ps-xen.sh └── vnc-create-stunnel.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # ignored files and folders 2 | 3 | tmp/ 4 | .* 5 | 6 | *.rej 7 | *.out 8 | *.patch 9 | *.diff 10 | *.swp 11 | *.bak 12 | *.tmp 13 | *.csv 14 | *.dat 15 | *.log 16 | *.key* 17 | *.txt 18 | *.zip 19 | *.pcap 20 | *.ids 21 | *.png 22 | *.pdf 23 | *.cfg 24 | *.svg 25 | *.old 26 | *.iso 27 | *.sha1 28 | *.sha256 29 | *.md5 30 | *.bin 31 | *.html 32 | *.list 33 | 34 | perf.data 35 | 36 | tmp.address 37 | mac.address 38 | mac.manufacturer 39 | 40 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "bashdb", 9 | "request": "launch", 10 | "name": "Bash-Debug (simplest configuration)", 11 | "program": "${file}" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Robert W. Baumgartner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /apt-dist-upgrade-chroots.sh: -------------------------------------------------------------------------------- 1 | apt/apt-dist-upgrade-chroots.sh -------------------------------------------------------------------------------- /apt-dist-upgrade.sh: -------------------------------------------------------------------------------- 1 | apt/apt-dist-upgrade.sh -------------------------------------------------------------------------------- /apt/apt-backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # backup apt packages 3 | # To restore: 4 | # - 'dpkg --set-selections < selections.txt && apt-get dselect-upgrade' 5 | 6 | hash dpkg 2>/dev/null || { echo >&2 "You need to install dpkg. Aborting."; exit 1; } 7 | hash apt-key 2>/dev/null || { echo >&2 "You need to install apt. Aborting."; exit 1; } 8 | 9 | if ! dpkg --get-selections > installed_packages.log; then 10 | echo >&2 "ERROR: Failed to export package selections." 11 | exit 1 12 | fi 13 | 14 | if ! apt-key exportall > repositories.keys 2>/dev/null; then 15 | echo >&2 "ERROR: Failed to export package repositories." 16 | exit 1 17 | fi 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /apt/apt-dist-upgrade-chroots.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # upgrades chroot environments 3 | 4 | hash sudo 2>/dev/null || { echo >&2 "You need to install sudo. Aborting."; exit 1; } 5 | hash apt-get 2>/dev/null || { echo >&2 "You need to install apt. Aborting."; exit 1; } 6 | hash schroot 2>/dev/null || { echo >&2 "You need to install schroot. Aborting."; exit 1; } 7 | 8 | APT_CMD="apt-get" 9 | 10 | # Ensure sudo privileges for the current user if not running as root. 11 | if [[ $EUID -ne 0 ]]; then 12 | echo "NOTICE: Running as user $USER; sudo privileges required." 13 | if ! sudo echo "" > /dev/null 2>&1; then 14 | echo >&2 "ERROR: Must have sudo privileges to modify configuration files." 15 | exit 1 16 | fi 17 | fi 18 | 19 | for chroot in $(schroot -l|awk -F : '{print $2}'); do 20 | echo "Upgrading '${chroot}' chroot ..." 21 | if ! sudo schroot -q --directory /tmp -c "${chroot}" -u root -- sh -c "${APT_CMD} -qq update && ${APT_CMD} -qy dist-upgrade && ${APT_CMD} -qy autoremove && ${APT_CMD} clean"; then 22 | echo >&2 "WARNING: Failed to upgrade chroot '${chroot}'." 23 | fi 24 | done 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /apt/apt-dist-upgrade.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Runs apt-get dist-upgrade so you don't develop carpel-tunnel 3 | # from upgrading your system all the time like you should. 4 | 5 | # Note: All arguments are passed to apt-get 6 | 7 | hash apt-get 2>/dev/null || { echo >&2 "You need to install apt. Aborting."; exit 1; } 8 | 9 | BASE_COMMAND="sudo apt-get $*" 10 | 11 | # Ensure sudo privileges for the current user if not running as root. 12 | if [[ $EUID -ne 0 ]]; then 13 | echo "NOTICE: Running as user $USER; sudo privileges required." 14 | if ! sudo echo "" > /dev/null 2>&1; then 15 | echo >&2 "ERROR: Must have sudo privileges to modify configuration files." 16 | exit 1 17 | fi 18 | fi 19 | 20 | if ! ${BASE_COMMAND} update; then 21 | echo >&2 "ERROR: System update failed." 22 | exit 1 23 | fi 24 | if ! ${BASE_COMMAND} dist-upgrade; then 25 | echo >&2 "ERROR: System upgrade failed." 26 | exit 1 27 | fi 28 | if ! ${BASE_COMMAND} autoremove; then 29 | echo >&2 "ERROR: Package autoremoval failed." 30 | exit 1 31 | fi 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /apt/apt-enable-pkg-src.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Create a new source list of pkg-src entries derived from primary sources. 3 | # Reads /etc/apt/sources.list and creates /etc/apt/sources.list.d/deb-src.list 4 | 5 | hash apt-get 2>/dev/null || { echo >&2 "You need to install apt. Aborting."; exit 1; } 6 | 7 | # Ensure sudo privileges for the current user if not running as root. 8 | if [[ $EUID -ne 0 ]]; then 9 | echo "NOTICE: Running as user $USER; sudo privileges required." 10 | if ! sudo echo "" > /dev/null 2>&1; then 11 | echo >&2 "ERROR: Must have sudo privileges to modify configuration files." 12 | exit 1 13 | fi 14 | fi 15 | 16 | if [ ! -e "/etc/apt/sources.list" ]; then 17 | echo >&2 "ERROR: Missing /etc/apt/sources.list" 18 | exit 1 19 | fi 20 | 21 | if ! grep '^deb ' /etc/apt/sources.list | \ 22 | sed 's/^deb /deb-src /g' | \ 23 | sudo tee /etc/apt/sources.list.d/deb-src.list; then 24 | echo >&2 "ERROR: Failed to create new source file." 25 | exit 1 26 | fi 27 | 28 | if ! sudo apt-get update -y; then 29 | echo >&2 "ERROR: Failed to update package cache; rolling back changes ..." 30 | sudo rm -vi "/etc/apt/sources.list.d/deb-src.list" 31 | exit 1 32 | fi 33 | 34 | exit 0 35 | -------------------------------------------------------------------------------- /apt/cleanup-boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Clean up the /boot partition 3 | # DANGER: This script is dangerous! 4 | # Only run it if you know what you 5 | # are doing. 6 | 7 | hash dpkg 2>/dev/null || { echo >&2 "You need to install dpkg. Aborting."; exit 1; } 8 | hash apt-get 2>/dev/null || { echo >&2 "You need to install apt. Aborting."; exit 1; } 9 | hash sudo 2>/dev/null || { echo >&2 "You need to install sudo. Aborting."; exit 1; } 10 | 11 | # Ensure sudo privileges for the current user if not running as root. 12 | if [[ $EUID -ne 0 ]]; then 13 | echo "NOTICE: Running as user $USER; sudo privileges required." 14 | if ! sudo echo "" > /dev/null 2>&1; then 15 | echo >&2 "ERROR: Must have sudo privileges to modify configuration files." 16 | exit 1 17 | fi 18 | fi 19 | 20 | dpkg -l 'linux-*' \ 21 | | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' \ 22 | | xargs sudo apt-get -y purge 23 | -------------------------------------------------------------------------------- /bareos/btraceback.gdb: -------------------------------------------------------------------------------- 1 | print my_name 2 | print exename 3 | print exepath 4 | print catalog_db 5 | print version 6 | print host_os 7 | print distname 8 | print distver 9 | print host_name 10 | print dist_name 11 | show env TestName 12 | bt 13 | thread apply all bt 14 | f 0 15 | info locals 16 | f 1 17 | info locals 18 | f 2 19 | info locals 20 | f 3 21 | info locals 22 | f 4 23 | info locals 24 | f 5 25 | info locals 26 | f 6 27 | info locals 28 | f 7 29 | info locals 30 | detach 31 | quit 32 | -------------------------------------------------------------------------------- /bareos/clear-cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 0x19e Networks 3 | # 4 | # Clears the cache and restarts the Bareos director 5 | # 6 | # Robert W. Baumgartner 7 | 8 | hash bconsole 2>/dev/null || { echo >&2 "You need to install bareos-bconsole. Aborting."; exit 1; } 9 | 10 | echo ".bvfs_clear_cache yes" | sudo bconsole 11 | sudo service bareos-dir restart 12 | echo ".bvfs_update" | sudo bconsole 13 | 14 | # perform a database check 15 | sudo -u bareos bareos-dbcheck -b -f 16 | 17 | exit $? 18 | -------------------------------------------------------------------------------- /bareos/drive-stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Prints a variety of statistics for the specified tape drive 3 | 4 | hash tapestat 2>/dev/null || { echo >&2 "You need to install sysstat. Aborting."; exit 1; } 5 | hash smartctl 2>/dev/null || { echo >&2 "You need to install smartmontools. Aborting."; exit 1; } 6 | 7 | DRIVE="/dev/sg0" 8 | if [ -n "$1" ]; then 9 | DRIVE="$1" 10 | fi 11 | 12 | if [ ! -c "${DRIVE}" ]; then 13 | echo >&2 "ERROR: '$1' is not a valid block device." 14 | exit 1 15 | fi 16 | 17 | if ! STATUS=$(tapestat "${DRIVE}"); then 18 | echo >&2 "ERROR: Failed to read tape status from ${DRIVE}." 19 | exit 1 20 | fi 21 | 22 | if ! REPORT=$(smartctl -i -H -l error "${DRIVE}"); then 23 | echo >&2 "ERROR: Failed to read S.M.A.R.T. status from ${DRIVE}." 24 | exit 1 25 | fi 26 | 27 | echo "${STATUS}" 28 | echo "${REPORT}" | tail -n+3 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /bareos/end-backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # releases the tape after nightly catalog backups 3 | 4 | if [ ! -e "/usr/lib/bareos/scripts/delete_catalog_backup" ]; then 5 | echo >&2 "ERROR: Missing Bareos script: /usr/lib/bareos/scripts/delete_catalog_backup" 6 | exit 1 7 | fi 8 | 9 | # delete the catalog backup 10 | /usr/lib/bareos/scripts/delete_catalog_backup 11 | 12 | # rewind and eject the current tape 13 | hash mt 2>/dev/null || { echo >&2 "You need to install mt-st; cannot eject tape."; exit 1; } 14 | mt rewind 15 | mt eject 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /bareos/get-client-cmd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 0x19e Networks 3 | # 4 | # Generate a bconsole command for adding a client to Bareos 5 | # 6 | # Robert W. Baumgartner 7 | 8 | DIR_NAME="bareos-dir" 9 | 10 | hash bareos-fd 2>/dev/null || { echo >&2 "You need to install bareos-filedaemon. Aborting."; exit 1; } 11 | 12 | if [[ $EUID -ne 0 ]] && [[ "$USER" != "bareos" ]]; then 13 | echo "This script must have permissions to read the Bareos configuration files." >&2 14 | exit 1 15 | fi 16 | 17 | if [ -n "$1" ]; then 18 | DIR_NAME="$1" 19 | fi 20 | 21 | if ! [ -e "/etc/bareos/bareos-fd.d/director/${DIR_NAME}.conf" ]; then 22 | echo >&2 "ERROR: Missing /etc/bareos/bareos-fd.d/director/${DIR_NAME}.conf (is Bareos installed?)" 23 | exit 1 24 | fi 25 | 26 | # get (unquoted) password from config file 27 | FD_PASS=$(grep Password /etc/bareos/bareos-fd.d/director/"${DIR_NAME}".conf | awk '{print $3}' | sed -e 's/^"//' -e 's/"$//') 28 | 29 | if [ -z "$FD_PASS" ]; then 30 | echo >&2 "ERROR: Failed to determine client password." 31 | exit 1 32 | fi 33 | 34 | echo >&2 "To add this client to Bareos, run the following command on the server:" 35 | echo >&2 36 | echo " " echo \"configure add client name="$(hostname)" address="$(hostname --fqdn)" password="${FD_PASS}"\" \| sudo bconsole 37 | echo >&2 38 | 39 | exit 0 40 | -------------------------------------------------------------------------------- /bareos/hwe-status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Displays hardware encryption status 3 | 4 | DEVICE="/dev/sg0" 5 | 6 | hash bscrypto 2>/dev/null || { echo >&2 "You need to install bareos-storage-tape. Aborting."; exit 1; } 7 | 8 | result=0 9 | if ! bscrypto -d200 -e "${DEVICE}"; then 10 | result=1 11 | fi 12 | 13 | exit $result 14 | -------------------------------------------------------------------------------- /bareos/list-tapes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # list tapes using mtx command 3 | 4 | AUTOCHANGER="/dev/sg1" 5 | 6 | hash mtx 2>/dev/null || { echo >&2 "You need to install mtx. Aborting."; exit 1; } 7 | 8 | sudo mtx -f ${AUTOCHANGER} status 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /bareos/logwatch/applybareosdate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | ######################################################################## 4 | ## Copyright (c) 2009 Sigma Consulting Services Limited 5 | ## v1.00 2009/06/21 16:54:23 Ian McMichael 6 | ## 7 | ## This program is free software: you can redistribute it and/or modify 8 | ## it under the terms of the GNU General Public License as published by 9 | ## the Free Software Foundation, either version 2 of the License, or 10 | ## any later version. 11 | ## 12 | ## This program is distributed in the hope that it will be useful, 13 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | ## GNU General Public License for more details. 16 | ## 17 | ## You should have received a copy of the GNU General Public License 18 | ## along with this program. If not, see . 19 | ######################################################################## 20 | 21 | use Logwatch ':dates'; 22 | 23 | my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; 24 | 25 | $SearchDate = TimeFilter('%d-%b %H:%M'); 26 | 27 | if ( $Debug > 5 ) { 28 | print STDERR "DEBUG: Inside ApplyBareosDate...\n"; 29 | print STDERR "DEBUG: Looking For: " . $SearchDate . "\n"; 30 | } 31 | 32 | my $OutputLine = 0; 33 | 34 | while (defined($ThisLine = )) { 35 | if ($ThisLine =~ m/^$SearchDate /o) { 36 | $OutputLine = 1; 37 | } elsif ($ThisLine !~ m/^\s+/o) { 38 | $OutputLine = 0; 39 | } 40 | 41 | if ($OutputLine) { 42 | print $ThisLine; 43 | } 44 | } 45 | 46 | # vi: shiftwidth=3 syntax=perl tabstop=3 et 47 | -------------------------------------------------------------------------------- /bareos/logwatch/bareos: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | # 3 | # logwatch filter script for bareos log files 4 | # 5 | # Mon Jan 03 2005 6 | # D. Scott Barninger and Karl Cunningham 7 | # 8 | # Copyright 2005-2006 Free Software Foundation Europe e.V. 9 | # licensed under GPL-v2 10 | 11 | use strict; 12 | use POSIX qw(strftime); 13 | 14 | my (@JobName,$JobStatus,$ThisName,$ThisStatus,$ThisDate); 15 | my ($Job,$JobId,$JobDate,$Debug,$DebugCounter,%data); 16 | 17 | # set debug level 18 | $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; 19 | 20 | if ( $Debug >= 5 ) { 21 | print STDERR "\n\nDEBUG: Inside Bareos Filter \n\n"; 22 | $DebugCounter = 1; 23 | } 24 | 25 | while () { 26 | chomp; 27 | if ( $Debug >= 5 ) { 28 | print STDERR "DEBUG($DebugCounter): $_\n"; 29 | $DebugCounter++; 30 | } 31 | 32 | # Test the line for a new entry, which is a jobid record 33 | if (/^\s*JobId:\s+(\d+)/) { 34 | $JobId = $1; 35 | next; 36 | } 37 | 38 | (/^\s*Job:\s*(.*)/) and $Job = $1; 39 | (/^\s*Termination:\s*(.*)/) and $JobStatus = $1; 40 | (/^\s*Job:.*(\d{4}-\d{2}-\d{2})/) and $JobDate = $1; 41 | 42 | if ($JobId and $Job and $JobStatus and $JobDate) { 43 | $data{$JobId} = { 44 | "Job" => $Job, 45 | "JobStatus" => $JobStatus, 46 | "JobDate" => $JobDate, 47 | }; 48 | $JobId = $Job = $JobStatus = $JobDate = ""; 49 | } 50 | } 51 | 52 | # if we have data print it out, otherwise do nothing 53 | if (scalar(keys(%data))) { 54 | print "\nJobs Run:\n"; 55 | foreach my $Id (sort {$a<=>$b} (keys(%data))) { 56 | $ThisName = $data{$Id}{Job}; 57 | $ThisStatus = $data{$Id}{JobStatus}; 58 | $ThisDate = $data{$Id}{JobDate}; 59 | $ThisName =~ s/\s//g; 60 | $ThisStatus =~ s/\s//g; 61 | print "$ThisDate $Id $ThisName\n $ThisStatus\n\n"; 62 | } 63 | } 64 | 65 | exit(0); 66 | -------------------------------------------------------------------------------- /bareos/logwatch/logfile.bareos.conf: -------------------------------------------------------------------------------- 1 | # What actual file? Defaults to LogPath if not absolute path.... 2 | # LogFile = @LogDir@/bareos.log 3 | 4 | Title = "Bareos" 5 | 6 | LogFile = /var/log/bareos/bareos.log 7 | -------------------------------------------------------------------------------- /bareos/logwatch/services.bareos.conf: -------------------------------------------------------------------------------- 1 | Title = "bareos" 2 | 3 | # Which logfile group... 4 | LogFile = bareos 5 | 6 | *ApplyBareosDate = 7 | -------------------------------------------------------------------------------- /bareos/maintain-catalog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # perform post-backup catalog maintenence 3 | 4 | CATALOG="BareosCatalog" 5 | STATS_DAYS=14 6 | 7 | hash bconsole 2>/dev/null || { echo >&2 "You need to install bareos-bconsole. Aborting."; exit 1; } 8 | 9 | if ! OUTPUT=$(bconsole << END_OF_DATA 10 | @output /dev/null 11 | @output 12 | use catalog=${CATALOG} 13 | update stats days=${STATS_DAYS} 14 | prune stats yes 15 | .bvfs_update 16 | quit 17 | END_OF_DATA 18 | ); then 19 | echo >&2 "ERROR: Failed running post-backup maintenence for catalog ${CATALOG}." 20 | if [ -n "${OUTPUT}" ]; then 21 | echo >&2 "ERROR: Command output: ${OUTPUT}" 22 | fi 23 | exit 1 24 | fi 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /bareos/pwgen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generates a new password following the Bacula / Bareos specification 3 | 4 | hash openssl 2>/dev/null || { echo >&2 "You need to install openssl. Aborting."; exit 1; } 5 | 6 | openssl rand -base64 33 7 | 8 | exit 0 9 | -------------------------------------------------------------------------------- /bareos/release-tape.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # release tape storage 3 | # 4 | STORAGE="Tape" 5 | 6 | hash bconsole 2>/dev/null || { echo >&2 "You need to install bareos-bconsole. Aborting."; exit 1; } 7 | 8 | # Use bconsole to release storage 9 | if ! OUTPUT=$(bconsole << END_OF_DATA 10 | @output /dev/null 11 | @output 12 | release storage=${STORAGE} 13 | quit 14 | END_OF_DATA 15 | ); then 16 | echo >&2 "ERROR: Failed to release ${STORAGE} storage." 17 | if [ -n "${OUTPUT}" ]; then 18 | echo >&2 "ERROR: Command output: ${OUTPUT}" 19 | fi 20 | exit 1 21 | fi 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /bareos/reset-bareos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 0x19e Networks 3 | # 4 | # Resets bareos storage and database 5 | # 6 | # Robert W. Baumgartner 7 | 8 | # define the use to run database setup scripts as 9 | SUDO_USER="postgres" 10 | 11 | hash bareos-dir 2>/dev/null || { echo >&2 "You need to install bareos-director. Aborting."; exit 1; } 12 | hash bareos-fd 2>/dev/null || { echo >&2 "You need to install bareos-filedaemon. Aborting."; exit 1; } 13 | hash bareos-sd 2>/dev/null || { echo >&2 "You need to install bareos-storage. Aborting."; exit 1; } 14 | 15 | # stop all daemons 16 | sudo service bareos-dir stop 17 | sudo service bareos-fd stop 18 | sudo service bareos-sd stop 19 | 20 | # disable LTO encryption 21 | sudo bscrypto -c /dev/nst0 22 | 23 | # remove files 24 | sudo rm -rf /var/lib/bareos/storage/* 25 | sudo rm -rf /var/lib/bareos/bootstrap/* 26 | sudo rm -rf /var/lib/bareos/spool/* 27 | sudo rm /var/lib/bareos/* 28 | 29 | # add postgres to bareos group 30 | # this is required for setup scripts to read 31 | # the bareos configuration files, but may not 32 | # be good for production security. 33 | sudo usermod -a -G bareos postgres 34 | 35 | # drop databases 36 | pushd /usr/lib/bareos/scripts || exit 1 37 | sudo -u $SUDO_USER ./drop_bareos_database 38 | 39 | # (re-)create database 40 | sudo -u $SUDO_USER ./create_bareos_database 41 | sudo -u $SUDO_USER ./make_bareos_tables 42 | sudo -u $SUDO_USER ./grant_bareos_privileges 43 | popd || exit 1 44 | 45 | # remove postgres from the bareos group 46 | # should not be required after setup is complete 47 | sudo gpasswd -d postgres bareos 48 | 49 | # restart daemons 50 | sudo service bareos-dir start 51 | sudo service bareos-fd start 52 | sudo service bareos-sd start 53 | 54 | exit 0 55 | -------------------------------------------------------------------------------- /bareos/reset-client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 0x19e Networks 3 | # 4 | # Resets a client's Bareos File Daemon 5 | # 6 | # Robert W. Baumgartner 7 | 8 | hash bareos-fd 2>/dev/null || { echo >&2 "You need to install bareos-filedaemon. Aborting."; exit 1; } 9 | 10 | sudo service bareos-fd stop 11 | sudo rm -v /var/lib/bareos/* 12 | sudo service bareos-fd start 13 | 14 | exit $? 15 | -------------------------------------------------------------------------------- /bareos/restore-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A Script for Bacula Restore Test 4 | # 5 | # It selects, randomly x (FILES_PER_JOB) to restore from every Bacula Configured Client into a fixed Restore Client. 6 | # 7 | # Author: Robert W. Baumgartner 8 | # Original script by Heitor Faria - http://www.bacula.com.br | http://bacula.us 9 | # 10 | RESTORE_CLIENT=bareos-fd 11 | FILES_PER_JOB=10 12 | 13 | hash bconsole 2>/dev/null || { echo >&2 "You need to install bareos-bconsole. Aborting."; exit 1; } 14 | hash grep 2>/dev/null || { echo >&2 "You need to install grep. Aborting."; exit 1; } 15 | hash sed 2>/dev/null || { echo >&2 "You need to install sed. Aborting."; exit 1; } 16 | 17 | for CLIENT in $(echo "llist clients" | bconsole | grep -w '[Nn]ame:' | sed 's/[Nn]ame://g' | sed 's/ //g'); do 18 | JOBID=$(echo "list jobs client=$CLIENT" | bconsole | grep "| T" | tail -n 1 | cut -f 2 -d "|" | sed 's/[ ,]//g') 19 | echo "list files jobid=$JOBID" | bconsole |head -n -7 | tail -n +10 |cut -d "|" -f 2 | sed 's/^ //g' | sort -R | head -n $FILES_PER_JOB | sed 's/[ \t]\+$//g' > /tmp/list-"$CLIENT" 20 | echo "restore jobid=$JOBID client=$CLIENT restoreclient=$RESTORE_CLIENT restorejob=RestoreFiles file=/dev/null || { echo >&2 "You need to install bareos-bconsole. Aborting."; exit 1; } 8 | 9 | if [ -z "${JOB_ID}" ]; then 10 | echo >&2 "ERROR: No job specified." 11 | exit 1 12 | fi 13 | 14 | # validate job number 15 | re='^[0-9]+$' 16 | if ! [[ $JOB_ID =~ $re ]] ; then 17 | echo >&2 "ERROR: '${JOB_ID}' is not a valid job identifier." 18 | exit 1 19 | fi 20 | 21 | if ! OUTPUT=$(bconsole << END_OF_DATA 22 | @output /dev/null 23 | @output 24 | use catalog=${CATALOG} 25 | .bvfs_update jobid=${JOB_ID} 26 | quit 27 | END_OF_DATA 28 | ); then 29 | echo >&2 "ERROR: Failed to run post-job commands for job ${JOB_ID}." 30 | if [ -n "${OUTPUT}" ]; then 31 | echo >&2 "ERROR: Command output: ${OUTPUT}" 32 | fi 33 | exit 1 34 | fi 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /bareos/send-stats.cfg.example: -------------------------------------------------------------------------------- 1 | # Example send-stats.sh configuration. 2 | # This file provides a(n optional) way to configure script settings. 3 | # IMPORTANT: This file must be placed in the same directory as the send-stats.sh script! 4 | 5 | # Drive to report on. 6 | # This option can be modified at the command line. 7 | DRIVE="/dev/sg0" 8 | 9 | # E-mail settings. 10 | MAIL_HOST="localhost" 11 | MAIL_FROM="(Bareos) " 12 | MAIL_TO="root" 13 | MAIL_SUBJECT="Tape Drive Statistics" 14 | -------------------------------------------------------------------------------- /bareos/send-stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Sends tape drive statistics out using bsmtp 3 | 4 | CFG_NAME="send-stats.cfg" 5 | 6 | DRIVE="/dev/sg0" 7 | MAIL_HOST="localhost" 8 | MAIL_FROM="(Bareos) " 9 | MAIL_TO="root" 10 | MAIL_SUBJECT="Tape Drive Statistics" 11 | 12 | hash bsmtp 2>/dev/null || { echo >&2 "You need to install bareos-common. Aborting."; exit 1; } 13 | 14 | SOURCE="${BASH_SOURCE[0]}" 15 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 16 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 17 | SOURCE="$(readlink "$SOURCE")" 18 | # if $SOURCE was a relative symlink, we need to resolve it relative to the path where 19 | # the symlink file was located 20 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 21 | done 22 | CWD="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 23 | 24 | # Create some variables for use in configurerd strings 25 | T_STAMP=$(date '+%H:%M:%S%z') 26 | D_STAMP=$(date '+%Y.%m.%d') 27 | DT_STAMP=$(date '+%Y.%m.%d_%H:%M:%S%z') 28 | export TIME="${T_STAMP}" 29 | export DATE="${D_STAMP}" 30 | export TIMESTAMP="${DT_STAMP}" 31 | 32 | CONFIG_PATH="${CWD}/${CFG_NAME}" 33 | if [ -e "${CONFIG_PATH}" ]; then 34 | # shellcheck source=/dev/null 35 | source "${CONFIG_PATH}" 36 | fi 37 | 38 | # Check if a drive path was supplied 39 | if [ -n "$1" ]; then 40 | DRIVE="$1" 41 | fi 42 | if [ ! -c "${DRIVE}" ]; then 43 | echo >&2 "ERROR: '$1' is not a valid block device." 44 | exit 1 45 | fi 46 | 47 | # Configure the stats command 48 | STATS_COMMAND="${CWD}/drive-stats.sh ${DRIVE}" 49 | 50 | # Get statistics 51 | if ! STATS="$(${STATS_COMMAND})"; then 52 | echo >&2 "ERROR: Failed to run stats command '${STATS_COMMAND}'." 53 | exit 1 54 | fi 55 | if [ -z "${STATS}" ]; then 56 | echo >&2 "ERROR: Statistics output is null." 57 | exit 1 58 | fi 59 | 60 | # Send the message 61 | if ! echo "${STATS}" | bsmtp -h "${MAIL_HOST}" -f "${MAIL_FROM}" -s "${MAIL_SUBJECT}" "${MAIL_TO}"; then 62 | echo >&2 "ERROR: Failed to e-mail statistics to ${MAIL_TO}." 63 | exit 1 64 | fi 65 | 66 | echo "Sent tape drive statistics to ${MAIL_TO}." 67 | exit 0 68 | -------------------------------------------------------------------------------- /bareos/tape-alert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 0x19e Networks 4 | # 5 | # Isolates SMART errors for a tape drive for conditional reporting 6 | # 7 | # Robert W. Baumgartner 8 | # 9 | DRIVE="/dev/sg0" 10 | if [ -n "$1" ]; then 11 | DRIVE="$1" 12 | fi 13 | 14 | if [ ! -c "${DRIVE}" ]; then 15 | echo >&2 "ERROR: '$1' is not a valid block device." 16 | exit 1 17 | fi 18 | 19 | hash smartctl 2>/dev/null || { echo >&2 "You need to install smartmontools. Aborting."; exit 1; } 20 | 21 | if ! OUTPUT=$(smartctl -H "${DRIVE}"); then 22 | echo >&2 "ERROR: Failed to read S.M.A.R.T. status from ${DRIVE}." 23 | exit 1 24 | fi 25 | 26 | ALERT=$(echo "${OUTPUT}" | tail -n+5 | cut -d ':' -f2 | awk '{$1=$1};1') 27 | if [ -n "${ALERT}" ] && [ "${ALERT}" != "OK" ]; then 28 | # Error detected 29 | echo "Tape alert: ${ALERT}" 30 | exit 1 31 | fi 32 | 33 | # No errors detected 34 | exit 0 35 | -------------------------------------------------------------------------------- /bareos/tape-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Show some basic tape information 3 | 4 | DRIVE="/dev/nst0" 5 | 6 | hash tapeinfo 2>/dev/null || { echo >&2 "You need to install mtx. Aborting."; exit 1; } 7 | hash bscrypto 2>/dev/null || { echo >&2 "You need to install bareos-storage-tape. Aborting."; exit 1; } 8 | 9 | tapeinfo -f ${DRIVE} && echo && bscrypto -e ${DRIVE} 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /bindiff.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Peform a binary diff of two files using hexdump 3 | 4 | hash diff 2>/dev/null || { echo >&2 "You need to install diff (diffutils). Aborting."; exit 1; } 5 | hash hexdump 2>/dev/null || { echo >&2 "You need to install hexdump (bsdmainutils). Aborting."; exit 1; } 6 | 7 | export HEXDUMP_ARGS="-v -C" 8 | export DIFFCMD_ARGS="-u" 9 | 10 | function version_gt() { test "$(printf '%s\n' "$@" | sort -bt. -k1,1 -k2,2n -k3,3n -k4,4n -k5,5n | head -n 1)" != "$1"; } 11 | function enable_diff_color() { 12 | DIFF_VERSION=$(diff --version | grep -Po '(?<=diff\s\(GNU\sdiffutils\)\s)[0-9\.]+$' | head -n1) 13 | if version_gt "${DIFF_VERSION}" "3.3"; then 14 | export DIFFCMD_ARGS="${DIFFCMD_ARGS} --color" 15 | fi 16 | } 17 | 18 | # uncomment to enable colored diffs where supported (version >= 3.4) 19 | enable_diff_color 20 | 21 | FILE1="$1" 22 | FILE2="$2" 23 | 24 | if [ -z "${FILE1}" ] || [ -z "${FILE2}" ]; then 25 | echo >&2 "Usage: $0 " 26 | exit 1 27 | fi 28 | if [ ! -e "${FILE1}" ]; then 29 | echo >&2 "ERROR: File '$FILE1' does not exist." 30 | exit 1 31 | fi 32 | if [ ! -e "${FILE2}" ]; then 33 | echo >&2 "ERROR: File '$FILE2' does not exist." 34 | exit 1 35 | fi 36 | 37 | # perform the actual diff 38 | function perform_diff() { 39 | diff_cmd="diff ${DIFFCMD_ARGS}" 40 | hexdump_cmd="hexdump ${HEXDUMP_ARGS}" 41 | if ! ${diff_cmd} <(${hexdump_cmd} "${FILE1}") <(${hexdump_cmd} "${FILE2}"); then 42 | return 1 43 | fi 44 | return 0 45 | } 46 | 47 | if ! output=$(perform_diff); then 48 | if hash colordiff 2>/dev/null && ! echo "${DIFFCMD_ARGS}" | grep "\-\-color"; then 49 | echo "${output}" | colordiff 50 | else 51 | echo "${output}" 52 | fi 53 | exit 1 54 | fi 55 | 56 | echo "Files are identical." 57 | exit 0 58 | -------------------------------------------------------------------------------- /broadcast-message.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # broadcasts a message 3 | 4 | if [[ -z "$1" ]]; then 5 | echo "Usage: $0 " >&2 6 | exit 1 7 | fi 8 | 9 | TMP_FILE=/tmp/wall_msg 10 | 11 | echo "$@" > $TMP_FILE 12 | wall < $TMP_FILE 13 | rm -f $TMP_FILE 14 | -------------------------------------------------------------------------------- /change-ext.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # script to change file extensions 3 | 4 | if [ "$#" -ne 3 ]; then 5 | echo >&2 "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | echo "Updating extensions in $1 ..." 10 | echo "Converting $2 -> $3" 11 | 12 | for f in *.$2; do 13 | mv -v "$f" "$(basename "$f" ."$2").$3" 14 | done 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /check-fsck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "Usage: $0 " 5 | exit 1 6 | fi 7 | 8 | # check if superuser 9 | if [[ $EUID -ne 0 ]]; then 10 | echo >&2 "This script must be run as root." 11 | exit 1 12 | fi 13 | 14 | function showInfo() { 15 | if [ -z "$1" ]; then 16 | echo >&2 "ERROR: No device specified." 17 | return 1 18 | fi 19 | 20 | if ! output=$(tune2fs -l "$1"); then 21 | return 1 22 | fi 23 | 24 | if ! last=$(echo "$output" | grep Last\ c); then 25 | return 1 26 | fi 27 | if ! count=$(echo "$output" | grep Mount); then 28 | return 1 29 | fi 30 | if ! max=$(echo "$output" | grep Max); then 31 | return 1 32 | fi 33 | 34 | echo "$last" 35 | echo "$count" 36 | echo "$max" 37 | 38 | return 0 39 | } 40 | 41 | if ! showInfo "$1"; then 42 | exit 1 43 | fi 44 | 45 | exit 0 46 | -------------------------------------------------------------------------------- /check-uefi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -d /sys/firmware/efi ]; then 4 | echo "Using UEFI" 5 | else 6 | echo "Using BIOS" 7 | fi 8 | 9 | # [ -d /sys/firmware/efi ] && echo UEFI || echo BIOS 10 | -------------------------------------------------------------------------------- /clean-kernel-modules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # create a script to clean kernel modules 3 | # the current kernel is excluded for posterity 4 | 5 | TMP="*" 6 | if [[ -n "$1" ]]; then 7 | TMP=$1 8 | fi 9 | 10 | PATTERN=$TMP bash -c 'echo "# clean kernel modules matching pattern \"$PATTERN\""; 11 | echo "# WARNING: DOUBLE-CHECK COMMANDS BEFORE RUNNING!"; 12 | for f in $(ls -d /lib/modules/$PATTERN | grep -v $(uname -r)); do 13 | echo sudo rm -v -r $f; done' 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /cmd-hist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Allows searching command history for the current user 3 | # Note: The leading index can be stripped from 'history' 4 | # output using 'awk', e.g.: 5 | # history | awk '{first = $1; $1 = ""; print $0, first; }' 6 | 7 | # Set the number of commands to display 8 | TOP_COUNT=20 9 | 10 | # Parse command history 11 | HISTORY=$(grep "$1" ~/.bash_history) 12 | TOTAL=$(echo "$HISTORY" | wc -l) 13 | UNIQUE=$(echo "$HISTORY" | sort | uniq -c) 14 | TOP_CMD=$(echo "$UNIQUE" | sort -rh | head -${TOP_COUNT}) 15 | COUNT=$(echo "$UNIQUE" | wc -l) 16 | 17 | # Display results 18 | echo "Command History" 19 | echo "===============" 20 | if [ -n "$1" ]; then 21 | echo "Applied command filter (grep): $1" 22 | fi 23 | echo "Found $COUNT unique commands out of $TOTAL BASH history entries for $USER." 24 | echo "Top $TOP_COUNT commands:" 25 | echo "$TOP_CMD" 26 | 27 | exit 0 28 | -------------------------------------------------------------------------------- /console-colors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # show each of the available console colors 3 | 4 | #for code in {0..255}; do 5 | # echo -e "\e[38;05;${code}m $code: This is a test string." 6 | #done 7 | 8 | for clbg in {40..47} {100..107} 49 ; do 9 | 10 | for clfg in {30..37} {90..87} 39 ; do 11 | 12 | for attr in 0 1 2 4 5 7 ; do 13 | echo -n -e "\e[${attr};${clbg};${clfg}m ^[${attr};${clbg};${clfg}m \e[0m" 14 | done 15 | echo 16 | 17 | done 18 | 19 | done 20 | 21 | #echo -n -e "\e[4;1m Test \e[0m" 22 | #echo -n -e "\e[0;101;31m Test \e[0m" 23 | #echo -e "\e[4m Test \e[0m" 24 | -------------------------------------------------------------------------------- /cpu-top-10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # print top 10 processes by cpu usage 3 | 4 | ps --no-headers aux | sort -rnk +3 | head 5 | -------------------------------------------------------------------------------- /cpu-usage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # gets current (total) cpu usage 3 | # rwb < rwb[at]0x19e.net > 4 | 5 | MPSTAT_BIN=$(which mpstat) 6 | TOP_BIN=$(which top) 7 | 8 | if [[ -z "$MPSTAT_BIN" ]]; then 9 | # echo "Using '$TOP_BIN' for calculating CPU usage..." 10 | 11 | $TOP_BIN -bn1 | grep "Cpu(s)" | \ 12 | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | \ 13 | awk '{print 100 - $1"%"}' 14 | else 15 | # echo "Using '$MPSTAT_BIN' for calculating CPU usage..." 16 | LANG=c $MPSTAT_BIN | awk '$12 ~ /[0-9.]+/ { print 100 - $12"%" }' 17 | fi 18 | -------------------------------------------------------------------------------- /do-chroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # runs a command in the specified schroot 3 | # rwb [ rwb[at]0x19e.net ] 4 | 5 | if [[ -z "$1" ]]; then 6 | echo "Usage: $0 [COMMAND]" 7 | exit 1 8 | fi 9 | 10 | # The full path to the schroot binary 11 | SCHROOT_BIN="/usr/bin/schroot" 12 | 13 | # The name of the schroot to jail the daemon in 14 | SCHROOT_NAME="$1" 15 | 16 | # Get the command to run 17 | CMD_ARGS="${*:2}" 18 | 19 | echo -e "schroot \t : $SCHROOT_NAME" 20 | echo -e "command \t : $CMD_ARGS" 21 | 22 | # check to make sure the specified schroot actually exists 23 | CHROOT_EXISTS="" 24 | for ch in $($SCHROOT_BIN -l -a|grep "chroot"|awk -F: '{print $2}'); do 25 | if [[ $ch == "$SCHROOT_NAME"* ]]; then 26 | CHROOT_EXISTS="y" 27 | fi 28 | done 29 | if [[ -z "$CHROOT_EXISTS" ]]; then 30 | echo "ERROR: The specified chroot, '$SCHROOT_NAME', does not exist." 31 | exit 1 32 | fi 33 | 34 | # Get the schroot session (or create a new one) 35 | SESSION="" 36 | for sn in $($SCHROOT_BIN -l -a|grep "session:"|awk -F: '{print $2}'); do 37 | if [[ $sn == "$SCHROOT_NAME"* ]]; then 38 | SESSION=$sn 39 | fi 40 | done 41 | if [[ -z "$SESSION" ]]; then 42 | echo "Creating new schroot session for '$SCHROOT_NAME' ..." 43 | SESSION=$(schroot --begin-session -c "$SCHROOT_NAME") 44 | fi 45 | echo "Using schroot session '$SESSION' ..." 46 | 47 | echo "Running command '$CMD_ARGS' ..." 48 | if ! $SCHROOT_BIN --directory / --run-session -c "$SESSION" "$CMD_ARGS"; then 49 | exit 1 50 | fi 51 | 52 | exit 0 53 | -------------------------------------------------------------------------------- /dpkg-list-files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEBFILE="$1" 4 | 5 | if [[ ! -f "$DEBFILE" ]]; then 6 | echo >&2 "ERROR: Must supply path to package." 7 | exit 1 8 | fi 9 | 10 | dpkg -c "$DEBFILE" | awk '{ print $6 }' | sort 11 | exit 0 12 | -------------------------------------------------------------------------------- /dpkg-purge-uninstalled.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Purges configurations for uninstalled packages 3 | # WARNING: This script deletes data! Make sure you have backups. 4 | 5 | sudo dpkg --purge "$(COLUMNS=300 dpkg -l "*" | grep "^rc" | cut -d\ -f3)" 6 | 7 | exit 0 8 | -------------------------------------------------------------------------------- /du-top-10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # find large files 3 | 4 | TOP_10_MSG="top 10 by size" 5 | INPUT_PATH="." 6 | 7 | if [ -z "${NO_SPINNER}" ]; then 8 | NO_SPINNER=0 9 | fi 10 | 11 | if [ -n "$1" ]; then 12 | if [ ! -d "$*" ]; then 13 | echo >&2 "usage: $0 [directory]" 14 | exit 1 15 | fi 16 | INPUT_PATH=$(readlink -m "$@") 17 | echo "$TOP_10_MSG: $INPUT_PATH" 18 | else 19 | INPUT_PATH=$(readlink -m "$INPUT_PATH") 20 | echo "$TOP_10_MSG" 21 | fi 22 | 23 | trap cleanup EXIT INT TERM 24 | cleanup() { 25 | if [ -n "$SCRIPT_PID" ]; then 26 | kill "$SCRIPT_PID" 27 | fi 28 | exit $? 29 | } 30 | 31 | run_spinner() 32 | { 33 | local msg="$1" 34 | local delay=0.5 35 | local SP='\|/-'; 36 | while [ "$SPIN" == "true" ] 37 | do 38 | printf "\b\r[%s] %s" "${SP:i++%${#SP}:1}" "${msg}" 39 | sleep $delay; 40 | done 41 | } 42 | 43 | start_spinner() 44 | { 45 | SPIN="true" 46 | run_spinner "$1" & 47 | SCRIPT_PID=$! 48 | } 49 | 50 | stop_spinner() 51 | { 52 | SPIN="false" 53 | 54 | # clear current line of any text 55 | echo -ne "\r%\033[0K\r" 56 | } 57 | 58 | 59 | if [ "$NO_SPINNER" -eq 0 ]; then 60 | start_spinner "Calculating directory sizes ..." 61 | fi 62 | 63 | INPUT_PATH_ESCAPED="" 64 | if [ "$INPUT_PATH" != "/" ]; then 65 | INPUT_PATH=${INPUT_PATH}"/" 66 | INPUT_PATH_ESCAPED=$(readlink -m "${INPUT_PATH}" | sed -e 's/\//\\\//g' -e 's/\./\\\./g') 67 | fi 68 | 69 | pushd "${INPUT_PATH}" > /dev/null 2>&1 70 | 71 | RAW=$(du -shx ./.[^.]* 2>/dev/null ; du -shx ./[^.]* 2>/dev/null) 72 | OUTPUT=$(echo "${RAW}" | sed "s/\.\//${INPUT_PATH_ESCAPED}\//g" \ 73 | | LC_ALL=C sort -k2 | sort -rh \ 74 | | head -10) 75 | 76 | popd > /dev/null 2>&1 77 | 78 | if [ "$NO_SPINNER" -eq 0 ]; then 79 | stop_spinner 80 | fi 81 | 82 | echo "$OUTPUT" 83 | 84 | exit 0 85 | -------------------------------------------------------------------------------- /du-top-20.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # find large files 3 | 4 | TOP_20_MSG="top 20 by size" 5 | INPUT_PATH="." 6 | 7 | if [ -z "${NO_SPINNER}" ]; then 8 | NO_SPINNER=0 9 | fi 10 | 11 | if [ -n "$1" ]; then 12 | if [ ! -d "$*" ]; then 13 | echo >&2 "usage: $0 [directory]" 14 | exit 1 15 | fi 16 | INPUT_PATH=$(readlink -m "$@") 17 | echo "$TOP_20_MSG: $INPUT_PATH" 18 | else 19 | INPUT_PATH=$(readlink -m "$INPUT_PATH") 20 | echo "$TOP_20_MSG" 21 | fi 22 | 23 | trap cleanup EXIT INT TERM 24 | cleanup() { 25 | if [ -n "$SCRIPT_PID" ]; then 26 | kill "$SCRIPT_PID" 27 | fi 28 | exit $? 29 | } 30 | 31 | run_spinner() 32 | { 33 | local msg="$1" 34 | local delay=0.5 35 | local SP='\|/-'; 36 | while [ "$SPIN" == "true" ] 37 | do 38 | printf "\b\r[%s] %s" "${SP:i++%${#SP}:1}" "${msg}" 39 | sleep $delay; 40 | done 41 | } 42 | 43 | start_spinner() 44 | { 45 | SPIN="true" 46 | run_spinner "$1" & 47 | SCRIPT_PID=$! 48 | } 49 | 50 | stop_spinner() 51 | { 52 | SPIN="false" 53 | 54 | # clear current line of any text 55 | echo -ne "\r%\033[0K\r" 56 | } 57 | 58 | 59 | if [ "$NO_SPINNER" -eq 0 ]; then 60 | start_spinner "Calculating directory sizes ..." 61 | fi 62 | 63 | INPUT_PATH_ESCAPED="" 64 | if [ "$INPUT_PATH" != "/" ]; then 65 | INPUT_PATH=${INPUT_PATH}"/" 66 | INPUT_PATH_ESCAPED=$(readlink -m "${INPUT_PATH}" | sed -e 's/\//\\\//g' -e 's/\./\\\./g') 67 | fi 68 | 69 | pushd "${INPUT_PATH}" > /dev/null 2>&1 70 | 71 | RAW=$(du -shx ./.[^.]* 2>/dev/null ; du -shx ./[^.]* 2>/dev/null) 72 | OUTPUT=$(echo "${RAW}" | sed "s/\.\//${INPUT_PATH_ESCAPED}\//g" \ 73 | | LC_ALL=C sort -k2 | sort -rh \ 74 | | head -20) 75 | 76 | popd > /dev/null 2>&1 77 | 78 | if [ "$NO_SPINNER" -eq 0 ]; then 79 | stop_spinner 80 | fi 81 | 82 | echo "$OUTPUT" 83 | 84 | exit 0 85 | -------------------------------------------------------------------------------- /du-top-50.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # find large files 3 | 4 | TOP_50_MSG="top 50 by size" 5 | INPUT_PATH="." 6 | 7 | if [ -z "${NO_SPINNER}" ]; then 8 | NO_SPINNER=0 9 | fi 10 | 11 | if [ -n "$1" ]; then 12 | if [ ! -d "$*" ]; then 13 | echo >&2 "usage: $0 [directory]" 14 | exit 1 15 | fi 16 | INPUT_PATH=$(readlink -m "$@") 17 | echo "$TOP_50_MSG: $INPUT_PATH" 18 | else 19 | INPUT_PATH=$(readlink -m "$INPUT_PATH") 20 | echo "$TOP_50_MSG" 21 | fi 22 | 23 | trap cleanup EXIT INT TERM 24 | cleanup() { 25 | if [ -n "$SCRIPT_PID" ]; then 26 | kill "$SCRIPT_PID" 27 | fi 28 | exit $? 29 | } 30 | 31 | run_spinner() 32 | { 33 | local msg="$1" 34 | local delay=0.5 35 | local SP='\|/-'; 36 | while [ "$SPIN" == "true" ] 37 | do 38 | printf "\b\r[%s] %s" "${SP:i++%${#SP}:1}" "${msg}" 39 | sleep $delay; 40 | done 41 | } 42 | 43 | start_spinner() 44 | { 45 | SPIN="true" 46 | run_spinner "$1" & 47 | SCRIPT_PID=$! 48 | } 49 | 50 | stop_spinner() 51 | { 52 | SPIN="false" 53 | 54 | # clear current line of any text 55 | echo -ne "\r%\033[0K\r" 56 | } 57 | 58 | 59 | if [ "$NO_SPINNER" -eq 0 ]; then 60 | start_spinner "Calculating directory sizes ..." 61 | fi 62 | 63 | INPUT_PATH_ESCAPED="" 64 | if [ "$INPUT_PATH" != "/" ]; then 65 | INPUT_PATH=${INPUT_PATH}"/" 66 | INPUT_PATH_ESCAPED=$(readlink -m "${INPUT_PATH}" | sed -e 's/\//\\\//g' -e 's/\./\\\./g') 67 | fi 68 | 69 | pushd "${INPUT_PATH}" > /dev/null 2>&1 70 | 71 | RAW=$(du -shx ./.[^.]* 2>/dev/null ; du -shx ./[^.]* 2>/dev/null) 72 | OUTPUT=$(echo "${RAW}" | sed "s/\.\//${INPUT_PATH_ESCAPED}\//g" \ 73 | | LC_ALL=C sort -k2 | sort -rh \ 74 | | head -50) 75 | 76 | popd > /dev/null 2>&1 77 | 78 | if [ "$NO_SPINNER" -eq 0 ]; then 79 | stop_spinner 80 | fi 81 | 82 | echo "$OUTPUT" 83 | 84 | exit 0 85 | -------------------------------------------------------------------------------- /dump-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # get some info about the current host in a nifty one-liner 3 | # rwb[at]0x19e.net 4 | 5 | #SPEEDTEST_URL="http://speedtest.tele2.net/10MB.zip" 6 | #SPEEDTEST_URL="http://speedtest.wdc01.softlayer.com/downloads/test10.zip" 7 | SPEEDTEST_URL="http://chicago02.speedtest.windstream.net:8080/speedtest/random2500x2500.jpg" 8 | 9 | (printf "%s - %s\n" "$(date)" "$(hostname --fqdn)"; \ 10 | uname -a; echo; \ 11 | uptime; \ 12 | id; \ 13 | who -apb; \ 14 | echo; df -hT; echo; \ 15 | grep "model name" /proc/cpuinfo | uniq -c; \ 16 | grep MemTotal /proc/meminfo | uniq -c; \ 17 | ifconfig | grep 'inet addr'; \ 18 | echo; \ 19 | wget --output-document=/dev/null "${SPEEDTEST_URL}" /dev/null 2>&1 | grep --before-context=5 saved; \ 20 | echo; \ 21 | if hash finger 2>/dev/null; then finger root; fi; \ 22 | lsof -i) | uniq 23 | -------------------------------------------------------------------------------- /dump-kconfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Dump running kernel configuration 3 | 4 | KERNEL_VERSION=$(uname -r) 5 | KCONFIG_PATH="/boot/config-${KERNEL_VERSION}" 6 | 7 | if [ ! -e "${KCONFIG_PATH}" ]; then 8 | echo "ERROR: Kernel configuration '${KCONFIG_PATH}' not found." >&2 9 | exit 1 10 | fi 11 | 12 | cat "${KCONFIG_PATH}" 13 | exit 0 14 | -------------------------------------------------------------------------------- /dump-mbr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | hash xxd 2>/dev/null || { echo >&2 "You need to install xxd. Aborting."; exit 1; } 4 | hash dd 2>/dev/null || { echo >&2 "You need to install dd. Aborting."; exit 1; } 5 | 6 | # check if superuser 7 | if [[ $EUID -ne 0 ]]; then 8 | echo >&2 "This script must be run as root." 9 | exit 1 10 | fi 11 | 12 | if [ ! -z "$1" ]; then 13 | DEVICE="$1" 14 | fi 15 | 16 | if [ -z "${DEVICE}" ]; then 17 | DEVICE="/dev/sda" 18 | fi 19 | 20 | if [ ! -b "${DEVICE}" ]; then 21 | echo >&2 "ERROR: ${DEVICE} is not a valid block device." 22 | exit 1 23 | fi 24 | 25 | # dump MBR from device 26 | echo "Dumping MBR from device ${DEVICE} ..." 27 | if ! dd if="${DEVICE}" bs=512 count=1 2>/dev/null | xxd; then 28 | echo >&2 "ERROR: Failed to dump first 512 blocks from device ${DEVICE}" 29 | exit 1 30 | fi 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /dump-mem-strings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # read strings from memory 3 | 4 | # check if superuser 5 | if [[ $EUID -ne 0 ]]; then 6 | echo >&2 "This script must be run as root." 7 | exit 1 8 | fi 9 | 10 | dd if=/dev/mem | cat | strings 11 | -------------------------------------------------------------------------------- /ecryptfs/config.sh.example: -------------------------------------------------------------------------------- 1 | ## eCrypt volume settings 2 | 3 | # Resolve root directory path 4 | SOURCE="${BASH_SOURCE[0]}" 5 | if [ -h "$SOURCE" ]; then 6 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 7 | SOURCE="$(readlink "$SOURCE")" 8 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 9 | export ROOT_DIR="$( cd -P $DIR && pwd )" 10 | else 11 | export ROOT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 12 | fi 13 | 14 | KEYFILE="${ROOT_DIR}/keyfile" 15 | DEVNAME="crypt1" 16 | STORAGE="${ROOT_DIR}/container" 17 | MNTPATH="${ROOT_DIR}/device" 18 | SIZE_MB="10240" 19 | DEV_RND="/dev/urandom" 20 | 21 | CIPHER="aes-xts-plain64" 22 | KEY_SIZE="512" 23 | HASH_ALG="sha512" 24 | ITER_TIME="2000" 25 | 26 | # [ EOF ] # 27 | -------------------------------------------------------------------------------- /ecryptfs/create-keyfile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # creates a new keyfile 3 | 4 | RNG_DEV="/dev/urandom" 5 | 6 | # Load configuration 7 | CONFIG=$(dirname "$0")/config.sh 8 | if ! [ -e "${CONFIG}" ]; then 9 | echo >&2 "ERROR: Missing configuration file '${CONFIG}'." 10 | exit 1 11 | fi 12 | # shellcheck source=/dev/null 13 | source "${CONFIG}" 14 | 15 | if [ ! -e "${RNG_DEV}" ]; then 16 | echo >&2 "ERROR: RNG device '${RNG_DEV}' does not exist." 17 | exit 1 18 | fi 19 | if [ -e "${KEYFILE}" ]; then 20 | echo >&2 "ERROR: Key file '${KEYFILE}' already exists." 21 | exit 1 22 | fi 23 | 24 | echo "Creating new key file..." 25 | if ! dd bs=512 count=8 if="${RNG_DEV}" of="${KEYFILE}" iflag=fullblock; then 26 | echo >&2 "ERROR: Failed to create key file '${KEYFILE}'." 27 | exit 1 28 | fi 29 | 30 | echo "Wrote new key file to ${KEYFILE}." 31 | exit 0 32 | -------------------------------------------------------------------------------- /ecryptfs/device/README: -------------------------------------------------------------------------------- 1 | This folder is the mount-point for encrypted storage. 2 | If you can read this file, the volume is locked. 3 | You must unlock the desired container for files to appear. 4 | 5 | If you are not the author of this file, odds are you're a dick. 6 | So fuck off. mmmk? THX! 7 | -------------------------------------------------------------------------------- /ecryptfs/format-luks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | hash cryptsetup 2>/dev/null || { echo >&2 "You need to install cryptsetup-bin. Aborting."; exit 1; } 4 | 5 | # Load configuration 6 | CONFIG=$(dirname "$0")/config.sh 7 | if ! [ -e "${CONFIG}" ]; then 8 | echo >&2 "ERROR: Missing configuration file '${CONFIG}'." 9 | exit 1 10 | fi 11 | # shellcheck source=/dev/null 12 | source "${CONFIG}" 13 | 14 | if [ ! -e "${STORAGE}" ]; then 15 | echo >&2 "ERROR: The container '${STORAGE}' does not exist." 16 | exit 1 17 | fi 18 | 19 | if ! cryptsetup --verbose \ 20 | --type plain \ 21 | --align-payload=1 \ 22 | --use-urandom \ 23 | --verify-passphrase \ 24 | --cipher "${CIPHER}" \ 25 | --key-size "${KEY_SIZE}" \ 26 | --hash "${HASH_ALG}" \ 27 | --iter-time "${ITER_TIME}" \ 28 | luksFormat "${STORAGE}"; then 29 | echo >&2 "ERROR: Failed to format LUKS container file '${STORAGE}'." 30 | exit 1 31 | fi 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /ecryptfs/unmount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | hash cryptsetup 2>/dev/null || { echo >&2 "You need to install cryptsetup-bin. Aborting."; exit 1; } 4 | 5 | # Load configuration 6 | CONFIG=$(dirname "$0")/config.sh 7 | if ! [ -e "${CONFIG}" ]; then 8 | echo >&2 "ERROR: Missing configuration file '${CONFIG}'." 9 | exit 1 10 | fi 11 | # shellcheck source=/dev/null 12 | source "${CONFIG}" 13 | 14 | sudo umount "${MNTPATH}" 15 | sudo cryptsetup close "${DEVNAME}" 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /filename-cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DRY_RUN="true" 4 | 5 | # print out commands to clean filenames in the current directory 6 | for i in *; do 7 | if echo "$i" | grep -Po '\s'; then 8 | if [ "$DRY_RUN" == "false" ]; then 9 | mv -v "$i" "$(echo "$i" | sed -e 's/ /_/g' -e 's/(//g' -e 's/)//g' )"; 10 | else 11 | echo mv -v \""$i"\" "$(echo "$i" | sed -e 's/ /_/g' -e 's/(//g' -e 's/)//g' )"; 12 | fi 13 | fi 14 | done 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /find-broken-pdfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Search for broken PDF files 3 | 4 | hash pdfinfo 2>/dev/null || { echo >&2 "You need to install poppler-utils. Aborting."; exit 1; } 5 | 6 | SEARCH_DIR="$(readlink -m "$0")" 7 | 8 | if [ ! -z "$1" ]; then 9 | if [ ! -e "$1" ]; then 10 | echo >&2 "Search path does not exist: $1" 11 | exit 1 12 | fi 13 | 14 | SEARCH_DIR="$1" 15 | fi 16 | 17 | echo "Searching folder '${SEARCH_DIR}' ..." 18 | 19 | find "${SEARCH_DIR}" -type f -name '*.pdf' | while read -r f; do 20 | if [ ! -s "$f" ]; then 21 | echo "Empty (zero-byte) PDF : '$f'" 22 | elif ! pdfinfo "$f" > /dev/null 2>&1; then 23 | echo "Corrupted PDF document : '$f'" 24 | fi 25 | done 26 | 27 | echo "Finished." 28 | exit 0 29 | -------------------------------------------------------------------------------- /find-edids.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Find and display available EDIDs 3 | 4 | DIR_NAME="/sys" 5 | FILENAME="edid" 6 | NO_COLOR="0" 7 | 8 | # If the below value is set, edid-decode will not be used. 9 | # NO_DECODE="1" 10 | 11 | # check if edid-decode is installed 12 | HAS_EDID_DECODE=0 13 | if hash edid-decode 2>/dev/null; then 14 | HAS_EDID_DECODE=1 15 | fi 16 | 17 | print_cyan() 18 | { 19 | if [ "${NO_COLOR}" -ne "1" ]; then 20 | echo -e "\x1b[39;49;00m\x1b[36;01m${1}\x1b[39;49;00m" #> $(tty) 2>&1 < $(tty) 21 | else 22 | echo "${1}" #> $(tty) 2>&1 < $(tty) 23 | fi 24 | } 25 | 26 | print_red() 27 | { 28 | if [ "${NO_COLOR}" -ne "1" ]; then 29 | echo -e "\x1b[39;49;00m\x1b[31;01m${1}\x1b[39;49;00m" #> $(tty) 2>&1 < $(tty) 30 | else 31 | echo "${1}" #> $(tty) 2>&1 < $(tty) 32 | fi 33 | } 34 | 35 | FOUND_EDID=0 36 | EDID_ROKAY=0 37 | while read -r line; do 38 | if [ ! -s "${line}" ]; then 39 | if ! raw_edid=$(hexdump -C "${line}"); then 40 | echo >&2 "WARNING: Failed to read EDID: ${line}"; 41 | fi 42 | FOUND_EDID=1 43 | if [ -n "${raw_edid}" ]; then 44 | print_cyan "${line}"; 45 | echo "${raw_edid}"; 46 | EDID_ROKAY=1; 47 | if [ "${HAS_EDID_DECODE}" -eq "1" ] && [ -z "${NO_DECODE}" ]; then 48 | edid-decode -ec "${line}" 49 | fi 50 | else 51 | print_red "WARNING: EDID is empty: ${line}" 52 | fi 53 | fi 54 | done < <(find "${DIR_NAME}" -name "${FILENAME}" 2>/dev/null) 55 | 56 | if [ "${FOUND_EDID}" -ne "0" ]; then 57 | if [ "${EDID_ROKAY}" -eq "0" ]; then 58 | echo >&2 "ERROR: Failed to read any available EDIDs." 59 | exit 1 60 | fi 61 | else 62 | echo >&2 "ERROR: Failed to locate any EDIDs under ${DIR_NAME}." 63 | exit 1 64 | fi 65 | 66 | exit 0 67 | -------------------------------------------------------------------------------- /find-rfc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # allows searching for an RFC 3 | 4 | # check if doc-rfc is installed 5 | stat /usr/share/doc/RFC/rfc-index.txt.gz &> /dev/null || { echo >&2 "You need to install doc-rfc. Aborting."; exit 1; } 6 | 7 | if [[ -z "$1" ]]; then 8 | echo "Usage: $0 " 9 | exit 1 10 | fi 11 | 12 | # grep the index file for the specified term 13 | zgrep -i "$1" /usr/share/doc/RFC/rfc-index.txt.gz || echo "No subject found for $1" 14 | -------------------------------------------------------------------------------- /flatten-text.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Flattens a text file by removing all leading and trailing 3 | # space characters from each line of text. 4 | 5 | file=$1 6 | if [ -z "$file" ]; then 7 | echo "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | if ! [ ! -s "$file" ] | [ "$(file --mime-type "$file" | grep -Po 'text/')" == "text/" ]; then 12 | echo "File is not a valid text file: $file" 13 | exit 1 14 | fi 15 | 16 | # strip leading and trailing space characters from each line 17 | # - to remove blank lines: sed '/^$/d' 18 | # - to remove leading whitespace: sed -e 's/^[ \t]*//' 19 | # - to remove trailing whitespace: sed 's/[ \t]*$//' 20 | 21 | sed 's/^[ \t]*//;s/[ \t]*$//' "$file" > "$file.flat" 22 | 23 | echo "Saved file to: $file.flat" 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /freq-cmd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # print a list of the most frequently used commands 3 | 4 | # the number of commands to list 5 | COUNT=20 6 | 7 | awk '{a[$1]++}END{for(i in a){print a[i] " " i}}' ~/.bash_history \ 8 | | sort -rn \ 9 | | head -n $COUNT 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /fun/bsod.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # For more BSoDs check http://ro.wikipedia.org/wiki/Blue_Screen_of_Death/Simulare 3 | echo -ne "\033[1;37m" #white text 4 | echo -ne "\033[44m" #blue bg 5 | echo -ne "\033[0;0H" #Start of screen 6 | echo -ne "\033[2J" #cls 7 | 8 | echo 9 | echo 10 | echo 11 | 12 | echo -e " \033[0;34m\033[47mWindows\033[0;1m" 13 | echo -ne "\033[1;37m" #white text 14 | echo -ne "\033[44m" #blue bg 15 | echo -e " A fatal exception OE has occured at 0028:C0011E36 in VXD VMM(01) +\033[44m\033[K" 16 | echo " 00010E36. The current application will be terminated. 17 | * Press any key to terminate the current application 18 | * Press CTRL+ALT+DEL again to restart your computer. You will 19 | lose any unsaved information in all applications. 20 | " 21 | echo -e " Press any key to continue _\033[0;0m" 22 | 23 | echo 24 | echo 25 | echo 26 | echo -ne "\033[999B" 27 | read -r 28 | -------------------------------------------------------------------------------- /fun/fortune-rnd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # check if curl command exists 4 | hash fortune 2>/dev/null || { echo >&2 "You need to install fortune. Aborting."; exit 1; } 5 | hash cowsay 2>/dev/null || { echo >&2 "You need to install cowsay. Aborting."; exit 1; } 6 | 7 | if [ -z "$COWPATH" ]; then 8 | COWPATH='/usr/share/cowsay/cows/' 9 | fi 10 | 11 | cow_file_length=$(find "$COWPATH" -type f | wc -l) 12 | 13 | # initialize the random seed with the process id of this script 14 | RANDOM=$$ 15 | let "random_line = $RANDOM % $cow_file_length + 1" 16 | cow=$(find "$COWPATH" -type f | head -n "$random_line" | tail -n 1) 17 | 18 | fortune | cowsay -n -f "$cow" 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /fun/get-random-commit-msg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Print a random commit message from whatthecommit.com 3 | 4 | hash curl 2>/dev/null || { echo >&2 "You need to install curl. Aborting."; exit 1; } 5 | 6 | curl -s http://whatthecommit.com/index.txt 7 | 8 | exit $? 9 | -------------------------------------------------------------------------------- /fun/matrix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # matrix-style animation 3 | # rwb[at]0x19e[dot]net 4 | 5 | tr -c "[:digit:]" " " < /dev/urandom \ 6 | | dd cbs="$(tput cols)" conv=unblock \ 7 | | GREP_COLOR="1;32" grep --color "[^ ]" 8 | -------------------------------------------------------------------------------- /fun/screensaver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # It's just a shell screensaver ;) 3 | 4 | LINES=60; COLUMNS=120; echo -ne "\033[$((1+RANDOM%LINES));$((1+RANDOM%COLUMNS))H\033[$((RANDOM%2));3$((RANDOM%8))m$((RANDOM%10))"; echo -ne "\033[$((1+RANDOM%LINES));$((1+RANDOM%COLUMNS))H\033[$((RANDOM%2));3$((RANDOM%8))m$((RANDOM%10))"; echo -ne "\033[$((1+RANDOM%LINES));$((1+RANDOM%COLUMNS))H\033[$((RANDOM%2));3$((RANDOM%8))m$((RANDOM%10))"; trap cleanup EXIT INT TERM; cleanup() { clear ; echo -ne "\033[$((1+RANDOM%LINES));$((1+RANDOM%COLUMNS))H\033[$((RANDOM%2));3$((RANDOM%8))m$((RANDOM%10))" ; }; for ((;;)); do echo -ne "\033[$((1+RANDOM%LINES));$((1+RANDOM%COLUMNS))H\033[$((RANDOM%2));3$((RANDOM%8))m$((RANDOM%10))" ; sleep 0.1 ; done; echo -ne "\033[$((1+RANDOM%LINES));$((1+RANDOM%COLUMNS))H\033[$((RANDOM%2));3$((RANDOM%8))m$((RANDOM%10))"; echo -ne "\033[$((1+RANDOM%LINES));$((1+RANDOM%COLUMNS))H\033[$((RANDOM%2));3$((RANDOM%8))m$((RANDOM%10))"; 5 | -------------------------------------------------------------------------------- /get-datestamp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generates a date/time stamp 3 | 4 | STAMP=$(date '+%Y%m%d%H%M%S') 5 | 6 | echo "$STAMP" 7 | 8 | exit 0 9 | -------------------------------------------------------------------------------- /get-driver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Find all modules and drivers for a given class device. 4 | # From https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/ch08s02.html 5 | # 6 | 7 | if [ $# != "1" ] ; then 8 | echo 9 | echo "Script to display the drivers and modules for a specified sysfs class device" 10 | echo "usage: $0 " 11 | echo 12 | echo "example usage:" 13 | echo " $0 sda" 14 | echo "Will show all drivers and modules for the sda block device." 15 | echo 16 | exit 1 17 | fi 18 | 19 | if test -e "$1"; then 20 | DEVPATH=$1 21 | else 22 | # find sysfs device directory for device 23 | DEVPATH=$(find /sys/class -name "$1" | head -1) 24 | test -z "$DEVPATH" && DEVPATH=$(find /sys/block -name "$1" | head -1) 25 | test -z "$DEVPATH" && DEVPATH=$(find /sys/bus -name "$1" | head -1) 26 | if ! test -e "$DEVPATH"; then 27 | echo "no device found" 28 | exit 1 29 | fi 30 | fi 31 | 32 | echo "looking at sysfs device: $DEVPATH" 33 | 34 | if test -L "$DEVPATH"; then 35 | # resolve class device link to device directory 36 | DEVPATH=$(readlink -f "$DEVPATH") 37 | echo "resolve link to: $DEVPATH" 38 | fi 39 | 40 | if test -d "$DEVPATH"; then 41 | # resolve old-style "device" link to the parent device 42 | PARENT="$DEVPATH"; 43 | while test "$PARENT" != "/"; do 44 | if test -L "$PARENT/device"; then 45 | DEVPATH=$(readlink -f "$PARENT/device") 46 | echo "follow 'device' link to parent: $DEVPATH" 47 | break 48 | fi 49 | PARENT=$(dirname "$PARENT") 50 | done 51 | fi 52 | 53 | while test "$DEVPATH" != "/"; do 54 | DRIVERPATH= 55 | DRIVER= 56 | MODULEPATH= 57 | MODULE= 58 | if test -e "$DEVPATH/driver"; then 59 | DRIVERPATH=$(readlink -f "$DEVPATH/driver") 60 | DRIVER=$(basename "$DRIVERPATH") 61 | echo -n "found driver: $DRIVER" 62 | if test -e "$DRIVERPATH/module"; then 63 | MODULEPATH=$(readlink -f "$DRIVERPATH/module") 64 | MODULE=$(basename "$MODULEPATH") 65 | echo -n " from module: $MODULE" 66 | fi 67 | echo 68 | fi 69 | 70 | DEVPATH=$(dirname "$DEVPATH") 71 | done 72 | 73 | exit 0 74 | -------------------------------------------------------------------------------- /get-random.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | TMP_FILE="/tmp/random_data" 5 | 6 | echo "Generating random data..." >&2 7 | dd if=/dev/urandom bs=1 count=256 > /tmp/random_data 8 | RANDOM_HASH=$(sha512sum -b /tmp/random_data | awk '{ print $1 }') 9 | rm $TMP_FILE 10 | 11 | echo "$RANDOM_HASH" 12 | -------------------------------------------------------------------------------- /get-src-main.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Get the main function from the specified C source file 3 | 4 | if [ -n "$*" ]; then 5 | if ! MATCH=$(grep -Pzo "(?s)(\s*)\N([a-z]+(\s)?){0,3}main.*?{.*?\1}" "$@"); then 6 | exit 1 7 | fi 8 | else 9 | if ! MATCH=$(grep -Pzo "(?s)(\s*)\N([a-z]+(\s)?){0,3}main.*?{.*?\1}" ./*.c); then 10 | exit 1 11 | fi 12 | fi 13 | 14 | if [ -z "$(echo "${MATCH}" | head -n1)" ]; then 15 | MATCH=$(echo "${MATCH}" | tail -n+2) 16 | fi 17 | 18 | echo "${MATCH}" 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /get-sshd-banner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | strings /usr/sbin/sshd \ 4 | | tr , '\n' \ 5 | | grep 'OpenSSH[-_][0-9](\.[0-9])*(p[0-9])?$' \ 6 | | head -n 1 7 | -------------------------------------------------------------------------------- /git/git-autocommit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # -=[ 0x19e Networks ]=- 4 | # 5 | # Enables auto-commiting changes to a file that is already under Git control 6 | # 7 | # Author: Robert W. Baumgartner 8 | 9 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 10 | 11 | FILE="$1" 12 | MESSAGE="$2" 13 | 14 | # display usage information and exit 15 | function usage() 16 | { 17 | echo >&2 "Usage: $0 " 18 | exit 1 19 | } 20 | 21 | # check required arguments 22 | if [ -z "${FILE}" ] || [ -z "${MESSAGE}" ]; then 23 | usage 24 | fi 25 | 26 | # resolve parent directory 27 | SOURCE="${FILE}" 28 | if [ ! -d "$SOURCE" ]; then 29 | while [ -h "$SOURCE" ]; do 30 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 31 | SOURCE="$(readlink "$SOURCE")" 32 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 33 | done 34 | ROOT="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 35 | else 36 | ROOT="$SOURCE" 37 | fi 38 | if [ -z "${ROOT}" ]; then 39 | echo >&2 "ERROR: Failed to resolve parent directory for '${FILE}'." 40 | exit 1 41 | fi 42 | 43 | # git handling for etckeeper (check if /etc/.git exists) 44 | if hash git 2>/dev/null; then 45 | pushd "${ROOT}" > /dev/null 2>&1 46 | if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then 47 | if [[ "$(git status --porcelain -- "${FILE}" | grep -E '^(M| M)')" != "" ]]; then 48 | # commit pending changes 49 | if ! git add --all "${FILE}"; then 50 | echo >&2 "ERROR: Failed to add file(s) using git-add." 51 | exit 1 52 | fi 53 | if ! git commit -m "$MESSAGE"; then 54 | echo >&2 "ERROR: Failed to commit file(s) to Git repository (${ROOT})." 55 | exit 1 56 | fi 57 | exit 0 58 | fi 59 | fi 60 | popd > /dev/null 2>&1 61 | fi 62 | 63 | exit 2 64 | -------------------------------------------------------------------------------- /git/git-graph.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Displays a pretty log for the specified repository 3 | 4 | # todo: refactor to properly handle arguments, including path argument 5 | 6 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 7 | 8 | # specify the default number of entries to display 9 | export LOG_COUNT=50 10 | 11 | # check if an argument was provided 12 | if [ $# -gt 0 ]; then 13 | if [[ "$*" =~ ^-?[0-9]+$ ]]; then 14 | export LOG_COUNT="$*" 15 | else 16 | echo >&2 "ERROR: Argument must be a valid number." 17 | exit 1 18 | fi 19 | fi 20 | 21 | SOURCE="${BASH_SOURCE[0]}" 22 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a syml$ 23 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 24 | SOURCE="$(readlink "$SOURCE")" 25 | # if $SOURCE was a relative symlink, we need to resolve it relative to the pa$ 26 | # the symlink file was located 27 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 28 | done 29 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 30 | 31 | # TODO: Support input Git dir argument 32 | # GIT_DIR="" 33 | 34 | GIT_DIR=$(pwd) 35 | 36 | if [ "$(dirname "$0")" = "$GIT_DIR" ]; then 37 | echo >&2 "This script must be run from within a valid Git repository." 38 | exit 1 39 | fi 40 | 41 | if ! git -C "$GIT_DIR" rev-parse; then 42 | echo >&2 "Directory does not appear to be a valid Git repository: $DIR" 43 | exit 1 44 | fi 45 | 46 | pushd "$GIT_DIR" /dev/null 2>&1 47 | 48 | # git log -n $LOG_COUNT --format="%h %s" 49 | 50 | git log --graph --abbrev-commit --decorate --date=relative \ 51 | --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all 52 | 53 | # log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all 54 | 55 | popd > /dev/null 2>&1 56 | 57 | exit 0 58 | -------------------------------------------------------------------------------- /git/git-last-log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Displays a short-log of the current Git branch. 3 | 4 | # todo: refactor to properly handle arguments, including path argument 5 | 6 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 7 | 8 | # specify the default number of entries to display 9 | LOG_COUNT=50 10 | 11 | # check if an argument was provided 12 | if [ $# -gt 0 ]; then 13 | if [[ "$*" =~ ^-?[0-9]+$ ]]; then 14 | LOG_COUNT=$* 15 | else 16 | echo >&2 "ERROR: Argument must be a valid number." 17 | exit 1 18 | fi 19 | fi 20 | 21 | # TODO: Support input Git dir argument 22 | # GIT_DIR="" 23 | 24 | GIT_DIR=$(pwd) 25 | 26 | if [ "$(dirname "$0")" = "$GIT_DIR" ]; then 27 | echo >&2 "This script must be run from within a valid Git repository." 28 | exit 1 29 | fi 30 | 31 | if ! git -C "$GIT_DIR" rev-parse; then 32 | echo >&2 "Directory does not appear to be a valid Git repository: $GIT_DIR" 33 | exit 1 34 | fi 35 | 36 | pushd "$GIT_DIR" /dev/null 2>&1 37 | 38 | # git log -n $LOG_COUNT --format="%h %s" 39 | git log -n "$LOG_COUNT" \ 40 | --graph \ 41 | --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' \ 42 | --abbrev-commit \ 43 | --date=relative 44 | 45 | popd > /dev/null 2>&1 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /git/git-list-authors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 4 | hash cut 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 5 | hash grep 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 6 | hash sort 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 7 | hash uniq 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 8 | 9 | # specify the git directory 10 | GIT_DIR=$(pwd) 11 | 12 | # check if an argument was provided 13 | if [ $# -gt 0 ]; then 14 | if [ -n "$1" ]; then 15 | GIT_DIR=$1 16 | else 17 | echo >&2 "ERROR: Argument must not be null." 18 | exit 1 19 | fi 20 | fi 21 | 22 | if [ ! -e "$GIT_DIR" ]; then 23 | echo >&2 "'$GIT_DIR' does not exist." 24 | exit 1 25 | fi 26 | 27 | if ! git -C "$GIT_DIR" rev-parse; then 28 | echo >&2 "Directory does not appear to be a valid Git repository: $DIR" 29 | exit 1 30 | fi 31 | 32 | pushd "$GIT_DIR" /dev/null 2>&1 33 | 34 | echo "Authors for $GIT_DIR:" 35 | 36 | git log --pretty=full \ 37 | | grep -Po '(Author|Commit): (.*)' \ 38 | | cut -f '2-' -d ' ' \ 39 | | sort \ 40 | | uniq 41 | 42 | popd > /dev/null 2>&1 43 | 44 | exit 0 45 | -------------------------------------------------------------------------------- /git/git-log-delta-master.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Displays a list of commits only found in the specified branch 3 | 4 | if [ -z "$1" ]; then 5 | echo >&2 "usage: $0 " 6 | exit 1 7 | fi 8 | 9 | git log --oneline --cherry-pick --no-merges --right-only master..."$1" 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /git/git-ls-ignored.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Lists unversioned and ignored files in a Git repository 3 | 4 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 5 | 6 | # check that we're actually in a repository 7 | if ! git rev-parse --git-dir > /dev/null 2>&1; then 8 | echo >&2 "Current directory is not a git repository. Aborting." 9 | exit 1 10 | fi 11 | 12 | echo >&2 "Unversioned / ignored files:" 13 | 14 | git clean -dnx | cut -c 14- 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /git/git-reset-hard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Reset the current branch to match origin remote 3 | 4 | UPSTREAM_REMOTE="origin" 5 | 6 | # TODO: Support input Git dir argument 7 | GIT_DIR=$(readlink -m ".") 8 | 9 | if [ -z "${UPSTREAM_REMOTE}" ]; then 10 | echo >&2 "No upstream remote is configured." 11 | exit 1 12 | fi 13 | 14 | if [ "$(dirname "$0")" = "$GIT_DIR" ]; then 15 | echo >&2 "This script must be run from within a valid Git repository." 16 | exit 1 17 | fi 18 | 19 | if ! git -C "$GIT_DIR" rev-parse; then 20 | echo >&2 "Directory does not appear to be a valid Git repository: $GIT_DIR" 21 | exit 1 22 | fi 23 | 24 | # BRANCH_NAME=$(git branch | grep "\*" | cut -d ' ' -f2) 25 | # if ! git ls-remote "$UPSTREAM_REMOTE" > /dev/null 2>&1; then 26 | # if ! git ls-remote --heads "${UPSTREAM_REMOTE}" "${BRANCH_NAME}" | grep "${BRANCH_NAME}" >/dev/null; then 27 | 28 | ORIGIN_RE=$(echo "${UPSTREAM_REMOTE}" | sed -e 's/\+/\\+/g' -e 's/\-/\\-/g' -e 's/\[/\\[/g' -e 's/\]/\\]/g') 29 | if ! git remote 2>&1 | grep -P "^$ORIGIN_RE"; then 30 | echo >&2 "Working copy doesn't have a remote named '$UPSTREAM_REMOTE'. Aborting." 31 | exit 1 32 | fi 33 | 34 | echo "Fetching from remote '${UPSTREAM_REMOTE}' ..." 35 | if ! git fetch "${UPSTREAM_REMOTE}"; then 36 | echo >&2 "Failed to pull from remote '${UPSTREAM_REMOTE}'." 37 | exit 1 38 | fi 39 | 40 | # Get branch name and make sure it exists on the remote 41 | BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD) 42 | BRANCH_RE=$(echo "${BRANCH_NAME}" | sed -e 's/\+/\\+/g' -e 's/\-/\\-/g' -e 's/\[/\\[/g' -e 's/\]/\\]/g') 43 | if ! git branch -r 2>&1 | grep -P "(\s+)?${ORIGIN_RE}\/${BRANCH_RE}\$"; then 44 | echo >&2 "ERROR: Could not find remote branch: '$UPSTREAM_REMOTE/$BRANCH_NAME'. Aborting." 45 | exit 1 46 | fi 47 | 48 | echo "Attempting a hard reset for branch '${BRANCH_NAME}' in Git directory '$GIT_DIR' ..." 49 | 50 | if ! git reset --hard "${UPSTREAM_REMOTE}/${BRANCH_NAME}"; then 51 | echo >&2 "ERROR: Failed to reset branch to '${UPSTREAM_REMOTE}/${BRANCH_NAME}'" 52 | exit 1 53 | fi 54 | 55 | #if ! git clean -fd; then 56 | # echo >&2 "ERROR: Failed to clean working directory." 57 | # exit 1 58 | #fi 59 | 60 | echo "Finished." 61 | exit 0 62 | -------------------------------------------------------------------------------- /git/git-reset-submodules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Clean and reset all submodules and unversion files 3 | 4 | # To delete all directories: 5 | # git submodule | cut -c43- | while read -r line; do (rm -rf "$line"); done 6 | 7 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 8 | 9 | if ! git -C . rev-parse; then 10 | echo >&2 "Directory does not appear to be a valid Git repository." 11 | exit 1 12 | fi 13 | 14 | if ! git clean -xfd; then 15 | echo >&2 "Failed to clean folder." 16 | exit 1 17 | fi 18 | 19 | if ! git submodule foreach --recursive git clean -xfd; then 20 | echo >&2 "Failed to clean Git submodules." 21 | exit 1 22 | fi 23 | 24 | if ! git reset --hard; then 25 | echo >&2 "Failed to reset Git repository." 26 | exit 1 27 | fi 28 | 29 | if ! git submodule foreach --recursive git reset --hard; then 30 | echo >&2 "Failed to reset Git submodules." 31 | exit 1 32 | fi 33 | 34 | if ! git submodule update --init --recursive; then 35 | echo >&2 "Failed to initialize Git submodules." 36 | exit 1 37 | fi 38 | 39 | exit 0 40 | -------------------------------------------------------------------------------- /git/git-set-fdate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Set file modification times to date of last commit. 3 | 4 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 5 | 6 | if ! git -C . rev-parse; then 7 | echo >&2 "Directory does not appear to be a valid Git repository." 8 | exit 1 9 | fi 10 | 11 | IFS=" 12 | " 13 | for FILE in $(git ls-files) 14 | do 15 | TIME=$(git log --pretty=format:%cd -n 1 --date=iso -- "$FILE") 16 | TIME=$(date -d "$TIME" +%Y%m%d%H%M.%S) 17 | touch -m -t "$TIME" "$FILE" 18 | done 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /git/git-stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Print Git statistics 3 | # 4 | # Some other useful commands: 5 | # 6 | # Per-user line contributions: 7 | # git ls-files | xargs -n1 -d'\n' -i git-blame {} | perl -n -e '/\s\((.*?)\s[0-9]{4}/ && print "$1\n"' | sort -f | uniq -c -w3 | sort -r 8 | # 9 | # Get commit history for local repository: 10 | # git reflog show | grep '}: commit' | nl | sort -nr | nl | sort -nr | cut --fields=1,3 | sed s/commit://g | sed -e 's/HEAD*@{[0-9]*}://g' 11 | # 12 | # List all branches, sorted by date modified: 13 | # for k in `git branch|perl -pe s/^..//`;do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue(%cr%Creset)" $k|head -n 1` : $k;done|sort -r 14 | # 15 | # List all contributors: 16 | # git log --format='%aN' | sort -u 17 | # 18 | 19 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 20 | 21 | if ! git -C . rev-parse; then 22 | echo >&2 "Directory does not appear to be a valid Git repository." 23 | exit 1 24 | fi 25 | 26 | git log --shortstat \ 27 | | grep -E "fil(e|es) changed" \ 28 | | awk '{files+=$1; inserted+=$4; deleted+=$6; delta+=$4-$6; if(inserted>0) { ratio=deleted/inserted } } END {printf "Commit stats:\n- Files changed (total).. %s\n- Lines added (total).... %s\n- Lines deleted (total).. %s\n- Total lines (delta).... %s\n- Add./Del. ratio (1:n).. 1 : %s\n", files, inserted, deleted, delta, ratio }' 29 | 30 | echo 31 | echo "Contributors:" 32 | git shortlog -s -n -e 33 | 34 | exit $? 35 | -------------------------------------------------------------------------------- /git/git-svn-setignored.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set excluded files for git-svn branch 3 | 4 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 5 | 6 | if ! git svn --help > /dev/null 2>&1; then 7 | echo >&2 "git-svn does not appear to be installed. Aborting." 8 | exit 1 9 | fi 10 | 11 | if ! git rev-parse --git-dir > /dev/null 2>&1; then 12 | echo >&2 "Current directory is not a git repository. Aborting." 13 | exit 1 14 | fi 15 | 16 | if ! [ -d .git/svn ]; then 17 | echo >&2 "Current directory does not appear to be a git-svn working copy. Aborting." 18 | exit 1 19 | fi 20 | 21 | # set excluded files for project 22 | echo "Setting excluded files and folders for git-svn project..." 23 | git svn show-ignore > .git/info/exclude 24 | -------------------------------------------------------------------------------- /git/gitattributes.template: -------------------------------------------------------------------------------- 1 | # Git attributes file 2 | # 3 | # For full extended diff support, the following 4 | # commands must be in your PATH: 5 | # - pandoc 6 | # - pdfinfo 7 | # - hexdump 8 | # - odt2txt 9 | # - unzip 10 | # - zcat 11 | # - bzcat 12 | # - xzcat 13 | # - tar 14 | # - exif 15 | # 16 | # To install this template, run: 17 | # 18 | # `cp gitconfig.template ~/.gitconfig` 19 | # `cp gitattributes.template ~/.gitattributes` 20 | # 21 | 22 | ## Extension diff mappings 23 | *.tar diff=tar 24 | *.tar.bz2 diff=tar-bz2 25 | *.tar.gz diff=tar-gz 26 | *.tar.xz diff=tar-xz 27 | *.bz2 diff=bz2 28 | *.gz diff=gz 29 | *.zip diff=zip 30 | *.xz diff=xz 31 | *.odf diff=odf 32 | *.odt diff=odf 33 | *.odp diff=odf 34 | *.pdf diff=pdf 35 | *.exe diff=bin 36 | *.png diff=bin 37 | *.jpg diff=bin 38 | *.dll diff=bin 39 | *.elf diff=bin 40 | *,ko diff=bin 41 | *.o diff=bin 42 | *.o_binary diff=bin 43 | -------------------------------------------------------------------------------- /grep-syslog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # helpful grep command for parsing syslog 3 | 4 | grep -rP "([Ff]ail|[Ee]rror|[Ww]arn)" /var/log/syslog \ 5 | | sed -E "s/\s([A-Za-z0-9]+)\[[0-9]{0,6}\]\:\s/ \1 /g" \ 6 | | cut -d " " -f 4- | sort | uniq \ 7 | | grep -v postfix | grep -v named 8 | -------------------------------------------------------------------------------- /grep-whitespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Finds whitespace in the specified document. 3 | 4 | if [ -z "${1}" ]; then 5 | echo >&2 "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | grep -Pn "^.*([\t|\s|\b]+)$" "${1}" 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /helpers/datetime.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Date/time helpers 3 | 4 | function displaytime() { 5 | local T=$1 6 | local D=$((T/60/60/24)) 7 | local H=$((T/60/60%24)) 8 | local M=$((T/60%60)) 9 | local S=$((T%60)) 10 | (( D > 0 )) && printf '%d days ' $D 11 | (( H > 0 )) && printf '%d hours ' $H 12 | (( M > 0 )) && printf '%d minutes ' $M 13 | (( D > 0 || H > 0 || M > 0 )) && printf 'and ' 14 | printf '%d seconds\n' $S 15 | } 16 | 17 | function countdown() { 18 | start_date=$(($(date +%s) + $1)); 19 | while [ "$start_date" -ge "$(date +%s)" ]; do 20 | echo -ne "$(date -u --date @$((start_date - $(date +%s))) +%H:%M:%S)\r"; 21 | sleep 0.1 22 | done 23 | } 24 | 25 | function stopwatch() { 26 | start_date=$(date +%s); 27 | while true; do 28 | echo -ne "$(date -u --date @$(($(date +%s) - start_date)) +%H:%M:%S)\r"; 29 | sleep 0.1 30 | done 31 | } 32 | -------------------------------------------------------------------------------- /helpers/fs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Date/time helpers 3 | 4 | function formatSizeBc() { 5 | local size="$1" 6 | 7 | if [ -z "$size" ]; then 8 | size=0 9 | fi 10 | 11 | local scale=2 12 | if hash bc 2>/dev/null; then 13 | if [ "$size" -ge 1099511627776 ]; then 14 | size=$(echo "scale=$scale;$size/1099511627776"| bc)" TB" 15 | elif [ "$size" -ge 1073741824 ]; then 16 | size=$(echo "scale=$scale;$size/1073741824"| bc)" GB" 17 | elif [ "$size" -ge 1048576 ]; then 18 | size=$(echo "scale=$scale;$size/1048576" | bc)" MB" 19 | elif [ "$size" -ge 1024 ]; then 20 | size=$(echo "scale=$scale;$size/1024" | bc)" KB" 21 | else 22 | size=$size" B" 23 | fi 24 | else 25 | size=$size" B" 26 | fi 27 | 28 | echo -n "$size" 29 | return 0 30 | } 31 | 32 | function getSizeString() { 33 | if [ -z "$1" ]; then 34 | echo -n "NULL" 35 | return 1 36 | fi 37 | 38 | re='^[0-9]+(\.[0-9]+)?$' 39 | if ! [[ $1 =~ $re ]] ; then 40 | echo -n "NaN" 41 | return 1 42 | fi 43 | 44 | VALUE=$(awk "BEGIN { print int($1) }") 45 | 46 | if [ "$VALUE" -lt 1000 ]; then 47 | echo -n "${VALUE} bytes" 48 | return 0 49 | fi 50 | 51 | echo -n "$VALUE" | awk ' 52 | function human(x) { 53 | if (x<1000) {return x} else {x/=1024} 54 | s="kMGTEPZY"; 55 | while (x>=1000 && length(s)>1) 56 | {x/=1024; s=substr(s,2)} 57 | return sprintf("%.2f", x) " " substr(s,1,1) "B" 58 | # return int(x+0.5) substr(s,1,1) 59 | } 60 | {sub(/^[0-9]+/, human($1)); print}' 61 | 62 | return 0 63 | } 64 | -------------------------------------------------------------------------------- /helpers/net.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Networking helpers 3 | 4 | function valid_url() { 5 | url="$1" 6 | if [ -z "${url}" ]; then 7 | echo >&2 "No URL string was specified." 8 | exit 1 9 | fi 10 | 11 | hash wget 2>/dev/null || { echo >&2 "You need to install wget. Aborting."; exit 1; } 12 | if wget -q "${url}" -O /dev/null; then 13 | return 0 14 | fi 15 | 16 | return 1 17 | } 18 | 19 | # Test an IP address for validity: 20 | # Usage: 21 | # valid_ip IP_ADDRESS 22 | # if [[ $? -eq 0 ]]; then echo good; else echo bad; fi 23 | # OR 24 | # if valid_ip IP_ADDRESS; then echo good; else echo bad; fi 25 | # 26 | function valid_ip() { 27 | local ip=$1 28 | local stat=1 29 | 30 | if [ -z "$ip" ]; then 31 | echo >&2 "ERROR: IP address cannot be null." 32 | return 1 33 | fi 34 | 35 | if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then 36 | IFS="." read -r -a ip <<< "$ip" 37 | [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ 38 | && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] 39 | stat=$? 40 | fi 41 | 42 | return $stat 43 | } 44 | 45 | function valid_hostname() { 46 | local host="$1" 47 | if [ -z "${host}" ]; then 48 | echo >&2 "ERROR Hostname cannot be null." 49 | return 1 50 | fi 51 | 52 | if [[ "$host" =~ ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$ ]]; then 53 | return 0 54 | fi 55 | 56 | return 1 57 | } 58 | 59 | function get_hostname() { 60 | local ip="$1" 61 | if [ -z "$ip" ]; then 62 | echo >&2 "ERROR: IP address cannot be null." 63 | return 1 64 | fi 65 | 66 | hash nslookup 2>/dev/null || { echo >&2 "You need to install dnsutils in order to resolve hostnames. Aborting."; exit 1; } 67 | if ! hostname=$(nslookup "${ip}" | grep -Po '(?<=name\s\=\s).*(?=\.)'); then 68 | return 1 69 | fi 70 | 71 | echo "${hostname}" 72 | return 0 73 | } 74 | -------------------------------------------------------------------------------- /hw-report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # create a report of available hardware 3 | # Only the full path to the report is sent to stdout 4 | # For example, to store it in a variable: 5 | # `REPORT_PATH=$(sudo ./hw-report.sh 2>/dev/null)` 6 | 7 | # check if superuser 8 | #if [[ $EUID -ne 0 ]]; then 9 | # echo "This script must be run as root" >&2 10 | # exit 1 11 | #fi 12 | 13 | OUTPUT="hardware.html" 14 | 15 | if ! RAW=$(sudo lshw -html); then 16 | echo >&2 "ERROR: Failed to generate hardware report." 17 | exit 1 18 | fi 19 | 20 | echo "${RAW}" > "${OUTPUT}" 21 | 22 | echo >&2 "Saved hardware report to $(basename ${OUTPUT})" 23 | readlink -f "${OUTPUT}" 24 | exit 0 25 | -------------------------------------------------------------------------------- /image-cdrom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # creates an image of a CD/DVD disk 3 | # rwb[at]0x19e.net 4 | 5 | # specify the CD/DVD drive 6 | DRIVE=/dev/cdrom 7 | OUTPUT="" 8 | 9 | if [ -n "${1}" ]; then 10 | if [ "${1}" == "-h" ] || [ "${1}" == "--help" ]; then 11 | echo "Usage: $0 [output] [drive]" 12 | exit 1 13 | fi 14 | OUTPUT="${1}" 15 | fi 16 | if [ -n "${2}" ]; then 17 | DRIVE="${2}" 18 | fi 19 | 20 | if [ ! -b "${DRIVE}" ]; then 21 | echo >&2 "ERROR: Optical drive '${DRIVE}' does not exist. Check hardware and drivers for errors." 22 | exit 1 23 | fi 24 | 25 | # check if superuser 26 | if [ $EUID -eq 0 ]; then 27 | echo >&2 "ERROR: This script should not be run as root." 28 | exit 1 29 | fi 30 | 31 | # check if a disk is inserted 32 | if ! blkid "$DRIVE" > /dev/null 2>&1; then 33 | echo >&2 "ERROR: No disk found in $DRIVE" 34 | exit 1 35 | fi 36 | 37 | # get some information about the inserted disk 38 | if ! LABEL=$(blkid "$DRIVE" | sed -n 's/.*LABEL=\"\([^\"]*\)\".*/\1/p' | sed -e 's/ /_/g'); then 39 | echo >&2 "ERROR: Failed to determine label for media in ${DRIVE}" 40 | exit 1 41 | fi 42 | if ! SIZE=$(blockdev --getsize64 "$DRIVE"); then 43 | echo >&2 "ERROR: Failed to determine block size of media in ${DRIVE}" 44 | exit 1 45 | fi 46 | 47 | if [ -z "${OUTPUT}" ]; then 48 | if ! OUTPUT=$(readlink -f "$LABEL".iso); then 49 | echo >&2 "ERROR: Failed to generate output file name." 50 | exit 1 51 | fi 52 | fi 53 | if [ -e "${OUTPUT}" ]; then 54 | echo >&2 "ERROR: File '${OUTPUT}' already exists (will not overwrite)." 55 | exit 1 56 | fi 57 | 58 | # get the size in megabytes 59 | SIZE_IN_MB=$((SIZE/1024/1024)) 60 | 61 | echo "Ripping $LABEL ($SIZE_IN_MB MB) from drive ${DRIVE}" 62 | echo "Writing image to $OUTPUT ..." 63 | 64 | # create an image 65 | if ! dd if="$DRIVE" | pv -brtep -s "$SIZE" | dd of="$OUTPUT"; then 66 | echo >&2 "ERROR: Failed to create image." 67 | if [ -e "${OUTPUT}" ]; then 68 | rm -v "${OUTPUT}" 69 | fi 70 | exit 1 71 | fi 72 | 73 | # eject the disk 74 | echo "Ejecting ${DRIVE} ..." 75 | if ! eject "$DRIVE"; then 76 | echo >&2 "WARNING: Failed to eject ${DRIVE}" 77 | fi 78 | 79 | echo "Image saved to $OUTPUT" 80 | exit 0 81 | -------------------------------------------------------------------------------- /io-mem.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Display IO memory mappings 3 | 4 | if ! IOMEM_RAW=$(sudo cat /proc/iomem); then 5 | echo >&2 "ERROR: Failed to read /proc/iomem" 6 | exit 1 7 | fi 8 | 9 | echo "${IOMEM_RAW}" | while IFS= read -r line; do 10 | pci_addr=$(echo -n "${line}" | grep -Po '(?<=\s\:\s)[0-9]{4}\:[0-9]{2}\:[0-9]{2}\.[0-9]$') 11 | # pre_tabs=$(echo -n "${line}" | grep -Po '^\s+') 12 | if [ -n "${pci_addr}" ]; then 13 | pci_info=$(sudo lspci -v -k -s "${pci_addr}") 14 | pci_desc=$(echo -n "${pci_info}" | head -n 1) 15 | # dev_drvr=$(echo -n "${pci_info}" | grep -Po '(?<=Kernel\sdriver\sin\suse\:\s).*$') 16 | # krnl_drv=$(echo -n "${pci_info}" | grep -Po '(?<=Kernel\smodules\:\s).*$') 17 | echo "${line} (${pci_desc})" 18 | else 19 | echo "${line}" 20 | fi 21 | done 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /iommu-groups.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List assigned IOMMU groups 3 | 4 | LOGFILE=/var/log/kern.log 5 | 6 | #for d in /sys/kernel/iommu_groups/*/devices/*; do 7 | # n=${d#*/iommu_groups/*}; n=${n%%/*} 8 | # printf 'IOMMU Group %s ' "$n" 9 | # lspci -nns "${d##*/}" 10 | #done; 11 | 12 | IOMMU_GROUPS=$(grep iommu "${LOGFILE}" | grep group | awk '{print $14}' | uniq) 13 | 14 | for d in $IOMMU_GROUPS; do 15 | GROUP_DEVS=$(grep iommu "${LOGFILE}" | grep "group $d" | awk '{print $11}' | uniq) 16 | for gd in $GROUP_DEVS; do 17 | DESCR=$(lspci -nn -s "$gd") 18 | echo "group $d device $DESCR" 19 | done 20 | done; 21 | -------------------------------------------------------------------------------- /js-list.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dumps joystick info 3 | 4 | JS_PATH="/dev/input/js*" 5 | 6 | if ls "$JS_PATH" 1> /dev/null 2>&1; then 7 | for js in $JS_PATH; do 8 | echo "$js" 9 | udevadm info "$js" 10 | done 11 | else 12 | echo "No joysticks detected." 13 | fi 14 | 15 | echo 16 | echo "DKMS Modules:" 17 | dkms status 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /kill-defunct.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # script to kil defunct processes 3 | 4 | # NOTE: Need to test the following command against current implementation: 5 | # ps afx | grep defunct -B 1 | grep -Eo "[0-9]{3,}" | xargs kill -9 6 | 7 | # get a list of unique zombie pids 8 | ZOMBIE_PIDS=$(ps --no-headers -A -ostat,ppid | awk '/[zZ]/{print $2}' | sort -n | uniq) 9 | 10 | if [ -z "$ZOMBIE_PIDS" ]; then 11 | echo "No zombie processes detected." 12 | exit 1 13 | fi 14 | 15 | echo "Sending kill signal to zombie PIDs..." 16 | echo "PIDs: $ZOMBIE_PIDS" 17 | 18 | kill "$ZOMBIE_PIDS" 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /last-modified.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List the last modified files in the current directory 3 | 4 | find . -type f -exec stat --format '%Y :%y %n' "{}" \; \ 5 | | sort -nr | cut -d: -f2- | head 6 | 7 | exit 0 8 | -------------------------------------------------------------------------------- /lastlog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List the logs last written to 3 | 4 | LOGGING_PATH=/var/log 5 | RESULT_COUNT=12 6 | 7 | ls -lt ${LOGGING_PATH} | head -n${RESULT_COUNT} 8 | 9 | exit 0 10 | -------------------------------------------------------------------------------- /list-crontabs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # prints all crontabs 3 | # note that crontabs are stored in /var/spool/cron/crontabs 4 | # this just enumerates everything using the crontab command 5 | 6 | if [[ $EUID -ne 0 ]]; then 7 | echo >&2 "This script must be run as root." 8 | exit 1 9 | fi 10 | 11 | # Colors 12 | export ESC_SEQ="\x1b[" 13 | export COL_RESET=$ESC_SEQ"39;49;00m" 14 | export COL_RED=$ESC_SEQ"31;01m" 15 | export COL_GREEN=$ESC_SEQ"32;01m" 16 | export COL_YELLOW=$ESC_SEQ"33;01m" 17 | export COL_BLUE=$ESC_SEQ"34;01m" 18 | export COL_MAGENTA=$ESC_SEQ"35;01m" 19 | export COL_CYAN=$ESC_SEQ"36;01m" 20 | 21 | printf "$COL_RED%.0s-$COL_RESET" {1..30}; echo 22 | cut -f1 -d: /etc/passwd | while read -r user; do 23 | OUT=$( crontab -u "$user" -l 2>/dev/null ) 24 | if [[ $OUT ]]; then 25 | echo -e "$COL_GREEN crontab for $user $COL_RESET" 26 | printf "$COL_RED%.0s-$COL_RESET" {1..30}; echo 27 | echo -e "$COL_CYAN minute (0-59), $COL_RESET" 28 | echo -e "$COL_CYAN | hour (0-23), $COL_RESET" 29 | echo -e "$COL_CYAN | | day of the month (1-31), $COL_RESET" 30 | echo -e "$COL_CYAN | | | month of the year (1-12), $COL_RESET" 31 | echo -e "$COL_CYAN | | | | day of the week (0-6 with 0=Sunday). $COL_RESET" 32 | echo -e "$COL_CYAN | | | | | command(s) $COL_RESET" 33 | echo -e "$COL_CYAN | | | | | | $COL_RESET" 34 | echo "$OUT" | grep -v '^#' | grep -v '^$' 35 | printf "$COL_RED%.0s-$COL_RESET" {1..30}; echo 36 | fi 37 | done 38 | 39 | echo -e "$COL_YELLOW Finished listing crontabs$COL_RESET" 40 | printf "$COL_RED%.0s-$COL_RESET" {1..30}; echo 41 | -------------------------------------------------------------------------------- /list-inodes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # find directories with a lot of inodes 3 | 4 | TOP_COUNT=40 5 | TOP_MSG="top ${TOP_COUNT} by inodes" 6 | INPUT_PATH="." 7 | 8 | if [ -n "$1" ]; then 9 | INPUT_PATH=$(readlink -m "$@") 10 | echo "$TOP_MSG: $INPUT_PATH" 11 | else 12 | INPUT_PATH=$(readlink -m "$INPUT_PATH") 13 | echo "$TOP_MSG" 14 | fi 15 | 16 | find "${INPUT_PATH}" -xdev -printf '%h\n' \ 17 | | sort \ 18 | | uniq -c \ 19 | | sort -k 1 -n -r \ 20 | | head -${TOP_COUNT} 21 | -------------------------------------------------------------------------------- /list-kernels.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # lists all installed kernels 3 | # (aside from the running version) 4 | # can be used to automate removal of old modules 5 | 6 | dpkg -l 'linux-*' | \ 7 | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' 8 | -------------------------------------------------------------------------------- /list-mountpoints.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Lists partitions on the current system 3 | # 4 | # NOTE: To remount a given filesystem, for example to enable RW: 5 | # sudo mount -o remount,rw /partition/identifier /mount/point 6 | 7 | if ! info=$(sudo mount -v | grep "^/" | awk '{print "Partition identifier: " $1 "\n Mountpoint: " $3 "\n"}'); then 8 | echo >&2 "ERROR: Failed to get mountpoint info." 9 | exit 1 10 | fi 11 | 12 | #printf "System mountpoints: \n" 13 | #printf "=================== \n" 14 | 15 | printf "%s\n" "$info" 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /list-vga.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List PCI devices 3 | 4 | # list pci id, class, vendor and device ids 5 | # for device in /sys/bus/pci/devices/*; do echo "$(basename ${device} | cut -c '6-') $(cut -c '3-6' ${device}/class): $(cut -c '3-' ${device}/vendor):$(cut -c '3-' ${device}/device)"; done 6 | 7 | # list vga devices 8 | for I in $(lspci |awk '/VGA/{print $1}');do lspci -v -s "$I"; done 9 | # lspci -v | perl -ne '/VGA/../^$/ and /VGA|Kern/ and print' 10 | -------------------------------------------------------------------------------- /ls-chmod.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # list file and folder permissions 3 | 4 | if [[ -z "$1" ]]; then 5 | ls -lah | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) *2^(8-i));if(k)printf("%0o ",k);print}' 6 | else 7 | ls -lah "$1" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) *2^(8-i));if(k)printf("%0o ",k);print}' 8 | fi 9 | -------------------------------------------------------------------------------- /ls-group.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # list all members of the specified group 3 | 4 | hash awk 2>/dev/null || { echo >&2 "You need to install awk. Aborting."; exit 1; } 5 | 6 | if [[ -z "$1" ]]; then 7 | echo "Usage: $0 " >&2 8 | exit 1 9 | fi 10 | 11 | GROUP_NAME="$1" 12 | 13 | MEMBERS=$(awk -F':' "/^$GROUP_NAME/{print $4}" /etc/group) 14 | 15 | echo "$MEMBERS" 16 | -------------------------------------------------------------------------------- /ls-icon-names.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Outputs a list of icon names 3 | 4 | ICONS_PATH="/usr/share/icons/gnome/32x32/$1" 5 | 6 | if [ ! -e "${ICONS_PATH}" ]; then 7 | echo >&2 "ERROR: The path '${ICONS_PATH}' does not exist." 8 | exit 1 9 | fi 10 | 11 | function getList() 12 | { 13 | find "${ICONS_PATH}" -type f | while read -r f; do 14 | ico=$(basename "$f") 15 | echo "${ico%.*}" 16 | done 17 | } 18 | 19 | NAMES=$(getList) 20 | echo "$NAMES" | sort | uniq 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /ls-open-logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # list open log files 3 | 4 | sudo lsof \ 5 | | grep -P "(\.log|/log/)" \ 6 | | awk '{ if ($NF == "(deleted)") { printf("%s\t%s %s\n",$2,$(NF-1),$NF); } else if ($NF != "(deleted)") { printf("%s\t%s\n",$2,$NF); } }' \ 7 | | sort -u 8 | 9 | exit 0 10 | -------------------------------------------------------------------------------- /ls-usb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # print usb device info 3 | 4 | sudo lsusb -v 2>/dev/null | \ 5 | grep --color=never '^Bus\|iSerial\|idVendor\|idProduct\|bcdDevice\|bcdUSB' 6 | 7 | exit 0 8 | -------------------------------------------------------------------------------- /lstty.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List available serial devices and driver information 3 | 4 | hash grep 2>/dev/null || { echo >&2 "You need to install grep. Aborting."; exit 1; } 5 | hash sort 2>/dev/null || { echo >&2 "You need to install sort. Aborting."; exit 1; } 6 | 7 | function get_devices() { 8 | for f in /sys/class/tty/*/device/driver; do 9 | 10 | driver_dir="$f" 11 | serial_dev=$(echo "$f" | grep -Po '(?<=tty\/)[^\/]+(?=\/device)') 12 | driver_dir=$(readlink -f "$f") 13 | echo -e "$serial_dev \t -> $driver_dir" 14 | 15 | done 16 | } 17 | 18 | OUTPUT=$(get_devices) 19 | 20 | echo "${OUTPUT}" | sort -V 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /md5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -z "$1" ]]; then 4 | echo "Usage: $0 " >&2 5 | exit 1 6 | fi 7 | 8 | echo -n "$1" | md5sum | awk '{print $1}' 9 | -------------------------------------------------------------------------------- /mem-top.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # print top processes by memory usage 3 | 4 | OUTPUT_CN=10 5 | PS_OUTPUT="user,pid,pcpu,pmem,comm" 6 | PS_MEM_CN=4 7 | 8 | # check if an argument was provided 9 | if [ $# -gt 0 ]; then 10 | if [[ "$*" =~ ^-?[0-9]+$ ]]; then 11 | OUTPUT_CN=$* 12 | else 13 | echo >&2 "ERROR: Argument must be a valid number." 14 | exit 1 15 | fi 16 | fi 17 | 18 | # print header 19 | ps -axo ${PS_OUTPUT} | head -n1 20 | 21 | # print output 22 | if ! OUTPUT=$(ps --no-headers -axo ${PS_OUTPUT} | sort -rnk +${PS_MEM_CN}); then 23 | exit 1 24 | fi 25 | 26 | echo "${OUTPUT}" | head -n"${OUTPUT_CN}" 27 | exit 0 28 | -------------------------------------------------------------------------------- /mem-usage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Prints a table of top memory consuming processes 3 | 4 | printf "NPROC\t\t\tUSER\tCPU\tMEM\n" 5 | 6 | ps --no-headers -eo user:20,pcpu,pmem \ 7 | | awk '{num[$1]++; cpu[$1] += $2; mem[$1] += $3} END{for (user in cpu) printf("%d\t%20s\t%.2f\t%.2f\n", num[user], user, cpu[user], mem[user]) }' \ 8 | | sort -k4nr 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /mount-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Mounts an image to the specified mountpoint 3 | 4 | hash mountpoint 2>/dev/null || { echo >&2 "'mountpoint' command not found; you need to install initscripts package. Aborting."; exit 1; } 5 | hash mount 2>/dev/null || { echo >&2 "You need to install 'mount'. Aborting."; exit 1; } 6 | 7 | if [ $# -lt 1 ]; then 8 | echo "Usage: $0 [mountpoint]" 9 | echo "Note: Mountpoint defaults to /mnt if not specified." 10 | exit 1 11 | fi 12 | 13 | IMAGE="$1" 14 | MOUNT_POINT="/mnt" 15 | 16 | MOUNT_RW="false" 17 | MOUNT_OPTS="loop" 18 | 19 | # check if image exists 20 | if [ ! -e "$IMAGE" ]; then 21 | echo >&2 "'$IMAGE' does not exist; aborting." 22 | exit 1 23 | fi 24 | 25 | # verify image is a regular file 26 | if [ ! -f "$IMAGE" ]; then 27 | echo >&2 "'$IMAGE' is not a regular file; aborting." 28 | exit 1 29 | fi 30 | 31 | # test image to ensure it can be mounted 32 | # todo: support additional image types 33 | MOUNT_TYPE="iso9660" 34 | IMAGE_TYPE=$(file -i "$IMAGE" | awk -F" " '{ printf "%s\n", $2 }' | sed 's/application\///g' | sed 's/;//g') 35 | if [ "$IMAGE_TYPE" != "x-iso9660-image" ]; then 36 | echo >&2 "'$IMAGE' is not a valid ISO9660 image file; aborting." 37 | exit 1 38 | fi 39 | 40 | if [ -n "$2" ]; then 41 | # user-specified mountpoint 42 | MOUNT_POINT="$2" 43 | fi 44 | 45 | # check if mountpoint exists 46 | if [ ! -d "$MOUNT_POINT" ]; then 47 | echo >&2 "'$MOUNT_POINT' does not exist; aborting." 48 | exit 1 49 | fi 50 | 51 | # check if mountpoint is in use 52 | if mountpoint -q "$MOUNT_POINT" > /dev/null 2>&1; then 53 | echo >&2 "'$MOUNT_POINT' is already in use; aborting." 54 | exit 1 55 | fi 56 | 57 | # check if mountpoint is empty 58 | if [ -z "$MOUNT_POINT" ]; then 59 | echo >&2 "'$MOUNT_POINT' is not empty; aborting." 60 | exit 1 61 | fi 62 | 63 | # decide whether or not image should be mounted r/o 64 | if [ "$MOUNT_RW" == "true" ]; then 65 | MOUNT_OPTS=$MOUNT_OPTS",rw" 66 | else 67 | MOUNT_OPTS=$MOUNT_OPTS",ro" 68 | fi 69 | 70 | # mount the image 71 | echo "Mounting $IMAGE to $MOUNT_POINT ..." 72 | mount -t $MOUNT_TYPE -o $MOUNT_OPTS "$IMAGE" "$MOUNT_POINT" 73 | 74 | exit $? 75 | -------------------------------------------------------------------------------- /net/arp-scan.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # [0x19e Networks] 4 | # 5 | # arp-scan.sh - scan for hosts using ARP 6 | # author: Robert W. Baumgartner 7 | # 8 | # Perform an arp scan on the primary interface 9 | # 10 | # This script tries to identify the correct interface 11 | # by examining the default route to reach a host 12 | # on the target network. The resolved IP is again 13 | # used to perform a IPv4 route lookup to find the 14 | # interface being used. 15 | # 16 | # There are several ways to identify the target 17 | # interface automatically: 18 | # 19 | # Using 'route': 20 | # route | grep '^default' | grep -o '[^ ]*$' 21 | # 22 | # Using 'ip': 23 | # ip -4 route ls | grep '^default' | grep -Po '(?<=dev )(\S+)' 24 | # 25 | # To resolve the first IP address given a hostname: 26 | # getent ahosts 0x19e.net | awk '{ print $1; exit}' 27 | # 28 | # To get the interface used to contact the outside web: 29 | # ip -4 route get 10.6.6.8 | grep -Po '(?<=dev )(\S+)' 30 | 31 | # make sure required commands are installed 32 | hash grep 2>/dev/null || { echo >&2 "You need to install grep. Aborting."; exit 1; } 33 | hash arp-scan 2>/dev/null || { echo >&2 "You need to install arp-scan. Aborting."; exit 1; } 34 | 35 | # check if superuser 36 | if [[ $EUID -ne 0 ]]; then 37 | echo "This script must be run as root" >&2 38 | exit 1 39 | fi 40 | 41 | # get the interface for scanning 42 | IFACE_HOST="0x19e.net" 43 | IFACE_NAME=$(ip -4 route get "$(getent ahosts $IFACE_HOST | awk '{ print $1; exit}')" | grep -Po '(?<=dev )(\S+)') 44 | 45 | # perform the scan 46 | arp-scan -l --interface "$IFACE_NAME" 47 | 48 | exit 0 49 | -------------------------------------------------------------------------------- /net/arpwatch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Dump entries from local arpwatch database(s) 3 | 4 | ARP_DB="/var/lib/arpwatch/*.dat" 5 | 6 | hash arpwatch 2>/dev/null || { echo >&2 "You need to install arpwatch. Aborting."; exit 1; } 7 | 8 | # check if superuser 9 | if [[ $EUID -ne 0 ]]; then 10 | echo >&2 "ERROR: This script must be run as root." 11 | exit 1 12 | fi 13 | 14 | # check for arpwatch database 15 | if ! ls "${ARP_DB}" 1> /dev/null 2>&1; then 16 | echo >&2 "ERROR: Could not find arpwatch database(s) '${ARP_DB}'." 17 | exit 1 18 | fi 19 | 20 | # Alternate method of checking for database file(s) 21 | #for f in ${ARP_DB}; do 22 | # if [ ! -e "$f" ]; then 23 | # echo >&2 "ERROR: Could not find arpwatch database(s) '${ARP_DB}'." 24 | # exit 1 25 | # fi 26 | # break 27 | #done 28 | 29 | # Get list of IP addresses in arpwatch database 30 | awk -F'\t' '{printf "%-18s %-20s %s\n", $2, $1, $4}' "${ARP_DB}" \ 31 | | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 \ 32 | | uniq 33 | 34 | exit $? 35 | -------------------------------------------------------------------------------- /net/block-ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Blocks an IP address for 2 hours 3 | 4 | hash at 2>/dev/null || { echo >&2 "You need to install at. Aborting."; exit 1; } 5 | hash iptables 2>/dev/null || { echo >&2 "You need to install iptables. Aborting."; exit 1; } 6 | 7 | if [[ -z "$1" ]]; then 8 | echo "Usage: $0 " >&2 9 | exit 1 10 | fi 11 | 12 | # check if superuser 13 | if [[ $EUID -ne 0 ]]; then 14 | echo "This script must be run as root" >&2 15 | exit 1 16 | fi 17 | 18 | # Set the offending IP 19 | REMOTE_IP=$1 20 | 21 | # how many hours the offending IP should be blocked for 22 | BLOCK_TIME_HOURS=2 23 | 24 | # The action to use for the blocking rule 25 | IPTABLES_ACTION="DROP" 26 | 27 | # set the lock file. this file will be removed after the block is lifted. 28 | LOCKDIR=/tmp 29 | LOCKFILE="$LOCKDIR/dos-$REMOTE_IP" 30 | 31 | # Test an IP address for validity: 32 | # Usage: 33 | # valid_ip IP_ADDRESS 34 | # if [[ $? -eq 0 ]]; then echo good; else echo bad; fi 35 | # OR 36 | # if valid_ip IP_ADDRESS; then echo good; else echo bad; fi 37 | # 38 | function valid_ip() 39 | { 40 | local ip=$1 41 | local stat=1 42 | 43 | if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then 44 | OIFS=$IFS 45 | IFS='.' 46 | ip=("$ip") 47 | IFS=$OIFS 48 | [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ 49 | && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] 50 | stat=$? 51 | fi 52 | return $stat 53 | } 54 | 55 | # Add a firewall rule to block offending IP 56 | # Unblock offending IP after 2 hours through the 'at' command (see 'man at' for further details) 57 | # Remove lock file for future checks 58 | 59 | if valid_ip "$REMOTE_IP"; then 60 | $IPTABLES -I INPUT -s "$REMOTE_IP" -j $IPTABLES_ACTION 61 | echo "iptables -D INPUT -s $REMOTE_IP -j $IPTABLES_ACTION" | at now + $BLOCK_TIME_HOURS hours 62 | rm -f "$LOCKFILE" 63 | echo "iptables rule added to $IPTABLES_ACTION $REMOTE_IP for the next $BLOCK_TIME_HOURS hour(s)" 64 | else 65 | echo "Invalid IP: $REMOTE_IP" >&2 66 | exit 1 67 | fi 68 | 69 | exit 0 70 | -------------------------------------------------------------------------------- /net/bus-speed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Test available memory bus bandwidth using netperf 3 | 4 | hash netperf 2>/dev/null || { echo >&2 "You need to install netperf. Aborting."; exit 1; } 5 | 6 | #if ! source "$(dirname "$0")/../helpers/fs.sh"; then 7 | # echo >&2 "ERROR: Failed to load $(dirname "$0")/../helpers/fs.sh" 8 | # exit 1 9 | #fi 10 | 11 | if ! OUTPUT=$(netperf -T0,0 -C -c -P1); then 12 | exit 1 13 | fi 14 | 15 | RESULT=$(echo "${OUTPUT}" | tail -n1) 16 | SPEED=$(echo "${RESULT}" | awk '{ print $5 }') 17 | 18 | echo "${OUTPUT}" 19 | echo 20 | 21 | # Total bandwidth - 10^6bits/s (or 1 Mb/s) 22 | # MBPS=$(awk "BEGIN {print (${SPEED}/8)}") 23 | # echo "Total bandwidth: ${MBPS} MB/s" 24 | 25 | # Convert 10^6bits/s -> bps 26 | BPS=$(awk "BEGIN {print (${SPEED}*125000)}") 27 | # echo "Total bandwidth: $(getSizeString "${BPS}")/s" 28 | 29 | # Gb/s = n/125000000 30 | # GB/s = n/1250000000 31 | 32 | GBPS=$(awk "BEGIN {print (${BPS}/125000000)}") 33 | echo "Total bandwidth: ${GBPS} Gb/s" 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /net/capture-mail.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IFACE="eth0" 4 | 5 | if [ ! -z "${1}" ]; then 6 | IFACE="${1}" 7 | fi 8 | 9 | # sudo tcpdump -nn -l port 25 | grep -Ei 'MAIL FROM\|RCPT TO' 10 | # sudo tcpdump -vv -x -X -s 1500 -i eth1 'port 25' 11 | # sudo tcpdump -w /file/name -s 2000 host example.com and port 25IFACE="eth0" 12 | 13 | if ! sudo tcpdump -i "${IFACE}" -l -A port 25 or port 587 | grep -Ei 'MAIL FROM|RCPT TO'; then 14 | exit 1 15 | fi 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /net/capture-plaintext.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IFACE="eth0" 4 | 5 | if [ ! -z "${1}" ]; then 6 | IFACE="${1}" 7 | fi 8 | 9 | if ! sudo tcpdump -i "${IFACE}" port http or port ftp or port smtp or port imap or port pop3 or port telnet -l -A | grep -Ei -B5 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd=|password=|pass:|user:|username:|password:|login:|pass |user '; then 10 | exit 1 11 | fi 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /net/check-tor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## Check for a working ToR connection 3 | 4 | hash curl 2>/dev/null || { echo >&2 "You need to install curl. Aborting."; exit 1; } 5 | 6 | TEST_URL="https://check.torproject.org" 7 | 8 | if ! RESULT=$(curl -s "${TEST_URL}" | grep -E "Sorry|Congratulations" | head -n1 | sed -e 's/^[ \t]*//'); then 9 | echo >&2 "ERROR: Failed to connect to test server." 10 | exit 1 11 | fi 12 | 13 | # Print the result to stdout 14 | echo "${RESULT}" 15 | 16 | if echo "${RESULT}" | grep -qE "Sorry"; then 17 | # echo >&2 "ERROR: Tor is inactive or not configured correctly." 18 | exit 1 19 | fi 20 | 21 | exit 0 22 | -------------------------------------------------------------------------------- /net/dig-do-transfer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # performs a zone transfer using dig 3 | # lazy; expects command in the format of './dig-do-transfer.sh example.com @8.8.8.8' 4 | 5 | if [[ -z "$1" ]]; then 6 | echo "Usage: $0 [domain] [@local-server]" >&2 7 | exit 1 8 | fi 9 | 10 | dig "$2" "$1" axfr 11 | -------------------------------------------------------------------------------- /net/find-port-name.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #./update-port-list 3 | 4 | if [ -z "$1" ]; then 5 | echo >&2 "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | INC_DESC="false" 10 | PORTS_MAP_FILE="$(dirname "$0")/service-names-port-numbers.csv" 11 | DOWNLOAD_URL="http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.csv" 12 | 13 | hash awk 2>/dev/null || { echo >&2 "You need to install awk. Aborting."; exit 1; } 14 | hash wget 2>/dev/null || { echo >&2 "You need to install wget. Aborting."; exit 1; } 15 | 16 | function download_map() 17 | { 18 | if [ -z "${DOWNLOAD_URL}" ]; then 19 | echo >&2 "ERROR: Download URL is not configured." 20 | exit 1 21 | fi 22 | 23 | if ! wget --quiet -O "${PORTS_MAP_FILE}" "$DOWNLOAD_URL"; then 24 | return 1 25 | fi 26 | 27 | return 0 28 | } 29 | 30 | if [ ! -e "${PORTS_MAP_FILE}" ] || [ ! -s "${PORTS_MAP_FILE}" ]; then 31 | if hash wget 2>/dev/null ; then 32 | if ! download_map; then 33 | echo >&2 "ERROR: Failed to download port map." 34 | exit 1 35 | else 36 | echo "Downloaded missing ports map from ${DOWNLOAD_URL}" 37 | fi 38 | else 39 | echo >&2 "ERROR: Ports database '${PORTS_MAP_FILE}' does not exist." 40 | exit 1 41 | fi 42 | fi 43 | 44 | if [ "$INC_DESC" == "true" ]; then 45 | # Include description 46 | grep -v "IANA assigned" "${PORTS_MAP_FILE}" | grep -P '^[^\s]' | grep ",," \ 47 | | awk -F"," '("$5" != "[John_Fake]") && (length($1) > 0) && (length($2) > 0) && (length($3) > 0) {printf("%-40s %-60s %s/%s\n", $1, substr($4, 1, 55), $2, $3)}' \ 48 | | grep -i -P "(^|\\s)$1(\\s|\/tcp|\/udp|$)?" 49 | else 50 | # Name only 51 | grep -v "IANA assigned" "${PORTS_MAP_FILE}" | grep -P '^[^\s]' | grep ",," \ 52 | | awk -F"," '("$5" != "[John_Fake]") && (length($1) > 0) && (length($2) > 0) && (length($3) > 0) {printf("%-40s %s/%s\n", $1, $2, $3)}' \ 53 | | grep -i -P "(^|\\s)$1(\\s|\/tcp|\/udp|$)?" 54 | fi 55 | 56 | exit 0 57 | -------------------------------------------------------------------------------- /net/flush-iptables.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Resets iptables to default values. 3 | # 4 | 5 | # check if superuser 6 | if [[ $EUID -ne 0 ]]; then 7 | echo "This script must be run as root." >&2 8 | exit 1 9 | fi 10 | 11 | # 12 | # Configurations 13 | # 14 | IPTABLES="/sbin/iptables" 15 | # 16 | # reset the default policies in the filter table. 17 | # 18 | $IPTABLES -P INPUT ACCEPT 19 | $IPTABLES -P FORWARD ACCEPT 20 | $IPTABLES -P OUTPUT ACCEPT 21 | # 22 | # reset the default policies in the nat table. 23 | # 24 | $IPTABLES -t nat -P PREROUTING ACCEPT 25 | $IPTABLES -t nat -P POSTROUTING ACCEPT 26 | $IPTABLES -t nat -P OUTPUT ACCEPT 27 | # 28 | # reset the default policies in the mangle table. 29 | # 30 | $IPTABLES -t mangle -P PREROUTING ACCEPT 31 | $IPTABLES -t mangle -P POSTROUTING ACCEPT 32 | $IPTABLES -t mangle -P INPUT ACCEPT 33 | $IPTABLES -t mangle -P OUTPUT ACCEPT 34 | $IPTABLES -t mangle -P FORWARD ACCEPT 35 | # 36 | # flush all the rules in the filter and nat tables. 37 | # 38 | $IPTABLES -F 39 | $IPTABLES -t nat -F 40 | $IPTABLES -t mangle -F 41 | # 42 | # erase all chains that's not default in filter and nat table. 43 | # 44 | $IPTABLES -X 45 | $IPTABLES -t nat -X 46 | $IPTABLES -t mangle -X 47 | 48 | exit 0 49 | -------------------------------------------------------------------------------- /net/gen-ipv6-ula.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generate a IPv6 Unique Local Address 3 | 4 | r1=$(dd if=/dev/urandom bs=1 count=1 2>/dev/null | hexdump -e '1/1 "%02x"') 5 | r2=$(dd if=/dev/urandom bs=2 count=1 2>/dev/null | hexdump -e '2/1 "%02x"') 6 | r3=$(dd if=/dev/urandom bs=2 count=1 2>/dev/null | hexdump -e '2/1 "%02x"') 7 | 8 | echo "ULA prefix: fd$r1:$r2:$r3::/48" 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /net/get-mac.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Determine Mfg. from MAC OUI 3 | 4 | ouifile="$(dirname "$0")/../oui.txt" 5 | 6 | # Print header 7 | printf "\n MAC address OUI checker \n\n" 8 | 9 | # Error messages 10 | fatal_error() { 11 | printf " Usage: perl %s \n\n", "$0" 12 | 13 | printf " MAC can be submitted as: \n" 14 | printf " 001122334455 \n" 15 | printf " 00:11:22:33:44:55 \n" 16 | printf " 00-11-22-33-44-55 \n" 17 | printf " OUI can be submitted as: \n" 18 | printf " 001122 \n" 19 | printf " 00:11:22 \n" 20 | printf " 00-11-22 \n\n" 21 | 22 | printf " Error: No MAC address or OUI specified or could not recognize it.\n\n"; 23 | 24 | exit 1 25 | } 26 | 27 | # Check if argument has been given 28 | if [ -z "$1" ]; then 29 | fatal_error 30 | fi 31 | 32 | if [ ! -e "${ouifile}" ]; then 33 | echo "ERROR: Cannot access OUI file '${ouifile}'." >&2 34 | exit 1 35 | fi 36 | 37 | # Removing seperators from MAC address and uppercase chars 38 | OUI=$(echo "${1}" | awk '{ print toupper($0) }') 39 | OUI=${OUI//[^0-9A-F]/} 40 | 41 | # Get OUI from MAC 42 | if OUI=$(echo "$OUI" | grep -Eo '^([0-9A-F]{6})'); then 43 | printf " Checking OUI: %s \n", "$OUI"; 44 | else 45 | fatal_error 46 | fi 47 | 48 | if match=$(grep "(base 16)" "${ouifile}" | grep "${OUI}"); then 49 | if company=$(echo "${match}" | grep -Po '(?<=\(base\s16\))(?:\s+)[^$]+' | sed -e 's/^[\s\t\r\n\b]*//' -e 's/[\s\t\r\n\b]*$//'); then 50 | printf " Found OUI: %s - $company \n\n", "$OUI"; 51 | exit 0 52 | fi 53 | fi 54 | 55 | # Show if OUI was not found 56 | printf " Could not find OUI: %s \n\n", "$OUI"; 57 | 58 | exit 1 59 | -------------------------------------------------------------------------------- /net/get-public-ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # get public ip address using ipinfo.io api 3 | 4 | SERVICE_URL="http://ipinfo.io/ip" 5 | # SERVICE_URL="http://ifconfig.me/ip" 6 | 7 | if hash curl 2>/dev/null; then 8 | curl $SERVICE_URL 9 | exit 0 10 | else 11 | if hash wget 2>/dev/null; then 12 | wget -qO- $SERVICE_URL 13 | exit 0 14 | fi 15 | fi 16 | 17 | # another way using just dns: 18 | # dig +short myip.opendns.com @resolver1.opendns.com 19 | 20 | echo >&2 "you must install either curl or wget" 21 | 22 | exit 1 23 | -------------------------------------------------------------------------------- /net/get-wan-ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Output current WAN IP 3 | # wan_iface=$(route -n | grep -P '^0\.0\.0\.0' | awk '{ print $8 }') 4 | 5 | if ! wan_iface=$(route -n | grep -P '^0\.0\.0\.0\s+[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\s+0\.0\.0\.0\s+[UG]{2}' | awk '{ print $8 }' | uniq | head -n1); then 6 | echo >&2 "ERROR: Failed to determine primary interface." 7 | exit 1 8 | fi 9 | if [ -z "${wan_iface}" ]; then 10 | echo >&2 "ERROR: Something went wrong trying to determine primary interface." 11 | exit 1 12 | fi 13 | 14 | err=0 15 | if ! wan_ip=$(ifconfig "${wan_iface}" | grep -Po '(?<=inet\s)[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(?=\s)'); then 16 | err=1 17 | fi 18 | if [ "${err}" -ne 0 ] || [ -z "${wan_ip}" ]; then 19 | if wan_ip=$(ifconfig "${wan_iface}" | grep -Po '(?<=inet\saddr:)[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(?=\s)'); then 20 | err=0 21 | fi 22 | fi 23 | 24 | if [ "${err}" -ne 0 ] || [ -z "${wan_ip}" ]; then 25 | echo >&2 "ERROR: Failed to resolve IP address for interface '${wan_iface}'." 26 | exit 1 27 | fi 28 | 29 | echo "${wan_ip}" 30 | exit 0 31 | -------------------------------------------------------------------------------- /net/grep-allowed-email.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | IP_REGEX='((([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d))' 3 | 4 | if ! grep -qP 'DPT\=(25|587)' /var/log/syslog; then 5 | exit 0 6 | fi 7 | 8 | # print header 9 | printf '=%.0s' {1..50} 10 | printf '\n' 11 | printf "%-16s %s\\n" "IP Address" "Hostname" 12 | printf '=%.0s' {1..50} 13 | printf '\n' 14 | 15 | for ip in $(grep -P 'DPT\=(25|587)' /var/log/syslog | grep -P '(accepted)' | grep -Po "(?<=SRC=)$IP_REGEX(?=\\b)" | sort -n | uniq | sort -n); do 16 | name=$(nslookup "$ip" | awk '/name = / { print $4 }') 17 | printf "%-16s %s\\n" "$ip" "$name" 18 | done 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /net/grep-dropped-email.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | IP_REGEX='((([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d))' 3 | 4 | if ! grep -qP 'DPT\=(25|587)' /var/log/syslog; then 5 | exit 0 6 | fi 7 | 8 | # print header 9 | printf '=%.0s' {1..50} 10 | printf '\n' 11 | printf "%-16s %s\\n" "IP Address" "Hostname" 12 | printf '=%.0s' {1..50} 13 | printf '\n' 14 | 15 | for ip in $(grep -P 'DPT\=(25|587)' /var/log/syslog | grep -P '(dropped)' | grep -Po "(?<=SRC=)$IP_REGEX(?=\\b)" | sort -n | uniq | sort -n); do 16 | name=$(nslookup "$ip" | awk '/name = / { print $4 }') 17 | printf "%-16s %s\\n" "$ip" "$name" 18 | done 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /net/grep-iptables-attackers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Greps dropped packets from a system log 3 | 4 | LOGPATTERN="/var/log/syslog" 5 | 6 | if [ -n "$1" ]; then 7 | if [ ! -e "$1" ]; then 8 | echo >&2 "ERROR: The specified log file '$1' does not exist." 9 | exit 1 10 | fi 11 | LOGPATTERN="$1" 12 | fi 13 | 14 | function grep_table() 15 | { 16 | grep "iptables dropped:" "$LOGPATTERN" | while read -r line; do 17 | src=$(echo "${line}" | grep -Po '(?<=SRC=)([0-9]{1,3}[\.]){3}[0-9]{1,3}(?=\s)') 18 | dpt=$(echo "${line}" | grep -Po '(?<=DPT=)[0-9]+(?=\s)') 19 | proto=$(echo "${line}" | grep -Po '(?<=PROTO=)[A-Za-z]+(?=\s)') 20 | # dst=$(echo "${line}" | grep -Po '(?<=DST=)([0-9]{1,3}[\.]){3}[0-9]{1,3}(?=\s)') 21 | # mac=$(echo "${line}" | grep -Po '(?<=MAC=)([0-9a-fA-F][0-9a-fA-F]:){5,15}([0-9a-fA-F][0-9a-fA-F])(?=\s)') 22 | # inface=$(echo "${line}" | grep -Po '(?<=IN=)[A-Za-z0-9\._-]+(?=\s)') 23 | 24 | printf "%-15s\\t%s/%s\\n" "$src" "$dpt" "$proto" 25 | # printf "%-15s -> %-15s \\t %s/%s\\n" "$src" "$dst" "$dpt" "$proto" 26 | done 27 | } 28 | 29 | function print_report() 30 | { 31 | output=$(grep_table) 32 | echo "${output}" | sort -n \ 33 | | uniq -c \ 34 | | sort -rn \ 35 | | head -n 50 36 | } 37 | 38 | print_report 39 | 40 | exit 0 41 | -------------------------------------------------------------------------------- /net/grep-port-clients.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | LOGFILE="/var/log/syslog" 4 | 5 | IFACE="wan" 6 | # IFACE="fwbr.wan" 7 | 8 | PORT="$1" 9 | if [ -z "${PORT}" ]; then 10 | echo "Usage: $0 [iface]" 11 | exit 1 12 | fi 13 | if [ -n "$2" ]; then 14 | IFACE="$2" 15 | fi 16 | if [ -n "$3" ]; then 17 | LOGFILE="$3" 18 | fi 19 | 20 | if [ ! -e "${LOGFILE}" ]; then 21 | echo >&2 "ERROR: The specified logfile '${LOGFILE}' does not exist." 22 | exit 1 23 | fi 24 | 25 | function get_hostname() 26 | { 27 | local ip="$1" 28 | if [ -z "$ip" ]; then 29 | echo >&2 "ERROR: IP address cannot be null." 30 | exit 1 31 | fi 32 | 33 | if ! hostname=$(nslookup "${ip}" | grep -Po '(?<=name\s\=\s).*(?=\.)'); then 34 | return 1 35 | fi 36 | 37 | echo "${hostname}" 38 | return 0 39 | } 40 | 41 | echo >&2 "Incoming connections to TCP port $PORT on interface '${IFACE}' (logfile: ${LOGFILE}):" 42 | echo >&2 "--" 43 | 44 | # To get the interface: 45 | # grep -Po '(?<=IN\=)[^\s]+(?=\s)' 46 | 47 | IFS=$'\n'; for src in $(grep -ni "DPT=${PORT}" "${LOGFILE}" | grep -P "(?<=IN\\=)([^\\s]+)?${IFACE/\./\\.}([^\\s]+)?(?=\\s)" | grep -Po '(?<=SRC\=)([0-9]+(\.)?){1,4}' | uniq -c | sort -rn); do 48 | count=$(echo "${src}" | awk -F' ' '{ print $1 }') 49 | ip=$(echo "${src}" | awk -F' ' '{ print $2 }') 50 | if [ -n "$ip" ]; then 51 | host=$(get_hostname "$ip") 52 | printf "%s \\t %-20s %s\\n" "$count" "$ip" "$host" 53 | fi 54 | done 55 | 56 | echo >&2 "--" 57 | exit 0 58 | 59 | -------------------------------------------------------------------------------- /net/ip-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # super simple, uses ipinfo.io to get ip details 3 | 4 | if [[ -z "$1" ]]; then 5 | echo "Usage: $0 " >&2 6 | exit 1 7 | fi 8 | 9 | CURL_BIN=$(command -v curl) 10 | REMOTE_IP=$1 11 | 12 | # Test an IP address for validity: 13 | # Usage: 14 | # valid_ip IP_ADDRESS 15 | # if [[ $? -eq 0 ]]; then echo good; else echo bad; fi 16 | # OR 17 | # if valid_ip IP_ADDRESS; then echo good; else echo bad; fi 18 | # 19 | function valid_ip() 20 | { 21 | local ip=$1 22 | local stat=1 23 | 24 | if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then 25 | IFS="." read -r -a ip <<< "$ip" 26 | [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ 27 | && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] 28 | stat=$? 29 | fi 30 | return $stat 31 | } 32 | 33 | if valid_ip "$REMOTE_IP"; then 34 | $CURL_BIN "ipinfo.io/$REMOTE_IP/json" 35 | else 36 | echo "Invalid IP: $REMOTE_IP" 37 | exit 1 38 | fi 39 | 40 | exit 0 41 | -------------------------------------------------------------------------------- /net/isup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # checks if a site is up and available 3 | # by sending an HTTP request using cURL 4 | # 5 | # Example: 6 | # if curl -s --head --request GET https://www.google.com \ 7 | # | grep -Po '^(?:HTTP/[012\.]+\s)[0-9]+\s' \ 8 | # | awk '{ print $2 }' \ 9 | # | grep -Po '^200$' > /dev/null; then 10 | # echo "is up!" 11 | # fi 12 | 13 | TARGET_URL="$1" 14 | if [ -z "${TARGET_URL}" ]; then 15 | echo >&2 "Usage: $0 " 16 | exit 1 17 | fi 18 | 19 | # define the regex used to determine if a site is up 20 | ISUP_REGEX="^200$" 21 | 22 | # configure the request type 23 | CURL_REQUEST="GET" 24 | 25 | # perform the request 26 | RESPONSE=$(curl -s --head --request "${CURL_REQUEST}" "${TARGET_URL}") 27 | RESPONSE_CODE=$(echo -n "${RESPONSE}" | grep -Po '^(?:HTTP/[012\.]+\s)[0-9]+\s' | awk '{ print $2 }') 28 | 29 | echo "Test website : ${TARGET_URL}" 30 | echo "Response code : ${RESPONSE_CODE}" 31 | 32 | if echo "${RESPONSE_CODE}" | grep -Po "${ISUP_REGEX}" > /dev/null; then 33 | echo "${TARGET_URL} is up!" 34 | exit 0 35 | fi 36 | 37 | echo >&2 "${RESPONSE_URL} is down." 38 | exit 1 39 | -------------------------------------------------------------------------------- /net/list-active-connections.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List active network connections 3 | 4 | netstat -an \ 5 | | awk '{print $5}' | grep -v '0.0.0.0:*' \ 6 | | grep -o "[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}" \ 7 | | grep -v "($(for i in $(ip addr | grep inet | grep -P '((eth|br|tap|enp)([0-9]+))' | cut -d/ -f1 | awk '{print $2}'); do echo -n "$i|" | sed 's/\\./\\\\./g;'; done)127\\.|\\0\\.0\\.0)" \ 8 | | sort -n | uniq -c | sort -rn 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /net/list-dhcp-leases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DHCPD_LEASES="/var/lib/dhcp/dhcpd.leases" 4 | 5 | if [ ! -e "${DHCPD_LEASES}" ]; then 6 | echo >&2 "ERROR: DHCP daemon leases cache file '${DHCPD_LEASES}' does not exist." 7 | exit 1 8 | fi 9 | 10 | cat "${DHCPD_LEASES}" 11 | 12 | exit 0 13 | -------------------------------------------------------------------------------- /net/list-nics.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List Network Interface Device(s) excluding 'lo' and 'vif.*' interfaces 3 | 4 | # Set the path to the network device file 5 | DEV_FILE="/proc/net/dev" 6 | 7 | # Define a RegEx to filter output NICs 8 | # DEV_FILTER="(lo|vif)" 9 | DEV_FILTER="(lo)" 10 | 11 | # Define a RegEx to filter output NICs 12 | DEV_SELECT="" 13 | if [ -n "$1" ]; then 14 | DEV_SELECT="$1" 15 | fi 16 | 17 | if [ ! -e "${DEV_FILE}" ]; then 18 | echo >&2 "ERROR: File does not exist: ${DEV_FILE}" 19 | exit 1 20 | fi 21 | 22 | if ! NICS=$(tail -n+3 "${DEV_FILE}" \ 23 | | awk -F: '{ print $1 }' \ 24 | | tr -d ' ' \ 25 | | sort -h \ 26 | | uniq \ 27 | | grep -vE "${DEV_FILTER}"); then 28 | echo >&2 "ERROR: Failed to determine local Network Interface Card(s) (NICs)." 29 | exit 1 30 | fi 31 | 32 | function list_nics() { 33 | local filter req_state dev_up dev_path 34 | if [ -e "$1" ] && [ "$1" != "*" ]; then 35 | filter=1 36 | req_state="$1" 37 | fi 38 | 39 | echo "${NICS}" | while read -r dev; do 40 | dev_path="/sys/class/net/${dev}/operstate" 41 | if [ ! -e "${dev_path}" ]; then 42 | echo >&2 "ERROR: Device file not found: ${dev_path}" 43 | exit 1 44 | fi 45 | 46 | dev_up=0 47 | dev_state=$(cat "${dev_path}") 48 | case "${dev_state}" in 49 | down) 50 | dev_up=1 51 | shift 52 | ;; 53 | up) 54 | dev_up=0 55 | shift 56 | ;; 57 | unknown) 58 | dev_up=-1 59 | shift 60 | ;; 61 | *) 62 | # unknown state 63 | echo >&2 "ERROR: Device '${dev}' state '${dev_state}' is not supported." 64 | dev_up=-2 65 | exit 1 66 | ;; 67 | esac 68 | 69 | if [[ ${filter} -ne 1 ]] || [ ${dev_up} -eq "${req_state}" ]; then 70 | printf "$COL_RESET%-24s : %s\n" "${dev}" "${dev_state}" 71 | fi 72 | done 73 | 74 | return 0 75 | } 76 | 77 | if [ -n "${DEV_SELECT}" ]; then 78 | if ! list_nics "*" | sort -t: -k2 | grep -Ei "${DEV_SELECT}"; then 79 | exit 1 80 | fi 81 | else 82 | if ! list_nics "*" | sort -t: -k2; then 83 | exit 1 84 | fi 85 | fi 86 | 87 | exit 0 88 | -------------------------------------------------------------------------------- /net/net-graph.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # create ascii graph of active tcp network connections 3 | # rwb[at]0x19e[dot]net 4 | 5 | netstat -ant \ 6 | | grep ESTABLISHED \ 7 | | awk '{print $5}' \ 8 | | awk -F: '{print $1}' \ 9 | | sort \ 10 | | uniq -c \ 11 | | awk '{ printf("%s\t%s\t",$2,$1) ; for (i = 0; i < $1; i++) {printf("*")}; print "" }' 12 | -------------------------------------------------------------------------------- /net/netperf-mst.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Run a netperf test using multiple streams 3 | 4 | hash netperf 2>/dev/null || { echo >&2 "You need to install netperf. Aborting."; exit 1; } 5 | 6 | NUMBER=8 7 | TMPFILE=$(mktemp) 8 | PORT=12865 9 | DURATION=10 10 | 11 | if [ -z "$1" ]; then 12 | echo >&2 "Usage: $0 "; exit 1; 13 | fi 14 | PEER="$1" 15 | 16 | # echo "Writing to file $TMPFILE ..." 17 | 18 | for i in $(seq $NUMBER); do 19 | echo "Starting netperf stream: $i" 20 | nohup netperf -H "$PEER" -p $PORT -t TCP_MAERTS -P 0 -c -l $DURATION -- -m 32K -M 32K -s 256K -S 256K >> "$TMPFILE" & 21 | nohup netperf -H "$PEER" -p $PORT -t TCP_STREAM -P 0 -c -l $DURATION -- -m 32K -M 32K -s 256K -S 256K >> "$TMPFILE" & 22 | done 23 | 24 | if ! wait; then 25 | echo >&2 "ERROR: Failed." 26 | killall netperf 27 | exit 1 28 | fi 29 | 30 | echo "Finished." 31 | echo 32 | 33 | echo "Total result: $(awk '{sum += $5} END{print sum}' "$TMPFILE") Mb/s" 34 | rm "$TMPFILE" 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /net/nic-balance.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Manually balance interrupts 3 | 4 | if [ -z "$1" ] || [ -z "$2" ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | cpu=0 10 | grep "$1" /proc/interrupts | awk '{ print $1 }' | sed 's/://' | while read -r a; do 11 | echo $cpu > "/proc/irq/$a/smp_affinity_list" 12 | echo "echo $cpu > /proc/irq/$a/smp_affinity_list" 13 | if [ $cpu = "$2" ]; then 14 | cpu=0 15 | fi 16 | let cpu=cpu+1 17 | done 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /net/pkt-capture.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # invokes tcpdump on the specified interface 3 | # rwb[at]0x19e[dot]net 4 | 5 | hash tcpdump 2>/dev/null || { echo >&2 "You need to install tcpdump. Aborting."; exit 1; } 6 | 7 | # Specify capture options 8 | # -i : Specify the interface(s) to capture from, eg. -i eth0 9 | # -e : Get ethernet header as well 10 | # -n : Do not resolve hostnames 11 | # -nn : Do not resolve hostnames OR ports 12 | # -s0 : Snap length - 0=unlimited 13 | # -S : Print absolute sequence numbers 14 | # -X : Include both hex AND ascii output 15 | # -XX : Same as -X but includes ethernet header 16 | # -v : Increase packet detail - can be -v, -vv or -vvv 17 | # -w : Write output to file - eg, -w file.pcap 18 | # 19 | # OPTS="-nnXSs 1514" 20 | # OPTS="-nnvvvXSs 1514" 21 | OPTS="-nnvvveXXSs0" 22 | 23 | if [[ -z "$1" ]]; then 24 | echo "Usage: $0 [file]" 25 | exit 1 26 | fi 27 | 28 | if [[ -z "$2" ]]; then 29 | OUTPUT="${1}-$(date '+%Y%m%d%H%M%S').pcap" 30 | else 31 | OUTPUT="$2" 32 | fi 33 | 34 | echo "Capturing $1 to '$OUTPUT' ..." 35 | echo "Using options: ${OPTS}" 36 | 37 | if ! tcpdump "$OPTS" -w "$OUTPUT" -i "$1"; then 38 | exit 1 39 | fi 40 | 41 | exit 0 42 | -------------------------------------------------------------------------------- /net/port-listeners.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # prints a list of processes listening on the specified port 3 | 4 | # get the port number 5 | port=$1 6 | 7 | # configure headers 8 | no_headers=0 9 | 10 | # check for required arguments 11 | if [[ -z "$1" ]]; then 12 | echo "Usage: $0 " >&2 13 | exit 1 14 | fi 15 | 16 | # check if superuser 17 | if [[ $EUID -ne 0 ]]; then 18 | echo "This script must be run as root." >&2 19 | exit 1 20 | fi 21 | 22 | # validate port number 23 | re='^[0-9]+$' 24 | if ! [[ $port =~ $re ]] ; then 25 | echo >&2 "ERROR: '$port' is not a valid port number." 26 | exit 1 27 | fi 28 | 29 | # note: lsof requires root to identify procs 30 | pid=$(lsof -Pan -i tcp -i udp | grep ":$port"|tr -s " " | cut -d" " -f2) 31 | if [[ -z "$pid" ]]; then 32 | echo >&2 "No processes found listening on port $port." 33 | exit 1 34 | fi 35 | 36 | if [ "${no_headers}" -eq 1 ]; then 37 | ps -o user,pid,command --sort=pid --pid "${pid//$'\n'/ }" --no-headers 38 | else 39 | ps -o user,pid,command --sort=pid --pid "${pid//$'\n'/ }" 40 | fi 41 | 42 | exit 0 43 | -------------------------------------------------------------------------------- /net/show-listeners.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # list all active listeners 3 | # rwb[at]0x19e[dot]net 4 | 5 | if [ -z "${NO_HEADER}" ]; then 6 | NO_HEADER=1 7 | fi 8 | 9 | hash awk 2>/dev/null || { echo >&2 "You need to install awk. Aborting."; exit 1; } 10 | 11 | # check if superuser 12 | if [[ $EUID -ne 0 ]]; then 13 | echo "This script must be run as root." >&2 14 | exit 1 15 | fi 16 | 17 | function get_lsof_output() 18 | { 19 | # get all running listeners 20 | listeners="$(lsof -Pan -i tcp -i udp | grep LISTEN | awk '{print $2,$9}')" 21 | if [ -z "${listeners}" ]; then 22 | return 1 23 | fi 24 | 25 | # loop through each entry and print out relavent info 26 | IFS=$'\n'; for line in $listeners; do 27 | pid=$(echo "$line" | awk '{print $1}') 28 | con=$(echo "$line" | awk '{print $2}') 29 | cmd=$(ps -p "$pid" -o args --no-headers) 30 | out=$(printf "%-30s %-10s %s\\n" "$con" "$pid" "$cmd" | sed '/^\s*$/d') 31 | if [ -n "$out" ]; then 32 | echo "$out" 33 | fi 34 | done 35 | 36 | return 0 37 | } 38 | 39 | OUTPUT=$(get_lsof_output) 40 | 41 | # print header 42 | if [ "${NO_HEADER}" != 1 ]; then 43 | printf "%-30s %-10s %s\\n" "CONNECTION" "PID" "COMMAND" 44 | # printf "=%.0s" {1..90}; printf "\\n" 45 | fi 46 | 47 | echo "${OUTPUT}" | LC_ALL=C sort -t: -k2n | uniq 48 | 49 | exit 0 50 | -------------------------------------------------------------------------------- /net/show_irq_affinity.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Copyright (c) 2017 Mellanox Technologies. All rights reserved. 4 | # 5 | # This Software is licensed under one of the following licenses: 6 | # 7 | # 1) under the terms of the "Common Public License 1.0" a copy of which is 8 | # available from the Open Source Initiative, see 9 | # http://www.opensource.org/licenses/cpl.php. 10 | # 11 | # 2) under the terms of the "The BSD License" a copy of which is 12 | # available from the Open Source Initiative, see 13 | # http://www.opensource.org/licenses/bsd-license.php. 14 | # 15 | # 3) under the terms of the "GNU General Public License (GPL) Version 2" a 16 | # copy of which is available from the Open Source Initiative, see 17 | # http://www.opensource.org/licenses/gpl-license.php. 18 | # 19 | # Licensee has the right to choose one of the above licenses. 20 | # 21 | # Redistributions of source code must retain the above copyright 22 | # notice and one of the license notices. 23 | # 24 | # Redistributions in binary form must reproduce both the above copyright 25 | # notice, one of the license notices in the documentation 26 | # and/or other materials provided with the distribution. 27 | # 28 | if [ -z "$1" ]; then 29 | echo "usage: $0 " 30 | exit 1 31 | fi 32 | # shellcheck source=/dev/null 33 | source "$(dirname "$0")/common_irq_affinity.sh" 34 | 35 | IRQS=$( get_irq_list "$1" ) 36 | if [ -z "$IRQS" ] ; then 37 | echo "No IRQs found for $1." 38 | exit 1 39 | fi 40 | 41 | for irq in $IRQS 42 | do 43 | show_irq_affinity "$irq" 44 | done 45 | 46 | -------------------------------------------------------------------------------- /net/show_irq_affinity_hints.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Copyright (c) 2017 Mellanox Technologies. All rights reserved. 4 | # 5 | # This Software is licensed under one of the following licenses: 6 | # 7 | # 1) under the terms of the "Common Public License 1.0" a copy of which is 8 | # available from the Open Source Initiative, see 9 | # http://www.opensource.org/licenses/cpl.php. 10 | # 11 | # 2) under the terms of the "The BSD License" a copy of which is 12 | # available from the Open Source Initiative, see 13 | # http://www.opensource.org/licenses/bsd-license.php. 14 | # 15 | # 3) under the terms of the "GNU General Public License (GPL) Version 2" a 16 | # copy of which is available from the Open Source Initiative, see 17 | # http://www.opensource.org/licenses/gpl-license.php. 18 | # 19 | # Licensee has the right to choose one of the above licenses. 20 | # 21 | # Redistributions of source code must retain the above copyright 22 | # notice and one of the license notices. 23 | # 24 | # Redistributions in binary form must reproduce both the above copyright 25 | # notice, one of the license notices in the documentation 26 | # and/or other materials provided with the distribution. 27 | # 28 | if [ -z "$1" ]; then 29 | echo "usage: $0 " 30 | exit 1 31 | fi 32 | 33 | # shellcheck source=/dev/null 34 | source $(dirname "$0")/common_irq_affinity.sh 35 | 36 | IRQS=$( get_irq_list "$1" ) 37 | if [ -z "$IRQS" ] ; then 38 | echo "No IRQs found for $1." 39 | exit 1 40 | fi 41 | 42 | for irq in $IRQS 43 | do 44 | show_irq_affinity_hints "$irq" 45 | done 46 | 47 | -------------------------------------------------------------------------------- /net/ssh-speed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # script to test speed of ssh connection 3 | 4 | hash ssh 2>/dev/null || { echo >&2 "You need to install SSH. Aborting."; exit 1; } 5 | hash pv 2>/dev/null || { echo >&2 "You need to install the Pipe Viewer ('pv') utility. Aborting."; exit 1; } 6 | 7 | if [[ -z "$1" ]]; then 8 | echo "Usage: $0 " 9 | exit 1 10 | fi 11 | 12 | # note: compression is enabled using -C 13 | # yes | pv | ssh -C "$1" "cat > /dev/null" 14 | 15 | dd if=/dev/zero bs=4096 count=1048576 | pv -paes 4g | ssh "$1" 'cat > /dev/null' 16 | -------------------------------------------------------------------------------- /net/update-ethercodes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # update-ethercodes.sh 3 | # This script downloads the currect mac address data from the IEEE and parses it for nmap and arpwatch. 4 | # nmap-mac-prefixes is for nmap. 5 | # ethercodes.dat is arpwatch. 6 | 7 | # Download the current data 8 | 9 | wget -N http://standards.ieee.org/regauth/oui/oui.txt 10 | 11 | # Divide the data into Manufacturer and Address files 12 | grep '(base 16)' oui.txt | cut -f3 > mac.manufacturer 13 | grep '(base 16)' oui.txt | cut -f1 -d' ' > mac.address 14 | 15 | # Paste them back together for nmap data 16 | #paste mac.address mac.manufacturer > nmap-mac-prefixes 17 | 18 | # Parse the address data for arpwatch 19 | perl -pe 's/^(([^0].)|0(.))(([^0].)|0(.))(([^0].)|0(.))/\2\3:\5\6:\8\9/' mac.address > tmp.address 20 | tr '[:upper:]' '[:lower:]' < tmp.address > mac.address 21 | 22 | # Paste the parsed data into the arpwatch file 23 | paste mac.address mac.manufacturer > ethercodes.dat 24 | 25 | # Clean up intermediary files 26 | rm tmp.address 27 | rm mac.address 28 | rm mac.manufacturer 29 | 30 | # rm oui.txt 31 | -------------------------------------------------------------------------------- /net/update-port-list.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # downloads the IANA ports list 3 | 4 | hash wget 2>/dev/null || { echo >&2 "You need to install wget. Aborting."; exit 1; } 5 | 6 | DOWNLOAD_URL=http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.csv 7 | # DOWNLOAD_URL=http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt 8 | 9 | if ! wget "$DOWNLOAD_URL"; then 10 | exit 1 11 | fi 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /openwrt/set-ipv6-ula.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | [ "$(uci -q get network.globals.ula_prefix)" != "auto" ] && echo >&2 "ula_prefix is not set to auto." && exit 0 4 | 5 | r1=$(dd if=/dev/urandom bs=1 count=1 2>/dev/null | hexdump -e '1/1 "%02x"') 6 | r2=$(dd if=/dev/urandom bs=2 count=1 2>/dev/null | hexdump -e '2/1 "%02x"') 7 | r3=$(dd if=/dev/urandom bs=2 count=1 2>/dev/null | hexdump -e '2/1 "%02x"') 8 | 9 | echo "New ULA prefix: fd$r1:$r2:$r3::/48" 10 | 11 | uci -q batch <<-EOF >/dev/null 12 | set network.globals.ula_prefix=fd$r1:$r2:$r3::/48 13 | commit network 14 | EOF 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /openwrt/upgrade-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Upgrade all packages 3 | 4 | hash opkg 2>/dev/null || { echo >&2 "Could not find opkg command in PATH. Aborting."; exit 1; } 5 | 6 | if ! PKG_LIST=$(opkg list-upgradable | cut -f 1 -d ' '); then 7 | echo >&2 "The list-upgradable command returned a non-zero exit code. Aborting..." 8 | exit 1 9 | fi 10 | 11 | if [ -z "${PKG_LIST}" ]; then 12 | echo "No packages to upgrade." 13 | exit 0 14 | fi 15 | 16 | if ! echo "${PKG_LIST}" | xargs opkg upgrade; then 17 | exit 1 18 | fi 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /perf-report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Records performance data and displays a report 3 | 4 | REC_SECONDS=4 5 | USE_SPINNER=0 6 | 7 | hash perf 2>/dev/null || { echo >&2 "The perf command is missing; you need to install linux-tools-common and/or linux-tools-generic. Aborting."; exit 1; } 8 | hash sudo 2>/dev/null || { echo >&2 "You need to install sudo. Aborting."; exit 1; } 9 | 10 | if [[ ${USE_SPINNER} -eq 1 ]] && [ ! -e "$(dirname "$0")/helpers/spinner.sh" ]; then 11 | echo >&2 "WARNING: Cannot find spinner source file: ./helpers/spinner.sh" 12 | USE_SPINNER=0 13 | fi 14 | 15 | if [[ ${USE_SPINNER} -eq 1 ]]; then 16 | # shellcheck source=/dev/null 17 | if ! source "$(dirname "$0")/helpers/spinner.sh"; then 18 | echo >&2 "WARNING: Failed to include spinner source file: ./helpers/spinner.sh" 19 | USE_SPINNER=0 20 | fi 21 | fi 22 | 23 | if [[ $EUID -ne 0 ]]; then 24 | echo >&2 "User is not root; checking sudo privileges for current user $USER ..." 25 | if ! sudo echo "" > /dev/null 2>&1; then 26 | echo >&2 "ERROR: User $USER does not have or failed to authenticate for sudo privileges." 27 | exit 1 28 | fi 29 | fi 30 | 31 | OWNS_DATA=0 32 | if [ ! -e "./perf.data" ]; then 33 | OWNS_DATA=1 34 | fi 35 | 36 | if [[ ${USE_SPINNER} -eq 1 ]]; then 37 | start_spinner "Recording performance data for ${REC_SECONDS} seconds ..." 38 | else 39 | echo -n "Recording performance data for ${REC_SECONDS} seconds ... " 40 | fi 41 | 42 | if ! sudo perf record -g -a sleep ${REC_SECONDS} > /dev/null 2>&1; then 43 | if [[ ${USE_SPINNER} -eq 1 ]]; then stop_spinner 1; else echo "done."; fi 44 | echo >&2 "ERROR: Failed to record performance data." 45 | exit 1 46 | fi 47 | if [[ ${USE_SPINNER} -eq 1 ]]; then stop_spinner 0; else echo "done."; fi 48 | 49 | echo -n "Displaying report... " 50 | if ! sudo perf report; then 51 | echo "error!" 52 | echo >&2 "ERROR: Failed to display report." 53 | exit 1 54 | fi 55 | 56 | # Delete perf.data file 57 | if [[ ${OWNS_DATA} -eq 1 ]]; then 58 | if [ -e "./perf.data" ]; then 59 | sudo rm ./perf.data 60 | fi 61 | fi 62 | 63 | echo "finished." 64 | 65 | exit 0 66 | -------------------------------------------------------------------------------- /permissions-backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # creates a backup of all file and folder ownership and permissions 3 | # output is stored in the format 'user:group chmod path' 4 | 5 | # check if superuser 6 | if [[ $EUID -ne 0 ]]; then 7 | echo >&2 "This script must be run as root." 8 | exit 1 9 | fi 10 | 11 | TODAY=$(date +"%Y-%m-%d") 12 | 13 | find / -name '*' -printf '%u:%g %m %p\n' > "permissions-backup-${TODAY}.txt" 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /pi-bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # a simple cpu benchmark using PI calculation 3 | 4 | CPU="${1:-1}"; 5 | SCALE="${2:-5000}"; 6 | 7 | hash bc 2>/dev/null || { echo >&2 "You need to install bc. Aborting."; exit 1; } 8 | 9 | echo "Cores: $CPU"; echo "Digit: $SCALE" ; 10 | for i in $(seq 1 "$CPU"); do 11 | echo "Starting working on CPU $i ..." 12 | time echo "scale=${SCALE}; 4*a(1)" | bc -l -q | grep -v ^"[0-9]" 13 | done 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /pid-clock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Watches a running process until it completes 3 | 4 | # Here's the one-liner this script is created from: 5 | # PID=0; SP='\|/-'; i=1; while `ps -p $PID > /dev/null`; do PROC_TIME=$(ps -p $PID -o etime= | awk '{ print $1 }'); printf "\n"; printf "\b\r[${SP:i++%${#SP}:1}] PID $PID is running ($PROC_TIME)"; sleep 1; done; 6 | 7 | # check if an argument was provided 8 | if [ $# -gt 0 ]; then 9 | if [[ "$*" =~ ^-?[0-9]+$ ]]; then 10 | PID=$* 11 | else 12 | echo >&2 "ERROR: Argument must be a valid number." 13 | exit 1 14 | fi 15 | fi 16 | 17 | if [ -z "$PID" ]; then 18 | echo >&2 "Usage: $0 " 19 | exit 1 20 | fi 21 | 22 | # check if pid is running 23 | if ! ps -p "$PID" > /dev/null; then 24 | echo "The specified PID is not valid." 25 | exit 1 26 | fi 27 | 28 | SP='\|/-'; 29 | while ps -p "$PID" > /dev/null; do 30 | PROC_TIME=$(ps -p "$PID" -o etime= | awk '{ print $1 }'); 31 | printf "\b\r[%s] PID %s is running (%s)", "${SP:i++%${#SP}:1}", "$PID", "$PROC_TIME"; 32 | sleep 1; 33 | done; 34 | 35 | printf "\b\rPID %s has exited after %s\n", "$PID", "$PROC_TIME"; 36 | 37 | exit 0 38 | -------------------------------------------------------------------------------- /print-active.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Print a file excluding comments 3 | 4 | if [[ -z "$1" ]]; then 5 | echo "Usage: $0 " >&2 6 | exit 1 7 | fi 8 | 9 | # check valid file 10 | if [ ! -f "$1" ]; then 11 | echo "File does not exist: $1" >&2 12 | exit 1 13 | fi 14 | 15 | grep -v '^$\|^\s*\#' "$1" 16 | -------------------------------------------------------------------------------- /print-cmd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # print the full command line of the specified process by pid 3 | 4 | PID=$1 5 | 6 | if [ -z "$PID" ]; then 7 | echo >&2 "Must specify a valid process ID (PID) to read the command from." 8 | exit 1 9 | fi 10 | 11 | # check to make sure value is a valid port 12 | re='^[0-9]+$' 13 | if ! [[ $PID =~ $re ]] ; then 14 | echo >&2 "ERROR: '$PID' is not a valid PID." 15 | exit 1 16 | fi 17 | 18 | # valid PIDs start at one 19 | if [ "$PID" -lt 1 ]; then 20 | echo >&2 "ERROR: '$PID' is less than 1 and is not a valid PID." 21 | exit 1 22 | fi 23 | 24 | # print the full command line of the specified process 25 | ps --no-headers -up "$PID" | awk '{ s = ""; for (i = 11; i <= NF; i++) s = s $i " "; print s }' 26 | 27 | exit 0 28 | -------------------------------------------------------------------------------- /ps-chroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # list processes running inside of schroot jails 3 | # this script will enumerate all of the installed 4 | # schroots, and then check the mount point to see 5 | # if it's jailed. 6 | 7 | # check if superuser 8 | if [[ $EUID -ne 0 ]]; then 9 | echo >&2 "This script must be run as root." 10 | exit 1 11 | fi 12 | 13 | # the mountpoint used by schroot 14 | # this is used to determine which procs are jailed so it must be correct! 15 | MOUNTPOINTS=("/var/lib/schroot/mount" "/var/chroot") 16 | 17 | for chroot in $(schroot -l|awk -F : '{print $2}'); do 18 | PROCS="" 19 | for p in $(ps -o pid -A); do 20 | LINK=$(readlink "/proc/$p/root") 21 | for mp in "${MOUNTPOINTS[@]}"; do 22 | if [[ $LINK == "$mp/$chroot"* ]]; then 23 | PROCS="$PROCS $p" 24 | fi 25 | done 26 | done 27 | echo "Jailed in \"$chroot\": $PROCS" 28 | done 29 | -------------------------------------------------------------------------------- /ps-ctxt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Process context switching 3 | 4 | hash pidstat 2>/dev/null || { echo >&2 "You need to install sysstat. Aborting."; exit 1; } 5 | hash grep 2>/dev/null || { echo >&2 "You need to install grep. Aborting."; exit 1; } 6 | hash awk 2>/dev/null || { echo >&2 "You need to install gawk. Aborting."; exit 1; } 7 | 8 | pidstat -w 2 1 | grep Average | grep -v pidstat \ 9 | | sort -r -n -k4 \ 10 | | head -n 20 \ 11 | | awk '{ if ($3 != "PID") printf("PID:%-8s%-12scswch/s\t%-12snvcswch/s\t%s\n", $3, $4, $5, $6) }' 12 | 13 | exit $? 14 | -------------------------------------------------------------------------------- /ps-tree.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Display a scrollable process tree 3 | 4 | ps awwfux | less -S 5 | 6 | exit 0 7 | -------------------------------------------------------------------------------- /pull-pastebin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Gets a raw paste from PasteBin 3 | 4 | # check if curl command exists 5 | hash curl 2>/dev/null || { echo >&2 "You need to install curl. Aborting."; exit 1; } 6 | 7 | if [[ -z "$1" ]]; then 8 | echo "Usage: $0 " >&2 9 | exit 1 10 | fi 11 | 12 | # TODO: Validate paste id using regex 13 | PASTE_ID=$(echo "$1" | tr -d "[:cntrl:][:punct:][:space:]") 14 | if [[ -z "$PASTE_ID" ]]; then 15 | echo "Fatal: Filtered paste id is null." >&2 16 | exit 1 17 | fi 18 | 19 | # load the raw paste 20 | RAW_PASTE=$(curl -Ls "http://pastebin.com/raw.php?i=$PASTE_ID") 21 | 22 | echo -e "$RAW_PASTE" 23 | -------------------------------------------------------------------------------- /reboot-required.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # checks if the system is pending a reboot 3 | 4 | if [ ! -e /etc/apt/apt.conf.d/50unattended-upgrades ]; then 5 | echo >&2 "This script depends on the 'unattended-upgrades' package." 6 | exit 1 7 | fi 8 | 9 | if [ -f /var/run/reboot-required ]; then 10 | cat /var/run/reboot-required 11 | exit 0 12 | fi 13 | 14 | exit 1 15 | -------------------------------------------------------------------------------- /reset-usb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $EUID != 0 ]] ; then 4 | echo This must be run as root! 5 | exit 1 6 | fi 7 | 8 | for xhci in /sys/bus/pci/drivers/?hci_hcd ; do 9 | 10 | if ! cd "$xhci" ; then 11 | echo "Weird error. Failed to change directory to $xhci" 12 | exit 1 13 | fi 14 | 15 | echo "Resetting devices from $xhci..." 16 | 17 | for i in ????:??:??.? ; do 18 | echo -n "$i" > unbind 19 | echo -n "$i" > bind 20 | done 21 | done 22 | -------------------------------------------------------------------------------- /rngtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # tests the random pool 3 | 4 | hash rngtest 2>/dev/null || { echo >&2 "You need to install rng-tools. Aborting."; exit 1; } 5 | 6 | RND_SOURCE="/dev/urandom" 7 | TEST_COUNT=1000 8 | 9 | echo "Testing ${RND_SOURCE} ..." 10 | if ! rngtest -c $TEST_COUNT < "${RND_SOURCE}"; then 11 | echo 12 | echo "WARNING: Test failed!" 13 | exit 1 14 | fi 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /run-local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Runs an executable using the CWD for shared libraries 3 | 4 | if [[ -z "$*" ]]; then 5 | echo >&2 "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | CWD=$(pwd) 10 | CMD="$*" 11 | 12 | if [[ "$VERBOSE" =~ 1|true ]] || [[ "$VERBOSITY" -gt 0 ]]; then 13 | echo "LD_LIBRARY_PATH=${CWD} bash -c \"${CMD}\"" >&2 14 | fi 15 | 16 | if ! LD_LIBRARY_PATH="${CWD}" bash -c "${CMD}"; then 17 | exit 1 18 | fi 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /scan-qr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Scan the desktop for a QR code and decode if found 3 | # Uses zbarimg, for example: 4 | # zbarimg -q --raw "${temp_file}" 5 | 6 | hash gnome-screenshot 2>/dev/null || { echo >&2 "You need to install gnome-screenshot. Aborting."; exit 1; } 7 | hash zbarimg 2>/dev/null || { echo >&2 "You need to install zbar-tools. Aborting."; exit 1; } 8 | 9 | function countdown() { 10 | start_date=$(($(date +%s) + $1)); 11 | while [ "$start_date" -ge "$(date +%s)" ]; do 12 | seconds=$(date -u --date @$((start_date - $(date +%s))) +%s) 13 | if [ "$seconds" -eq 0 ]; then 14 | echo -ne "Taking screenshot ...........\r"; 15 | break; 16 | else 17 | echo -ne "Screenshot in $seconds second(s) ...\r"; 18 | fi 19 | sleep 0.1 20 | done 21 | } 22 | 23 | if ! temp_file=$(mktemp -t screenshot.XXXXXXXXXX.png); then 24 | echo >&2 "ERROR: Failed to create temporary file for screenshot." 25 | exit 1 26 | fi 27 | 28 | countdown 3 29 | 30 | if ! gnome-screenshot -f "${temp_file}"; then 31 | echo >&2 "ERROR: Failed to take desktop screenshot." 32 | exit 1 33 | fi 34 | 35 | echo -ne "Scanning for barcodes .......\r"; 36 | 37 | err=0 38 | if ! results=$(zbarimg -q "${temp_file}"); then 39 | err=1 40 | fi 41 | 42 | if [ -e "${temp_file}" ]; then 43 | rm -f "${temp_file}" 44 | fi 45 | 46 | # HACK: Clear the entire line. 47 | echo -ne "\r \r" 48 | 49 | if [ "${err}" -ne 0 ]; then 50 | echo >&2 "No barcodes detected." 51 | exit 1 52 | fi 53 | 54 | echo "${results}" 55 | exit 0 56 | -------------------------------------------------------------------------------- /security/audit-acct.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | hash ac 2>/dev/null || { echo >&2 "You need to install acct. Aborting."; exit 1; } 4 | 5 | echo "USERS' CONNECT TIMES" 6 | echo "" 7 | 8 | ac -d -p 9 | 10 | echo "" 11 | echo "COMMANDS BY USER" 12 | echo "" 13 | 14 | users=$(awk -F ':' '{print $1}' /etc/passwd | sort) 15 | 16 | for user in $users ; do 17 | comm=$(lastcomm --user "$user" | awk '{print $1}' | sort | uniq -c | sort -nr) 18 | if [ "$comm" ] ; then 19 | echo "$user:" 20 | echo "$comm" 21 | fi 22 | done 23 | 24 | echo "" 25 | echo "COMMANDS BY FREQUENCY OF EXECUTION" 26 | echo "" 27 | 28 | sa | awk '{print $1, $6}' | sort -n | head -n -1 | sort -nr 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /security/clear-lastlog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # clears lastlog entries 3 | # all users will appear to have never logged in 4 | # warning: this script is noisy and will raise flags on monitored systems 5 | 6 | # check if superuser 7 | if [[ $EUID -ne 0 ]]; then 8 | echo "This script must be run as root" >&2 9 | exit 1 10 | fi 11 | 12 | true > /var/log/lastlog 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /security/clear-wtmp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # clears wtmp and btmp logs 3 | # this clears all entries presented by the last/lastb commands 4 | # warning: this script is noisy and will raise flags on secured systems 5 | 6 | # check if superuser 7 | if [[ $EUID -ne 0 ]]; then 8 | echo "This script must be run as root" >&2 9 | exit 1 10 | fi 11 | 12 | true > /var/log/wtmp 13 | true > /var/log/btmp 14 | 15 | -------------------------------------------------------------------------------- /security/find-ow-perm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # searches for files/folders with o+w permission bit 3 | 4 | if [[ $EUID -ne 0 ]]; then 5 | echo "This script must be run as root." >&2 6 | exit 1 7 | fi 8 | 9 | find / -xdev \( -perm o+w \) -type f -print0 2>&- | xargs -0 ls -l 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /security/find-setgid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # find all setgid binaries 3 | 4 | if [[ $EUID -ne 0 ]]; then 5 | echo "This script must be run as root." >&2 6 | exit 1 7 | fi 8 | 9 | find / -xdev \( -perm -2000 \) -type f -print0 2>&- | xargs -0 ls -l 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /security/find-setuid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # find all setuid binaries 3 | 4 | if [[ $EUID -ne 0 ]]; then 5 | echo "This script must be run as root." >&2 6 | exit 1 7 | fi 8 | 9 | find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \; 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /security/gen-passwd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # generates a random password 3 | # uses /dev/random to ensure good random numbers 4 | 5 | RNG_DEV="/dev/urandom" 6 | 7 | # Strong passwords should be at least this long 8 | DEFAULT_LENGTH="20" 9 | 10 | # Standard charset is alphanumeric with upper and 11 | # lower case w/ some special characters 12 | CHARSET="A-Za-z0-9_" 13 | 14 | # Use the below charset for higher entropy 15 | # CHARSET="A-Za-z0-9_\$#!@&%^*~=+,.<>[]/\\\"\'\`" 16 | 17 | LENGTH="$1" 18 | re='^[0-9]+$' 19 | if ! [[ $LENGTH =~ $re ]] ; then 20 | LENGTH=$DEFAULT_LENGTH 21 | fi 22 | 23 | PASSWD=$(head $RNG_DEV | tr -dc "$CHARSET" | head -c $LENGTH) 24 | 25 | echo "${PASSWD}" 26 | 27 | exit 0 28 | -------------------------------------------------------------------------------- /security/gpg-agent-restart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # restarts the gpg agent 3 | # useful for when a gpg mfd like a yubikey gets locked 4 | 5 | hash gpg-connect-agent 2>/dev/null || { echo >&2 "You need to install gpgconf. Aborting."; exit 1; } 6 | 7 | gpg-connect-agent killagent /bye 8 | gpg-connect-agent /bye 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /security/gpg-delete-key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # deletes a keypair from gpg 3 | 4 | hash gpg 2>/dev/null || { echo >&2 "You need to install gnupg. Aborting."; exit 1; } 5 | 6 | if [[ -z "$1" ]]; then 7 | echo >&2 "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | echo "Trying to delete GnuPG key with fingerprint ID $1 ..." 12 | 13 | gpg --delete-secret-key "$1" 14 | gpg --delete-key "$1" 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /security/gpg-test-key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # tests gpg encryption/decryption for the specified key 3 | 4 | hash gpg 2>/dev/null || { echo >&2 "You need to install gnupg. Aborting."; exit 1; } 5 | 6 | if [[ -z "$1" ]]; then 7 | echo >&2 "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | KEY_ID="$1" 12 | EXTRA_OPTS="--verbose" 13 | #EXTRA_OPTS="--verbose --debug-all --debug-level guru" 14 | 15 | echo "Testing GnuPG key with fingerprint ID $1 ..." 16 | uname -a | gpg ${EXTRA_OPTS} --encrypt --armor --recipient "${KEY_ID}" | gpg ${EXTRA_OPTS} --decrypt --armor 17 | 18 | exit 0 19 | -------------------------------------------------------------------------------- /security/kernel-bugs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List known mitigations for CPU bugs via sysfs 3 | 4 | if [ ! -e "/sys/devices/system/cpu/vulnerabilities" ]; then 5 | echo "ERROR: Kernel does not support listing known bugs." >&2 6 | exit 1 7 | fi 8 | 9 | if ! head -n -0 /sys/devices/system/cpu/vulnerabilities/*; then 10 | exit 1 11 | fi 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /security/lock-gnome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # locks GNOME by clearing any cached credentials 3 | 4 | hash gnome-keyring-daemon 2>/dev/null || { echo >&2 "You need to install gnome-keyring. Aborting."; exit 1; } 5 | 6 | printf "Locking GNOME keyring ..." 7 | 8 | # clear cached keys from gnome-keyring 9 | gnome-keyring-daemon -r -d > /dev/null 2>&1 10 | 11 | printf "done.\n" 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /security/ls-auth-failures.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Simple script to list logged authentication failures 3 | 4 | AUTH_LOG="/var/log/auth.log" 5 | 6 | # list authentication failures 7 | FAILED=$(grep -i "failure" ${AUTH_LOG}) 8 | if [ -z "${FAILED}" ]; then 9 | echo "No authentication failures found in logfile: ${AUTH_LOG}" 10 | exit 0 11 | fi 12 | 13 | # Define regular expression parts for extracting rhost 14 | REGEX_RHOST_START='rhost\=' 15 | REGEX_RHOST_TERM='\b' 16 | REGEX_MATCH_IPADDR='([0-9]{1,3}[\.]){3}[0-9]{1,3}' 17 | 18 | # Extract unique hosts which failed to authenticate 19 | declare -a REMOTE_HOSTS=(); 20 | IFS=$'\n'; for line in ${FAILED}; do 21 | rhost=$(echo "$line" | grep -Po "(?<=\s${REGEX_RHOST_START})${REGEX_MATCH_IPADDR}(?=${REGEX_RHOST_TERM})") 22 | if [[ ! " ${REMOTE_HOSTS[*]} " =~ ${rhost} ]]; then 23 | REMOTE_HOSTS=("${REMOTE_HOSTS[@]}" "${rhost}") 24 | fi 25 | done 26 | 27 | # Report on authentication failures 28 | echo >&2 "WARNING: Found authentication failures in ${AUTH_LOG}:" 29 | 30 | echo >&2; echo >&2 "Remote hosts:" 31 | for ((idx=0;idx<=$((${#REMOTE_HOSTS[@]}-1));idx++)); do 32 | rhost=${REMOTE_HOSTS[$idx]} 33 | echo >&2 " @ ${rhost}" 34 | done 35 | 36 | echo >&2; echo >&2 "Log entries:"; echo >&2 "${FAILED}" 37 | 38 | exit 1 39 | -------------------------------------------------------------------------------- /security/pulledpork-update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # [0x19e.net] pulledpork-update.sh 3 | # updates suricata rules using pulledpork 4 | # also handles auto-commit for etckeeper 5 | # configured to use git for version control. 6 | # this script works well as a cronjob. 7 | 8 | hash perl 2>/dev/null || { echo >&2 "You need to install perl. Aborting."; exit 1; } 9 | hash git 2>/dev/null || { echo >&2 "You need to install git. Aborting."; exit 1; } 10 | hash suricata 2>/dev/null || { echo >&2 "You need to install suricata. Aborting."; exit 1; } 11 | 12 | # script variables 13 | PULLEDPORK_PLSCRIPT="/usr/local/bin/pulledpork.pl" 14 | PULLEDPORK_CONFFILE="/etc/pulledpork/pulledpork.conf" 15 | SURICATA_RULES_FILE="/etc/suricata/suricata.rules" 16 | 17 | # updates require root (unless specially configured) 18 | # if you want to run this script as another user, 19 | # you will need to ensure proper permissions for the 20 | # download folder, output file(s) etc. 21 | if [[ $EUID -ne 0 ]]; then 22 | echo "This script must be run as root" >&2 23 | exit 1 24 | fi 25 | 26 | # run pulledpork 27 | # note: use -k for separate rule files 28 | perl $PULLEDPORK_PLSCRIPT -T \ 29 | -c $PULLEDPORK_CONFFILE \ 30 | -o $SURICATA_RULES_FILE # -k 31 | 32 | # git handling for etckeeper (check if /etc/.git exists) 33 | if git -C "/etc" rev-parse > /dev/null 2>&1; then 34 | # check /etc/suricata for modifications 35 | # if there are changes under the config folder, commit them 36 | if [[ "$(git --git-dir=/etc/.git --work-tree=/etc status --porcelain -- /etc/suricata | grep -E '^(M| M)')" != "" ]]; then 37 | echo "Auto-committing updated ruleset..." 38 | pushd /etc > /dev/null 2>&1 39 | git add --all /etc/suricata 40 | git commit -m "suricata: auto-commit updated rules" 41 | popd > /dev/null 2>&1 42 | fi 43 | fi 44 | 45 | # reload suricata 46 | for x in $(pidof "suricata"); do 47 | # send live reload signal (USR2) 48 | echo "Sending live reload signal to suricata pid $x ..." 49 | kill -USR2 "$x" 50 | done 51 | 52 | exit 0 53 | -------------------------------------------------------------------------------- /security/secure-delete.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # securely deletes a file 3 | 4 | hash shred 2>/dev/null || { echo >&2 "You need to install coreutils. Aborting."; exit 1; } 5 | 6 | if [ ! $# -gt 0 ]; then 7 | echo >&2 "Usage: $0 ..." 8 | exit 1 9 | fi 10 | 11 | RND_SOURCE="/dev/urandom" 12 | SHRED_TIMES=48 13 | # SHRED_TIMES=10 14 | 15 | echo "Starting secure delete ..." 16 | echo "Entropy source : $RND_SOURCE" 17 | echo "Overwrite count : $SHRED_TIMES" 18 | 19 | FILE_COUNT=0 20 | 21 | function shred_file() 22 | { 23 | local file="$1" 24 | local verbose_flag="-v" 25 | 26 | if [ -z "$file" ]; then 27 | echo >&2 "ERROR: No file was supplied to shred." 28 | exit 1 29 | fi 30 | 31 | echo "Shredding file : $file ..." 32 | 33 | shred $verbose_flag \ 34 | --random-source "$RND_SOURCE" \ 35 | --iterations "$SHRED_TIMES" \ 36 | --zero \ 37 | --remove \ 38 | "$file" 39 | 40 | echo "Shredded file : $file" 41 | ((FILE_COUNT++)) 42 | } 43 | 44 | function shred_folder() 45 | { 46 | if [ -z "$1" ]; then 47 | echo >&2 "ERROR: Null argument for folder" 48 | exit 1 49 | fi 50 | if [ ! -d "$1" ]; then 51 | echo >&2 "ERROR: Argument is not a directory" 52 | fi 53 | 54 | echo "Searching directory '$1' ..." 55 | 56 | for f in find "$1" -type f; do 57 | shred_file "$f" 58 | done 59 | } 60 | 61 | echo "Processing file(s) ..." 62 | 63 | for arg in "$@"; do 64 | if [ ! -e "$arg" ]; then 65 | echo >&2 "ERROR: File/folder not found: $arg" 66 | exit 1 67 | fi 68 | 69 | if [ -d "$arg" ]; then 70 | # note: erasing files from subdirectories is dangerous, and this 71 | # script should supply more options before allowing recursive 72 | # erasure. print out a message and skip the folder 73 | echo >&2 "Ignored folder : $arg" 74 | 75 | # uncomment below to enable subdirectory handling 76 | # shred_folder "$arg" 77 | elif [ -f "$arg" ]; then 78 | shred_file "$arg" 79 | fi 80 | done 81 | 82 | echo "Finished erasing $FILE_COUNT file(s)." 83 | 84 | exit 0 85 | -------------------------------------------------------------------------------- /security/suricata-reload-rules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # triggers a live reload of suricata rules 3 | 4 | hash suricata 2>/dev/null || { echo >&2 "You need to install suricata. Aborting."; exit 1; } 5 | 6 | if [[ $EUID -ne 0 ]]; then 7 | echo "This script must be run as root" >&2 8 | exit 1 9 | fi 10 | 11 | # make sure suricata is running 12 | SURICATA_PID=$(pidof -s "suricata") 13 | if [[ -z "$SURICATA_PID" ]]; then 14 | echo >&2 "ERROR: Suricata doesn't appear to be running." 15 | exit 1 16 | fi 17 | 18 | for x in $(pidof "suricata"); do 19 | # send live reload signal (USR2) 20 | echo "Sending live reload signal to suricata pid $x ..." 21 | kill -USR2 "$x" 22 | done 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /security/swap-nuke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # secure swap erasure 3 | 4 | # check if sswap command exists 5 | hash sswap 2>/dev/null || { echo >&2 "You need to install secure-delete. Aborting."; exit 1; } 6 | 7 | # check if superuser 8 | if [[ $EUID -ne 0 ]]; then 9 | echo "This script must be run as root" >&2 10 | exit 1 11 | fi 12 | 13 | # find the swap device 14 | SWAP_DEVICE=$(swapon -s | grep /dev | awk '{print $1}') 15 | if [[ -z "$SWAP_DEVICE" ]]; then 16 | echo "Failed to determine swap device. Does it exist? Is it activated?" >&2 17 | exit 1 18 | else 19 | echo "Found swap device: $SWAP_DEVICE" 20 | fi 21 | 22 | # turn swap off 23 | swapoff -v "$SWAP_DEVICE" 24 | 25 | # clear swap 26 | sswap -v "$SWAP_DEVICE" 27 | 28 | # turn swap back on 29 | swapon -v "$SWAP_DEVICE" 30 | 31 | exit 0 32 | -------------------------------------------------------------------------------- /security/virustotal-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # [ 0x19e Networks ] 4 | # 5 | # VirusTotal MD5 Database Check 6 | # 7 | # Takes as MD5 hash or a file as the only argument 8 | # If a file path is provided then md5sum is used to 9 | # calculate the hash. 10 | # 11 | # Note that since this script doesn't upload anything 12 | # there won't be any results for files not seen before. 13 | # This is good in a lot of situations but keep in mind 14 | # you'll need a different script to perform submission. 15 | # 16 | 17 | echo "Virus Total MD5 DB Check" 18 | 19 | # the virustotal API key to use 20 | # below is the API key for 0x19e Networks - feel free to use it but please 21 | # don't give it out to others. if they are meant to have it they can get it 22 | # themselves. 23 | API_KEY="374e4810c5a6584c9a2fcf456b39223e09c198233996e0181a35a713abab4e2f" 24 | 25 | if [[ -z "$1" ]]; then 26 | echo "Usage: $0 [file or hash...]" >&2 27 | exit 1 28 | fi 29 | 30 | hash curl 2>/dev/null || { echo >&2 "You need to install curl. Aborting."; exit 1; } 31 | hash awk 2>/dev/null || { echo >&2 "You need to install gawk. Aborting."; exit 1; } 32 | 33 | # process file 34 | if [[ -f "$1" ]]; then 35 | MD5_SUM=$(md5sum "$1" | awk '{print $1}') 36 | echo "Processing $1 ($MD5_SUM) ..." 37 | REPORT=$(curl -s -X POST 'https://www.virustotal.com/vtapi/v2/file/report' --form apikey="$API_KEY" --form resource="$MD5_SUM") 38 | SUMMARY=$(echo "$REPORT" | awk -F'positives\":' '{print $2}' | awk -F' ' '{print $1" "$4$5$6}'|sed 's/["}]//g') 39 | echo "VirusTotal Hits: $SUMMARY" 40 | exit 0 41 | fi 42 | 43 | # process single hash 44 | HTEST=$(echo "$1" | grep -e "[0-9a-f]\{32\}") 45 | if [ ! -f "$1" ] && [ "$HTEST" != "$1" ]; then 46 | echo "$1 is not a valid md5 hash" 47 | else 48 | echo "Processing $1 ..." 49 | REPORT=$(curl -s -X POST 'https://www.virustotal.com/vtapi/v2/file/report' --form apikey="$API_KEY" --form resource="$1") 50 | echo "$REPORT" | awk -F'positives\":' '{print "VirusTotal Hits:" $2}' | awk -F' ' '{print $1$2" "$3$6$7}'|sed 's/["}]//g' 51 | fi 52 | 53 | exit 0 54 | -------------------------------------------------------------------------------- /setup/configs/bash.logout: -------------------------------------------------------------------------------- 1 | # ~/.bash_logout: executed by bash(1) when login shell exits. 2 | 3 | # when leaving the console clear the screen to increase privacy 4 | 5 | if [ "$SHLVL" = 1 ]; then 6 | [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q 7 | fi 8 | -------------------------------------------------------------------------------- /setup/configs/gnupg/dirmngr.conf.example: -------------------------------------------------------------------------------- 1 | keyserver hkps://hkps.pool.sks-keyservers.net 2 | keyserver hkp://keys.gnupg.net 3 | keyserver hkp://jirk5u4osbsr34t5.onion 4 | 5 | honor-http-proxy 6 | allow-ocsp 7 | disable-ipv6 8 | 9 | # note: use 'use-tor' to enable tor 10 | no-use-tor 11 | 12 | log-file agent-debug.log 13 | debug-level basic 14 | 15 | connect-timeout 8 16 | connect-quick-timeout 2 17 | resolver-timeout 15 18 | -------------------------------------------------------------------------------- /setup/configs/gnupg/gpg-agent.conf.example: -------------------------------------------------------------------------------- 1 | enable-ssh-support 2 | pinentry-program /usr/bin/pinentry 3 | default-cache-ttl 60 4 | max-cache-ttl 120 5 | default-cache-ttl-ssh 60 6 | max-cache-ttl-ssh 120 7 | 8 | log-file gpg-agent.log 9 | # write-env-file /home/$USER/.gnupg/gpg-agent-info 10 | 11 | #dirmngr-program /usr/local/bin/dirmngr 12 | #scdaemon-program /usr/local/lib/scdaemon 13 | 14 | extra-socket /home/$HOME/.gnupg/S.gpg-agent.extra 15 | -------------------------------------------------------------------------------- /setup/configs/gnupg/gpg.conf.example: -------------------------------------------------------------------------------- 1 | auto-key-locate cert pka ldap keyserver 2 | keyserver hkps://hkps.pool.sks-keyservers.net 3 | keyserver hkp://keys.gnupg.net 4 | keyserver-options auto-key-retrieve 5 | keyserver-options honor-keyserver-url=yes 6 | 7 | #agent-program /usr/local/bin/gpg-agent 8 | #dirmngr-program /usr/local/bin/dirmngr 9 | 10 | armor 11 | use-agent 12 | utf8-strings 13 | fixed-list-mode 14 | charset utf-8 15 | no-comments 16 | no-emit-version 17 | keyid-format 0xlong 18 | with-fingerprint 19 | verify-options show-uid-validity show-policy-urls show-notations show-keyserver-urls 20 | list-options show-uid-validity 21 | require-cross-certification 22 | max-cert-depth 5 23 | 24 | cert-digest-algo SHA512 25 | s2k-cipher-algo AES256 26 | s2k-digest-algo SHA512 27 | 28 | # note: for desktop installs only 29 | # photo-viewer "display -title 'KeyID 0x%k'" 30 | 31 | # Normal security 32 | default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed 33 | personal-cipher-preferences AES256 AES192 AES CAST5 34 | personal-digest-preferences SHA512 SHA384 SHA256 35 | 36 | # Enhanced security 37 | # default-preference-list SHA512 SHA384 SHA256 AES256 AES192 ZLIB BZIP2 ZIP Uncompressed 38 | # personal-digest-preferences SHA512 SHA384 SHA256 39 | # personal-cipher-preferences AES256 AES192 40 | 41 | # Highest security 42 | # default-preference-list SHA512 SHA384 AES256 ZLIB BZIP2 ZIP Uncompressed 43 | # personal-digest-preferences SHA512 SHA384 44 | # personal-cipher-preferences AES256 45 | 46 | # NOTE: The minimum default is: 47 | # gpg> setpref uncompressed 48 | # Set preference list to: 49 | # Cipher: 3DES 50 | # Digest: SHA1 51 | # Compression: Uncompressed 52 | # Features: MDC, Keyserver no-modify 53 | -------------------------------------------------------------------------------- /setup/configs/gnupg/scdaemon.conf.example: -------------------------------------------------------------------------------- 1 | reader-port "Yubico Yubikey NEO OTP+U2F+CCID 0" 2 | log-file reader.log 3 | verbose 4 | debug-level guru 5 | #debug 2048 6 | 7 | allow-admin 8 | 9 | # enable shared access for multi-purpose keys 10 | # note: only supported by custom builds 11 | #shared-access 12 | -------------------------------------------------------------------------------- /setup/configs/profile.skel: -------------------------------------------------------------------------------- 1 | # ~/.profile: executed by the command interpreter for login shells. 2 | # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login 3 | # exists. 4 | # see /usr/share/doc/bash/examples/startup-files for examples. 5 | # the files are located in the bash-doc package. 6 | 7 | # the default umask is set in /etc/profile; for setting the umask 8 | # for ssh logins, install and configure the libpam-umask package. 9 | #umask 022 10 | 11 | # if running bash 12 | if [ -n "$BASH_VERSION" ]; then 13 | # include .bashrc if it exists 14 | if [ -f "$HOME/.bashrc" ]; then 15 | . "$HOME/.bashrc" 16 | fi 17 | fi 18 | 19 | # set PATH so it includes user's private bin if it exists 20 | if [ -d "$HOME/bin" ] ; then 21 | PATH="$HOME/bin:$PATH" 22 | fi 23 | if [ -d "$HOME/.local/bin" ] ; then 24 | PATH="$HOME/.local/bin:$PATH" 25 | fi 26 | 27 | # Examine the system and add various additional folders to PATH 28 | if hash tail 2>/dev/null && hash grep 2>/dev/null; then 29 | # Locate and add Xen binaries to PATH 30 | XEN_DIR="/usr/lib" 31 | XEN_BIN="${XEN_DIR}/$(ls -1 ${XEN_DIR} | grep -P 'xen\-([1-9][0-9]{0,8}|0)(\.([1-9][0-9]{0,8}|0)){1,3}$' | tail -n1)/bin" 32 | if [ -n "${XEN_BIN}" ] && [ "${XEN_BIN}" != "." ] && [ -e "${XEN_BIN}" ]; then 33 | PATH="${XEN_BIN}:$PATH" 34 | # echo "Added Xen hypervisor bin/ folder to PATH: ${XEN_BIN}" 35 | fi 36 | fi 37 | -------------------------------------------------------------------------------- /setup/configs/ssh/sshdusers.rsyslog: -------------------------------------------------------------------------------- 1 | # SSH User Authentication Log (rsyslog configuration) 2 | # Install to: /etc/rsyslog.d/sshdusers.conf 3 | 4 | :msg, regex, "Found matching .* key:" -/var/log/sshdusers.log 5 | :msg, regex, "Accepted publickey for" -/var/log/sshdusers.log 6 | :msg, regex, "Accepted password for" -/var/log/sshdusers.log 7 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-console-messages.conf.example: -------------------------------------------------------------------------------- 1 | 2 | # the following stops low-level messages on console 3 | kernel.printk = 4 4 1 7 4 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-ipv6-privacy.conf.example: -------------------------------------------------------------------------------- 1 | # IPv6 Privacy Extensions (RFC 4941) 2 | # --- 3 | # IPv6 typically uses a device's MAC address when choosing an IPv6 address 4 | # to use in autoconfiguration. Privacy extensions allow using a randomly 5 | # generated IPv6 address, which increases privacy. 6 | # 7 | # Acceptable values: 8 | # 0 - don’t use privacy extensions. 9 | # 1 - generate privacy addresses 10 | # 2 - prefer privacy addresses and use them over the normal addresses. 11 | net.ipv6.conf.all.use_tempaddr = 2 12 | net.ipv6.conf.default.use_tempaddr = 2 13 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-kernel-hardening.conf.example: -------------------------------------------------------------------------------- 1 | # These settings are specific to hardening the kernel itself from attack 2 | # from userspace, rather than protecting userspace from other malicious 3 | # userspace things. 4 | # 5 | # 6 | # When an attacker is trying to exploit the local kernel, it is often 7 | # helpful to be able to examine where in memory the kernel, modules, 8 | # and data structures live. As such, kernel addresses should be treated 9 | # as sensitive information. 10 | # 11 | # Many files and interfaces contain these addresses (e.g. /proc/kallsyms, 12 | # /proc/modules, etc), and this setting can censor the addresses. A value 13 | # of "0" allows all users to see the kernel addresses. A value of "1" 14 | # limits visibility to the root user, and "2" blocks even the root user. 15 | kernel.kptr_restrict = 1 16 | 17 | # The contents of /proc//maps and smaps files are only visible to 18 | # readers that are allowed to ptrace() the process 19 | #kernel.maps_protect = 1 20 | 21 | # Enable exec shield 22 | #kernel.exec-shield = 1 23 | #kernel.randomize_va_space = 1 24 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-link-restrictions.conf.example: -------------------------------------------------------------------------------- 1 | # These settings eliminate an entire class of security vulnerability: 2 | # time-of-check-time-of-use cross-privilege attacks using guessable 3 | # filenames (generally seen as "/tmp file race" vulnerabilities). 4 | fs.protected_hardlinks = 1 5 | fs.protected_symlinks = 1 6 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-lxd-inotify.conf.example: -------------------------------------------------------------------------------- 1 | # Increase the user inotify instance limit to allow for about 2 | # 100 containers to run before the limit is hit again 3 | fs.inotify.max_user_instances = 1024 4 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-magic-sysrq.conf.example: -------------------------------------------------------------------------------- 1 | # The magic SysRq key enables certain keyboard combinations to be 2 | # interpreted by the kernel to help with debugging. The kernel will respond 3 | # to these keys regardless of the current running applications. 4 | # 5 | # In general, the magic SysRq key is not needed for the average Ubuntu 6 | # system, and having it enabled by default can lead to security issues on 7 | # the console such as being able to dump memory or to kill arbitrary 8 | # processes including the running screen lock. 9 | # 10 | # Here is the list of possible values: 11 | # 0 - disable sysrq completely 12 | # 1 - enable all functions of sysrq 13 | # >1 - enable certain functions by adding up the following values: 14 | # 2 - enable control of console logging level 15 | # 4 - enable control of keyboard (SAK, unraw) 16 | # 8 - enable debugging dumps of processes etc. 17 | # 16 - enable sync command 18 | # 32 - enable remount read-only 19 | # 64 - enable signalling of processes (term, kill, oom-kill) 20 | # 128 - allow reboot/poweroff 21 | # 256 - allow nicing of all RT tasks 22 | # 23 | # For example, to enable both control of console logging level and 24 | # debugging dumps of processes: kernel.sysrq = 10 25 | # 26 | kernel.sysrq = 176 27 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-ptrace.conf.example: -------------------------------------------------------------------------------- 1 | # The PTRACE system is used for debugging. With it, a single user process 2 | # can attach to any other dumpable process owned by the same user. In the 3 | # case of malicious software, it is possible to use PTRACE to access 4 | # credentials that exist in memory (re-using existing SSH connections, 5 | # extracting GPG agent information, etc). 6 | # 7 | # A PTRACE scope of "0" is the more permissive mode. A scope of "1" limits 8 | # PTRACE only to direct child processes (e.g. "gdb name-of-program" and 9 | # "strace -f name-of-program" work, but gdb's "attach" and "strace -fp $PID" 10 | # do not). The PTRACE scope is ignored when a user has CAP_SYS_PTRACE, so 11 | # "sudo strace -fp $PID" will work as before. For more details see: 12 | # https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace 13 | # 14 | # For applications launching crash handlers that need PTRACE, exceptions can 15 | # be registered by the debugee by declaring in the segfault handler 16 | # specifically which process will be using PTRACE on the debugee: 17 | # prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0); 18 | # 19 | # In general, PTRACE is not needed for the average running Ubuntu system. 20 | # To that end, the default is to set the PTRACE scope to "1". This value 21 | # may not be appropriate for developers or servers with only admin accounts. 22 | #kernel.yama.ptrace_scope = 1 23 | 24 | kernel.yama.ptrace_scope = 0 25 | -------------------------------------------------------------------------------- /setup/configs/sysctl/10-zeropage.conf.example: -------------------------------------------------------------------------------- 1 | # Protect the zero page of memory from userspace mmap to prevent kernel 2 | # NULL-dereference attacks against potential future kernel security 3 | # vulnerabilities. (Added in kernel 2.6.23.) 4 | # 5 | # While this default is built into the Ubuntu kernel, there is no way to 6 | # restore the kernel default if the value is changed during runtime; for 7 | # example via package removal (e.g. wine, dosemu). Therefore, this value 8 | # is reset to the secure default each time the sysctl values are loaded. 9 | vm.mmap_min_addr = 65536 10 | -------------------------------------------------------------------------------- /setup/configs/sysctl_ixgb.conf: -------------------------------------------------------------------------------- 1 | # some of the defaults may be different for your kernel 2 | # call this file with sysctl -p 3 | # these are just suggested values that worked well to increase throughput in 4 | # several network benchmark tests, your mileage may vary 5 | 6 | ### IPV4 specific settings 7 | # turn TCP timestamp support off, default 1, reduces CPU use 8 | net.ipv4.tcp_timestamps = 0 9 | # turn SACK support off, default on 10 | # on systems with a VERY fast bus -> memory interface this is the big gainer 11 | net.ipv4.tcp_sack = 0 12 | # set min/default/max TCP read buffer, default 4096 87380 174760 13 | net.ipv4.tcp_rmem = 10000000 10000000 10000000 14 | # set min/pressure/max TCP write buffer, default 4096 16384 131072 15 | net.ipv4.tcp_wmem = 10000000 10000000 10000000 16 | # set min/pressure/max TCP buffer space, default 31744 32256 32768 17 | net.ipv4.tcp_mem = 10000000 10000000 10000000 18 | 19 | ### CORE settings (mostly for socket and UDP effect) 20 | # set maximum receive socket buffer size, default 131071 21 | net.core.rmem_max = 524287 22 | # set maximum send socket buffer size, default 131071 23 | net.core.wmem_max = 524287 24 | # set default receive socket buffer size, default 65535 25 | net.core.rmem_default = 524287 26 | # set default send socket buffer size, default 65535 27 | net.core.wmem_default = 524287 28 | # set maximum amount of option memory buffers, default 10240 29 | net.core.optmem_max = 524287 30 | # set number of unprocessed input packets before kernel starts dropping them; default 300 31 | net.core.netdev_max_backlog = 300000 32 | -------------------------------------------------------------------------------- /setup/configs/xrdp/45-allow-colord.pkla: -------------------------------------------------------------------------------- 1 | 2 | [Allow Colord all Users] 3 | Identity=unix-user:* 4 | Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile 5 | ResultAny=no 6 | ResultInactive=no 7 | ResultActive=yes 8 | -------------------------------------------------------------------------------- /setup/fix-xrdp-colord.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Allow colord for all users 3 | # Fixes issues associated with xRDP permissions 4 | 5 | BASE_PATH=$(dirname "$0") 6 | 7 | CONFIG_DIR="/etc/polkit-1/localauthority/50-local.d" 8 | NEW_CONFIG="45-allow-colord.pkla" 9 | 10 | hash sudo 2>/dev/null || { echo >&2 "You need to install sudo. Aborting."; exit 1; } 11 | 12 | if [ ! -d "${CONFIG_DIR}" ]; then 13 | echo >&2 "ERROR: Configuration directory '${CONFIG_DIR}' does not exist. Aborting." 14 | exit 1 15 | fi 16 | 17 | if [ -e "${CONFIG_DIR}/${NEW_CONFIG}" ]; then 18 | echo "Configuration file '${NEW_CONFIG}' is already installed." 19 | exit 0 20 | fi 21 | 22 | echo "Installing configuration file..." 23 | if ! cp -v "${BASE_PATH}/configs/xrdp/${NEW_CONFIG}" "${CONFIG_DIR}"/; then 24 | echo >&2 "ERROR: Failed to install configuration file." 25 | exit 1 26 | fi 27 | 28 | echo "Done." 29 | exit 0 30 | -------------------------------------------------------------------------------- /setup/init-maildir.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Initializes a new Maildir folder for the specified user 3 | 4 | USER=$1 5 | 6 | MAILDIR_PATH="/home/${USER}/Maildir" 7 | 8 | echo "Creating Maildir folder $MAILDIR_PATH ..." 9 | 10 | maildirmake.dovecot "${MAILDIR_PATH}" 11 | maildirmake.dovecot "${MAILDIR_PATH}/.Drafts" 12 | maildirmake.dovecot "${MAILDIR_PATH}/.Sent" 13 | maildirmake.dovecot "${MAILDIR_PATH}/.Junk" 14 | maildirmake.dovecot "${MAILDIR_PATH}/.Trash" 15 | maildirmake.dovecot "${MAILDIR_PATH}/.Templates" 16 | 17 | maildirmake.dovecot "${MAILDIR_PATH}/virtual" 18 | 19 | chmod 700 "${MAILDIR_PATH}" 20 | chmod -R 770 "${MAILDIR_PATH}/" 21 | 22 | chown -R "${USER}": "${MAILDIR_PATH}" 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /setup/install-welcome-issue.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # writes a custom message in /etc/issue 3 | # rwb[at]0x19e[dot]net 4 | 5 | ipaddress=$(ifconfig | grep inet | awk 'NR==1 {print $2}' | awk 'BEGIN { FS=":" } { print $2 }') 6 | 7 | # create simple /etc/issue banner 8 | banner='\n \l' 9 | echo "$banner" > /etc/issue 10 | echo "IP Address: $ipaddress" >> /etc/issue 11 | 12 | RANGE=3 13 | number=$((RANDOM%=RANGE)) 14 | case $number in 15 | 0) 16 | cow="tux" 17 | ;; 18 | 1) 19 | cow="koala" 20 | ;; 21 | 2) 22 | cow="moose" 23 | ;; 24 | esac 25 | 26 | RANGE=2 27 | number=$((RANDOM%=RANGE)) 28 | case $number in 29 | 0) 30 | command="/usr/games/cowsay" 31 | ;; 32 | 1) 33 | command="/usr/games/cowthink" 34 | ;; 35 | esac 36 | 37 | # Add to /etc/issue 38 | /usr/games/fortune -s | $command -f $cow | sed 's:\\:\\\\:g' >> /etc/issue 39 | 40 | # Add to /etc/issue.net 41 | echo '' > /etc/issue.net 42 | /usr/games/fortune -s | $command -f $cow >> /etc/issue.net 43 | 44 | exit 0 45 | -------------------------------------------------------------------------------- /setup/set-timezone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $EUID -ne 0 ]]; then 4 | echo "This script must be run as root" >&2 5 | exit 1 6 | fi 7 | 8 | ZONE_TAB="/usr/share/zoneinfo/zone.tab" 9 | 10 | if [[ -z "$1" ]]; then 11 | echo "Usage: $0 " >&2 12 | exit 1 13 | fi 14 | 15 | TZ_NAME=$(grep -i "$1" "$ZONE_TAB" | awk '{print $3}') 16 | if [[ -z "$TZ_NAME" ]]; then 17 | echo "ERROR: Failed to find timezone for '$1'" >&2 18 | exit 1 19 | fi 20 | 21 | echo "$TZ_NAME" | sudo tee /etc/timezone 22 | sudo dpkg-reconfigure --frontend noninteractive tzdata 23 | -------------------------------------------------------------------------------- /setup/sm-ipmi-keygen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Supermicro IPMI key generator 3 | # See https://peterkleissner.com/2018/05/27/reverse-engineering-supermicro-ipmi/ 4 | 5 | echo "Supermicro IPMI/OOB management key generator" 6 | 7 | # TODO: Validate input MAC 8 | 9 | if [ -z "$1" ]; then 10 | echo "Usage: $0 " >&2 11 | exit 1 12 | fi 13 | 14 | MAC=$(echo "${1}" | awk '{ print toupper($0) }') 15 | MAC=${MAC//[^0-9A-F]/} 16 | 17 | if ! key=$(echo -n "${MAC}" \ 18 | | xxd -r -p \ 19 | | openssl dgst -sha1 -mac HMAC -macopt hexkey:8544E3B47ECA58F9583043F8 \ 20 | | awk '{print $2}' \ 21 | | cut -c 1-24 \ 22 | | sed 's/.\{4\}/&\-/g;s/\-$//'); then 23 | echo "ERROR: Failed to generate IPMI key." >&2 24 | exit 1 25 | fi 26 | 27 | echo "IPMI MAC address : ${MAC}" 28 | echo "IPMI license key : ${key}" 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /setup/sshd-keygen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # sshd-keygen.sh 3 | # generates a new host ssh keypair 4 | 5 | if [[ $EUID -ne 0 ]]; then 6 | echo "This script must be run as root" >&2 7 | exit 1 8 | fi 9 | 10 | SSHKEYGEN=/usr/bin/ssh-keygen 11 | RSA_BITS=2048 12 | DSA_BITS=1024 13 | COMMENT="" 14 | 15 | # Colors 16 | export ESC_SEQ="\x1b[" 17 | export COL_RESET=$ESC_SEQ"39;49;00m" 18 | export COL_RED=$ESC_SEQ"31;01m" 19 | export COL_GREEN=$ESC_SEQ"32;01m" 20 | export COL_YELLOW=$ESC_SEQ"33;01m" 21 | export COL_BLUE=$ESC_SEQ"34;01m" 22 | export COL_MAGENTA=$ESC_SEQ"35;01m" 23 | export COL_CYAN=$ESC_SEQ"36;01m" 24 | 25 | printf "$COL_GREEN%s$COL_RESET\n" "First-time key generation for SSH daemon" 26 | printf "$COL_CYAN%s$COL_RESET\n" "NOTE: This will not replace existing keys!" 27 | printf "$COL_BLUE%.0s-$COL_RESET" {1..40}; echo 28 | 29 | if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then 30 | printf "$COL_YELLOW%s$COL_RESET\n" "Using $RSA_BITS bits for new RSA key..." 31 | $SSHKEYGEN -t rsa -b $RSA_BITS -f /etc/ssh/ssh_host_rsa_key -N "" \ 32 | -C "$COMMENT" < /dev/null 33 | printf "$COL_GREEN%s$COL_RESET\n" "Created /etc/ssh/ssh_host_rsa_key" 34 | else 35 | printf "$COL_RED%s$COL_RESET\n" "Key already exists: /etc/ssh/ssh_host_rsa_key" 36 | fi 37 | 38 | if [ ! -f /etc/ssh/ssh_host_dsa_key ]; then 39 | printf "$COL_YELLOW%s$COL_RESET\n" "Using 1024 bits for new DSA key..." 40 | $SSHKEYGEN -t dsa -b $DSA_BITS -f /etc/ssh/ssh_host_dsa_key -N "" \ 41 | -C "$COMMENT" < /dev/null 42 | printf "$COL_GREEN%s$COL_RESET\n" "Created /etc/ssh/ssh_host_dsa_key" 43 | else 44 | printf "$COL_RED%s$COL_RESET\n" "Key already exists: /etc/ssh/ssh_host_dsa_key" 45 | fi 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /sha1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # gets the sha1 hash of an input string 3 | 4 | if [ -z "$1" ]; then 5 | cat | sha1sum | awk '{printf "\n%s\n\n", $1}' 6 | else 7 | echo -n "$1" | sha1sum | awk '{printf "\n%s\n\n", $1}' 8 | fi 9 | -------------------------------------------------------------------------------- /show-irq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Read system interrupt(s). 3 | 4 | IRQ_REQ="$1" 5 | 6 | if ! RAW_OUTPUT=$(grep -vP '^(\s+)?(ERR|MIS)' /proc/interrupts | tail -n+2 | awk '{printf "%s|", $1; for(j=(NF-2);j<=NF;j++){if($j~/^[A-Za-z]/){printf "%s ", $j} }; if($j=NF){printf "\n";} }' && grep -P '^(\s+)?(ERR|MIS)' /proc/interrupts | awk '{printf "%s|%s\n", $1, $2}'); then 7 | echo >&2 "ERROR: Failed to read interrupts." 8 | exit 1 9 | fi 10 | if ! OUTPUT=$(echo "${RAW_OUTPUT}" | awk -F'|' '{ printf "IRQ %s %s\n", $1, $2 }'); then 11 | echo >&2 "ERROR: Failed to parse interrupts." 12 | exit 1 13 | fi 14 | 15 | if [ ! -z "${IRQ_REQ}" ]; then 16 | if ! echo "${OUTPUT}" | grep -P "^(IRQ(\s+)?)?${IRQ_REQ}(\s+)?\:"; then 17 | echo "ERROR: Could not find interrupt '${IRQ_REQ}'." 18 | fi 19 | else 20 | echo "${OUTPUT}" 21 | fi 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /sort-hex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Sorts an input list of hexadecimal values to sort 3 | 4 | cat | awk '{printf("%050s\t%s\n", toupper($0), $0)}' | LC_COLLATE=C sort -k1,1 | cut -f2 5 | -------------------------------------------------------------------------------- /speaker-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Script to find the correct device to play audio from 4 | # See speaker-test(1) for more 5 | 6 | hash grep 2>/dev/null || { echo >&2 "You need to install grep. Aborting."; exit 1; } 7 | hash speaker-test 2>/dev/null || { echo >&2 "You need to install alsa-utils. Aborting."; exit 1; } 8 | 9 | set -euo pipefail 10 | 11 | pcmDevs="$( 12 | aplay --list-pcms | 13 | grep --invert-match --extended-regexp '^[[:space:]]' | 14 | grep --invert-match --extended-regexp '^(default|null|pulse|usb)' | 15 | while IFS=, read -r record _; do echo "$record"; done | 16 | while IFS=: read -r label cardKeyValue; do 17 | card="${cardKeyValue}" 18 | #card="${cardKeyValue/CARD=/}" 19 | if [ "$card" = Loopback ];then continue;fi 20 | printf -- '%s:%s\n' "$label" "$card" 21 | done | 22 | sort --stable | 23 | uniq 24 | )"; declare -ra pcmDevs 25 | 26 | currentlyTesting=0 27 | reportInterruptedDevice() ( 28 | if [[ -z "$currentlyTesting" ]];then return; fi 29 | printf 'INTERRUPTED testing device "%s"\n' "$currentlyTesting" 30 | ) 31 | trap reportInterruptedDevice SIGINT 32 | 33 | # shellcheck disable=2068 34 | for pcmDevice in ${pcmDevs[@]};do 35 | currentlyTesting="$pcmDevice" 36 | 37 | printf 'TESTING device "%s"\n' "$pcmDevice" 38 | echo speaker-test --nloops 1 --channels 2 --device "$pcmDevice" -t wav 39 | if ! speaker-test --nloops 1 --channels 2 --device "$pcmDevice" -t wav; then 40 | printf '\nFAILED testing device "%s"\n\n' "$pcmDevice" 41 | else 42 | printf '\nFINSHED testing device "%s"\n\n' "$pcmDevice" 43 | fi 44 | done 45 | currentlyTesting='' 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /ssl/check-ocsp-staple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # determine if a server has ocsp stapling enabled 3 | # produces no output if server does not use or has 4 | # incorrectly configured OCSP stapling. 5 | 6 | if [[ -z "$1" ]]; then 7 | echo >&2 "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | SERVER="$1" 12 | SSL_PORT=443 13 | 14 | ping_test() 15 | { 16 | if [[ -z "$1" ]]; then 17 | echo 2 18 | return 19 | fi 20 | 21 | local hostname="$1" 22 | 23 | # todo: investigate using fping instead 24 | # fping -c1 -t300 $IP 25 | if ! ping -c 1 "$hostname" > /dev/null 2>&1; then 26 | echo >&2 "$SERVER is not rresponding to ping requests and may be down." 27 | exit 3 28 | fi 29 | } 30 | 31 | ping_test "$SERVER" 32 | 33 | if SSL_RESULT=$(echo QUIT | openssl s_client -connect "$SERVER:$SSL_PORT" \ 34 | -servername "$SERVER" \ 35 | -status > /dev/null 2>&1); then 36 | echo "Got response from $SERVER:$SSL_PORT (server name $SERVER)" 37 | else 38 | echo >&2 "Failed to get response from server $SERVER:$SSL_PORT" 39 | exit $? 40 | fi 41 | OCSP_RESPONSE=$(echo "$SSL_RESULT" | grep -A 17 'OCSP response:' \ 42 | | grep --color=never -B17 -A1 'This Update') 43 | 44 | if [[ -z "$OCSP_RESPONSE" ]]; then 45 | echo >&2 "The server does not appear to have OCSP stapling." 46 | exit 2 47 | fi 48 | 49 | echo "$OCSP_RESPONSE" 50 | 51 | exit 0 52 | -------------------------------------------------------------------------------- /ssl/check-ssl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # print openssl info for a given site 3 | 4 | DEFAULT_PORT=443 5 | 6 | if [[ -z "$1" ]]; then 7 | echo >&2 "Usage: $0 [port]" 8 | exit 1 9 | fi 10 | 11 | # re='^(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]$' 12 | re='^[-A-Za-z0-9\+&@#%?=~_|!:,.;]+$' 13 | if ! [[ $1 =~ $re ]]; then 14 | echo >&2 "ERROR: Invalid server name" 15 | exit 1 16 | fi 17 | 18 | # figure out what port to try 19 | SP=$DEFAULT_PORT 20 | if [[ -n "$2" ]]; then 21 | re='^[0-9]+$' 22 | if ! [[ $2 =~ $re ]]; then 23 | echo >&2 "ERROR: Port must be a valid number" 24 | fi 25 | SP=$2 26 | fi 27 | 28 | SERVER="$1" 29 | PORT="$SP" 30 | if ! timeout 2 bash -c "echo QUIT | openssl s_client -CApath /etc/ssl/certs -connect $SERVER:$PORT -servername $SERVER -status"; then 31 | echo >&2 "ERROR: Failed to connect to server." 32 | exit 1 33 | fi 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /ssl/clean-pem.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # clean PEM certificates 3 | 4 | # note: use either '$*' or '$@' to process all input 5 | for f in "$@"; do 6 | echo "Cleaning PEM file: $f" 7 | openssl x509 -in "$f" -outform pem -out "$f" 8 | done 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /ssl/gen-snakeoil.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generate a new 'snakeoil' self-signed certificate for testing 3 | 4 | hash make-ssl-cert 2>/dev/null || { echo >&2 "You need to install ssl-cert. Aborting."; exit 1; } 5 | 6 | # check if superuser 7 | if [[ $EUID -ne 0 ]]; then 8 | echo >&2 "ERROR: This script must be run as root." 9 | exit 1 10 | fi 11 | 12 | echo "Installing new self-signed snakeoil certificate ..." 13 | if ! make-ssl-cert generate-default-snakeoil --force-overwrite; then 14 | echo >&2 "Failed." 15 | exit 1 16 | fi 17 | 18 | echo "Finished." 19 | exit 0 20 | -------------------------------------------------------------------------------- /ssl/get-serial.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generates random 64-bit non-negative hexadecimal value 3 | 4 | hash openssl 2>/dev/null || { echo >&2 "You need to install openssl. Aborting."; exit 1; } 5 | 6 | DEFAULT_SERIAL="01" 7 | 8 | HEX_COUNT=16 9 | MAX_TRIES=100 10 | 11 | # Get a fresh, non-negative, random serial 12 | COUNT=0 13 | SERIAL=$(openssl rand -hex ${HEX_COUNT}) 14 | while [ ${COUNT} -lt ${MAX_TRIES} ] && [ $((0x${SERIAL})) -lt 0 ]; do 15 | SERIAL=$(openssl rand -hex ${HEX_COUNT}) 16 | ((COUNT++)) 17 | done 18 | if [ ${COUNT} -ge ${MAX_TRIES} ]; then 19 | echo ${DEFAULT_SERIAL} 20 | exit 1 21 | fi 22 | 23 | echo "${SERIAL}" 24 | exit 0 25 | -------------------------------------------------------------------------------- /ssl/print-asn1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Dumps the ASN.1 structure of the specified certificate 3 | 4 | hash openssl 2>/dev/null || { echo >&2 "You need to install openssl. Aborting." exit 1; } 5 | 6 | # Load configuration 7 | # The directive below prevents shellcheck from complaining about not knowing where to load 8 | # the config file from. All variables should be accounted for locally. 9 | # shellcheck source=/dev/null 10 | if ! source "$(dirname "$0")"/config.sh; then 11 | echo >&2 "ERROR: Failed to load configuration file." 12 | exit 1 13 | fi 14 | 15 | export OPENSSL_CONF="etc/root-ca.conf" 16 | 17 | CERT="$1" 18 | if [ -z "${CERT}" ]; then 19 | echo "Usage: $0 " 20 | exit 1 21 | fi 22 | 23 | if [ ! -e "${CERT}" ]; then 24 | echo >&2 "ERROR: Certificate does not exist." 25 | exit 1 26 | fi 27 | 28 | if ! openssl asn1parse -in "${CERT}"; then 29 | exit 1 30 | fi 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /ssl/print-cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # display a certificate 3 | 4 | if [[ -z "$1" ]]; then 5 | echo >&2 "Usage: $0 " 6 | exit 1 7 | fi 8 | if [ ! -f "$1" ]; then 9 | echo >&2 "Certificate not found: $1" 10 | exit 1 11 | fi 12 | 13 | FILE=$(readlink -m "$1") 14 | 15 | echo "File: $FILE" 16 | openssl x509 -in "$FILE" -noout -text 17 | 18 | exit 0 19 | -------------------------------------------------------------------------------- /ssl/print-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # display a certificate 3 | 4 | if [[ -z "$1" ]]; then 5 | echo >&2 "Usage: $0 " 6 | exit 1 7 | fi 8 | if [ ! -f "$1" ]; then 9 | echo >&2 "Certificate not found: $1" 10 | exit 1 11 | fi 12 | 13 | FILE=$(readlink -m "$1") 14 | 15 | echo "filePath=$FILE" 16 | openssl x509 -in "$FILE" -noout -serial -subject -issuer -startdate -enddate 17 | 18 | exit 0 19 | -------------------------------------------------------------------------------- /ssl/print-req.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Display the contents of a Certificate Signing Request (CSR) 3 | 4 | hash openssl 2>/dev/null || { echo >&2 "You need to install openssl. Aborting."; exit 1; } 5 | 6 | if [ -z "$1" ]; then 7 | echo >&2 "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | if ( [ ! -e "$1" ] | [ ! -s "$1" ] ); then 12 | echo >&2 "ERROR: The specified CSR '${1}' does not exist." 13 | exit 1 14 | fi 15 | 16 | CSR_PATH="$1" 17 | NAMEOPT="dump_nostr,utf8,multiline,show_type" 18 | 19 | # Print the CSR 20 | if ! openssl req -noout -text -nameopt ${NAMEOPT} -in "$CSR_PATH"; then 21 | exit 1 22 | fi 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /ssl/test-oid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Tests OpenSSL OID recognition and support. 4 | # 5 | # If OpenSSL returns a String identifier for the supplied OID, then 6 | # that OID was compiled into the version of OpenSSL along with an 7 | # ASN.1 definition for it. 8 | # 9 | hash openssl 2>/dev/null || { echo >&2 "You need to install openssl. Aborting."; exit 1; } 10 | 11 | OID="$1" 12 | if [ -z "${OID}" ]; then 13 | echo "Usage: $0 [config]" 14 | exit 1 15 | fi 16 | 17 | if [ -n "$2" ]; then 18 | if [ -e "$2" ]; then 19 | export OPENSSL_CONF="$2" 20 | echo "Using configuration file ${OPENSSL_CONF}" 21 | else 22 | echo "ERROR: Configuration file '${OPENSSL_CONF}' does not exist." 23 | exit 1 24 | fi 25 | fi 26 | 27 | if ! OUTPUT=$(openssl asn1parse -genstr OID:"${OID}"); then 28 | echo >&2 "ERROR: Failed to parse Object identifier '${OID}'." 29 | exit 1 30 | fi 31 | 32 | echo "${OUTPUT}" 33 | 34 | exit 0 35 | -------------------------------------------------------------------------------- /stopwatch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # one-liner 4 | start_date=$(date +%s); while true; do echo -ne "$(date -u --date @$(($(date +%s) - start_date)) +%H:%M:%S)\r"; done 5 | 6 | exit 0 7 | -------------------------------------------------------------------------------- /sys-bandwidth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # read 32GB zero's and throw them away. 3 | # rwb[at]0x19e[dot]net 4 | 5 | SIZE_MB=32 6 | 7 | dd if=/dev/zero of=/dev/null bs=1M count=$((SIZE_MB*1024)) 8 | # dd if=/dev/zero bs=1M count=$((SIZE_MB*1024)) | pv -brtep -s "${SIZE_MB}m" | dd of=/dev/null 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /sys-call-table.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # display the syscall table 3 | 4 | # check if superuser 5 | if [[ $EUID -ne 0 ]]; then 6 | echo >&2 "This script must be run as root." 7 | exit 1 8 | fi 9 | 10 | grep sys_call_table "/boot/System.map-$(uname -r)" | cut -d " " -f 1 11 | 12 | exit 0 13 | -------------------------------------------------------------------------------- /sysload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # print an overview of current system load 3 | 4 | hash iostat 2>/dev/null || { echo >&2 "You need to install sysstat. Aborting."; exit 1; } 5 | 6 | function getSizeString() { 7 | if [ -z "$1" ]; then 8 | echo "NULL" 9 | return 1 10 | fi 11 | 12 | re='^[0-9]+$' 13 | if ! [[ $1 =~ $re ]] ; then 14 | echo "NaN" 15 | return 1 16 | fi 17 | 18 | if [ "$1" -lt 1000 ]; then 19 | echo "${1} bytes" 20 | return 0 21 | fi 22 | 23 | echo "$1" | awk ' 24 | function human(x) { 25 | if (x<1000) {return x} else {x/=1024} 26 | s="kMGTEPZY"; 27 | while (x>=1000 && length(s)>1) 28 | {x/=1024; s=substr(s,2)} 29 | return sprintf("%.2f", x) " " substr(s,1,1) "B" 30 | } 31 | {sub(/^[0-9]+/, human($1)); print}' 32 | 33 | return 0 34 | } 35 | 36 | iostat -m 37 | 38 | top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{printf("CPU Load:\t%s%\n",100-$1)}' 39 | free -m | awk 'NR==2{printf "Memory Usage:\t%s MB / %s MB (%.f%%)\n", $3,$2,$3*100/$2 }' 40 | 41 | printf "Disk Usage:\n" 42 | df -h | awk '{ printf("%s %s %s %s %s\n", $6, $1, $3, $2, $5); }' \ 43 | | grep -v "Mounted" | grep -vP '^\/(dev|run|sys)' \ 44 | | awk '{ printf(" - %-14s on\t %-14s: %-6s / %-6s (%s)\n", $2, $1, $3, $4, $5); }' 45 | # df -h | awk '$NF=="/"{printf "Disk Usage:\t%d GB /%d GB (%s)\n", $3,$2,$5}' 46 | 47 | # NOTE: ps returns value in kB 48 | echo -e "\nProcess memory usage:" 49 | ps axo rss,comm,pid | awk '{ proc_list[$2]++; proc_list[$2 "," 1] += $1; } END { for (proc in proc_list) { printf("%d %s\n", proc_list[proc "," 1],proc); }}' | sort -n | tail -n 10 | sort -nr | while read -r line; do 50 | proc=$(echo "$line" | awk -F' ' '{ print $2 }') 51 | bytes=$(echo "$line" | awk -F' ' '{ print $1 }') 52 | size=$(getSizeString "$((bytes*1024))") 53 | 54 | printf "%-14s %s\n" "$size" "$proc" 55 | done 56 | 57 | exit 0 58 | -------------------------------------------------------------------------------- /systemd/disable-sleep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Disable sleep/suspend/hibernate 3 | 4 | TARGETS="sleep.target suspend.target hibernate.target hybrid-sleep.target" 5 | 6 | hash sudo 2>/dev/null || { echo >&2 "You need to install sudo. Aborting."; exit 1; } 7 | 8 | # Ensure sudo privileges for the current user if not running as root. 9 | if [[ $EUID -ne 0 ]]; then 10 | echo "NOTICE: Running as user $USER; sudo privileges required." 11 | if ! sudo echo "" > /dev/null 2>&1; then 12 | echo >&2 "ERROR: Must have sudo privileges to modify configuration files." 13 | exit 1 14 | fi 15 | fi 16 | 17 | systemd_cmd="systemctl mask ${TARGETS}" 18 | 19 | # shellcheck disable=2086 20 | if ! sudo $systemd_cmd; then 21 | echo >&2 "ERROR: Failed to disable sleep/suspend/hibernate targets." 22 | exit 1 23 | fi 24 | 25 | echo "Disabled systemd sleep/suspend/hibernate targets." 26 | exit 0 27 | -------------------------------------------------------------------------------- /systemd/list-enabled.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List enabled systemd units 3 | 4 | hash systemctl 2>/dev/null || { echo >&2 "You need to install systemd. Aborting."; exit 1; } 5 | hash grep 2>/dev/null || { echo >&2 "You need to install grep. Aborting."; exit 1; } 6 | hash awk 2>/dev/null || { echo >&2 "You need to install awk. Aborting."; exit 1; } 7 | 8 | systemctl list-unit-files | grep enabled | awk '{ print $1 }' | sort 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /systemd/list-running.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # List enabled systemd units 3 | 4 | hash systemctl 2>/dev/null || { echo >&2 "You need to install systemd. Aborting."; exit 1; } 5 | hash grep 2>/dev/null || { echo >&2 "You need to install grep. Aborting."; exit 1; } 6 | hash awk 2>/dev/null || { echo >&2 "You need to install awk. Aborting."; exit 1; } 7 | 8 | systemctl | grep running | awk '{ print $1 }' | sort 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /systemd/plot-boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # creates a plot of system boot tasks 3 | # the plot can be used to determine which 4 | # startup tasks are taking the longest time 5 | # to complete 6 | 7 | hash systemd-analyze 2>/dev/null || { echo >&2 "This system does not appear to use systemd (the systemd package was not detected). Aborting."; exit 1; } 8 | 9 | # determine the directory this script is in and store it in SCRIPT_DIR 10 | SOURCE="${BASH_SOURCE[0]}" 11 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 12 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 13 | SOURCE="$(readlink "$SOURCE")" 14 | # if $SOURCE was a relative symlink, we need to resolve it relative to the path where 15 | # the symlink file was located 16 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 17 | done 18 | SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 19 | 20 | OUT_FILE="$SCRIPT_DIR/boot.svg" 21 | 22 | echo "Generating systemd plot file $OUT_FILE ..." 23 | 24 | systemd-analyze plot > "$OUT_FILE" 25 | 26 | echo " done." 27 | 28 | exit 0 29 | -------------------------------------------------------------------------------- /systemd/plot-services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # creates a plot of systemd services 3 | 4 | hash systemd-analyze 2>/dev/null || { echo >&2 "This system does not appear to use systemd (the systemd package was not detected). Aborting."; exit 1; } 5 | hash dot 2>/dev/null || { echo >&2 "You need to install graphviz. Aborting."; exit 1; } 6 | 7 | # determine the directory this script is in and store it in SCRIPT_DIR 8 | SOURCE="${BASH_SOURCE[0]}" 9 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 10 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 11 | SOURCE="$(readlink "$SOURCE")" 12 | # if $SOURCE was a relative symlink, we need to resolve it relative to the path where 13 | # the symlink file was located 14 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 15 | done 16 | SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 17 | 18 | OUT_FILE="$SCRIPT_DIR/services.svg" 19 | 20 | echo "Generating systemd service plot file $OUT_FILE ..." 21 | 22 | systemd-analyze dot --to-pattern='*.service' --from-pattern='*.service' | dot -Tsvg > "$OUT_FILE" 23 | 24 | echo " done." 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /systemd/plot-targets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # creates a plot of systemd targets 3 | 4 | hash systemd-analyze 2>/dev/null || { echo >&2 "This system does not appear to use systemd (the systemd package was not detected). Aborting."; exit 1; } 5 | hash dot 2>/dev/null || { echo >&2 "You need to install graphviz. Aborting."; exit 1; } 6 | 7 | # determine the directory this script is in and store it in SCRIPT_DIR 8 | SOURCE="${BASH_SOURCE[0]}" 9 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 10 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 11 | SOURCE="$(readlink "$SOURCE")" 12 | # if $SOURCE was a relative symlink, we need to resolve it relative to the path where 13 | # the symlink file was located 14 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 15 | done 16 | SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 17 | 18 | OUT_FILE="$SCRIPT_DIR/targets.svg" 19 | 20 | echo "Generating systemd targets plot file $OUT_FILE ..." 21 | 22 | systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > "$OUT_FILE" 23 | 24 | echo " done." 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /tripwire/dump-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # TripWire Dump Config 3 | 4 | hash tripwire 2>/dev/null || { echo >&2 "You need to install tripwire. Aborting."; exit 1; } 5 | 6 | if [[ $EUID -ne 0 ]]; then 7 | echo "This script must be run as root." >&2 8 | exit 1 9 | fi 10 | 11 | SOURCE="${BASH_SOURCE[0]}" 12 | # resolve $SOURCE until the file is no longer a symlink 13 | while [ -h "$SOURCE" ]; do 14 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 15 | SOURCE="$(readlink "$SOURCE")" 16 | # if $SOURCE was a relative symlink, we need to resolve 17 | # it relative to the path where the symlink file was located 18 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 19 | done 20 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 21 | 22 | DIR="/etc/tripwire" 23 | 24 | if [ ! -e "$DIR/tw.cfg" ]; then 25 | echo >&2 "ERROR: Configuration file '$DIR/tw.cfg' does not exist." 26 | exit 1 27 | fi 28 | if [ ! -e "$DIR/tw.pol" ]; then 29 | echo >&2 "ERROR: Policy configuration '$DIR/tw.pol' does not exist." 30 | exit 1 31 | fi 32 | 33 | echo "Writing policy configuration to $DIR/twpol.txt ..." 34 | if ! twadmin --print-polfile > "$DIR/twpol.txt"; then 35 | echo >&2 "ERROR: Failed to write policy configuration." 36 | fi 37 | 38 | echo "Writing Tripwire configuration to $DIR/twcfg.txt ..." 39 | if ! twadmin --print-cfgfile > "$DIR/twcfg.txt"; then 40 | echo >&2 "ERROR: Failed to write Tripwire configuration." 41 | fi 42 | 43 | echo "Setting permissions on plaintext configuration files ..." 44 | chmod 600 -v "$DIR/twpol.txt" 45 | chmod 600 -v "$DIR/twcfg.txt" 46 | 47 | echo "Plaintext configuration files dumped to $DIR" 48 | 49 | exit 0 50 | -------------------------------------------------------------------------------- /tripwire/print-latest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # TripWire Print Script 3 | 4 | REPORT_DIR="/var/lib/tripwire/report" 5 | 6 | hash tripwire 2>/dev/null || { echo >&2 "You need to install tripwire. Aborting."; exit 1; } 7 | 8 | if [[ $EUID -ne 0 ]]; then 9 | echo "This script must be run as root" >&2 10 | exit 1 11 | fi 12 | 13 | # Get the filename of the newest report 14 | REPORT=$(find "$REPORT_DIR" -type f -printf "%T@ %p\n" | sort -k1 -n | tail -n1 | cut -d' ' -f 2-) 15 | if [[ -z "$REPORT" ]]; then 16 | echo "Fatal: Couldn't find latest report, exiting..." >&2 17 | exit 1 18 | else 19 | echo "Printing report: $REPORT" 20 | fi 21 | 22 | if ! twprint -m r --twrfile "$REPORT"; then 23 | exit 1 24 | fi 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /tripwire/update-latest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # TripWire Update Script 3 | 4 | REPORT_DIR="/var/lib/tripwire/report" 5 | 6 | hash tripwire 2>/dev/null || { echo >&2 "You need to install tripwire. Aborting."; exit 1; } 7 | 8 | if [[ $EUID -ne 0 ]]; then 9 | echo "This script must be run as root" >&2 10 | exit 1 11 | fi 12 | 13 | # Get the filename of the newest report 14 | REPORT=$(find "$REPORT_DIR" -type f -printf "%T@ %p\n" | sort -k1 -n | tail -n1 | cut -d' ' -f 2-) 15 | if [[ -z "$REPORT" ]]; then 16 | echo "Fatal: Couldn't find latest report, exiting..." >&2 17 | exit 1 18 | else 19 | echo "Updating report: $REPORT" 20 | fi 21 | 22 | if ! tripwire --update --twrfile "$REPORT" && tripwire --init; then 23 | exit 1 24 | fi 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /tripwire/update-policy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Update tw.pol from twpol.txt 3 | # To get the decoded file: 4 | # sudo sh -c 'twadmin --print-polfile > /etc/tripwire/twpol.txt' 5 | 6 | hash sudo 2>/dev/null || { echo >&2 "You need to install sudo. Aborting."; exit 1; } 7 | hash tripwire 2>/dev/null || { echo >&2 "You need to install tripwire. Aborting."; exit 1; } 8 | 9 | if [ ! -e "/etc/tripwire" ]; then 10 | echo >&2 "ERROR: Tripwire configuration directory '/etc/tripwire' does not exist." 11 | exit 1 12 | fi 13 | 14 | if [ ! -e "/etc/tripwire/site.key" ]; then 15 | echo >&2 "ERROR: Missing site key '/etc/tripwire/site.key' (required)." 16 | exit 1 17 | fi 18 | if [ ! -e "/etc/tripwire/$HOSTNAME-local.key" ]; then 19 | echo >&2 "ERROR: Missing local key file '/etc/tripwire/$HOSTNAME-local.key'." 20 | exit 1 21 | fi 22 | 23 | if [ ! -e "/etc/tripwire/twpol.txt" ]; then 24 | echo >&2 "ERROR: Missing unencrypted configuration file '/etc/tripwire/twpol.txt'." 25 | exit 1 26 | fi 27 | 28 | # Re-generate policy file 29 | if ! sudo twadmin --create-polfile "/etc/tripwire/twpol.txt"; then 30 | echo "ERROR: Failed to create new encrypted policy file." >&2 31 | exit 1 32 | fi 33 | 34 | if ! sudo tripwire --init; then 35 | echo "ERROR: Database initialization failed." >&2 36 | exit 1 37 | fi 38 | 39 | exit 0 40 | -------------------------------------------------------------------------------- /update-geoip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # downloads the latest GeoLine City database 3 | 4 | DOWNLOAD_URL="http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz" 5 | 6 | wget -O GeoLiteCity.dat.gz "$DOWNLOAD_URL" 7 | 8 | gunzip -v -f GeoLiteCity.dat.gz 9 | -------------------------------------------------------------------------------- /update-pcidb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # updates the PCI ID database 3 | 4 | DOWNLOAD_URL="https://github.com/pciutils/pciids/raw/master/pci.ids" 5 | # DOWNLOAD_URL="http://pci-ids.ucw.cz/v2.2/pci.ids" 6 | 7 | hash wget 2>/dev/null || { echo >&2 "You need to install wget. Aborting."; exit 1; } 8 | 9 | # download the database 10 | wget -N $DOWNLOAD_URL 11 | -------------------------------------------------------------------------------- /url-decode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # decodes a url using built-in python method 3 | # rwb[at]0x19e[dot]net 4 | 5 | hash python 2>/dev/null || { echo >&2 "You need to install python. Aborting."; exit 1; } 6 | 7 | INPUT="$1" 8 | 9 | if [[ -z "$INPUT" ]]; then 10 | echo >&2 "Usage: $0 " 11 | exit 0 12 | fi 13 | 14 | python -c "import sys, urllib as ul; print ul.unquote_plus(\"$INPUT\")" 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /url-encode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # decodes a url using built-in python method 3 | # rwb[at]0x19e[dot]net 4 | 5 | hash python 2>/dev/null || { echo >&2 "You need to install python. Aborting."; exit 1; } 6 | 7 | INPUT="$1" 8 | 9 | if [[ -z "$INPUT" ]]; then 10 | echo >&2 "Usage: $0 " 11 | exit 0 12 | fi 13 | 14 | python -c "import sys, urllib as ul; print ul.quote_plus(\"$INPUT\")" 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /usbreset-ehci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # resets a USB device 3 | 4 | # the USB driver to use 5 | USB_DRIVER="ehci_hcd" 6 | 7 | if [[ -z "$1" ]]; then 8 | echo "Usage: $0 " >&2 9 | exit 1 10 | fi 11 | 12 | # check if superuser 13 | if [[ $EUID -ne 0 ]]; then 14 | echo >&2 "This script must be run as root." 15 | exit 1 16 | fi 17 | 18 | USB_DEVICE="$1" 19 | 20 | if [ ! -e "/sys/bus/pci/drivers/$USB_DRIVER/$USB_DEVICE" ]; then 21 | echo "The specified USB device could not be found." >&2 22 | exit 1 23 | fi 24 | 25 | echo "Resetting USB device /sys/bus/pci/drivers/$USB_DRIVER/$USB_DEVICE ..." 26 | 27 | echo -n "$USB_DEVICE" | tee "/sys/bus/pci/drivers/$USB_DRIVER/unbind" 28 | echo -n "$USB_DEVICE" | tee "/sys/bus/pci/drivers/$USB_DRIVER/bind" 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /usbreset-xhci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # resets a USB device 3 | 4 | # the USB driver to use 5 | USB_DRIVER="xhci_hcd" 6 | 7 | if [[ -z "$1" ]]; then 8 | echo "Usage: $0 " >&2 9 | exit 1 10 | fi 11 | 12 | # check if superuser 13 | if [[ $EUID -ne 0 ]]; then 14 | echo >&2 "This script must be run as root." 15 | exit 1 16 | fi 17 | 18 | USB_DEVICE="$1" 19 | 20 | if [ ! -e "/sys/bus/pci/drivers/$USB_DRIVER/$USB_DEVICE" ]; then 21 | echo "The specified USB device could not be found." >&2 22 | exit 1 23 | fi 24 | 25 | echo "Resetting USB device /sys/bus/pci/drivers/$USB_DRIVER/$USB_DEVICE ..." 26 | 27 | echo -n "$USB_DEVICE" | tee "/sys/bus/pci/drivers/$USB_DRIVER/unbind" 28 | echo -n "$USB_DEVICE" | tee "/sys/bus/pci/drivers/$USB_DRIVER/bind" 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /wikipedia.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # define a keyword using wikipedia by DNS 3 | # rwb[at]0x19e[dot]net 4 | 5 | hash curl 2>/dev/null || { echo >&2 "You need to install curl. Aborting."; exit 1; } 6 | hash jq 2>/dev/null || { echo >&2 "You need to install jq. Aborting."; exit 1; } 7 | hash sed 2>/dev/null || { echo >&2 "You need to install sed. Aborting."; exit 1; } 8 | 9 | if [[ -z "$1" ]]; then 10 | echo >&2 "Usage: $0 " 11 | exit 1 12 | fi 13 | 14 | # alternative way to query (not as reliable) 15 | #dig +short txt ${1}.wp.dg.cx 16 | 17 | LANG="en" 18 | 19 | # convert spaces to underscores 20 | var=$(echo "$*" | sed 's/ /_/g') 21 | 22 | # retrieve wiki data 23 | wiki_data=$(curl -s "https://$LANG.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro&explaintext&titles=$var&redirects" | jq '.query.pages | to_entries[0] | .value.extract') 24 | 25 | # eliminate quotes characters 26 | data=$(echo "$wiki_data" | sed 's/\\\"/"/g') 27 | 28 | if [[ $data = "null" ]]; then 29 | echo >&2 "ERROR: No data to fetch." 30 | exit 1 31 | fi 32 | 33 | # print result 34 | url=https://en.wikipedia.org/wiki/$var 35 | echo -e "${data:1:${#data}-2}\n" 36 | echo "See more on $url" 37 | 38 | exit 0 39 | -------------------------------------------------------------------------------- /x11notify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # X11 Notification Script 3 | # 4 | # The example below displays a reminder for the current user: 5 | # export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ); 6 | # /usr/bin/notify-send -i appointment -c "im" "Example reminder" --icon=dialog-warning 7 | 8 | if [ -z "$1" ]; then 9 | echo >&2 "Usage: $0 " 10 | exit 1 11 | fi 12 | 13 | MESSAGE="$1" 14 | CATEGORY="alerts" 15 | URGENCY="normal" 16 | ICON="dialog-information" 17 | 18 | hash notify-send 2>/dev/null || { echo >&2 "You need to install libnotify-bin. Aborting."; exit 1; } 19 | 20 | # Get required paths 21 | NOTIFY_SEND=$(which notify-send) 22 | 23 | # Get a list of active sessions 24 | SESSIONS=$(w -hs | awk -v tty="$(cat /sys/class/tty/tty0/active)" '$2 == tty && $3 != "-" {print $1 FS $3}') 25 | 26 | # Process each session 27 | IFS=$'\n' 28 | for SESSION in ${SESSIONS}; do 29 | USER=$(echo "${SESSION}" | awk '{print $1}') 30 | DISP=$(echo "${SESSION}" | awk '{print $2}') 31 | 32 | echo "Sending message to ${USER} on display ${DISP} ..." 33 | export DISPLAY=${DISP}; 34 | export "$(grep -z DBUS_SESSION_BUS_ADDRESS "/proc/$(pgrep -u "${USER}" gnome-session)/environ")" 35 | ${NOTIFY_SEND} -u "${URGENCY}" -c "${CATEGORY}" "${MESSAGE}" -i "${ICON}" 36 | done 37 | 38 | exit 0 39 | -------------------------------------------------------------------------------- /xen/create-domain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # create a new xen domain 3 | # this script also checks for post-up scripts 4 | # following the format '.sh' 5 | # requires xen-tools package (xl) toolchain 6 | # [0x19e Networks] rwb@0x19e.net 7 | 8 | # check if xl command exists 9 | hash xl 2>/dev/null || { echo >&2 "You need to install xen-tools. Aborting."; exit 1; } 10 | 11 | # check if superuser 12 | if [[ $EUID -ne 0 ]]; then 13 | echo "This script must be run as root." >&2 14 | exit 1 15 | fi 16 | 17 | if [ -z "$1" ]; then 18 | echo "Usage: $0 " >&2 19 | exit 1 20 | fi 21 | 22 | DOMAIN_NAME="$1" 23 | DOMAIN_CONF="/etc/xen/$DOMAIN_NAME.cfg" 24 | POST_SCRIPT="/etc/xen/$DOMAIN_NAME.sh" 25 | 26 | if [ ! -f "$DOMAIN_CONF" ]; then 27 | echo "Failed to find domain configuration $DOMAIN_CONF" >&2 28 | exit 1 29 | fi 30 | 31 | # check if domain is already running 32 | PS_OUT=$(pgrep -f 'xl\screate\s.*\/etc\/xen\/'"$DOMAIN_NAME"'\.cfg') 33 | if [ -n "$PS_OUT" ]; then 34 | pid=$(echo "$PS_OUT" | awk '{print $1}') 35 | if ( kill -0 "$pid" > /dev/null 2>&1; ); then 36 | echo "The domain $DOMAIN_NAME is already running under xl on pid $pid" 37 | exit 1 38 | fi 39 | fi 40 | 41 | # create the new domain 42 | xl create "$DOMAIN_CONF" 43 | 44 | if [ -x "$POST_SCRIPT" ]; then 45 | echo "Running post-script $POST_SCRIPT ..." 46 | $POST_SCRIPT "$DOMAIN_NAME" 47 | fi 48 | -------------------------------------------------------------------------------- /xen/get-vnc-port.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # gets the vnc port for a named qemu domain 3 | # [0x19e Networks] rwb@0x19e.net 4 | 5 | # check if superuser 6 | if [[ $EUID -ne 0 ]]; then 7 | echo "This script must be run as root" >&2 8 | exit 1 9 | fi 10 | 11 | if [ "$1" = "" ]; then 12 | echo "Usage: $0 " >&2 13 | exit 1 14 | fi 15 | 16 | NAME="$1" 17 | PID=$(pgrep -f '^(\/usr)?(\/lib)?(\/xen\-[1-9](\.[0-9]{1,2}))\/bin\/qemu.*\-name\s'"${NAME}") 18 | 19 | if [[ -z "$PID" ]]; then 20 | echo "ERROR: Failed to find qemu pid for '$NAME'" >&2 21 | exit 1 22 | fi 23 | 24 | # get the port number 25 | PORT=$(lsof -nPi | grep "$PID" | awk '{print $9}' | awk -F":" '{print $2}') 26 | 27 | # check to make sure value is a valid port 28 | re='^[0-9]+$' 29 | if ! [[ $PORT =~ $re ]] ; then 30 | echo >&2 "ERROR: '$PORT' is not a valid port number" 31 | exit 1 32 | fi 33 | 34 | echo "$PORT" 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /xen/ps-xen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # list xen and qemu processes 3 | # [0x19e Networks] rwb@0x19e.net 4 | 5 | procs=$(pgrep -af 'xl|qemu|xen' | grep -v "$0") 6 | if [[ -z "$procs" ]]; then 7 | echo "No processes found." 8 | exit 1 9 | fi 10 | 11 | echo "$procs" 12 | exit 0 13 | --------------------------------------------------------------------------------