Unity로 MMORPG를 개발하고 있을 때 발생한 일이다.
네트워크는 Mirror를 사용하였고 존 서버를 게임 서버에 띄워서 테스트를 진행하고 있었다.
에디터에서 Host로 실행했을 때 문제없이 API 통신이 성공하였지만 존 서버와 연결을 한 후에 통신을 한 경우 요청이 처리되지 않는 상황이 발생했다.
에러는 curl error 28 connection time out으로 요청이 시간 내에 처리되지 못해서 실패한 경우이다.
먼저 게임 서버와 통신을 다시 테스트하기 위해서 IP를 확인하고 방화벽의 Port 상태를 확인했지만 문제가 없었기 때문에 더욱 혼란스러웠다. 다행히 테스트용 URL를 만들고 브라우저에서 호출을 해서 API에는 문제가 없다는 것을 확인한 후에 혹시나 하는 생각에 게임 서버에 원격으로 접속하여 URL을 호출하여 테스트해 보니 time out 에러가 발생하는 것을 확인할 수 있었다.
즉 외부에서 서버의 Public IP로 접근하는 것은 허용이 되지만 내부에서 Public IP로의 접근은 막혀 있었고 LocalHost와 Private IP는 또 잘 동작했기에 이 부분에 대해서 좀 알아보기로 했다.
동작이 실패하는 과정은 다음으로 추정한다.
1. 내부에서 Public IP로 요청
2. 라우터/방화벽에 도달, NAT 설정은 내부에서 내부로 가능 경로를 인식하지 못함
3. 패킷이 처리되지 못하고 실패하게 됨
이러한 상황을 해결해 주는 방법이 Loopback NAT이다.
Loopback NAT
또는 Hairpin NAT으로도 부른다.
위 상황이 장황했지만 간단하게 말하면 내부 네트워크의 장치가 같은 네트워크의 다른 장치에 접근할 때 직접 내부 IP를 사용하는 경우 Loopback NAT이 없다면 내부 사용자는 외부로 나갔다가 다시 들어오는 비효율적인 경로를 통해 접근하거나 이 접근조차 완전히 차단되는 상황이 발생한다.
Loopback NAT은 내부 네트워크의 클라이언트가 공개 IP 주소를 통해 요청을 보낼 때, 라우터나 방화벽이 이 요청이 내부로 향하는 것을 인식하고 적절히 내부 IP로 변환하여 처리한다.
1. 라우터/ 방화벽에 내부에서 Public IP로 향하는 요청 감지
2. 해당 요청을 자동으로 내부 Private IP로 변환하여 처리
3. 응답 패킷을 처리하여 클라이언트 반환
이렇게 되면 내부 및 외부 사용자가 동일한 URL을 사용할 수 있고 내부 트래픽이 불필요하게 외부로 나가지 않고 효율적으로 라우팅이 된다. 또한 동일한 서비스에 대해서 내부용과 외부용 DNS 설정을 별도로 유지할 필요가 없어진다.
문제도 해결하고 새로운 사실도 알게 되었다. 일단은 내부에서 Private IP를 사용하도록 처리하고 다음 회의에서 Loopback에 대해서 언급을 하기로 한다.
NAT
여기서 NAT이란 무엇인지에 대해서 사고가 확장된다.
NAT은 Network Address Translation으로 "사설 IP와 공인 IP" 간의 주소를 변환하는 기술이다.
여러 대의 컴퓨터가 하나의 공인 IP로 인터넷을 공유, IPv4 주소 부족 문제를 해결, 외부에서 직접 내부 네트워크로 접근하기 어렵도록 보안의 목적 등으로 사용된다.
예를 들어 집에서 인터넷을 쓰는 경우 보통 핸드폰에서는 192.168.0.10과 같은 사설 IP를 사용하는데 외부 인터넷에 요청을 보내게 되면 NAT 장비가 그 요청을 중간에서 공인 IP로 바꿔서 보내고 응답이 오면 다시 원래의 사설 IP로 돌아오게 된다.
즉 여러 개의 장비로 인터넷을 나누어 쓰더라도 각각의 내부 IP는 다르지만 외부로 나가는 요청에서는 NAT 장비를 통해 동일한 공인 IP로 식별되게 된다.
이외에도 여러 NAT 방식이 존재한다.
SNAT(Source NAT) : 출발지 주소를 변경, 내부에서 외부 통신
DNAT(Destination NAT) : 목적지 주소를 변경, 외부에서 내부 통신