[Network] IP 종류와 차이점, 서버 접속을 위한 포트포워딩 설정




IP 주소를 확인하다보면 명칭이 많다. 외부 IP, 내부 IP, 공인 IP, 사설 IP, 유동 IP, 고정 IP 등 여러가지가 존재하는데, IP가 IP지 뭔 종류가 이렇게 많은지 생각해본 적이 있을 것이다. 그리고 간혹 서버나 클라이언트를 구현하다보면 IP를 입력하는데 어떤 IP를 입력해야 정상적으로 접속이 가능한지 헷갈릴 수 있다. 여기에 대해 한번 알아보도록 하자. 

들어가기에 앞서, 필자도 IP에 대해 공부한 내용을 적은 것이며, 개념적으로 틀린 부분이 있을 수도 있습니다. 혹시라도 잘못 된 내용이 있다면 언제든지 지적을 환영합니다. 



1. 외부 IP (= 공인 IP)


아무것도 모르는 상태라고 했을 때 IP를 알고 싶어서 브라우저에 "아이피 확인" 이런 검색어로 검색해본 적이 있는가?  그럼 아이피 확인에 대한 여러 글들이 나오면서 몇개의 사이트가 나오게 되는데, 그런 사이트를 눌러보면 "내 IP : xxx.xxx.xxx.xxx" 이런 식으로 크게 적혀있는 것을 볼 수 있을 것이다.

집이 아닌 외부에 형성되어 있는 네트워크를 외부 네트워크라고 부르는데, 집에서 다른 외부와 통신을 할 때 사용하는 IP가 외부 IP 또는 공인 IP이다. 공인 IP라고 부르는 것은 외부에서 우리 집의 네트워크에 접속하려고 할 때 해당 IP를 통해서 접속할 수 있기 때문에 공인된 IP라는 의미로써 부르는 것이다. '공인된 IP로 해당 IP를 통해 특정 내부 네트워크에 접속을 할 수 있다.' 정도로 이해하면 되겠다. 



2. 내부 IP (= 사설 IP)


친구들과 어렸을 때 이야기를 하면서 컴퓨터 좀 만져봤다고 시작 - cmd - ipconfig 를 쳐서 뭔가 있어보이는 척을 했다는 얘기를 인터넷 상에서 심심찮게 볼 수 있다. 맥 OS에서는 시스템 환경설정 - 네트워크를 눌러보면 어떤 IP 주소가 나오는데 이것이 내부 IP 또는 사설 IP이다. 

내부 IP는 집에 형성되어 있는 내부 네트워크 안에 있는 기기 (데스크탑, 스마트폰, 노트북 등등) 에 할당되어 있는 IP이다. 이 내부 IP는 사용자가 임의로 부여해서 사용할 수 있는데, 그 대신 내부 IP는 인터넷에 연결이 되지 않기 때문에 내부 IP로는 외부 네트워크와 통신을 할 수 없다. 외부와 차단된 IP여서 사설 IP라고 부른다.

통신사의 인터넷을 사용하고 있는 집이라면 아래의 대역에 포함된 IP를 종종 볼 수 있을텐데, 공인 IP 중에서 해당 대역에 포함되어 있는 IP가 바로 내부 IP이며, 이 IP 대역을 제외한 나머지 IP는 공인 IP로 사용되어진다.
  • A 클래스 : 10.0.0.0 ~ 10.255.255.255
  • B 클래스 : 172.16.0.0 ~ 172.31.255.255
  • C 클래스 : 192.168.0.0 ~ 192.168.255.255
모뎀으로 인터넷과 연결을 하고 라우터 & 공유기를 연결하여 사설 IP를 생성해서 내부 네트워크 내의 모든 기기에 연결한다고 생각하면 되겠다. 물론 모뎀과 공유기 기능을 합친 것도 나오긴 하는데... 여기서는 이런 통신장치에 대해 설명을 하는 것은 아니므로 넘어가도록 하겠다. (그리고 사실 잘 모른다)




3. 유동 IP


유동 IP 혹은 동적 IP 라고 부른다. DHCP (Dynamic Host Configuration Protocol) 라고도 하는데, IP가 필요한 컴퓨터에 유동 IP를 부여하고 해당 컴퓨터를 종료하면 그 IP를 반환받아서 다른 장치에 다시 부여하는 것이다. 즉 컴퓨터를 끄기 전까지 가지고 있는 IP를 말한다. 내부 IP는 주로 유동 IP로 설정해서 내부 네트워크 내의 모든 기기가 인터넷을 문제없이 쓸 수 있도록 해준다. 물론 내부 IP를 고정 IP로 설정할 수도 있다.

재밌는 것은 인터넷을 연결해주는 모뎀의 주소는 외부 IP는 맞는데, 고정 IP인 것은 아니다. 그런데 모뎀의 IP를 보면 항상 같은 IP를 사용해서 고정 IP처럼 보이는데, 유동 IP는 "기기를 켰다 끌 때까지 가지고 있는 IP"이므로 모뎀을 껐다 켜면 IP가 바뀌어 있을 것이다.

즉 인터넷에 "아이피 확인" 이라고 쳐서 사이트에 들어가서 확인하는 IP는, SK broadband나 KT에서 운영하는 내부 네트워크(이 내부 네트워크에는 해당 통신사의 인터넷을 사용하는 가정이 포함된다.)의 유동 IP가 된다. 한마디로 드물게 인터넷에 쳐서 알아낸 IP가 바뀔 수 있는 것이다.

이 유동 IP와 고정 IP 가 서버 & 클라이언트 연결을 하는데 중요한 문제가 될 것이다. 




4. 고정 IP


말 그대로 고정된 IP이며, 부여된 컴퓨터가 해당 IP를 안 쓸 때까지는 계속 가지고 있는 IP이다. 즉 컴퓨터를 종료한다고 해도 고정 IP는 바뀌지 않는다. 유동 IP가 일반 가정에서 주로 사용되는 것과 달리, 고정 IP는 보통 웹 서비스 등을 운영하는 기업에서 구매해서 사용한다.




5. 고정 IP와 유동 IP에 대해서


고정 IP가 반영구적으로 가지는 IP이고, 유동 IP가 종료 때마다 바뀌는 IP라면, 매번 바뀌어서 헷갈리는 유동 IP보다 고정 IP가 사용하기 더 좋은 것 아닌가? 유동 IP를 사용하는 이유는 무엇일까?


1. 가격

말 그대로 고정 IP를 사용하려면 비싼 비용을 내야 한다. 현재 주로 사용되고 있는 IP는 IPv4 체계인데, 이는 2^32 = 4,294,967,296개 이며 현재 사용 가능한 IP가 고갈되었고, 반환된 IP를 재사용하기 때문에 비싼 돈을 내고 사용할 수 밖에 없다.

2. 보안 문제 

고정 IP는 상시 같은 IP 주소를 가지고 있으므로 유동 IP에 비해서 접속하기 편하다. 즉 해킹 하기도 편하단 얘기다. 대놓고 '우리 사이트에 들어와주세요' 의 목적을 가진 기업의 홈페이지 등이라면 당연히 접속하기 편한 고정 IP를 사용하는게 좋지만, 일반 가정은 누군가의 무작위 침입을 원치 않는다. 이러한 문제 때문에 유동 IP를 사용하여 외부에서의 침입에 대처하는 것이다.

3. 사용 목적

말 그대로 일반 가정은 인터넷에 접속해서 유튜브를 보든, 게임을 하든 간에 외부로 접속하는 것을 주된 목적으로 하지, 외부로부터의 접속을 목적으로 하지 않는다. 물론 컴돌이들이 용돈벌이로 서버 하나 만들어서 뭔가 하는 것이라면 몰라도, 대부분의 경우는 그렇다는 얘기다. 애당초 굳이 필요하지 않기 때문에 개인 가정에서 비싼 값 주면서까지 고정 IP를 사용할 이유가 있나 싶은 것이다.


여담으로 IPv4 = 2^32 인 것과 달리 IPv6 = 2^128 = 340,282,366,920,938,463,463,374,607,431,768,211,456개이다. 즉 전세계 사람들이 너도 나도 덤벼들어 사용하려고 한다 해도 다 못사용하는 양이다. 그렇다면 왜 IPv6를 사용하지 않는가? 에 대해선... 

공부 범위를 너무 벗어나긴 했지만, 일단 사용자가 많이 요구를 하지 않는다고 한다. 애당초 IPv4 체계로 구축된 인프라를 IPv6에 맞춰 다시 개발을 해야하니까, 말 그대로 귀찮기도 하고, 아직까지는 딱히 별 부족한 걸 못 느껴서 그렇다고 보면 될 것 같다. 



6. Localhost IP


자기 자신을 가리키기 위한 IP 주소이다. IPv4 체계에선 127.0.0.0 ~ 127.255.255.255 까지 있으며, 보통 127.0.0.1을 사용한다. IPv6 체계에서는 ::1(0:0:0:0:0:0:0:1의 약자) 이거 하나만 사용한다. 한마디로 컴퓨터 자기 자신을 의미한다. loopback IP 라고도 한다. 




서버 & 클라이언트 구현과 포트포워딩


이 내용을 공부하게 된 이유는 서버 구축과 클라이언트 구현을 하는 도중에 IP에 관해서 궁금한 점이 많아져 이 기회에 알아본 것이다. 아마 네트워크에 대한 전반 지식이 없는 필자와 같은 사람이 소켓 프로그래밍을 하려고 서버를 만들다보면 뭔가 코드는 맞는 것 같은데 접속이 이상하게 안되는 경우를 경험한 적이 있을 것이다. 이 글은 아래의 링크와 연관되어 설명한다.




INADDR_ANY 의 IP


server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

INADDR_ANY 는 0.0.0.0 상태로 대기하고 있다가 연결 요청이 들어왔을 경우 적당한 IP를 소켓에 바인드해서 보내준다. 그렇다면 이 INADDR_ANY를 사용하지 않고 서버 컴퓨터의 IP를 직접 입력하고 싶은 경우, 외부 IP를 넣어야할까? 내부 IP를 넣어야할까?

생각할 필요도 없이 내부 IP이다. 이 컴퓨터에 접속을 하려면 외부 IP를 통해 들어온 접속이 내부 네트워크 내의 해당 컴퓨터에 들어가려면 해당 컴퓨터의 IP 주소가 필요한 것이다. 즉 서버를 내부 네트워크 내의 특정 컴퓨터에 접속을 하려면 아래와 같은 그림과 같이,

공인 IP를 통해 접속한 INTERNET에서 공유기가 할당한 사설 IP 를 통해 컴퓨터로 접속하는 것이다. 결론적으로 서버를 구현한 컴퓨터의 내부 아이피를 집어 넣어도 된다.


Client의 socket IP


ia = InetAddress.getByName("여기에 본인의 IP 주소를 적으면 된다.");    
socket = new Socket(ia,9000);

여기서의 IP는 어떤 IP를 집어넣어야 할까? 괜히 서버 컴퓨터의 내부 IP를 넣으면 시간초과 에러가 발생할 것이다. (잘못된 IP를 넣게 될 경우 IP를 찾지 못해 시간 초과가 발생한다.) 내부 IP는 인터넷과 연결되지 않은 내부 네트워크에서만 사용되는 IP이기 때문에 외부에서 직접 접근할 수 없다.

따라서 당연히 접속하고자하는 컴퓨터의 공인 IP를 넣어야한다. 외부 네트워크에서 특정 내부 네트워크 내의 컴퓨터에 접속하기 위함이므로 외부 IP를 통해 해당 내부 네트워크로 진입한 후, 공유기를 통해 해당 컴퓨터로 접속하게 된다. 이 때, "특정 컴퓨터로 접근하려면 그 컴퓨터의 내부 IP가 필요한 것 아닌가?" 라는 의문이 들 수도 있는데, 그것을 위해 포트포워딩이라는 것을 설정해줘야 한다. 

그 전에 잠깐, 위에서 공인 IP라도 고정 IP가 아닌 유동 IP이기 때문에 드물게 바뀔 수 있다고 했는데, 그렇다면 클라이언트에서 해당 공인 IP로 접속을 했을 때, 드물게 바뀌는 그 상황 때문에 접속을 못하게 되지 않을까?

물론이다. 그렇기 때문에 기업에서는 공인 IP로 고정 IP를 사용한다. 혹은 DDNS라는 것을 이용해 고정 IP처럼 사용할 수 있는데, 이건 기회가 생긴다면 따로 정리해보겠다. 


포트포워딩 (Port Forwarding) 이란?


아래 그림에서 '컴퓨터 1'이 포트 9000번을 열었고, 컴퓨터 1 9000번 포트로 접속하려고 한다. 제대로 접속이 될까?

당연히 컴퓨터 1까지 도달하기 전에 공유기에 도달하고 끝난다. 공유기에 도달한 후 컴퓨터 1, 2, 3 중에 어디에 접속할 것인지 판단할 수 없기 때문이다. 그래서 "9000번 포트로 들어오는 연결을 컴퓨터 1로 보내라" 라는 명령이 필요한 것이며, 이를 포트포워딩 (port forwading) 이라고 하고 공유기에서 설정해줄 수 있다.

만약 공유기가 여러 개라면? 당연히 모든 공유기에 대해서 9000번 포트로 들어오는 연결을 어디로 보낼지 설정해줘야 한다. 

공유기 포트포워딩 설정하는 방법은 구글링을 해보면 여기저기서 많이 나오기도 하고, 나중에 기회가 된다면 따로 소개하도록 하겠다.
그렇다면 공유기 포트포워딩도 끝냈고, 정상적인 IP로 입력도 했고, 코드도 문제 없겠다, 이제 제대로 통신할 수 있는건가? 서버를 돌리고 클라이언트에 접속을 시도하면, 윈도우나 맥 OS로 서버를 만든 사람이라면 다른 부분에서 문제가 없는 이상 정상적으로 통신이 되겠지만, 가상머신 리눅스로 서버를 구축한 사람이라면 아마 포트포워딩이 제대로 안 된 것 마냥 시간 초과가 발생할 것이다. 도대체 뭐가 문제인가? 코드도 분명 문제 없고, IP도 문제 없고, 모든 게 완벽한 것 같은데..

가상 머신이라는 것을 생각해보자. 사설 IP는 컴퓨터에 부여하는 것인데, 이 가상 머신도 "가상의 컴퓨터"이다. 한마디로 가상 머신에도 내부 IP가 할당 될 것이고, 그 말은 이 가상 머신에 대해서도 포트 포워딩을 해줘야 한다. VM 리눅스 포트 포워딩 방법도 구글링을 하면 나올 것이고, 공유기 포트 포워딩과 함께 기회가 된다면 정리해보겠다.




마치며...


누군가에겐 무척 당연하고 별거 아닌 정보일 것이고, 누군가에겐 잊고 있어서 리마인드 하는 느낌으로 다시 훑어 보는 글일 수 있다. 또 누군가에겐 밤새도록 해결 못한 문제를 해결할 수 있는 실마리가 될 지 모른다. 혹시라도 필자가 겪었던 끔찍한 에러들과 문제들을 다른 누군가는 해매지 않고 해결하길 바라며 글을 마친다. 


댓글