problem area

Cybersecurity Triage

Defensive commands for checking exposure, logs, permissions, and suspicious activity.

33 checked fixes

One-liners in this area

Cybersecurity Triage safe

Extract Environment Names Only

Audit environment labels without printing secret values.

grep -RhoE 'ENVIRONMENT|NODE_ENV|APP_ENV|RAILS_ENV' config deploy | sort -u
Cybersecurity Triage caution

Inspect Container Environment Names

Check what environment variables exist without printing their secret values.

docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' api | sed 's/=.*$/=/'
Cybersecurity Triage safe

Review Recent Docker Events

Docker keeps a recent event trail for starts, stops, pulls, and health changes.

docker events --since 30m --until 0s
Cybersecurity Triage safe

Read UFW Policy Verbosely

The firewall was active, but the defaults mattered more than the rule list.

ufw status verbose
Cybersecurity Triage safe

List Numbered UFW Rules

Numbered rules make firewall review less ambiguous.

ufw status numbered
Cybersecurity Triage safe

Show iptables INPUT Rules

Legacy firewall state can still explain live exposure.

iptables -S INPUT
Cybersecurity Triage safe

Show Publicly Bound Listeners

Localhost services are different from public listeners.

ss -ltnp | awk 'NR==1 || $4 ~ /^(0[.]0[.]0[.]0|[[]::[]]|[*]):/'
Cybersecurity Triage safe

Find Allowed Ports with No Listener

An open firewall rule can outlive the service it was created for.

comm -23 <(ufw status numbered | awk '/ALLOW/ {print}' | grep -Eo '[0-9]+/(tcp|udp)' | cut -d/ -f1 | sort -u) <(ss -ltnp | awk '/LISTEN/ {n=split($4,a,":"); print a[n]}' | sort -u)
Cybersecurity Triage safe

Find Public Listeners Not Allowed by UFW

The process was public, but the firewall did not mention it.

comm -13 <(ufw status numbered | awk '/ALLOW/ {print}' | grep -Eo '[0-9]+/(tcp|udp)' | cut -d/ -f1 | sort -u) <(ss -ltnp | awk '$4 ~ /^(0[.]0[.]0[.]0|[[]::[]]|[*]):/ {n=split($4,a,":"); print a[n]}' | sort -u)
Cybersecurity Triage safe

Check Whether SSH Is Publicly Bound

SSH can be locked down by source and still bind publicly.

ss -ltnp | awk '$4 ~ /:22$/ && $4 !~ /^127[.]/ {print}'
Cybersecurity Triage safe

Show Local-Only Database Listeners

The database was listening, but only on localhost.

ss -ltnp | awk '$4 ~ /^127[.]0[.]0[.]1:(5432|3306|6379)$/ {print}'
Cybersecurity Triage safe

Find Listening Ports with ss

Before blaming the firewall, check whether anything is actually listening.

ss -ltnp
Cybersecurity Triage safe

Count Failed SSH Login Users

Failed SSH attempts are noisy; grouping users makes the pattern readable.

sed -n 's/.*Failed password for \(invalid user \)\?\([^ ]*\) from .*/\2/p' logs/auth.log | sort | uniq -c | sort -nr
Cybersecurity Triage safe

Count Failed SSH Login IPs

The loudest SSH source is usually visible with one count.

sed -n 's/.*Failed password .* from \([0-9.]*\) port.*/\1/p' logs/auth.log | sort | uniq -c | sort -nr
Cybersecurity Triage safe

Show Accepted SSH Logins

During first response, successful logins matter more than background noise.

grep 'Accepted publickey' logs/auth.log
Cybersecurity Triage safe

Show Recent sudo Commands

Privilege use is one of the fastest first-response signals.

grep 'sudo:' logs/auth.log | tail -n 10
Cybersecurity Triage safe

List Users with Login Shells

Not every local account should be able to log in.

awk -F: '$7 ~ /sh$/ {print $1, $7}' etc/passwd
Cybersecurity Triage safe

Check Key SSH Authentication Settings

SSH policy should be visible before you change it.

grep -nE '^(PasswordAuthentication|PermitRootLogin|PubkeyAuthentication|AllowUsers)' etc/ssh/sshd_config
Cybersecurity Triage safe

Find Loose Private Key Permissions

SSH private keys should not be readable like ordinary files.

find home -type f -name 'id_*' -printf '%m %p\n' | awk '$1 > 600'
Cybersecurity Triage safe

List authorized_keys Files

Authorized keys are the server's practical access list.

find home -path '*/.ssh/authorized_keys' -printf '%m %p\n'
Cybersecurity Triage safe

Find the IPs Creating the Most 4xx Noise

One address can turn a normal access log into a wall of failed requests.

awk '$9 ~ /^4/ {count[$1]++} END {for (ip in count) print count[ip], ip}' ./fixtures/nginx/access.log | sort -nr | head
Cybersecurity Triage safe

Spot Unusual HTTP Methods in Access Logs

Most site traffic is boring. The weird methods are worth a look.

awk '$6 !~ /^"(GET|POST|HEAD|OPTIONS)$/ {print $1, $6, $7, $9}' ./fixtures/nginx/access.log | sort | uniq -c | sort -nr
Cybersecurity Triage safe

Count the Most Common User Agents

A strange traffic spike often has a strange user agent.

awk -F'"' '{print $6}' ./fixtures/nginx/access.log | sort | uniq -c | sort -nr | head
Cybersecurity Triage safe

Find Common Admin Probe Paths

A site does not need WordPress to receive WordPress-looking probes.

awk '$7 ~ /(admin|login|wp-|phpmyadmin)/ {print $1, $7, $9}' ./fixtures/nginx/access.log | sort | uniq -c | sort -nr | head
Cybersecurity Triage safe

Find Paths Repeatedly Returning 404

One missing URL is normal. A repeated missing URL is a signal.

awk '$9==404 {count[$7]++} END {for (path in count) if (count[path] >= 3) print count[path], path}' ./fixtures/nginx/access.log | sort -nr | head
Cybersecurity Triage safe

Spot Request Bursts by Minute

Traffic spikes are easier to read when you bucket them by time.

awk '{minute=substr($4,2,17); count[minute]++} END {for (m in count) print count[m], m}' ./fixtures/nginx/access.log | sort -nr | head
Cybersecurity Triage safe

Find Clients Repeating the Same Path

The suspicious pattern is sometimes one client hammering one URL.

awk '{key=$1 " " $7; count[key]++} END {for (k in count) if (count[k] >= 5) print count[k], k}' ./fixtures/nginx/access.log | sort -nr | head