네트워크에서 NAT에 대한질문인데요

mogin1의 이미지

NAT라우터에 연결된 로컬 호스트A가있습니다.

A가 데이터를 보낼때 NAT라우터를 통과하는데여 NAT라우터를 통과할때 보낸쪽의 사설아이피를 공인 IP로 변환해주는역활을 하지요.

그런데 NAT라우터는 자신에게보낸 로컬호스트 사설아이피를 보고 그 주소가 자신한테 속한 로컬영역인지 아닌지 어떻게 알까요?

koseph의 이미지

정확히 말하면 NAT은 대표적인 IP 패킷 조작 기술 중 하나입니다.

여러가지 기법이 있는데 여기서 그걸 다 설명 드릴 순 없고 간단하게 개념만 살펴보죠.

사실 이것도 소스를 보면 간단한게 아닙니다. 은근히 복잡합니다.

C를 아신다면 커널 소스의 netfilter 부분을 보시면 되겠습니다.

그리고 IP를 제대로 이해하시고 계시면 이해가 더 빠릅니다.

IP 주소에는 source와 destination이 있지요? 그리고 또 뭐가 더 있나요?

바로 port number입니다. 이것까지 있어야 IP 패킷 헤더에 이러한 정보가 충실히 들어가 있어야 패킷이라고 부를 수 있겠죠?

영어가 되시면 다음 참조 URL을 보시면 되겠습니다.

http://www.kerio.co.uk/manual/wrl/en/131.htm

리눅스 커널에는 NAT과 관련한 기능을 켜면 NAT 테이블이 생성이 됩니다.

우리가 소위 내부 IP(private IP)라고 말하는 주소는 router에서는 다른 주소로 라우팅하지 못하도록 rfc로 명시가 되어 있습니다. 강제로 이 규칙을 어기더라도 다른 라우터가 다 차단해 버리므로 결국 패킷은 외부로 나가질 못합니다.

NAT을 쓰게 되면, 커널은 TCP/IP 스택에 이 내부 IP라고 말하는 source에서 공용 IP(public IP)로 나가고자 하는 패킷이 있는지 보고 있다가 그런 패킷이 걸려들면 이걸 잽싸게 NAT 루틴으로 hooking 합니다. 더 쉬운 말로 잠깐 패킷을 납치 내지는 보쌈합니다.

그리고 온갖 고문기술(?)을 이용하여 이 패킷이 도대체 어디로 나갈 것인지 프로토콜은 무엇인지 제대로 된 녀석인지 알몸 수색을 합니다.

자격이 되는 녀석(즉, NAT 설정에 맞는 패킷 - 이것은 시스템 관리자가 NAT룰을 제대로 만들어 놓았다고 가정하구요)이라면 이 녀석의 원래 헤더를 복사해서 NAT 테이블에 기록합니다. 이때 잘못하면 NAT 테이블 변조가 일어날 수도 있으므로 기록할 때는 테이블 락킹을 합니다. 이 말은 일종의 제가 즐겨쓰는 "침 바른다"는 표현입니다. 음, 요놈은 내가 처리했던 놈이야 하고 확실히 침을 발라놓습니다. 다음에 다시 오더라도 구분하기 위해서죠.

자 이제 본격적으로 성형수술을 해야 할 시기입니다. 성형수술 담당의는 한 녀석이 아니시구요. 여러 명으로 구성이 되어 있습니다. 거의 종합병원 수준입니다. 프로토콜에 따라 패킷 성형술이 다르기 때문이죠.

이 성형수술을 하는 가장 큰 이유는 패킷이 외부에서 생존해야 하기 때문입니다. 즉, 우편물이 제대로 배달이 제대로 되려면 약정된 규격(편지봉투의 크기, 편지봉투의 무게 등의), 즉 프로토콜에 위배되어서는 안됩니다. 이 통신규약을 어기는 순간 라우터라는 녀석들이 통행을 금지시키고 패킷을 절단내어 버리기 때문이죠.

이 세상은 혼자 사는 세상이 아니죠?

이 패킷이 외부 라우터에서도 무사히 생존하려면 절대 내부 IP에서 왔다는 흔적을 남겨서는 안됩니다. 다시 말해, Public IP network에 맞는 기준을 가지고 있어야겠죠? Private IP에 대해서는 통행이 금지되어 있으므로 source 어드레스에 192.168.x.x라든가 10.0.0.0 뭐 이런 식의 주소가 들어간 패킷이 있어서는 안된다는 것입니다.

이 성형수술의 핵심은 IP 헤더의 source 주소를 NAT 머신의 주소로 바꿔치기 하는 것입니다. 그리고, 원래 보내던 패킷과 성형한 패킷에 대한 정보를 주로 port 번호를 이용하여 NAT 테이블에 저장해 놓습니다.

이제 상대 호스트로 보낼 거의 완벽한 가짜 패킷을 내보낼 차례입니다.

상대 호스트는 이렇게 조작된 패킷이 실제로 public IP를 가지고 있는 호스트에서 보낸 자연미인으로 알고 접수를 합니다.

그리고 응답을 하겠죠?

편지가 그러하듯, IP 역시 아까 패킷이 왔을때 source 헤더(조작된 헤더)에 기록이 되어 있던 포트를 알고 있으므로 그 정보를 이용하여 답신합니다.

다시 NAT 머신이 이걸 받겠죠?

NAT 머신은 아까 패킷을 내보내던 것의 역순으로 돌아온 패킷이 NAT 테이블에 등록되어 있는 짝퉁 패킷인지 아닌지 검사합니다. 즉, 침발라서 보낸 녀석인지 아닌지는 NAT 테이블 조사하면 다 나오겠죠?

네??? 어케 조사하느냐구요? 암튼 조사하면 다 나옵니다. 자세한 건 소스를 보시라!

NAT 테이블에 없는 패킷(보낸 적이 없는데 온 패킷)이라면 이건 자기 소관이 아닙니다.
NAT 테이블에 있던 녀석이라면 - 즉, 침 발랐던 녀석이라면 원래대로 역성형수술을 해야 할 차례입니다.

잠깐동안 바꿔 달았던 mangled 헤더를 떼어내고 원래의 source 헤더를 destination 헤더로 바꾸어서 내부 IP 호스트로 보내는 것입니다. 물론 NAT 테이블에 있는 사항도 이제 지워주어야겠죠?

그럼, 내부 호스트는 이걸 그대로 전달 받게 되는 것입니다.

이런 패킷 수정 작업이 엄청나게 빨리 일어나기 때문에 마치 사용자들은 NAT이 있는지 없는지도 모르죠.

답이 되었을까요?

간만에 적어보려 했더니 나도 힘드네요.

흐미, 답을 적고 보니........ 제가 너무 말을 많이 했군요.

Quote:
그런데 NAT라우터는 자신에게보낸 로컬호스트 사설아이피를 보고 그 주소가 자신한테 속한 로컬영역인지 아닌지 어떻게 알까요?

이건 NAT과 관련한 iptables rule에 따라 결정합니다.

답은 이거네요.

There's always another way, dear.

---------------------------------
There's always another way, dear.

primewizard의 이미지

재미있게 잘 읽었습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.