Files
security-tools/README.md
pdmarf 50aa38712e Add bind-ssh-tailscale.sh as standalone manual-run script
Places the script in standalone/ so it is excluded from setup.sh automation.
Documents manual curl-and-run usage in README.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 14:22:56 +01:00

3.9 KiB

Security Tools

A collection of security scripts versioned in this repository.

Scripts

check-npm-sudo-config.sh

Audits npm configuration on a Linux VM to detect cases where npm is — or has been — configured to install packages into system-owned directories, which requires sudo and creates security risks.

Running sudo npm install -g can deposit files owned by root inside your npm prefix or cache directory. This causes permission errors for non-root users, encourages further sudo npm use to work around them, and means malicious packages run with root privileges during installation.

This script is audit-only — it makes no changes. It reports issues and prints recommended commands, but you must run those commands yourself.

The script checks:

  1. npm prefix — flags if it points to /usr or /usr/local (system-wide, requires sudo)
  2. ~/.npmrc — checks whether the prefix is explicitly pinned to a user directory
  3. PATH — confirms the npm prefix bin directory is in PATH
  4. Root-owned files in the prefix — evidence of past sudo npm usage
  5. Shell history — scans .bash_history / .zsh_history for sudo npm commands
  6. npm cache ownership — root-owned cache files cause EACCES errors
  7. Node version manager — detects nvm, fnm, or n; flags if n is present without N_PREFIX set

If issues are found, it sends a Telegram alert and logs results to logs/.

The correct fix is to configure npm to install global packages into a user-owned directory (e.g. ~/.npm-global) so that sudo is never needed:

npm config set prefix ~/.npm-global
export PATH="$HOME/.npm-global/bin:$PATH"

Standalone Scripts

These scripts live in standalone/ and are not run by setup.sh. They are single-use tools intended to be copied to a target machine and run manually.

standalone/bind-ssh-tailscale.sh

Binds SSH to the Tailscale interface only and disables password authentication.

  • Requires root (sudo bash bind-ssh-tailscale.sh)
  • Tailscale must be installed and connected before running
  • Uses a drop-in config at /etc/ssh/sshd_config.d/99-tailscale-only.conf if that directory exists; otherwise edits /etc/ssh/sshd_config directly with an automatic backup
  • Validates the config with sshd -t before restarting the SSH service
  • Prints revert instructions on completion

To use on a target machine:

curl -O https://gitea.pdmarf.co.uk/pdm/security-tools/raw/branch/master/standalone/bind-ssh-tailscale.sh
# or via Tailscale:
curl -O http://100.120.125.113:3000/pdm/security-tools/raw/branch/master/standalone/bind-ssh-tailscale.sh

sudo bash bind-ssh-tailscale.sh

Claude Code Context

This project is maintained with Claude Code. The working directory on macOS is:

/Users/petermarfleet/code/bin/security

To resume work in Claude Code from this directory:

cd /Users/petermarfleet/code/bin/security
claude

Cloning to a New Machine

If git is not installed (e.g. a fresh LXC/VM):

apt install git -y

Then clone and run setup:

On Tailscale:

git clone http://100.120.125.113:3000/pdm/security-tools.git
cd security-tools
bash setup.sh

Without Tailscale:

git clone https://gitea.pdmarf.co.uk/pdm/security-tools.git
cd security-tools
bash setup.sh

To clone to a specific path:

git clone http://100.120.125.113:3000/pdm/security-tools.git /path/to/destination

Activating on a New VM

After cloning, run setup.sh once. It will:

  • Ask for your Telegram bot token and chat ID
  • Register cron jobs to run scans daily at 08:00
  • Send a test Telegram message confirming the VM is active
  • Create a logs/ folder — logs are kept for 60 days then auto-deleted

Updating an Existing VM

When changes are pushed to this repo, update any VM by running:

cd ~/security-tools
git pull
bash setup.sh

setup.sh is safe to re-run — it skips steps already completed.