DaleSchool

네트워크 도구

입문25분

학습 목표

  • curl로 HTTP 요청을 보내고 응답을 확인할 수 있다
  • wget으로 파일을 다운로드할 수 있다
  • ping으로 네트워크 연결을 확인할 수 있다
  • SSH로 원격 서버에 접속할 수 있다

동작하는 코드

예제 1: ping으로 연결 확인

ping google.com

출력:

PING google.com (142.250.206.46): 56 data bytes
64 bytes from 142.250.206.46: icmp_seq=0 ttl=116 time=12.345 ms
64 bytes from 142.250.206.46: icmp_seq=1 ttl=116 time=11.234 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
  • icmp_seq: 패킷 번호 (연속적이어야 함, 빠지면 패킷 손실)
  • time: 응답 시간 (낮을수록 좋음, 100ms 이하면 정상)
  • packet loss: 패킷 손실률 (0%가 정상)

Ctrl+C로 종료합니다.

# 횟수 제한
ping -c 4 google.com   # 4번만

예제 2: curl로 HTTP 요청

# 기본 GET 요청
curl https://httpbin.org/get

출력 (JSON):

{
  "headers": {
    "Host": "httpbin.org",
    "User-Agent": "curl/8.1.2"
  },
  "origin": "123.456.789.0",
  "url": "https://httpbin.org/get"
}
# 헤더 포함해서 보기
curl -i https://httpbin.org/get

출력:

HTTP/2 200
content-type: application/json
...

{
  ...
}

예제 3: 파일 다운로드

# curl로 파일 다운로드 (-O: 원본 파일명 유지)
curl -O https://example.com/file.txt

# wget으로 다운로드 (curl의 대안)
wget https://example.com/file.txt

직접 수정하기

curl: API 호출의 표준 도구

# POST 요청 (JSON 데이터 전송)
curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"name": "홍길동", "age": 30}'

출력:

{
  "data": "{\"name\": \"홍길동\", \"age\": 30}",
  "json": {
    "age": 30,
    "name": "홍길동"
  }
}
# 응답 코드만 확인
curl -o /dev/null -s -w "%{http_code}" https://google.com
# 200

# 인증 헤더 추가
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/data

# 기본 인증
curl -u username:password https://api.example.com/protected

# 응답을 파일로 저장
curl -o output.json https://api.example.com/data

# 리다이렉션 따라가기
curl -L https://bit.ly/shortlink

자주 쓰는 curl 옵션

| 옵션 | 의미 | 예시 | | ------------- | -------------------- | ------------------------------------- | | -X METHOD | HTTP 메서드 | -X POST, -X DELETE | | -H "헤더" | 헤더 추가 | -H "Content-Type: application/json" | | -d "데이터" | 요청 본문 | -d '{"key":"value"}' | | -o 파일명 | 응답 저장 | -o result.json | | -O | 원본 파일명으로 저장 | (URL의 마지막 부분) | | -s | 진행 표시 숨기기 | (silent) | | -v | 상세 출력 | (verbose, 디버깅) | | -L | 리다이렉션 따라가기 | (follow redirects) | | -i | 응답 헤더 포함 출력 | (include headers) |

wget: 파일 다운로드 전문 도구

# 기본 다운로드
wget https://example.com/archive.tar.gz

# 다른 이름으로 저장
wget -O myfile.tar.gz https://example.com/archive.tar.gz

# 백그라운드 다운로드
wget -b https://example.com/large-file.iso

# 재시도 횟수 설정
wget --tries=5 https://example.com/file.txt

# 인증이 필요한 경우
wget --user=username --password=password https://example.com/protected

# 전체 웹사이트 다운로드 (오프라인용)
wget --mirror https://example.com

SSH: 원격 서버 접속

# 기본 접속
ssh username@server-ip-or-hostname

# 포트 지정 (기본 22)
ssh -p 2222 username@server.example.com

# SSH 키로 접속
ssh -i ~/.ssh/my-key.pem username@server.example.com

# 접속하면서 명령어 실행
ssh username@server "ls /var/www"

# 파일 복사 (SCP)
scp local-file.txt username@server:/remote/path/
scp username@server:/remote/file.txt ./local/

# 디렉토리 복사
scp -r local-dir/ username@server:/remote/path/

SSH 키 생성:

# RSA 키 쌍 생성
ssh-keygen -t ed25519 -C "your@email.com"

# 생성된 파일
ls ~/.ssh/
# id_ed25519     ← 개인 키 (절대 공유 금지!)
# id_ed25519.pub ← 공개 키 (서버에 등록)

# 공개 키 내용 확인
cat ~/.ssh/id_ed25519.pub

# 서버에 공개 키 등록
ssh-copy-id username@server

"왜?" — 네트워크 도구가 필요한 이유

개발자가 네트워크 도구를 써야 하는 상황:

| 상황 | 도구 | | ------------------------ | ----------------- | | API 동작 확인 | curl | | 서버 연결 확인 | ping | | 파일/소프트웨어 다운로드 | wget, curl -O | | 서버 관리 | ssh | | 서버에 파일 전송 | scp |

실전 시나리오: API 테스트

# REST API 전체 CRUD 테스트
# 생성
curl -X POST https://jsonplaceholder.typicode.com/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "할 일 추가", "completed": false}'

# 조회
curl https://jsonplaceholder.typicode.com/todos/1

# 수정
curl -X PUT https://jsonplaceholder.typicode.com/todos/1 \
  -H "Content-Type: application/json" \
  -d '{"id": 1, "title": "수정된 할 일", "completed": true}'

# 삭제
curl -X DELETE https://jsonplaceholder.typicode.com/todos/1

흔한 실수

실수 1: curl의 -d와 -H 혼동

# 잘못됨: Content-Type 없이 JSON 전송
curl -X POST https://api.example.com/data \
  -d '{"key": "value"}'

# 올바름: Content-Type 헤더 추가
curl -X POST https://api.example.com/data \
  -H "Content-Type: application/json" \
  -d '{"key": "value"}'

실수 2: SSH 개인 키 공유

# 절대 공유하면 안 되는 파일
cat ~/.ssh/id_rsa      # 개인 키! 공유 금지

# 공유해도 되는 파일
cat ~/.ssh/id_rsa.pub  # 공개 키 (서버 등록용)

실수 3: ping이 막혔을 때 연결 안 된다고 오해

일부 서버는 보안 정책으로 ping(ICMP)을 차단합니다:

ping google.com   # Request timeout (서버는 실제로 살아있음)

# 다른 방법으로 확인
curl -I https://google.com   # HTTP 헤더만 요청
# HTTP/1.1 301 → 실제로 작동함

실수 4: wget 없는 macOS

macOS에는 기본적으로 wget이 없습니다:

wget file.txt
# zsh: command not found: wget

# 해결
brew install wget

# 또는 curl로 대체
curl -O https://example.com/file.txt

심화 학습

curl로 응답 시간 측정
curl -o /dev/null -s -w "
    DNS 조회:      %{time_namelookup}s
    TCP 연결:      %{time_connect}s
    TLS 핸드셰이크: %{time_appconnect}s
    첫 바이트:     %{time_starttransfer}s
    총 시간:       %{time_total}s
    크기:          %{size_download} bytes
" https://google.com

API 성능 측정이나 지연 디버깅에 유용합니다.

SSH 설정 파일 (~/.ssh/config)

자주 접속하는 서버를 설정해두면 편합니다:

# ~/.ssh/config
Host myserver
    HostName 123.456.789.0
    User ubuntu
    IdentityFile ~/.ssh/my-key.pem
    Port 22

Host devserver
    HostName dev.example.com
    User developer
    Port 2222

설정 후:

# 이렇게 짧게 접속 가능
ssh myserver
scp file.txt myserver:/home/ubuntu/
netstat/lsof로 포트 확인
# 열려 있는 포트 확인
lsof -i -P -n | grep LISTEN

# 특정 포트 사용 프로세스
lsof -i :3000
lsof -i :8080

# macOS의 네트워크 통계
netstat -an | grep LISTEN
  1. ping -c 4 google.com으로 구글 서버까지의 응답 시간을 확인하세요.
  2. curl https://httpbin.org/get으로 GET 요청을 보내고 응답을 확인하세요.
  3. curl -X POST https://httpbin.org/post -H "Content-Type: application/json" -d '{"name":"test"}'로 POST 요청을 보내보세요.
  4. curl -o /dev/null -s -w "%{http_code}" https://google.com으로 HTTP 상태 코드만 확인하세요.
  5. ssh-keygen -t ed25519 -C "test@example.com"으로 SSH 키 쌍을 생성해보세요 (이미 있다면 건너뛰세요).

Q1. curl -X POST -H "Content-Type: application/json" -d '{"key":"val"}' URL에서 각 옵션의 역할이 올바른 것은?

  • A) -X POST: 헤더 추가, -H: HTTP 메서드, -d: URL 지정
  • B) -X POST: HTTP 메서드, -H: 헤더 추가, -d: 요청 본문 데이터
  • C) -X POST: 파일 저장, -H: 호스트 지정, -d: 데이터 형식
  • D) -X POST: 디버그 모드, -H: 헬프, -d: 도메인 지정