codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
노트›infra

루프백 바인딩과 SSH 터널

2026-04-28 게시· 2026-05-18 갱신·0회 조회

루프백 바인딩과 SSH 터널

어떤 포트는 인터넷에서 닿아야 하고, 어떤 포트는 같은 호스트 안에서만 쓰여야 합니다. 둘을 구분하는 가장 단순한 도구는 바인딩 주소. 외부에서만 들어갈 수 있는 길을 열고 싶으면 SSH 터널이 가벼운 답. 이 글은 0.0.0.0 과 127.0.0.1 의 차이 · Docker 의 포트 매핑 · SSH 포트 포워딩 (-L · -R · -D) · VPN 도구 비교 · 외부 노출 최소화의 운영 모델.

1. 바인딩 주소에 대한 이야기

주소 의미
0.0.0.0 모든 인터페이스에 바인딩 (외부 접근 가능).
127.0.0.1 루프백. 같은 호스트에서만 접근 가능.
:: / ::1 IPv6 의 모든 인터페이스 / 루프백.
<특정 IP> 해당 인터페이스에만.

리스닝 소켓이 어떤 주소에 묶이느냐가 외부 도달 가능성을 결정. 방화벽이 첫 방어선이라면, 바인딩 주소는 그 이전의 결정.

2. Docker 의 포트 매핑

Compose · docker run 의 포트 표기:

ports:
  - "8080:8080"             # 호스트의 0.0.0.0:8080 으로 노출
  - "127.0.0.1:8080:8080"   # 호스트 루프백에만 노출
  - "8080"                  # 임의의 호스트 포트 → 컨테이너 8080

운영에서는 외부 노출이 필요한 서비스 (웹 · 프록시) 만 0.0.0.0 으로 열고, DB · 캐시 · 관리 UI 는 루프백 바인딩만 사용하는 모델이 흔함. 외부 접근이 필요할 때는 SSH 터널을 통해 일시적으로 통과.

3. SSH 포트 포워딩

ssh 의 세 가지 포워딩 옵션:

옵션 의미
-L 로컬 포트 → 원격 호스트의 어떤 포트로 (로컬 포워딩).
-R 원격의 포트 → 로컬의 어떤 포트로 (원격 포워딩).
-D 로컬에 SOCKS 프록시 (동적 포워딩).

-L — 운영 DB 접근:

ssh -L 5432:127.0.0.1:5432 user@server

내 PC 의 5432 로 접속하면 SSH 터널을 통해 server 의 루프백 5432 (= DB) 로 연결. 서버의 DB 포트는 인터넷에 열려 있을 필요가 없습니다.

-R — 내부 개발 서버 임시 노출:

ssh -R 8080:127.0.0.1:3000 user@server

서버의 8080 으로 들어온 연결을 내 PC 의 3000 으로. 서버 측 GatewayPorts yes 설정 필요할 수 있음.

-D — SOCKS 프록시:

ssh -D 1080 user@server

내 PC 의 1080 에 SOCKS5 프록시. 브라우저 · 도구가 서버를 경유해 통신.

4. VPN 도구

도구 메모
WireGuard 2016 시작. 리눅스 커널 통합 (2020). 단순하고 빠른 모던 VPN.
Tailscale 2019. WireGuard 기반의 메시 VPN. 기기 간 직접 연결 + 코디네이션.
OpenVPN 2001. SSL / TLS 기반의 오래된 VPN.

SSH 터널이 한두 포트의 일시 노출에 가볍다면, VPN 은 다수 포트 · 여러 호스트를 안정적으로 잇는 자리. Tailscale 은 NAT 통과 · 제로 설정 측면에서 자주 거론됩니다.

5. 외부 노출 최소화

여러 층의 방어가 겹쳐 있을 때 가장 안쪽의 결정이 바인딩 주소.

  • 클라우드 보안 그룹 / Network ACL.
  • 호스트 수준의 ufw (Linux) · Windows Defender Firewall.
  • 컨테이너 네트워크 격리.

클라우드 보안 그룹이 0.0.0.0/0 으로 열려 있어도 서비스가 127.0.0.1 에 묶여 있으면 외부에서 닿지 못함 (역도 마찬가지).

6. bastion / jump host

여러 내부 호스트로의 접근을 한 호스트 (bastion) 로 모음:

# ~/.ssh/config
Host db1
    Hostname 10.0.1.5
    ProxyJump bastion

Host bastion
    Hostname bastion.example.com

ssh db1 만으로 bastion 을 거쳐 db1 에. SSH 의 ProxyJump (-J) 옵션은 OpenSSH 7.3+ 에서 표준.

7. 운영 서버 일반 구성

  • 80 / 443 — 외부 노출 (Caddy 또는 nginx).
  • 22 — 외부 노출 (SSH). 가능하면 키 인증 · fail2ban · 포트 변경.
  • 그 외 모든 포트 — 127.0.0.1 바인딩 + SSH 터널로만 접근.
services:
  app:
    ports:
      - "127.0.0.1:8080:8080"
  db:
    ports:
      - "127.0.0.1:5432:5432"
  caddy:
    ports:
      - "80:80"
      - "443:443"

외부에 닿는 컨테이너는 Caddy 만, 그 외는 호스트 루프백을 통해서만 접근. SSH 터널이나 호스트 셸 안에서 직접 호출.

8. 개발 PC 에서 운영 DB 보기

ssh -L 15432:127.0.0.1:5432 user@server
psql -h 127.0.0.1 -p 15432 -U app appdb

로컬 포트를 5432 가 아닌 15432 로 두면 로컬에 같은 DB 가 떠 있어도 충돌 없음.

9. 자주 걸리는 자리

0.0.0.0 의도치 않은 노출 — compose 의 "PORT:PORT" 표기는 기본이 0.0.0.0. 검토 없이 복붙하면 외부 노출이 누적.

-R 의 권한 한계 — 기본 SSH 설정은 원격 포워딩을 루프백에만 묶음. 외부 접근까지 열려면 서버의 GatewayPorts yes 필요, 그만큼 보안 검토가 따라옴.

터널이 끊기는 경우 — 네트워크 단절 시 SSH 세션이 침묵하다 죽음. ServerAliveInterval · autossh 같은 보조가 도움.

방화벽 · SG · 바인딩의 책임 혼동 — 어느 층이 막고 있는지 추적이 어려움. 변경 시 한 층씩 점검.

Docker 사용자 정의 네트워크와 호스트 노출 — 컨테이너 간 통신은 사용자 네트워크로, 외부 노출은 명시적 ports. 두 자리를 섞지 않음.

하고픈 말

루프백 바인딩 + SSH 터널 둘이 결합하면 운영 서버의 보안 표면이 80 / 443 / 22 세 포트로 압축됩니다. compose 에 무심코 적힌 "5432:5432" 한 줄이 운영 사고의 출발점이 되는 자리. 모든 새 컨테이너는 127.0.0.1 접두를 기본값으로 둘 만큼.

Next

  • single-server-philosophy
  • local-https-mkcert

OpenSSH 매뉴얼 · Docker 네트워킹 개요 · Tailscale 공식 · WireGuard 공식 · Mozilla SSH 가이드라인 · ProxyJump (OpenSSH) 를 참고합니다.

infra 카테고리의 다른 글

카테고리 전체 보기 →
  • 클라우드 에뮬레이터 스택 — 4번째 환경의 설계
  • 로컬 HTTPS — mkcert 와 자체 CA
  • 단일 서버 운영의 자리
  • Caddy 와 nginx — 비교의 자리
  • Docker Compose 패턴
  • Docker 기초