'dnat'에 해당되는 글 2건

  1. 2009.06.08 iptables를 이용한 NAT(Network Address Translation) 구현 (1)
  2. 2008.10.20 Setup a transparent proxy with Squid in three easy steps
2009.06.08 13:45

iptables를 이용한 NAT(Network Address Translation) 구현

1. NAT란

개요: 컴퓨터에서 인터넷을 사용하려면 IP주소를 부여받아야 한다. 보통 이러한 IP를 공인 IP라 부른다. 그러나 IP주소는 폭발적인 인터넷 사용인구의 증가로 IP가 부족해지는 현상이 나타났다. 이러한 부족현상을 해결하는 방안중의 한 기술이 NAT이다.

정의: NAT란 말 그대로 네트워크의 주소를 변환하여 주는 역할을 하는 것이다. 즉 한개의 공인 IP주소를 가지고 있는데 여러개의 컴퓨터를 사용하려는 경우처럼 한대의 컴퓨터에 공인 IP를 부여하고 나머지는 사설 IP를 부여하여 인터넷사용시에는 공인IP를 공유하여 사용할 수 있도록 해주는 기술이다.


2. NAT의 사용예

여러 대의 피시에서 한 개의 IP를 공유하여 인터넷을 사용하는 경우
=> 공인된 IP가 부여된 컴퓨터에는 랜카드를 두개를 장착하여 하나는 공인IP를 부여하고 다른 하나는 사설IP가 부여된 사설네트워크 연결을 위해 사설IP를 부여하여 인터넷을 공유할 수 있다.

한 개의 IP주소에 여러 대의 서버를 연결하는 경우
=> 부하분산을 위해 한 개의 도메인네임에 대해 여러 대의 서버를 운영하는 경우에도 NAT를 사용한다. 즉, www.linux.ac.kr 도메인 한개에 웹서버, 메일서버, FTP서버를 따로 운영하는 경우 부하평준하 기능도 구현이 가능하다. 예를 들면 웹서버는 192.168.0.1, 메일서버는 192.168.0.2 등 이런 방법으로 구현이 가능하다.

투명프락시
=> 학원에서 인터넷을 강의하는 경우처럼 동일 네트워크에 연결된 여러 대의 PC에서 동시에 같은 사이트를 연결한다. 이 경우 프록시 서버를 이용하면 그 해당사이트를 프록시서버에서 참조해 보다 빠른 접속을 할 수 있다. 이런 프록시 서버를 이용하려면 각 컴퓨터에 설치된 웹브라우저에서 프록시서버를 지정해 주어야 한다. 리눅스에 프록시서버를 설정하면 리눅스를 통과하는 패킷은 자동으로 리눅스에 설치된 프록시서버 프로그램으로 연결된다.


3. iptables에서 NAT의 분류

개요: iptables에서는 크게 두 부류의 NAT로 분류한다. 위 의 경우를 SNAT라 하고 와 의 경우를 DNAT라 분류한다.

종류
1) SNAT: 패킷의 소스 어드레스를 변경한다는 의미이다. 즉 내부 어드레스인 192.168.1.2인 컴퓨터가 다른 웹사이트를 접속하면 203.247.XX.XXX 처럼 공인 IP로 나타나기 때문이다. SNAT는 라우팅 결정 이후에 이루어진다.
패킷의 목적지주소는 이미 정해져 있으므로 라우팅 경로는 결정되어 있고 패킷의 소스 주소가 리눅스를 떠나기 직전에 변경된다.
2) DNAT: 위의 개념과 반대되는 것으로 NAT를 시행하는 리눅스에서 패킷의 목적지 주소를 변경한다. 패킷의 목적지 주소가 먼저 변경되고 그 변경된 주소에 의거하여 새로운 라우팅 경로를 찾는다. 즉 DNAT는 라우팅 이전 단계에서 작용한다.


4. iptables를 이용한 설정

SNAT: 기존의 IP Masquerade를 말한다.

1) 사용법
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 203.247.50.3
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 203.247.50.3-203.247.50.7
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 203.247.50.3:1-1023
=> -o 는 패킷을 보내는 인터페이스 장치를 지정한다. SNAT에서는 패킷을 내보내는 장치를 지정할 수 있다.
 --to 는 나가는 패킷에 부여할 소스 주소이다. IP공유라면 --to 는 인터넷 쪽의 공인 IP를 지정하면 된다.

2) 사용예

ㄱ. 한국통신 ADSL을 리눅스에 연결해 인터넷을 공유하는 경우
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

ㄴ. 고정 IP를 사용하는 리눅스에서 인터넷을 공유하는 경우
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j SNAT --to 203.247.50.3
=> 참고로 192.168.0.0/24는 지정하지 않아도 된다.

ㄷ. 유동 IP를 사용하여 인터넷을 공유하는 경우
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

3) 설정의 확인
# iptables -t nat -L

위 설정이외에도 다음과 같은 명령을 내려서 포워딩이 가능하게 해야 한다.
# echo 1 > /proc/sys/net/ipv4/ip_forward

DNAT

1) 개요: DNAT는 부하분산이나 평준화에만 사용하는 것은 아니다. 간단한 방화벽으로도 유용하다.
리눅스A에 DNAT를 설정하여 웹서버와 메일서버를 각각 내부주소인 리눅스B와 리눅스C에서 서비스 하도록 지정하고 인터넷에서 다른 연결은 리눅스A로 지정하면 리눅스A는 간단한 방화벽과 같은 구실을 한다.

2) 사용예

ㄱ. 웹서버 분산
# iptables -A PREROUTING -t nat -p tcp -d 203.247.50.3 --dport 80 -j DNAT --to 192.168.1.11:80
=> 
 -A PREROUTING : DNAT는 먼저 목적지 주소를 변경하고 다음에 라우팅이 이루어진다.
 -t nat : 부하분산도 nat기능이다.
 -p tcp : 웹은 tcp를 사용한다.
 -d 203.247.50.3 --dport 80 : 들어오는 패킷의 목적지 주소가 203.247.50.3이고 포트번호가 www인 경우만 이 규칙을 적용한다.
 -j DNAT : destination NAT
 --to 192.168.1.11:80 : 패킷의 목적지 주소를 192.168.1.11 포트번호를 80번으로 설정하라는 뜻이다. 192.168.1.11 서버에서는 80번 포트에서 웹서버 프로그램을 가동해야 한다.

ㄴ. 메일서버
# iptables -A PREROUTING -t nat -p tcp -d 203.247.50.3 --dport 25 -j DNAT 192.168.1.12:25

ㄷ. DNS서버를 192.168.1.10으로 변경하려면 다음과 같이 지정한다.
# iptables -A PREROUTING -t nat -p udp -d 203.247.50.3 --dport 53 -j DNAT --to 192.168.1.10:53
=> DNS는 UDP를 사용한다.

3) 설정의 확인
# iptables -t nat -L
=> 설정을 보통 포트이름등으로 보여준다.
# iptables -t nat -nL
=> 설정을 포트넘버등 숫자로 보여준다.

4) 설정의 해제
# iptables -t nat -F


5. iptables를 이용한 투명프록시 구현

투명프록시란 투명프록시는 내부 네트워크의 웹브라우저에서 프록시서버를 지정하지 않아도 강제로 프록시서버를
사용하게 하는 설정이다. 프록시를 설정하는 경우의 이점은 캐시를 사용하므로 인터넷 접속 속도를 빠르게 할 수 있다.

iptables에서 설정
1) squid 프록시서버를 작동시킨다.
2) 리눅스 서버의 인터넷쪽에 연결된 랜카드의 인터페이스명이 eth0, 내부랜인 eth1의 주소가 192.168.2.1이라면 다음과 같이 명령을 내린다.
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128
=> 
 -t nat : 투명프록시도 패킷의 주소를 변경하는 설정이므로 nat이다.
 -A PREROUTING : 투명프록시는 패킷의 주소를 변경하는 작업이 경로를 찾는 것보다 우선한다.
 -i eth1 : 변경할 패킷이 들어오는 장치를 지정한다. 내부랜이 eth1에 연결되어 있고 이 랜에 연결된 내부 네트워크 시스템들은 이 리눅스를 통해 인터넷을 사용하므로 들어오는 패킷의 장치명은 eth1이다.
 -p tcp : 들어오는 패킷 중 tcp프로토콜만 nat를 적용한다는 뜻이다. www연결은 tcp를 사용한다.
 --dport 80 : 들어오는 패킷의 목적지 포트가 80번인 경우에만 nat를 적용한다는 뜻이다. 따라서 ftp, telnet등은 적용을 안 받는다.
 -j REDIRECT : 투명프록시는 리눅스 내부에서 패킷의 입력포트번호를 변경해 주는 방법이다.
 --to-port 3128 : 들어오는 패킷의 목적지 포트번호를 3128번으로 변경하는 뜻이다. 목적지의 IP주소는 지정하지 않았으므로 모든 인터넷 웹 검색에 대해 투명프록시가 적용된다.
3) 확인
# iptables -t nat -L

다른예
투명프록시가 설치된 리눅스 서버에 웹서버를 설치해도 상관없다. 그런데 192.168.2.x네트워크에서 자신의 웹서버 데이터를 접근할 때도 프록시 서버를 공유한다는 것은 아무런 의미가 없다. 웹서버에서 읽을 때는 홈페이지 디렉토리에서 찾고 프록시에서 찾을 때는 프록시서버의 캐시 디렉토리에서 찾는 차이밖에 없다. 자신의 홈페이지 데이터를 내부랜에서 수시로 변경하는 경우는 오히려 프록시서버 캐시 디렉토리에서 찾으면 문제가 된다. 캐시가 지워지지 않는한 변경된 홈페이지 데이터를 볼 수가 없다. 그래서 내부랜의 윈도우에서 192.168.2.1리눅스 서버의 변경된 홈페이지 데이터를 즉시 확인해야 한다면 http://192.168.2.1 명령시에는 투명프록시가 작용하지 않아야 한다.
1) 그 방법은 아래와 같다.
# iptables -t nat -A PREROUTING -i eth1 -p tcp -d ! 192.168.2.1 --dport 80 -j REDIRECT --to-port 3128
=> 처음의 기본설정에 -d ! 192.168.2.1을 추가하였다. 즉 들어오는 패킷의 목적지주소가 192.168.2.1이면 투명프록
시를 적용하지 말라는 뜻이다.
2) 설정해제
# iptables -t nat -F

www외의 인터넷 연결에 대한 nat설정
1) 설명: 주의할 것은 투명프록시는 오직 http 즉 www검색만 해당되고 telnet이나 ftp는 적용되지 않으므로 내부랜에서 인터넷의 다른 호스트에 telnet 및 ftp를 사용하려면 추가로 SNAT를 설정해 주어야 한다.
2) 설정
# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j SNAT --to 203.247.50.3
=> 
 -A ROSTROUTING
 -s 192.168.2.0/24 : 192.168.2.0 네트워크로부터의 패킷에만 SNAT를 적용한다.
 -o eth0  : 패킷이 나가는 장치를 말한다. 
 -j SNAT : Source NAT를 말한다. 소스 주소를 변경한다는 뜻이다.
 --to 203.247.40.3 : 소스 주소를 203.247.50.3으로 변경하라는 뜻이다.
3) 확인
# iptables -t nat -L
참고
투명프록시가 적용되려면 인터넷에 나가는 패킷이 투명 프록시가 설정되어 있는 리눅스를 통과해야 한다. 통과하지 않는 패킷에 대해서는 포트의 방향을 변경할 방법이 없다. 따라서 투명프록시를 사용하는 모든 내부 컴퓨터의 디폴트 게이트웨이는 리눅스에 부여된 내부 IP주소이어야 한다.


Trackback 2 Comment 1
  1. transparentproxy 2009.07.08 18:51 address edit & del reply

    http://www.cyberciti.biz/tips/linux-setup-transparent-proxy-squid-howto.html

2008.10.20 10:12

Setup a transparent proxy with Squid in three easy steps

Y'day I got a chance to play with Squid and iptables. My job was simple : Setup Squid proxy as a transparent server.

Main benefit of setting transparent proxy is you do not have to setup up individual browsers to work with proxies.

My Setup:

i) System: HP dual Xeon CPU system with 8 GB RAM (good for squid).
ii) Eth0: IP:192.168.1.1
iii) Eth1: IP: 192.168.2.1 (192.168.2.0/24 network (around 150 windows XP systems))
iv) OS: Red Hat Enterprise Linux 4.0 (Following instruction should work with Debian and all other Linux distros)

Eth0 connected to internet and eth1 connected to local lan i.e. system act as router.

Server Configuration

  • Step #1 : Squid configuration so that it will act as a transparent proxy
  • Step #2 : Iptables configuration
    • a) Configure system as router
    • b) Forward all http requests to 3128 (DNAT)
  • Step #3: Run scripts and start squid service

First, Squid server installed (use up2date squid) and configured by adding following directives to file:
# vi /etc/squid/squid.conf

Modify or add following squid directives:
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
acl lan src 192.168.1.1 192.168.2.0/24
http_access allow localhost
http_access allow lan

Where,

  • httpd_accel_host virtual: Squid as an httpd accelerator
  • httpd_accel_port 80: 80 is port you want to act as a proxy
  • httpd_accel_with_proxy on: Squid act as both a local httpd accelerator and as a proxy.
  • httpd_accel_uses_host_header on: Header is turned on which is the hostname from the URL.
  • acl lan src 192.168.1.1 192.168.2.0/24: Access control list, only allow LAN computers to use squid
  • http_access allow localhost: Squid access to LAN and localhost ACL only
  • http_access allow lan: -- same as above --

Here is the complete listing of squid.conf for your reference (grep will remove all comments and sed will remove all empty lines, thanks to David Klein for quick hint ):
# grep -v "^#" /etc/squid/squid.conf | sed -e '/^$/d'

OR, try out sed (thanks to kotnik for small sed trick)
# cat /etc/squid/squid.conf | sed '/ *#/d; /^ *$/d'

Output:
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY
hosts_file /etc/hosts
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern . 0 20% 4320
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl purge method PURGE
acl CONNECT method CONNECT
cache_mem 1024 MB
http_access allow manager localhost
http_access deny manager
http_access allow purge localhost
http_access deny purge
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
acl lan src 192.168.1.1 192.168.2.0/24
http_access allow localhost
http_access allow lan
http_access deny all
http_reply_access allow all
icp_access allow all
visible_hostname myclient.hostname.com
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
coredump_dir /var/spool/squid

Iptables configuration

Next, I had added following rules to forward all http requests (coming to port 80) to the Squid server port 3128 :
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

Here is complete shell script. Script first configure Linux system as router and forwards all http request to port 3128 (Download the fw.proxy shell script):
#!/bin/sh
# squid server IP
SQUID_SERVER="192.168.1.1"
# Interface connected to Internet
INTERNET="eth0"
# Interface connected to LAN
LAN_IN="eth1"
# Squid port
SQUID_PORT="3128"
# DO NOT MODIFY BELOW
# Clean old firewall
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# Load IPTABLES modules for NAT and IP conntrack support
modprobe ip_conntrack
modprobe ip_conntrack_ftp
# For win xp ftp client
#modprobe ip_nat_ftp
echo 1 > /proc/sys/net/ipv4/ip_forward
# Setting default filter policy
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
# Unlimited access to loop back
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow UDP, DNS and Passive FTP
iptables -A INPUT -i $INTERNET -m state --state ESTABLISHED,RELATED -j ACCEPT
# set this system as a router for Rest of LAN
iptables --table nat --append POSTROUTING --out-interface $INTERNET -j MASQUERADE
iptables --append FORWARD --in-interface $LAN_IN -j ACCEPT
# unlimited access to LAN
iptables -A INPUT -i $LAN_IN -j ACCEPT
iptables -A OUTPUT -o $LAN_IN -j ACCEPT
# DNAT port 80 request comming from LAN systems to squid 3128 ($SQUID_PORT) aka transparent proxy
iptables -t nat -A PREROUTING -i $LAN_IN -p tcp --dport 80 -j DNAT --to $SQUID_SERVER:$SQUID_PORT
# if it is same system
iptables -t nat -A PREROUTING -i $INTERNET -p tcp --dport 80 -j REDIRECT --to-port $SQUID_PORT
# DROP everything and Log it
iptables -A INPUT -j LOG
iptables -A INPUT -j DROP

Save shell script. Execute script so that system will act as a router and forward the ports:
# chmod +x /etc/fw.proxy
# /etc/fw.proxy
# service iptables save
# chkconfig iptables on

Start or Restart the squid:
# /etc/init.d/squid restart
# chkconfig squid on

Desktop / Client computer configuration

Point all desktop clients to your eth1 IP address (192.168.2.1) as Router/Gateway (use DHCP to distribute this information). You do not have to setup up individual browsers to work with proxies.

How do I test my squid proxy is working correctly?

See access log file /var/log/squid/access.log:
# tail -f /var/log/squid/access.log

Above command will monitor all incoming request and log them to /var/log/squid/access_log file. Now if somebody accessing a website through browser, squid will log information.

Problems and solutions

(a) Windows XP FTP Client

All Desktop client FTP session request ended with an error:
Illegal PORT command.

I had loaded the ip_nat_ftp kernel module. Just type the following command press Enter and voila!
# modprobe ip_nat_ftp

Please note that modprobe command is already added to a shell script (above).

(b) Port 443 redirection

I had block out all connection request from our router settings except for our proxy (192.168.1.1) server. So all ports including 443 (https/ssl) request denied. You cannot redirect port 443, from debian mailing list, "Long answer: SSL is specifically designed to prevent "man in the middle" attacks, and setting up squid in such a way would be the same as such a "man in the middle" attack. You might be able to successfully achive this, but not without breaking the encryption and certification that is the point behind SSL".

Therefore, I had quickly reopen port 443 (router firewall) for all my LAN computers and problem was solved.

(c) Squid Proxy authentication in a transparent mode

You cannot use Squid authentication with a transparently intercepting proxy.

Further reading:


Trackback 2 Comment 0