localhost 를 외부에서 접속하기

김형섭 (Matthew)·2024년 6월 7일
41

네트워크의 원리

목록 보기
2/6
post-thumbnail

Why

localhost 로 내 PC에서 내 서버에 접속할 수 있습니다.
지난 글에 제가 자세한 원리를 소개해 드렸죠.

localhost 동작 원리
(이번 글을 이해하려면, 위 글을 먼저 이해해야 합니다.)

그런데 말입니다.

내 PC에 나 말고 타인의 접속을 받고 싶다면, 어떻게 해야할까요?
내 지금 IP를 알려주면 될까요? 그렇다면 Private IP 를 알려주나요?
나는 되는데 상대방은 안된다구요?

된다면 왜 돼는지, 안되면 왜 안되는지, 물음표가 많으실 겁니다.

오늘 이 부분을 명쾌하게 알아봐요~

localhost 를 PC 밖에서 접속 하려면

localhost127.0.0.1 이라는 IP 주소를 사용한다는 것을 이제 다 아시죠?
127.0.0.1 은 나 자신, 바로 내 주소를 의미 합니다.

그런데 지금 상황은 PC 밖에서 타인이 내게 접속하는 것이죠.
그 타인의 컴퓨터도 IP가 있을텐데, 그 안에서는 그들 자신도 127.0.0.1 이잖아요?

결국 127.0.0.1 이라는 주소를 가지고는 자기 자신 외에는 통신이 불가능한 사태가 발생 합니다.
그래서, Loopback NI가 아닌, 다른 Network Interface 를 사용해야 합니다.
Lan 이나 Wifi 같은 것 말이죠.

생각해보면, 타인의 접속을 받기 위해서는 PC 밖으로 데이터가 나가고 들어와야 하니까
애초에 localhost 는 사용 할 수 없습니다.

다른 NI 를 통해 접속 받기

이제 다른 NI를 통해 접속을 받기로 했으니, 나의 IP를 상대방에게 알려줘야 합니다.
상대방은 그 IP로 접속을 할 것이고요.
물론 같은 망 내에 연결되어 있어야 겠죠.

그런데, 그동안 localhost 로만 서버를 띄워 오셨다면,
IP를 알려줘도 접속이 안될거예요.

이 이유를 이해하려면 서버 앱을 시작할때 bind 하는 동작을 이해해야 합니다.

서버앱의 Bind

서버 앱이 있습니다.
이 서버는 이 PC의 어떤 NI에서 오는 요청을 받아야 할까요?
그냥 다 받는 걸까요?

아닙니다.
사실 명시 해야 합니다.

즉, 내 앱은 어떤 IP어떤 포트로 오는 요청에 대해서 처리하겠다 라고, 말하는거죠.
이때 서버 앱은 다른 누구도 아닌, NI 한테 얘기하는 것입니다.

이 행위를 Bind 라고 하는데요.
서버 개발 해보신 분은 아래와 같은 IP들을 많이 보셨을 겁니다.

여기서 IPPort가 서버가 Bind 할 때 필요한 정보 입니다.
이때, 여기에 명시한 IP 대역이 어느 NI 에 속하는지 찾아내서, 그 NI에게 말해서 Bind 합니다.

그러니까

  • 127.0.0.1:3000 으로 Bind 하면, 결국 루프백 NI 에만 등록 합니다.
  • 192.168.0.11:3000 으로 Bind 하면, 같은 192.168.0.0/24 IP 범위를 가진 NI 한테만 등록하고요.
  • 0.0.0.0:3000 으로 하면, 그냥 모든 NI에 다 등록 합니다.

결론은

127.0.0.1 로 서버를 띄워 놓았다면,
지금 내 IP가 192.168.0.11 이라고 할때, 이 IP를 주변에 아무리 알려줘도
접속을 못한다는 거죠.

이 경우는 서버를 확실히 192.168.0.11 로 바인드 하거나,
0.0.0.0 으로 바인드 해야, 타인이 접속이 가능 합니다.

결국, 이 이야기는 서버의 Bind 동작NI와 밀접한 관계가 있기 때문에
NI를 모르고서는 트러블 슈팅 하기가 어려웠을 겁니다.

이제는 확실히 이해하셨죠?
그런데, 이렇게 IP를 알려주고 하는 행위가 너무 불편 하고, 뭔가 굉장히 구식 같습니다.

좀 편리한 방법이 없을까요?

당연히 신박한 방법이 있죠!

ngrok

ngrok 라고 들어보셨나요?
https://ngrok.com 라는 서비스 입니다.

이 서비스를 사용하면 내 localhost 서버를 IP 없이,
외부에서 접속할 수 있는 public 도메인 주소로 바꿔줍니다.

신기하죠?

그런데, 이것도 사실은 알고 나면, 크게 어려운 기술이 아닙니다.

ngrok 의 동작 구조

  • 로컬에 ngroklocalhost:3000 을 서버로 호스팅 하겠다고 말해요
  • 그럼, ngrok 가 내부적으로 눈에 안보이는 SSH 연결을 하나 만들어요.
    • 이때, ngrok 의 인터넷 서버에 SSH로 연결 하게 됩니다.
  • 그리고 ngrok 가 자신의 인터넷 서버 안에서 특정 도메인 주소와 매핑되는 서버를 띄웁니다.
    • 내가 받은 나만의 domain host와 연결하죠.
    • 예를 들면, abc.ngrok.io 처럼요.
    • 그 서버에서는 SSL도 다 처리해주고, 외부 연결시 필요한 귀찮은걸 다 해줍니다.
  • 이제 그 도메인 주소로 외부에서 요청이 오면, ngrok는 모든 트래픽을 나와 연결된 SSH 로 포워딩 합니다.
    • 엄밀하게는 SSH 터널링이라는 기술을 사용해요.
  • 그럼 내 PC에 띄워진 ngrok 가 그렇게 오는 모든 트래픽을 다시 localhost:3000 으로 중계하고요.
  • 결국, 외부에 있는 사람도 내 네트워크에 없지만, ngrok 가 외부와 나 사이에 가상의 다리를 놓아서 가능해 집니다.

ngrok 는 사실 단순한 기술 입니다.

그러나, 사실 위처럼 간단히 사용할 수 있는 사용성!
이게 너무 너무 편리해서 많이 사용 하는 것입니다.

https 를 위한 SSL 처리 부터,
SSH 터널링과 그 연결 유지 관리 등,
자잘한 기술을 한데 모아 편리하게 제공하는 서비스 입니다.

ngrok 관련 한가지 에피소드가 있는데요.
이름이 왜 ngrok 인지 자신들도 모른다고 합니다 ㅎㅎ

마무리

ngrok 와 비슷한 서비스로는 오픈소스도 있고 유사 서비스가 많습니다.

비슷한 서비스들

다만, 이런 서비스는 인터넷에 호스팅 되는 서버가 반드시 필요하고
도메인에 대한 인증서 부터 서버 셋업이 꽤 지루 합니다.

또한 단일 서버로는 SSH 터널링의 기본 제약사항인
1인 1포트 점유를 하려면, 서버마다 포트숫자의 한계(65536개)가 있기 때문에
동시 사용 가능한 유저수 제한 등의 조치들이 필요 합니다.

(깜짝퀴즈: 포트숫자가 왜 65536개 일까요? → byte 랑 관계가 있습니다.)

그래서 이미 있는 서비스를 편리하게 사용하는 것이 좋습니다.
오늘은 localhost 를 인터넷으로 확장하는 방법에 대해 알아봤는데요.

재미 있으셨나요?
다음에도 좋은 글로 찾아올께요.

아임웹 CTO
매튜 드림.

profile
CTO at Imweb, 20년차 개발 장인, 전) 플레이오토 CTO/창업자

4개의 댓글

comment-user-thumbnail
2024년 6월 11일

이번에도 좋은 글 감사합니다. 네트워크 터널링에 대한 내용을 알기쉽게 너무 잘 설명해주셨네요... 65536은 2의 16승인데, 16비트로 구분하기 때문일까요~?

1개의 답글