From 0be1602bd562f3ff37950badf48f167d6a3f6101 Mon Sep 17 00:00:00 2001 From: ste vaidis Date: Tue, 22 Sep 2026 04:37:10 +0300 Subject: [PATCH] better readme --- README.md | 108 ++---------- cheatsheets/firewall.md | 29 ++++ cheatsheets/network_settings.md | 57 +++++++ cheatsheets/rc.server.ksh | 14 ++ packages/.grep.ksh.swp | Bin 0 -> 12288 bytes packages/grep.ksh | 3 + security/audit.ksh | 285 ++++++++++++++++++++++++++++++++ 7 files changed, 398 insertions(+), 98 deletions(-) create mode 100644 cheatsheets/firewall.md create mode 100644 cheatsheets/network_settings.md create mode 100644 cheatsheets/rc.server.ksh create mode 100644 packages/.grep.ksh.swp create mode 100644 packages/grep.ksh create mode 100644 security/audit.ksh diff --git a/README.md b/README.md index b798d75..9a29df4 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,28 @@ # OpenBSD-Notes +Time saver scripts installing and configuring basic stuff on secure OpenBSD installations + ## Enviroment -- Better prompt: Colors, Git, Exit Code, -- Color ls +- prompt : color prompt, git branch, latest exit Code +- navigation: color ls +- working : color grep, git aliases (ga, gs, gd, gc, gp) ## Packages -- vim -- git -- iftop, tcodump - +- vim (no plugins, monokai theme, extra keymaps, intro screen for keymaps) +- git, ggrep +- iftop, tcpdump ## Vim - Keymaps - Theme - +## Networking +- netstat-tulp.ksh (from linux) set -o vi -## Networking - -Dynamic IP Address - -`vi /etc/hostname.em0` - -```sh -dhcp -``` - -Static IP Address - -`vi /etc/hostname.stge0` - -```sh -media 100baseTX -mediaopt full-duplex -inet 192.168.2.1 0xffffff00 -``` -Routing - -```sh -route show -netstat -r -netstat -r -n -netstat -r -f inet -n -``` - -Default Gateway - -`vi /etc/mygate` - -```sh -192.168.1.1 -``` - -Hostname - -`vi /etc/myname` - -```sh -echo 'OpenBSD' > /etc/myname -hostname OpenBSD -``` - -Reload -```sh - -``` - -DNS - -`vi /etc/resolv.conf` - -```sh -nameserver 9.9.9.9 -nameserver 1.1.1.1 -``` - -# Firewall - -Control - -```sh -pfctl -sr # view rules -pfctl -ss # view state -pfctl -si # view stats -pfctl -sa # view all -``` - -Write Rules - -`/etc/pf.conf` - -```sh -lan = stge0 -block out tcp from $lan to any port {80,443} -``` - -Apply rules - -```sh -pfctl -d -pfctl -f /etc/pf.conf -pfctl -e -``` - - -# Gitea - - # WEB SERVER diff --git a/cheatsheets/firewall.md b/cheatsheets/firewall.md new file mode 100644 index 0000000..93cacfe --- /dev/null +++ b/cheatsheets/firewall.md @@ -0,0 +1,29 @@ +# Firewall + +### Show rules + +```sh +pfctl -sr # view rules +pfctl -ss # view state +pfctl -si # view stats +pfctl -sa # view all +``` + +### Write rules + +`/etc/pf.conf` + +```sh +lan = stge0 +block out tcp from $lan to any port {80,443} +``` + +### Apply rules + +```sh +pfctl -d +pfctl -f /etc/pf.conf +pfctl -e +``` + + diff --git a/cheatsheets/network_settings.md b/cheatsheets/network_settings.md new file mode 100644 index 0000000..ef0be15 --- /dev/null +++ b/cheatsheets/network_settings.md @@ -0,0 +1,57 @@ +## Networking + +### Set IP Address on interface `em0` + +`vim /etc/hostname.em0` + +Dynamic + +``` +dhcp +``` + +Static + +```sh +media 100baseTX +mediaopt full-duplex +inet 192.168.2.1 0xffffff00 +``` +### Routing + +Show table + +```sh +route show +netstat -r +netstat -r -n +netstat -r -f inet -n +``` + +Set default Gateway + +`vi /etc/mygate` + +```sh +192.168.1.1 +``` + +### Set hostname + +`vi /etc/myname` + +```sh +echo 'OpenBSD' > /etc/myname +hostname OpenBSD +``` + +### Set DNS + +`vi /etc/resolv.conf` + +```sh +nameserver 9.9.9.9 +nameserver 1.1.1.1 +``` + + diff --git a/cheatsheets/rc.server.ksh b/cheatsheets/rc.server.ksh new file mode 100644 index 0000000..ac45217 --- /dev/null +++ b/cheatsheets/rc.server.ksh @@ -0,0 +1,14 @@ +#!/bin/ksh + +daemon="/usr/local/bin/node" +daemon_user="_stevault" +daemon_execdir="/usr/obj/stevault/backend" +daemon_flags="/usr/obj/stevault/backend/dist/index.js" +daemon_logger="daemon.info" + +. /etc/rc.d/rc.subr + +rc_reload=NO +rc_bg=YES +rc_cmd $1 + diff --git a/packages/.grep.ksh.swp b/packages/.grep.ksh.swp new file mode 100644 index 0000000000000000000000000000000000000000..28dee089ec81aa78ce2211b78fd2c11c5689b05a GIT binary patch literal 12288 zcmeI2Jx|+E6oyawF+wTbs|ySWiP%X{hYl)RygJAqo>2vanF5 zc4&7%0b49;(S1oX32u|Ug`1m{W#~|`*^bK_0-#iMfFn42+D}a zk6&Lm52i&jUqpP@4WsUUrDzoLp;j~;(+M=I&~th@N~pi`toPYBbIBz)v;w{8Z0ojf zdD>R6(KC<(G(ZCbFfb%DnRF^jG%-G=o{cUKASYAM01eOp4bT7$&;Sk401ez11EH6Y zU2OJ2yy1s&ow!rSO;$8O12jMbG(ZD1Km#;D12jMbG(ZFQ(12lze10Nw38L@+jrac> zw6Eg+Q`A4fH*f)t!4WtFAHY7Sf(qCJ0r0^pSOKp=79_z_Fa#chN8sL5`IdNiD>P*@{Bwo4u zc518NUazgyaogNTG}1O&KU>>Tx{lrLthbvvn~oZJx{S0=@&Dk~JR8;;@^h}H%DU$H g?mH)MiII1VKt&H`cCt04@i->M+p^aT)2xTfKmTCZ)Bpeg literal 0 HcmV?d00001 diff --git a/packages/grep.ksh b/packages/grep.ksh new file mode 100644 index 0000000..6ba3633 --- /dev/null +++ b/packages/grep.ksh @@ -0,0 +1,3 @@ +pkg_add ggrep +alias grep='ggrep --color=auto' +. ~/.profile diff --git a/security/audit.ksh b/security/audit.ksh new file mode 100644 index 0000000..8c92c1c --- /dev/null +++ b/security/audit.ksh @@ -0,0 +1,285 @@ +#!/bin/ksh +# +# First-login security audit for OpenBSD. +# +# This script is intentionally diagnostic: it does not repair, install, or +# reconfigure the host. OpenBSD security(8) may rotate its normal comparison +# state in /var/backups, just as it does during the daily security run. +# This script cannot prove that a host is clean. +# A root-level attacker may alter the kernel, commands, logs, or this script's +# view of the system. Treat warnings as reasons to investigate and credible +# evidence of root compromise as a reason to isolate and reinstall the host. +# +# Exit status: +# 0 No automatic red flags were found (not proof that the host is clean). +# 1 One or more findings require manual review. +# 2 The audit could not run correctly. + +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin +export PATH + +umask 077 + +WARNINGS=0 +ERRORS=0 + +heading() +{ + printf '\n===== %s =====\n' "$1" +} + +pass() +{ + printf '[PASS] %s\n' "$1" +} + +info() +{ + printf '[INFO] %s\n' "$1" +} + +warn() +{ + printf '[WARN] %s\n' "$1" + WARNINGS=$((WARNINGS + 1)) +} + +error() +{ + printf '[ERROR] %s\n' "$1" >&2 + ERRORS=$((ERRORS + 1)) +} + +print_file() +{ + if [ -s "$1" ]; then + sed 's/^/ /' "$1" + fi +} + +if [ "$(id -u)" -ne 0 ]; then + printf 'Run this audit as root, for example:\n' >&2 + printf ' doas %s\n' "$0" >&2 + exit 2 +fi + +if [ "$(uname -s)" != "OpenBSD" ]; then + printf 'This script is intended only for OpenBSD.\n' >&2 + exit 2 +fi + +AUDIT_TMPDIR=$(mktemp -d /tmp/openbsd-audit.XXXXXXXXXX) || { + printf 'Cannot create temporary audit directory.\n' >&2 + exit 2 +} + +cleanup() +{ + case "$AUDIT_TMPDIR" in + /tmp/openbsd-audit.*) + /bin/rm -rf "$AUDIT_TMPDIR" + ;; + esac +} + +case "$AUDIT_TMPDIR" in + /tmp/openbsd-audit.*) + trap cleanup EXIT + trap 'exit 2' HUP INT TERM + ;; + *) + printf 'Refusing unexpected temporary path: %s\n' "$AUDIT_TMPDIR" >&2 + exit 2 + ;; +esac + +heading "IMPORTANT LIMITATION" +cat <<'EOF' +This report can find common integrity and persistence problems, but it cannot +certify that the host is unhacked. A sufficiently privileged attacker can +make a running system lie. For strong assurance, inspect from trusted boot +media or reinstall from verified OpenBSD media and rotate exposed secrets. +EOF + +heading "SYSTEM IDENTITY" +printf 'Date (UTC): %s\n' "$(date -u '+%Y-%m-%d %H:%M:%S UTC')" +printf 'Hostname: %s\n' "$(hostname)" +printf 'Kernel: %s\n' "$(uname -a)" +printf 'Architecture: %s\n' "$(machine 2>/dev/null || uname -m)" +printf 'Uptime: %s\n' "$(uptime)" + +if [ -n "${SSH_CONNECTION:-}" ]; then + set -- $SSH_CONNECTION + printf 'SSH source: %s:%s\n' "$1" "$2" + printf 'SSH destination: %s:%s\n' "$3" "$4" +else + printf 'SSH connection: not detected\n' +fi + +SECURELEVEL=$(sysctl -n kern.securelevel 2>/dev/null) +if [ -z "$SECURELEVEL" ]; then + error "Could not read kern.securelevel" +elif [ "$SECURELEVEL" -ge 1 ] 2>/dev/null; then + pass "kern.securelevel is $SECURELEVEL" +else + warn "kern.securelevel is $SECURELEVEL; review why it is below 1" +fi + +heading "OPENBSD SECURITY(8)" +SECURITY_OUT="$AUDIT_TMPDIR/security.out" +/usr/libexec/security >"$SECURITY_OUT" 2>&1 +SECURITY_RC=$? + +if [ "$SECURITY_RC" -ne 0 ]; then + warn "security(8) exited with status $SECURITY_RC" + print_file "$SECURITY_OUT" +elif [ -s "$SECURITY_OUT" ]; then + warn "security(8) produced findings; review every line" + print_file "$SECURITY_OUT" +else + pass "security(8) produced no findings" +fi + +heading "BASE SYSTEM PATCHES" +printf '%s\n' "Installed syspatches:" +syspatch -l 2>&1 | sed 's/^/ /' + +SYSPATCH_OUT="$AUDIT_TMPDIR/syspatch.out" +syspatch -c >"$SYSPATCH_OUT" 2>&1 +SYSPATCH_RC=$? + +if [ "$SYSPATCH_RC" -ne 0 ]; then + warn "Could not reliably check for missing syspatches (status $SYSPATCH_RC)" + print_file "$SYSPATCH_OUT" +elif [ -s "$SYSPATCH_OUT" ]; then + warn "Available syspatches are not installed" + print_file "$SYSPATCH_OUT" +else + pass "No missing syspatches were reported" +fi + +heading "INSTALLED PACKAGE INTEGRITY" +PKG_OUT="$AUDIT_TMPDIR/pkg-check.out" +pkg_check -n -F -x >"$PKG_OUT" 2>&1 +PKG_RC=$? + +if [ "$PKG_RC" -ne 0 ]; then + warn "pkg_check reported an error (status $PKG_RC)" + print_file "$PKG_OUT" +elif [ -s "$PKG_OUT" ]; then + warn "pkg_check produced output; review package checksums and extra objects" + print_file "$PKG_OUT" +else + pass "Installed package files and checksums passed pkg_check" +fi + +heading "PRIVILEGED ACCOUNTS" +UID0_OUT="$AUDIT_TMPDIR/uid0.out" +awk -F: '$3 == 0 { print $1 ":" $7 }' /etc/master.passwd >"$UID0_OUT" +printf '%s\n' "Accounts with UID 0:" +print_file "$UID0_OUT" + +UID0_COUNT=$(wc -l <"$UID0_OUT" | tr -d ' ') +if [ "$UID0_COUNT" -eq 1 ] && grep -q '^root:' "$UID0_OUT"; then + pass "Only root has UID 0" +else + warn "Expected exactly one UID 0 account named root" +fi + +heading "SSH AUTHORIZED KEYS" +KEY_LIST="$AUDIT_TMPDIR/authorized-keys.list" +find /root /home -type f -path '*/.ssh/authorized_keys' -print \ + 2>/dev/null >"$KEY_LIST" + +if [ ! -s "$KEY_LIST" ]; then + info "No authorized_keys files were found" +else + while IFS= read -r KEY_FILE; do + printf '%s\n' "File: $KEY_FILE" + ls -ld "$KEY_FILE" | sed 's/^/ /' + ssh-keygen -lf "$KEY_FILE" 2>&1 | sed 's/^/ /' + done <"$KEY_LIST" + info "Confirm that every SSH key fingerprint belongs to an authorized person" +fi + +heading "RC SERVICES" +printf '%s\n' "Enabled services:" +rcctl ls on 2>&1 | sed 's/^/ /' + +printf '%s\n' "Currently started services:" +rcctl ls started 2>&1 | sed 's/^/ /' + +FAILED_RC="$AUDIT_TMPDIR/rc-failed.out" +rcctl ls failed >"$FAILED_RC" 2>&1 +FAILED_RC_STATUS=$? + +if [ "$FAILED_RC_STATUS" -ne 0 ]; then + warn "Could not query failed rc services" + print_file "$FAILED_RC" +elif [ -s "$FAILED_RC" ]; then + warn "Some enabled services are in a failed state" + print_file "$FAILED_RC" +else + pass "No failed rc services were reported" +fi + +heading "CRON PERSISTENCE LOCATIONS" +if [ -d /var/cron/tabs ]; then + find /var/cron/tabs -type f -exec ls -ld {} \; 2>/dev/null +else + warn "/var/cron/tabs does not exist" +fi +info "Review the content of every expected user crontab manually" + +heading "RECENT LOGINS" +last -20 2>&1 + +heading "RECENT SSH AUTHENTICATION EVENTS" +if [ -r /var/log/authlog ]; then + grep -Ei 'accepted|failed|invalid user|authentication' /var/log/authlog \ + 2>/dev/null | tail -50 +else + warn "Cannot read /var/log/authlog" +fi + +heading "RUNNING PROCESSES" +ps auxww + +heading "INTERNET SOCKETS AND CONNECTIONS" +FSTAT_NET="$AUDIT_TMPDIR/fstat-network.out" +fstat -n 2>/dev/null | grep -E 'internet|internet6' >"$FSTAT_NET" + +if [ -s "$FSTAT_NET" ]; then + cat "$FSTAT_NET" + info "Confirm that every listener and remote connection is expected" +else + info "No internet sockets were reported by fstat" +fi + +heading "PF STATUS AND RULES" +pfctl -si 2>&1 +printf '\nFilter rules:\n' +pfctl -sr 2>&1 +printf '\nNAT and redirection rules:\n' +pfctl -sn 2>&1 + +heading "FILESYSTEMS" +mount +df -h + +heading "AUDIT RESULT" +if [ "$ERRORS" -gt 0 ]; then + printf '[ERROR] Audit incomplete: %d error(s), %d warning(s).\n' \ + "$ERRORS" "$WARNINGS" + printf 'Do not treat this host as verified.\n' + exit 2 +elif [ "$WARNINGS" -gt 0 ]; then + printf '[WARN] Manual review required: %d warning(s).\n' "$WARNINGS" + printf 'Warnings are not proof of compromise, but they must be explained.\n' + exit 1 +else + printf '[PASS] No automatic red flags were found.\n' + printf 'This increases confidence but does not prove that the host is clean.\n' + exit 0 +fi +