2009년 4월 29일 수요일

RAID에 대한 소개 및 RAID를 이용한 시스템의 복구

RAID는 Redundant Array of Independent Disks의 줄임말이다. 스토리지 시스템에 RAID가 활성화되어 있으면 시스템에 두 개 이상의 드라이브를 연결하여 하나의 큰 드라이브처럼 사용할 수 있고 또는 시스템의 드라이브를 사용하여 사용자 데이터를 자동으로, 지속적으로 복제하여 실시간으로 백업하도록 설정할 수도 있다.

RAID의 장점

RAID 드라이브 시스템을 찾는 이유 세 가지:

   1. 아주 큰 스토리지 공간이 필요한 동시에 속도 또한 빨라야 한다. (RAID 0)
   2. 데이터를 지속적으로, 자동으로 백업하고 싶다. (RAID 1)
   3. 두 가지 다 원한다. (RAID 5)

어떤 RAID 모드를 사용해야 할까?

1. 속도 (RAID 0)

고성능 모드(일명 스트리핑 모드 또는 RAID 0)로 설정하면 다음의 경우 스토리지 시스템에서 사용자가 필요로 하는 파워를 제공 받을 수 있다.

    * 대용량 그래픽 디자인 및 매우 빠른 Photoshop 스크래치 공간이 필요.
    * 깨끗한 오디오 성능을 유지하면서 대용량 DV 파일을 녹화하려 할 때
    * DV 또는 HD 비디오 편집 및 프레임 드롭없는 부드러운 워크플로우 요구.
    * 복잡한 3D 오브젝트 또는 특수 효과를 렌더링할 때
    * 디스크 집약적인 데이터베이스 작업을 수행할 때
    * 놀라울 정도로 정말 빠른 컴퓨터에 처음으로 매료된 때

RAID 0의 속도가 빠른 이유가 무엇을가? 설명하기 약간 복잡하긴 하지만, 헤드는 두 개 또는 그 이상, 이 경우, 드라이브는 하나 이상인 것이 좋다고 말할 수 있다. 여러 개의 호스로 동시에 하나의 양동이에 물을 채우고 있는 사진과 여러 사람이 하나의 보트를 노젓고 있는 사진을 보면, 스트리핑한 두 개 드라이브가 왜 하나보다 더 빠른지 이해할 수 있다. 데이터는 양쪽 드라이브에 저장되고 액세스는 모든 드라이브에서 병렬로 가능하기 때문에 사용자는 대용량 데이터 액세스시 데이터 전송률을 높일 수 있고 작은 데이터에 액세스할 때는 입출력 속도를 높일 수 있다.

2. 데이터 보호 (RAID 1)

시스템을 데이터 보호 모드로 설정하면(일명, 미러링 모드 또는 RAID 1) 용량이 절반으로 나누어진다. 용량의 절반은 데이터 보관에 이용되고 나머지 반은 사본 복제에 이용된다. (서버운영시 많이 사용하는 RAID방식~)

그 런 중복성이 왜 필요한가요? 당신의 데이터, 가족 사진, 사랑스런 아기의 첫 걸음마에 관한 영상, 당신이 쓴 첫 소설. 다시 얻을 수 없는 중요한 자료이다. 또한 서버 운영시 한 HDD에 문제생김으로 인한 데이타의 유실 및 지속적인 서비스 등이 필요하기 때문에 RAID방식으로 시스템을 구성하면 더욱 안전하게 서버를 운영할 수 있다.

3. 데이터 보호 및 속도(RAID 5)

세 개 또는 그 이상의 드라이브를 갖춘 시스템(WD의 N8 TB WD ShareSpace™ 네트워크 스토리지 시스템처럼)의 경우 시스템을 RAID 5로 설정할 것을 권장한다. 이것이 최적의 구성이다. 모든 드라이브에 걸쳐 데이터를 스트리핑함으로써 성능을 높이고 각 드라이브의 1/4를 내고장성에 할애하고 나머지 부분은 데이터 저장 공간으로 남겨둠으로써 데이터 보호 성능을 최대화한다.

문제점 발생시 해결책

직접 /proc/mdstat를 읽는 방식으로 현재 구성된 RAID의 상태에 대하여 알아볼 수 있다. 하지만 이런 방식으로 상태를 알아보는건 그다지 효율적이지 못하다.

mdadm --detail를 이용하여 다중 하드 디스크 상태를 알아보는것이 더욱 편하고 효율적이다.

# mdadm --detail /dev/md2 | tail -n 3
   Number   Major   Minor   RaidDevice State
       0       8        3        0      active sync   /dev/sda3
       1       8       19        1      active sync   /dev/sdb3

위 예제는 md2 다중 하드 디스크 상태를 보여주는것이다.
상태를 보면 모두 active sync로 되었음을 알수 있다. 즉 RAID가 정상적으로 작동하고 있다.^^
만약 그중 한 하드디스크에 문제가 발생했다면 active sync대신 faulty spare라는 메세지가 뜰 것이다.

만약 이런 상황에 맞띄웠다면 당황해할 필요가 없다. 우리가 설치한 보조 하드디스크가 나머지 데이타를 고스란히 가지고 있기 때문이다. 우리가 해야 할 작업은 망가진 하드디스크만 빼내면 그뿐이다.

① mdadm MD_DEVICE --remove DEVICE를 이용하여 문제가 발생한 하드 디스크를 제거한다.
② 서버를 잠시 중지시키고 물리적으로 문제가 생긴 하드 디스크를 제거한다.
③ 정상적인 하드 디스크를 설치한후 새로운 파티션을 생성한다.
④ mdadm MD_DEVICE --add DEVICE를 이용하여 새롭게 만든 파티션을 md에 물린다.

실제 문제가 발생할 였을 때 해결하는 과정을 보여주면 다음과 같다.

# mdadm --detail /dev/md2 | tail -n 3
    Number   Major   Minor   RaidDevice State
       0       8        3        0      faulty spare   /dev/sda3
       1       8       19        1      active sync   /dev/sdb3
# mdadm /dev/md2 --remove /dev/sdb3
mdadm: hot removed /dev/sda3

reboot...

// 새로 파티션을 만들어 주는 과정이 필요함...

# mdadm --detail /dev/md2 | tail -n 3
    Number   Major   Minor   RaidDevice State
       0       0        0        0      removed
       1       8       19        1      active sync   /dev/sdb3

# mdadm /dev/md2 --add /dev/sdc3
mdadm: added /dev/sdc3

# mdadm --detail /dev/md2 | tail -n 3
    Number   Major   Minor   RaidDevice State
       2       8       20        0      spare rebuilding    /dev/sdc3
       1       8       19        1      active sync   /dev/sdb3

# mdadm --detail /dev/md2 | tail -n 3
    Number   Major   Minor   RaidDevice State
       0       8       20        0      spare sync    /dev/sdc3
       1       8       19        1      active sync   /dev/sdb3

2009년 4월 28일 화요일

SSH의 Brute Force Attak을 막기

가장 무식하지만서도 가장 확실한 SSH의 Brute Force Attack을 막기

SSH Brute Force Attack이란 흔한 사용자 이름과 암호로 ssh를 계속 접속해서 해킹을 시도하는 방법으로 잘못 이용되었을 경우 악영향을 끼친다. 기본으로 SSH 포트를 바꾸어버려 어느정도 SSH BFA를 막을 수도 있겠지만 확실한 해결책이 못된다.

방어방법
1. 강한 비밀번호 설정
2. RSA 인증 방식 사용
3. iptables를 이용한 패킷 Drop
4. sshd 로그를 이용하여 공격을 막기

1. 강한 비밀번호 설정
웬만하면 쉬운 비밀번호나 알아내기 쉬운 비밀번호를 쓰지 않도록 하는것이 좋다. 이미 쉬운비밀번호나 알아내기 쉬운 비밀번호들은 해커들의 Dic파일속에 존재하기 때문에 BFA를 몇시간째 돌리고 있으면 인츰 비밀번호가 깨질 수 있다. 특정된 구절의 이니셜을 이용하여 비밀번호를 설정하면 가장 좋다. 아니면 한글 사용자일 경우 다른 분의 이름 영문자타법에 특수문자 조합으로 설정하며 되겠다.
우점: 너무 심플하다.
결점: 비밀번호를 바꾸어도 BFA때문에 생기는 시스템 부하를 줄일수 없다.

2. RSA 인증 방식
기존에 비밀번호를 통한 인증방식보다 좀 더 고급적인 인증방식이다. 이런 방식으로 인증방식으로 바꾸면 일반 비밀번호를 통한 해킹은 전혀 의미가 없게 된다. ^^

① ssh-keygen -t rsa를 이용하여 RSA 키를 새로 생성한다. 위 명령어를 실행하면 /home/username/.ssh/id_rsa (private 키) and /home/username/.ssh/id_rsa.pub (public 키)가 생성된다.

# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
32-digit_hexadecimal_fingerprint username@hostname

② ssh 클라이언트 측 /home/username/.ssh/authorized_keys파일속에 기존에 만들어진 키들을 조합하여 넣는다. 알다싶이 이파일속에는 여러가지 public키들이 위치하여 이런 키들에 대한 관리가 용이해질 수 있다.
단 여기서 잊지 말아야 할 것은 authorized_keys를 만든 후 퍼민션을 필히 644로 세팅 해주어야 한다. 필자는 퍼미션을 정확히 세팅하지 않으므로 rsa인증이 잘 되지 않았다.

# cat /home/username/.ssh/id_rsa.pub >> /home/username/.ssh/authorized_keys
# chmod 644 /home/username/.ssh/authorized_keys

이렇게 생성된 authorized_keys파일을 ssh클라이언트측에 저장하여 매번 ssh접속시 사용 할 수가 있다. 위에 든 예제는 Linux상에서 public 키를 이용하여 인증하는 방식이고 윈도우에서 접속하려면 위 방식과 좀 다르다. 일단 쉘접속 툴로 많이 사용되는 SecureCRT에서 RSA 인증을 하는 과정을 보여주면 다음과 같다.
SecureCRT상에서 SSH세션을 새로 생성해준다. 다음 Session Option->Connection->SSH2 를 클릭하면 다음과 같은 대화창이 뜰거다.



위 대화창에서 볼 수 있다싶이 Authentication 방식에서 password란이 체크가 되지 않았다. Default값으로 password가 체크되어있을 것이다. 체크를 해제하고 Publickey를 선택한 상태에서 옆에 Properties버튼을 클릭하여 이미 생성한 RSA Public 키를 불러 들여오자.



단 주의할 점은 서버상 유저 루트 디렉토리 퍼미션이 700으로 설정이 되어야 정확히 인증이 된다. (이점은 좀 이상하다. 하지만 퍼미션을 707로설정하고 로그인을 시도한 결과 인증을 받을 수 없었다.)

③ 서버측 /home/username/.ssh/id_rsa 여기에는 이미 private 키가 생성이 되었으므로 별도의 작업이 필요 없다.

④ 마지막으로 /etc/ssh/sshd_config파일을 수정하여 비밀번호를 통한 인증방식을 무효화 한다. 또한 RSA Authentication 인증방식을 Yes을 바꾸어주고 주석문속에 해제한다.
마지막으로 service sshd restart하여 ssh데몬을 재시작 해준다.
우점: 보안이 상당히 믿음직스럽다. 일반 password방식보다는 한단계 업그레이드 된 인증 방식이다. 또한 password를 통한 무단 Brute Force Attack을 줄일 수 있다.
결점: 서버접속 할려면 public key를 갖고 있어야 할 뿐만 아니라 passphrase를 알고 있어야 한다. RSA인증 방식에 대한 이해를 못한 유저들은 이런 키를 자기절로 생성하여 쓸수 없으므로 다른 사람의 도움이 필요할것이다.

3. iptables를 이용한 패킷 Drop

① 정말로 약한 암호를 사용하는 사용자가 있을 경우 해당 계정이 해킹당할 수 있으며, 이 해킹당한 계정으로 로컬 커널 익스플로잇 등을 사용해서 루트를 빼앗길 수도 있다. 되도록이면 로컬 사용자를 적게 만들고 또한 만들었으면 비밀번호를 복잡하게 설정하여 이런 BFA를 어느정도 막을 수 있어야 한다. 하지만 해커가 사용하고 있는 Dictionary가 막강하면 암호를 복잡하게 만들었다 할지라도 뚤릴수 밖에 없게 된다.

② 그렇지 않더라도, 사용자 인증 로그(auth.log)에 짧은 시간 내에 수많은 실패 로그가 쌓여 다른 로그를 보는 데 방해가 될 수 있다.

③ 접속을 받는 동안 SSH 데몬이 암호학적 계산을 해야 하므로 시스템 자원을 소모할수도 있다.

iptables 는 리눅스 커널에 기본적으로 포함되어 있는 방화벽으로, 아주 다양한 방화벽 규칙을 만들 수 있으며, iptables 모듈을 사용해서 기능을 확장할 수도 있다. 다음은 iptables로 SSH Brute Force Attack을 막는 간단한 규칙이다. 이 규칙은 iptables 기본 모듈인 state와 recent를 사용한다.

state 모듈과 recent 모듈은 man 페이지에 자세하게 문서화되어 있기 때문에 문서를 참조하면 구체적인 사용법데 대하여 알수 있으므로 여기서는 생략하겠다. state 모듈은 언제 접속이 시작되고 끝나는지 추적할 수 있게 하고, recent 모듈은 IP 주소의 목록을 만들고 최근 접속 시간을 기록할 수 있게 한다.

규칙은 ssh 포트로 20초간 5회 이상 접속을 시도하면 10분간 접속을 차단하는 것이다.

우선 blacklist와 ssh 체인을 만든다.

# iptables -N blacklist
# iptables -N ssh

INPUT 체인에서 state 모듈로 ssh 포트인 22번 포트에 접속이 시작되면 ssh 체인으로 보낸다.

# iptables -A INPUT -m state --state NEW -p tcp --dport ssh -j ssh

blacklist 체인에서는 recent 모듈로 "blacklist"라는 목록에 접속 주소를 기록하고 접속을 거부한다.

# iptables -A blacklist -m recent --set --name blacklist
# iptables -A blacklist -j REJECT

규칙의 핵심인 ssh 체인은 다음과 같다.

# iptables -A ssh -m recent --update --seconds 600 --hitcount 1 --name blacklist -j REJECT
# iptables -A ssh -m recent --set --name ssh
# iptables -A ssh -m recent --update --seconds 20 --hitcount 5 --name ssh -j blacklist
# iptables -A ssh -j ACCEPT

이 규칙을 순서대로 설명하면 다음과 같다.
첫 번째 규칙은 접속 주소가 이미 "blacklist"에 들어 있고, 지난 10분간 1회 이상 접속이 있었으면 접속을 거부한다.
두 번째 규칙은 접속 주소를 "ssh" 목록에 기록한다.
세 번째 규칙은 접속 주소가 이미 "ssh" 목록에 들어 있고, 지난 20초간 5회 이상 접속이 있었으면 blacklist 체인으로 보낸다.
네 번째 규칙은 여기까지 통과한 경우 ssh 접속을 허락한다.

따라서 전체 스크립트는 다음과 같이 된다.

iptables -N blacklist
iptables -N ssh
iptables -A INPUT -m state --state NEW -p tcp --dport ssh -j ssh
iptables -A blacklist -m recent --set --name blacklist
iptables -A blacklist -j REJECT
iptables -A ssh -m recent --update --seconds 600 --hitcount 1 --name blacklist -j REJECT
iptables -A ssh -m recent --set --name ssh
iptables -A ssh -m recent --update --seconds 20 --hitcount 5 --name ssh -j blacklist
iptables -A ssh -j ACCEPT

4. sshd 로그를 이용하여 공격을 막기
서버에 들어오는 ssh 공격에 대하여 sshd 데몬은 그것들을 특정된 로그파일에 저장해주고 있는데 이렇게 생성된 파일을 참조하고 몇가지 프로그램을 조합하여 사용하는 것을 통하여 ssh 공격을 막을 수 있다.

① sshdfilter는 iptables를 이용하여 블럭을 한다. 동작방식은 상당히 간단한데 firewall 룰을 iptables에 추가하여 특정된 공격을 막는것이다. 이 방식으로 공격을 막기위하여 sshd데몬대신 sshdfilter데몬을 작동시켜야 한다. sshdfilter데몬은 sshd데몬과 흡사한데 단지 다른점이라면 생성된 log에 대한 분석을 해준다는것이다.

② Fail2Ban은 일종 Python스크립트인데 이 스크립트는 sshd로그에 근거하여 커스텀 Firewall룰을 적용시키는 방식으로 공격을 막는다. 공격을 막기 위하여 사용되는 툴로는 iptables, ipfwadm 혹은 ipfw등이다.

③ DenyHosts는 firewall을 이용하여 공격을 막는것이 아니고 관련 룰들을 /etc/hosts.deny에 써주는 방식으로 공격을 차단한다. 단 이것을 사용하기 위하여서는 sshd 데몬이 컴파일 될시 tcp_wrappers를 지원하게끔 되어있어야 한다. 사실 DenyHosts도 Python 스크립트로 씌여졌다. tcp_wrappers를 지원하고 있는 지를 판단하는 방법은 상당히 심플한데 직접 hosts.deny를 편집하고 그 속에 127.0.0.1를 넣어준 상태에서 서버에서 ssh방식으로 자기자신을 접속하게 한다. 만약 접속이 안되면 tcp_wrappers를 지원하고 있는것이다.

참조문서: http://la-samhna.de/library/brutessh.html

2009년 4월 27일 월요일

DoS 공격 방어 모듈 mod_evasive 설치기

1. mod_evasive이란 무엇인가?

이것은 HTTP Dos 또는 DDos 스택 또는 저돌적인 공격으로부터 아파치를 보호하는데 있다. 또한 ipchains, 방화벽, 라우터등으로 쉽게 구성될 수 있도록 디자인 되었다.
탐지는 주소, URI의 IP 내부 동적 해쉬테이블을 생성함으로 수행되고, 각 아이피별로 거부된다.
- 초당 몇번 이상의 같은 페이지를 요청하는 경우
- 초당 같은 자식노드를 동시에 50번 이상 생성하는 경우
- 일시적으로 블러킹되는 동안 어떠한 요청을 생성하는 경우

2.  mod_evasive의 설치

# wget http://www.zdziarski.com/projects/mod_evasive/mod_evasive_1.10.1.tar.gz

# 압축해제
# tar xvzf mod_evasive_1.10.1.tar.gz

# 디렉토리 이동
# cd mod_evasive

# 모듈 추가
# /usr/local/apache2/bin/apxs -iac mod_evasive.c -> Apache.1.x
# /usr/local/apache2/bin/apxs -iac mod_evasive20.c -> Apache.2.x

# 환경설정
# vi /usr/local/apache2/conf/httpd.conf

# 아파치 1.X와 2.X에서의 모듈명칭이 약간 차이가 있으므로 주의할 것!
# 아래에 해당하는 내용이 존재하는지 확인 한다. 없으면 추가.

LoadModule evasive_module    modules/mod_evasive.so -> Apache.1.x
LoadModule evasive20_module    modules/mod_evasive20.so -> Apache.2.x

<IfModule mod_evasive.c>
        DOSHashTableSize        3097
        DOSPageCount              3
        DOSSiteCount                50
        DOSPageInterval            1
        DOSSiteInterval              1
        DOSBlockingPeriod        30

        DOSEmailNotify            webmaster@yoursite.com
        DOSLogDir                   "/usr/local/apache2/logs/mod_evasive.log"
        DOSSystemCommand      "su - someuser -c '/sbin/... %s ...'"
</IfModule>

# 환경설정 검사
# apachectl configtest
# 재시작
# apachectl -k restart

3. 각 지시자에 대한 설명

- DOSHashTableSize
각 자식 해쉬테이블 마다 탑레벨 노드의 수를 지정한다.
수치가 높으면 높을수록 더 많은 퍼포먼스가 나타나지만 테이블스페이스에 메모리를 남기게 된다, 접속량이 많으면 이 수치를 높혀도 된다.

- DOSPageCount
이것은 같은 페이지 또는 URI, 인터벌당 요청수에 대한 카운트 수이다.
지정된 값이 초과되면 클라이언트에 대한 IP 정보가 블러킹리스트에 추가된다.

- DOSSiteCount
지정된 시간동안 같은 페이지를 지정된 수 보다 초과될경우 IP 정보가 블러킹리스트에 추가된다.

- DOSPageInterval
페이지 카운트 시발점, 디폴트는 1초이다.

- DOSSiteInterval
사이트 카운트 시발점, 디폴트는 역시 1초이다.

- DOSBlockingPeriod
클라이언트가 블랙리스트에 추가되어 블러킹되는 총 시간. 이때 클라이언트는 403 (Forbidden) 에러를 출력하게 된다.

- DOSEmailNotify
이 값이 지정되면, IP가 블러킹될때마다 지정된 이메일로 발동된다.
주의 : 메일러는 mod_dosevasive.c 에 정확하게 지정되야 한다. 디폴트는 "/bin/mail -t %s" 이다.

- DOSLogDir
로그 파일 경로

- DOSSystemCommand
이 값이 지정되면, 시스템은 아이피가 블러킹될때마다 명령행을 실행한다.

- DOSWhitelist
차단에서 제외될 호스트
DOSWhitelist    127.0.0.1
DOSWhitelist    127.0.0.* - (와일드카드는(*) 필요하다면 최대 8진수(xxx.*.*.*)까지 사용할 수 있다.)


4. 테스트하기

# perl test.pl <- 다운받은 파일 안에 포함되어 있다.
   HTTP/1.1 200 OK
   HTTP/1.1 403 Forbidden
   HTTP/1.1 200 OK
   HTTP/1.1 403 Forbidden
   HTTP/1.1 403 Forbidden

5. 같이쓰면 좋은 iptables

흔히 DOS 공격방어라고 하면 mod_evasive 모듈을 사용한다고 알려져 있다.
특히, 과도한 DOS 공격이 들어올 경우 아파치가 부하를 견디지 못하고 죽어버리는 경우도 생긴다. 따라서 과다 접속 차단에 대해서는 iptables를 이용하시는것이 근본적이고 효과적 이다.
iptables를 보게되면 connlimit 기능이 있는데 이 설정을 잘 이용하시면
매우 효과적이고 안정적인 서버 운영이 가능하다.

# 1초에 10번 이상의 HTTP 접근을 할경우 (DOS공격) 접근을 차단한다. 단 여기서 지정하는 아이피 Range는 C클래스에만 해당하다. 여기서 mask 24를 이용하여 이를 지정했다.
# iptables -I FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 24 -j DROP

# 매 아이피당 최대 5개의 동시 연결 갯수만 허용. 80포트에 한해서...
# iptables -I FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 5 -j DROP

# 포트스캔을 차단한다.
# psd match를 사용하기 위하여 커널에 p-o-m패치를 적용시켜 놓아야 한다.
# 상세한 사항은 여기를 클릭하여 확인하기 바란다.
# iptables -A INPUT -m psd -j DROP

# 만약서버가 해킹당해 DOS공격지로 사용될때 적용시킴.
# DNS 쿼리이외에 UDP 패킷이 나가는 것을 방지
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A OUTPUT -p udp ! --dport 53 -m state --state NEW -j DROP

이렇게 설정한 iptable룰들을 iptables를 재 시작하면 먹히지 않습니다. 삭제 되는거죠.
이를 유지시키려면 iptables 설정에 저장 시켜야 합니다.
/etc/init.d/iptables save를 통하여 저장 하면 되겠죠?!

CentOS 5.3 + Kernel 2.6.29.1 + iptables 의 connlimit 모듈 설치하기

CentOS에 최신커널을 컴파일하여 넣어 보자~

iptables를 건드리다가 connlimit옵션이 먹히지 않아서 찾아보니 현재 사용중인 커널 버젼이 낮음으로 하여 먹히지 않았던 것이 였다.
간단히

# cat /proc/net/ip_tables_matches

를 통하여 현재 iptables상에 올라온 모듈들을 볼 수 있다.
connlimit 모듈이 깔리지 않은 상태에서 해당 모듈이 리스트에 뜨지 않을 것이다.

1. 최신 커널 및 iptables 소스 파일 다운로드 및 설치
현재 커널 버젼을 아래 명령어를 통하여 알아보도록 하자.

# uname -a
Linux localhost 2.6.18-128.el5 #1 SMP Wed Jan 21 10:44:23 EST 2009 i686 i686 i386 GNU/Linux

위에서 보다싶이 현재 사용중인 커널 버젼은 2.6.18이다.
http://www.kernel.org 에 접속하여 최신버젼 커널을 다운로드 받아 온다.

Kernel 2.6.29.1 => http://www.kernel.org/
Iptables 1.4.3.2 => http://www.netfilter.org/
정확히 다운로드 되었으면 다운로드 받은 커널 소스는 /usr/src에 압축을 풀고 iptables소스는 /usr/local/src/에 압축을 풀어놓는다.

# cd /tmp
# wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.29.1.tar.bz2
# wget http://ftp.netfilter.org/pub/iptables/iptables-1.4.3.tar.bz2
# tar xvfj linux-2.6.29.1.tar.bz2 -C /usr/src
# tar xvfz iptables-1.4.3.2.tar.bz2 -C /usr/local/src

작업을 좀 더 편하게 하기 위하여 미리 심볼릭 링크를 걸어 둔다.

# ln -s /usr/src/linux-2.6.29.1 /usr/src/linux

커널 소스 디렉토리로 들어갔으면 기존에 정상적으로 사용하던 커널의 환경옵션을 그대로 가져 와서 컴파일하는 것이 좋다.
/boot 디렉토리 안을 보면 이름이 config 로 시작하는 커널 환경 변수 정보가 담겨있는 파일들이 있는데 이 중 가장 최근까지 정상적으로 사용해 오던 파일을 복사해다가 /usr/src/linux 디렉토리 안에 .config 라는 이름의 파일로 저장해서 불러들이는 방식을 취하면 된다.

# cp /boot/config-2.6.18-128.el5 /usr/src/linux/.config

2. 커널 설정 및 컴파일
자~ 기본적으로 커널 설정을 하기 위한 초기 작업이 끝났다.
새로 받은 커널 소스 폴더로 이동하여 커널 설정을 해주겠다.

# cd /usr/src/linux
# make menuconfig

제일 하단에서 2번째에 있는 Load an Alternate Configuration File 메뉴를 통해 .config 파일을 로드한다.

Networking --> Networking option --> Network packet filtering framework (Netfilter) 옵션으로 들어가서
Core Netfilter Configuration을 비롯하여 넷필터, iptables 관련 모듈을 모두 체크하고 빠져 나온다.
Core Netfilter Configuration 옵션 안의 모듈들은 가급적 <M> 체크하여 모듈 형태로 저장한다.
iptables관련 모듈들은 하나가 모듈로 컴파일되면 다른 것들도 모듈로 되기를 요구하는 것 같다. connlimit 모듈은 중간 쯤에 나온다. 이해를 돕기 위하여 아래에 스크린샷을 첨부하겠다.


또한 IPv4 컨넥션 트래킹 모듈까지 설치하겠다. NAT에는 필수니까...


# make bzImage
# make modules
# make modules_install
# make install

make install하면 아래와 같은 Warning문이 뜬다.

WARNING: No module dm-mem-cache found for kernel 2.6.29.1, continuing anyway
WARNING: No module dm-message found for kernel 2.6.29.1, continuing anyway
WARNING: No module dm-raid45 found for kernel 2.6.29.1, continuing anyway

일단 커널 설치에는 영향을 주지 않으므로 건너뛰겠다.

마지막으로 grub.conf파일을 편집하여 부팅시 우리가 새로 빌드한 커널을 기본으로 로드하겠다.
/boot/grub/grub.conf를 편집기로 열고 hiddenmenu를 주석문속에 넣는다.
이렇게 하면 부팅할 때 두가지 커널을 alternative하게 선택할 수 있게 된다.
또한 우리가 새로 컴파일한 커널을 Default커널로 띠우기 위하여 default값 1을 0으로 고친다.
서버를 재부팅하면 새롭게 컴파일된 커널을 만날 수 가 있다.^^

새로 부팅하고 uname -a를 쳐보자.

# uname -a
Linux localhost 2.6.29.1 #1 SMP Mon Apr 27 15:30:11 CST 2009 i686 i686 i386 GNU/Linux

정확히 우리가 원하는 커널로 부팅이 되었음을 확인 할 수 있다. 이로써 커널 설치는 끝마리를 맺는다.

3. iptables 설치
자 이제 그럼 iptables를 새로 컴파일 하여 connlimit 모듈을 추가해보자.
일단 새로 부팅한후
# iptables -L -n
해보면 아무내용도 뜨지 않음을 발견할 수 있다.
setup을 이용하여 새로 설정을 한후 iptables 을 내렸다 올리자.

# lsmod | grep connlimit 해보면 모듈이 로드 되지 않았음을 알 수 있다.
# modprobe xt_connlimit 하여 connlimit 모듈을 로드하여 보자.
# lsmod | grep connlimit
xt_connlimit            3500  0
nf_conntrack           58828  4 xt_connlimit,nf_conntrack_netbios_ns,nf_conntrack_ipv4,xt_state
x_tables               13864  7 xt_connlimit,ip_tables,ip6t_REJECT,ip6_tables,ipt_REJECT,xt_state,xt_tcpudp

정확히 로드가 되었음을 확인 할 수 있다. (커널에 컴파일하여 넣었으니 로드가 않되면 이상하다.ㅎㅎ)

여기서는 기존의 rpm 버전 iptables를 삭제하지 않고 그 위에 소스컴파일로 덮어씌우는 방식으로 진행을 하겠다.
왜냐하면 rpm 버전을 삭제한 뒤 소스로 새롭게 설치하게 되면 기존의 rpm 버전에서 제공하던 system-config-securitylevel, lokkit, /etc/rc.d/init.d/iptables 와 같은 실행 스크립트 파일이 존재하지 않기 때문에 따로 스크립트로 구현하지 않는 한 일일이 iptables 룰을 추가해야 하는 불편함을 감수해야 한다.
다행스럽게도 iptables를 소스로 설치하게 되면 바이너리 파일, 환경설정 파일, 라이브러리 등이 rpm 버전과 거의 동일한 경로에 설치되므로 rpm 버전 위에 덮어 씌워 설치하면 기존의 관련 명령어를 그대로 활용할 수 있다는 장점이 있다. (찝찝함이 남아 있는것만은 사실이다. 허나 노가다를 줄이기 위해서는 이 방법이 최상책일 것이다.)
잠시 iptables를 중지하겠다.

# service iptables stop

# cd /usr/local/src/iptables-1.4.3.2
# ./configure
# make
# make install

이제 기존의 rpm 버전 iptables에서 사용되던 명령어들을 백업하고 새로 설치한 소스 버전의 명령어들로 교체하는 작업이 필요하다.
/sbin 디렉토리안의 iptables 관련 명령 삭제 후, /usr/local/sbin 아래에 생성된 iptables 관련 명령들을 심볼릭 링크한다.(총 8개 명령)

# cd /sbin
# mv ip6tables ip6tables.old
# mv ip6tables-restore ip6tables-restore.old
# mv ip6tables-save ip6tables-save.old
# mv iptables iptables.old
# mv iptables-restore iptables-restore.old
# mv iptables-save iptables-save.old

심볼릭 링크를 걸어줄 대상들을 확인해보자~
# ls /usr/local/sbin
ip6tables  ip6tables-multi  ip6tables-restore  ip6tables-save  iptables  iptables-multi  iptables-restore  iptables-save

# ln -s /usr/local/sbin/ip6tables /sbin
# ln -s /usr/local/sbin/ip6tables-restore /sbin
# ln -s /usr/local/sbin/iptables /sbin
# ln -s /usr/local/sbin/iptables-restore /sbin
# ln -s /usr/local/sbin/ip6tables-multi /sbin
# ln -s /usr/local/sbin/ip6tables-save /sbin
# ln -s /usr/local/sbin/iptables-multi /sbin
# ln -s /usr/local/sbin/iptables-save /sbin

iptable을 버젼을 확인 해보면...

# iptables -V
iptables v1.4.3.2

iptables가 정확히 업그레이드 되었음을 볼 수 있다.

# service iptables start
# iptables -L -n

기존에 룰들이 그대로 존재하고 있을 것이다.

connlimit 모듈을 적용해보자.

공개 웹방화벽 ModSecurity 모듈 설치기

인젠 웹에도 방화벽을 씌울 시기가 왔다~

리눅스에 기본으로 깔린 iptables을 제외하고도 여러가지 방화벽이 많다.
이번엔 Apache 보안 모듈인 웹방화벽 ModSecurity를 설치하여 보겠다.
ModSecurity는 Ivan Ristic이 개발한 Apache 웹서버용 공개 웹방화벽으로 PHP Injection 공격 등 Apache 웹서버의 주요 공격 차단 가능하다.

1. ModSecurity 다운로드 및 설치
ModSecurity공식 웹사이트에 접속하여 최신 버젼으로 다운로드 받는다.
다운로드 받을 파일을 모두 두개인데 하나는 ModSecurity 소스파일이고 다른 하나는 Core Rule파일이다.

다운로드: http://www.modsecurity.org/download/index.html

설치과정은 무난하다.

단지 설치하기 전에 mod_unique_id 모듈이 Apache에 설정이 되어져야 한다.
또한 libxml2 라이브러리가 설치된 상태여야 한다.

# tar xvfz modsecurity-apache_2.5.9.tar.gz -C /usr/local/src
# cd /usr/local/src/modsecurity-apache_2.5.9/apache2
# vi modsecurity_config.sh
./configure \
--with-apxs=/usr/local/apache2/bin/apxs \
--with-httpd-src=/usr/local/src/httpd-2.2.11 \
--with-libxml=/usr

# chmod 700 ./modsecurity_config.sh
# ./modsecurity_config.sh
# make
# make install

이러게 되면 /usr/local/apache2/modules/mod_security2.so 모듈 파일이 생긴다.

httpd.conf 파일을 vi로 열고

LoadModule security2_module modules/mod_security2.so

Apache를 재시동 한다.

2. ModSecurity 설정
ModSecurity 기본 설정 Core Rule을 받고 압축을 풀어서 Apache2가 설치된 경로의 conf/modsecurity에 넣는다.

tar xvfz modsecurity-core-rules_2.5-1.6.1.tar.gz -C /usr/local/apache2/conf/modsecurity

httpd.conf파일을 열고 Include conf/modsecurity/*.conf 을 추가한다.
최소 Rule을 적용할려면 modsecurity.minimal.conf파일을 복사하여 conf/modsecurity에 넣고 저 파일을 인클루드 하면 되겠다.
각 Sample Rules에 대한 설정 파일들의 용도는 다음과 같다.

modsecurity_crs_20_protocol_violations.conf
정상적인 http protocol 위반접속요구(request header)
modsecurity_crs_21_protocol_anomalies.conf
정상적인 http protocol 위반접속요구(request header)
modsecurity_crs_30_http_policy.conf

http 정책에 대한 룰
modsecurity_crs_35_bad_robots.conf
User-Agent에 대한 룰 : 고급화된 공격차단보다는 스캐너등 차단목적
modsecurity_crs_40_generic_attacks.conf
SQL injection / PHP injection / Command access 에 대한 룰
modsecurity_crs_45_trojans.conf
trojan이나 백도어에 대한 접근 룰
modsecurity_crs_50_outbound.conf
에러등 특정 결과값을 통해 정보를 취득하려는 시도 차단

구체적인 Rule설정을 볼려면 첨부한 문서를 참조하면 되겠다.

2009년 4월 26일 일요일

iptables에 대한 이모저모

iptables 초보 딱지 떼기 강좌~

서버 세팅을 하다보면 필수로 장악해야 할 부분이 바로 방화벽 설정이다.
리눅스상에서는 iptables를 이용하여 방화벽을 구축할 수 있다. 하지만 그 설정들이 복잡하여 처음 접해보는 사람들은 구조에 대하여 파악하기 힘들다.
이 강좌는 인터넷을 돌아다니면서 모은 강좌들을 입맛에 맛게 새로 편집한것이다.

1. 패킷필터링의 기본 배경 지식

패킷필터링은 지나가는 패킷의 해더를 보고 그 전체 패킷의 운명을 결정하는 것을 말한다. (iptables의 경우 많은 개발중인 기능에서 헤더에 그치지 않고 data의 내용을 검토하기도 한다. 가장 대표적인것이 string match기능이다.)
일반적으로 패킷은 헤더와 데이타를 가진다. 헤더에 필터링할 정보인 출발지IP:PORT,도착지 IP:PORT, checksum,프로토콜 옵셋등을 가지며 데이터는 각각의 전송데이터가 들어간다.

Netfilter이란?
일반 iptables사용자들이 가장간과하기 쉬운부분중 한 부분이다.
iptables이 패킷을 필터링 하는것이 아니다.
패킷필터링은 커널에 탑제된 netfilter기능으로 하며
iptables은 단지 netfilter의 룰을 세워줄 뿐이다.
즉 다시 말하자면 iptables은 룰셋구축 툴이라는 말이다.

2. 패킷필터링에 대한 심층적인 이해

iptables에 대해

iptable에 기본 Chain은 아래와 같다.

INPUT chain
FORWARD chain
OUTPUT chain

위의 3가지가 기본 체인이다. 체인들의 모식도는 아래와 같다.

------>INPUT------> Linux Box ------>OUTPUT--------->
---------↕-------------------------------↕
---------└---------- FORWARD ---------┘

여러분의 Linux box를 도착지로 삼는 모든패킷은 INPUT Chain을 통과하게 되며
여러분의 Linux box에서 생성되 외부로 보내지는 모든패킷은 OUTPUT Chain을
통과하게 된다.

Forward chain은 엄밀히 말하자면 도착지가 여러분의 Linux box가 아닌 패킷이 통과하게 되는 체인이다.

# iptables -A INPUT -j DROP

엔터키를 누르는 즉시 여러분의 Linux box로 오는 패킷은 모두 거부당할것이다. 즉 모든 통신이 끊어진다.

위의 룰을 굳이 말로 옮기자면

-A:룰을 추가한다
INPUT: 패킷이 들어오는 체인에
-j:패킷의 운명을 결정한다.
DROP: 패킷을 버려라.

즉, INPUT체인으로 들어오는 패킷을 모두 버리는 룰을 추가하는 명령이다.

적용시킨 룰을 보고 싶다면

# iptables -L

이라는 명령을 치면된다.

-A와 같은 위치에 있는 옵션은 아래와 같다.

체인에 새로운 규칙을 추가하기 (-A)
체인의 어떤 지점에 규칙을 삽입하기 (-I)
체인의 어떤 지점의 규칙을 교환하기 (-R)
체인의 어떤 지점의 규칙을 제거하기 (-D)
체인에서 일치하는 첫번째 규칙을 제거하기 (-D)

이제 위에서 내린 룰을 지워 통신이 되게 하자.
아래와 같이 명령을 내리면 된다.

# iptables -D INPUT 1
또는
# iptables -D INPUT -j DROP 하면 될것이다.

첫번째 방법은 index(룰의 순서)를 지정해서 지우는 방법이고, 두번째는 룰의 내용으로 지우는것이다.

Chain INPUT (policy ACCEPT)

(policy ACCEPT)를 설명하자면 여러분들이 세운룰에 해당되지 않을때
마지막으로 기본정책을 따라 패킷의 운명을 결정하게 된다. 여기서는 ACCEPT이므로
패킷은 받아드려질것이다. 하지만 이것을 DROP으로하면 패킷은 버려질것이다.

이제 기본정책을 바꾸어 보자.

# iptables -P INPUT DROP

위의 명령을 내리고 다시 iptables -L을 하면

Chain INPUT (policy DROP)으로 된걸 볼수있다.

-P와 동등 위치의 옵션은 아래와 같다.

새로운 체인 만들기 (-N).
비어있는 체인을 제거하기 (-X).
※ 이 두옵션은 직접체인을 만들었을경우와 제어할경우에 해당된다. 기본체인(INPUT,OUTPUT,FORWARD) 에는 해당되지 않는다.

미리 만들어진 체인의 정책을 바꾸기 (-P)
어떤 체인의 규칙들을 나열하기 (-L)
체인으로부터 규칙들을 지우기 (-F)
체인내의 모든 규칙들의 패킷과 바이트의 카운드를 0 으로 만들기 (-Z)

3. 패킷의 목적지또는 출처 제어

패킷출처 제어옵션 -s

# iptables -A INPUT -s 192.168.0.10 -j DROP

위에 같은 명령을 내렸다면 192.168.0.10으로 부터 온 패킷은 모두 버려지게 된다.

-s(--source,--src와 같은 옵션이다.) : 패킷의 출처 IP 지정

목적지 제어옵션 -d

# iptables -A INPUT -d 192.168.0.12 -j DROP

위와 같은 명령을 내렸다면 192.168.10.12의 IP를 도착지로 가지고있는 패킷은 모두 버려지게된다.

-d(--destination,--dst와 같은 옵션이다.): 패킷의 도착지 IP지정

※ IP지정 이외에 몇 가지 방법이 더 존재한다.
-s www.xxxx.com : 도메인으로 제어
-s 192.168.0.0/24 : 네트워크 또는 집단으로 제어
-s 192.168.0.0/255.255.255.0 :위와 동일

※ 보통 프로그래밍 약속기호처럼 !는 역('not')이라는 것을 표시한다.
ex) -s ! 192.168.0.10 이라고 하면 "출발지가 192.168.0.10이 아닌" 이라는 뜻이된다.

4.프로토콜 제어

프로토콜제어 옵션은 -p이다

-p옵션의 인자는 TCP,UDP,ICMP가 될수있다.

# iptables -A INPUT -p TCP -j ACCEPT

라는 명령을 내렸다면 tcp프로토콜을 쓰는 모든 패킷은 ACCEPT에 의해 허락될것이다.

※ -p의 인자로 TCP,UDP,ICMP의 프로토콜번호를 알고있다면 번호를 써도 상관없다.

포트 제어

포트제어 옵션은 --sport와 --dport이다

--sport는 패킷의 출발지 포트이다.( --source-port와 같은 옵션이다.)

--dport는 패킷의 도착지 포트이다.( --destination-port와 같은 옵션이다.)


# iptables -A INPUT -p tcp --dport 80 -j DROP

위와 같은 명령은 tcp프로토콜의 80(www:웹서버포트)번 포트를 목적지로 하는 패킷을
버리는 것이다.

※ --dport나 --sport의 인자로 서비스이름을 적어도 된다.
ex) --dport www

※ 여러 포트를 지정해야 된다면 --dport 1024:65535 와 같이 지정할수있다.
뜻은 1024 부터 65535번까지라는 뜻이다.

5. 인터페이스 지정

인터페이스는 -i (input interface), -o (output interface)로 지정할수있다.

# iptables -A INPUT -i eth0 -p tcp --dport 80 -j DROP

위의 명령은 -i eth0옵션을 빼고는 port지정 예와 같다.

-i eth0는 eth0로 들오는 모든 패킷을 뜻한다.

보통 리눅스 박스처럼 인터넷과 연결된 디바이스가 1개라면 필요없는 옵션이 되겠지만
만약 eth0, eth1등 2개이상의 인터페이스가 인터넷과 연결되어있다면 위의 옵션은 유용하게 쓰일것이다.

※ INPUT 체인은 -i 옵션만 쓸수 있고, OUTPUT 체인에는 -o옵션만 쓸쑤있다.
반면에 FORWARD 체인은 -i,-o 옵션 두가지 다 쓸쑤있다. 이유는 다음문서에서 다루겠다.

총괄적인 예:

# iptables -A INPUT -i eth0 -d 192.168.0.10 -p tcp --dport 80 -j DROP

해설: INPUT 체인에 - 입력인터페이스가 eth0이고 도착지가 192.168.10.10이고
프로토콜은 tcp이며 도착 포트는 80(www)인 패킷은 DROP시켜라.

이제까지는 별 다른 지식이 없이도 이해할수있는 부분이었다.
하지만 지금부터 나오게될 내용은 tcp/ip의 기반적인 지식을 가지고있어야
이해하기 쉬울것이다.
tcp/ip지식이 필요한 옵션에 대해서는 그에따른 자세한 설명을 하겠지만
이해가 되지 않는 부분은 다른 문서나 책을 찾아보길 바란다.

6. 패킷의 행동 유형에 따른 필터링(--tcp-flags,m state --state)

! 주의 : 밑에 나오는 모든옵션은 TCP프로토콜옵션(-p TCP)가 먼저
선행되어 있어야 적용되는 옵션이다.

① --tcp-flags 옵션은 상태에 따라 유용하게 설정할수있다.
이 옵션을 설정하는 가장 큰 예는 한방향으로만 통신이 되게끔설정하기 위해
많이 사용한다.
tcp/ip는 3핸드쉐이크의 접속방식이다.
즉. 접속요청패킷,접속허가 패킷,확인패킷

접속 단계를 좀더 자세하게 보면

C: Client S:Server

1) C --------- syn -------▷ S
2) C ◁------- syn ack ----- S
3) C --------- ack -------▷ S

이런식으로 접속절차가 이루어진다.

syn패킷은 접속요청 플래그(syn)가 설정된 패킷이므로 syn패킷만 막으면 상대편에서 접속을 할수 없다는 것이다.

※ Dos공격의 일종인 Syn Flooding이 서버에 위에서 말한 syn형패킷을 무수히 많이
보내는 것이다.

이제 본격적으로 --tcp-flags옵션으로 syn 접속형 패킷을 막는것을 하겠다.

# iptables -A INPUT -p TCP --tcp-flags SYN,RST,ACK SYN -j DROP

--tcp-flags에 첫번째 인자는 검사할 리스트 마스크이다.
두번째 인자는 설정되어있어야할 플래그다.
즉 syn,rst,ack플래그중 syn이 set이 1로 되어있으면 위의 --tcp-flags설정에
해당이 되므로 패킷은 DROP된다.

위의 옵션과 같은 뜻을 가진것이 있는데 그것은 --syn이다.
--syn은 '--tcp-flags SYN,RST,ACK SYN'의 뜻을 가지고 있다.

② --tcp-flags보다 더 간단하게 설정하는 방법이 있다.
바로 tcp의 상태천이 다이아그램을 축소시켜 놓은듯한 느낌을 받는 상태에 따른 패킷분류를 iptables은 지원한다.

이것은 확장기능이므로 -m 플래그로 설정은 한다.

사용옵선은 -m state --state 이다.

인자값으로 들어가야할 상태에따른 리스트는 아래와 같다.

NEW : 새로운 접속을 만드는 패킷

ESTABLISHED :존재하는 접속에 속하는 패킷 (즉, 응답 패킷을 가졌던 것)
즉 접속이 허가되고 통신하면서 발생되는 패킷이다.

RELATED :기존의 접속의 부분은 아니지만 연관성을 가진 패킷으로 .
ICMP 에러 나 (FTP 모듈이 삽입 되어있으면) ftp 데이터
접속을 형성하는 패킷.

INVALID :어떤 이유로 확인할 수 없는 패킷. 알려진 접속과 부합하지 않는 ICMP 에러와 'out of memory' 등을 포함한다. 보통 이런 패킷은 DROP 된다.

이제 이 state 옵션을 사용해보자

위의 --tcp-flags옵션에서 예제와 같은 작용을 하는 룰을 만들어보겠다.

# iptables -A INPUT -p TCP -m state --state NEW -j DROP

왜 룰이 이렇게 되는지 차근차근 읽어보았다면 쉽게 이해가 될것이다.

일반적으로 서버는

# iptables -A INPUT -p TCP --dport 특정포트 -m state --state NEW, ESTABLISHED -j ACCEPT

이렇게 룰을 많이 세운다.
뜻은 tcp 특정 포트에 new:접속패킷과,established:통신패킷(정확히 쉽게 설명할
단어가 생각나지 않아 부적절하지만 통신패킷이라 부른다)을 허용하라.

그리고 클라이언트 측에서는 위의 state상태에서 NEW를 빼고 사용한다.

# iptables -A INPUT -p TCP --sport 특정포트 -m state --state ESTABLISHED -j ACCEPT

왜 NEW를 뺄까? 그 이유는
그 이유는 클라이언트입장에서 보면 접속을 허가해달라는 패킷이 필요없다는것이다.
더 쉽게 말하자면 클라이언트는 접속허가를 요청하는 위치이지 요청받는
위치가 아니라는 말이다.
그러므로 ESTABLISHED만 있으면 일반적으로 통신하는데 아무런 문제가 없다

그리고 주의깊게 본 사람이라면 위에 --sport가 쓰여진것을 볼수있을것이다.

왜 서버에서는 --dport로 제어를 하면서 클라이언트는 --sport로 제어를 할까?

지금 리눅스 박스라면 wget을 쓰던지 x-windows에서 브라우져를 쓰던지 아무런 웹사이트에 접속을 하고 바로 콘솔에서 'netstat -nat'라는 명령을 내려보자.

무슨말인지 알겠는가?

서비스를 한번이라도 해본적있는 사람이면 알겠지만 서버는 특정PORT를 열어놓고 접속을 기다린다.
클라이언트는 특정 서버에 접속을 하기 위해 별도로 포트를 생성하고 접속을 시도한다.
이때 클라이언트가 생성하는 포트번호는 1024이후의 랜덤값이다. 이런이유로 클라이언트입장에서는
--dport로 제어를 하지않는게 보통이다. 제어를 하더라도 상관없다. 하지만 그것은
상당한 비효율적인 룰이 될것이다.

SSH포트를 변경하기

SSH기본 포트 22를 다른 값으로 변경하기

서버를 운영하다보면 여러가지 공격을 많이 받게 되는데 그중에서 가장 흔하면서 또한 가장 기본으로 되는 해킹방법이 바로 포트 스캔이다. 서버에 포트스캔을 막어주는 portsentry를 깔고 기본 쉘접속 포트인 22를 다른값으로 변경하면 해킹을 어느정도 막을 수 있다.(어느정도이다, 절대로 해킹당하지 않는다는 보장은 없다...)

1. ssh 설정변경
ssh설정 파일은 /etc/ssh/sshd_config 에 위치하고 있다.


vi편집기로 열고 #port 22 이 라인중에서 #주석문을 제거하고 port xx로 바꾼다.(xx에는 바꿀 포트숫자를 써준다.)
저장하고 vi편집기에서 빠져나온다.


2. iptables에 새로 추가한 포트에 대한 rule을 추가한다.

또한 iptables에 rule을 추가하여 기존에 22포트를 블럭하고 새로 설정한 포트에 대한 input 컨넥션을 accept해준다.

# iptables -L -n

위 명령어를 이용하여 현재 적용된 iptable 룰들을 살펴 볼수 가 있다.


여기서 주의해서 봐야할 것은 포트 22를 사용하는 SSH가 accept rule로 등록이 되어있는지 확인하는것이다. 보다 싶이 현재 이미 등록이 되어 있는 상태이다. 이 상태에서 우리가 추가한 포트도 xx포트로 접속이 가능하도록 rule을 추가해야 한다.

# iptables -A INPUT -p TCP --dport xx -m state --state NEW -j ACCEPT

(RH나 CentOS일 경우 -A INPUT 대신 -A RH-Firewall-1-INPUT 을 사용하여야 한다.)

또한 기존에 추가된 22포트를 iptables룰에서 삭제 해야한다.

# iptables -D INPUT -p TCP --dport 22 -m state --state NEW -j ACCEPT

(RH나 CentOS일 경우 -A INPUT 대신 -A RH-Firewall-1-INPUT 을 사용하여야 한다.)

# service iptables save

위 명령어를 이용하여 추가한 룰을 iptable에 적용시킨후 다시금 iptable의 상태를 살펴본다.


그림에처럼 22포트는 정확히 삭제되고 우리가 추가한 xx포트가 떠있는것을 확인 할 수 있다.

3. SSH 재시동
포트가 정확히 iptables에 추가되었음이 확인 되면 ssh데몬을 재시동하여 포트 xx에서 서비스를 시작하게 한다.

# service sshd restart

새로운 컨넥션을 만들고 접속을 시도한다.
정확히 쉘에 접속이 됨을 확인 할 수 있다~

2009년 4월 25일 토요일

FoxyProxy를 이용하여 IP가 막힌 웹사이트 접속하기

FoxyProxy을 이용하여 Firefox에서 무제한으로 웹사이트 접속하기

요즘들어 중국정부에서는 다음에서 운영중인 티스토리를 전격 봉쇄했다. 이유는 더 언급하고 싶지도 않으므로 생략하겠다. 개인 블로그를 티스토리로 운영중인 나로서는 받아들일수 없는 현실인것만은 사실이다. 여러모로 다른 블로그 서비스를 알아본바로는 텍스트큐브닷컴과 블로그스팟 등과 같은 무료 블로그서비스들도 존재는 하였다. 하지만 텍스트큐브는 아직까지 정식으로 서비스를 제공해 주지 않는 상태라 초대장을 얻기가 힘들다. 이런저런 이유때문에 당분간은 티스토리에서 블로그를 계속 운영해 나가기로 계획했다. 그렇다면 어떻게 막힌 IP를 풀고 접속을 할것인가?! 일단은 VPN으로 접속이 가능하다만 대부분은 유료이고, 무료인것들은 짜증(?)나는 광고가 붙어다니므로 무료 Proxy서버로 문제를 해결하기로 했다. 일단은 무료 프록시를 찾아본다. 이 포스트는 무료프록시 서버를 찾았다는 전제하에서 진행이 되기에 프록시 탐색은 여기에서 다루지 않겠다.

1. Firefox플러그인 배포사이트에 접속하여 FoxyProxy를 다운로드 받는다.
https://addons.mozilla.org/
키워드를 FoxyProxy로 하고 검색을 한다.


2. FoxyProxy를 설정한다.
찾은 프록시 서버를 FoxyProxy에 설정해준다. 하지만 모든 URL에 프록시서버가 적용되지 않도록 하기 위하여 특정된 패턴에 부합되는 URL에 접속할때에만 비로소 우리가 설정한 프록시서버를 사용하도록 설정해준다.


티스토리만 등록한 상태이다.

2009년 4월 24일 금요일

Webalizer 설치기

Apache 로그 분석 툴 - Webalizer

새로 리눅스 서버를 설치하게 되었다. 일단은 APM 셋업이 끝났고, iptables을 좀 끄적대다가 서버를 모니터링할 수 있는 툴이 있었으면 참 좋겠다는 생각이 머리속에서 스치게 되었다.

당연 생각에서만 그치면 안되겠다 싶어서 직접 현존하는 서버 모니터링툴을 찾아보게 되었다. 트랙픽 모니터링툴로는 SNMP기반 MRTG와 RRD가 있었다. 허나 가장 마음에 드는 툴은 그래도 Apache서버 전문 모니터링 툴인 Webalizer였다.

일단은 webalizer 공식 배포사이트에 접속하여 최신 버젼 webalizer을 받아온다. 사실 yum으로 직접 rpm버젼을 설치할 수 도 있었으나 좀 더 고급(?)스러운 설정을 적용할 수 있지 않을가 하는 기대감으로 소스버젼을 찾아서 설치하기로 결정했다.

webalizer 배포 공식 사이트 주소
http://www.mrunix.net/webalizer/

1. Webalizer 설치

# cd /usr/local/src/

소스를 풀고 컴파일 후 설치 한다.

# tar xvfz webalizer-xxx-src.tgz -C /usr/local/src
# cd ./webalizer-xxx
# vi webalizer_config.sh


configure 옵션들을 파일에 쓴 후 실행시키는 방식으로 진행한다.
나중에 다시 configure 할 때 일일이 옵션을 적지 않아도 되므로 매우 편리하다.
webalizer_config.sh 에 들어갈 내용은 다음과 같다.

./configure \
--prefix=/usr/local/webalizer \
--with-language=korean


저장하고 vi에서 빠져나간다.

# chmod 700 webalizer_config.sh
# ./webalizer_config.sh
# make
# make install


2. Webalizer 설정
환경 설정 파일 수정
환경설정 sample 파일이 /usr/local/webalizer/etc/webalizer.conf.sample에 위치한다.
이 파일을 복사하여 webalizer.conf라는 파일을 만든다.

# cp /usr/local/webalizer/etc/webalizer.conf.sample /usr/local/webalizer/etc/webalizer.conf

/usr/local/webalizer/etc/webalizer.conf 파일의 다음 부분의 주석을 해제 후 수정한다.

LogFile   /아파치가 설치된 경로/logs/access_log
OutputDir  /아파치 기본 웹 디렉토리 경로/webalizer
HostName  호스트명

3. Webalizer 실행
설치 과정을 마치고 직접 Webalizer를 실행한다.
Webalizer 실행 파일는 /usr/local/webalizer/bin 폴더에 위치한다.

# /usr/local/webalizer/bin/webalizer

마지막으로 주기적으로 실행하기 위하여 크론에 등록한다.

crontab –e
*/30 * * * * /usr/local/webalizer/bin/webalizer > /dev/null 2>&1