iptables 포트 포워딩에서 응답 패킷이 되돌아갈 수 있는 원리...?

raymundo의 이미지

안녕하세요,

iptables port forwarding 으로 검색하면 거의 모든 글이 외부에서 들어온 요청을 내부망의 서버, NAT 으로 연결된 호스트 등으로 전달하는 경우만 보이고, 제가 하려는 것에 해당하는 것을 정확히 찾기 좀 힘드네요. 이리 저리 해보다가 궁금한 게 생겨서 질문 올립니다.

두 호스트 A, B가 있고, 서로 전혀 관계없는 네트워크에 있고 둘 다 공인IP가 있는 상태입니다.
이 상태에서 A호스트의 3000 포트로 들어오는 요청을 B호스트의 80 포트로 전달하고자 합니다.
(이유는, A호스트에서 서비스하던 것을 B호스트로 이전하려는데, DNS를 A에서 B로 바꾸는 것은 전파되는 딜레이가 있다보니 그동안은 A호스트로 들어오는 요청을 B로 넘겨 처리시키려는 것입니다)

일단 가능성을 확인하기 위해 테스트 중인데요.
A호스트에서 다음과 같이 설정했습니다.

패킷 포워딩 허용
# sysctl -w net.ipv4.ip_forward=1
 
3000 포트로 들어오는 패킷을 B:80으로 전달하기 위해 패킷의 목적지 어드레스를 변경
# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 3000 -j DNAT --to-destination B의IP:80
 
이것만 가지고는 B에서 보낸 응답이 클라이언트로 바로 가니까, 클라이언트 쪽에서는 뜬금없는 응답이라
무시하게 되므로, B의 응답을 일단 A가 받아야 함. 따라서 패킷의 소스어드레스를 A로 변경
# iptables -t nat -A POSTROUTING -d B의IP/32 -p tcp -m tcp --dport 80 -j SNAT --to-source A의IP
 
마지막으로 filter 테이블의 FORWARDING 체인에서 허용을 해주어야 하는데, 현재 기본 정책이 ACCEPT로 되어 있어서 패스

이렇게 해서 A:3000 으로 요청을 보내면 B에서 받는 게 되는 건 확인했는데요,

제가 궁금한 건,

1. 포트 포워딩을 이렇게 하는 것만으로 다 된 게 맞을까요. 추가로 챙겨야 되는 게 더 있을까요?

2. 위의 설정에서, 클라이언트의 요청이 A를 거쳐 B로 갔다가, B에서는 패킷의 소스가 A의 주소이니 A로 응답을 보낼 것까지는 이해가 됩니다.
그런데 A는 이 응답을 어떻게 다시 원래 클라이언트로 보낼 수가 있는 건지요? 이 응답의 패킷은 소스가 B, 목적지가 A로 되어 있을텐데.
일단 TCP connection이 만들어지는 경우는 따로 매핑 테이블 같은 게 생겨나서 챙겨주는 건가요?

(리버스 프록시를 쓰는 것도 고려 대상입니다만, 이렇게 포워드해야 될 서비스가 웹 말고도 또 있어서 어쨌거나 포트 포워딩으로 해결해야 되는 상황입니다)

익명 사용자의 이미지

Quote:

1. 포트 포워딩을 이렇게 하는 것만으로 다 된 게 맞을까요. 추가로 챙겨야 되는 게 더 있을까요?

설정하신 것만으로 끝입니다. 더 이상 할게 없습니다.

Quote:

2. 위의 설정에서, 클라이언트의 요청이 A를 거쳐 B로 갔다가, B에서는 패킷의 소스가 A의 주소이니 A로 응답을 보낼 것까지는 이해가 됩니다.
그런데 A는 이 응답을 어떻게 다시 원래 클라이언트로 보낼 수가 있는 건지요? 이 응답의 패킷은 소스가 B, 목적지가 A로 되어 있을텐데.
일단 TCP connection이 만들어지는 경우는 따로 매핑 테이블 같은 게 생겨나서 챙겨주는 건가요?

iptables 모듈이 올라가면 자동으로 매핑 테이블이 생깁니다.

이 매핑 테이블이 full 나게되면 통신에 장애가 발생합니다.

이때 커널에서 아래와 같은 메세지를 보실 수 있습니다.

kernel: nf_conntrack: table full, dropping packet. 

이를 해결 하기 위해선 /proc/sys/net/nf_conntrack_max , /proc/sys/net/netfilter/nf_conntrack_max 값을 늘려 해결 하는 방법있습니다.

raymundo의 이미지

감사합니다!

좋은 하루 되세요!

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.