Restructure repository: organize tools by purpose, create what search tool
- Move single-file tools to tools/ organized by category (security, forensics, data, etc.) - Move multi-file projects to projects/ (go-tools, puzzlebox, timesketch, rust-tools) - Move system scripts to scripts/ (proxy, display, setup, windows) - Organize config files in config/ (shell, visidata, applications) - Move experimental tools to archive/experimental - Create 'what' fuzzy search tool with progressive enhancement (ollama->fzf->grep) - Add initial metadata database for intelligent tool discovery - Preserve git history using 'git mv' commands
This commit is contained in:
51
tools/system/backup_docker.sh
Executable file
51
tools/system/backup_docker.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if the Docker Compose file was provided
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "No Docker Compose file provided"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
COMPOSE_FILE=$1
|
||||
DIR=$(dirname "${COMPOSE_FILE}")
|
||||
BASE_DIR_NAME=$(basename "${DIR}")
|
||||
BACKUP_DIR=/mnt/backups/$BASE_DIR_NAME
|
||||
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
|
||||
|
||||
# Create a new backup directory for this stack if it doesn't already exist
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# Stop the Docker Compose stack
|
||||
docker-compose -f $COMPOSE_FILE down
|
||||
|
||||
# Tarball the Docker Compose directory
|
||||
CONFIG_BACKUP_FILE="files_${DIR##*/}"_$TIMESTAMP.tar.gz
|
||||
tar -czvf $BACKUP_DIR/$CONFIG_BACKUP_FILE -C / $DIR
|
||||
|
||||
# Identify and save each Docker image used by the stack
|
||||
IMAGES=$(docker-compose -f $COMPOSE_FILE config | awk '{if ($1 == "image:") print $2;}')
|
||||
BACKUP_FILE=$BACKUP_DIR/"backup_${BASE_DIR_NAME}_${TIMESTAMP}.txt"
|
||||
|
||||
# Clear the backup list file
|
||||
echo "${COMPOSE_FILE}" > $BACKUP_FILE
|
||||
|
||||
# Write config backup file name to the backup list file
|
||||
echo $CONFIG_BACKUP_FILE >> $BACKUP_FILE
|
||||
|
||||
for IMAGE in $IMAGES; do
|
||||
# Get image id (strip off "sha256:" prefix)
|
||||
IMAGE_ID=$(docker inspect --format="{{.Id}}" $IMAGE | sed 's/sha256://')
|
||||
|
||||
# Check if the image backup file already exists
|
||||
IMAGE_BACKUP_FILE="image_${IMAGE//[:\/]/_}_${IMAGE_ID}.tar.gz"
|
||||
IMAGE_BACKUP=$BACKUP_DIR/$IMAGE_BACKUP_FILE
|
||||
if [ ! -f $IMAGE_BACKUP ]; then
|
||||
docker save $IMAGE | gzip > $IMAGE_BACKUP
|
||||
fi
|
||||
|
||||
# Write image backup file name to the backup list file
|
||||
echo $IMAGE_BACKUP_FILE >> $BACKUP_FILE
|
||||
done
|
||||
|
||||
# Restart the Docker Compose stack
|
||||
docker-compose -f $COMPOSE_FILE up -d
|
||||
65
tools/system/ltop.py
Executable file
65
tools/system/ltop.py
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import curses
|
||||
from operator import itemgetter
|
||||
import time
|
||||
|
||||
# Number of top items to be displayed
|
||||
N = 10
|
||||
|
||||
|
||||
def gen_output(item_dict, N=10):
|
||||
"""
|
||||
Generate a formatted output string for the top N items in item_dict.
|
||||
|
||||
:param item_dict: A dictionary containing items and their counts
|
||||
:param N: The number of top items to be displayed
|
||||
:return: A generator yielding formatted strings for each of the top N items
|
||||
"""
|
||||
top_items = dict(sorted(item_dict.items(), key=itemgetter(1), reverse=True)[:N])
|
||||
count_length = len(str(max(top_items.values())))
|
||||
|
||||
for i, key in enumerate(top_items):
|
||||
yield i, f'{i + 1:3} : [{top_items[key]:{count_length}}] {key}'
|
||||
|
||||
|
||||
def main(screen):
|
||||
"""
|
||||
Main function to read input lines, maintain a count of each unique line, and
|
||||
periodically display the top N lines with the highest counts using curses.
|
||||
|
||||
:param screen: A curses window object
|
||||
"""
|
||||
if not sys.stdin.isatty(): # Check if the input comes from a pipe
|
||||
# Initialize an empty dictionary to store unique input lines and their counts
|
||||
toplist = {}
|
||||
|
||||
# Set the next screen update time
|
||||
t_update = time.time() + 1
|
||||
|
||||
for line in sys.stdin:
|
||||
line = line.strip()
|
||||
|
||||
# Increment the count for each unique input line
|
||||
if line in toplist:
|
||||
toplist[line] += 1
|
||||
else:
|
||||
toplist[line] = 1
|
||||
|
||||
# Periodically update the screen with the top N lines
|
||||
if time.time() > t_update:
|
||||
for idx, line in gen_output(toplist):
|
||||
screen.addstr(idx, 0, line)
|
||||
screen.refresh()
|
||||
t_update = time.time() + 1
|
||||
|
||||
# Clean up the curses environment and print the final top N lines
|
||||
curses.endwin()
|
||||
for idx, line in gen_output(toplist):
|
||||
print(line)
|
||||
else:
|
||||
print("Usage: cat input_file.txt | ./top_lines.py")
|
||||
print("Or: ./top_lines.py < input_file.txt")
|
||||
|
||||
# Initialize the curses library, run the main function, and restore the terminal state
|
||||
curses.wrapper(main)
|
||||
57
tools/system/restore_docker.sh
Normal file
57
tools/system/restore_docker.sh
Normal file
@@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Specify your backup directory
|
||||
BACKUP_DIR=/mnt/backups
|
||||
|
||||
# List available stacks for backup
|
||||
echo "Available stacks for recovery:"
|
||||
STACKS=($(ls $BACKUP_DIR))
|
||||
|
||||
select STACK_NAME in "${STACKS[@]}"; do
|
||||
# Verify stack backup directory exists
|
||||
STACK_BACKUP_DIR=$BACKUP_DIR/$STACK_NAME
|
||||
if [ -d $STACK_BACKUP_DIR ]; then
|
||||
break
|
||||
else
|
||||
echo "Invalid selection"
|
||||
fi
|
||||
done
|
||||
|
||||
# List available backups for the stack
|
||||
echo "Available backups for stack $STACK_NAME:"
|
||||
BACKUPS=($(ls $STACK_BACKUP_DIR/backup_*.txt))
|
||||
|
||||
# Display only the timestamps
|
||||
TIMESTAMPS=("${BACKUPS[@]##*_}")
|
||||
|
||||
select CHOICE in "${TIMESTAMPS[@]}"; do
|
||||
# Get the full filename of the chosen backup
|
||||
BACKUP_FILE=$(echo "${BACKUPS[@]}" | tr ' ' '\n' | grep $CHOICE)
|
||||
if [ -f $BACKUP_FILE ]; then
|
||||
break
|
||||
else
|
||||
echo "Invalid selection"
|
||||
fi
|
||||
done
|
||||
|
||||
# Extract original Docker Compose file path
|
||||
COMPOSE_FILE=$(head -n 1 $BACKUP_FILE)
|
||||
DIR=$(dirname "${COMPOSE_FILE}")
|
||||
|
||||
# Check if stack is running and stop it
|
||||
docker-compose -f $COMPOSE_FILE down
|
||||
|
||||
# Rename existing Docker Compose directory
|
||||
mv $DIR $DIR.recovery_$(date +"%Y%m%d%H%M%S")
|
||||
|
||||
# Restore files from backup
|
||||
tar -xzvf $STACK_BACKUP_DIR/$(sed '2q;d' $BACKUP_FILE) -C /
|
||||
|
||||
# Load Docker images from backup
|
||||
tail -n +3 $BACKUP_FILE | while read IMAGE_FILE; do
|
||||
docker load < $STACK_BACKUP_DIR/$IMAGE_FILE
|
||||
done
|
||||
|
||||
# Change to the Docker Compose directory and restart the Docker Compose stack
|
||||
cd $DIR
|
||||
docker-compose up -d
|
||||
22
tools/system/watchgrowth.sh
Executable file
22
tools/system/watchgrowth.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
old_size=$(du -b "${1}" | cut -f1)
|
||||
while true; do
|
||||
sleep 1
|
||||
new_size=$(du -b "${1}" | cut -f1)
|
||||
size_diff=$(( ${new_size} - ${old_size} ))
|
||||
old_size=${new_size}
|
||||
#speed=$(( ${size_diff} / (1024*1024) ))
|
||||
progress=""
|
||||
|
||||
if [[ $# -eq 3 ]] ; then
|
||||
total=${2}
|
||||
progress_p=$(echo "2 k ${new_size} ${total} 100 / / p" | dc)
|
||||
progress="${progress_p} %"
|
||||
fi
|
||||
|
||||
speed=$(echo "2 k ${size_diff} 1024 1024 * / p" | dc)
|
||||
|
||||
echo "${progress} - ${speed} MB/s"
|
||||
done
|
||||
101
tools/system/wipe.sh
Normal file
101
tools/system/wipe.sh
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/bin/bash
|
||||
|
||||
#disabling Kernellogging to Console
|
||||
echo '2 4 1 7' > /proc/sys/kernel/printk
|
||||
|
||||
#rechnet die eine centrierierte fensterposition aus anhand von bildschirm- & fenstergröße
|
||||
# 'mitte 50'
|
||||
function mitte(){
|
||||
cols=$(tput cols)
|
||||
mitte=$(echo $(( $cols / 2 - $1 / 2 )) )
|
||||
echo $mitte
|
||||
}
|
||||
|
||||
#zeigt eine infomeldung für x-Sekunden an
|
||||
# 'info text 5'
|
||||
function info(){
|
||||
text=${1}
|
||||
text_len=$(( ${#1} + 4 ))
|
||||
timeout=${2}
|
||||
dialog --backtitle "CERTBw - Zero-Wipe" --infobox "$text" 3 $text_len; sleep $timeout
|
||||
}
|
||||
|
||||
#zeigt überischt von datenträgern an und fragt ab welcher gewipet werden soll
|
||||
function ask_4_device(){
|
||||
[ -e /tmp/devicelist ] || rm /tmp/devicelist
|
||||
lsblk -o NAME,SIZE,TYPE,FSTYPE | tail -n+2 | tr -cd ',.\n [:alnum:]' | awk '{printf "%-5s%6s %s (%s) \n" , $1,$2,$3,$4}' | sed -e "s/()//g" >/tmp/devicelist
|
||||
devlines=$(( $(cat /tmp/devicelist | wc -l) + 2 ))
|
||||
dialog --backtitle "CERTBw - Zero-Wipe" --begin 2 $(mitte 30) --title "Available Devices" --progressbox $devlines 30 --and-widget --stdout --inputbox 'Welche Platte soll gewipet werden?' 7 60 '/dev/sda' < /tmp/devicelist
|
||||
result=${?}
|
||||
return $result
|
||||
}
|
||||
|
||||
#prüft den rückgabewert des vorangegangenen 'dialog' fensters auf abbruch und startet das menu neu
|
||||
function check_result(){
|
||||
result=${?}
|
||||
if ([ $result = 1 ] || [ $result = 255 ]); then
|
||||
info 'CANCELED' 1
|
||||
menu
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
#kopiert Nullen auf das Angegebene Gerät und zeitg den Fortschritt mit 'dialog' an
|
||||
function wipe(){
|
||||
#anlegen von named pipes für den Datenstrom und Statusmeldungen
|
||||
mkfifo data
|
||||
mkfifo status
|
||||
|
||||
size_512=$(blockdev --getsz $1)
|
||||
size=$((512 * ${size_512}))
|
||||
|
||||
echo "wiping Disk $1:"
|
||||
(while read -r line
|
||||
do
|
||||
#Zusammenfassen von Informationen für das Dialogfenster in ein 'dialog' kompatibles Format
|
||||
split=$(echo $line | tr -d "%[]=<>" | xargs)
|
||||
|
||||
space=$(echo "$split" | cut -f1 -d" ")
|
||||
time=$(echo "$split" | cut -f2 -d" ")
|
||||
rate=$(echo "$split" | cut -f3 -d" ")
|
||||
prozent=$(echo "$split" | cut -f4 -d" ")
|
||||
eta=$(echo "$split" | cut -f6 -d" ")
|
||||
echo "XXX"
|
||||
echo $prozent
|
||||
echo "Wiped $space in $time so far. ($rate)"
|
||||
echo "ETA : $eta"
|
||||
echo "XXX"
|
||||
done < <(pv -f -s $size /dev/zero 1>data 2>status | dd bs=1M iflag=fullblock oflag=nocache if=data of=$1 2>/dev/null | stdbuf -oL tr "\r" "\n" <status) ) | dialog --backtitle "CERTBw - Zero-Wipe" --title "Wiping $1" --gauge "Please wait" 7 70 0
|
||||
rm data
|
||||
rm status
|
||||
}
|
||||
|
||||
function menu(){
|
||||
menu=$(dialog --stdout --backtitle "CERTBw - Zero-Wipe" --title "Wiping Complete" --menu "Action:" 0 0 5 1 Reboot 2 Poweroff 3 Verify 4 Re-Wipe 5 Shell)
|
||||
case "$menu" in
|
||||
1) info "REBOOTING" 1; reboot
|
||||
exit 0
|
||||
;;
|
||||
2) info "SHUTTING DOWN" 1; poweroff
|
||||
exit 0
|
||||
;;
|
||||
3) info "Verify - Not yet implemented" 3
|
||||
menu
|
||||
;;
|
||||
4) /etc/wipe.sh
|
||||
exit 0
|
||||
;;
|
||||
5) exit 0
|
||||
;;
|
||||
*) info 'CANCELED' 1
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
##simpler ablauf
|
||||
drive=$(ask_4_device)
|
||||
check_result
|
||||
wipe $drive
|
||||
menu
|
||||
exit 0
|
||||
Reference in New Issue
Block a user