개요
데이터 엔지니어라는 직무를 하면서 인프라와는 밀접하게 지낼 수밖에 없고 인프라에서 네트워크는 중요한 부분이다. Application 끼리의 연결이 안 되거나 할 때는 네트워크 이슈가 대부분이기 때문에 이참에 리눅스 환경에서 네트워크 트러블 슈팅을 할 때 상황에 따른 대처 방법과 필요한 명령어에 대해 정리하려고 한다. 해당 글은 OSI 7 계층에 대한 이해가 어느 정도 있다고 가정하고 포스팅한다.
네트워크 모델
일반적으로 우리가 알고 있는 대표적인 네트워크 모델로는 OSI 7 Layer Model 이 있다. 하지만 OSI 모델보다 현대 네트워크에 더 어울리는 모델인 TCP/IP 모델을 우리는 중점적으로 볼 것이다. TCP/IP 모델은 크게 네 가지의 계층으로 나뉜다.
- Application Layer
- Transport Layer
- Internet Layer
- Network Layer
Application Layer는 Software Application 범주, Transport Layer는 Host 간의 연결 범주, Internet Layer는 인터넷 네트워크 범주, Network Access Layer는 LAN 상의 노드들 간의 통신 범주이다. 아래는 OSI 모델과 TCP/IP 모델을 비교한 그림이다.
트러블슈팅에서 네트워크 모델이 왜 중요하냐, 만약 MySQL 이 설치되어 있는 노드가 있을 때, 해당 노드로 SSH 통신은 가능하지만 MySQL DB로의 통신은 불가능하다면 이것은 해당 노드로의 통신은 가능하다는 것으로 최소한 Network Access Layer나 Internet Layer의 문제는 아닐 것이다. 이처럼 네트워크 트러블 슈팅은 네트워크 문제가 어디서 발생했는지 범위를 줄여나가는 것이 중요하기 때문에 해당 모델을 통해 범위를 줄이고 그에 맞는 해결 방안을 도출할 수 있다.
네트워크 트러블 슈팅
네트워크 트러블 슈팅을 할 때에는 위의 모델에 따라 Application Layer부터 하위 계층으로 하나씩 확인해 나가는 것이 좋다. 만약, 클라우드 공급자(AWS, GCP, Azure 등)를 사용한다면 우리가 Network Access Layer가 문제여도 해결할 방법이 없고 보통 상위 계층에서 문제가 많이 발생하고 범위도 좁기 때문이다. 이제 각 Layer 별 진단 방법에 대해 알아보자.
Physical Layer (L1, 물리 계층)
L1은 물리적인 전기가 흐르는 계층으로 보통은 케이블이 제대로 꽂혔는지 확인하는 방법이 가장 먼저 떠오르는데, Linux Command로도 문제가 있는지 간단히 확인해 볼 수 있다고 한다.
[ec2-user@ip-172-21-1-53 ~]$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 02:e1:dc:f1:d0:76 brd ff:ff:ff:ff:ff:ff
위의 인터페이스에서 eth0를 보면 state 가 UP으로 되어 있는데 이는 잘 동작하고 있다는 것이다. DOWN으로 표시될 경우, 제대로 동작하지 않는다는 의미로 이때, 케이블이나 스위치 등의 문제를 점검하면 된다.
Data Link Layer (L2, 데이터 링크 계층)
L2는 LAN에서의 연결을 담당하는데, 해당 계층에서 많이 사용하는 프로토콜은 L3의 IP 주소를 L2의 이더넷 MAC 주소에 매핑하는 ARP(Address Resolution Protocol)가 있다. LAN 구간에서는 호스트에 접근하려고 할 때, IP 주소가 아닌 MAC 주소로 통신하기 때문에 다른 호스트들의 IP와 MAC주소 매핑하기 위해 ARP를 사용한다.
[ec2-user@ip-172-21-1-53 ~]$ arp -an
? (172.21.0.1) at 02:ad:9e:40:74:6a [ether] on eth0
? (172.21.0.2) at 02:ad:9e:40:74:6a [ether] on eth0
- arp -an 명령을 통해 ARP 테이블을 볼 수 있다.
- 172.21.0.1과 172.21.0.2라는 호스트와 MAC 주소가 써져 있다.
보통 L2에서 문제가 생길 경우에는 ARP 테이블이 채워지지 않았거나 localhost가 default 게이트웨이의 MAC주소를 얻지 못하는 상황일 것이다. 이런 문제는 게이트웨이에 대해 잘못된 IP 주소를 갖고 있거나, 스위치 포트 연결이 잘못되어 있거나 하는 경우일 수 있다.
[ec2-user@ip-172-21-1-53 ~]$ ip neighbor show
172.21.0.1 dev eth0 lladdr 02:ad:9e:40:74:6a REACHABLE
- ip neighbor show 명령을 통해 ARP entry를 확인해 볼 수 있다.
- RECHABLE은 문제가 없는 경우이고, FAILED가 뜰 경우 문제가 있는 경우이다.
Network/Internet Layer (L3, 네트워크 계층)
L3는 우리가 가장 익숙한 IP 주소를 포함하는 계층이다. IP 주소를 LAN을 벗어나는 다른 외부의 호스트에 대한 주소를 제공한다.
[ec2-user@ip-172-21-1-53 ~]$ ip -br address show
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 172.21.1.53/20 fe80::e1:dcff:fef1:d076/64
- ip -br address show 명령을 통해 로컬 호스트의 IP 주소를 확인할 수 있다.
L3에서의 트러블 슈팅에서 가장 기본적인 명령은 ping 명령이다. ping은 ICMP Echo Request 패킷을 보내고, ICMP Echo Reply 응답을 기대한다.
[ec2-user@ip-172-21-1-53 ~]$ ping www.google.com
PING www.google.com (172.217.26.228) 56(84) bytes of data.
64 bytes from bom05s09-in-f4.1e100.net (172.217.26.228): icmp_seq=1 ttl=46 time=28.0 ms
많이 사용되는 다른 명령으로는 traceroute 가 있다. 해당 명령을 통해 호스트 자체에 문제가 있는지, 호스트에 도달하기까지 네트워크 경로 중에 문제가 있는지 확인할 수 있다.
[ec2-user@ip-172-21-1-53 ~]$ traceroute www.google.com
traceroute to www.google.com (172.217.26.228), 30 hops max, 60 byte packets
1 ec2-<public-ip>.ap-northeast-2.compute.amazonaws.com (<public-ip>) 4.982 ms 4.946 ms ec2-52-79-0-147.ap-northeast-2.compute.amazonaws.com (52.79.0.147) 8.079 ms
2 100.65.19.0 (100.65.19.0) 4.068 ms 100.65.19.32 (100.65.19.32) 4.055 ms 100.65.18.240 (100.65.18.240) 4.491 ms
3 100.66.8.196 (100.66.8.196) 0.941 ms 100.66.8.250 (100.66.8.250) 49.429 ms 100.66.8.158 (100.66.8.158) 113.595 ms
4 100.66.10.66 (100.66.10.66) 4.751 ms 100.66.10.4 (100.66.10.4) 2.345 ms 100.66.10.36 (100.66.10.36) 4.721 ms
5 100.66.7.7 (100.66.7.7) 25.759 ms 100.66.7.197 (100.66.7.197) 7.392 ms 100.66.7.131 (100.66.7.131) 1.341 ms
...
20 nrt12s51-in-f4.1e100.net (172.217.26.228) 33.247 ms 108.170.242.129 (108.170.242.129) 29.300 ms bom05s09-in-f4.1e100.net (172.217.26.228) 28.417 ms
traceroute를 사용할 때는 주의해야 하는 사항이 있다. 비교적 작은 LAN 안에서는 비교적 정확한 경로를 보여줄 수 있지만 큰 네트워크나 인터넷 환경에서는 경로가 동적으로 바뀔 수 있다. 즉, 트래픽이 매번 전송될 때마다 같은 경로를 타고 간다는 것을 보장할 순 없다.
Transport Layer (L4, 전송 계층)
L4는 TCP와 UDP 등의 프로토콜을 포함하는 계층이다.
- TCP는 connection-orientd protocol이며, UDP는 connectionless protocol이다.
- Application은 IP 주소와 Port로 구성된 Socket에서 LISTEN 상태로 대기한다. 특정 포트로 들어온 트래픽은 커널에 의해서 LISTENING 중인 Application으로 전달된다.
가장 먼저 체크해야 되는 것은 localhost에서 listening 중인 포트이다. 만약 머신에서 웹이나 SSH 등의 특정 서비스에 연결할 수 없는 상태라면 이 결과가 도움이 될 수 있다. 다른 문제로는 이미 특정 포트를 listening 중인 프로그램이 있어서 해당 포트를 사용하려는 프로그램이 시작되지 못하는 경우가 있다. 이때 ss나 netstat 명령을 통해 확인해 볼 수 있다.
[ec2-user@ip-172-21-1-53 ~]$ sudo ss -tunlp4
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:* users:(("dhclient",pid=2839,fd=6))
udp UNCONN 0 0 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=2585,fd=6))
udp UNCONN 0 0 0.0.0.0:632 0.0.0.0:* users:(("rpcbind",pid=2585,fd=7))
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=2593,fd=5))
tcp LISTEN 0 128 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=2585,fd=8))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=28786,fd=3))
tcp LISTEN 0 100 127.0.0.1:25 0.0.0.0:* users:(("master",pid=3034,fd=13))
[ec2-user@ip-172-21-1-53 ~]$ sudo netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 2585/rpcbind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 28786/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3034/master
tcp6 0 0 :::111 :::* LISTEN 2585/rpcbind
tcp6 0 0 :::22 :::* LISTEN 28786/sshd
케이스
우리가 만약 원격 서버의 MySQL 3306 포트로 접근하려 할 때, 접근이 되는 것을 확인하기 위해서 telnet 명령이나 nc 명령을 사용할 것이다.
- TCP 확인을 위해서 telnet을, UDP 확인을 위해서 nc 명령을 사용하는 것을 권장한다.
- nc(netcat)은 일반적으로 보안 리스크가 있는 유틸리티로 간주하므로, 트러블 슈팅을 위해서 활용한 후 삭제하는 것을 권장한다.
만약 telnet이나 nc 명령이 실패하면 우선 MySQL이 해당 포트를 리스닝하고 있는지 확인할 필요가 있고, 리스닝하고 있다면 해당 리모트 호스트로의 접근은 가능한 지 테스트해볼 필요가 있다. 해당 리모트 호스트로 접근이 안된다면 호스트나 방화벽이 트래픽을 필터링하는 것은 아닌 지 확인해 볼 필요가 있다. 이후 문제가 없다면 해당 트래픽이 호스트로까지 도달은 하는지 차근차근 확인해 나가면 된다.
정리
대부분의 연결 문제는 네트워크 이슈가 많기 때문에 위의 내용을 유용하게 사용하면 좋을 것이다. 나도 아직 배워나가는 입장이지만 이런 것에 익숙해지기 위해 자주 사용해 볼 것이다.
'Linux' 카테고리의 다른 글
[Linux] ubuntu apt-get 속도 향상 하는 법 (0) | 2021.12.22 |
---|---|
[Linux] ubuntu에서 계정 생성 하기 (3) | 2021.12.20 |
[Linux] Windows 에서 WSL2로 ubuntu 사용하기 (0) | 2021.12.14 |
[Linux] 리눅스 기본 디렉토리 구조 (1) | 2021.12.13 |