iptables 소스 ip 에따른 redirect

hotcpu의 이미지

안녕하세요.

아래는 가정 상황 입니다.

소스 IP 가 1.1.1.1 이고

서버에는 httpd 데몬이 두개 띄워져 있으며

1개는 80으로 일반적인 웹서비스를

1개는 8080으로 열어 두었습니다.

소스 IP 1.1.1.1 이외

여타의 사용자가 들어올때 정상적으로 80으로 들어가 웹서비스를 받게되고,

iptables 에서 지정해둔 특정 사용자 (소스 IP 1.1.1.1) 가 들어오면

이 사용자만 로컬의 8080 포트로 넘겨주어 다른 화면이뜨게 하고싶습니다.

redirect 구문을 이용하여 처리가 가능한 것인지..

만약 가능하다면..

8080포트 말고 예를들어 44444 포트를 httpd에 배정하고

IP 1.1.1.1 사용자가 접속하면 해당 IP만

포트 44444로 iptables 에서 포워딩 하도록하여 보내도

IP 1.1.1.1 사용자가 웹 페이지를 보는것은 문제가 없는지요? (44444가 보편적인 HTTP 포트가 아닌데 열리는데 문제가 없는것인지?)

iptables 에서 어떻게 지정을 하여두면 될까요?

고견을 바랍니다. ^^; :oops:

wariua의 이미지

네, REDIRECT target으로 처리가 가능합니다. 딱 REDIRECT에 적합한 상황입니다. 그리고 사용자가 80으로 접속하든 8080으로 접속하든, httpd가 80으로 바인딩 하고 있든 44444로 바인딩 하고 있든 웬간해서는 별 관계 없습니다. 나이가 숫자에 불과한 건지 어떤지는 잘 모르겠지만, 이 경우 포트 번호는 확실히 숫자에 불과합니다.

# iptables -t nat -A PREROUTING -s 1.1.1.1 -p tcp --dport 80 -j REDIRECT --to 8080

httpd를 44444 포트로 바인딩 시킨 경우라면 "--to" 다음의 포트를 바꿔주면 됩니다.

이 설정을 재부팅 후에도 적용되도록 저장하는 방법(내지는 별도로 저장 작업이 필요한지 여부)는 배포판에 따라 다릅니다.

$PWD `date`

hotcpu의 이미지

답변 감사합니다.

기왕에 여쭈어 본것 한가지만 더 여쭙겠습니다. ^^

위의 사정은(사설IP 사용목적이 아닌)

지정한 특정 IP 의 사용자를 별개의 페이지로 안내하는게 목적인데요.

이 경우는 내부의 특정포트에서 또다른 내부의 특정포트로 보내주는 것입니다.

그렇다면, 내부가 아닌 외부로 연결 시켜주는것은 어떻게 처리해야 할까요?

IP 1.1.1.1 사용자가 80번으로 접속을 해온다면

211.218.150.25080 (이건 네이버 입니다.) 로 바로 보내버리게요.

저는

iptables -A PREROUTING -t nat -p tcp -s 1.1.1.1 --dport 80 -j DNAT --to 211.218.150.25080
iptables -A PREROUTING -t nat -p tcp -s 1.1.1.1 --dport 80 -j DNAT --to 211.218.150.250

이렇게 설정을 했었는데.. 이거 안되더라고요. ㅡ,.ㅡ;;; 위 두가지 바꾸어 가며 적용을 해 보았습니다.

1.1.1.1이 제 아이피인데.. 서버로의 웹접속 자체가 막혀버리더군요. 뭔가 작동을 하는거 같은데..

제대로 네이버쪽이 안뜨는거 같습니다.

제 생각에는 저렇게 하면 지정된 IP 1.1.1.1 사용자가 접속하면 내부가 아닌 다른 서버로 바로 연결 될것이라 생각했는데

잘 안되더군요.

알려주신 경우는 내부인데.. 이 경우도 같이 적용이 가능한지요?

두번째 질문의 사례를 룰로 한수 지도해 주시면 감읍하리오리다~ 상감!!!!!!!!!! ^^

hotcpu의 이미지

--port 80 이라서 그런가? -_-;;;;

-port 80 이 맞나요?

--port 80 이 맞나요? --;;

hotcpu의 이미지

혹시 이것을 적용하고 별개의 실행이 필요한지요?

iptables restart 외에 다른 작업이 필요한지..?

wariua의 이미지

말씀하신 웹서버(211.218.150.250)의 경우는 별 문제 없이 되어야 정상입니다. 문제가 될 수도 있는 경우는 아래에서 따로 말씀드리겠습니다.

아마도 패킷 포워딩이 꺼져 있는 게 아닐까 싶습니다. 보통 패포판 깔면 보안 때문에 기본적으로 꺼둡니다. 다음 명령으로 확인이 가능합니다.

# cat /proc/sys/net/ipv4/ip_forward

결과가 "0"이면 꺼져 있는 것입니다. 다음 명령으로 켜주시면 됩니다. (물론 따로 설정 저장을 안 해주시면 리부팅 후 초기화됩니다.)
# echo 1 > /proc/sys/net/ipv4/ip_forward

그래도 안 된다면(혹은 이미 켜져 있었다면) 다음으로 의심해 볼 만한 건 FORWARD 체인의 기본 정책입니다. "iptables -L FORWARD" 했을 때 막는 규칙이 들어가 있거나 기본 정책("policy"라고 하고서 표시되는)이 DROP이면 패킷 전달이 차단됩니다. 적절한 iptables 명령으로 풀어주시면 됩니다.

그래도 안 된다면 다시 포스팅 해 주십시오.
----
상당수의 경우에는 이렇게 DNAT로 목적지를 전환해 주는 게 동작합니다만 예외가 되는 경우를 만나실 수도 있습니다. 가령 구글 홈페이지(http://www.google.com/)를 위 방법으로 접속을 강제하면 첫 페이지는 잘 표시가 됩니다. 하지만 거기서 "뉴스"나 "그룹스" 링크를 클릭하면 접속이 안 되는 걸 보실 수 있습니다.

이건 http://66.102.7.147/처럼 IP 주소로 구글에 접속할 때도 나타나는 버그(?)입니다만... 근본적으로 사용자가 주소창에 특정 서버 주소를 입력해서 들어올 거라고 (사용자가 입력한 주소값이 웹브라우저가 보내는 HTTP 요청에 그대로 담겨서 웹서버에 전달됩니다.) 가정하고 작성된 웹페이지가 있다는 의미입니다. 그런 웹페이지에선 다소 문제를 겪을 수 있습니다. 그리고 한 대의 웹서버에서 가상 호스트 기능을 이용해 여러 홈페이지를 서비스 하는 경우에 접속할 홈페이지를 지정해 줄 수 없기도 합니다.

인즉, 어느정도 제한된 범위에서만 위의 기법으로 목적지 웹서버를 변경해 줄 수 있습니다.

$PWD `date`

익명 사용자의 이미지

아아.. 역시나 안됩니다. T_T

말씀하신 ip 포워딩이 꺼져있어 결과값을 1이 나오게 알려주신대로 제대로 했고..

iptables 의 FORWARD 에는 별개의 룰이 없고 기본정책이 허용으로 되어 있습니다.

말씀드렸던 서버는 네이버인데..

지정한 사용자가 접근하면 네이버로 보내버리는 것인데..
(차후, 외부에다가 서버를 하나 둬서 특정 접속자가 접속시 그쪽 서버로 보내버릴 목적)

IP만입력해서 네이버가 잘 뜨는걸로 보아 도메인이 필요한거 같진 않습니다.

이거 참.. 어렵네요. ^^;;

필요하시다면 룰 전체를 올려 보겠습니다. 고견 감사합니다 ^^

익명 사용자의 이미지

다른이에게 테스트를 해보게 했는데요.

상황은 이렇습니다.

* cat /proc/sys/net/ipv4/ip_forward 결과 1 확인
* 룰을 보아 FORWARD 기본정책이 허용임을 확인(현재 기본정책이 DROP인 정책은 없습니다. )

1. IDC에 있는 서버A에 테스터(220.64.10.214)가 접속을 준비중입니다. (IE로 80번 디폴트포트)

2. 룰을 저장하고 파일을 보니

*nat
:OUTPUT ACCEPT [2:1592]
:POSTROUTING ACCEPT [2:1592]
:PREROUTING ACCEPT [329:26569]
-A PREROUTING -s 220.64.10.214 -p tcp -m tcp -j DNAT --to-destination 211.218.150.250:80
COMMIT

이렇게 포함되어 있는 상태이고요.

iptables 리스타트 일단 했습니다.

3. 테스터에게 접속을 하라고 했습니다.

4. 페이지를 찾을 수 없다고 나옵니다. (저 룰을 제거하면 디폴트 페이지가 나타납니다.)

5. 네이버서버의 문제인가 해서 다른 서버로 바꾸어도 동일하게 페이지를 찾지 못합니다.

6. 네이버 주소의 :80 을 빼고 해 보아도 마찬가지 입니다.

흑.. T_T

익명 사용자의 이미지

갑자기..

211.218.150.250:80 이것을 ie 주소창에다가 그냥 입력해 보았습니다.

그랬더니 페이지를 못찾는다고 나오네요.

http:// 를 지정하니 찾아갑니다.

그렇다면 iptables 에서도 이것때문에 아까 페이지를 찾지 못한다고 나왔을까요?

그러면 테스터가 접속해오면 이것이 http 임을 어떻게 알려야 할까요? 끄응.......

익명 사용자의 이미지

지금 생각난건데..

제가 외부에서 들어오는건 몇개 포트를 제외하곤 모두 막아놨습니다.

그렇다면, 지정된 테스터가 서버로 접속해올때

그 테스터를 네이버등의 타 사이트로 보내려고 할때에..

이후 테스터와 네이버간의 데이타 교류는 어떻게 되는것인가요?

서버를 거쳐서 이루어진다면 포트를 막아둔거나 데이타의 전달과정에서 문제가 있을거 같기도 한데요.

서버를 거치지 않고 사용자와 네이버간의 1:1 교류라면 문제가 없을거 같고요. 원하는것도 이것이고요.

일단 보내버리면 그것으로 서버의 역할은 끝나버려야 하는데..

계속 간여를 해야 한다면 문제가 있을거 같기도 하고, 앞선 경우처럼 페이지를 못찾을수도 있을거 같은데요.

혹시 이런 유사한 경우로 사용해본 분이 계실지?

wariua의 이미지

IDC에 위치한 컴퓨터(220.64.10.214)에서 사용자가 DNAT를 하는 서버의 주소로 80 포트를 통해 웹 접속을 하면 서버는 그 요청을 특정 웹서버(네이버 웹서버)로 전달해 주는 걸로 이해하고서 말씀드리겠습니다.

----

IE에서 "211.218.150.250:80"이라고 입력했을 때 접속이 안 되는 건 IE의 고유한 동작 방식 때문인가 봅니다. "211.218.150.250" 또는 "http://211.218.150.250:80"으로 주소를 입력해서 접속해 주시면 되겠구요...

----

DNAT 규칙을 추가할 때 "--to-destination"에 넣는 주소에서 포트(":80")을 넣어주지 않으면 패킷의 본래 목적지 포트를 그대로 사용합니다. 따라서 사용자가 80 이외의 포트를 지정해서 접속을 하고 있는 게 아니라면 ":80"을 지정해 주지 않아도 규칙의 효과는 동일합니다.

----

서버를 거쳐서 사용자와 네이버 간의 접속이 이뤄진 '후'의 데이터 교환에 대해선...
말씀하신 "데이터 교류"라는 것이 어떤 데이터를 말씀하시는 건지 잘은 모르겠습니다만... 단순히 웹페이지의 데이터들(HTML 문서, 이미지, 플래시, ...)를 말씀하시는 거라면 이후에도 계속 서버의 중계를 거쳐서 통신이 이루어지는 경우가 있을 수 있습니다. 가령 첫 페이지의 어느 버튼 이미지의 src가 "/img/button1.gif"라고 되어 있으면 웹문서와 동일한 웹서버(지금의 경우에는 중계를 하는 서버)로 이미지를 요청하고, 그 요청이 다시 네이버 웹서버로 전달됩니다. 하지만 src가 "http://img.naver.com/button1.gif"라는 식으로 웹서버를 지정하도록 되어 있다면 이때는 웹브라우저가 중계 서버를 거치지 않고 img.naver.com이라는 서버에 직접 접속합니다.

네이버의 경우 언듯 보기에 모든 이미지나 플래시 등이 후자의 방식으로 주소가 지정되어 있고, 하부 서비스에 대한 링크를 클릭하는 경우에도 변환 과정을 한 번 거친 후 결국 후자의 방식으로 주소를 직접 지정해 주기 때문에 첫 페이지의 HTML 문서를 제외한 대부분의 데이터는 사용자와 네이버 서버간의 직접 통신으로 오가게 될 것으로 보입니다.

----

자, 그러면 제일 중요한 문제인 접속 자체로 돌아오자면...

중계 서버가 사용자의 웹 접속을 무사히 네이버 웹서버로 전달해 줄 수 있기 위한 조건은 대략 다음과 같습니다.

1. 사용자와 중계 서버간의 네트워크에서 통신이 잘 이루어진다.
2. 사용자의 웹 접속(목적지 포트가 80)을 중계 서버가 받아들인다.
3. 중계 서버가 패킷 포워딩을 허용한다.
4. 중계 서버가 웹 접속(목적지 포트 80)이 나가는 걸 허용한다.
5. 중계 서버와 목적지 웹서버간의 네트워크에서 통신이 잘 이루어진다.

규칙을 제거했을 때 기본 페이지가 나왔다고 하셨으니 1번과 2번까지는 문제가 없습니다. ip_forward 설정을 1로 바꿔주셨고 FORWARD 정책도 확인하셨다니 3번도 문제가 없습니다. 5번이 문제가 될 가능성은 별로 없을 것이고, 그렇다면 4번을 한번 확인해 볼 필요가 있겠네요.

# wget http://www.naver.com/

명령으로 중계 서버에서 웹서버로 접속해서 index.html 파일을 받아오는지 확인해 주시면 되겠습니다. (그럴 가능성은 낮다고 생각됩니다만) 접속이 안된다면 OUTPUT 체인을 확인해 주시면 됩니다.

여전히 문제가 해결이 안 되었다면 tcpdump나 ethereal 같은 패킷 캡처 프로그램을 사용해 보실 수 있습니다.

# tcpdump port 80 -i any -n -x

정도 하면 들어오는 패킷과 나가는 패킷을 확인해 보실 수 있을 겁니다. 사용자에게서 syn 패킷 하나 들어오고 만다면 중계 서버 어딘가에서 패킷 전달이 안 되고 있는 것이고(2,3,4번 중 하나), 뭔가 분주히 오가는 게 보인다면 대략 통신이 이루어지고 있다고 할 수 있습니다. 여기까지도 문제 해결이 안되고 있다면 tcpdump 결과를 올려 주시면 도움이 될 듯 합니다. 더불어 말씀하신 대로 전체 규칙도 함께 올려주시면 더욱 좋습니다. (참, IP 주소 마지막 자리 정도는 가려주셔도 문제 없습니다:))

$PWD `date`

익명 사용자의 이미지

늦은밤 감사합니다. ^^

밤에 하도 뒤지다가 머리도 시킬겸 바둑 잠시 보다가 들어와봤더니 글이 남겨져 있네요.

말씀하신대로 참고해서 시도를 해 보겠습니다.

답변 감사합니다. ^^

결과를 빠른시간내에 올리겠습니다. 꾸벅!

익명 사용자의 이미지

아이구 잠깐 졸았네요.

제가 한숨 자고 제 정신으로 확인 해보겠습니다. ^^;

안녕히 주무세요~

yoocj9의 이미지

hotcpu wrote:
답변 감사합니다.

기왕에 여쭈어 본것 한가지만 더 여쭙겠습니다. ^^

위의 사정은(사설IP 사용목적이 아닌)

지정한 특정 IP 의 사용자를 별개의 페이지로 안내하는게 목적인데요.

이 경우는 내부의 특정포트에서 또다른 내부의 특정포트로 보내주는 것입니다.

그렇다면, 내부가 아닌 외부로 연결 시켜주는것은 어떻게 처리해야 할까요?

IP 1.1.1.1 사용자가 80번으로 접속을 해온다면

211.218.150.250:80 (이건 네이버 입니다.) 로 바로 보내버리게요.

이런 처리는 iptables의 DNAT로는 불가능합니다.

wariua의 이미지

아, 하나 빠트린 게 있었습니다 :oops:

중계 서버에서 네이버로 전달하는 패킷에 대해 출발지 주소를 중계 서버의 주소로 바꿔주어야 합니다. 그래야 네이버 서버의 응답 패킷이 중계 서버를 다시 거쳐서 무사히 사용자의 컴퓨터로 돌아갑니다. 이게 안 되어 있으면 네이버 서버에서 보낸 응답 패킷이 사용자에게 직접 전달되고, 사용자의 컴퓨터는 그 패킷의 정체들 알 수 없으므로(자신은 분명 중계 서버로 접속했는데 네이버에서 패킷이 왔으니) 무시하게 됩니다.

대략...

# iptables -t nat -A POSTROUTING -s 220.64.10.214 -d 211.218.150.250 -p tcp --dport 80 -j MASQUERADE

정도면 되지 않을까 싶습니다.

$PWD `date`

댓글 달기

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