Skip to content

Useful Commands

JJ edited this page Oct 12, 2026 · 12 revisions

Ubuntu

Check who's trying to connect to ssh

sudo grep "Failed" /var/log/auth.log | tail -20

Note

Block access to port 22, or disable root login

Unban self from fail2ban

sudo fail2ban-client set sshd unbanip YOUR_IP

Check who's listening on ports

sudo ss -tlnp

Docker on Ubuntu

Important

Bind to localhost when mapping ports, eg: 127.0.0.1:8080:80

Prevents docker skipping firewall rules and opening ports to public.

Check Docker's iptables chain

sudo iptables -t nat -L DOCKER -n

Setup iptables for containers running on macvlan

# eg for Nginx Proxy Manager:
# docker compose service config...
cap_add: [NET_ADMIN]
entrypoint: >
      sh -c "
      apt-get update && apt-get install -y iptables &&
      update-alternatives --set iptables /usr/sbin/iptables-legacy &&
      update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy &&
      iptables -F &&                                                                  # clear any existing rules
      iptables -P INPUT DROP &&                                                       # drop all incoming requests (block without responding)
      iptables -P FORWARD DROP &&                                                     # drop all forwarded requests (block without responding)
      iptables -P OUTPUT ACCEPT &&                                                    # allow outgoing requests from container
      iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT &&       # maintain any connections the container opened with outside
      iptables -A INPUT -i lo -j ACCEPT &&                                            # allow container to talk to itself
      iptables -A INPUT -s <ip/subnet> -p tcp --dport 443 -j ACCEPT &&                # allow incoming requests to port 443 (https)
      iptables -A INPUT -s <ip/subnet> -p tcp --dport 81 -j ACCEPT &&                 # allow incoming requests to port 81 (nginx proxy man admin ui)
      iptables -A INPUT -p icmp -j ACCEPT &&                                          # allow pinging the container
      exec /init
      "
# ...docker compose service config

Note

Many ways to confirm -> try curl -v telnet://<ip>:<port> - should establish connection for allowed ports/ips and timeout otherwise (not refuse)

Github

Signing

Confirm commits are signed

git log --show-signature -1

Tell git to sign commits (SSH)

git config --global gpg.format ssh
git config --global user.signingkey <path-to-private-key>
git config --global commit.gpgsign true

Note

replace with path to private ssh key (eg: windows -> ~/.ssh/id_ed25519)

Add allowed signers (if needed)

# check if exists already
git config --get gpg.ssh.allowedSignersFile
# otherwise
touch ~/.ssh/allowed_signers
echo 'email@domain.com namespaces="git" '$(cat ~/.ssh/<signing_key>.pub) >> ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
# verify
git config --get gpg.ssh.allowedSignersFile

Test with a signed commit

git commit --allow-empty -S -m "test: signed commits" # remove -S if signing is enabled globally

Tell git to sign commits (GPG)

Win11: Install and configure Gpg4Win

git config --global gpg.format openpgp
git config --global gpg.program "C:/Program Files (x86)/GnuPG/bin/gpg.exe"
git config --global commit.gpgsign true

List GPG keys

gpg --list-keys --keyid-format=long

Export GPG key

gpg --armor --export YOUR_KEY_ID

Note

KEY_ID is the value after rsa../

Verify git config

# verify 
git config --global --get gpg.format
git config --global --get user.signingkey

Test with a signed commit

git commit --allow-empty -S -m "test: signed commits" # remove -S if signing is enabled globally

Homelab

TinyAuth

Nginx Manager config (guard entire proxy host incl. custom locations)

# Tinyauth auth request
auth_request /tinyauth; # can use any path
error_page 401 = @tinyauth_login;
auth_request_set $tinyauth_remote_user $upstream_http_remote_user;
proxy_set_header remote-user $tinyauth_remote_user;

# Exclude common paths
location ~ ^/(css|js|img|images|fonts|assets|static|login|logout|health|metrics) {
  auth_request off;
  proxy_pass $forward_scheme://$server:$port;
}

# Tinyauth auth request
location /tinyauth { # use same path from first line
  internal;
  proxy_pass http://tinyauth:3000/api/auth/nginx; # replace with tinyauth container:port

  # Pass the request headers
  proxy_set_header x-forwarded-proto $scheme;
  proxy_set_header x-forwarded-host $http_host;
  proxy_set_header x-forwarded-uri $request_uri;
}

# Tinyauth login redirect
location @tinyauth_login {
  return 302 https://auth.example.com/login?redirect_uri=$scheme://$http_host$request_uri; # Replace with your app URL
}

SSH key access between machines

1. Generate a key (on the client)

ssh-keygen -t ed25519 -f ~/.ssh/<name> -C "<comment>"

Use a separate key per machine/agent. Windows PowerShell: same command, keys live in $env:USERPROFILE\.ssh.

2. Install the public key on the server

Linux/macOS client:

ssh-copy-id -i ~/.ssh/<name>.pub user@<host>

Windows client:

type $env:USERPROFILE\.ssh\<name>.pub | ssh user@<host> "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Manual: append the .pub contents to ~/.ssh/authorized_keys on the server, then:

chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

Tip

If you created the files with sudo or as root (e.g. setting up another user's key from your admin account), they'll be owned by root and sshd will silently ignore the key. Fix ownership with:

sudo chown -R <user>: /home/<user>/.ssh

The trailing : with no group means "that user's login group", which works even when the group name differs from the username. Not needed if you created the files as the target user or used ssh-copy-id.

3. Test (keep the existing session open)

ssh -i ~/.ssh/<name> -o PasswordAuthentication=no user@<host> whoami

First connect also saves the host key to known_hosts (needed for non-interactive use).

4. Optional client config (~/.ssh/config)

Host <alias>
    HostName <host>
    User <user>
    IdentityFile ~/.ssh/<name>
    IdentitiesOnly yes

5. Harden the server

Warning

Only do this after step 3 works for every user who needs access, including your own admin user. Otherwise you'll lock yourself out of SSH.

/etc/ssh/sshd_config.d/10-hardening.conf:

PasswordAuthentication no
PermitRootLogin no
AllowUsers user1 user2
sudo sshd -t && sudo systemctl restart ssh

Test a fresh login in a new window before closing the old one.

Troubleshooting

Note

Key being ignored? Check sudo journalctl -u ssh -n 30 for "bad ownership or modes". That points at wrong permissions on ~/.ssh / authorized_keys, or the ownership issue in the tip above.