SharedIT | 묻고 답하기(AMP)

서버로 NAT되어 들어오는 클라이언트의 원래 IP를 알 수는 없을까요?

안녕하세요.

언제나 많은 도움을 받고 있습니다.


저희 회사 그룹웨어가 클라우드상에 위치해 있습니다.

사무실과 클라우드 간에 VPN으로 연결되어 있는데,

사무실 PC들 사설대역은 192.168.x.x 대역이고, 서버의 사설대역은 10.61.x.x 대역이라

방화벽에서 192.168.x.x -> 10.61.x.y으로 NAT 처리가 되어 있습니다.

그렇다보니 그룹웨어 서버에서 보기에는 모든 클라이언트 IP가 10.61.x.y로 동일하게 표시되는데,

접속 ip를 확인해야 할 필요가 있을 때 로그가 아무 짝에 쓸모가 없습니다 ㅠ.ㅠ


서버에서 NAT되기 전 IP를 볼 수 있도록 할 수는 없을까요?

Tags : 태그가 없습니다.

7개의 답변이 있습니다.

wansoo
  0 추천 | 약 2년 전

VPN(Virtual Private Network)은 터널링 기술을 사용하고, 대표적인 VPN 프로토콜로 PPTP( Point to Point Tunneling Protocol)와 L2TP( Layer 2 Tunneling Protocol )가 있겠는데요,.

L2TP는 PPTP와 L2F ( Layer 2 Forwarding )가 결합된 형태의 프로토콜이 되겠고요.

PPTP는 PPP ( Point to Point Protocol ) 프로토콜을 그대로 사용하면서 GRE ( Generic Routing Encapsulation) 프로토콜을 사용하여 IP Packet를 캡슐화 시켜서 보내게 되고요.

캡슐화된 패킷안에 출발지 컴퓨터의 사설 IP 정보가 Packet의 Payload(data)에 포함되어 있어 추출해 낼 수 있게 됩니다.


VPN은 양쪽 네트워크(또는 컴퓨터) 간에 연결하는 가상 사설 네트워크이며, 다양한 종류의 프로토콜이 있겠고요. 

두 지점간에 연결되는 방식이기 때문에 두 지점간에 표준화되지 않은 특수한 프로토콜을 사용할 경우도 있겠는데요.


일반적인 관점에서는 상대편 컴퓨터의 사설 IP를 확인할 수 있어야 하는 게 정상적이지만...

사용하는 VPN 프로토콜에 따라 확인하기 어려운 경우가 있을 가능성도 배제하기는 어려울것 같네요.


아래의 가상 사설망의 핵심 터널링 기술 개요 자료를 참고해 보시면 도움 될 것 같고요.
https://www.itfind.or.kr/WZIN/jugidong/947/94703.html

GRE( Generic Routing Encapsulation )는 시스코에서 개발해서 표준화 된 프로토콜이고 RFC 1701RFC 1702RFC 2784RFC 2890RFC 8086 등에 정의되어 있고요.



빨간신발
  0 추천 | 약 2년 전

NAT(Network Address Translation)

네트워크 주소 변환입니다.

제가 알기로는 192.168.1.1 이 외부로 나갈때는 

공유기(라우터, 방화벽 등)의 IP로 변환됩니다.

192.168.1.1 위에 1.1.1.1로 다시 캡슐화하는 것이 아니고

변환하여 전송하는 것으로 알고 있습니다.

즉 발신지 정보가 192.168.1.1 -> 1.1.1.1 로 변환되어 외부로 전송됩니다.

그래서 서버측에서는 공유기 안쪽의 사설 IP의 정보를 알 수 없습니다.

서버측에서는 응답으로 1.1.1.1로 하면 

공유기에서 받아서 목적지는 1.1.1.1에서 192.168.1.1로 다시 변환해서 클라이언트에 전송합니다.

이런 관계로 불가능하리라 생각됩니다만.

웹프로그램을 하실 수 있으면 자바스크립트 같은 클라이언트 사이드 언어로

클라이언트 ip를 추출하시고 데이터로 전송하시면 될 듯 합니다.

서버에서는 해당 ip를 받아서 별도로 저장해주시면 됩니다.


wansoo | 약 2년 전

패킷안에 클라이언트의 원래 IP를 캡슐화해서 가지고 있다면 서버 사이드 프로그래밍으로 클라이언트의 원래 IP를 추출할 수 있을 것이고, 패킷안에 클라이언트의  원래 IP를 가지고 있지 않다면 서버에서는 어떤 방법으로도 클라이언트의 원래 IP를 알아 낼 수 있는 방법이 없을 것입니다.

NAT가 내부와 외부 IP를 1:1로 변환하는 테이블을 가지고 있으면서 전환을 한다면 클라이언트에서 출발해서 서버에 도달한 클라이언트 요청을 서버가 다시 클라이언트로 돌려 보낼때 NAT가 1:1로 변환된 IP로 해서 NAT에 돌려 보내면 NAT 장비가 목적지로 설정된 IP를 기반으로 원래 요청한 클라이언트 IP가 무엇인지를 매칭 테이블을 통해서 변환 확인해서 클라이언트로 서버가 응답한 내용을 보내 주면 되겠지만...

1:N 변환 방식으로 변환되는 IP일 경우에는 서버로 부터 돌려 받은 1개의 IP로 내부에 있는 다수의 컴퓨터 중에 어떤 IP로 전환해서 돌려 줘야 하는지 알수 있는 방법이 없기 때문에 단순 변환 방법으로는 서버가 응답한 결과를 클라이언트에게 다시 돌려 줄 수 있는 방법이 없어져 버리게 됩니다.

1:N 변환일 경우라도 NAT 장비가 서버로 부터 받은 응답 결과를 원래 요청한 클라이언트에게 돌려 줄 수 있으려면 클라이언트로 부터 받은 패킷을 통째로해서 데이터로 캡슐화시키고, 찾아 가는 목적지 주소는 그대로 하고, 출발지 주소를 NAT 장비 자신의 IP로 넣어서 패킷을 새로 만들어 찾아 가려는 서버로 보내게 됩니다.

그리고 서버가 응답해 오는 결과를 받았을때 서버가 보내온 패킷을 분해해서 원래 보냈던 클라이언트 IP를 꺼집어 내어서 목적지 IP로 설정해서 서버가 보낸 결과를 클라이언트가 받을 수 있게 보내어 주게 되는 과정을 거치게 됩니다.

이런 절차 없이는 클라이언트와 외부에 있는 서버간에 NAT 장비 중개를 통한 통신이 진행되기 어려워 집니다.

빨간신발 | 약 2년 전

저도 캡슐화일거라 생각하고 살았는데..


오늘 캡슐화인지 변환인지 많이 찾아봤는데 캡슐화한다는 내용은 못 찾고..


변환만 나오더군요.. 이름도 Natwork Address Translation


Nat를 1:1로 하면 문제가 없는데 말씀처럼 N:1로 같은 서비스를 같은 포트로 요청하면 충돌이 발생합니다.


192.168.1.1:54321 -> 1.1.1.1:54321 -> google.com:443


이렇게 하나가 가면 문제가 없고


192.168.1.1:54321 -> 1.1.1.1:54321 -> google.com:443


192.168.1.2:54321 -> 1.1.1.1:54321 -> google.com:443


이렇게 두개의 요청이 중복되면 나중에 구글에서 답해주는 부분이 어느 클라이언트 갈지 선택할 수 없게 됩니다.


그래서 포트 변환을 같이 합니다.


192.168.1.1:54321 -> 1.1.1.1:54321 -> google.com:443


192.168.1.2:54321 -> 1.1.1.1:12345 -> google.com:443


이런식으로 nat에서 포트도 변환 후 해당 내용을 일정시간 기억하고 있다가


구글에서 1.1.1.1:54321로 응답을 하면 192.168.1.1:54321로 보내주고


구글에서 1.1.1.1:12345로 응답을 하면 192.168.1.2:54321로 보내줍니다.


저도 제가 아는 지식을 조합해서 설명하다보니 일부 부정확한 사실이 있을 수 있습니다.


https://aws-hyoh.tistory.com/145


이 블로그에 잘 설명되어 있습니다.

wansoo | 약 2년 전

지식을 탐구하는 열정 보기 좋습니다.

그런 열정이 있기 때문에 고급 지식을 쌓아 가고 있다고 보여 지네요.

포트 주소를 이용한 주소 변환 기법 사용되는것 맞고요.

NAT에 있어서 항상 PAT 기법이 활용되는 것인지는 좀 더 확인해 봐야 할 것 같네요.

포트 주소를 활용해서 원래 출발지 컴퓨터를 찾을 수 있다는 건 충분히 설득력 있습니다.

그렇지만 한가지 빠진게 있네요.

NAT을 통해서 나가는 패킷만 가지고 통신사에서 NAT 내부에 몇대의 컴퓨터가 인터넷을 사용하는지는 알아 낼 수가 있고, 웹 서버에서 클라이언트의 사설 IP 주소를 추출해 낼 수 있게 되는 원리는 설명하기가 어렵겠네요.

웹서버에서 

"HTTP_X_COMING_FROM"

"HTTP_X_FORWARDED_FOR"

"HTTP_X_FORWARDED"

"HTTP_X_REAL_IP"

"HTTP_VIA"

"HTTP_COMING_FROM"

"HTTP_FORWARDED_FOR"

"HTTP_FORWARDED"

"HTTP_FROM"

"HTTP_PROXY_CONNECTION"

"CLIENT_IP"

"FORWARDED

와 같은 환경 변수들을 사용해서 NAT 장비 내부에 있는 IP 주소를 찾으려는 시도 조차 하기 어렵게 될 것이고요.


Genghis Khan | 약 2년 전

빨간신발님이 내용에 공감이 가네요

과거 동일 문제로 해결되었던 부분이네요

빨간신발 | 약 2년 전

생각해보니 통신사에서 내부 단말수를 몰라야 정상인데 아는게 이상하네요.

그래서 생각해봅니다.

1.  통신사에서 제공하는 공유기에 해당 정보를 수집해서 전송하는 기능이 숨겨져 있다.

  -> 충분히 가능할 수 있을 거라 생각합니다. 

통신사 공유기 아니면 모를까?

2. iptime 같은 국내 독점에 가까운 사업자고 국내 사업자인 관계로 일반인들 모르게 1번 기능을 숨겨두었다.

  -> 의심은 가지만 이런 이슈를 지금까지 잘 숨기고 있다는게 어려울 것 같네요.

3. 그럼 해외에서 수입한 제품을 사용하면 통신사가 내부의 단말수를 모를까?

  ->  방법은 모르겠지만 어떻게든 수집하리라 생각합니다.

그래서 생각한 방법은

통신사에서 실제 http 헤더를 까서 일정시간동안 수집되는 o/s정보를 수집해서 대략적인 추측을 하지 않을까 생각이 드네요.


그리고 http 헤더에는 클라이언트의 실제 사설ip(공유기에서 할당받은 사설ip)는 없는 듯 합니다.(개인적인 생각입니다.)

저도 10년전에 같은 문제로 http헤더에서 ip정보 추출하는 것은 포기했었습니다.

10년도 넘었고 시간이 지났으니 요즘은 다를 수도 있겠네요.

요즘은 워낙 다양한 언어가 많이 있으니 꼭 헤더 정보가 아니더라도 추출은 가능하겠지요.


wansoo | 약 2년 전

무에서 유를 만들어 내지는 못해요.


숨겨둔걸 찾아 내는 건 멋진 툴을 이용하거나 기술로서 처리할 수 있지만,


패킷에 포함되지 않은 정보는 아무리 좋은 언어가 나오고, 기술이 발전해도 알아 내지는 못하겠고요.


NAT 장비 ( 방화벽 )에서 NAT 테이블에 담겨 있는 정보를 기반으로 내부의 IP 정보를 알아 낼 수 있는 유일한 방법은 서버에서 클라이언트가 있는 곳의 방화벽(NAT장비)에게 질의를 해야 알 수 있겠죠.


표준적인 방법으로 외부 서버에서 NAT 장비에 매칭된 IP를 질의하는 Protocol이 존재하지는 않겠고요.


NAT 장비에 매칭 IP 쿼리 프로토콜이 있다할지라도...


서버에서 사설 IP를 추줄하기 위해 클라이언트쪽 방화벽에 질의해서 결과를 다시 받아 처리한다는 자체가 처리 속도 면에서 큰 손실을 발행하는 요인이기 때문에 특수한 경우가 아니라면 잘 사용하지 않으려고 하겠고요.


패킷안에 클라이언트의 내부 주소가 담긴 정보가 포함되어 있기 때문에 아래와 같은 다양한 환경 변수로 부터 내부 사설 IP를 찾아 내는 기법을 일반적으로 활용되고 있고요.

"HTTP_X_COMING_FROM", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_REAL_IP", "HTTP_VIA", "HTTP_COMING_FROM", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_FROM", "HTTP_PROXY_CONNECTION", "CLIENT_IP", "FORWARDED"


환경 변수들의 이름들을 잘 한번 관찰해 보세요.

다양한 환경 변수를 사용한다는 건, 다양한 장치들에 의해 캡슐화 처리를 하고 있다는 의미가 되겠고요.

forward, via, proxy 등의 단어들이 있는데...

이들은 포워드 시키는 장비, 경유되는 장비, 프락시 장비 등등에서 캡슐화 시켰을때 내부 IP를 찾아 낸다는 의미가 될테고요.

빨간신발 | 약 2년 전

https://kldp.org/node/62354

과거 오래전부터 다른 곳에서도 많은 이슈가 있었네요.

중간에 "김정균"님이 답변을 하시것을 보면

"해당 헤더는 일반적인 proxy server나 cache server에서 보내주는 헤더 입니다. NAT (즉 공유기 같은 것) 환경에서는 해당 헤더가 넘어오지 않습니다."

저도 이 말에 동의 합니다.


미생
  0 추천 | 약 2년 전

내부망에 사설을 나눠서 쓰고 하는 경우에는 서버측에 케이블을 두개 꽂아서 하나는 외부용, 하나는 내부용으로 만든 뒤 route_table 수정을 해서 처리하는 방법도 있는 것 같더군요

저희도 51.x를 쓰는데, 53.x로 route 돌려서 내부에서 접속로그 남기고 했었는데, 시간 지나면서 결국 해결 못하고 현재는 두는 중입니다.

wansoo
  0 추천 | 약 2년 전

NAT으로 패킷이 캡슐화되어 전달되더라도...

서버가 수신한 패킷에 대한 응답을 다시 클라이언트까지 돌려 보내야 하기 때문에

캡슐화된 패킷 안에 클라이언트 IP를 포함하고 있어야만 출발지인 클라이언트에게 다시 결과를 되돌려 줄 수 있겠고요.

클라이언트로 부터 수신한 패킷을 열어서 잘 분석해 보면 클라이언트의 IP 주소를 확인할 수 있을거라 봅니다.

예를 들어 웹서버에서 PHP로 클라이언트 사설 IP를 찾아 낼때 아래와 같은 함수를 만들어서 여러개의 환경 변수를 점검해서 찾아 내는 기법을 이용하게 되고요.

================

function getRealClientIp() {

  $ipaddress = '';

  if (getenv('HTTP_CLIENT_IP')) {

     $ipaddress = getenv('HTTP_CLIENT_IP');

  } else if(getenv('HTTP_X_FORWARDED_FOR')) {

     $ipaddress = getenv('HTTP_X_FORWARDED_FOR');

  } else if(getenv('HTTP_X_FORWARDED')) {

     $ipaddress = getenv('HTTP_X_FORWARDED');

  } else if(getenv('HTTP_FORWARDED_FOR')) {

     $ipaddress = getenv('HTTP_FORWARDED_FOR');

  } else if(getenv('HTTP_FORWARDED')) {

     $ipaddress = getenv('HTTP_FORWARDED');

  } else if(getenv('REMOTE_ADDR')) {

     $ipaddress = getenv('REMOTE_ADDR');

  } else {

     $ipaddress = '알수없음';

  }

  return $ipaddress;

}

===============

환경 변수를 통해서 찾을 수도 있고, 아니면 직접 수신한 패킷을 열어서 캡슐화되어 있는 데이터에서 추출해 내어 확인할 수도 있을 걸로 보여지네요.

빨간신발
  0 추천 | 약 2년 전

web에서는 사설에서 공인으로 변경되어 접속하면

공인ip만 확인이 가능합니다.

웹서버 로그에도 공인ip로 기록이 됩니다.

Back Go
  0 추천 | 약 2년 전

윗분 말씀대로 1:1 NAT 방식이 아니라면 어려울듯합니다. 

192.168.x.x -> 10.61.x.y 으로 가는 방화벽 로그로 확인 하는것이 최선일듯합니다. 

타와리
  0 추천 | 약 2년 전

그룹웨어가 웹 방식이면 브라우저에서 NIC 인터페이스의 정보를 주지 않기 때문에 

불가합니다.


개인 사용자의 사설 IP (192.168.x.x) -> 별도의 사설(10.60.x.x) 로

1:1 NAT 방식으로 변경하셔야 합니다.