forcemax's

/etc/init.d/iptables를 다음과 같이 만든다. (permission은 775)

#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          iptables
# Required-Start:    networking ifupdown $local_fs
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

IPTABLES=/sbin/iptables
EXT_ETH=eth0

${IPTABLES} -F
${IPTABLES} -t nat -F
${IPTABLES} -X BLACKLISTCHECK

${IPTABLES} -P INPUT ACCEPT
${IPTABLES} -P OUTPUT ACCEPT
${IPTABLES} -P FORWARD ACCEPT

${IPTABLES} -A INPUT -j ACCEPT -i lo
${IPTABLES} -A INPUT -j ACCEPT -p icmp --icmp-type any
${IPTABLES} -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED

${IPTABLES} -N BLACKLISTCHECK
${IPTABLES} -A INPUT -j BLACKLISTCHECK -i ${EXT_ETH} -m state --state NEW -p tcp --dport 22

for x in `cat /tmp/ssh_evil`; do
${IPTABLES} -I BLACKLISTCHECK -s $x -j DROP
done

# 80, 22번 포트만 오픈
${IPTABLES} -A INPUT -j ACCEPT -i ${EXT_ETH} -m state --state NEW -p tcp --dport 22
${IPTABLES} -A INPUT -j ACCEPT -i ${EXT_ETH} -m state --state NEW -p tcp --dport 80

${IPTABLES} -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
${IPTABLES} -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 6 -j LOG --log-prefix "SSH_brute_force "

${IPTABLES} -A INPUT -j REJECT --reject-with icmp-host-prohibited

/etc/init.d/swatch 파일이 없다면 다음의 내용으로 생성한다. (permission은 775)
#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          swatch
# Required-Start:    networking ifupdown $local_fs
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

PATH="/sbin:/bin:/usr/sbin:/usr/bin"
NAME="swatch"
DAEMON="/usr/bin/swatch"
DESC="simple watcher"
CONFFILE="/etc/swatch.conf"
#LOGFILE="/var/log/secure"
LOGFILE="/var/log/syslog"
PIDFILE="/var/run/swatch.pid"
OPTS="--config-file=$CONFFILE --tail-file=$LOGFILE --pid-file=$PIDFILE --awk-field-syntax --tail-args='-F' --daemon"

test -x $DAEMON || exit 0

start() {
    if [ ! -f "$CONFFILE" ]; then
        echo "Error: $CONFFILE does not exist."
        exit 1
    fi
    if [ ! -f "$LOGFILE" ]; then
        echo "Error: $LOGFILE does not exist."
        exit 1
    fi
    if [ -f "$PIDFILE" ]
    then
        echo "Error: $NAME is already running."
    else
        $DAEMON $OPTS >/dev/null 2>&1
    fi
}

stop() {
    if [ -f "$PIDFILE" ]
    then
        PID=`cat $PIDFILE`
        if ps h $PID > /dev/null
        then
            pkill -P $PID
            kill $PID
        else
            echo "Error: $NAME is not running, but PID file exists. Deleting it."
        fi
        rm -f $PIDFILE
    else
        echo "Error: $NAME is not running."
    fi
}

case "$1" in
  start)
    echo "Starting $DESC: $NAME"
    start
    ;;
  stop)
    echo "Stopping $DESC: $NAME"
    stop
    ;;
  restart)
    echo "Restarting $DESC: $NAME"
    stop
    sleep 1
    start
    ;;
  *)
    echo "Usage: $0 start|stop|restart"
    exit 1
    ;;
esac

exit 0

swatch.conf에는 다음을 추가한다.
perlcode my $sshscript = '/root/swatch-ssh';
watchfor /([a-zA-Z]{3})\s+([0-9]{1,2}) ([0-9]{2}:[0-9]{2}:[0-9]{2}) ([a-zA-Z0-9_-]+) kernel: \[.*\] SSH_brute_force .*SRC=(.*) DST=/
        exec "$sshscript '$*' >> /var/log/swatch.log"
        throttle 00:00:30

swatch에서 실행할 스크립트를 만든다.
/root/swatch-ssh 파일의 내용은 다음처럼 구성한다. (역시 permission은 775)
(다른 기능도 같이 하는 스크립트에서 일부만 발췌함)
#!/usr/bin/ruby1.8

if ARGV.length==0 && ARGV.length < 2
  puts "Error!! Argument must more than 1 words!!"
  puts "ex) swatch-ssh message"
  exit 1
else
  begin
    message = ""
    argv_msg = ARGV[0].split
    host = argv_msg[3]

    beginflag = false
    for qs in argv_msg do
      message = message + (message!=""?" ":"") + qs if beginflag == true
      beginflag = true if qs == host
    end

    # for 3ware modules message
    message.sub!(/kernel: \[[0-9\s]+\.[0-9]+\] /, '')
    message.sub!(/\(.*\)/, '')

    smsmessage = sprintf("[%s]%s\n", host, message)
#    smsmessage.gsub!(' ', '_')
    smsmessage.sub!(/\[mgm\]/, '')
    smsmessage.sub!(/SSH_brute_force .* SRC=/, '')
    smsmessage.sub!(/ DST=.*/, '')

    File.open("/tmp/ssh_deny", 'a') {|f| f.write(smsmessage) }
    command = sprintf("cat /tmp/ssh_evil /tmp/ssh_deny | sort -u > /tmp/ssh_uniq_evil ; rm /tmp/ssh_deny ; cp /tmp/ssh_uniq_evil /tmp/ssh_evil ; /etc/init.d/iptables")
#    printf("%s\n", command)
    system(command)
  end
end

exit 0

이제 모든 준비는 완료되었습니다.
iptables 스크립트를 실행시키고 swatch를 restart하면 끝.
iptables -N BLACKLISTCHECK
touch /tmp/ssh_evil
update-rc.d iptables defaults 20
update-rc.d swatch defaults 20
/etc/init.d/iptables
/etc/init.d/swatch restart

위에서 설정한 내용은 다음과 같습니다.

1. iptables를 설정하여 ssh 연결이 1분에 6번 이상 연결되면 kernel에 log를 남기게 됩니다.
2. swatch에서는 iptables가 남긴 kernel log를 발견하게 되면 /root/swatch-ssh 스크립트를 실행시킵니다.
3. /root/swatch-ssh 스크립트에서는 해당 IP Address를 /tmp/ssh_evil 파일에 남기는 동시에 /etc/init.d/iptables 스크립트를 실행시켜서 발견된 IP Addreess를 통해서 들어오는 연결을 차단합니다.

위의 1,2,3 과정을 반복하면서 ssh brute force attack이 발견되면 해당 IP Address를 지속적으로 차단합니다.

작성자 : 저입니다. ^^

MySQL Proxy

작업2010. 3. 29. 14:15
MySQL Proxy is a simple program that sits between your client and MySQL server(s) that can monitor, analyze or transform their communication.

https://launchpad.net/mysql-proxy

http://forge.mysql.com/wiki/MySQL_Proxy

MySQL에 fail-over와 load balancing(round-robin)을 하기 위한 가장 쉬운 도구.

mkfs.xfs 옵션 설정

Linux2009. 9. 24. 14:29
mkfs.xfs -f -d su=256k,sw=7 -l version=2,su=256k /dev/sdb1

sw는 disk의 갯수에 맞게 수정 (8개 raid5의 경우 7)
su는 raid stripe size에 맞추어서 수정 (raid 구성시 설정을 256k로 하였음)

회사의 한 서버에 tomcat과 rails를 같이 사용할 일이 생겼다.

rails는 passenger를 사용하면 되지만 passenger를 사용하게 되면 apache가 port 80을 점유하므로 tomcat 서비스는 port 80을 사용할 수 없게 된다.
이를 해결할 수 있는 방법으로 mod_proxy를 선택하였다.

VirtualHost를 하나 생성하고 그 설정 안에 mod_proxy의 설정을 한다.

<VirtualHost 192.168.2.60:80>
        ServerAdmin webmaster@mydomain.com
        ServerName service.mydomain.com

        ProxyRequests Off
        <Proxy *>
                Order deny,allow
                Allow from all
        </Proxy>
        ProxyPass / http://localhost:8080/
        ProxyPassReverse / http://localhost:8080/
        ProxyPreserveHost On

...
</VirtualHost>

a2enmod 명령으로 proxy 모듈과 proxy_http 모듈을 활성화 한다.

root@forcemax:/root# a2enmod proxy
root@forcemax:/root# a2enmod proxy_http

이제 Apache2를 재시작하고 웹브라우저에서 service.mydomain.com으로 연결하면 서버의 port 8080에 동작중인 tomcat에 연결된다.

이렇게 tomcat 서비스를 사용할 경우 tomcat 서비스의 소스를 좀 수정해야하는 경우가 생긴다. Reverse Proxy이기 때문에 약간 골치 아프긴하다.



회사 서비스 서버중 DB 서버가 4GB의 메모리를 갖고 있는데 우리가 많이 사용하는 max_connections 계산식에 대입해보면 max_connections값으로 1333을 설정할 수 있다고 한다.

그런데 아무리 [mysqld] 섹션에 max_connections 값으로 1200을 설정해도 적용이 안되고 show variables 해보면 max_connections값이 886으로 되어 있다.

이러한 이유에서 찾아보니 다음의 두가지 설정이 중요하였다.

일단 /etc/mysql/my.cnf에는 다음의 설정을 넣어준다.

[mysqld]
max_connections = 1200
open-files-limit = 4096

그리고 한 process의 최대 open files 값을 변경하기 위해 /etc/security/limits.conf 에 다음 설정을 추가한다.

mysql           soft    nofile          4096
mysql           hard    nofile          4096

mysql 데몬을 재시작하자!



Ubuntu 8.10 Intrepid Ibex에서는 기존의 xorg.conf 파일을 설정하는 방법으로는 IBM TrackPoint의 휠 기능을 사용할 수 없다.

Xorg가 시동중에 hal의 설정을 임의로 불러와 사용하는데 이 부분에서 기존의 Xorg 설정이 무시되기 때문이다.

결국 hal에 설정을 해주어야 Xorg가 해당 설정을 읽어서 TrackPoint의 휠 기능이 동작할 수 있게 된다.

/proc/bus/input/devices 파일을 보면 다음과 같은 내용이 있다.

I: Bus=0003 Vendor=06cb Product=0009 Version=0100
N: Name="Synaptics Inc. Composite TouchPad / TrackPoint"
P: Phys=usb-0000:00:0b.0-4.4/input0
S: Sysfs=/devices/pci0000:00/0000:00:0b.0/usb1/1-4/1-4.4/1-4.4:1.0/input/input4
U: Uniq=
H: Handlers=mouse2 event4
B: EV=17
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=3
B: MSC=10

I: Bus=0003 Vendor=06cb Product=0009 Version=0100
N: Name="Synaptics Inc. Composite TouchPad / TrackPoint"
P: Phys=usb-0000:00:0b.0-4.4/input1
S: Sysfs=/devices/pci0000:00/0000:00:0b.0/usb1/1-4/1-4.4/1-4.4:1.1/input/input5
U: Uniq=
H: Handlers=mouse3 event5
B: EV=17
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=3
B: MSC=10

위에 나오는 내용외에도 각종 input device 관련 내용이 있는데 일단 무시하고 Name 항목을 복사해 두자.

/etc/hal/fdi/policy/mouse-wheel.fdi 파일을 만든다. 내용은 다음과 같다.

<match key="info.product" string="Synaptics Inc. Composite TouchPad / TrackPoint">
<merge key="input.x11_options.EmulateWheel" type="string">true</merge>
<merge key="input.x11_options.EmulateWheelButton" type="string">2</merge>
<merge key="input.x11_options.ZAxsisMapping" type="string">4 5</merge>
<merge key="input.x11_options.Emulate3Buttons" type="string">true</merge>
</match>

위 설정중 match 태그의 string property에 나오는 내용이 위에 /proc/bus/input/devices에서 복사해둔 내용이다.

위 파일을 저장하고 hal 데몬을 재시작한 후 X를 재시작 한다.

이제 IBM TrackPoint의 휠 기능이 동작한다.

참조 : http://www.linlap.com/wiki/Lenovo+Thinkpad+W500

Linux Traffic Control 2

Linux2008. 10. 13. 21:18

지난번에는 ingress policing을 구현하였는데 이번에는 egress shaping을 구현할 일이 생겼다.

구현할 내용은 local network에 대해서는 최대 트래픽을 사용하지만 internet으로 나가는 트래픽에 대해서는 제한을 두는 것이다.

#!/bin/bash

TC=/sbin/tc
DEV=bond0
MAX=2000
LIMIT=1000

case "$1" in
        start)
                $TC qdisc del dev $DEV root 2> /dev/null
                $TC qdisc add dev $DEV root handle 1: htb default 10
                # local network is unrestricted
                $TC class add dev $DEV parent 1: classid 1:10 htb rate ${MAX}mbit burst ${MAX}k quantum 1514
                $TC qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10
                $TC filter add dev $DEV parent 1:0 protocol ip prio 10 u32 match ip dst 192.168.5.0/24 flowid 1:10
                # internet traffic is limited
                $TC class add dev $DEV parent 1: classid 1:20 htb rate ${LIMIT}mbit ceil ${LIMIT}mbit burst ${LIMIT}k quantum 1514
                $TC qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
                $TC filter add dev $DEV parent 1:0 protocol ip prio 20 u32 match ip src 0.0.0.0/0 flowid 1:20
                ;;
        stop)
                $TC qdisc del dev $DEV root 2> /dev/null
                ;;
        show)
                $TC qdisc show dev $DEV
                $TC -s class show dev $DEV
                $TC -s filter show dev $DEV
                ;;
        *)
                echo "Usage: $0 start|stop|show" >&2
                exit 3
                ;;
esac




일단 위의 스크립트 대로 적용하면 2Gbps의 bond0 인터페이스에서 외부로 나가는 트래픽중
'192.168.5.0/24' 대역에 걸리는 트래픽은 $MAX에 정해놓은 수치(위에는 2Gbps)로
그 외 '0.0.0.0/0' (전체 네트웍)으로 나가는 트래픽은 $LIMIT에 정해놓은 수치(위에는 1Gbps)로
나가도록 설정된다.


$ parted /dev/sda
GNU Parted 1.7.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt
(parted) print

Disk /dev/sda: 9000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start  End  Size  File system  Name  Flags

(parted) mkpart primary 0 9000G
(parted) quit


Linux Traffic Control

Linux2008. 6. 24. 10:02
일반적으로 저속의 상황을 시뮬레이션하기 위해서는 Client의 Traffic을 제한할 필요가 있다. QOS에 관련하여 알아보던 중 Incoming Traffic을 제한하는 방법은 Ingress Policing 밖에 없음을 알게되었다.

알게된 상황을 정리해 보면.

ingress policing : incoming traffic control
egress shaping : outgoing traffic control

ingress policing은 오직 한가지 방법만이 존재하며 다음 링크에서 살펴볼 수 있다.
http://blog.stevedoria.net/20050906/ingress-policing-with-linux-and-tc

내가 작성한 ingress policing script는 다음과 같다.

#!/bin/bash

TC=/sbin/tc
DEV=eth0
MAX=400

# clear all queuing on the device.
${TC} qdisc del dev ${DEV} root 2> /dev/null > /dev/null
${TC} qdisc del dev ${DEV} ingress 2> /dev/null > /dev/null

# Handle the speed of the traffic coming from network
# Add a limiter to the ingress
${TC} qdisc add dev ${DEV} handle ffff: ingress
# Set the maximum limit
${TC} filter add dev ${DEV} parent ffff: protocol ip prio 2 u32 match ip src 0.0.0.0/0 police rate ${MAX}kbps burst 100kb drop

위 스크립트는 ubuntu 8.04에서 잘 돌아간다. 내용은 incoming traffic의 속도를 400kbytes/sec로 제한하는 것이다.

debian etch에서는 위 스크립트로 동작이 안되는데 마지막 줄을 다음과 같이 수정한다.

${TC} filter add dev ${DEV} parent ffff: protocol ip prio 2 u32 match ip src 0.0.0.0/0 police rate ${MAX}kbps burst 100kb drop flowid :1





Ubuntu 8.04 Hardy를 사용하던중 IBM USB Ultranav travel을 업어왔다.

GDM을 통해서 Login하면 Numlock키가 On 상태가 되었다.

그런데 Shift + Scrlk 버튼을 누르면 Numlock이 풀려야 하는데 풀리지 않는다. 이런 ㅠㅠ

찾아보던중 numlockx 라는 패키지를 설치하고 numlockx off 라는 명령을 내리면 Numlock이 풀린다는 내용을 보았다.

바로 numlockx 패키지를 설치하고 세션에 numlockx off 명령을 넣어주어서 이제는 Numlock이 풀린상태로 Login이 되었다.

만세~

PS. 그런데 Shift + Scrlk 버튼을 누르면 Toggle이 되야하는데 왜 안되는거지;;