Monthly Archives: November 2009

우분투 firefox에서 SSH protocol 링크

여러대의 서버를 관리하면서, 모니터링할수 있는 페이지를 만들고, 해당 서버를 클릭하면 SSH로 바로 연결할수 있도록 MIME 링크를 만들어서 사용하고 있습니다. MIME 링크 처리는 윈도우즈에서 프로그램을 제작해서 ssh:// 형태의 MIME type에 대해서 처리하게 했습니다. 프로그램은 단순히 putty를 찾아서 실행해주는 간단한 구조입니다.

이걸 리눅스에서 할려고 했더니 어떻게 해야하는지 좀 헤맸습니다. mime type이라는 건 서버에서 파일이 내려갈때 HTTP header에 붙어서 가고, 이를 브라우저에서 처리하는 거라… ssh:// 형태의 링크는 mime 링크로는 처리가 안되고, 이를 처리하는 걸 protocol handler라고 하더군요. 검색어 자체가 잘못되서 해결책을 찾는데 꽤 시간이 걸렸습니다.

먼저 gnome에서 ssh 프로토콜을 프로그램 연결하는 부분입니다.

$ gconftool-2 -s /desktop/gnome/url-handlers/ssh/command ‘/usr/bin/gnome-terminal -e “~/bin/handle_protocol.sh %s”‘ –type string
$ gconftool-2 -s /desktop/gnome/url-handlers/ssh/enabled -t boolean true

참고 URL: http://kb.mozillazine.org/Register_protocol

~/bin/handle_protocol.sh 파일 내용입니다.

#!/bin/sh

link=$1
proto=`echo "$link"|cut -d: -f1`
host=`echo "$link"|cut -d/ -f3`
echo "$proto $host"
exec $proto $host


파일 만들고 실행되도록 chmod 해야 합니다.

$ chmod a+x ~/bin/handle_protocol.sh

이렇게 하면 firefox에서 ssh:// 로 시작하는 링크 누르면 gnome-terminal이 뜨면서 ssh로 연결됩니다. telnet도 똑같은 방법으로 등록하면 사용이 가능합니다.

이렇게 설정했는데 우분투(9.10)에서 원격 접속했을때 윈도우즈에서 putty 이용했을때보다 속도가 많이 느리더군요. /etc/ssh/ssh_config에서 맨 아래 두줄을 주석 처리하면 빨라집니다.

#GSSAPIAuthentication yes
#GSSAPIDelegateCredentials no

출처: http://onlyubuntu.blogspot.com/2007/04/fix-for-ssh-slow-to-ask-for-password-in.html

Linux 방화벽 iptables & DDoS 방어?

PF로 DDoS 공격을 어느정도 막으면서, iptables에서도 가능한지 궁금해졌습니다. PF 처럼 쉽게 공격 IP를 완전하게 차단하는 방법은 찾지 못했지만, IP당 시간당 연결수를 제한하는 방법은 있네요.

iptables -N SSHSCAN
iptables -A INPUT -p tcp –dport 22 -m state –state NEW -j SSHSCAN
iptables -A SSHSCAN -m recent –set –name SSH
iptables -A SSHSCAN -m recent –update –seconds 300 –hitcount 3 –name SSH -j DROP

5분동안 22포트에 똑같은 IP가 3번 이상의 TCP 연결이 들어오면 그 이후로는 막습니다. 즉 5분간 3개의 연결만을 허용합니다. SSH 돌리기 신공은 막을수 있겠지만, DDoS 공격을 차단하기는 부족한 기술인듯하네요.

using-iptables-to-block-brute-force-attacks 문서를 보시면, 자세한 설명이 있고, 공격 아이피에 대해서 로깅을 하는 방법도 있습니다. 로그 분석해서 iptables rule을 등록해주면 공격 아이피에 대해서 차단할수 있을듯하네요. 하지만 이 방법 말고 더 쉬운 방법이 없을까 고민중입니다.

여러가지 로그 파일에서 로그인 실패를 모니터링해서 공격을 막아주는 fail2ban 이라는 툴도 있네요. 설명은 여기를 참고하세요. 역시 DDoS 방어용은 아니지만, 로그 분석을 통해서 방화벽에 IP 등록하는걸 응용할수 있을듯합니다.

최근
Linux Firewalls: Attack Detection and Response with iptables, psad, and fwsnort 책을 보기 시작했는데 좀더 좋은 방어 방법 찾으면 다시 글 올리겠습니다.

BSD 방화벽 PF & DDoS 방어

PF(Packet Filter)는 BSD용 방화벽입니다. 원래 IPF라고 개인이 만든 공개 방화벽이 있어서, 여러 BSD 계열 UNIX에서 주로 사용하였었습니다. 다른 개발자들이 라이센스에 대해 명확하지 않은 부분에 대해서 설명 요구에 대한 응답에 만족하지 못한 오픈소스 개발자들이 새롭게 만든 방화벽이 PF입니다. 정말 너무나도 빠르게, IPF와 기능은 유사하게 만들어졌습니다. IPF는 소스는 공개였지만, 소스 분기는 허용하지 않고 원 개발자가 필요한 패치만 해서 하나의 버전을 유지하겠다고 했었습니다…

하여간 PF가 OpenBSD 개발자들에 의해서 순식간에 만들어지고, 여러개발자들이 참여가 가능했기 때문에 금방 여러가지 추가 기능들이 구현됐습니다. 오픈 소스 최고의 방화벽으로 자리 잡았고, 상용 방화벽이 갖추지 못한 좋은 기능들도 많이 가지고 있습니다.

FreeBSD에서 PF 방화벽을 사용하려면 /etc/rc.conf 에

pf_enable=”YES”
pflog_enable=”YES”

를 추가해야합니다.

정책 설정은 /etc/pf.conf 에서 합니다.

설정 파일에서 가장 중요한 부분은 pass/block이죠…

pass/block in/out (log) on 인터페이스
proto 프로토콜
from 주소/마스크비트 port 포트

to 주소/마스크비트 port 포트

1.2.3.x 에서 오는 모든 udp 패킷을 막고 싶다면…

block in proto udp from 1.2.3.0/24 to any

80포트로 오는 걸 열어주고 로그로 남기고 싶으면,

pass in log proto tcp from any to port 80 keep state

keep state하면 생성된 TCP 세션에 대해서 들어오고 나가는 패킷이 방화벽을 통과합니다.

패킷이 왔을때 위에서 부터 비교가 되며… 맨 마지막 매치가 선택됩니다.
단, quick이 설정되어 있으면 그 매치가 선택됩니다.

아래는 현재 사용중인 설정입니다. 추가적인 보안 관련 설정이 여러가지 있습니다..

ext_if=”em0″

set limit { states 80000, frags 5000 }

set block-policy drop

set skip on lo0

scrub in all
antispoof for $ext_if

block in all
block out all

table <bruteforce> persist
table <sshbruteforce> persist

block in quick log proto tcp from <bruteforce> to port 80
block in quick log proto tcp from <sshbruteforce> to port 22

pass in on $ext_if proto tcp from any to $ext_if port 22 \
            flags S/SA keep state \
            (max-src-conn-rate 10/30, overload <sshbruteforce> flush global)
pass in on $ext_if proto tcp from any to $ext_if port 80 \
        flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $ext_if port 80 \
        flags S/SA keep state \
        (max-src-conn 100, max-src-conn-rate 300/10, \
        overload <bruteforce> flush global)

위에 설정에서 ssh나 http로 하나의 IP에서 여러개의 요청이 한번에 오면 막는 기능이 동작합니다. HTTP의 경우 최대 100개의 동시 연결, 10초간 300개 이상의 연결이 발생하게 되면 공격자로 인식하고 기존 연결을 모두 끊어버리고 연결을 막습니다.

한번 등록되면 방화벽 재시작 전에는 해당 IP에서 연결이 안됩니다. 일정 기간이 지나면 풀리게 하는 방법은 expiretable를 사용하면 가능합니다.

FreeBSD에서는

# cd /usr/ports/security/expiretable
# make install

# /usr/local/sbin/expiretable -t 2h bruteforce

2시간 이상 지난 IP를 풀어주는 명령으로 crontab에 등록해서 사용하면 됩니다.

최신 버전 PF를 사용하면 pfctl로 같은 기능을 할수 있다고 합니다.

# pfctl -t bruteforce -T expire 7200

방화벽 시작, 재시작, 설정 파일 다시 읽기, 종료 방법:

# /etc/rc.d/pf start
# /etc/rc.d/pf restart
# /etc/rc.d/pf reload
# /etc/rc.d/pf stop
# /etc/rc.d/pflog start
# /etc/rc.d/pflog stop

방화벽 로그를 실시간으로 보는 방법

# tcpdump -i pflog0

쌓인 로그를 보는 방법

# tcpdump -r /var/log/pflog

방화벽 상태 보기

# pfctl -s all
# pfctl -vvs all (보다 자세한 정보 보기)

방화벽 공격 IP 보기

# pfctl -t bruteforce -T show

마지막으로… 원격에서 방화벽 잘못 설정하면 IDC로 튀어가야합니다.
신중을 기해야합니다.

한가지 터득한 방법은…

# /etc/rc.d/pf reload; sleep 15; /etc/rc.d/pf stop

restart보다는 reload가 그나마 안전합니다. reload할 때는 세션 테이블이 초기화 되지 않습니다.

DDoS의 공격의 종류가 많고 어디가 bottleneck이 되느냐에 따라 해결방법이 틀려집니다. 서버 자체의 부하를 일으켜 서비스 거부 공격을 받는 경우 PF로 많은 공격을 막을수 있습니다.

pfstat을 설치하면, PF의 여러가지 상황을 모니터링 할수 있습니다.

# cd /usr/ports/sysutils/pfstat
# make install

pfstat 홈페이지의 설정파일을 복사하고, 인터페이스명과 파일 저장 위치들만 바꿔주고
crontab에 아래처럼 등록했습니다.

# crontab -l
* * * * * /usr/local/bin/pfstat -q
*/5 * * * * /usr/local/bin/pfstat -p