Linux Server SSH Hardening | Public Keys· ProxyJump
이 글의 핵심
SSH key exchange, host and user authentication, ssh config, local/remote port forwarding, ProxyJump, SCP/SFTP, and operational hardening with OpenSSH, fail2ban, and least privilege.
Introduction
SSH (Secure Shell) is more than an encrypted remote shell: SCP/SFTP, port forwarding, SOCKS, and transports for Git, Ansible, kubectl make it central to infrastructure and developer workflows. It replaced Telnet and rsh with confidentiality, integrity, and server authentication. This article pairs protocol concepts (key exchange, host verification, user authentication) with OpenSSH practice. Key hygiene, jump hosts, and least privilege matter because one mistake can spread across fleets.
After reading this post
- Explain the order of KEX, host keys, and user authentication
- Use ssh-keygen, ~/.ssh/config, and ProxyJump
- Apply local and remote port forwarding safely
- Run a hardening checklist (keys, MFA, intrusion response)
Table of contents
- Protocol overview
- How it works
- Hands-on usage
- Security considerations
- Real-world use cases
- Optimization tips
- Common problems
- Conclusion
Protocol overview
History and background
SSH emerged in the 1990s to fix Telnet/rlogin/rsh weaknesses; OpenSSH is the de facto standard. Ed25519, ECDSA, RSA keys and ChaCha20-Poly1305, AES-GCM AEAD suites are common—stay current with security updates through 2026 and beyond.
OSI placement
SSH is an application-layer protocol over TCP (default port 22). TLS secures the web; SSH secures interactive shells, subsystems (SFTP), and port forwarding in one secure transport.
Core properties
| Property | Description |
|---|---|
| Encrypted session | After KEX, symmetric keys protect payloads. |
| Server authentication | Host keys mitigate MITM. |
| User authentication | Password, public key, keyboard-interactive (2FA), … |
| Channels | Multiplex shell, SFTP, forwards on one connection. |
How it works
End-to-end flow (concept)
- TCP connect (default :22).
- Version and algorithm negotiation (KEX)—derive session keys.
- Server authentication: server presents host public key; client checks
known_hosts. - Encrypted channel—user authentication (public key challenge/response, …).
- Open shell or subsystem channels.
Roles of keys
- KEX: per-session symmetric keys.
- Host keys: long-term server identity.
- User keys: client private key signs a challenge—passphrase protects the key file.
Authentication modes
| Mode | Notes |
|---|---|
| password | Convenient but vulnerable to brute force and leaks—pair with MFA or avoid. |
| publickey | Agent + passphrase is the common production baseline. |
| keyboard-interactive | 2FA tokens, etc. |
sequenceDiagram participant C as Client participant S as SSH Server C->>S: TCP connect :22 C->>S: Algorithm negotiation C->>S: Key exchange (KEX) S->>C: Host key + proof C->>C: Verify known_hosts C->>S: User authentication (public key signature, etc.) S->>C: Success → shell/SFTP channel
Hands-on usage
ssh-keygen
# Ed25519 recommended (short and strong)
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519
# RSA 4096 if legacy compatibility requires it
ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/id_rsa
# Register public key on server (~/.ssh/authorized_keys one line per key)
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
Private key permissions: chmod 600 ~/.ssh/id_ed25519
ssh config
~/.ssh/config:
Host bastion
HostName bastion.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519
Host internal-*
User app
ProxyJump bastion
IdentityFile ~/.ssh/id_ed25519
Host db-tunnel
HostName app.internal
LocalForward 15432 localhost:5432
ProxyJump bastion
Connect:
ssh internal-api
ssh db-tunnel # local 15432 → remote postgres
Port forwarding
# Local: your machine :8080 → target:80 as seen from the server
ssh -L 8080:target.internal:80 user@bastion
# Remote: server :9090 → your local :3000
ssh -R 9090:localhost:3000 user@public-host
ProxyJump
ssh -J [email protected] [email protected]
Fixing jump hosts in config reduces mistakes.
SCP / SFTP
scp -i ~/.ssh/id_ed25519 ./build.tar.gz user@host:/var/app/
sftp user@host
# sftp> put local.bin /remote/path/
Security considerations
Key management
- Key types: Prefer Ed25519 for new keys; RSA 3072+ when required.
- Separation: Split personal, CI, and deploy keys; document revocation if leaked.
- In authorized_keys, use command=, from=“IP”, … for least privilege.
2FA
TOTP modules or FIDO2/sk- keys* (where supported) reduce password-only risk. Public key + MFA is common.
fail2ban and intrusion response
PasswordAuthentication noPermitRootLogin noAllowUsers …- fail2ban on exposed SSH when passwords ever existed
Agent forwarding
ForwardAgent yes is convenient but risky if a host is compromised—enable only on trusted hops and briefly.
Real-world use cases
| Area | Notes |
|---|---|
| Server ops | Shell, systemd, log tailing, patching. |
| Deploy | CI SSH deploy scripts, Docker context over SSH. |
| Tunneling | Map internal DB/Redis to local ports safely. |
| Git | [email protected]:... URLs with pinned host keys. |
| Segmented networks | Jump chains preserve network isolation. |
Optimization tips
ControlMaster multiplexing
Host *
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m
Speeds repeat connections—policy may restrict.
Compression
-C helps slow links; can waste CPU on fast LANs.
Keepalives
Host *
ServerAliveInterval 30
ServerAliveCountMax 4
Reduces NAT idle timeouts dropping sessions.
ssh-agent
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519 # macOS example
Common problems
| Symptom | Check |
|---|---|
| Permission denied (publickey) | authorized_keys path and permissions (~/.ssh` 700, key file 600), correct key, username. |
| REMOTE HOST IDENTIFICATION HAS CHANGED | Server reinstall or IP reuse—remove stale known_hosts after verifying new fingerprint. |
| Connection timeout | Security groups, NAT, IPv4 vs IPv6, missing jump. |
| Too many authentication failures | Too many keys in agent—IdentitiesOnly yes, explicit IdentityFile. |
| Forwarding fails | AllowTcpForwarding, GatewayPorts policy. |
Conclusion
SSH unifies encrypted shells, file transfer, and tunneling—key management, jump hosts, and least privilege prevent outages and breaches. Keys and config files are assets like application code: that is the 2026 baseline for Linux server access. Good next steps: standardize team SSH onboarding, jump-host architecture, DB tunnels, and secure deploy pipelines using the patterns above.
References
man ssh,man sshd_config,man ssh_config- OpenSSH release notes (algorithm guidance)
- NIST·ENISA SSH hardening guides
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. SSH key exchange, host and user authentication, ssh config, local/remote port forwarding, ProxyJump, SCP/SFTP, and opera… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- HTTP 프로토콜 완전 가이드 | HTTP/1.1·HTTP/2·HTTP/3·REST·HTTPS·캐시 실전
- [SSH: Secure Remote Access | Keys· ProxyJump](/en/blog/network-protocol-ssh-practical-guide/
- SSH 프로토콜 보안 원격 접속 | 공개키·ProxyJump·포트 포워딩·OpenSSH 실전
이 글에서 다루는 키워드 (관련 검색어)
Linux, SSH, Security, OpenSSH, Hardening, Public Key, Port Forwarding, Server 등으로 검색하시면 이 글이 도움이 됩니다.