본문 바로가기

에러 해결

외부 접속이 안되는 문제를 해결해보자

문제

서비스를 외부로 공개하기 위해서 포트포워딩을 사용해서 

외부 아이피의 5000포트로 접속하면 내부 아이피의 3000포트로 포워딩하도록 설정했다.

그런데 내부 네트워크에서 telnet으로 내부 아이피 접속 테스트를 하면 잘되었지만

외부 아이피로 테스트하면 접속이 안되었다.

netstat을 사용해서 네트워크의 연결 상태를 확인하면 

외부 네트워크 요청을 정상적으로 허용하고 있었다.

 

원인

호스트에서 로컬로 서버를 띄웠을 때는 외부 접속이 가능했지만

docker로 서버를 띄웠을 때는 외부 접속이 가능했다.

 

이 둘의 차이점을 이해하기 위해서 방화벽을 살펴봤다.

로컬로 서버를 띄웠을 때는 패킷이 아래와 같은 체인들을 거쳐서 들어온다.

반면 docker로 서버를 띄웠을 때는 패킷이 아래와 같은 체인들을 거쳐서 들어오게 되는데

forward 체인으로 들어오는 패킷은 drop되는 규칙이 적용되고 있었다.

아래의 명령어를 통해 확인할 수 있었다.

iptables -L FORWARD -n -v

 

IPTable

netfilter는 리눅스 커널 모듈로 들어오고 나가는 패킷들을 가로채서 작업을 수행할 수 있도록 해준다.

iptable은 netfilter의 기능을 제어해주는 도구이다.

 

체인은 패킷이 이동하는 경로마다 규칙을 적용할 수 있는 지점이다.

iptable에는 5개의 체인이 있다.

1. prerouting 체인 : 패킷이 가장 먼저 거치는 체인으로 목적지를 결정한다.

2. input 체인 : 목적지가 로컬인 패킷이 거친다.

3. forward 체인 : 목적지가 다른 곳인 패킷이 거친다.

4. output 체인 : 외부로 나가는 패킷이 거친다.

5. postrouting 체인 : 패킷이 나가기 직전 마지막으로 거치는 체인이다.

 

iptable은 5개의 테이블로 구성되어있다.

1. filter 테이블 : 패킷을 accept할지 drop할지에 대한 정보를 저장한다.

2. nat 테이블 :  패킷의 source나 destination을 변환하는 정보를 저장한다.

3. mangle 테이블 : 패킷의 header를 변환하는 정보를 저장한다.

4. raw 테이블 : connection tracking과 관련된 정보를 저장한다.

5. security 테이블 : 패킷의 보안과 관련된 정보를 저장한다.

 

해결

docker를 설치하면 docker와 관련된 사용자 정의 체인들이 추가된다.

기본적으로 forward 체인으로 들어오는 패킷은 drop하되

forward 체인에서 docker 네트워크 관련된 패킷만 docker 체인을 타도록 설정했다.

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -j DOCKER