Complete SSH reference — key-based auth, config files, port forwarding, file transfer, and troubleshooting for secure remote access.
Connect to a remote host.
ssh deploy@10.20.30.40
ssh deploy@db.internal.razorpay.net
ssh -p 2222 deploy@10.20.30.40 ## non-default port
ssh -i ~/.ssh/orders-api-deploy deploy@10.20.30.40
ssh deploy@10.20.30.40 "uptime" ## run one command, no interactive shell
exit ## close the session
Parameter Breakdown:
-p: Connects to a non-standard SSH port-i: Uses a specific private key instead of the default ~/.ssh/id_rsaSet up passwordless, more secure login.
ssh-keygen -t ed25519 -C "aditi@razorpay.com"
ssh-keygen -t rsa -b 4096 -f ~/.ssh/orders-api-deploy
ssh-copy-id deploy@10.20.30.40 ## install your public key on the remote host
ssh-copy-id -i ~/.ssh/orders-api-deploy.pub deploy@10.20.30.40
chmod 600 ~/.ssh/orders-api-deploy ## private key must not be group/world readable
Parameter Breakdown:
-t ed25519: Modern, faster, and smaller than RSA — preferred for new keysssh-copy-id: Appends your public key to the remote host's ~/.ssh/authorized_keyschmod 600: SSH refuses to use a private key with overly permissive file permissionsStop typing long connection strings every time.
## ~/.ssh/config
## Host orders-db
## HostName db.internal.razorpay.net
## User deploy
## Port 2222
## IdentityFile ~/.ssh/orders-api-deploy
##
## Host bastion
## HostName bastion.razorpay.net
## User ops
## IdentityFile ~/.ssh/bastion-key
ssh orders-db ## now just works, no flags needed
ssh -F ~/.ssh/work-config orders-db ## use an alternate config file
Parameter Breakdown:
Host block is an alias — connect with ssh <alias> instead of the full commandIdentityFile: Lets each host use a different key automaticallyTunnel traffic through an SSH connection.
## Local forward — access a remote-only service on your machine
ssh -L 5432:localhost:5432 deploy@db.internal.razorpay.net
## Remote forward — expose your local service to the remote host
ssh -R 8080:localhost:3000 deploy@10.20.30.40
## Dynamic forward — SOCKS proxy through the SSH host
ssh -D 1080 deploy@bastion.razorpay.net
## Background a tunnel and keep it alive without an interactive shell
ssh -fN -L 5432:localhost:5432 deploy@db.internal.razorpay.net
Command Parameter Table:
| Flag | Description |
|---|---|
-L |
Local port forward, local_port:remote_host:remote_port |
-R |
Remote port forward, exposes a local service to the remote side |
-D |
Dynamic SOCKS proxy through the SSH connection |
Move files securely over SSH.
scp report.csv deploy@10.20.30.40:/opt/exports/
scp deploy@10.20.30.40:/var/log/orders-api/app.log ./
scp -r ./config deploy@10.20.30.40:/opt/orders-api/
scp -i ~/.ssh/orders-api-deploy report.csv deploy@10.20.30.40:/tmp/
rsync -avz ./build/ deploy@10.20.30.40:/opt/orders-api/
rsync -avz --delete ./build/ deploy@10.20.30.40:/opt/orders-api/
Parameter Breakdown:
scp -r: Recursive copy for directoriesrsync -avz: Archive mode, verbose, compressed — only transfers changed files--delete: Removes files on the destination that no longer exist on the source — use carefullyAvoid retyping your key passphrase constantly.
eval "$(ssh-agent -s)" ## start the agent for this shell session
ssh-add ~/.ssh/orders-api-deploy ## load a key into the agent
ssh-add -l ## list keys currently loaded
ssh-add -D ## remove all keys from the agent
ssh -A deploy@bastion.razorpay.net ## forward agent through a bastion host
Parameter Breakdown:
ssh-add: Caches the decrypted key in memory so you aren't prompted on every connection-A (agent forwarding): Lets a bastion host use your local key to hop further — only enable for trusted hostsssh-add -D: Clears the agent, useful before switching between client credentialsDiagnose connection failures fast.
ssh -v deploy@10.20.30.40 ## verbose, basic
ssh -vvv deploy@10.20.30.40 ## maximum verbosity
## "Permission denied (publickey)"
ssh -i ~/.ssh/orders-api-deploy -v deploy@10.20.30.40
## "Host key verification failed"
ssh-keygen -R 10.20.30.40 ## remove the stale known_hosts entry
## Connection timing out
nc -zv 10.20.30.40 22 ## confirm port 22 is even reachable
Notes:
-vvv shows exactly which key was offered and why the server rejected itknown_hosts entry is the most common cause of "host key verification failed" after a server rebuildnc -zv times out, the issue is network/firewall, not SSH configurationCommon sshd_config settings worth knowing, even if you don't manage the server.
## /etc/ssh/sshd_config — common production settings
## PasswordAuthentication no
## PermitRootLogin no
## Port 2222
## AllowUsers deploy ops
sudo systemctl restart sshd ## apply config changes
sshd -t ## test config syntax before restarting
Parameter Breakdown:
PasswordAuthentication no: Forces key-only login — the single biggest brute-force mitigationsshd -t: Validates config syntax — always run this before restarting, a bad config can lock you outAllowUsers: Explicit allowlist instead of relying on default open accessShortcuts worth adding to your shell config.
alias sshprod='ssh -i ~/.ssh/prod-deploy deploy@bastion.razorpay.net'
## Copy your public key to a new server in one line
cat ~/.ssh/id_ed25519.pub | ssh deploy@10.20.30.40 \
"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
## Keep a tunnel alive automatically if it drops
autossh -M 0 -fN -L 5432:localhost:5432 deploy@db.internal.razorpay.net