RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR
'Linux'에 해당되는 글 112
출처 블로그 > H.i.p.p.i.e .♂. N.a.y.a
원본 http://blog.naver.com/xxfinger/100002953652

[펌] 온더넷


리눅스/윈도우의 PPTP 프로토콜로 VPN 구성하기 ①
 출판일 :2004년 6월호

VPN을 운영하는 데는 다양한 프로토콜이 있다. 이중 PPTP(Point-to-Point Tunneling Protocol)는 TCP/IP 상에서 안전한 통신을 지원하고 멀티프로토콜 통신을 추가한 새로운 개념의 프로토콜이다. 또한 PPTP를 이용한 통신으로, 리눅스와 윈도우 간의 VPN을 쉽게 구축할 수 있다. 이 글을 통해 리눅스와 윈도우를 이용해 서버 대 서버, 서버 대 클라이언트를 구성하는 방법을 알아본다.



정낙수, 정민, 김규현_국민대학교 OSSRC 소속 개발자

VPN 서비스를 이용하는 가장 쉬운 방법은 VPN 장비를 도입하는 것이지만, 그 비용은 접속 노드 2∼3개를 증설할 수 있는 것과 맞먹기 때문에 중소기업은 부담스러운 것이 현실이다. 하지만 중소기업에서 비용 부담없이 VPN을 구축할 수 있는 방법이 있다. 구형 PC와 윈도우, 리눅스를 이용해 VPN을 구축하는 것으로, 여러 가지 장점이 있다.  
윈도우, 리눅스가 모두 소프트웨어이기 때문에 기능 업그레이드를 손쉽게 할 수 있고 다양한 프로토콜의 지원도 가능해진다. 물론 저렴하다는 점 역시 매우 큰 장점이다. 클라이언트 용도로 사용하기 힘든 PC에 윈도우 2000 서버를 이용해 VPN 서버를 구성할 수도 있고, 윈도우 2000 라이센스 비용에 일반 PC 비용 대신 폐기 처분될 PC에 리눅스를 설치해 VPN 서버로 만들 수 있으니 말이다.
또한 세션이 무제한이라는 장점이 있다. 소규모 네트워크를 위한 VPN 장비의 경우 최대 세션과 터널 수에도 제한이 있다. 때문에 일정 수의 사용자 이상은 접속할 수 없다는 단점이 있지만, 공개 소프트웨어나 기본 내장 VPN을 이용한 경우에는 최대 세션 수 제한이 없기 때문에 사용자 수를 확장해 사용할 수 있다. 그러나 소프트웨어로 구현된 장비가 늘 그렇듯이 하드웨어 장비에 비해 속도가 느리다는 단점이 있다. 물론 소프트웨어의 경우 해당 소프트웨어에 대한 정확한 이해가 필요하다는 것도 단점일 수 있다. 어떤 점에 더 비중을 둘 것인가는 네트워크 관리자의 몫이고 가장 적합한 솔루션을 선택하는 것 역시 네트워크 관리자의 몫이므로 여기에서 무엇이 더 좋은가에 대한 의제는 무의미할 것이다.

다양한 VPN 프로토콜을 통한 안전한 통신 확보
구축에 앞서 VPN의 개념을 파악해보자. VPN은 공중 통신망 기반 시설을 터널링 프로토콜과 보안 절차 등을 사용해 개별 기업의 목적에 맞게 구성한 사설 네트워크다. 자체망이나 전용회선의 개념을 인터넷과 같은 공중망을 통해 이용하는 것이다. VPN은 모든 회사들이 저마다 개별적으로 회선을 임대하는 것보다, 공중망을 공유함으로써 비용은 낮추면서도 전용회선과 거의 동등한 서비스를 사용하기 위해 활용된다. 또한 인증, 암호화, 복호화, 라우팅 등의 방식을 통해 데이터를 안전하게 처리할 수 있도록 지원한다.
VPN은 공중망을 통해 데이터를 송신하기 전에 데이터를 암호화하고, 수신측에서 복호화한다. 암호화는 데이터뿐 아니라, 부가적인 차원의 보안으로서 송수신지의 네트워크 어드레스도 포함한다. 또한 최근 모바일 업무가 증가함에 따라 모바일을 사용하는 직원들의 안전한 사내 네트워크 사용을 위해서도 VPN은 사용된다.


(그림 1) VPN을 이용한 LAN to LAN 구성



(그림 1)과 같이 3개의 사업장이 있을 때 각각의 사업장은 다른 사업장에 접근하기 위해서는 모든 장비에 공인 IP를 부여해야 한다. 이는 보안상 문제점을 지니며 IP를 확보하는 것 역시 부가 비용이 든다. 하지만 각각의 사업장을 VPN을 통해 터널을 생성하면 3개의 사업장이 하나의 네트워크 세그먼트를 구성하며 이를 통해 내부 IP를 사용하더라도 다른 사업장의 장비에 접근할 수 있다.
둘째, 리모트 액세스(Remote Access) VPN은 재택 근무나 모바일 근무와 같은 단독 사용자 환경에 적합한 구성이다. (그림 2)와 같이 외부의 사용자가 인터넷을 이용해 사업장의 VPN을 통해 터널을 생성하게 되면 모바일 사용자가 회사내의 사용자 혹은 자원에 로컬 네트워크에 속해있는 것과 같이 사업장내의 다른 자원에 접근할 수 있다.


(그림 2) VPN을 이용한 리모트 액세스 구성

VPN 솔루션은 마이크로소프트, 3Com 그리고 몇몇 다른 회사들이 PPTP라는 표준 프로토콜을 제안했으며, 시스코는 L2F, L2TP 등의 VPN 솔루션을 제공하고 있다. 최근의 노텔, 넷스크린, 시스코 장비들은 이같은 프로토콜을 모두 지원하고 있으므로, 서로 다른 장비를 이용하더라도 VPN 연결은 매우 손쉽게 구성할 수 있다. 기본적인 구성은 LAN to LAN VPN으로, 지사와 같은 멀티 유저 환경에서 프로토콜을 이용해 가상 네트워크를 만든다. VPN을 구성하는 프로토콜은 다음과 같다.


·IPSec 프로토콜
IPSec(Internet Protocol Security)은 보안을 위해 계획된 프로토콜로, RFC-2411에 정의돼 있다. 이전의 보안 기법들은 보안이 통신 모델의 애플리케이션 계층에 삽입됐다면 IPSec은 본질적으로 데이터 송신자의 인증을 허용하는 인증 헤더 AH와, 송신자의 인증과 데이터 암호화를 함께 지원하는 ESP(Encapsulating Security Payload), 키교환을 위한 IKE 등의 보안 서비스를 제공한다. AH는 MD5 또는 HMAC 알고리즘을 사용해 인증을 처리한다. ESP는 DES, RC5 등의 암호화 알고리즘을 사용해 데이터를 암호화한다. IKE 키관리 절차에서는 ISAKMP/Oakley 프로토콜과 같은 별개의 키 프로토콜들이 선택할 수 있다. 이같은 각 서비스에 관련된 명확한 정보는 IP 패킷 헤더의 뒤를 잇는, 헤더 속의 패킷에 삽입된다. AH가 무결성을 보장한다면 ESP는 보안성을 보장한다. 그리고 IPSec으로 전송시 전송 모드(Transport Mode)와 터널 모드(Tunnel Mode)를 지원한다.

·L2TP 프로토콜
L2TP(Layer 2 Tunneling Protocol)는 L2F 프로토콜을 향상시키기 위해 마이크로소프트의 PPTP와 시스코사의 L2F(Layer 2 Forwarding) 프로토콜이 결합돼 IETF가 산업 표준으로 제정한 터널링 프로토콜이다. 현재 L2TP v3는 L2TP를 확장해 일부 새로운 서비스 모델을 포함시켰다. 또한 PP만이 아닌 터널링 대안의 계층 2PDU에 대한 지원도 제공된다. LT2P는 IP, IPX, NetBEUI 트랙픽을 암호화 한 다음, IP 헤더로 캡슐화해 전송한다. PPP에서 제공되는 데이터 암호화 기법을 사용할 수도 있고 IPSec에 의해 제공되는 더 강력한 데이터 암호화 기법을 사용할 수 있다. 이때는 L2TP/IPSec라고 한다. L2TP와 IPSec의 결합 형태에서 연결은 DES(Data Encryption Standard) 알고리즘을 사용하는데, 이 알고리즘은 DES에 대해 하나의 56비트 키를, 3DES에 대해 세 개의 56비트 키를 사용한다. L2TP/IPSec 연결은 두 가지 수준의 인증을 요구한다. IPSec SA(보안 연결)를 작성해 L2TP 캡슐화 데이터를 보호하기 위해 L2TP/IPSec 클라이언트는 인증서나 미리 공유된 키를 사용해 컴퓨터 수준의 인증을 수행한다. IPSec SA가 성공적으로 작성되면 연결의 L2TP 부분에서 PPTP와 동일한 사용자 수준의 인증을 수행한다.

·PPTP 프로토콜
PPTP(Point-to-Point Tunneling Protocol)는 PPP의 확장으로 개발된 PPTP에서는 인터넷을 통한 새로운 수준의 강화된 보안과 멀티프로토콜 통신이 추가됐다. 인터넷 프로토콜인 TCP/IP를 그대로 이용하면서도 외부인은 접근할 수 없는 별도의 VPN을 운용할 수 있는 프로토콜이다. 특히 PPTP 지원하는 VPN을 통한 데이터 전송은 새로운 EAP(Extensible Authentication Protocol)를 사용하기 때문에 단일 LAN 내의 회사 사이트에서 데이터를 전송하는 것만큼이나 안전성을 보장한다. VPN 서버는 모든 보안 검사와 유효성 검사를 수행하고 데이터를 암호화해 보안되지 않는 네트워크를 통해 가상 터널을 생성해서 보다 안전하게 전송할 수 있다. 또한 개인 LAN to LAN 네트워크에 PPTP를 사용할 수도 있다. PPTP에서는 전화 접속 연결이 필요하지 않다. 그러나 컴퓨터와 서버가 IP로 연결돼 있어야 한다. IP LAN에 직접 연결돼 있으면서 서버와 접속할 수 있으면 LAN을 통한 PPTP 터널을 설정할 수 있다. 그러나 인터넷을 통해 터널을 만드는 중이고 일반적으로 ISP와의 전화 접속 연결을 통해 인터넷에 액세스하는 경우 터널을 설정하기 전에 전화 접속으로 인터넷에 연결해야 한다. 리눅스에서는 PPTPD라는 서버 데몬과 PPTP라는 클라이언트를 통해 VPN을 구성할 수 있다. 물론 PPTP 프로토콜을 통한 VPN을 구성함에 있어서 리눅스와 윈도우간의 서버 대 서버, 서버 대 클라이언트간의 구성이 가능하다.

·MPLS VPN
MPLS VPN은 고객별로 터널링하는 것으로 MPLS 코어를 운영하는 서비스 업체들에 의해 구현된다. 기업을 위한 주요 애플리케이션은 자사의 WAN 코어를 서비스 업체에 부분적이거나 모든 부분을 아웃소싱한다. MPLS의 특성을 이용해 서비스 업체들은 에지 라우터의 고객 어드레스 공간을 분리한 다음, 고객으로부터 트래픽이 서비스 업체의 코어에 들어오면 VPN 라벨이 IP 패킷에 첨부돼 터널 라벨 스위치 경로를 통해 전환된다.

·AToM
AToM(Any Transport over MPLS)은 서비스 업체 MPLS 네트워크에서 사용하기 위한 L2TP v3와 유사하게 동작한다. 2계층 프레임을 MPLS 네트워크로 전송하며, 목적지 상대방에 전송하기 전 고객 트래픽에 라벨을 붙인다는 점에서 MPLS VPN과 비슷하다. 하지만 확장된 라벨 전송 프로토콜 세션을 사용해 독특한 가상 회선이나 유사 회선 라벨과 협상, 다양한 2계층의 고객 트래픽을 규명한다는 점에서 차이가 있다. 서비스 업체 네트워크가 고객으로부터 패킷을 받게 되면, 패킷에 라벨을 붙이고 터널 LSP(Label Switched Path)를 사용해 변환, 목적지 에지 라우터에 보낸다. 수신하는 에지 라우터는 라벨을 벗기고 패킷을 순수한 2계층 PDU 형태로 고객 사이트에 포워딩한다.

이와 같은 대표적인 프로토콜 이외에도 AMTP(Ascend Tunnel Management Protocol), VTP(Virtual Tunneling Protocol), IP in IP 등의 방법이 있으나 실제로 IPSec, PPTP, L2TP가 가장 많이 사용되고 구현이 쉽다.


리눅스를 이용한 VPN 서버 구성 솔루션
윈도우와 함께 활용할 리눅스 VPN 프로그램을 살펴보자. FreeSWAN(www.freeswan.org)은 리눅스에서 IPSec 프로토콜을 이용해 서버를 구성할 수 있는 솔루션이다. 리눅스에서 FreeSWAN을 구성하기 위해서는 커널 컴파일로 커널에서 IPSec을 지원하게 만들어야 한다. 또한 서버에서 NAT를 지원해야 하므로 커널에서 NAT 기능을 사용하기 위해 iptables을 설정해야 한다. 커널 컴파일후 FreeSWAN을 설치한다. 이때 커널 패치가 이뤄지고 설치 후에는 /etc/ipsec.secrets와 /etc/ipsec.conf 파일을 통해 설정할 수 있다. 최신 커널인 2.6에는 IPSec 지원이 커널에 삽입돼 커널 패치를 하지 않아도 사용할 수 있다.
Poptop(www.poptop.org)은 리눅스에서 PPTP를 이용해 서버를 구성하는 솔루션이다. 리눅스에서 Poptop을 구성하기 위해서는 커널 컴파일을 통해 커널에서 PPP 방식을 지원할 수 있게 해야 한다. 이는 PPTP가 PPP를 이용해 구현됐기 때문이다. 또한 L2TPD(www.l2tpd.org)는 리눅스에서 L2TP를 이용해 서버를 구성할 수 있는 솔루션이다.


윈도우 2000으로 클라이언트 접속을 위한 서버 구성하기
이제 실제로 VPN을 구축해 보자. 여기에 사용된 장비는 펜티엄Ⅲ 700 CPU이며, 리눅스 커널 버전은 2.4.20 & 2.4.3 그리고 윈도우 2000 서버이다. 실제로 테스트가 이뤄질 때, 펜티엄 클래식 166Mhz에 메모리 32MB와 1GB의 하드디스크에 리눅스를 올려 구축했는데, 매우 원활하게 동작했다.
(그림 3)에서 클라이언트는 사설 IP 대역인 192.X.X.X의 IP에는 접속하지 못하므로 해당 서비스를 이용할 수 없다. 하지만 VPN을 이용할 경우 VPN 서버에 연결 후 서버로부터 가상의 IP인 192.168.1.10을 부여받으면서 서버와 같은 네트워크에 속하게 된다. 때문에 사설 IP로 할당된 전자우편이나 웹서비스를 이용할 수 있다.


(그림 3) LAN to 클라이언트 구성도(www.poptop.org 참조)
우선 클라이언트 접속을 위한 서버를 구성해 보자. 윈도우 2000의 라우팅 및 원격 액세스 서버 설치 마법사를 통해 구축을 시작한다(화면 1). 시작 → 프로그램 → 관리도구 → 라우팅 및 원격 액세스 선택 수동으로 구성한 서버를 선택하고 마친다.


(화면 1) 라우팅 및 원격 액세스 서버 설치 마법사 화면

라우팅 및 원격 액세스 서버가 설치되고 가동되면 서버에 접속한 원격 클라이언트에게 할당할 IP 대역을 설정한다(화면 2). 로컬 등록 정보 화면에서 서버 → 등록정보 → IP 탭을 선택한다.

(화면 2) 로컬 등록 정보 화면

원격 액세스 정책을 설정하기 위해 원격 액세스 정책 탭을 클릭해 새로 만들기를 선택한다(화면 3). 추가 탭을 눌러 다음과 같은 조건을 선택한다. Tunnel-Type 항목에 들어가 PPTP 선택하고, Windows-Group에서 클라이언트 계정에 필요한 그룹을 선택한다. 사용자 계정 그룹은 시작 → 프로그램 → 관리도구 → 컴퓨터관리 → 로컬사용자 및 그룹에서 관리로 들어간다. Day-And-Time-Restictions 항목에서 액세스 가능 시간대를 선택해준다.


(화면 3) 원격 액세스 정책 추가 화면

(화면 4) 원격 액세스 정책 권한 화면


원격 액세스 권한 허용을 선택한다(화면 4). 이로써 윈도우 2000 VPN 서버의 기본 설정을 마친 것이다.



리눅스/윈도우의 PPTP 프로토콜로 VPN 구성하기 ②
 출판일 :2004년 6월호

VPN을 운영하는 데는 다양한 프로토콜이 있다. 이중 PPTP(Point-to-Point Tunneling Protocol)는 TCP/IP 상에서 안전한 통신을 지원하고 멀티프로토콜 통신을 추가한 새로운 개념의 프로토콜이다. 또한 PPTP를 이용한 통신으로, 리눅스와 윈도우 간의 VPN을 쉽게 구축할 수 있다. 이 글을 통해 리눅스와 윈도우를 이용해 서버 대 서버, 서버 대 클라이언트를 구성하는 방법을 알아본다.



정낙수, 정민, 김규현_국민대학교 OSSRC 소속 개발자







리눅스 PoPtop으로 클라이언트 접속 서버 구성하기
리눅스 VPN 서버를 구성하기 위해서는 몇가지 다운로드가 필요하다.

·파일 다운 로드
www.kernel.org/pub/linux/kernel   / : 커널 
http://wlan.informatik.uni-bremen.de/doku/debian/download/sonstiges/ppp-2.4/ppp-2.4.1-n :  ppp-2.4.1-mppe.tar.gz
ftp://ftp.psy.uq.oz.au/pub/crypto/ssl/ssleay-0.9.0b.tar.gz : ssleay-0.9.0b.tar.gz
www.poptop.org    : pptpd-1.1.3-4.i386.rpm                                    

솔루션을 다운로드했다면, PPPD 설치(MSCHAP v2 & MPPE SUPPORT)를 실행한다.  

#] tar xvfz ppp-2.4.1-mppe.tar.gz
#] tar xvfz SSLeay-0.9.0b.tar.gz

#] cp SSLeay-0.9.0b/crypto/rc4/rc4.h ppp-2.4.1-openssl0.9.6mppe-MSCHAPv2fix/linux/
#] cp SSLeay-0.9.0b/crypto/rc4/rc4_enc.c ppp-2.4.1-openssl0.9.6mppe-MSCHAPv2fix/linux/
#] cd ppp-2.4.1-openssl0.9.6mppe-MSCHAPv2fix

#] ./configure
#] make
#] make install

#] cp pppd/pppd /usr/sbin/

커널 컴파일(MPPE-PPP SUPPORT)을 실행한다. 배포판 커널에도 PPP는 모듈로 설정돼 있지만 MPPE와 MSCHAPv2를 지원하지 않는 경우가 대부분이기 때문에 이를 추가해 커널을 다시 만들어야 한다. 커널 컴파일시 network-device-support에서 ppp-support 항목을 yes로 하고 ppp의 세부항목(async serial ports, sync tty ports, deflate compression, bsd-comression)은 꼭 module로 설정한다.
만약, 클라이언트가 VPN 서버 접속을 끊지 않은 상태에서 웹 검색 등을 지원하려면 VPN 서버에서 NAT를 지원해야 한다. iptables을 이용한 마스커레이드(masqurade)를 이용할 것이라면 iptables를 추가해서 컴파일해야 한다. 물론 ipchains를 통해 마스커레이드를 할 경우는 ipchain을 추가해야 한다.

#] cd /usr/src
#] ln -s /usr/src/linux-2.4.20 /usr/src/linux
#] gunzip linux-2.4.16-openssl-0.9.6b-mppe.patch.gz
#] mv linux-2.4.16-openssl-0.9.6b-mppe.patch linux
#] cd linux
#] patch -p1 < linux-2.4.16-openssl-0.9.6b-mppe.patch

#] cd /usr/src/linux/drivers/net/
#] vi Makefile
#] # 다음 6라인을
 obj-$(CONFIG_PPP) += ppp_generic.o slhc.o ppp_mppe.o
 obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
 obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
 obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
 obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
#] #다음 6라인으로 대체 한다. (ppp_mppe.o가 컴파일 안될 경우대비)
 obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
 obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
 obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
 obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o ppp_mppe.o
 obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o

#] make menuconfig
#] make dep && make clean && make bzImage && make install && make modules && make #] modules_install
#] cd arch/i386/boot/
#] cp bzImage /boot/vmlinuz-2.4.20
#] cp Sysmap.map /boot/Sysmap.map-2.4.20

#] vi /etc/lilo.conf
   image=/boot/vmlinuz-2.4.20
   label=linux-2.4.20
   read-only
 
#] lilo

#] reboot

컴파일이 제대로 됐다면 /lib/modules/2.4.20/kernel/drivers/net/에 bsd_comp.o, ppp_async.o, ppp_deflate.o, ppp_synctty.o가 포함돼야 한다. 그 다음에 PPTPD를 설치하고, 설정한다.

rpm -Uvh pptpd-1.1.3-4.i386.rpm

/etc/modules.conf
#pptpd를 위해 추가해야할 설정
alias char-major-108 ppp_generic
alias tty-ldisc-3 ppp_async
alias tty-ldisc-14 ppp_synctty
alias ppp-compress-18 ppp_mppe
alias ppp-compress-21 bsd_comp
alias ppp-compress-24 ppp_deflate
alias ppp-compress-26 ppp_deflate

/etc/pptpd.conf
option /etc/ppp/options.pptpd
localip 192.168.10.200               #VPN 서버의 가상 IP로 설정됩니다.
remoteip 192.168.10.201-254      #VPN 클라이언트에게 배정될 IP 대역이 됩니다.

/etc/ppp/options.pptpd
#리눅스 VPN 클라이언트와 윈도우 VPN 클라이언트 접속을 위한 설정
name *                        #서버 name
lock                           #client에서 serial장치 외부 접근 방지
mtu 1450                      # client 에게 1450보다 많지 않은 패킷을 보내도록
mru 1450                      # client 에게 1450보다 많은 패킷은 보내지 않도록
proxyarp                       # client가 proxy ARP 목록 생성 금지
nodeflate                       # deflate compression을 사용하지 않는다
nobsdcomp                     # bsd-compression을 사용하지 않는다
auth                            # 인증 사용
+chap                          # chap 인증 사용
+chapms-v2                    # chapv2인증 사용
ipcp-accept-local               # 상대측 정보를 시스템의 local ip로 받는다
ipcp-accept-remote             # 상대측 정보를 시스템의 remote ip로 받는다
lcp-echo-failure 3              # 물리적으로 접속이 끊어질 경우 종료
lcp-echo-interval 5             # client가 연결 되어있는지 확인
deflate 0                       # deflate compression
mppe-128                      #mppe 암호화 사용
mppe-40
mppe-stateless

vi /etc/ppp/chap-secrets
username * password * 

첫번째 *는 VPN 서버 이름이 되고 두 번째 *는 username을 사용해서 접속한 클라이언트에게 할당할 IP를 적어주면 된다. *로 할 경우 서버에서 자동으로 /etc/pptpd.conf에 지정한 IP 대역에서 처리한다.
VPN 접속후 클라이언트는 VPN 서버를 거치기 때문에 VPN 서버에서 마스커레이드를 해주어야 한다. 그래야만 클라이언트의 패킷이 VPN 서버를 거쳐 VPN 서버의 내부로 흘러가지 않는다. 하지만 이는 VPN 서버에 부하를 주기 때문에 VPN을 이용하지 않을 경우에는 VPN을 끊고 웹 검색을 해야 한다. 커널 2.4 이후에는 iptables을 지원하므로 iptables를 통해 마스커레이드를 하고 그렇지않을 경우 ipchains을 사용한다면 ipchains을 이용한 마스커레이드를 해줄 수 있다. iptables을 이용한 마스커레이드는 다음과 같다.   

#] vi /etc/rc.d/rc.local
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A POSTROUTING -t nat -o ppp0 -j MASQUERADE
#] reboot

이와 같은 마스커레이드는 어떤 패킷 필터링도 하지 않은 상태다. 특정 패킷 필터링이 필요한 경우 추가시켜주면 된다.



리눅스/윈도우의 PPTP 프로토콜로 VPN 구성하기 ③
 출판일 :2004년 6월호

VPN을 운영하는 데는 다양한 프로토콜이 있다. 이중 PPTP(Point-to-Point Tunneling Protocol)는 TCP/IP 상에서 안전한 통신을 지원하고 멀티프로토콜 통신을 추가한 새로운 개념의 프로토콜이다. 또한 PPTP를 이용한 통신으로, 리눅스와 윈도우 간의 VPN을 쉽게 구축할 수 있다. 이 글을 통해 리눅스와 윈도우를 이용해 서버 대 서버, 서버 대 클라이언트를 구성하는 방법을 알아본다.



정낙수, 정민, 김규현_국민대학교 OSSRC 소속 개발자



서버 접속을 위한 LAN to 클라이언트 구성하기
이제 클라이언트 구성을 알아보자. 윈도우 서버와 윈도우 클라이언트를 이용해 VPN 접속하는데, VPN 서버 어드레스 입력이 필요하다.

·윈도우 2000 구성하기 
설정 → 네트워크 및 전화접속 연결 → 새연결 만들기 → VPN을 통한연결 → VPN 서버 어드레스 입력

·윈도우 XP 구성하기
시작 → 프로그램 → 보조프로그램 → 통신 → 새연결 만들기 → 회사네트워크에 연결 → VPN 연결 → 초기 연결을 사용 안함 → VPN 서버 어드레스 입력


(화면 5) 네트워크 연결 마법사를 이용한 VPN 클라이언트 설정


윈도우 서버와 PPTP 클라이언트를 이용한 VPN 접속하기 위해서는 파일 다운로드(pptpclient.sourceforge.net)가 필요하다.
PPP를 설치하기 위해 준비(MSCHAP v2 & MPPE)한다.

#] tar xvfz ppp-2.4.2
#] cd ppp-2.4.2
#] ./linux/mppe/mppeinstall.sh /usr/src/linux-2.4.20
 
커널 컴파일시 network-device-support에서 ppp-support 항목을 yes로 클릭하고 ppp의 세부항목은 꼭 module로 설정한다.

#] make xconfig
#] make dep && make clean && make bzImage && make install && make modules && make #] modules_install
#] cd arch/i386/boot/
#] cp bzImage /boot/vmlinuz-2.4.20
#] cp Sysmap.map /boot/Sysmap.map-2.4.20

#] vi /etc/lilo.conf
   image=/boot/vmlinuz-2.4.20
   label=linux-2.4.20
   read-only
 
#] lilo

#] reboot

PPP & PPTP를 설치, 설정한다.

#] cd ppp-2.4.2
#] ./configure
#] make
#] make install

#] tar pptp-linux-1.3.1
#] cd pptp-linux-1.3.1
#] make
#] make install

/etc/ppp/options.pptp
lock                               # client에서 serial장치 외부 접근 방지
noauth                            # 인증 사용 안함
nobsdcomp                        # bsd-compression을 사용하지 않는다
nodeflate                          # deflate compression을 사용하지 않는다
require-mppe-40                  # mppe 암호화 사용
require-mppe-128


/etc/ppp/peers/vpn
pty "pptp 210.121.xxx.xxx nolaunchpppd"#VPN 서버 IP
name xxxx                             # xxxx는 VPN 서버에 등록된 클라이언트 ID
require-mppe                          # mppe암호화 사용
require-mschap-v2                    # chapv2 인증 사용
file /etc/ppp/optios.pptp                # options.pptp 설정 사용
ipparam vpn         

vi /etc/ppp/chap-secrets
# ID  서버  패스워드 IP
xxxx  vpn  xxxx  *                   # id, 서버name, passward 기록

VPN 서버에 접속한다.

#] pppd call vpn

PPTP 클라이언트 GUI 설치한다. 리눅스에서도 PPTP 클라이언트용 GUI TOOL이 있다.

#] ./rpm -Uvh pptp-php-gtk.rpm     #GUI TOOL 설치
#] ./pptpconfig                       #TOOL 실행


(화면 6) PPTP GUI 툴

그 다음 Poptop과 윈도우 클라이언트를 이용해 VPN에 접속한다. 리눅스 서버인 Poptop과 윈도우의 원격접속 클라이언트는 서로 호환이 되기 때문에 이와 같이 설명한 방식은 윈도우 클라이언트를 구성해서 Poptop으로 구성된 서버에 연결해 사용할 수 있다.
Poptop과 PPTP를 이용해 VPN에 접속한다. 리눅스 서버인 Poptop과 리눅스 클라이언트인 PPTP의 설정은 이미 설명한 그대로 사용할 수 있다.

윈도우 서버를 이용한 LAN to LAN 구성하기
이제 LAN to LAN 구성을 해보자. (그림 4)는 LAN to LAN 혹은 게이트웨이 투 게이트웨이 간의 구성도이다. 그림의 클라이언트 내부 네트워크의 호스트인 A나 B는 NAT를 통해 클라이언트의 203.0.0.55를 인터넷에 연결할 수 있다. 하지만 (그림 4)에서와 마찬가지로 호스트 A나 B는 서버의 내부 네트워크인 전자우편이나 웹 서비스를 이용할 수 없다. 하지만 VPN을 이용할 경우 클라이언트의 요청에 의해 서버는 클라이언트와 가상 터널을 만들고 호스트 A나 B는 클라이언트와 서버의 가상 터널을 통해 서비스를 이용할 수 있다.

(그림 4) LAN to LAN 구성도


윈도우 2000 서버 버전을 이용해서 LAN to LAN을 구성할 경우 그림에서 클라이언트라고 표시된 부분과 서버라고 표시된 부분이 VPN 서버가 된다. LAN to LAN 구성은 크게, 필요할때마다 연결하는 것과 영구적으로 연결하는 것, 둘로 나눌 수 있다. 필요시 연결이라고 하면 클라이언트의 호스트 A가 메일 서버에 접속하기 위해 클라이언트에 요청을 하면 클라이언트와 서버 사이에 VPN이 생긴다. 생성된 VPN은 호스트 A나 호스트 B의 사용이 없는 경우 사라지게 된다. 영구 사용할 때 연결은 호스트의 요청이나 사용 여부에 관계없이 VPN이 존재한다. 

·필요시 연결 구성하기
① 양쪽 라우터가 VPN 서버가 될 수 있게 라우팅과 원격 액세스를 시작한다.
② 라우터간 연결을 위한 인터페이스를 설정한다.
③ 상대 라우터의 내부 네트워크 대역을 고정 경로 등록을 통해 기록한다.
④ (그림 4)의 A나 B의 요청이 있으면 연결 후 해제 

(그림 4)의 클라이언트와 서버의 설정은 고정 경로시 IP 설정이 상대편 대역으로 설정하는 것만 다르고 나머지 설정은 같다. 양쪽 라우터가 VPN 서버가 될 수 있게 라우팅과 원격 액세스를 시작한다(화면 7). 라우팅 인터페이스 → 새 필요시 전화 접속 인터페이스 선택한다.

(화면 7) 라우팅 및 원격 액세스 서버 설치 마법사

라우터간 연결을 위한 인터페이스를 설정한다(화면 8). 또한 연결 형식을 VPN을 사용해 연결로 선택한다(화면 9). 만들고자 하는 VPN의 인터페이스의 유형을 PPTP로 선택한다(화면 10).
LAN to LAN 연결이기 때문에 상대편 게이트웨이의 어드레스를 적어준다(화면 11). 원격 라우터 접속을 위한 계정을 사용할 수 있도록 설정한다(화면 12). 상대편 라우터가 접속할 때 사용할 계정이 된다(화면 13). 상대 라우터에 연결할 사용자 인증을 기록한다(화면 14).

(화면 8) 서버의 인터페이스 이름 설정
(화면 9) 연결 형식 선택
(화면 10) 프로토콜 방식 선택
(화면 11) 대상 어드레스 입력
(화면 12) 원격 라우터가 전화 접속하도록 사용자 계정 추가
(화면 13) 상대편 라우터가 접속할 때 사용할 계정
(화면 14) 상대 라우터에 연결할 사용자 인증 기록

상대 라우터의 내부 네트워크 대역을 고정 경로 등록을 통해 기록한다(화면 15). 경로는 IP 라우팅 → 고정 경로 → 새 고정 경로를 지정한다.

(화면 15) 고정 경로

우선 수준 등록 정보 중 라우팅 및 원격액세스 → IP라우팅 → 일반 → 등록정보 → 우선수준에서 경로원본의 고정 우선순위를 낮춘다(화면 16).

(화면 16) 우선수준 등록 정보

NAT를 위해 인터넷과 연결된 NIC의 등록정보에서 인터넷 연결 공유 탭을 활성화시킨다(화면 17).

(화면 17) 연결 공유탭

(그림 4)에서 클라이언트의 호스트 A 또는 B가 요청을 하면 VPN이 구성된다.

·영구 VPN을 연결하기 위한 구성
① 양쪽 라우터가 VPN 서버가 될 수 있도록 라우팅 및 원격 액세스를 시작한다.
② 라우터간 연결을 위한 인터페이스를 설정한다.
③ 상대 라우터의 내부 네트워크 대역을 고정 경로 등록을 통해 기록한다.
④ 클라이언트의 원격 액세스 정책을 설정한다.
⑤ 클라이언트의 요청이 있으면 영구적으로 연결된다.

기본 설정은 필요시 연결의 설정과 같다. 하지만 클라이언트의 원격 액세스 정책이 (화면 18)과 같이 달라지며 네트워크를 형성하기 위한 요청을 클라이언트가 된다. 또한 NAS-Port-Type → VPN을 선택하고, Called-Station-ID 선택 →게이트웨이 어드레스 입력한다.

(화면 18) VPN 등록 정보

Windows-Groups에서 클라이언트 계정에 필요한 그룹을 선택한다. 사용자 계정 그룹은 시작 → 프로그램 → 관리도구 → 컴퓨터관리 → 로컬 사용자 및 그룹에서 관리할 수 있다.

Poptop을 이용한 LAN to LAN 구성하기
Poptop을 이용한 LAN to LAN 구성을 위해서는 연결을 요청하는 쪽은 클라이언트가 되고 요청받는 쪽은 서버가 된다. 물론 클라이언트나 서버는 뒤쪽으로 내부 네트워크를 가지고 있다. LAN to LAN 연결 방식과 설정은 위에서 설명한 LAN to 클라이언트와 같다. 다만 내부 네트워크를 가지기 때문에 각 내부 네트워크 호스트의 패킷이 구성된 터널을 통과해야 하는지 아닌지에 대한 ROUTE 경로의 추가와 NAT가 필요하다. 때문에 클라이언트와 서버에 공통으로 상대편 내부 네트워크에 대한 고정 경로를 추가하고 iptables나 ipchains를 이용한 마스커레이드가 필요하다.

·고정 경로 추가하기
클라이언트에서
#] route add -net 192.168.0.0 netmask 255.255.0.0 dev ppp0

서버에서
#] route add -net 10.0.1.0 netmask 255.255.255.0 dev ppp0

·클라이언트 & 서버 iptables을 이용한 마스커레이드 
#] vi /etc/rc.d/rc.local
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A POSTROUTING -t nat -o ppp0 -j MASQUERADE
#] reboot

이와 같은 마스커레이드는 어떤 패킷 필터링도 하지 않은 것이다. 특정 패킷 필터링이 필요한 경우 추가시켜야 한다.

Poptop과 윈도우 VPN 서버를 이용한 LAN to LAN 구성하기
Poptop과 윈도우 VPN 서버와 연결할 때 그 설정은 이미 설명한 각 서버의 구성과 다르지 않다. (그림 2)에서 클라이언트는 윈도우 VPN 서버가 되고 서버는 Poptop으로 구성한다. 일단 윈도우의 설정은 이미 설명한 윈도우 서버를 이용한 LAN to LAN 구성 방식에서 필요할 때 설정 방법과 같다. 또한 Poptop의 설정 또한 이미 설명한 Poptop을 이용한 LAN to 클라이언트 구성 방식에서 LAN 쪽의 서버 구성 방식과 같다. 각각의 설정이 맞춰진 후 윈도우의 라우팅과 원격 액세스에서 라우팅 인터페이스 항목에서 추가한 VPN 인터페이스의 연결을 선택하면 Poptop과 윈도우 VPN 서버와의 LAN to LAN 구성이 이뤄진다.
VPN 서버를 구성할 경우 서두에 열거한 여러 프로토콜 중에서 어떤 것을 선택하는지 서버 구성자의 선택에 달려있다. 또한 VPN 장비를 사용해 구성할 것인지 리눅스를 이용해 저렴하게 구성할 것인지 또한 구성자의 몫이 된다.
Poptop을 이용한 서버 구성의 장점은 윈도우나 리눅스를 사용하는 클라이언트가 윈도우의 원격 접속이나 리눅스의 PPTP 툴 등을 통해 서버에 간편하게 접속할 수 있으며 윈도우나 리눅스의 다른 운영체제 하에서 LAN to LAN 구성할 수 있다는 것이다. 향후 와우리눅스의 엔터프라이즈 버전에도 이런 VPN 솔루션이 탑재될 예정이라고 하니 일반 사용자가 손쉽고 저렴하게 VPN을 구성할수 있는 날도 그리 멀지 않았다.

2006/09/08 22:38 2006/09/08 22:38
이 글에는 트랙백을 보낼 수 없습니다
출처 블로그 > jks3500님의 블로그
원본 http://blog.naver.com/jks3500/40002554697
nmap은 열린 포트를 확인하여 보안 점검을 위한 대표적인 툴이면서
원치 않는 서버를 대상으로 포트 스캐닝과 시스템의 OS 종류와 버전을 알아내는데 사용되기도 한다.
최근에 나온 nmap 3.45버전은 오픈된 서비스의 버전 정보까지도 확인시켜준다.

--------------------------------------------------------------
# nmap -A -T4 -F localhost

Starting nmap 3.45 (
http://www.insecure.org/nmap/ ) at 2003-09-16 22:45 KST
Interesting ports on truefeel (127.0.0.1):
(The 1203 ports scanned but not shown below are in state: closed)
PORT   STATE SERVICE  VERSION
21/tcp  open ftp    vsFTPd 1.2.0
25/tcp  open smtp    Sendmail smtpd Securing..214-2.0.0 This is sendmail version 8.12.
80/tcp  open http    Apache httpd 2.0.44 ((Unix) DAV/2 PHP/4.3.2)
... 중략 ...
Running: Linux 2.4.X|2.5.X
OS details: Linux Kernel 2.4.0 - 2.5.20, Linux kernel 2.4.20
Uptime 0.505 days (since Tue Sep 16 10:38:25 2003)

Nmap run completed -- 1 IP address (1 host up) scanned in 16.859 seconds
--------------------------------------------------------------

위에서 보는 것처럼 nmap의 뛰어난 기능으로 어느 OS를 사용하는지 쉽게 알 수 있다.

이러한 nmap의 OS를 알아내는 기능은 7단계(T1~T7)를 거치게 된다.
T1 단계에서 열린 포트로 SYN 패킷을 보내고, T2에서 열린 포트로 null 패킷 전송,
T3에서 열린 포트로 SYN, FIN, URG, PSH 패킷을 전송
T5 부터는 닫혀진 포트로 비슷한 과정을 거치게 된다.

자~ 이제 nmap OS fingerprinting을 막는 방법을 알아보자.

1. iplog 툴

iplog는 포트 스캐닝으 로깅하는 툴이다. TCP 포트, UDP 포트 스캐닝, TCP null 스캔, FIN 스캔,
smurf 공격, Xmas 스캔, ping 플러딩, IP fragment 공격 등을 감지할 수 있다.
procmisc 모드를 지원하여 같은 서브넷으로 들어오는 스캐닝을 감지할 수 있다.
또한 OS 정보를 숨기기한 목적으로도 사용할 수 있다.

1) 설치

http://ojnk.sourceforge.net/ 에서 iplog-2.2.3.tar.gz 을 받아온다.

--------------------------------------------------------------
# tar xvfz iplog-2.2.3.tar.gz
# cd iplog-2.2.3
# ./configure
# make
# make install
# cp example-iplog.conf /etc/iplog.conf
--------------------------------------------------------------

iplog.conf에서 다음 2가지를 수정한다.

--------------------------------------------------------------
user nobody          # default는 iplog 사용자로 실행함
pid-file /var/run/iplog.pid  # default는 /var/run/iplog/iplog.pid 임
--------------------------------------------------------------

소스 설치가 귀찮은 분 중
레드햇 사용자는
http://www.rpmfind.net/ 에서 iplog-2.2.3-fr2.i386.rpm 받아 설치한다.

FreeBSD 사용자는 포트 시스템을 이용해서 설치한다.
실행 파일은 /usr/local/sbin에, 설정파일은 /usr/local/etc에 설치된다.

--------------------------------------------------------------
# cd /usr/ports/net/iplog/
# make install
# make clean
--------------------------------------------------------------

'포트시스템이 뭐에요?' 하는 분은 최준호님이 쓴 글을 참고하기 바란다.
http://www.bsdnet.co.kr/articles/article.qsp?no=14

2) 실행

--------------------------------------------------------------
# iplog -o -z -i lo (테스트를 위해 lo interface를 지정함)
--------------------------------------------------------------

-o 등의 옵션의 의미는 nmap 테스트 후에 알아본다.

--------------------------------------------------------------
# nmap -sS -O localhost

Starting nmap 3.45 (
http://www.insecure.org/nmap/ ) at 2003-10-29 23:37 KST
Insufficient responses for TCP sequencing (2), OS detection may be less accurate
Insufficient responses for TCP sequencing (3), OS detection may be less accurate
Interesting ports on truefeel (127.0.0.1):
(The 1651 ports scanned but not shown below are in state: closed)
PORT   STATE SERVICE
25/tcp  open smtp
80/tcp  open http
... 중략 ...
No exact OS matches for host (If you know what OS is running on it, see
http://www.insecure.org/cgi-bin/nmap-submit.cgi).
TCP/IP fingerprint:
SInfo(V=3.45%P=i686-pc-linux-gnu%D=10/29%Time=3F9FD0B9%O=25%C=1)
T1(Resp=Y%DF=Y%W=7FFF%ACK=S++%Flags=AS%Ops=MNNTNW)
T2(Resp=Y%DF=Y%W=100%ACK=O%Flags=BAPRSF%Ops=)
T2(Resp=Y%DF=N%W=0%ACK=O%Flags=BARS%Ops=)
T2(Resp=Y%DF=Y%W=100%ACK=O%Flags=BPRF%Ops=)
T3(Resp=Y%DF=Y%W=7FFF%ACK=S++%Flags=AS%Ops=MNNTNW)
T4(Resp=Y%DF=Y%W=0%ACK=O%Flags=R%Ops=)
T5(Resp=Y%DF=Y%W=0%ACK=S++%Flags=AR%Ops=)
T6(Resp=Y%DF=Y%W=0%ACK=O%Flags=R%Ops=)
T7(Resp=Y%DF=Y%W=0%ACK=S++%Flags=AR%Ops=)
PU(Resp=N)


Uptime 0.303 days (since Wed Oct 29 16:21:04 2003)

Nmap run completed -- 1 IP address (1 host up) scanned in 21.301 seconds
--------------------------------------------------------------

nmap은 T1~T7까지 OS 탐지 테스트 과정을 거쳤지만 OS 종류는 알아내지 못했음을 확인했다.
그럼 도대체 스캐닝 로그는 어디에 있는건가? /etc/iplog.conf 설정에 따라 /var/log/iplog에 저장된다.

--------------------------------------------------------------
... 생략 ...
Oct 29 23:37:09 ICMP: echo from truefeel (127.0.0.1) (8 bytes)
Oct 29 23:37:09 TCP: port 5901 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: port 516 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: port 657 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: port 32 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: port 2044 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: port 737 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: pop2 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: port 872 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: port 670 connection attempt from truefeel (127.0.0.1):49574
Oct 29 23:37:09 TCP: SYN scan detected [ports 5901,516,657,32,2044,737,109,872,670,374,...] from
truefeel (127.0.0.1) [port 49574]
Oct 29 23:37:12 TCP: Bogus TCP flags set by truefeel (127.0.0.1):49581 (dest port 25)
Oct 29 23:37:14 TCP: ipp connection attempt from truefeel (127.0.0.1):40509
... 생략 ...
--------------------------------------------------------------

3) 옵션과 설정은?

-o : 백그라운드로 실행하지 않는다. (기본 백그라운드)
-z : 이게 바로 핵심이다. nmap로 OS 정보 알아내는 것을 막는다.
-L : log를 화면으로 출력한다.
-i : interface를 지정한다. (기본 eth0)
-u : iplog 실행 사용자 또는 UID를 지정한다. (기본 nobody)
-g : iplog 실행 그룹명 또는 GID를 지정한다. (기본 nobody)
-l : 로그파일을 지정한다. (기본 /var/log/iplog)
-a : promisc 모드로 전환하여 지정한 네트워크 내의 스캐닝을 로깅한다. (예. -a 192.168.123.0/24)
-k : iplog 프로세스를 kill한다. 백그라운드, 포그라운드 실행중인 것과 상관없이 kill.
-R : iplog를 재실행한다.

이 많은 옵션을 어떻게 사용하면 좋을까?

화면으로 모니터링한다면

# iplog -o -z -L

파일로 로깅을 한다면 (부팅시 실행되도록 하려면 /etc/rc.d/rc.local 등에 추가)

# iplog -z

/etc/iplog.conf 설정 파일에서는 옵션으로 사용할 것을 미리 지정해 둘 수 있다.
실행 사용자, interface, 감지에서 제외할 포트 등

2. iptables 이용하는 방법

iptables를 이용하는 방법이 있으나 커널 패치+iptables 패치를 해야하는 과정이 필요하며
커널 2.4.19 이후의 버전에 대해서는 더이상의 발표도 있지 않아 간단하게 설명한다.

http://ippersonality.sourceforge.net/ 에서 ippersonality-20020819-2.4.19.tar.gz 를
받아 커널과 iptables 각각 패치를 한 후 컴파일을 한다.

ippersonality-20020819-2.4.19/samples 디렉토리에는 OS를 속이기 위한 총 10개의 파일이 있다.
AmigaOS, Dreamcast, FreeBSD, Linux 2.0x, Linux 2.2, MacOS 9, Solaris 8, Tru64 UNIX,
Win Me 또는 Win 2000, Win 9x 이렇게 10개.

Windows를 사용하는 것 처럼 속이려면 어떻게 해야 하는가?

패치된 iptables를 이용해서

--------------------------------------------------------------
# insmod ipt_PERS (모듈을 로딩, 커널 컴파일시에 CONFIG_IP_NF_PERS=m로 했을 때)
# /usr/local/sbin/iptables -t mangle -A PREROUTING -s ! 서버IP -d 서버IP -j PERS --tweak dst --local --conf win2k.conf
# /usr/local/sbin/iptables -t mangle -A OUTPUT   -s 서버IP -d ! 서버IP -j PERS --tweak src --local --conf win2k.conf
--------------------------------------------------------------

3. 참고 자료

* A practical approach for defeating Nmap OS-Fingerprinting
 
http://coffeenix.net/doc/security/nmap_os_fingerprinting.html
* IP Personality 프로젝트
 
http://ippersonality.sourceforge.net/
* iplog
 
http://ojnk.sourceforge.net/
* nmap 3.45의 새기능, 버전 스캐닝 (글 좋은진호)
 
http://coffeenix.net/board_view.php?bd_code=71
2006/09/08 22:29 2006/09/08 22:29
이 글에는 트랙백을 보낼 수 없습니다

fdisk 와 cfdisk 사용하기

루트 디스크를 사용한 다음 첫번째 설치 단계는 하드디스크에 대한 파티션 테이블을 작성하는 것이다. 앞에서 파티션을 나누기 위해 FDISK를 사용했다 하더라도 이제 다시 파티션 테이블 작성으로 되돌아와 리눅스가 알아듣는 정보를 넣어주어야 한다.

리눅스 파티션을 만들기 위해서 리눅스 버전의 fdisk 프로그램 또는 화면 중심의 cfdisk 프로그램을 이용해야 한다.

일반적으로 설치 프로그램은 이미 존재하는 파티션 테이블을 찾아서 그걸 바탕으로 fdisk 또는 cfdisk를 실행시키도록 해준다. 둘 중에 cfdisk의 사용이 더 쉽다. 그러나 현재 버전은 파티션 테이블이 존재하지 않거나 잘못된 것이면 사용하기가 어렵다.

(특히 어떤 오퍼레이팅 시스템도 설치되어 있지않은 처녀 시스템의 경우) cfdisk를 사용할 수 있는 상태로 만들기 위해 먼저 fdisk를 실행시킬 필요가 있는 경우가 있다. 먼저 cfdisk를 실행시켜보고 안되면 fdisk를 사용하기 바란다. (여러분의 컴퓨터에 리눅스만을 설치할 계획인데 cfdisk를 사용할 수 없다면, 먼저 fdisk를 실행시켜 존재하는 파티션을 모두 지워버린 후에 cfdisk를 실행시켜 파티션 테이블을 작성하는 것도 좋은 방법이다.)

fdisk 와 cfdisk 모두에 적용되는 몇가지 주의사항. 둘다 리눅스 파티션을 만들 드라이브의 이름을 지정해줄 변수를 필요로한다. 하드 드라이브의 장치 이름은:

/dev/hda First IDE drive

/dev/hdb Second IDE drive

/dev/sda First SCSI drive

/dev/sdb Second SCSI drive

예를 들어, 첫번째 SCSI 드라이브에 리눅스 파티션을 만들려고 한다면 아래의 명령을 사용해야 할 것이다 (어떤 설치 프로그램은 메뉴를 선택하는 것일 수도 있다) :

cfdisk /dev/sda

fdisk 또는 cfdisk에 아무런 변수 지정 없이 사용한다면 /dev/hda 에 리눅스 파티션을 만드는 것으로 여길 것이다.

시스템의 두 번째 드라이브에 리눅스 파티션을 만들고자 하면 /dev/hdb (IDE 드라이브의 경우) 또는 /dev/sdb (SCSI 드라이브의 경우) 라고 입력한다.

리눅스 파티션이 모두 하나의 드라이브에 있을 필요는 없다. 예를 들어, 루트 파일시스템을 위한 파티션은 /dev/hda 에, 스왑 파티션은 /dev/hdb 에 만들 수 있다. 그렇게 하려면 각각의 드라이브에 대하여 fdisk 또는 cfdisk를 한번씩 실행시키면 된다.

리눅스에서 파티션들은 그들이 속해 있는 드라이브를 바탕으로 한 이름이 주어진다. 예를 들어 드라이브 /dev/hda의 첫 번째 파티션은 /dev/hda1, 두 번째는 /dev/hda2 ... 등으로 이름이 주어진다. 만약 어떠한 로지컬 파티션을 가진다면 그것들은 /dev/hda5에서 시작하여 /dev/hda6 등의 순서로 이름이 붙여진다.

NOTE: 리눅스 fdisk 또는 cfdisk로는 리눅스외의 오퍼레이팅 시스템을 위한 파티션을 만들거나 지우면 안된다. 즉, 리눅스 버전의 fdisk를 사용하여 MS-DOS 파티션을 만들거나 지우지 말라. 대신에 MS-DOS 버전의 FDISK를 사용하기 바란다. 리눅스 fdisk 로 MS-DOS 파티션을 만들려고 한다면 아마 MS-DOS는 그 파티션을 인식하지 못할 것이고 부팅이 올바로 되지 않을 것이다.

여기에 fdisk 사용의 예가 있다. 드라이브에 61693 블록을 사용하는 하나의 MS-DOS 파티션을 가지고 있고 드라이브의 그 나머지는 리눅스를 위하여 남겨둔 것이다. (리눅스하에서 1블럭은 1024바이트, 그러므로 61693블럭은 대략 61메가 바이트) 두 개의 리눅스 파티션을 만들려 한다고 하자. 하나는 스왑, 다른 하나는 루트 파일시스템을 위한 것이다. 이 예를 응용하면 저 위에서 추천한 네개의 파티션 만들기를 할 수 있을 것이다: 하나는 스왑, 하나는 루트 파일시스템, 하나는 시스템 소프트웨어 (/usr), 나머지 하나는 홈 디렉토리.

먼저, 현재 파티션 테이블을 표시하기 위해 명령어 "p"를 사용한다. 보다시피, /dev/hda1은 (/dev/hda의 첫 번째 파티션) 61693블럭의 도스 파티션이다.

Command (m for help): p

Disk /dev/hda: 16heads, 38 secrors, 683 cylinders

Units = cylinders of 608 * 512 bytes

Device Boot Begin Start End Blocks Id System

/dev/hda1 * 1 1 203 61693 6 DOS 16-bit >=32M

Command (m for help):

그 다음에 명령어 "n"을 사용하면 새로운 파티션을 생성시킬 수 있다. 리눅스 루트 파티션의 크기를 80 메가로 할 것이다.

Command (m for help): n

Command action

e extended

p primary partition (1-4)

p

extended 혹은 primary 파티션을 생성할 것인지 물어볼 것이다. 대부분의 경우. 한 개의 드라이브에 네 개이상의 파티션을 팔요로 하지 않는다면 primary 파티션을 사용하려 할 것이다. 더 자세한 것은 저 위의 "Repartitioning" 절을 참고하기 바란다.

Partition number (1-4): 2

First cylinder (204-683): 204

Last cylinder or +size or +sizeM or +sizeK (204-683): +80M

첫 번째 실린더는 마지막 파티션이 끝난 뒤의 실린더가 되어야 한다. 이 경우에 /dev/hda1은 실린더 203에서 끝났다. 그래서 실린더 204에서 새로운 파티션이 시작된다.

보다시피, "+80M" 이라고 표기를 한다면 그것은 크기가 80메가인 파티션을 규정하는 것이다. 유사하게, "+80K" 라는 표기는 80킬로바이트 파티션을 규정한다. 그리고 "+80"은 단지 80바이트 파티션을 규정한다.

Warning: Linux cannot currently use 33090 sectors of this partition

여러분이 위와 같은 경고문을 보게 된다면 무시해도 좋다. 리눅스 파일시스템의 크기가 64 메가 이상일 수 없었던 오래전의 한계에서부터 연유된것일 뿐이다. 오늘날의 파일시스템 타입에 적용되는 것이 아니다. 오늘날 파티션들의 크기는 4테라바이트까지 가능하다.

다음엔 10메가 스왑 파티션, /dev/hda3 을 생성한다.

Command (m for help): n

Command action

e extended

p primary partition (1-4)

p

partition number (1-4): 3

First cylinder (474-683): 474

Last cylinder or +size or +sizeM or +sizeK (474-683): +10M

다시 한번, 파티션 테이블의 내용을 표시한다. 여기에 있는 정보를 기록하여 확인하기 바란다. 특히 각 파티션의 크기가 몇 block 인지를 확인한다. 나중에 이 정보가 필요하다.

Command (m for help): p

Disk /dev/hda: 16 heads, 38 sectors, 683 cylinders

Units = cylinders of 608 * 512 bytes

Device Boot Begin Start End Blocks Id System

/dev/hda1 * 1 1 203 61693 6 DOS 16-bit >=32M

/dev/hda2 204 204 473 82080 83 Linux native

/dev/hda3 474 474 507 10336 83 Linux native

리눅스 스왑 파티션은 (여기에서는 /dev/hda3) "Linux native" 라는 타입을 갖고 있다는 것에 주의해라. 이를 "Linux swap" 이라는 타입명으로 바꾸어야 하며 그렇게 하므로서 설치 프로그램이 스왑 파티션의 타입을 "Linux swap"으로 인식하도록 해야한다. 그렇게 하기위해 fdisk 에 "t" 라는 명령어를 사용하도록 한다.

Command (m for help): t

Partition number (1-4): 3

Hex code (type L to list codes): 82

"L"을 사용한다면 타입 코드 목록을 보여줄 것이고, 82가 리눅스 스왑과 일치하는 타입이라는 것을 알 수 있을 것이다.

파티션 테이블의 변경 사항을 저장하고 fdisk를 빠져나오려면 명령어 "w", 저장하지않고 그만두려면 "q"를 사용한다.

fdisk를 끝낸후에 바뀐 것이 효력을 발휘하도록 시스템이 여러분에게 재부팅 할건지 확인할지도 모른다. 일반적으로 fdisk를 사용한 후엔 재부팅할 이유가 없다. 요즘의 fdisk 와 cfdisk 버전은 재부팅하지 않고서도 바뀐 파티션 내용을 충분히 갱신할 수 있다



---------------------------------------------------------------------------------------


출처 카페 > 리눅스 웹마스터 키우기 / 리눅서
원본 http://cafe.naver.com/k2linux/39

리눅스 설치시 전문가용으로 fdisk 라는 파티션 프로그램을 볼 수 있다. 이 프로그램은 디스크 드루이드(Disk Druid)보다 더 세밀한 파티션 설정이 가능하다는 면에서 아주 유용하다. 특히 리눅스를 여러개 설치할 때에나 두 번째 이후의 파티션에 설치할 때에 Primary 파티션을 여러개 두고 싶다면 fdisk를 사용해야 한다. 그러면, 이 프로그램에 대한 사용법에 대해서 알아보도록 한다.


1. fdisk의 시작

fdisk를 이용해 새로운 파티션의 생성, 기존 파티션의 삭제, 파티션의 타입 결정 등의 작업을 수행할 수 있다. 그런데, 래드헷 계열의 배포판은 설치시 대부분 Disk Druid 유틸리티를 이용해서 파티션을 분할한다. 그렇지만, 전통적으로 fdisk를 사용하며 이것은 디스크 드루이드보다 유연하기 때문에 아직도 설치시에 이 프로그램을 사용한다.

fdisk 프로그램은 한번에 한 디스크에 대해서만 작업을 수행한다. fdisk는 명령어 프롬프트 중심의 매우 간단한 인터페이스를 가지고 있다. 그러면 fdisk를 실행해 보자.

# fdisk [Hard disk device]


fdisk를 실행하기 위해서는 어떠한 디스크의 파티션을 나눌 것인지 알려 주어야 한다. 즉 하나의 컴퓨터에 여러 개의 하드디스크가 설치될 수 있으므로 어떤 하드디스크의 파티션을 변경할 것인지 알려 주어야 한다.

fdisk /dev/hda를 실행하면 (파티션을 생성/삭제할 하드디스크가 IDE1의 마스터 드라이브일 경우) 다음과 같은 화면을 볼 수 있다.

# fdisk /dev/hda



그러면 다음과 같은 도입 화면이 나올 것이다.


fdisk는 독자적인 명령어를 가지고 있다. 도움말을 원한다면 간단하게 m 명령어를 통해 얻을 수 있다. 그리고, 이 정보만 보고서도 충분히 파티션을 할 수 있을 것이다. 다음은 이 명령을 사용했을 때 나오는 명령에 대한 해설이다.

명 령

기 능

a부트 가능한 플래그로 변경
bbsd 디스크 레이블을 편집
c도스 호환 플래그로 변경
d파티션 삭제
l알려진 파티션 형태의 목록
m이 메뉴를 출력
n새로운 파티션 추가
o새로운 도스 파티션 테이블을 생성
p파티션 테이블을 출력
q변경을 저장하지 않고 종료
s새로운 Sun 디스크 레이블을 생성
t파티션의 시스템 id를 변경
u표시/엔트리 단위를 변경
v파티션 테이블을 점검
w디스크에 테이블을 기록하고 빠져나감


2. fdisk 명령어

다음은 fdisk 명령어에 대한 것들을 알아보자. 일단 많이 사용되는 명령어부터 해서 각각의 명령어들의 사용법에 대해서 알아보도록 한다.

  • m - 도움말

    이 명령어를 입력하면 fdisk는 Command(m for help): 라는 프롬프트를 보여주며 명령을 기다린다. m을 입력하면 다음과 같은 도움말을 볼 수 있다. 명령어를 전체적으로 외우기가 그렇게 쉬운 일만은 아니므로 이 명령어를 자주 사용하게 될 것이다.


  • p - 파티션 현황

    선택한 디스크에 있는 기존의 파티션 현황을 보기 위해서는 p를 입력하면 된다. 만약 기존에 파티션이 있고 파티션을 새로 만들어야 한다거나 만들어야 할 파티션이 많은 경우에 파티션 상태를 확인하는데 사용된다. 만약 기존의 모든 파티션을 하나씩 없애고 싶다면 d 명령어와 함께 제거하고자 하는 파티션의 번호를 입력하면 된다.


  • n - 파티션 생성

    새로운 파티션을 만들려면 n 명령어를 사용한다. 파티션 생성을 위해 우선 다음과 같이 n을 입력한다.

    Command (m for help): n

    다음에 나오는 선택 사항에서 우선 Primary 파티션을 만들어야 하므로 p를 입력한다. 4개 이상의 파티션을 만들고 싶을 경우에만 확장 파티션이 필요하다.

    Command action
      e extended
      p primary partition ( 1-4 )

    그 다음 프롬프트에서는 파티션 번호를 선택한다.

    Partition number ( 1-4 ) : 1

    첫 번째 파티션 이라면 1을, 두 번째는 2를 입력한다. 다음에는 파티션의 시작 블록 번호를 입력해야 한다. 괄호 안에 있는 숫자는 파티션에 사용할 수 있는 블록의 범위이다. 이번 파티션이 첫 번째 파티션이면 1을 시작 블록으로 한다.

    First cylinder ( 1-1024 ) : 1

    크기가 80Mbyte 인 파티션을 만들고 싶으면 바이트, 킬로바이트, 메가바이트로 크기를 지정할 수 있다.

    Last cylinder or +size or +sizeM or + sizeK ([1]-1024): +80M

    파티션이 잘 만들어 졌는지 확인을 해야 한다. 파티션 정보를 보려면 명령어 p를 사용한다.

    앞서 extended 파티션은 도스와는 조금 다르게 FDISK와 같이 4개 이상의 파티션을 만들기 위해 사용된다. 도스에서는 Primary 이외의 파티션을 모두 extended에 두지만 리눅스에서는 4번째 파티션을 extended로 잡고 아래에 다시 4개의 파티션을 만들 수 있다. 파티션 번호는 extended 파티션 번호 다음 번호부터 다시 잡힌다.

  • a - 부트 파티션 지정

    알맞게 파티션을 나눈 후에 부트파티션을 지정해 주어야 한다. 대부분 첫 번째 Primary 파티션을 부트파티션으로 잡는다. 프롬프트에서 다음과 같이 입력한다.

    Command(m for help) : a
    Partition number (1-6) : 1

  • d - 삭제

    삭제해야 할 파티션이 있다면 d 명령을 사용하여 삭제할 수 있다. 다음과 같이

    Command (m for help): d
    Partition number (1-8): [파티션 번호]

  • t 파티션의 시스템 id를 변경

    만들어진 파티션의 시스템 id는 기본적으로 83번으로 Linux 파티션이다. 그렇지만, 경우에 따라서 Dos 파티션을 만들어야 하는 경우도 있고 swap 파티션을 만들어야 하는 경우도 있다. 이 경우에 시스템 id를 변경해 주기 위해서 t 명령어를 사용한다. 다음은 t 명령어를 사용해서 83번으로 되어 있던 시스템 id를 82번으로 바꾼 예제이다.


  • l - 알려진 파티션 형태의 목록

    앞서 t 명령어를 사용할 때 시스템 id의 정보를 알아보기 위해서는 l 명령어를 사용한다.


  • w - 저장 후 종료

    일련의 작업이 끝난 후 실제로 반영시키기 위해서 w명령으로 변경 내용을 저장한 후 종료한다. 만약 새로 파티션을 생성하는 경우라면 재부팅을 해야 새로운 파티션이 인식이 된다. 그러므로, 포맷을 하기 위해서는 컴퓨터를 재부팅한다.


  • q - 저장하지 않고 종료

    실수로 파티션을 삭제하거나 잘못 설정한 경우에는 q 명령으로 변경 내용을 반영하지 않고 종료하거나 Ctrl + C키를 눌러 강제 종료 시켜야 한다.

    다음과 같이 q 명령을 내리면 그대로 fdisk가 종료된다.

    Command (m for help): q

  • b - bsd 디스크 레이블을 편집

    만약 컴퓨터가 알파 시스템이라면 bsd 디스크 레이블로 파티션을 편집해야 할 수도 있다. 이 경우에 b 명령어로 그렇게 할 수 있도록 환경을 변경해 주어야 한다. 이후의 파티션을 잡는 방식은 앞서와 같다.


[파티션 복구]


리눅스의 fdisk는 Windows 시스템의 fdisk와 달리 잘못 사용한 경우에 복구가 가능하다. 우선 이전의 실린더 숫자를 적어 두고 파티션을 나눈다. 그러면, 파티션을 잘못하고 저장한 경우 다른 시스템에 연결하여 실린더를 맞추어 이전의 것을 복구할 수 있다. 이것은 보안을 위해서도 사용될 수 있는데, 하드디스크의 실린더 숫자를 적어 놓고 파티션을 다르게 해버리면 파일시스템을 제대로 사용할 수 없게 된다. 이렇게 실린더 숫자를 적어 두는 것은 불시의 사고에 대비하는 방법이기도 한데, 만약 fdisk를 하면서 실수로 잘못 저장한 경우에 이전의 실린더 번호대로 복구하면 이전 상태 그대로 된다.


3. 파티션 요령과 fdisk 사용

fdisk를 이용해서 서버로 사용될 시스템의 파티션을 나눠 보도록 하자. 하드 디스크를 분할하는 것에는 일정한 공식은 없지만, 각각의 파일시스템에 사용될 파티션은 하드 디스크의 퍼센트보다는 각각의 사용 용량에 따라서 나눠 준다.

다음은 파일시스템에 따른 파티션 용량이다.

  • / - 300메가. 만약 위와 같이 각각을 모두 나눠서 파티션 한다면 /는 큰 용량이 필요 없다. 만약 하나의 세 개의 파티션으로 나눠야 한다면 /home, /, swap으로 나눠 주는 것이 좋다. 그리고, 이 경우라면 이 파티션은 약 3기가 정도의 크기여야 한다. 그리고, 이 경우에 /home 파티션은 크면 클수록 좋다.
  • /boot - 50메가. 50~60메가 정도로 잡는다. 아주 넉넉하게 100메가로 잡아도 상관 없다.
  • /var - 2기가. 서버로 사용하는 경우 메일 서버의 스풀과 메일 박스가 있는 장소로 충분히 크게 잡으면 좋다. 만약 이것이 없다면 300~500메가로 정도로 잡아도 상관 없고 파티션을 나누지 않아도 무관하다. 그렇지만 개인적으로 메일 서버롤 돌려야 하는 상황이라면 메일 박스를 홈디랙토리로 옮겨서 잡아주는 방법도 있다.
  • /usr - 2기가 이상. 이곳에는 온갖 잡다한 것들이 다 들어 간다. 처음 설치시 시스템에서 가장 많은 용량을 차지하는 곳이고 이후에 프로그램 설치시 이곳에 저장이 된다. 말하자면 윈도우즈 시스템의 Program Files 디랙토리와 windows 디랙토리의 일부를 합쳐 둔 것과 비슷하다. 사실 2기가로도 부족한 면이 있지만 많은 프로그램들을 운영할 계획이 없다면 이정도면 괜찮다. 만약 하드 디스크를 다시 분할하기 어렵고 각각의 파티션이 1.6기가 정도라면 /, /usr/share 정도로 나눠주면 된다. 처음 설치시 /usr/share의 용량은 상당히 크기 때문이다. 이후에 이것을 적당히 다시 조정할 수도 있을 것이다.
  • /tmp - 500메가. 이 부분은 X Window 같은 프로그램이 돌아가거나 윈도우즈의 temp와 같은 역할을 위한 작업을 하기 위한 공간으로 사용됩니다. 따라서 이정도는 필요할 것입니다.
  • swap - 물리적 메모리의 두배 정도면 충분하다. 물리적 메모리를 넉넉하게 하는 것이 컴퓨터를 사용하는데 좋다.
  • /home - 나머지 용량의 모두를 잡는다, 홈파티션이 생각보다 많이 필요하다. 특히, 시스템이 데스크탑용이거나 사용자가 많은 서버의 경우에는 절대적으로 많은 용량이 필요할 것이다.

이외에 자신의 필요에 따라 백업용 파티션을 나누거나 일정한 파티션에 백업용 공간을 둘 수 있을 겁니다.

위와 같이 나누면 되지만 일단 /, /usr, /home, swap, /boot 정도로 파티션을 나눠본다.

우선 /boot를 만든다. 이곳에는 시스템 부트에 관계되는 파일들이 있게 된다. 따라서, 이 부분은 가장 앞부분에 위치하도록 하는 것이 좋다. 만약 시스템에 윈도우즈 시스템에 있고 /boot가 1024 실린더 다음에 위치하게 되는 경우라면 이 파티션을 먼저 앞에 잡아 두고 다음에 윈도우즈용 파티션을 잡아 두는 것이 무리가 없다. 물론 lba32 옵션으로 lilo를 MBR에 설치할 수는 있지만 이것보다는 /boot 파티션을 앞에 잡아 두는 것이 더 편하다.

다음은 n 명령어로 파티션을 생성하는 것이다. 먼저 n 명령을 내린 다음, p로 primary 파티션으로 지정하고 파티션 번호를 지정한다. 이후에 시작 실린더 번호를 지정하고 마지막 실린더를 지정하거나 크기를 지정하면 된다.


다음에는 /, /usr, /home. swap를 위한 파티션을 차례로 잡아준다. swap의 경우에는 반드시 t 명령으로 시스템 id를 82번 swap으로 바꿔 주어야 한다.

다음은 /를 위한 두번째 파티션으로 300M를 잡아주는 모습이다.


다음은 /usr을 위한 파티션으로 2500M를 잡아주는 모습이다.


다음은 확장 파티션을 잡는 모습이다.


다음은 확장 파티션 아래에 swap 파티션으로 500M를 잡고 /home 파티션으로 남은 모든 공간을 잡은 모습이다.


다음은 p 명령어로 파티션 현황을 확인한 모습이다.


다음은 마지막으로 swap 파티션의 시스템 id를 82번으로 변경한 모습이다.


만약 윈도우즈 시스템이 있다면 swap 파티션을 윈도우즈 시스템과의 중간에 두거나 윈도우즈 시스템과 약간의 간격을 두고 파티션을 해주는 것이 안전하다. 파티션을 할 때 주의할 점의 하나는 윈도우즈 시스템의 FDISK에서 확장 파티션으로 잡은 도스용 파티션에 리눅스를 설치하지 말라는 것이다. 이 경우에 윈도우즈에서 리눅스 파티션이 보이면서 제대로 읽지 못해 시스템에 문제가 생길 수 있다.

파티션 편집이 모두 끝났다면 w 명령으로 설정을 저장하고 fdisk를 종료한다.


2006/09/08 22:28 2006/09/08 22:28
이 글에는 트랙백을 보낼 수 없습니다
--tcp-flags
'!' 옵션을 사용한다면 이것 뒤에 두개의 단어를 사용한다. 첫번째 것은 검사하고자 하는 지시자 리스트의 마스크이다. 두번째 단어는 지시자에게 어떤것이 설정 될 것인지를 말해준다. 예를들어,

# iptables -A INPUT -s 192.168.1.1 --protocol tcp --tcp-flags SYN,RST,ACK,SYN -j DENY
192.168.1.1로 부터 tcp방식에 의한 접속 차단

--syn
이것은 '--tcp-flags SYN,RST,ACK,SYN'의 약어이다.

# iptables -A INPUT -p TCP -s 192.168.1.1 --syn -j DENY

--source-port or --sport
Source 포트

--destination-port or --dport
도착지 포트

*****UDP 확장
이 확장은 '--protocol udp'가 지정되고 적용이 저정되지 않으면 자동으로 적재된다. 이것은 '--source-port', '--sport', '--destination-port', '-dport'를 지원하고 내용은 TCP 설명에서 자세히 나왔다.

*****새로운 타겟

타겟의 다른 형태는 확장이다. 타겟 확장은 커널 모듈로 구성된다. 그리고 iptables 에 대한 선택적 확장은 새로운 명령행의 옵션을 제공한다. 기본적으로 넷필터 배포에 포함된 몇몇의 확장은 다음과 같다.

LOG
일치하는 패킷의 커널 로그를 제공한다. 이것은 부가의 옵션을 제공한다.

--log-level 레벨 숫자나 이름 지정
'debug' 'info', 'notice', 'warning', 'err', 'crit', 'alert', 'emerg' 이름은 각각 숫자 7 에서 0 에 대응된다.
--log-prefix 14자 까지의 문장을 지정

REJECT
이 모듈은 'DROP'과 같은 효과를 나타낸다. 다만, 'port unreachable' 이라는 에러 메세지를 ICMP 로 보낸다.

RETURN
RETURN은 한 체인의 끝으로 보내지는 것과 같은 효과가 있다. : 미리 만들어진 체 인의 경우 그 체인의 정책은 실행이다. 사용자 정의 체인의 경우 이 체인으로 점프 하는 규칙의 바로 다음인 이전 체인으로 이동한다.

QUEUE
QUEUE은 특별한 타겟으로, 사용자공간의 작업을 위해 패킷을 대기하도록 한다. 패킷 을 위해서 대기하고있는 것이 없다면(즉, 이 패킷을 다룰 프로그램이 아직 씌어져 있지 않다면) 패킷은 DROP 될 것이다.

***3.4 타겟 지정

이제 패킷에서 어떤 검사를 할 수 있는지를 알았다. 이제 우리의 검사에 일치 하는 패킷을 어떻게 할 것인지를 말하는 것을 알아야 한다. 이것을 규칙 타겟 이라고 한다.

두개의 이미 만들어진 단순한 타겟이 있다. : DROP 과 ACCEPT. 이미 이것에 대해서는 이야기를 한 적이 있다. 적용이 되는 패킷과 그것의 타겟이 위의 두 개중 하나라면 더이상의 참고할 규칙은 없다. : 패킷의 운명은 결정 되는 것 이다.

이미 만들어진 두개의 타겟외에 두가지 형태의 타겟이 있다.: 확장과 사용자 지정의 체인들 이다.

****사용자 지정의 체인들

ipchains로 부터 상속되는 iptables의 강력한 기능중의 하나는 능력되는 사용 자가 기존의 세개의 체인(입력, 출력, 포워드)외에 새로운 체인을 생성할 수 있다는 것이다. 모임의 결과 사용자 지정의 체인은 그것을 구분하기 위하여 소문 자로 나타낸다. (아래 전체 체인에 대한 작용 부분에서 어떻게 사용자 지정의 새로운 체인을 만드는지 기술할 것이다.)

타겟이 사용자 지정의 체인인 규칙에 패킷이 맞으면 패킷은 사용자 지정의 체인을 따라 움직이게 된다. 그 체인이 패킷의 운명을 결정하지 못하면 그리고 그 체인에 따른 이송이 끝나면, 패킷은 현제 체인의 다음 규칙으로 돌아온다.

그림을 보자. 두개의 체인이 있고 그것이 입력과 테스트라는 사용자 지정의 체인이 라고 가정하자.

         `INPUT'                         `test'
        ----------------------------    ----------------------------
        | Rule1: -p ICMP -j DROP   |    | Rule1: -s 192.168.1.1    |
        |--------------------------|    |--------------------------|
        | Rule2: -p TCP -j test    |    | Rule2: -d 192.168.1.1    |
        |--------------------------|    ----------------------------
        | Rule3: -p UDP -j DROP    |
        ----------------------------

192.168.1.1 로부터 와서 1.2.3.4 로 향하는 TCP 패킷이 있다고 가정한다. 이것은 입력 체인으로 들어온다. Rule1 을 검사한다. 맞지 않음. Rule2 맞음. 그것의 타겟 은 테스트, 고로 다음 검사할 규칙은 테스트의 시작이다. 테스트의 Rule1 이 맞다. 그러나 이것이 타겟을 지정하지 않는다. 그러므로 다음 규칙이 검사된다. Rule 2. 맞지 않다. 그 체인의 끝에 도달했다. 다시 입력 체인으로 돌아가서 Rule3 을 검사 한다. 그것도 맞지 않다.

여기서 패킷의 이동경로를 그림으로 나타냈다.

                               v    __________________________
        `INPUT'                |   /    `test'                v
       ------------------------|--/    -----------------------|----
       | Rule1                 | /|    | Rule1                |   |
       |-----------------------|/-|    |----------------------|---|
       | Rule2                 /  |    | Rule2                |   |
       |--------------------------|    -----------------------v----
       | Rule3                 /--+___________________________/
       ------------------------|---
                               v

사용자 지정의 체인에서 대를 사용자 지정의 체인으로 갈수 있다. (그러나 루프 를 돌수는 없다. 루프를 발견하게 되면 패킷은 DROP 된다.)

잘못 설정한 예 - 순서를 바꾸어야 정상적으로 작동할 것이다.
iptables -A input -p tcp --dport 0:1023 -j DROP
iptables -A input -p tcp --dport 80 -j ACCEPT

***3.5 전체 체인에 대한 작용.

iptables의 유용한 기능주 하나는 여러 관계가 있는 규칙을 하나의 체인속으로 그룹화 하는 것이다. 체인의 이름은 어떤 것을 사용할 수도 있으나 미리 만들어 진 체인과의 혼동을 막기 위하여 소문자를 사용하기를 권한다. 체인의 이름은 16 자 까지 가능하다.

****새로운 체인 생성

# iptables -N test

****체인 제거
'-X' 나 '--delete-chain' 사용

# iptables -X test
체인을 지우기 위해서는 체인이 비어있어야 하며 다른 규칙의 타겟이 아니어야 한다.

****체인 비우기
'-F' ('--flush') 사용

# iptables -F forward

체인을 지정하지 않으면 모든 체인의 규칙이 지워진다.

****체인 규칙 나열하기
'-L' 사용
예)
iptables -L INPUT
iptables -t nat -L

**4. NAT(Network Address Translation) 활용

***4-1 NAT 이란
SNAT(Source Nat), DNAT(Destination Nat)

[PREROUTING](DNAT) --> Routing ------------> [POSTROUTING](SNAT) -->
                        |                          ^
                        |                          |
+- local Process ----------+  

****NAT의 활용

*****예1)MASQUERADING
   iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

*****예2) 고정IP 하나로 내부호스트들에 대한 서비스하기

   # soribada & dialpad for Sung-ho
   iptables -A PREROUTING -t nat -p udp --dport 9068 -j DNAT --to 192.168.1.7:9068
   iptables -A PREROUTING -t nat -p udp --dport 9067 -j DNAT --to 192.168.1.7:9067
   iptables -A PREROUTING -t nat -p udp --dport 9066 -j DNAT --to 192.168.1.7:9066
   iptables -A PREROUTING -t nat -p udp --dport 9065 -j DNAT --to 192.168.1.7:9065
   iptables -A PREROUTING -t nat -p tcp --dport 51210 -j DNAT --to 192.168.1.7:51210
   iptables -A PREROUTING -t nat -p udp --dport 51200 -j DNAT --to 192.168.1.7:51200
   iptables -A PREROUTING -t nat -p udp --dport 51201 -j DNAT --to 192.168.1.7:51201
   iptables -A PREROUTING -t nat -p tcp --dport 51210 -j DNAT --to 192.168.1.7:51210
   iptables -A PREROUTING -t nat -p udp --dport 51200 -j DNAT --to 192.168.1.7:51200
   iptables -A PREROUTING -t nat -p udp --dport 51201 -j DNAT --to 192.168.1.7:51201

   # nanumi for Sung-ho
   iptables -A PREROUTING -t nat -p udp --dport 9292 -j DNAT --to 192.168.1.7:9292
   iptables -A PREROUTING -t nat -p tcp --dport 9292 -j DNAT --to 192.168.1.7:9292

   # Winamp broadcast for Sung-ho
   iptables -A PREROUTING -t nat -p udp --dport 8000 -j DNAT --to 192.168.1.7:8000
   iptables -A PREROUTING -t nat -p tcp --dport 8000 -j DNAT --to 192.168.1.7:8000

   # ftp for Bokyu
   iptables -A PREROUTING -t nat -p udp --dport 2100 -j DNAT --to 192.168.1.5:2100
   iptables -A PREROUTING -t nat -p tcp --dport 2100 -j DNAT --to 192.168.1.5:2100

   # telnet for Bokyu
   iptables -A PREROUTING -t nat -p udp --dport 2300 -j DNAT --to 192.168.1.5:2300
   iptables -A PREROUTING -t nat -p tcp --dport 2300 -j DNAT --to 192.168.1.5:2300

   # www for Bokyu
   iptables -A PREROUTING -t nat -p udp --dport 8080 -j DNAT --to 192.168.1.5:8080
   iptables -A PREROUTING -t nat -p tcp --dport 8080 -j DNAT --to 192.168.1.5:8080

*****예3) 투명프록시

111.111.111.112   <->   192.168.1.2
111.111.111.113   <->   192.168.1.3
111.111.111.114   <->   192.168.1.4

내부 호스트의 Gateway 192.168.1.1

/etc/network/interfaces
------------------------------------------------------------------------
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)

# The loopback interface
# automatically added whe upgrading
auto lo
iface lo inet loopback

# The first network card - this entry was created during the Debian installatio
# (network, broadcast and gateway are optional)
# automatically added whe upgrading

auto eth0
iface eth0 inet static
     address 111.111.111.112
     netmask 255.255.255.0
     broadcast 111.111.111.255
     network 111.111.111.0
     gateway 111.111.111.1

auto eth0:0
iface eth0:0 inet static
     address 111.111.111.113
     netmask 255.255.255.0
     broadcast 111.111.111.255
     network 111.111.111.0

auto eth0:1
iface eth0:1 inet static
     address 111.111.111.114
     netmask 255.255.255.0
     broadcast 111.111.111.255
     network 111.111.111.0

auto eth1
iface eth1 inet static
     address 192.168.1.1
     netmask 255.255.255.0
     broadcast 192.168.1.255
     network 192.168.1.0

auto eth1:0
iface eth1:0 inet static
     address 192.168.1.2
     netmask 255.255.255.0
     broadcast 192.168.1.255
     network 192.168.1.0
------------------------------------------------------------------------
*nat
-A PREROUTING -d 111.111.111.112 -j DNAT --to-destination 192.168.1.2
-A PREROUTING -d 111.111.111.113 -j DNAT --to-destination 192.168.1.3
-A PREROUTING -d 111.111.111.114 -j DNAT --to-destination 192.168.1.4    

-A POSTROUTING -s 192.168.1.2 -j SNAT --to-source 111.111.111.102
-A POSTROUTING -s 192.168.1.3 -j SNAT --to-source 111.111.111.103
-A POSTROUTING -s 192.168.1.4 -j SNAT --to-source 111.111.111.104

*****예4) 부하분산

RoundRobin 방식에 의한 부하분산
목적지 주소를 192.168.1.2 이나 192.168.1.3 또는 192.168.1.4로 바꾸기
iptables -t nat -A PREROUTING -i eth1 -j DNAT --to 192.168.1.2-192.168.1.4


**5. 시스템 부트시 초기화하기

위에서 적용하였던 여러가지 Rule들을 저장하거나 복구하는 도구로서 iptables-save 와 iptables-restore 가 있다.
간단한 예를 살펴보면
# iptables-save > myRule

아래는 생성된 myRule 파일이다.
------------------------------------------------------------------------------------
# Generated by iptables-save v1.2.3 on Sat Oct 27 15:06:49 2001
*nat
:PREROUTING ACCEPT [865:65046]
:POSTROUTING ACCEPT [4:752]
:OUTPUT ACCEPT [162:9841]
-A PREROUTING -p udp -m udp --dport 9068 -j DNAT --to-destination 192.168.1.7:9068
-A PREROUTING -p udp -m udp --dport 9067 -j DNAT --to-destination 192.168.1.7:9067
-A PREROUTING -p udp -m udp --dport 9066 -j DNAT --to-destination 192.168.1.7:9066
-A PREROUTING -p udp -m udp --dport 9065 -j DNAT --to-destination 192.168.1.7:9065
-A PREROUTING -p tcp -m tcp --dport 51210 -j DNAT --to-destination 192.168.1.7:51210
-A PREROUTING -p udp -m udp --dport 51200 -j DNAT --to-destination 192.168.1.7:51200
-A PREROUTING -p udp -m udp --dport 51201 -j DNAT --to-destination 192.168.1.7:51201
-A PREROUTING -p tcp -m tcp --dport 51210 -j DNAT --to-destination 192.168.1.7:51210
-A PREROUTING -p udp -m udp --dport 51200 -j DNAT --to-destination 192.168.1.7:51200
-A PREROUTING -p udp -m udp --dport 51201 -j DNAT --to-destination 192.168.1.7:51201
-A PREROUTING -p udp -m udp --dport 9292 -j DNAT --to-destination 192.168.1.7:9292
-A PREROUTING -p tcp -m tcp --dport 9292 -j DNAT --to-destination 192.168.1.7:9292
-A PREROUTING -p udp -m udp --dport 8000 -j DNAT --to-destination 192.168.1.7:8000
-A PREROUTING -p tcp -m tcp --dport 8000 -j DNAT --to-destination 192.168.1.7:8000
-A PREROUTING -p udp -m udp --dport 2100 -j DNAT --to-destination 192.168.1.5:2100
-A PREROUTING -p tcp -m tcp --dport 2100 -j DNAT --to-destination 192.168.1.5:2100
-A PREROUTING -p udp -m udp --dport 2300 -j DNAT --to-destination 192.168.1.5:2300
-A PREROUTING -p tcp -m tcp --dport 2300 -j DNAT --to-destination 192.168.1.5:2300
-A PREROUTING -p udp -m udp --dport 8080 -j DNAT --to-destination 192.168.1.5:8080
-A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.1.5:8080
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Sat Oct 27 15:06:49 2001
--------------------------------------------------------------------------------------
                                             
# iptables-restore myRule

위의 과정은 현재 설정되어 있는 Rule 을 myRule 파일에 저장하고 다시 저장되었던 Rule 을 복구하는 방법이다.
하지만 이러한 방법보다는 필자의 경우는 다음과 같은 형식의 스크립트를 /etc/init.d/myRule 이라는 스크립트로 만들어서 저장하고 Runlevel 2 에서 이를 적용하여 사용하고 있다.


----------------------------------------------------------------------------
/etc/init.d/myRule
#/bin/sh

case "$1" in
   start)
   echo "iptables myRule start"
   iptables-restore /etc/myRule.conf
stop)
   echo "iptables myRule stop"
   iptables -F
   iptables -t nat -F
   ;;
restart)
   echo "iptables stop"
   iptables -F
   iptables -t nat -F
   echo "iptables start"
   iptables-restore /etc/myRule.conf
esac
exit 0
----------------------------------------------------------------------------

스크립트에서는 myRule.conf 파일을 읽어서 시스템 부트시 설정을 복구하고 있다.
myRule.conf 파일을 만드는 법은 아마도 다 아시리라는 생각을 한다. ^^;
iptables-save 로 해서 만들경우의 단점은 아무래도 주석부분이 아닐까 한다.
즉 iptables-save로서 만든후에 부분부분 주석을 넣어놓는것도 좋은 방법중의 하나일 것이다.

**6. 방화벽 설정의 예

아래의 예는 조대원님(PCHarley)의 설정입니다. 참고로 첨부하였습니다.
----------------------------------------------------------------------
#!/bin/sh

###### TCP 변수 설정 ######

# 외부로 서비스할 데몬의 포트 지정
# 20 : ftp-data port
# 21 : ftp port
# 22 : ssh port
# 25 : smtp port
# 80 : http port
# 113 : auth ident port
TCP_ALLOWPORT="20 21 22 25 80 113"
TCP_DENYPORT=1024

# 특정 호스트에 특정 포트를 개방
# 선별적인 호스트에 대하여 선별적인 서비스 오픈과 DNS Zone Transfer를 위해
# 사용하면 편리 
# <호스트ip주소>:<포트> 형식으로 사용
#TCP_HOSTPERPORT=""

# 출발지 포트로 오픈을 결정
# 클라이언트 프로그램을 사용하기 위하여 1024 이하의 특정 포트를 개방
# 21 : ftp 서버 응답 포트
# 22 : ssh 서버 응답 포트
# 23 : telnet 서버 응답 포트
# 25 : mail 서버 응답 포트
# 43 : whois 응답 포트
# 53 : dns 서버 응답 포트
# 79 : finger 서버 응답 포트
# 80 : httpd 서버 응답 포트
# 110 : pop3 서버 응답 포트
# 113 : AUTH 서버 응답 포트
# 119 : nntp 서버 응답 포트
# 443 : https 서버 응답 포트
TCP_ALLOWSPORT="21 22 23 25 53 80 110 113 119 443"

###### UDP 변수 설정 #######

# UDP의 경우에는 이 프로토콜의 특성상 위험한 서비스가 많다.
# 이 프로토콜을 이용하는 서비스를 허용해야 할 경우에는 주의를 하는것이 좋다

# 외부로 서비스할 데몬의 포트
#UDP_ALLOWPORT=""
UDP_DENYPORT=1024

# 특정 호스트에 특정 포트를 개방
# 선별적인 호스트에 대하여 선별적인 서비스 오픈과 DNS Zone Transfer를 위해
# 사용하면 편리 
# <호스트ip주소>:<포트> 형식으로 사용
#UDP_HOSTPERPORT=""

# 출발지 포트로 오픈을 결정
# 클라이언트 프로그램을 사용하기 위하여 1024 이하의 특정 포트를 개방
# 53 : dns 서버 응답 포트
UDP_ALLOWSPORT="53"

###### 디폴트변수 설정 ######

IPTABLES=/sbin/iptables
IPADD="<ip Address>"

# 루트 권한으로 운영되는 포트들
PRIVPORTS="0:1023"

# 일반 권한으로도 운영될수 있는 포트들
UNPRIVPORTS="1024:65535"


# 리눅스 머신이 GATEWAY나 MASQ로 사용될 경우 spoof 공격이나 잘 알려진
# 위험한 주소로 부터 오는 공격을 막기 위한 변수 설정
LOOPBACK="127.0.0.0/8"
BROADCAST_SRC="0.0.0.0"
BROADCAST_DEST="255.255.255.255"
CLASS_A="10.0.0.0/8"
CLASS_B="172.0.0.0/8"
CLASS_C="192.0.0.0/8"
CLASS_D_MULTICAST="224.0.0.0/4"
CLASS_E_RESERVED_NET="240.0.0.0/5"

###### kernel tunable parameter ######

# 어떤 인터페이스에서도 ping 에 반응하지 못하도록
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

# 브로드캐스트, 멀티캐스트 주소에 ICMP 메세지 보내는것 막기.
# smuf 공격 방지
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# ip 소스 라우팅을 방지(디폴트로 0이 되어 있지만 확실하게 하기 위함)
# ip 소스 라우팅이 허용될 경우 모든 방화벽 설정이 필요없게 된다.
for f in /proc/sys/net/ipv4/conf/*/accept_source_route
do
  echo 0 > $f
done

# DOS(서비스 부인 공격)의 방법인 SYN Attack을 방지하기 위하여 TCP syncookies를 enable
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# icmp_redirect 메세지를 거부
for f in /proc/sys/net/ipv4/conf/*/accept_redirects
do
   echo 0 > $f
done

# gateway나 Masquerading 머신으로 사용한다면 이 옵션은 반드시 포함 하여야 한다.
# echo 1 > /proc/sys/net/ipv4/ip_always_defrag

# 정의되지 않은 에러 메세지를 막음
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

# ip sppof 방지
for pfile in /proc/sys/net/ipv4/conf/*/rp_filter
do
   echo 1 > $pfile
done

# Log Spoofed Packets, Source Routed Packets, Redirect Packets 등을 탐지하면 로그파일에 기록
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

##### 초기화 #####
# 호스트가 X 윈도도 깔리지 않은 서버용으로 운영될 경우에는 OUTPUT 기본 정책도
# DROP으로 하는것이 안전하다.
${IPTABLES} -F INPUT
${IPTABLES} -P INPUT DROP
${IPTABLES} -F OUTPUT
${IPTABLES} -P OUTPUT ACCEPT
${IPTABLES} -F FORWARD
${IPTABLES} -P FORWARD DROP

###### INPUT ######
###### TCP ######

# local loopback 허용
${IPTABLES} -A INPUT -i lo -j ACCEPT

# 1024 밑에 루트에 의해 서버가 사용할 포트 오픈
for values in ${TCP_ALLOWPORT}
do
   ${IPTABLES} -A INPUT -i eth0 -p tcp --dport ${values} -j ACCEPT
done

# 특정 호스트로의 포트를 개방
#for values in ${TCP_HOSTPERPORT}
#do
#   echo ${values} | {
#   IFS=':' read hosts ports
#        ${IPTABLES} -A INPUT -s ${hosts} -p tcp --dport ${ports} -j ACCEPT
#        }
#done

# 출발 포트가 초기 접속이 아닌 경우 허가된 포트에 대해서만 허가
for values in ${TCP_ALLOWSPORT}
do
   ${IPTABLES} -A INPUT -i eth0 -p tcp ! --syn --sport ${values} ! --dport ${PRIVPORTS} -j ACCEPT
done

# ftp 노말 모드의 경우 클라이언트에서 서버로 접속을 요청할 경우 서버의
# 20포트에서 클라이언트로 초기 접속을 요청하므로 20번 포트에서 초기 접속을
# 허가해줘야함 이는 일종에 보안 구멍을 유발 하므로 passive mode 나 proxy를
# 사용해서 이 hole을 막을는 것이 좋다
# 만약 일반 모드로의 접속을 허용해야 한다면 잘 알려진 위험한 포트를 제외한
# 나머지 포트로만 허용을 해야한다.

# open window 포트로의 서비스 요구 거부
${IPTABLES} -A INPUT -i eth0 -p tcp --sport 20 --dport 2000 -j LOG --log-prefix "To 20 From 2000 DROP"
${IPTABLES} -A INPUT -i eth0 -p tcp --sport 20 --dport 2000 -j DROP
# NFS 포트로의 서비스 요구 거부
${IPTABLES} -A INPUT -i eth0 -p tcp --sport 20 --dport 2049 -j LOG --log-prefix "To 20 From 2049 DROP"
${IPTABLES} -A INPUT -i eth0 -p tcp --sport 20 --dport 2049 -j DROP
# xwindow 포트로의 서비스 요구 거부
${IPTABLES} -A INPUT -i eth0 -p tcp --sport 20 --dport 6000:6010 -j LOG  --log-prefix "To 20 From 6000:6010 DROP"
${IPTABLES} -A INPUT -i eth0 -p tcp --sport 20 --dport 6000:6010 -j DROP

${IPTABLES} -A INPUT -i eth0 -p tcp --sport 20 --dport ${UNPRIVPORTS} -j ACCEPT

# 1024:65535 포트는 초기 접속이 아닌경우 허가 - ftp passive mode와 apt-get
# 에서 필요.
# 1023이하 허용할 출발 포트는 사용하는 클라이언트에 따라 위에서 직접 지정

${IPTABLES} -A INPUT -i eth0 -p tcp ! --syn --sport ${UNPRIVPORTS} --dport ${UNPRIVPORTS} -j ACCEPT

###### UDP ######

# 열어줄 포트 개방 1024 밑에 포트
# for values in ${UDP_ALLOWPORT}
# do
#     ${IPTABLES} -A INPUT -p tcp --dport ${values} -j ACCEPT
# done

# 특정 호스트로의 포트를 개방
# for values in ${UDP_HOSTPERPORT}
# do
#     echo ${values} | {
#     IFS=':' read hosts ports
#         ${IPTABLES} -A INPUT -s ${hosts} -p udp --dport ${ports} -j ACCEPT
#         }
# done

# 상대편 포트를 보고 허가
# UDP는 특성상 -syn같은 옵션으로 초기 접속을 제한할 수가 없다.
# 그렇기때문에 UDP 프로토콜에 대해서는 허가할 서비스에 대해 상당한 주의가
# 요망 된다.
for values in ${UDP_ALLOWSPORT}
do
   ${IPTABLES} -A INPUT -i eth0 -p udp --sport ${values} ! --dport ${PRIVPORTS} -j ACCEPT
done


# ICMP

# 죽음의 핑이라 불리는 DOS(서비스 거부)공격에 사용되는 프로토콜이다.
# 내부 호스트에 이익이 되는것만을 선별해서 허용해야 한다.

# echo-reply (pong) - 0
# destination-unreachable - 3
# source-quench - 4
# redirect - 5
# echo-request (ping) - 8
# time-exceeded (ttl-exceeded) - 11
# parameter-problem - 12

# icmp 패킷 유형중 echo-reply(0)를 허가함
# 이 호스트가 외부 호스트로 ping을 사용하기 위해 pong은 허가
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type echo-reply -j ACCEPT

# icmp 패킷 유형중 destination-unreachable(3) 을 허가함
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type destination-unreachable -j ACCEPT

# icmp 패킷 유형중 source-quench(4) 를 허가함
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type source-quench -j ACCEPT

#  host에서 실행하는 traceroute 를 허용하기 위해 icmp time-exceeded(11)을
# 허용
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type time-exceeded -j ACCEPT

# icmp 패킷 유형중 parameter-problem(12)을 허가함
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type parameter-problem -j ACCEPT



###### deny 정책 #######
# deny 정책을 하기전에 먼저 허가할 것을 명시해야만 한다.

# ping을 이용한 DOS 공격에 대비하여 echo-request를 거부
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type echo-request -j LOG --log-prefix "PING REJECT"
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type echo-request -j REJECT

# icmp-type redirect(5) 거부
# 이것이 허용되면 외부에서 이 호스트의 라우팅 테이블을 임의로 조작할 수가 있게 된다.
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type redirect -j LOG --log-prefix "icmp-type 5 DROP"
${IPTABLES} -A INPUT -i eth0 -p icmp --icmp-type redirect -j DROP

# 그외 허가 되지 않은 1023이하의 포트 모두를 막음
${IPTABLES} -A INPUT -i eth0 -p tcp --dport 1:${TCP_DENYPORT} -j LOG --log-prefix "Under 1024 Tcp DROP"
${IPTABLES} -A INPUT -i eth0 -p udp --dport 1:${TCP_DENYPORT} -j LOG --log-prefix "Under 1024 Udp DROP"
${IPTABLES} -A INPUT -i eth0 -p tcp --dport 1:${TCP_DENYPORT} -j DROP
${IPTABLES} -A INPUT -i eth0 -p udp --dport 1:${TCP_DENYPORT} -j DROP

# 외부에서 허가된 tcp 접속 요청 제외한 모든 tcp접속 요청을 거부함
${IPTABLES} -A INPUT -i eth0 -p tcp --syn -j LOG --log-prefix "TCP SYN REJECT"
${IPTABLES} -A INPUT -i eth0 -p tcp --syn -j REJECT


# 그밖의 확인할수 없는 패킷을 모두 DROP
${IPTABLES} -A INPUT -i eth0 -m state --state INVALID -j LOG --log-prefix "INVALID DROP"
${IPTABLES} -A INPUT -i eth0 -m state --state INVALID -j DROP


###### OUTPUT ######


# local loopback 은 모든 패킷을 허용
${IPTABLES} -A OUTPUT -o lo -j ACCEPT

#ICMP OUTPUT DROP
${IPTABLES} -A OUTPUT -o eth0 -p icmp --icmp-type echo-reply -j LOG --log-prefix "ICMP output DROP"
${IPTABLES} -A OUTPUT -o eth0 -p icmp --icmp-type destination-unreachable -j LOG --log-prefix "ICMP output DROP"
${IPTABLES} -A OUTPUT -o eth0 -p icmp --icmp-type time-exceeded -j LOG --log-prefix "ICMP output DROP"
${IPTABLES} -A OUTPUT -o eth0 -p icmp --icmp-type echo-reply -j DROP
${IPTABLES} -A OUTPUT -o eth0 -p icmp --icmp-type destination-unreachable -j DROP
${IPTABLES} -A OUTPUT -o eth0 -p icmp --icmp-type time-exceeded -j DROP


###### 사설 ip 및 기타 거부 ######
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_A} -j LOG --log-prefix "CLASS_A DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_A} -j LOG --log-prefix "CLASS_A DROP"
${IPTABLES} -A OUTPUT -o eth0 -s ${CLASS_A} -j LOG --log-prefix "CLASS_A DROP"
${IPTABLES} -A OUTPUT -o eth0 -d ${CLASS_A} -j LOG --log-prefix "CLASS_A DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_A} -j DROP
${IPTABLES} -A INPUT -i eth0 -d ${CLASS_A} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -s ${CLASS_A} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -d ${CLASS_A} -j DROP

${IPTABLES} -A INPUT -i eth0 -s ${CLASS_B} -j LOG --log-prefix "CLASS_B DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_B} -j LOG --log-prefix "CLASS_B DROP"
${IPTABLES} -A OUTPUT -o eth0 -s ${CLASS_B} -j LOG --log-prefix "CLASS_B DROP"
${IPTABLES} -A OUTPUT -o eth0 -d ${CLASS_B} -j LOG --log-prefix "CLASS_B DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_B} -j DROP
${IPTABLES} -A INPUT -i eth0 -d ${CLASS_B} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -s ${CLASS_B} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -d ${CLASS_B} -j DROP

${IPTABLES} -A INPUT -i eth0 -s ${CLASS_C} -j LOG --log-prefix "CLASS_C DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_C} -j LOG --log-prefix "CLASS_C DROP"
${IPTABLES} -A OUTPUT -o eth0 -s ${CLASS_C} -j LOG --log-prefix "CLASS_C DROP"
${IPTABLES} -A OUTPUT -o eth0 -d ${CLASS_C} -j LOG --log-prefix "CLASS_C DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_C} -j DROP
${IPTABLES} -A INPUT -i eth0 -d ${CLASS_C} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -s ${CLASS_C} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -d ${CLASS_C} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -d ${CLASS_C} -j DROP
${IPTABLES} -A INPUT -i eth0 -s ${LOOPBACK} -j LOG --log-prefix "INPUT loopback DROP"
${IPTABLES} -A OUTPUT -o eth0 -s ${LOOPBACK} -j LOG --log-prefix "INPUT loopback REJECT"
${IPTABLES} -A INPUT -i eth0 -s ${LOOPBACK} -j DROP
${IPTABLES} -A OUTPUT -o eth0 -s ${LOOPBACK} -j REJECT

${IPTABLES} -A INPUT -i eth0 -s ${BROADCAST_DEST} -j LOG --log-prefix "Broadcast_dest DROP"
${IPTABLES} -A INPUT -i eth0 -d ${BROADCAST_DEST} -j LOG --log-prefix "Broadcast_src DROP"
${IPTABLES} -A INPUT -i eth0 -s ${BROADCAST_DEST} -j DROP
${IPTABLES} -A INPUT -i eth0 -d ${BROADCAST_DEST} -j DROP

# class D multicast address 거부
# multicast 는 소스 주소로는 불법
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_D_MULTICAST} -j LOG --log-prefix "class D Multicast DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_D_MULTICAST} -j DROP

${IPTABLES} -A INPUT -i eth0 -s ${CLASS_E_RESERVED_NET} -j LOG --log-prefix "class E reserved net DROP"
${IPTABLES} -A INPUT -i eth0 -s ${CLASS_E_RESERVED_NET} -j DROP

# refuse addresses defined as reserved by the IANA
# 0.*.*.*, 1.*.*.*, 2.*.*.*, 5.*.*.*, 7.*.*.*, 23.*.*.*, 27.*.*.*
# 31.*.*.*, 37.*.*.*, 39.*.*.*, 41.*.*.*, 42.*.*.*, 58-60.*.*.*
# 65-95.*.*.*, 96-126.*.*.*, 197.*.*.*, 201.*.*.* (?), 217-223.*.*.*
${IPTABLES} -A INPUT -i eth0 -s 1.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 2.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 5.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 7.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 23.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 27.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 31.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 37.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 39.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 41.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 42.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 58.0.0.0/7 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 60.0.0.0/8 -j LOG --log-prefix "IANA reserved DROP"
${IPTABLES} -A INPUT -i eth0 -s 1.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 2.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 5.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 7.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 23.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 27.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 31.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 37.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 39.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 41.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 42.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 58.0.0.0/7 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 60.0.0.0/8 -j DROP

#65: 01000001    - /3 includes 64 - need 65-79 spelled out
${IPTABLES} -A INPUT -i eth0 -s 65.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 66.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 67.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 68.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 69.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 70.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 71.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 72.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 73.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 74.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 75.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 76.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 77.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 78.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 79.0.0.0/8 -j LOG --log-prefix "65-79 DROP"
${IPTABLES} -A INPUT -i eth0 -s 65.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 66.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 67.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 68.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 69.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 70.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 71.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 72.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 73.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 74.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 75.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 76.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 77.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 78.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 79.0.0.0/8 -j DROP

#80: 01010000   - /4 masks 80-95
${IPTABLES} -A INPUT -i eth0 -s 80.0.0.0/4 -j LOG --log-prefix "80-95 DROP"
${IPTABLES} -A INPUT -i eth0 -s 80.0.0.0/4 -j DROP

# 96: 01100000    - /4 makses 96-111
${IPTABLES} -A INPUT -i eth0 -s 96.0.0.0/4 -j LOG --log-prefix "96-111 DROP"
${IPTABLES} -A INPUT -i eth0 -s 96.0.0.0/4 -j DROP

#126: 01111110    - /3 includes 127 - need 112-126 spelled out
${IPTABLES} -A INPUT -i eth0 -s 112.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 113.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 114.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 115.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 116.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 117.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 118.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 119.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 120.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 121.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 122.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 123.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 124.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 125.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 126.0.0.0/8 -j LOG --log-prefix "112-126 DROP"
${IPTABLES} -A INPUT -i eth0 -s 112.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 113.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 114.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 115.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 116.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 117.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 118.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 119.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 120.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 121.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 122.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 123.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 124.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 125.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 126.0.0.0/8 -j DROP

#217: 11011001    - /5 includes 216 - need 217-219 spelled out
${IPTABLES} -A INPUT -i eth0 -s 217.0.0.0/8 -j LOG --log-prefix "217-219 DROP"
${IPTABLES} -A INPUT -i eth0 -s 218.0.0.0/8 -j LOG --log-prefix "217-219 DROP"
${IPTABLES} -A INPUT -i eth0 -s 219.0.0.0/8 -j LOG --log-prefix "217-219 DROP"
${IPTABLES} -A INPUT -i eth0 -s 217.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 218.0.0.0/8 -j DROP
${IPTABLES} -A INPUT -i eth0 -s 219.0.0.0/8 -j DROP

#223: 11011111    - /6 masks 220-223
${IPTABLES} -A INPUT -i eth0 -s 220.0.0.0/6 -j LOG --log-prefix "220-223 DROP"
${IPTABLES} -A INPUT -i eth0 -s 220.0.0.0/6 -j DROP

----------------------------------------------------------------------

**참고자료:
패킷필터링, 조대원
리눅스 2.4 패킷필터링 하우투, Rusty Russel
리눅스 2.4 NAT 하우투, Rusty Russel

2006/09/08 22:20 2006/09/08 22:20
이 글에는 트랙백을 보낼 수 없습니다
출처 블로그 > 세상이 끝나는날 까지 도전하자
원본 http://blog.naver.com/ksemmen/140012802343

로컬 호스트 시스템을 백업하는 방법으로는 tar 아카이브를 이용하여 묶거나 압축하는 방법이 있고, cpio, dump, dd 유틸리티를 이용하여 하드 디스크를 백업하는 방법이 있다.

이번호에서는 이러한 유틸리티를 사용하지 않고, 미러링(Mirroring) 기능을 이용하여 로컬시스템 또는 원격서버의 데이터를 그대로 복사하여 백업하는 방법에 대해서 알아봅니다......


# 1. 미러링(Mirroring)


     레드햇 리눅스 사이트의 다운로드 페이지에 보면 FTP 미러 사이트들이 많이 링크되어 있

     음을 발견할 수 있다. 미러 사이트는 주 사이트의 데이터를 그대로 옮겨와 주 사이트와 똑

     같은 서비스를 제공하는 것이다.  원격 서버의 데이터를 원본 그대로 복사해 와서 원격 서

     버와 똑같은 데이터 상태를 유지시키는 것을 미러링(Mirroring) 이라 하는데 다른 표현으로

     는 서버 동기화(server  syncronization)라고도 한다.

     미러링에 의해서 원격 서버의 데이터가 변하면 미러링 서버도 그에 따라서 변하게 되며

     항상 미러링 서버는 원격 서버의 동일한 데이터 상태를 유지하게 된다. 미러링은 로컬 시스

     템의 데이터를 백업할 때도 적용할 수 있으며 서버마다 동일한 데이터 구조를 유지하고자

     할 때 이 방법이 사용된다.


# 2. 미러링 도구(rsync)


     여러대의 서버를 분산하여 서버를 동기화하는데 rsync 유틸리티가 많이 사용된다.

     rsync는 루트의 권한없이 서버로부터 데이터로 빠르게 전송받을 수 있으며, 원격 서버와

     미러 서버와 전송 데이터를 비교하여 변화된 데이터를 저장할 수 있다.

     또한 SSH를 이용하면 rsync 서버가 구축되어 있지 않아도 미러링을 할 수 있는 이점이 있 

     다.     


# 3. rsync 설치


     레드햇 리눅스 9에서는 최신 버전의 rsync RPM 패키지를 지원하므로 간단히 RPM 패키지

     를 설치하여 사용한다. 그러면 우선, rsync 패키지가 설치되어 있는지를 확인해 본다...

     [root@localhost  root]#  rpm  -qa  |  grep  rsync

     rsync-2.5.5-4

     [root@localhost  root]#  _ ----->대기중인 커서를 의미함.

    

     상기 화면과는 달리 아무런 rsync 버전 정보가 표시되지 않는다면 rsync가 시스템에 설치 

     되어 있지 않는 것이므로, rsync-2.5.5-4.i386.rpm 패키지를 구해 다음과 같이 설치한다.

     설치전에 반드시 미리 구한 패키지가 있는 디렉토리로 들어간후 설치하는것을 잊지 말자.

     [root@localhost  RPMS]#  rpm  -ivh  rsync-2.5.5-4.i386.rpm

      준비  중...                           ############################ [100%]

           1 : rsync                        ############################ [100%]

     [root@localhost  RPMS]#  _

     @ [참고사항] - rsync RPM 패키지 설치시 의존성 오류가 나올때

                           rsync RPM 패키지는 redhat-lsb 패키지와 의존성을 가지므로, 설치시

                           의존성 오류가 나올 때는 redhat-lsb-1.3-1.i386.rpm을 먼저 설치한 후

                           에  rsync 패키지를 설치한다.


# 4. SSH를 이용한 원격 서버 데이터 미러링


      rsync 서버를 구축하지 않은 상태에서 rsync로 SSH를 이용하여 데이터를 백업하는 방법

      은 다음과 같다. rsync 사용법에 관한 자세한 것은 잠시 후에 살펴보기로 하자...


      rsync  -avzr  --delete  -e  ssh  원격서버:데이터경로  백업경로

      그러면  192.168.1.13 클라이언트에서 192.168.1.1 원격 서버의 FTP 데이터를 SSH를 이용

      하여 미러링하는 방법은 다음과 같다...

      [root@localhost  root]#  rsync  -avz  --delete  -e  ssh  192.168.1.1:/ftp/pub/redhat9/

       /mirror/redhat9

      root's  password:

      receiving  file  list  ...  done

      ./

      shrike-i386-disc1.iso

      shrike-i386-disc2.iso

      shrike-i386-disc3.iso

      wrote  64 bytes  read  1855717755 bytes  2449792.50 bytes/sec

      total  size  is  1855094784  speedup  is  1.00

      [root@localhost  root]#  _


      원격 서버의 주소와 미러링하고자 하는 데이터의 경로를 지정한 후에 -e  ssh 옵션을

      사용하여 원격 서버에 접속을 하게 되면 패스워드를 묻게 되는데, 원격 서버의 루트 패스

      워드를 입력한다. 만일 일반 사용자 계정으로 이 명령을 수행한다면 원격 서버에도 동일한

      계정이 존재하여야 하며, 원격 서버의 계정 패스워드를 입력한다.

      SSH로 원격 서버에 접속이 이뤄지면 rsync에 의해서 원격 서버의 데이터를 미러링 서버

      의 지정된 경로로 다운로드됨을 볼 수 있다.

      @ [ 참고사항 ] - SSH를 이용한 rsync 데이터 동기화를 위한 원격 서버의 환경

                              클라이언트에서 rsync로 SSH를 이용하여 원격 서버에 접속하기 전에

                              원격 서버는 반드시 SSH 서버가 작동하고 있어야 접속이 가능하다.

                              즉,  /etc/init.d/sshd  restart를 실행하여 클라이언트가 SSH 서버에 접

                              속할 수 있도록 미리 준비해 놓고 있어야 한다는 예기다....


# 5. rsync  서버 설정(/etc/rsyncd.conf)

     앞서 SSH를 이용하여 미러링을 하는 방법에 대해 알아보았다. SSH 서버가 구축되지 않은

     원격 서버에서는 클라이언트가 미러링할 수 있도록 rsync 서버를 구축해야 한다. rsync 서

     버의 설정 파일은 /etc/rsyncd.conf 파일인데, 이 파일은 자동으로 생성되지 않으므로 사

     용자가 직접 만들어 사용해야 한다.  이 파일의 설정 형식은 다음과 같다.


         [rsync 서비스명]

                       comment  =  rsync서버에 대한 설명

                       path  =  미러링될 데이터의 경로

                       uid  =  사용자 ID

                       gid  =  그룹 ID

                       use  chroot  =  yes  /  no

                       read  only  =  yes  /no

                       host  allow  =  아이피주소

                       max  connections  =  최대접속횟수

                       timeout  =  초단위의 시간


  ① [rsync 서비스명] : rsync 서비스의 이름(모듈명)이다. 사용자가 원하는 형태로 서비스명

                                 을 지정할 수 있다. 예) rh90

  ② comment : rsync 서비스에 대한 설명이다. 예) Red Hat Linux 9.0 Mirror

  ③ path : 미러링 서비스 될 데이터의 경로를 지정한다. 예) /data/linux90

  ④ uid, gid : 각각 파일 전송하는 사용자와 그룹의 아이디로, 익명 접속이 가능하도록 기본값

                   은 nobody로 설정되어 있으므로 이 값을 그대로 사용한다.

  ⑤ use chroot : path로 지정된 경로를  root 상위 디렉토리로 사용한다. 사용자가 다른 상위

                        디렉토리로 접근하지 못하도록 하기 위해서 보안상 필요로 하므로 yes로 설

                        정한다.

  ⑥ read only : 클라이언트가 서버에서 데이터만 다운로드 하는 경우에는 이 옵션을 yes로 설

                      정하여 읽기 전용 권한을 부여해야 한다. 만일 업로드가 가능하도록 하려면

                      no로 설정하지만 특별한 경우가 아니라면 yes로 설정한다.

  ⑦ host allow : 접속 호스트를 제한하지 않으면 누구나 데이터를 가져갈 수 있기 때문에 익

                        명의 FTP 미러 서버가 아니라면 보안상 rsync 서버에 접속 가능한 호스트의

                       아이피를 지정하는 것이 안전하다.

  ⑧ max connections : 동시에 접속 가능한 접속횟수를 설정한다. 무제한은 0으로 설정한다.

  ⑨ timeout : 클라이언트의 접속이 idle 상태에 있을 때 접속을 끊어버릴 시간을 설정한다.

                   기본값은 60초이다.


  다음은 지금까지 살펴본 설정을 가지고 작성한 /etc/rsyncd.conf 예제 설정 파일이다.

  [root@localhost  /]# cat  >  /etc/rsyncd.conf

  [rh9iso]

  comment = Red Hat Linux 9 ISO Mirror

  path = /data/ftp/pub/redhat9

  uid = nobody

  gid = nobody

  use chroot = yes

  read only = yes

  host allow = 192.168.1.13

  max connections = 5

  timeout = 60


  [root@localhost  /]#  _


# 6.  /etc/xinetd.d/rsync 설정


     rsync 서비스는 슈퍼데몬 xinetd에 의해서 작동하기 때문에 /etc/xinetd.d/rsync 파일을

     설정해 주어야 한다. RPM 패키지 설치시 이 파일이 제공되므로 이 파일 가운데에서 다음

     화면과 같이 disable = yes를 disable = no로 변경한다.


     -------------------------------------------------------------------------------

      root@localhost:/

     -------------------------------------------------------------------------------

     service rsync

     {

                disable              =  no

                socket_type        =  stream

                wait                  =   no

                user                  =  root

                server               =  /usr/bin/rsync

                log_on_failure     +=  USER ID

      }

      _ ----->대기중인 커서를 의미함.

      ~


      [영어][완성][두벌식]                                                11,0-1                     모두

      --------------------------------------------------------------------------------

      그런 다음 xinetd 슈퍼 데몬을 다시 실행하여 rsync서비스가 작동될 수 있도록 한다.

      [root@localhost   /]#  /etc/init.d/xinetd  restart

      xinetd  를 정지함 :                                                                              [   확인   ]

      xinetd  (을)를 시작합니다 :                                                                   [   확인   ]

      [root@localhost  /]#  _


      rsync 서비스는 873 서비스 포트를 이용하므로, 텔넷으로 이 포트로 접속하여 rsyncd 정

      보가 나오는지를 확인한다. 만일 접속이 이뤄지지 않는다면 방화벽을 점검하거나

      /etc/rsyncd.conf 파일의 설정이 정확한지를 체크한다.


      [root@localhost  /]#  telnet  localhost  873

      Trying  127.0.0.1...

      Connected to  localhost.localdomain  (127.0.0.1)

      Escape  character  is  '^]' .

      @RSYNCD:  26

      _ ----->대기중인 커서를 의미함.


# 7. rsync 사용법


     SSH를 이용하여 rsync 미러링하는 방법에서 간단히 명령의 쓰임에 대해서 이미 살펴봤다.

     그러면 rsync의 사용법에 대해서 자세히 알아보자.........


     rsync  [옵션]  rsync서버주소::서비스명 미러경로

     rsync에서 자주 사용되는  옵션은 -avzr이다. -a 옵션은 아카이브 모드이며, -v 옵션은

     처리과정을 화면상에 출력되도록 하는 것이고, -z는 전송시 압축모드이며, -r 옵션은 하위

     디렉토리를 의미하는 옵션이다. 그외 자세한 옵션은 man 페이지를 참고하자.

     그러면 rsync로 미러링하는 방법을 연습해 보기로 하자....^_^*


7-1. rsync 서비스 모듈(서비스명과 설명) 알아보기


       앞서 작성한 /etc/rsyncd.conf 예제 파일을 통하여 원격 rsync 서버에서 어떤 서비스를

       현재 제공하는지를 알아보고자 할 때는 다음과 같은 명령을 실행한다.


      rsync  서버주소::

      

      [root@localhost  root]#  rsync  192.168.1.1::

      rh9iso               Red Hat Linux 9 ISO Mirror

      [root@localhost  root]#  _    

      이 때 출력되는 것은 /etc/rsyncd.conf 파일에서 서비스명(모듈명)과 comment로 설정

      된 메시지이다. 


  7-2. 로컬 시스템 데이터 백업


        rsync를 이용하여 로컬 시스템의 데이터를 백업하려면 다음과 같은 명령을 사용한다. 


        rsync  -avzr  --delete  백업소스경로  백업될경로

        --delete 옵션은 rsync서버의 백업할 데이터와 클라이언트의 데이터와 비교하여 변경

        된 데이터를 추가하거나 삭제하고자 할 때 사용하는 데이터 비교 옵션이다.

        그러면 /rh9hwp 디렉토리에 있는 파일을 /mirror/rh9hwp_backup 디렉토리로 백업해

        보자.........

        [root@localhost  root]# rsync  -avzr  /rh9hwp/  /mirror/rh9hwp_backup

        building  file  list  ...  done

        created  directory  /mirror/rh9hwp_backup

        ./

        맨드레이크  9.1.hwp

        명령어사전  .hwp

        제1부설치편  (60-151p).hwp

        제2부 (152-731p).hwp

        제3부 (732-1115p).hwp

        wrote  36854994 bytes  read 100 bytes  1890004.82 bytes/sec

        total  size  is  42531514  speedup  is 1.15

        [root@localhost  root]#  ls  /mirror/rh9hwp_backup

        맨드레이크  9.1.hwp  제1부설치편 (60-151p).hwp     제3부 (732-1115p).hwp

        명령어사전  .hwp      제2부 (152-731p).hwp

        [root@localhost  root]#  _


         /mirror/rh9hwp_backup 디렉토리로 데이터가 백업되고 있음을 확인할 수 있다.


  7-3. 원격 서버의 데이터 백업


        rsync  -avz  서버주소::모듈명(서비스명)  백업될경로


        이번에는 원격 서버의 레드햇리눅스9 배포판 이미지 파일을 미러링을 해보자.... 먼저

        rsync 서버주소::를 실행하여 모듈명을 확인하여 원격 서버에 접속해 미러링되게 하면

        된다.


        [root@localhost  root]#  rsync  192.168.1.1::

        rh9iso               Red Hat Linux 9 ISO Mirror

        [root@localhost  root]#  rsync  -avz  192.168.1.1::rh9iso  /mirror/redhat9

        receiving  file  list  ...   done

        ./

        shrike-i386-disc1.iso

        shrike-i386-disc2.iso

        shrike-i386-disc3.iso

        wrote 118 byets  read 1855717775 bytes  4995202.94 bytes/sec

        total  size  is  1855094784  speedup  is  1.00

        [root@localhost  root]#  _

2006/09/08 22:19 2006/09/08 22:19
이 글에는 트랙백을 보낼 수 없습니다
Linux/SHELL  2006/09/08 22:12

아마 MS-DOS를 접해본 분이라면 와일드카드(wildcard, 유닉스에서는 glob pattern이라고 부른다)이라고 부르는 *?와 같은 기호에 익숙할 겁니다. a로 시작하는 모든 GIF 파일을 a*.gif와 같이 비슷한 파일명을 일일이 명시하지 않고 지정할 수 있습니다. 정규표현식(regular express, 줄여서 regexp, regex, re)도 MS-DOS의 *?와 같이 패턴을 기술하는 방식입니다. 그러나 정규표현식은 MS-DOS의 와일드카드와는 달리 파일명 뿐만이 아니라 파일 내용을 포함한 일반적인 용도로 사용이 가능하며, 그 기능도 더 강력합니다.

유닉스는 기본적으로 그래픽보다는 문자 기반 인터페이스를 제공하기 때문에, 문자들을 찾거나 다른 문자로 대체하는 도구인 정규표현식은 매우 중요합니다. 사실, 정규표현식을 모르고 유닉스를 사용하는 것이 가능할까란 의문이 들 정도로 정규표현식은 유닉스 사용과 관리의 많은 부분에 적용이 가능합니다. 우리가 자주 사용하는 편집기인 vi와 emacs, 자주 사용하는 도구인 grep과 sed와 awk, portable shell로 불리는 Perl, 자동으로 메일을 정리하는 procmail 등, 정규표현식은 유닉스의 거의 모든 도구와 관련이 있습니다. 개인적으로 뼈아픈 경험뒤에 "멍청하면 손발이 고생한다"는 격언(?)의 적절한 예로 정규표현식을 꼽습니다.

불행히도 도구마다 정규표현식을 지원하는 정도가 조금 차이가 나지만 몇번 시도해보면 이 차이를 알 수 있습니다. 그러면 기본적이고 광범위하게 쓰이는 정규표현식부터 하나씩 알아봅시다.


2. 정규표현식 기초

기본적으로 정규표현식은 다음 세가지로 구별할 수 있습니다.

  • 문자에 해당되는 부분
  • 앞의 해당되는 부분을 반복하는 부분
  • 문자에 해당되지않고 위치나 결합을 나타내는 부분

이제 MS-DOS의 *와 같이 특수한 의미를 가지는 문자들을 만나게 됩니다. 우리가 정규표현식을 배운다는 것은 이런 특수 문자들과 그들의 의미를 아는 것입니다.

2.1. 문자에 해당되는 부분

우선 보통 알파벳과 숫자 등은 그 문자 그대로를 나타냅니다. 물론 대소문자는 서로 구별됩니다.

$ egrep 'GNU' COPYING GNU GENERAL PUBLIC LICENSE freedom to share and change it. By contrast, the GNU General Public the GNU Library General Public License instead.) You can apply it to ...(생략)... $

위에서 egrep은 파일들에서 원하는 문자들을 찾는 도구입니다. (흔히들 사용하는 grep의 변종으로 grep보다 다양한 정규표현식을 사용할 수 있습니다.) 첫번째 아규먼트로 원하는 문자를 나타내는 정규표현식을 사용합니다. 여기서 GNU는 정규표현식으로 뒤에 나오는 파일들에서 G, N, U 세 문자가 연이어 나오는 경우를 찾습니다. 여기서 사용한 파일인 COPYING은 자유 소프트웨어 소스코드에서 쉽게 찾을 수 있는 GPL 조항입니다. 결과를 명확하게 하기 위해서 찾은 단어를 굵게 표시했습니다.

그런데 왜 GNU 주위에 따옴표를 했을까요? 여기서 따옴표는 정규표현식에서 쓰이는 *, ?, | 등의 문자들이 쉘에서도 특별한 기능을 하기때문에 이들 문자가 쉘에서 처리되지 않게하려고 필요합니다. 또, egrep 'modified work' COPYING와 같이 찾으려는 패턴에 공백이 포함된 경우에도 따옴표는 이들을 한개의 아규먼트로 처리합니다. 사실 위의 GNU에 따옴표는 필요없지만, 항상 규칙처럼 따옴표를 같이 사용하는 것을 권합니다.

어떤 특정한 문자가 아니라 가능한 여러 문자들을 지정할 수도 있습니다.

$ egrep '[Tt]he' COPYING The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public software--to make sure the software is free for all its users. This ...(생략)... $

위에서 [Tt]는 그 자리에 Tt가 나올 수 있음을 의미합니다. 이렇게 []안에 가능한 문자들을 적어줄 수 있습니다.

[a-z]와 같이 [] 안에 -를 사용하여 그 범위 안의 문자들도 지정할 수 있습니다. 예를 들어, [a-zA-Z0-9]는 영문 알파벳 대소문자와 숫자들을 모두 포함합니다. 또, [^a-z]와 같이 [] 처음에 ^를 사용하여 뒤에서 지정된 문자 이외의 문자를 지시할 수도 있습니다. 즉, 이는 영문 알파벳 소문자를 제외한 문자들을 의미합니다.

([a-z]에서 범위는 ASCII 코드값으로 a (97)에서 z (122)까지를 뜻합니다. 만약 [z-a]와 같이 큰 값을 앞에 쓰면 안됩니다. ASCII 코드값은 man ascii로 볼 수 있습니다.)

마지막으로 (보통 행바꿈 문자를 제외한) 어떤 문자에도 대응되는 .이 있습니다. (MS-DOS의 ?와 같습니다.)

$ egrep 'th..' COPYING of this license document, but changing it is not allowed. freedom to share and change it. By contrast, the GNU General Public software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to ...(생략)... $

이는 th 뒤에 두 문자가 나오는 경우를 찾습니다. 세번째 줄 끝에 This는 대소문자를 구별하기 때문에 패턴에 해당되지않고, the 에서 공백도 한 문자로 취급한 것을 주의하길 바랍니다. 위에서 program will individually obtain patent licenses, in effect making the와 같은 줄을 출력하지 않은 이유는 마지막 the에서 th와 그 뒤의 한 문자는 찾았지만 그 뒤에 문자가 줄바꿈 문자이기 때문에 조건이 만족되지않기 때문입니다.

2.2. 앞의 해당되는 부분을 반복하는 부분

여기서는 *, ?, +을 다룹니다.

*는 바로 앞의 문자를 0번 이상 반복해도 됨을 나타냅니다. 예를 들어, abc*

  • abccccccccc
  • abc
  • ab

를 모두 만족합니다. 여기서 주의해서 볼 것은 "0번 이상"이기 때문에 마지막 경우와 같이 앞의 문자가 안나와도 된다는 것입니다. (그래서 MS-DOS의 *은 정규표현식으로 .*입니다.)

*와 비슷하게, ?는 앞의 문자가 없거나 하나 있는 경우를 나타내고, +는 앞의 문자가 1번 이상 반복하는 경우를 나타냅니다. 그래서 a+aa*와 같습니다.

이제 abc 모두를 반복하고 싶다면 어떻게 해야 되는지 의문이 듭니다. 이 경우 (, ) 괄호를 사용하여 문자들을 묶어주면 됩니다. 그래서 (abc)*

  • abcabcabcabc
  • abc

를 모두 만족합니다. 마지막 예는 0번 반복한 경우로 어떤 문자도 없는 빈 경우입니다. 이제 앞에서 말한 "앞의 문자"라는 말을 정정해야 겠습니다. *, ?, +는 "앞의 문자"에 적용되는 것이 아니라 "앞의 단위"에 적용됩니다. 기본적으로 한 문자는 그 자체로 한 단위입니다. 그래서 abc*에서 *는 바로 앞 문자이자 단위인 c에 적용된 것입니다. 그러나 괄호로 문자들을 묶어서 단위를 만들 수 있고, (abc)*의 경우에 *는 앞의 단위인 abc에 적용된 것입니다.

주의
위에서 (abc)*가 0번 반복해서 어떤 문자도 없는 것을 나타낼 수 있음을 주의해야 합니다. 정규표현식에서 이런 경우 대상과 관계없이 패턴이 만족한 것으로 판단하기 때문에 egrep '(abc)*' COPYING와 같은 명령어는 COPYINGabc라는 부분이 없음에도 불구하고 모든 줄을 출력합니다. 즉, egrep '(abc)*' COPYING | wc -lwc -l COPYING은 같습니다.

또, 주의할 점은 정규표현식은 패턴을 만족시키는 가장 긴 부분을 찾는다는 점입니다. 즉, abababab에 대한 정규표현식 (ab)+ababab에 대응되지 않고 abababab 모두에 대응됩니다. 이런 행동은 어떻게보면 당연한 것이지만 주의를 하지않으면 문제가 생길 수도 있습니다. 예를 들어, compiler and interpreter<\B>에 대한 정규표현식 .*<\B>는 (의도했을) compiler을 찾지않고 compiler and interpreter<\B> 전체를 찾게 됩니다. 이를 해결하기 위해 [^<]*<\B>을 사용합니다. . 대신에 [^<]를 사용한 것처럼 찾는 대상을 제한하기 위해서 [^...] 형식을 자주 사용합니다.

2.3. 문자에 해당되지않고 위치나 결합을 나타내는 부분

여기서 다루는 ^, $, |는 앞에서와는 달리 특정 문자에 대응하지는 않지만, 위치나 결합의 중요한 기능을 합니다.

우선 ^는 줄의 처음을 뜻합니다.

$ egrep '^[Tt]he ' COPYING the GNU Library General Public License instead.) You can apply it to the term "modification".) Each licensee is addressed as "you". the scope of this License. The source code for a work means the preferred form of the work for ...(생략)... $

정규표현식의 마지막 문자가 공백임을 주의하길 바랍니다. 만약 이 공백이 없다면 Thesethemselves,로 시작하는 줄들도 찾게됩니다. 이렇듯 정규표현식을 적을 때는 자신이 찾길 원하는 부분을 빼먹거나, 자신이 원하는 부분 이외의 것을 포함하지 않도록 주의해야 합니다. 지금처럼 정규표현식을 입력하고 그 결과를 하나씩 살펴볼때는 문제가 없지만, 많은 경우 정규표현식은 스크립트로 많은 문서를 한꺼번에 처리할때 사용하기때문에 주의해야 합니다. 잘못 쓴 정규표현식때문에 원하는 결과를 얻지 못하는 것은 물론이고 원본까지 망치게 되는 경우가 있습니다.

^는 이렇게 [Tt]와 같이 특정 문자에 대응되지는 않지만 원하는 문자가 선택될 수 있게 도와줍니다. 반대로, $는 줄의 끝을 나타냅니다. 그래서 ^$과 같은 정규표현식은 빈 줄을 찾습니다.

|은 기호 앞뒤의 것 중 하나를 선택한다는 뜻입니다. 즉, 문서에서 this(This)나 that(That)을 찾는다면,

  • this|This|that|That
  • [tT]his|[tT]hat
  • [tT]his|hat - 틀림! 이 정규표현식은 [tT]hishat을 찾음.
  • [tT](his|hat)
  • [tT]h(is|at)

모두 가능합니다. 세번째와 네번째 경우에서 괄호의 기능을 알 수 있습니다.

2.4. 일반문자와 특수문자

아마도 지금쯤 ^이 두가지 의미로 쓰인다는 것이 이상해 보일 수도 있을 겁니다. 정규표현식에서 쓰이는 문자는 크게 일반문자와 특수문자로 나눠볼 수 있습니다. 여기서 특수문자란 앞에서 다룬 (순서대로) [, ], -, ^, ., *, ?, +, (, ), $, |과 같이 정규표현식에서 문자그대로의 의미로 해석되지 않는 문자들입니다. 반대로 특수문자가 아닌 문자는 일반문자로 G, N, U와 같이 문자그대로의 의미를 가집니다.

여기서 특수문자는 쓰이는 곳에 따라 다릅니다. 자세히 말하면, []안이냐 밖이냐에 따라 특수문자가 달라집니다.

우선 [] 밖에서는 -를 제외한, ^, ., *, ?, +, (, ), $, |이 특수문자입니다. 여기서 ^는 줄의 시작을 의미합니다.

그러나 [] 안에서는 -^만이 특수문자이고, 다른 문자들은 일반문자가 됩니다. 즉, [*?+]는 반복이 아니라 문자그대로 *?+ 중 하나를 뜻합니다. [] 안에서 (제일 앞에 나오는) ^는 뒤에나오는 조건을 만족하지 않는 문자를 찾는다는 의미가 됩니다.

2.5. 특수문자에 해당하는 문자 사용하기

그렇다면 찾으려는 부분에 특수문자가 포함되있다면 어떻게 할까요? 예를 들어 what?이라는 물음표로 끝나는 문자를 찾고 싶다고, egrep 'what?' ...이라고 하면 ?이 특수문자이므로 wha를 포함한 whale도 찾게 됩니다. 또, 3.14로 찾을때는 3+14 등도 찾게 됩니다.

특수문자가 [] 안과 밖에서 다르다는 점을 생각하여 각각의 경우를 살펴봅시다. 우선 [] 밖의 경우는,

  • \을 특수문자 앞에 붙이기. 예, what\?, 3\.14
  • []을 사용하기. 예, what[?], 3[.]14

첫번째 방법은 보통 escape라고 부르며, 특수문자 앞에 \을 붙여서 특수문자의 특수한 기능을 제거합니다. 두번째 방법은 [] 밖의 많은 특수문자들이 [] 안에서는 일반문자가 되는 점을 이용한 것입니다. 보통 첫번째 방법을 많이 사용합니다.

주의할 점은 첫번째 방법에서 사용하는 \가 뒤에 나오는 특수문자를 일반문자로 만드는 특수문자이기 때문에, 문자 그대로의 \을 나타내려면 \\을 사용해야 합니다. 물론 [\]도 가능합니다.

[] 안의 특수문자는 위치를 바꿔서 처리합니다. 먼저, ^[^abc]와 같이 처음에 나와야만 의미가 있으므로 [abc^]와 같이 다른 위치에 사용하면 됩니다. -[a-z]와 같이 두 문자 사이에서만 의미가 있으므로 [-abc][abc-]와 같이 제일 처음이나 마지막에 사용합니다.

(grep과 같이 도구에 따라 역으로 일반 문자앞에 \를 붙여서 특수문자를 만드는 경우가 있습니다. 아래 각 도구에 대한 설명 참고.)


3. 정규표현식 고급

고급이라고 제목을 붙였지만 여기서는 도구마다 차이가 나거나 없을 수도 있는 내용을 다룹니다.

3.1. 자세한 반복

반복하는 횟수를 자세히 조정할 수 있습니다.

  • {n} - 정확히 n번 반복. a{3}aaa와 같음.
  • {n,} - n번 이상 반복. a{3,}aaaa*와 같음.
  • {n,m} - n번 이상 m번 이하 반복. a{2,4}aaa?a?와 같음.

물론 (abc){2,4}같이 괄호로 반복할 단위를 지정할 수 있습니다. 여기서 {, }*, ?, +와 같이 특수문자임을 주의하길 바랍니다. (엄밀한 의미에서 }은 특수문자가 아닙니다.)

3.2. 기억하기

앞에서 여러 문자를 묶어서 단위로 만드는 괄호는 정규표현식으로 찾은 부분을 기억하여 다른 곳에서 사용할때도 사용합니다. 예를 들어, HTML 제목 테그는 (egrep에서) <[Hh]([1-6])>.*와 같이 찾을 수 있습니다. 여기서 ([1-6])(, )는 사이에 대응된 부분을 기억하여 (첫번째 기억된 내용을) \1에서 사용합니다. 즉, 2>Conclusion2>에서 외에

등은 만족하지 않습니다.

(...)은 여러번 사용할 수 있고 (심지어 겹쳐서도), \n은 기억된 n번째 부분을 지칭합니다. 순서는 기억이 시작되는 (의 순서입니다.

여기에서는 ()이 특수문자이고, 그냥 \(\)는 일반문자이지만, 도구에 따라 반대인 경우도 있습니다.

이 기능은 또 치환에서 자주 사용됩니다. 아래 vi와 sed 부분을 참고하길 바랍니다.

3.3. 단어 찾기

앞에서 the를 찾으면 the 외에 them 등도 같이 찾는 것을 보았습니다. 그러면 정관사 the만 찾으려면 어떻게 할까요?

간단히 정규표현식 앞뒤에 공백을 추가한 the 를 생각해 볼 수 있습니다. 그러나 이 정규표현식에는 두가지 문제가 있습니다. 첫번째는 탭(tab) 등 다른 공백문자가 있기 때문입니다. 두번째는 이 정규표현식으로 the가 줄 제일 앞이나 제일 뒤에 나오는 경우는 찾지 못하기 때문입니다. 물론 [], ^, $|를 복잡하게 결합하여 이들 경우를 모두 처리할 수 있는 정규표현식을 쓸 수 있지만, 자주 사용하는 표현이기 때문에 간단히 할 수 있는 방법이 마련되있습니다.

그것은 \<\>로, \<은 공백에서 공백이 아닌 문자 사이, \>는 공백이 아닌 문자에서 공백 사이의 위치를 나타냅니다. 즉, ^$와 같이 문자에 해당되지않고 위치만을 나타냅니다. 이제 해답은 \입니다.

3.4. 단축 표현들

정규표현식에는 이외에도 자주 사용되는 표현에 대한 단축된 형식을 제공합니다. 예를 들어, vim에서 \i는 (C 언어 인식자 이름에서 사용하는 문자인) [_a-zA-Z0-9]와 같습니다. 그러나 이런 단축된 형식은 도구에 따라 많은 차이가 나기때문에 관련 문서를 참고하길 바랍니다.

POSIX.2에서 정의한 단축 표현은 다음과 같습니다. (C 언어에서 에 선언된 is*() 함수와 비슷한 것을 알 수 있습니다.) 단축된 형식이 나타내는 정확한 값은 locale에 따라 변합니다. 여기서는 영어권에서 사용하는 값을 보입니다. 독일어의 움라우트(a)와 같이 다른 언어권에서는 다른 값을 가질 수 있습니다.

  • [:alnum:] - 알파벳과 숫자. [a-zA-Z0-9]
  • [:alpha:] - 알파벳. [a-zA-Z]
  • [:cntrl:] - 제어문자. ASCII 값으로 0x00-0x1F와 0x7F
  • [:digit:] - 숫자. [0-9]
  • [:graph:] - 제어문자와 공백을 제외한 문자. ASCII 값으로 0x21-0x7E
  • [:lower:] - 소문자. [a-z]
  • [:print:] - 제어문자를 제외한 문자. ASCII 값으로 0x20-0x7E
  • [:punct:] - [:graph:] 중에 [:alnum:]에 속하지 않은 문자. !, @, #, :, ,
  • [:space:] - space, tab, carriage return, new line, vertical tab, formfeed. ASCII 값으로 0x09-0x0D와 0x20
  • [:upper:] - 대문자. [A-Z]
  • [:xdigit:] - 16진수에 사용하는 문자. [0-9a-fA-F]

3.5. 눈으로 보는 정규표현식

정규표현식이 패턴을 찾는 과정을 시각적으로 보여주는 프로그램들이 있습니다.

4. 정규표현식 사용

이제 이런 정규표현식을 실제로 어떻게 사용하는지 알아봅시다. 평소에 많이 사용하는 vi, grep/egrep/fgrep, sed/awk의 예를 들어보겠습니다.

4.1. vi에서

vi에서 정규표현식은 ':'상태에서 사용합니다. (실제로 이 상태에서 실행하는 명령어는 ed나 ex라는 프로그램이 처리하게 됩니다. 그래서 보통 이 상태를 "ed-모드"라고 합니다.) 문서에서 원하는 패턴을 찾으려면, (커서 다음에서 찾을때) /패턴이나 (커서 전에서 찾을때) ?패턴을 사용합니다.

정규표현식은 문자치환과 결합하여 강력한 기능을 합니다. 문자치환 명령은 다음과 같습니다.

:범위s/변경전/변경후/수정자

"범위"는 명령이 실행될 범위를 나타내며, 보통은 현재 편집하고 있는 문서 전체를 지시하는 (첫번째 줄에서 마지막 줄까지를 뜻하는) 1,$나 줄여서 %를 사용합니다.

뒤에 "s"는 치환(substitute) 명령어입니다.

"변경전"과 "변경후"에 치환할 내용을 입력합니다. "변경전"에 정규표현식을 적습니다. 정규표현식으로 ., *, ^, $, [], \(...\), \<...\>, POSIX.2 단축 표현을 사용할 수 있습니다. 여기서 여러 문자를 묶여서 단위를 만들고 찾은 내용을 기억하는 특수문자가 \(, \)임을 주의해야 합니다. 반대로 (, )가 일반문자입니다. vim(VI iMproved)에서는 vi에 추가로 |, +, (?와 같은) =, {n,m}을 사용할 수 있지만, 앞에 \를 붙여야 합니다. 또, vim에는 \i, \k, \p, \s 등의 단축 표현들이 있습니다.

"변경후"에 \n&를 사용할 수 있습니다. \n는 "변경전"에서 n번째 \(...\)에 대응하는 부분이고, &는 "변경전"에 만족한 전체를 나타냅니다. 예를 들어, :%s/\([0-9][0-9]*\) \([Cc]hapter\)/\2 \1/는 문서에서 12 Chapter같은 부분을 Chapter 12와 같이 치환하고, :%s/F[1-9][12]*/&/g는 HTML 문서에서 "F1" ~ "F12"란 단어 모두를 굵은 체로 바꿉니다. (주의! &는 정규표현식의 특수문자는 아니지만 vi의 특수문자이므로, 문자그대로의 &를 사용하려면 대신 \&를 사용해야 한다.) 이외에도 (뒤를 모두 대문자로) \u나 (뒤를 모두 소문자로) \l같은 기능이 있습니다.

"수정자"는 치환 명령의 세부사항을 결정합니다. 필요한 것만 뒤에 적어주면 됩니다.

  • g (global) - 한 줄에서 정규표현식을 만족하는 부분을 여러개 찾았을 때 모두다 치환한다. 이 수정자를 사용하지 않으면 처음 것만 치환한다.
  • c (confirm) - 만족하는 정규표현식을 찾았을때 치환하기 전에 확인한다.
  • i (ignore-case) - 대소문자를 무시하고 찾는다. 즉, :%s/[aA][bB][cC]/XXX/ 대신에 :%s/abc/XXX/i를 사용할 수 있다.

마지막으로 주의할 점은 치환명령어가 / 문자로 각 부분을 구분하기때문에 "변경전"이나 "변경후"에 / 문자를 사용하려면 \/ 같이 써야합니다. 필요하다면 / 대신 다른 문자를 사용해도 됩니다. 예를 들어, :%s/\/usr\/local\/bin\//\/usr\/bin\//g 대신 :%s#/usr/local/bin/#/usr/bin/#g가 알아보기 더 쉽습니다.

4.2. grep/egrep/fgrep에서

grep은 Global Regular Expression Print(ed 명령어로 :g/re/p)의 준말로 입력에서 원하는 정규표현식을 찾는 명령어입니다. grep에는 egrep과 fgrep이라는 변종이 있습니다. 전통적으로 egrep은 grep 보다 더 다양한 정규표현식을 지원하고, fgrep은 정규표현식을 지원하지 않고 빨리 검색하기 위한 명령어입니다. GNU grep에서 egrep은 grep -E, fgrep은 grep -F와 같습니다.

grep과 egrep 모두 ., *, ?, +, {n,m}, ^, $, |, [], (...), \n, \<...\>, POSIX.2 단축 표현을 지원합니다. 단, grep은 ?, +, {, |, (, )를 일반문자로 보기때문에 특수문자로 사용하려면 앞에 \를 붙여야 합니다.

2006/09/08 22:12 2006/09/08 22:12
이 글에는 트랙백을 보낼 수 없습니다

thegrendel (at) theriver.com



차례

Part 1. 소개
1. 왜 쉘 프로그래밍을 해야 하죠?
2. #! 으로 시작하기
2.1. 스크립트 실행하기
2.2. 몸풀기 연습문제(Preliminary Exercises)
Part 2. 기초 단계
3. 종료와 종료 상태(Exit and Exit Status)
4. 특수 문자
5. 변수와 매개변수 소개
5.1. 변수 치환(Variable Substitution)
5.2. 변수 할당(Variable Assignment)
5.3. Bash 변수는 타입이 없다(untyped)
5.4. 특수한 변수 타입
6. 쿼우팅(quoting)
7. 테스트
7.1. 테스트(Test Constructs)
7.2. 파일 테스트 연산자
7.3. 비교 연산자(이진)
7.4. 중첩된 if/then 조건 테스트
7.5. 여러분이 테스트문을 얼마나 이해했는지 테스트 해보기
8. 연산자 이야기(Operations and Related Topics)
8.1. 연산자(Operators)
8.2. 숫자 상수(Numerical Constants)
Part 3. 중급 단계(Beyond the Basics)
9. 변수 재검토(Variables Revisited)
9.1. 내부 변수(Internal Variables)
9.2. 문자열 조작
9.3. 매개변수 치환(Parameter Substitution)
9.4. 변수 타입 지정: declaretypeset
9.5. 변수 간접 참조
9.6. $RANDOM: 랜덤한 정수 만들기
9.7. 이중소괄호(The Double Parentheses Construct)
10. 루프와 분기(Loops and Branches)
10.1. 루프
10.2. 중첩된 루프
10.3. 루프 제어
10.4. 테스트와 분기(Testing and Branching)
11. 내부 명령어(Internal Commands and Builtins)
11.1. 작업 제어 명령어
12. 외부 필터, 프로그램, 명령어
12.1. 기본 명령어
12.2. 복잡한 명령어
12.3. 시간/날짜 명령어
12.4. 텍스트 처리 명령어
12.5. 파일, 아카이브(archive) 명령어
12.6. 통신 명령어
12.7. 터미널 제어 명령어
12.8. 수학용 명령어
12.9. 기타 명령어
13. 시스템과 관리자용 명령어
14. 명령어 치환(Command Substitution)
15. 산술 확장(Arithmetic Expansion)
16. I/O 재지향
16.1. exec 쓰기
16.2. 코드 블럭 재지향
16.3. 응용
17. Here Documents
18. 쉬어가기
Part 4. 고급 주제들(Advanced Topics)
19. 정규 표현식(Regular Expressions)
19.1. 정규 표현식의 간략한 소개
19.2. Globbing
20. 서브쉘(Subshells)
21. 제한된 쉘(Restricted Shells)
22. 프로세스 치환(Process Substitution)
23. 함수
23.1. 복잡 함수와 함수의 복잡성(Complex Functions and Function Complexities)
23.2. 지역 변수와 재귀 함수(Local Variables and Recursion)
24. 별칭(Aliases)
25. 리스트(List Constructs)
26. 배열
27. 파일들
28. /dev 와 /proc
28.1. /dev
28.2. /proc
29. 제로와 널(Of Zeros and Nulls)
30. 디버깅
31. 옵션
32. 몇 가지 지저분한 것들(Gotchas)
33. 스타일 있게 스크립트 짜기
33.1. 비공식 쉘 스크립팅 스타일시트
34. 자질구레한 것들
34.1. 대화(interactive)형 모드와 비대화(non-interactive)형 모드 쉘과 스크립트
34.2. 쉘 래퍼(Shell Wrappers)
34.3. 테스트와 비교: 다른 방법
34.4. 최적화
34.5. 팁 모음(Assorted Tips)
34.6. 괴상한 것(Oddities)
34.7. 이식성 문제(Portability Issues)
34.8. 윈도우즈에서의 쉘 스크립팅
35. Bash, 버전 2
36. 후기(Endnotes)
36.1. 저자 후기(Author's Note)
36.2. 저자에 대해서
36.3. 이 책을 만드는데 쓴 도구들
36.3.1. 하드웨어
36.3.2. 소프트웨어와 프린트웨어
36.4. 크레딧
서지사항
A. 여러분들이 보내준 스크립트들(Contributed Scripts)
B. Sed 와 Awk 에 대한 간단한 입문서
B.1. Sed
B.2. Awk
C. 특별한 의미를 갖는 종료 코드
D. I/O와 I/O 재지향에 대한 자세한 소개
E. 지역화(Localization)
F. 샘플 .bashrc 파일
G. 도스(DOS) 배치 파일을 쉘 스크립트로 변환
H. 연습문제
I. Copyright
예 목록
2-1. cleanup: /var/log 에 있는 로그 파일들을 청소하는 스크립트
2-2. cleanup: 위 스크립트의 향상되고 일반화된 버전.
3-1. 종료/종료 상태
3-2. !으로 조건을 부정하기
4-1. 코드 블럭과 I/O 재지향
4-2. 코드 블럭의 결과를 파일로 저장하기
4-3. 최근 하루동안 변경된 파일들을 백업하기
5-1. 변수 할당과 치환
5-2. 평범한 변수 할당
5-3. 평범하고 재미있는 변수 할당
5-4. 정수? 문자열?
5-5. 위치 매개변수
5-6. wh, whois 도메인 네임 룩업
5-7. shift 쓰기
6-1. 이상한 변수를 에코하기
6-2. 이스케이프된 문자들
7-1. 무엇이 참인가?
7-2. [ ]test 의 동일함
7-3. (( ))로 산술식 테스트 하기
7-4. 산술 비교와 문자열 비교
7-5. 문자열이 인지 테스트 하기
7-6. zmost
8-1. 산술 연산자 쓰기
8-2. && 와 || 를 쓴 복합 조건 테스트
8-3. 숫자 상수 표기법:
9-1. $IFS 와 빈 칸
9-2. 타임 아웃 처리 입력
9-3. 타임 아웃 처리 입력, 한 번 더
9-4. 내가 루트인가?
9-5. arglist: $* 과 $@ 로 인자를 나열하기
9-6. 일관성 없는 $*$@의 동작
9-7. $IFS 가 비어 있을 때 $*$@
9-8. 밑줄 변수(underscore variable)
9-9. 그래픽 파일을 다른 포맷 확장자로 이름을 바꾸면서 변환
9-10. 매개변수 치환과 : 쓰기
9-11. 변수의 길이
9-12. 매개변수 치환에서의 패턴 매칭
9-13. 파일 확장자 바꾸기:
9-14. 임의의 문자열을 파싱하기 위해 패턴 매칭 사용하기
9-15. 문자열의 접두, 접미어에서 일치하는 패턴 찾기
9-16. declare를 써서 변수 타입 지정하기
9-17. 간접 참조
9-18. awk에게 간접 참조를 넘기기
9-19. 랜덤한 숫자 만들기
9-20. RANDOM 으로 주사위를 던지기
9-21. RANDOM 에 seed를 다시 지정해 주기
9-22. C 형태의 변수 조작
10-1. 간단한 for 루프
10-2. 각 [list] 항목이 인자를 두 개씩 갖는 for
10-3. Fileinfo: 변수에 들어 있는 파일 목록에 대해 동작
10-4. for 문에서 파일 조작하기
10-5. in [list]가 빠진 for
10-6. for 문의 [list]에 명령어 치환 쓰기
10-7. 이진 파일에 grep 걸기
10-8. 특정 디렉토리의 모든 바이너리 파일에 대해 원저작자(authorship)를 확인 하기
10-9. 디렉토리에 들어 있는 심볼릭 링크들을 나열하기
10-10. 디렉토리에 들어 있는 심볼릭 링크들을 파일로 저장하기
10-11. C 형태의 for 루프
10-12. 배치 모드로 efax 사용하기
10-13. 간단한 while 루프
10-14. 다른 while 루프
10-15. 다중 조건 while 루프
10-16. C 형태의 문법을 쓰는 while 루프
10-17. until 루프
10-18. 중첩된 루프
10-19. 루프에서 breakcontinue의 영향
10-20. 여러 단계의 루프에서 탈출하기
10-21. 더 상위 루프 레벨에서 계속하기(continue)
10-22. case 쓰기
10-23. case로 메뉴 만들기
10-24. case용 변수를 만들기 위해서 명령어 치환 쓰기
10-25. 간단한 문자열 매칭
10-26. 입력이 알파벳인지 확인하기
10-27. select로 메뉴 만들기
10-28. 함수에서 select를 써서 메뉴 만들기
11-1. printf가 실제로 쓰이는 예제
11-2. read로 변수 할당하기
11-3. read로 여러줄의 입력 넣기
11-4. read파일 재지향과 같이 쓰기
11-5. 현재 작업 디렉토리 변경하기
11-6. let으로 몇 가지 산술 연산을 하기.
11-7. eval의 효과 보여주기
11-8. 강제로 로그 아웃 시키기
11-9. "rot13" 버전
11-10. 위치 매개변수와 set 쓰기
11-11. 변수를 "언셋"(unset) 하기
11-12. export를 써서, 내장된 awk 스크립트에 변수를 전달하기
11-13. getopts로 스크립트로 넘어온 옵션과 인자 읽기
11-14. 데이타 파일 "포함하기"
11-15. exec 효과
11-16. 작업을 계속 해 나가기 전에 프로세스가 끝나길 기다리기
12-1. CDR 디스크를 구울 때 ls로 목차 만들기
12-2. Badname, 파일 이름에 일반적이지 않은 문자나 공백 문자를 포함하는 파일을 지우기.
12-3. inode 로 파일을 지우기
12-4. 시스템 로그 모니터링용 xargs 로그 파일
12-5. copydir. xargs로 현재 디렉토리를 다른 곳으로 복사하기
12-6. expr 쓰기
12-7. date 쓰기
12-8. 스크립트에서 두 파일을 비교하기 위해 cmp 쓰기.
12-9. 낱말 빈도수 분석
12-10. 10자리 랜덤한 숫자 만들기
12-11. tail로 시스템 로그를 모니터하기
12-12. 스크립트에서 "grep"을 에뮬레이트 하기
12-13. 목록에 들어 있는 낱말들의 유효성 확인하기
12-14. toupper: 파일 내용을 모두 대문자로 바꿈.
12-15. lowercase: 현재 디렉토리의 모든 파일명을 소문자로 바꿈.
12-16. du: 도스용 텍스트 파일을 UNIX용으로 변환.
12-17. rot13: 초허접(ultra-weak) 암호화, rot13.
12-18. "Crypto-Quote" 퍼즐 만들기
12-19. 파일 목록 형식화.
12-20. column 으로 디렉토리 목록을 형식화 하기
12-21. nl: 자기 자신에게 번호를 붙이는 스크립트.
12-22. cpio로 디렉토리 트리 옮기기
12-23. rpm 아카이브 풀기
12-24. C 소스에서 주석을 제거하기
12-25. /usr/X11R6/bin 둘러보기
12-26. basenamedirname
12-27. 인코드된 파일을 uudecode하기
12-28. 저당에 대한 월 상환액(Monthly Payment on a Mortgage)
12-29. 진법 변환(Base Conversion)
12-30. 다른 방법으로 bc 실행
12-31. seq로 루프에 인자를 만들어 넣기
12-32. 키보드 입력을 갈무리하기
12-33. 파일을 안전하게 지우기
12-34. m4 쓰기
13-1. 지움 글자(erase character) 세팅하기
13-2. 비밀스런 비밀번호: 터미널 에코 끄기
13-3. 키누름 알아내기
13-4. pidof 로 프로세스를 죽이기
13-5. CD 이미지 확인하기
13-6. 한 파일에서 한번에 파일 시스템 만들기
13-7. 새 하드 드라이브 추가하기
13-8. killall, /etc/rc .d/init.d 에서 인용
16-1. exec으로 표준입력을 재지향 하기
16-2. 재지향된 while 루프
16-3. 다른 형태의 재지향된 while 루프
16-4. 재지향된 until 루프
16-5. 재지향된 for 루프
16-6. 재지향된 for 루프(표준입력, 표준출력 모두 재지향됨)
16-7. 재지향된 if/then 테스트
16-8. 이벤트 로깅하기
17-1. dummyfile: 두 줄짜리 더미 파일 만들기
17-2. broadcast: 로그인 해 있는 모든 사람들에게 메세지 보내기
17-3. cat으로 여러 줄의 메세지 만들기
17-4. 탭이 지워진 여러 줄의 메세지
17-5. Here document에서 매개변수 치환하기
17-6. 매개변수 치환 끄기
17-7. upload: "Sunsite" incoming 디렉토리에 파일 한 쌍을 업로드
17-8. "아무개"(anonymous) Here Document
20-1. 서브쉘에서 변수의 통용 범위(variable scope)
20-2. 사용자 프로파일 보기
20-3. 프로세스를 서브쉘에서 병렬로 돌리기
21-1. 제한된 모드로 스크립트 돌리기
23-1. 간단한 함수
23-2. 매개변수를 받는 함수
23-3. 두 숫자중 큰 수 찾기
23-4. 숫자를 로마 숫자로 바꾸기
23-5. 함수에서 큰 값을 리턴하는지 테스트하기
23-6. 큰 두 정수 비교하기
23-7. 사용자 계정 이름에서 실제 이름을 알아내기
23-8. 지역 변수의 영역(Local variable visibility)
23-9. 지역 변수를 쓴 재귀 함수
24-1. 스크립트에서 쓰이는 별칭(alias)
24-2. unalias: 별칭을 설정, 해제하기
25-1. "and list"를 써서 명령어줄 인자 확인하기
25-2. "and list"를 써서 명령어줄 인자를 확인하는 다른 방법
25-3. "or lists""and list"를 같이 쓰기
26-1. 간단한 배열 사용법
26-2. 배열의 특별한 특성 몇 가지
26-3. 빈 배열과 빈 원소
26-4. 아주 오래된 친구: 버블 정렬(Bubble Sort)
26-5. 복잡한 배열 어플리케이션: 에라토스테네스의 체(Sieve of Erastosthenes)
26-6. 복잡한 배열 어플리케이션: 기묘한 수학 급수 탐색(Exploring a weird mathematical series)
26-7. 2차원 배열을 흉내낸 다음, 기울이기(tilting it)
28-1. 특정 PID와 관련있는 프로세스 찾기
28-2. 온라인 연결 상태
29-1. 쿠키 항아리를 숨기기
29-2. /dev/zero로 스왑 파일 세팅하기
29-3. 램디스크 만들기
30-1. 버그 있는 스크립트
30-2. test24, 버그가 있는 다른 스크립트
30-3. "assert"로 조건을 테스트하기
30-4. exit 잡아채기(Trapping at exit)
30-5. Control-C 가 눌렸을 때 깨끗이 청소하기
30-6. 변수 추적하기
32-1. 서브쉘 함정(Subshell Pitfalls)
34-1. 쉘 래퍼(shell wrapper)
34-2. 조금 복잡한 쉘 래퍼(shell wapper)
34-3. awk 스크립트 쉘 래퍼(shell wrapper)
34-4. Bash 스크립트에 내장된 펄
34-5. 하나로 묶인 Bash 스크립트와 펄 스크립트
34-6. 자신을 재귀적으로 부르는 스크립트
35-1. 문자열 확장
35-2. 간접 변수 참조 - 새로운 방법
35-3. 배열과 약간의 트릭을 써서 한 벌의 카드를 4명에게 랜덤하게 돌리기
A-1. manview: 포맷된 맨 페이지를 보는 스크립트
A-2. mailformat: 이메일 메세지를 포맷해서 보기
A-3. rn: 간단한 파일이름 변경 유틸리티
A-4. encryptedpw: 로컬에 암호화 되어 있는 비밀번호로 ftp 사이트에 파일을 업로드하는 스크립트
A-5. copy-cd: 데이타 CD를 복사하는 스크립트
A-6. days-between: 두 날짜 사이의 차이를 계산해 주는 스크립트
A-7. behead: 메일과 뉴스 메세지 헤더를 제거해 주는 스크립트
A-8. ftpget: ftp에서 파일을 다운로드 해 주는 스크립트
A-9. password: 8 글자짜리 랜덤한 비밀번호 생성 스크립트
A-10. fifo: 네임드 파이프를 써서 매일 백업해 주는 스크립트
A-11. 나머지 연산자로 소수 생성하기
A-12. tree: 디렉토리 구조를 트리 형태로 보여주는 스크립트
A-13. 문자열 함수들: C 형태의 문자열 함수
A-14. 객체 지향 데이타 베이스
F-1. 샘플 .bashrc 파일
G-1. VIEWDATA.BAT: 도스용 배치 파일
G-2. viewdata.sh: VIEWDATA.BAT 의 스크립트 버전

출처 : http://wiki.kldp.org/HOWTO//html/Adv-Bash-Scr-HOWTO/index.html

        http://blog.naver.com/misadamo.do?Redirect=Log&logNo=80001904458

2006/09/08 16:23 2006/09/08 16:23
이 글에는 트랙백을 보낼 수 없습니다
Linux  2006/09/08 15:59
출처 블로그 > 몽크
원본 http://blog.naver.com/machoon/40003720775
1. Tcpdump란? tcpdump는 Lawrence Berkley Nation Lab의 Network Rearch Gruop에서 만든 것으로 네트워크의 패킷을 출력해주는 프로그램이다. 주어진 조건식을 만족하는 네트워크 인터페이스를 거치는 패킷들의 헤더들을 출력해 주는 프로그램이다. 주로 쓰임은 지정된 상대방 호스트로부터 들어오는 패킷을 체크하는 데 있다.2. tcpdump의 사용법 (1) 사용법   tcpdump [options] [host]
(2) tcpdump의 결과보기 [root@www root]# tcpdump 01:37:09.744959 203.xxx.xxx.10.4847 > linux.co.kr.ftp: S 2082495566:2082495566(0) win 16384 (DF) => (결과설명) 01:37:09.744959 : Timestamp로 보통 '시간.특정한숫자값'형태로 부여된다. 203.xxx.xxx.10.4847 : Source_address.source_port로 소스의 IP주소와 Port번호를 나타낸 다. > : Traffic direction으로 방향을 나타낸다. linux.co.kr.ftp : destination_address.destination_port로 도착지 IP주소와 Port번호를 나타낸다. S : TCP flag로 특정한 표시문자를 일컫는다. 2082495566:2082495566(0) : sequence number이다. win 16384 : window size이다. : various options 이다. (DF) : Don't fragment
3. tcpdump 플래그(flags) 
TCP 플래그 TCPDUMP 플래그 플래그의 의미
SYNS SYN패킷, 접속요청을 할 때 보내는 패킷을 말한다.
TCP접속시에 가장먼저 보내는 패킷이다.
ACKack ACK패킷, 상대방으로부터 패킷을 받은 뒤에 알려주는
패킷을 말한다. 다른 플래그와 같이 출력되는 경우도
있다.
FINF 접속종료를 위한 플래그로 이 패킷을 보내는 곳이
현재 접속하고 있는 곳과 접속을 끊고자 할 때 사용한다.
RESETR 이 패킷을 보내는 곳이 현재 접속하고 있는 곳과 즉시
연결을끊고자 할 때 사용한다.
PUSHP 데이터를 즉시 목적지로 보내라는 의미이다. 텔넷과
같이 상호작용이 중요한 프로그램의 경우 빠른 응답
이 중요한다. 이때 사용하는 플래그이다.
UGENTURG 긴급한 데이터는 다른 데이터에 비해 우선순위가
높아야 한다. 예를 들어 ftp로 자료를 받고 있는 도중
[CTRL]+[C] 를 받으면 즉시 자료받기를 중단해야 하는
것처럼 이 때 사용하는 플래그이다.
Placeholder. 패킷이 SYN, FINISH, RESET, PUSH등의 플래그가 없는
경우이 플래그가 세팅된다. 이 플래그는 ACK플래그와
함께 사용되는 경우도 있다.
4. tcpdump의 옵션 -h: 버전 및 기본 사용법을 보여준다. -a : Network & Broadcast 주소들을 이름들로 바꾼다. -c Number : 제시된 수의 패킷을 받은 후 종료한다. -d : compile된 packet-matching code를 사람이 읽을 수 있도록 바꾸어 표준 출력으로 출력하고, 종료한다. -dd : packet-matching code를 C program의 일부로 출력한다. -ddd : packet-matching code를 숫자로 출력한다. -e : 출력되는 각각의 행에 대해서 link-level 헤더를 출력한다. -f : 외부의 internet address를 가급적 심볼이 아닌 숫자로 출력한다.(Sun의 yp server와의 사용은 가급적 피한다.) -F file : filter 표현의 입력으로 파일을 받아들인다. 커맨드라인에 주어진 추가의 표현들은 모두 무시된다. -i device : 어느 인터페이스를 경유하는 패킷들을 잡을지 지정한다. 지저되지 않으면 시스템의 인터페이스 리스트를 검색하여 가장 낮은 번호를 가진 인터페이스를 선택한다.(이 때 loopback은 제외된다.) 예) tcpdump -i eth0 -l : 표준 출력으로 나가는 데이터들을 line buffering한다. 다른 프로그램에서 tcpdump로부터 데이 터를 받고자 할 때 유용하다. 보통 'tcpdump -l | tee dat' 나 'tcpdump -l < dat & tail -f dat' 명령으로 연계해서 사용하면 편리하다. -n : 모든 주소들을 번역하지 않는다(port,host address 등등) -N : 호스트 이름을 출력할 때, 도메인을 찍지 않는다. -O : packet-matching code optimizer를 실행하지 않는다. 이 옵션은 optimizer에 있는 버그를 찾을 때나 쓰인다. -p : 인터페이스를 promiscuous mode로 두지 않는다. -q : 프로토콜에 대한 정보를 덜 출력한다. 따라서 출력되는 라인이 좀 더 짧아진다. -r file : 패킷들을 '-w'옵션으로 만들어진 파일로 부터 읽어 들인다. 파일에 "-" 가 사용되면 표준 입력을 통해서 받아들인다. -s length: 패킷들로부터 추출하는 샘플을 default값인 68Byte외의 값으로 설정할 때 사용한다.(Sun OS의 NIT에서는 최소가 96Byte이다). 68Byte는 IP,ICMP, TCP, UDP등에 적절한 값이지만 Name Server나 NFS 패킷들의 경우에는 프로토콜의 정보들을 Truncation할 우려가 있다. 이 옵션을 수정할 때는 신중해야만 한다. 이유는 샘플 사이즈를 크게 잡으면 곧 패킷 하 나하나를 처리하는데 시간이 더 걸릴 뿐만아니라 패킷 버퍼의 사이즈도 자연히 작아지게 되어 손실되는 패킷들이 발생할 수 있기 때문이다. 또, 작게 잡으면 그만큼의 정보를 잃 게되는 것이다. 따라서 가급적 캡춰하고자 하는 프로토콜의 헤더 사이즈에 가깝게 잡아 주어야 한다. -T type : 조건식에 의해 선택된 패킷들을 명시된 형식으로 표시한다. type에는 다음과 같은 것들이 올 수 있다. rpc(Remote Procedure Call), rtp(Real-Time Applications protocol), rtcp (Real-Time Application control protocal), vat(Visual Audio Tool), wb(distributed White Board) -S : TCP sequence번호를 상대적인 번호가 아닌 절대적인 번호로 출력한다. -t : 출력되는 각각의 라인에 시간을 출력하지 않는다. -tt : 출력되는 각각의 라인에 형식이 없는 시간들을 출력한다. -v : 좀 더 많은 정보들을 출력한다. -vv : '-v'보다 좀 더 많은 정보들을 출력한다. -vvv : 16진수값 형태로 정보를 보여준다. 보통 -X옵션과 사용되어 -w : 캡춰한 패킷들을 분석해서 출력하는 대신에 그대로 파일에 저장한다. -x : 각각의 패킷을 헥사코드로 출력한다. -X : 헥사코드와 ascii형태 모두 출력해준다. 보통 -x 옵션과 같이 사용된다. -조건식(expression) 옵션의 제일 마지막인 조건식은 어떤 패킷들을 출력할 지를 선택하는 데 쓰인다. 조건식이 주어지지 않는다면 모든 패킷들이 대상이 된다. 조건식들은 하나 또는 여러 개의 primitive들로 구성되어 있고 primitive들은 다시 하나 또는 여러 개의 qualifier들 다음에 오는 하나의 값으로 이루어진다. *qualifier type : 주어진 값의 종류가 무엇인지를 나타낸다. 가능한 type들은 'host', 'net', 'port'가 있다. type이 없는 값들은 type을 host라 가정한다. dir : id로 부터의 어떤 특정한 전송 방향을 나타낸다. 가능한 방향은 'src', 'dst', 'src or dst', 'src and dst'이다. 만약 방향이 정해지지 않았다면, src or dst라 가정한다. "For `null' link layers (i.e. point to point protocols such as slip) the inb ound and out bound qualifiers can be used to specify a desired direction." proto : 매칭을 특정 프로토콜에 한해서 수행한다. 가능한 프로토콜들은 ether, fddi, ip, arp, rarp, decnet, lat, sca, moprc, mopdl, tcp, udp이다. 만약 프로토콜이 명시되지 않았다 면, 해당하는 값의 type에 관련된 모든 프로토콜들이 그 대상이 된다. *위의 패턴을 따르지 않는 primitive : gateway, broadcast, less, greater, 산술식이 있으며 참고 로 더 정교한 조건식을 사용하려면 'and(&&)','or(||)','not(!)' 을 사용할 수 있다. *사용가능한 primitive들 dst host HOST => packet의 IP destination 항목이 HOST일때 참이 된다. src host HOST => packet의 IP source 항목이 HOST일때 참이 된다. host HOST => IP source, IP destination 항목 중 어느 하나라도 HOST이면 참이다. ether dst ehost => ethernet destination 주소가 ehost일 때 참이다. ether src ehost => ethernet source 주소가 ehost일 때 참이다. ether host ehost => ethernet source, destination 항목들 중 어느 하나라도 ehost이면 참이다. gateway host => 패킷이 host를 게이트웨이로 사용하면 참이다. 이 말의 의미는 ethernet sour ce나 destina tion 항목은 host이지만, IP source와 destination은 host가 아닐 때를 말한다. dst net NET => 패킷의 IP destination 주소가 NET의 network number를 가지고 있을 때 참이다. src net NET => 패킷의 IP source 주소가 NET의 network number를 가지고 있을 때 참이다. net NET => 패킷의 IP source 주소 혹은 destination 주소가 NET의 network number를 가 지고 있을 때 참이다. net netmask mask => IP 어드레스가 지정된 netmask를 통해서 net과 매칭되면 참이다. net net/len => IP 어드레스가 netmask와 len 비트만큼 매치되면 참이다. dst port PORT => 패킷이 ip/tcp, ip/udp 프로토콜의 패킷이고 destination port의 값이 PORT일 때 참이다. port는 /etc/services에 명시된 이름일 수도 있고 그냥 숫자일 수도 있다. 만약 이름이 사용 됐다면 port 번호와 프로토콜이 같이 체크될 것이다. 만약 숫자나 불 확실한 이름이 사용됐을 경우에는 port 번호만이 체크될 것이다. src port PORT => 패킷의 source port의 값으로 PORT를 가지면 참이다. port PORT => 패킷의 source, destination port 중에 하나라도 PORT이면 참이다.
less length => 패킷이 length보다 짧거나 같으면 참이다.(len <= length) greater length => 패킷이 length보다 짧거나 같으면 참이다.(len >= length) ip proto protocol => 패킷이 지정된 종류의 프로토콜의 ip패킷이면 참이다. Protocol은 icmp, igrp, udp, nd, tcp 중의 하나 혹은 몇 개가 될 수 있다. 주의할 점은 tcp, udp, icmp들은 '\'로 escape되어야 한다. ehter broadcast => 패킷이 ethernet broadcast 패킷이라면 참이다. ehter는 생략 가능하다. ip broadcast => 패킷이 IP broadcast 패킷이라면 참이다. ether multicast => 패킷이 IP multicast 패킷이라면 참이다. ether proto protocol => 패킷이 ether type의 protocol이라면 참이다. protocol은 ip, arp, rarp 중에 하나 혹은 몇 개가 될 수 있다. ip proto protocol에서와 마찬가지로 ip, arp, rarp는 escape 되어야 한다. decnet src host => 만약 DECNET의 source address가 host이면 참이다. 이 어드레스는 '10.123'이 나 DECNET의 host name일 수 있다. DECNET host name은 DECNET에서 돌아가도록 설정된 Ultrix 시스템에서 만 사용 가능하다. decnet dst host => DECNET destination address가 host이면 참이다. decnet host HOST => DECNET source, destination address중의 하나라도 HOST이면 참이다. ip, arp, rarp, decnet => ether proto [ip|arp|rarp|decnet]의 약어 lat, moprc, mopdl => ether proto [lat|moprc|mopdl]의 약어 tcp, udp, icmp => ip proto [tcp|udp|icmp]의 약어 expr relop expr => EXPR proto [expr:size]의 형식을 띤다. proto, expr, size에 올 수 있는 것들은 다음과 같다. proto : ether, fddi, ip, arp, rarp, tcp, udp, icmp expr : indicate Byte offset of packet of proto size : optional. indicate the size of bytes in field of interest default is one, and can be two or four => RELOP !=, =, <=, >=, etc. 이 조건식을 사용하기 위해서는 먼저 해당하는 Protocol(proto)의 헤더에 관련된 것들을 자세 히 알아야만 한다. proto에는 대상이 될 프로토콜을 지정한다. expr에는 프로토콜 헤더의 처음 부터의 Byte Offset을 지정하는 식이 들어가게 된다. Size는 Option이며 지정이 안 되어 있을 경우에는 자동으로 1byte를 지칭한다. 따라서 이 조건식을 사용하게 되면 헤더에 포함된 정보 를 Bitmask를 사용하여 직 접 원하는 패킷인지를 가려낼 수 있기 때문에, 보다 정밀한 사용이 가능하게 된다.
5. tcpdump 기본사용예
(1) [root@www root]# tcpdump => 현재 서버의 모든 패킷을 보여준다. (2) [root@www root]# tcpdump port 21 tcpdump: listening on eth0 01:25:43.833276 203.xxx.xxx.100.4828 > xxx.com.ftp: S 1910472596:1910472596(0) win 16384 203.247.40.244.4828: S 4108025962:4108025962(0) ack 1910472597 ) => 21번 포트로 들어온 패킷만 보여준다. (3) [root@nanajjang /root]# tcpdump -c 2 host neuro.hannam.ac.kr Kernel filter, protocol ALL, datagram packet socket tcpdump: listening on all devices 11:09:44.576419 eth0 B arp who-has 203.247.40.247 tell neuro.hannam.ac.kr 11:09:44.576507 eth0 > arp reply 203.247.40.247 (0:c0:26:1:11:77) is-at 0:c0:26) => neuro.hannam.ac.kr의 패킷 2개만 보여준다. (4) tcpdump -v -e broadcast => broadcast 의 정보를 자세히 출력하고 출력되는 각각의 행에 대해서 link-level헤더를 출력 한다.
6. tcpdump로 패스워드 알아내기
(1) 설명: telnet을 이용하여 서버에 접속을 하면 패킷전송시에 암호화하지 않기 때문에 쉽게 내용 을 볼 수 있다. tcpdump를 이용하여 패스워드를 알아낼 수 있다. (2) 사용예 1) 실행명령 [root@www root]# tcpdump port telnet -l -vvv -x -X >dumpdata & tail -f dumpdata 2) 패킷분석: 패킷의 양이 많으므로 잘 찾아야 한다. 먼저 연결된 포트를 확인한다. 20:38:22.395281 xxx.com.telnet > 210.xxx.xxx.100.35383: P [tcp sum ok] 175:182(7) ack 81 win 5792 (DF) [tos 0x10] (ttl 64, id 59193, len 59) 0x0000 4510 003b e739 4000 4006 ca41 cbf7 28fc E..;.9@.@..A..(. 0x0010 d27b c1c2 0017 8a37 2992 16d8 2041 b972 .{.....7)....A.r 0x0020 8018 16a0 5fec 0000 0101 080a 04d1 f156 ...._..........V 0x0030 0223 7825 6c6f 6769 6e3a 20 .#x%login:. => 서버(xxx.com)에서 클라이언트(210.xxx.xxx.100에게 'login'이라는 것을 보여줌을 알 수 있다. 또한 연결된 클라이언트의 포트번호가 35383임을 알 수 있다. 이 포트번호를 확인해 야 패킷을 찾아갈 수 있다. ---중략--- 20:38:23.979306 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 81:82(1) ack 182 win 5840 (DF) [tos 0x10] (ttl 56, id 49475, len 53) 0x0000 4510 0035 c143 4000 3806 f83d d27b c1c2 E..5.C@.8..=.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b972 2992 16df ..(..7...A.r)... 0x0020 8018 16d0 5130 0000 0101 080a 0223 78c3 ....Q0.......#x. 0x0030 04d1 f156 70 ...Vp => 클라이언트에서 서버로 전송하는 부분만을 확인하면 된다. P 다음에 존재하는 81:82와 ack 다음에 182라는 번호를 꼭 확인한다. 다음 패킷번호는 82:83이 되고 ack 183번이 되므로 ack 183이라는 부분을 찾아가면 된다. 여기서 클라이언트에서 서버로 전송한 글자는 맨 마지막에 표시된다. 즉 'p'이다. ---중략--- 20:38:24.162490 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 82:83(1) ack 183 win 5840 (DF) [tos 0x10] (ttl 56, id 49477, len 53) 0x0000 4510 0035 c145 4000 3806 f83b d27b c1c2 E..5.E@.8..;.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b973 2992 16e0 ..(..7...A.s)... 0x0020 8018 16d0 4ef0 0000 0101 080a 0223 78d6 ....N........#x. 0x0030 04d1 f481 6f ....o ---중략--- 20:38:24.322785 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 83:84(1) ack 184 win 5840 (DF) [tos 0x10] (ttl 56, id 49479, len 53) 0x0000 4510 0035 c147 4000 3806 f839 d27b c1c2 E..5.G@.8..9.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b974 2992 16e1 ..(..7...A.t)... 0x0020 8018 16d0 4a80 0000 0101 080a 0223 78e6 ....J........#x. 0x0030 04d1 f4df 73 ....s ---중략--- 20:38:24.445142 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 84:85(1) ack 185 win 5840 (DF) [tos 0x10] (ttl 56, id 49481, len 53) 0x0000 4510 0035 c149 4000 3806 f837 d27b c1c2 E..5.I@.8..7.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b975 2992 16e2 ..(..7...A.u)... 0x0020 8018 16d0 5820 0000 0101 080a 0223 78f2 ....X........#x. 0x0030 04d1 f531 65 ...1e ---중략--- 20:38:24.532360 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 85:86(1) ack 186 win 5840 (DF) [tos 0x10] (ttl 56, id 49483, len 53) 0x0000 4510 0035 c14b 4000 3806 f835 d27b c1c2 E..5.K@.8..5.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b976 2992 16e3 ..(..7...A.v)... 0x0020 8018 16d0 53d6 0000 0101 080a 0223 78fb ....S........#x. 0x0030 04d1 f570 69 ...pi ---중략--- 20:38:24.624350 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 86:87(1) ack 187 win 5840 (DF) [tos 0x10] (ttl 56, id 49485, len 53) 0x0000 4510 0035 c14d 4000 3806 f833 d27b c1c2 E..5.M@.8..3.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b977 2992 16e4 ..(..7...A.w)... 0x0020 8018 16d0 4e9f 0000 0101 080a 0223 7904 ....N........#y. 0x0030 04d1 f59c 6e ....n ---중략--- => posein이라는 글자를 알 수 있다. 즉 사용자 ID가 posein이다. 20:38:24.932380 xxx.com.telnet > 210.xxx.xxx.100.35383: P [tcp sum ok] 190:200(10) ack 89 win 5792 (DF) [tos 0x10] (ttl 64, id 59201, len 62) 0x0000 4510 003e e741 4000 4006 ca36 cbf7 28fc E..>.A@.@..6..(. 0x0010 d27b c1c2 0017 8a37 2992 16e7 2041 b97a .{.....7)....A.z 0x0020 8018 16a0 d40b 0000 0101 080a 04d1 f669 ...............i 0x0030 0223 7923 5061 7373 776f 7264 3a20 .#y#Password:. => 서버에서 클라이언트에서 Password라는 글을 보내어 출력시킨다. ---중략--- 20:38:25.300524 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 89:90(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49490, len 53) 0x0000 4510 0035 c152 4000 3806 f82e d27b c1c2 E..5.R@.8....{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97a 2992 16f1 ..(..7...A.z)... 0x0020 8018 16d0 557f 0000 0101 080a 0223 7947 ....U........#yG 0x0030 04d1 f669 66 ...ip ---중략--- 20:38:25.454778 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 90:91(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49491, len 53) 0x0000 4510 0035 c153 4000 3806 f82d d27b c1c2 E..5.S@.8..-.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97b 2992 16f1 ..(..7...A.{)... 0x0020 8018 16d0 489e 0000 0101 080a 0223 7957 ....H........#yW 0x0030 04d1 f739 72 ...9a ---중략--- 20:38:25.659340 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 91:92(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49492, len 53) 0x0000 4510 0035 c154 4000 3806 f82c d27b c1c2 E..5.T@.8..,.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97c 2992 16f1 ..(..7...A.|)... 0x0020 8018 16d0 554e 0000 0101 080a 0223 796b ....UN.......#yk 0x0030 04d1 f774 65 ...ts ---중략--- 20:38:25.777475 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 92:93(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49493, len 53) 0x0000 4510 0035 c155 4000 3806 f82b d27b c1c2 E..5.U@.8..+.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97d 2992 16f1 ..(..7...A.})... 0x0020 8018 16d0 54d8 0000 0101 080a 0223 7977 ....T........#yw 0x0030 04d1 f7dd 65 ....s ---중략--- 20:38:26.049208 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 93:94(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49494, len 53) 0x0000 4510 0035 c156 4000 3806 f82a d27b c1c2 E..5.V@.8..*.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97e 2992 16f1 ..(..7...A.~)... 0x0020 8018 16d0 887f 0000 0101 080a 0223 7992 .............#y. 0x0030 04d1 f81a 31 ....w ---중략--- 20:38:26.243634 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 94:95(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49495, len 53) 0x0000 4510 0035 c157 4000 3806 f829 d27b c1c2 E..5.W@.8..).{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97f 2992 16f1 ..(..7...A..)... 0x0020 8018 16d0 86df 0000 0101 080a 0223 79a6 .............#y. 0x0030 04d1 f8a5 32 ....o ---중략--- 20:38:26.442302 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 95:96(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49496, len 53) 0x0000 4510 0035 c158 4000 3806 f828 d27b c1c2 E..5.X@.8..(.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b980 2992 16f1 ..(..7...A..)... 0x0020 8018 16d0 8768 0000 0101 080a 0223 79b9 .....h.......#y. 0x0030 04d1 f908 31 ....r ---중략--- 20:38:26.540930 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 96:97(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49497, len 53) 0x0000 4510 0035 c159 4000 3806 f827 d27b c1c2 E..5.Y@.8..'.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b981 2992 16f1 ..(..7...A..)... 0x0020 8018 16d0 80f7 0000 0101 080a 0223 79c3 .............#y. 0x0030 04d1 f96e 37 ...nd ---이하생략--- => 패스워드가 password라는 것을 알 수 있다.출처 : http://www.attikorea.com/secuutil/tcpdump.html
2006/09/08 15:59 2006/09/08 15:59
이 글에는 트랙백을 보낼 수 없습니다
출처 카페 > CrazyJava / 플그래머
원본 http://cafe.naver.com/autocrat/75

Vi 사용하기

Vi 시작하기

  • $ vi : vi 시작하기
  • $ vi aaa.txt : aaa.txt 파일을 편집하면서 vi 시작
  • $ vi -R aaa.txt : 읽기 전용으로 열기
Esc : 또는 /
편집상태
명령대기상태
(Esc모드)

명령줄상태
삽입명령어
i,a,A,I,o,O
Esc 또는 Enter
  • 명령대기상태 → 편집상태 : 삽입명령어 (아래참조.)
  • 편집상태 → 명령대기상태 : Esc글쇠.
  • 명령대기상태 → 명령줄상태 : : 또는 / (아래참조)
  • 명령줄상태 → 명령대기상태 : Esc 또는 Enter (아래참조)

커서의 이동

  • h, l, j, k : 왼쪽(←, Back space), 오른쪽(→, space), 위(↑), 아래(↓)
  • b, w : 이전 단어의 첫 글자로 / 다음 단어의 첫 글자로 이동.
  • B, W : 이전 단어의 첫 글자로 / 다음 단어의 첫 글자로 이동. (문장부호 무시)
  • e : 다음 단어의 끝 글자로 이동.
  • E : 다음 단어의 끝 글자로 이동. (문장부호 무시)
  • H, M, L : 화면의 맨 위/ 중간 / 맨 아래로
  • 0 : 그 줄의 맨 처음으로 (숫자 0이다.)
  • $ : 그 줄의 맨 끝으로
  • + : 다음 줄의 처음으로
  • - : 윗 줄의 처음으로
  • 3| : 현재 줄의 3번째 열로
  • 4H : 화면 상의 처음 줄부터 4줄 밑으로
  • 4L : 화면 상의 마지막 줄부터 4줄 위로
  • (, ) : 이전 문장의 시작으로 / 다음 문장의 시작으로
  • {, } : 이전 문단의 시작으로 / 다음 문단의 시작으로
  • [[, ]] : 이전 섹션의 시작으로 / 다음 섹션의 시작으로

편집 버퍼를 통한 이동

  • ^F, ^B : 한 화면 앞으로 / 뒤로 (^는 Ctrl글쇠를 의미.)
  • ^D, ^U : 반 화면 앞으로 / 뒤로
  • 4^B : 4화면 위로 이동
  • 4^F : 4화면 아래로 이동
  • 7^U : 7줄 위로 이동
  • 7^D : 7줄 아래로 이동
  • ^Y : 커서는 현재 위치 그대로 화면만 한 줄씩 아래로 이동
  • ^E : 커서는 현재 위치 그대로 화면만 한 줄씩 위로 이동

행 단위 이동

  • :0 : 파일의 첫 번째 행으로 가기 (숫자 0)
  • :10 : 10번째 행으로 가기
  • :$ : 파일의 마지막 행으로 가기
  • G : 파일의 마지막 행으로 가기
  • 10G : 10번째 행으로 가기

삽입명령어

  • i : 커서 위치부터 삽입 시작
  • a : 커서 위치 오른쪽부터 삽입 시작
  • A : 현재 줄의 맨 끝 부터 삽입 시작
  • I : 현재 줄의 맨 처음 부터 삽입 시작
  • o : 커서 아래에 행 삽입
  • O : 커서 위에 행 삽입

삭제명령

  • x : 현재 커서위치의 한 문자 삭제
  • X : 현재 커서 왼쪽의 한 문자 삭제
  • dd : 한 줄 지우기
  • 4dd : 4 줄 지우기
  • dw : 한 단어 지우기
  • d2w : 2 단어 지우기
  • D : 커서 오른쪽 행 삭제
  • :5 d : 5 째 행 삭제
  • :5,10 d : 5-10 째 행 삭제

파일의 저장 및 종료

  • :wq : 저장 후 vi 종료
  • :w : 저장 (종료는 하지 않고 계속 편집)
  • :q! : 저장하지 않고 vi 빠져나가기
  • :w filename : filename으로 저장 후 계속 편집
  • ZZ : 변경사항 저장 후 vi 종료

내용의 복사 및 이동

  • yy : 현재의 행 복사
  • 5yy : 현재의 행 위치부터 5행 복사
  • p : 아래(오른쪽)에 붙여넣기
  • P : 위(왼쪽)에 붙여넣기
  • f4yy : 현재의 행 위치부터 4행을 'f'라는 이름의 버퍼에 복사
  • fp : 'f'라는 이름의 버퍼에 복사된 내 용을 현재 행 위치에 붙여넣기
  • :3 co 7 : 3 행을 7행 다음으로 복사
  • :1,3 co 7 : 1-3 행을 7행 다음으로 복사
  • :3 m 7 : 3 행을 7행 다음으로 이동
  • :1,3 m 7 : 1-3 행을 7행 다음으로 이동

내용 고치기

  • J : 현재 행과 아래 행 결합
  • 3J : 3줄 합치기
  • u : 이전 명령 취소
  • cw : 단어 변경
  • cc : 행 변경
  • C : 커서 오른쪽의 행 변경
  • s : 커서가 위치한 문자열 대체
  • r : 한 글자만 변경 (입력 모드로 바뀌지 않음)
  • R : 입력하는 대로 겹쳐써서 변경
  • xp : 커서 위치 문자와 오른쪽 문자 교환
  • - : 문자형(대,소문자) 변경
  • U : 행 변경사항 취소
  • :u : 이전의 최종행 취소

명령 취소 및 반복

  • . : 마지막 명령 반복
  • 2. : 마지막 명령 2회 반복
  • u : 마지막 명령 취소
  • U : 현재 줄을 저장

행 번호 설정 및 화면표시

  • :set nu : 행 번호 표시
  • :set nonu : 행 번호 숨기기
  • := : 현재 줄번호 보여주기
  • :/pattern/ = : pattern이 위치한 줄번호 보여주기

시스템이 다운된 후에 파일 되살리기

  • vi -r : 되살릴 수 있는 모든 파일 이름 보여주기
  • vi -r file.txt : vi를 시작하여 지정한 파일 되살리기

다른 파일을 파일 내로 삽입

  • :r filename : 커서 다음에 파일 삽입
  • :20 r filename : 파일을 20번째 행 다음에 삽입

새로운 파일 편집하기

  • :e fine.txt : file.txt 편집하기
  • :e! : 현재의 편집중인 내용 무시하고 가장 최근에 편집한 내용 다시 편집하기

다중 편집하기

    % vi file1 file2 file3
    혹은
    :e file1 file2 file3
    했을 때,
  • :args : 편집 중인 파일목록 보여주기
  • :n[ext] : 다음 파일로 넘어가기
  • :prev[ious] : 이전 파일로 넘어가기 (단 편집 중인 파일이 저장되지 않으면 다음 파일로 넘어갈 수 없다.)

문자열 탐색

  • /aaa : 'aaa' 찾기 (현재 위치부터 뒤로)
  • ?aaa : 'aaa' 역방향 찾기 (현재 위치부터 앞으로)
  • / : 가장 최근에 검색한 문자열 다시 검색
  • ? : 가장 최근에 검색한 문자열 다시 역방향 검색
  • :set noh : 문자열 검색 후 문자열 강조 끄기

치환

vi에서 치환은 정규표현식이 이용된다. (실제로 이 상태에서 실행하는 명령어는 ed나 ex라는 프로그램이 처리하게 된다. 그래서 보통 이 상태를 "ed-모드"라고 한다.) 문서에서 원하는 패턴을 찾으려면 바로 위에 '문자열 탐색'에서 설명된 바와 같이 /문자열 이나 ?문자열 을 사용한다. 문자치환 명령은 다음과 같다.

[형식] :범위s/변경전/변경후/수정자  

'범위'는 명령이 실행될 범위(예: 10,20 이면 10행 부터 20행 까지)를 나타낸다. 's'는 치환(substitute)의 약자이며 '수정자'는 치환 명령의 세부사항을 결정한다. 필요한 것만 뒤에 적어주면 된다. (중복 가능)

  • g (global) - 한 줄에서 일치하는 부분을 여러개 찾았을 때 전부 치환한다. 이것을 사용하지 않으면 처음 것만 치환.
  • c (confirm) - 만족하는 정규표현식을 찾았을 때 치환하기 전에 확인한다.
  • i (ignore-case) - 대소문자를 구별하지 않는다.

"변경전"과 "변경후"에 치환할 내용을 입력한다. "변경전"에 정규표현식을 적는다. 정규표현식으로 ., *, ^, $, [], \(...\), \<...\>, POSIX.2 단축 표현을 사용할 수 있다. 여기서 여러 문자를 묶여서 단위를 만들고 찾은 내용을 기억하는 특수문자가 \(, \)임을 주의해야 한다. 반대로 (, )가 일반문자이다. vim(VI iMproved)에서는 vi에 추가로 |, +, (?와 같은) =, {n,m}을 사용할 수 있지만, 앞에 \ 를 붙여야 한다. 또, vim에는 \i, \k, \p, \s 등의 단축 표현들이 있다.

"변경후"에 \n & 를 사용할 수 있다. \n 는 "변경전"에서 n번째 \(...\) 에 대응하는 부분이고, & 는 "변경전"에 만족한 전체를 나타낸다. 예를 들어,
:%s/\([0-9][0-9]*\) \([Cc]hapter\)/\2 \1/
는 문서에서 12 Chapter같은 부분을 Chapter 12와 같이 치환하고,
:%s/F[1-9][12]*/&/g
는 HTML 문서에서 "F1" ~ "F12"란 단어 모두를 굵은 체로 바꿉니다. (주의! &는 정규표현식의 특수문자는 아니지만 vi의 특수문자이므로, 문자그대로의 &를 사용하려면 대신 \& 를 사용해야 한다.) 이외에도 (뒤를 모두 대문자로) \u 나 (뒤를 모두 소문자로) \l 같은 기능이 있다.

    :%s/aaa/bbb/g - 파일 전체(g)에서 'aaa'을 'bbb' 로 치환
    :%s/^M//g - 파일 전체(g)에서 ^M 을 삭제. ^M은 Ctrl+V+Enter로 입력한다.
    :s/aaa/bbb/ - 현재 행에서 'aaa'을 'bbb' 로 치환
    :1,10 s/aaa/bbb/ - 1행부터 10행 까지 'aaa'을 'bbb' 로 치환
    :1,. s/str/rep/ - 1부터 현재행까지 'aaa'를 'bbb' 로 전부 바꾸기
    :g/감자/s//바위/gc - 각 발생 확인 후 대체

주의할 점은 치환명령어가 / 문자로 각 부분을 구분하기때문에 "변경전"이나 "변경후"에 / 문자를 사용하려면 \/ 같이 써야한다.
필요하다면 / 대신 다른 문자를 사용해도 된다. 예를 들어,
:%s/\/usr\/local\/bin\//\/usr\/bin\//g
대신
:%s#/usr/local/bin/#/usr/bin/#g
가 알아보기 더 쉽다.



출처 블로그 > 오순도순
원본 http://blog.naver.com/putter/20757276

vi 환경에서 코딩 작업 등을 할때 사전에 설정해 두면 편리한 기능 들을 정리 해 보았습니다.

1. ": set" 으로 변경

   :set ai (autoindeant)

   --> 윗라인과 같이 자동으로 들려쓰기를 해 줍니다.

  

   :set ts=4 (tabstop)

   --> [tab] 키를 입력 하였을때 이동하는 크기를 조정 합니다.

         (보통 "ts=4" 일때가 가장 적당한 듯 합니다.)

   :set et (expandtab)

   --> [tab] 키를 입력 하였을때 tab에 대당하는 space 만큼 이동 됩니다.

         (Python 언어 코딩 할때 매우 편리 합니다.)

   :set si

   --> 코딩 할때 if, for 같은 것을 입력 하고 다음 라인으로 이동시 들려쓰기를 해줍니다.

   :set sw=4 (shiftwidth)

   --> "set si" 했을 경우 들려쓰기 하는 깊이를 설정 합니다.

   :set encoding=cp949 or utf-8

   --> 작업 하는 컴퓨터 또는 개발 언어에서 기본 인코딩 타입을 설정 할 수 있습니다.

[참고]

* 알고 있겠지만 모든 명령의 취소는 no를 앞에 붙여 주시면 됩니다. 예)  :set noai


* 항상 같은 설정이 되도록 하려면 UNIX는 홈디렉토리 아래에 .vimrc 에 넣어 주시구요

    windows 는  vim 설치 디렉토리에 _vimrc 파일에 넣어 주시면 됩니다.

   예) set ts=4

        set si

        set ai

        set sw=4

        set encoding=cp494



2. vi 편집 작업시

1) 화면 스크롤

   ^F : 한 화면 앞으로 스크롤

   ^B : 한 화면 뒤로 스크롤

   ^D : 반 화면 앞으로 스크롤

   ^U : 반 화면 뒤로 스크롤

   ^E : 한줄 앞으로 스크롤

   ^Y : 한줄 뒤로 스크롤

    H : 화면의 맨 윗줄로

    M : 화면의 중간 줄로

     I : 화면의 맨 아랫줄로

 

2) 화면 나누기

   : vs  수직으로 나눔

   : sp  스평으로 나눔

   * 화면간 이동은 ^ww

3) 마크 이동

  m[a~z] --> 현재의 위치를 기록

  '[a~z] --> 기록한 위치로 이동


4) 접기

  V 로 블럭 설정을 한후에 'zf' 하면 접힘

  'zo' 를 하면 다시 펴짐


5) 함수/변수명 자동 완성

   호출 하고자 하는 변수명이나 함수명의 앞글자만 쓰고서 ^p 를 입력 하면 자동 완성 됨


6) 잠시 쉘로 나가기

    ^z, 들어 올때는 fg



기본 명령어는 기술 하지 않았으며, 잘 알려지지 않았고 알면 편리한 기능 위주로 정리 했습니다.

상세한 정보는 기존에 스크랩 해놓은 자료나 vim.org 에서 확인 하시기 바랍니다.


작성 : 마그마(필명)


아래 웅자꺼를 쓸려면 프로그래밍 코딩 시 해당 코드가 활성화 되지 않는다. 이유는 vim 버전이 라이트버전이라서 기본적인 기능들만 포함되어져 있다.

$ sudo apt-cache search vim-full

$ sudo apt-get install vim-full

$ vi .vimrc

syntax on

추가하면 된다.




웅자가 쓰는 vimrc.

set nocompatible " VI 오리지널과 호환하는 모드를 사용하지 않음(VIM확장)

set number " 라인번호를 붙임

set backspace=indent,eol,start " BS로 라인끝과 처음 자동들여쓰기한 부분을 지날수 있음

set tabstop=4 " 탭문자는 4컬럼 크기로 보여주기

set shiftwidth=4 " 문단이나 라인을 쉬프트할 때 4컬럼씩 하기

set autoindent " 자동 들여쓰기

set visualbell " Alert 음을 화면 깜박임으로 바꿔보여주기

set laststatus=2 " 최종상태 2개 기억하기

set statusline=%h%F%m%r%=[%l:%c(%p%%)] " 상태표시줄 포맷팅

set hlsearch  " / ? 명령 등으로 찾은 문자열을 하일라이트 해준다.

syntax on " 적절히 Syntax에 따라 하일라이팅 해주기

set background=dark " 이건 터미널 모드에선 영향이 없다.

set hi=1000 "명령어 기록을 남길갯수 지정

set hlsearch " / ? 명령 등으로 찾은 문자열을 하일라이트 해준다.

set bs=indent,eol,start " 백스페이스 사용



set ru " 커서의 위치를 항상 보이게 함.

set ts=8 "탭 길이

set sts=4 "들여쓰기 탭 간격

set sw=4 " 들여쓰기 탭 간격

set noet " 탭 -> 공백 변환 기능 (사용 안함)

set sol "여러가지 이동 동작시 줄의 시작으로 자동 이동

set hls "검색어 강조 기능

set scs "똑똑한 대소문자 구별 기능 사용


imap <F2> <C-X><C-O>

map <F3> :set paste<CR>

map <F4> :set nopaste<CR>

vmap <F5> :norm i// i;<CR>

vmap <F6> :norm xx<CR>

vmap <F9> zf

map <F10> zo

map <F11> zc

map <C-b> :tabprevious<CR>

map <C-n> :tabnext<CR>

map <F12> :tabnew<CR>:e .<CR>

2006/09/08 15:58 2006/09/08 15:58
이 글에는 트랙백을 보낼 수 없습니다
Linux  2006/09/08 15:57
출처 블로그 > maxoverpro 블로그
원본 http://blog.naver.com/maxoverpro/140008222477

/etc/rc.d/rc3.d/S22nospoof에 위치시키고 방화벽 또는 라우터에 설치

/etc/rc.d/init.d/S22nospoof로 연결

#/bin/sh

#Turn on Source Address Verification on all interface

if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then

   echo -n "Enabling IP spoofing blocking..."

   for f in /proc/sys/net/ipv4/conf/*/rp_filter; do

       echo 1 > $f

   done

   echo "done"

else

   echo "ERROR : CANNOT SET UP IP SPOOF BLOCKING!"

   sleep 30

fi

2006/09/08 15:57 2006/09/08 15:57
이 글에는 트랙백을 보낼 수 없습니다
웅쓰:웅자의 상상플러스
웅자의 상상플러스
전체 (379)
게임 (5)
영화 (2)
기타 (23)
맛집 (5)
영어 (2)
대수학 (3)
형태소 (5)
Hacking (9)
Linux (112)
HTML (48)
Application_developing (48)
Web_developing (102)
Window (11)
«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
  1. 2016/01 (1)
  2. 2015/12 (3)
  3. 2015/10 (3)
  4. 2015/03 (2)
  5. 2015/01 (4)