Tag Archives: Linux

Linux #17 : OpenLDAP Installation Guide

OpenLDAP은 Lightweight Directory Access Protocal로 Windows의 Active Directory와 같은 Linux의 인증관리 시스템입니다. 이 시스템을 이용하여 Unix Based Authentication과는 별도록 Account를 통합 관리 할 수 있습니다.

OpenLDAP 공식 Page : http://www.openldap.org

2011년 현재(3월 기준) 2.4.23의 stable version을 받을 수 있고, OpenLDAP을 설치하기 위해서는 아래와 같은 Application을 추가로 설치를 해 주시면 됩니다.
필자는 Source Version을 통해서 설치를 하였기 때문에 RPM을 이용한 설치 방법에 대해서는 기술하지 않도록 하겠습니다.

OpenLDAP 설치 전 필요한 Source들은 Berkeley DB, Crypt Library, GNUTLS Library, OpenSSL입니다. 현재 Version은 각기 다를 수 있고 System상에 설치된 Version들을 그대로 활용 할 수도 있습니다.

Install Berkeley DB
Berkely DB for Oracle : http://www.oracle.com/technology/products/berkeley-db/db/index.html

Installed Version : db-4.6.21
# cd build_unix/
# ../dist/configure --prefix=/usr
# make;make install

Install CRYPT Library
libcrypt : ftp://ftp.gnupg.org/gcrypt/libgcrypt/

Installed Version : libcrypt-1.4.4
# ./configure
# make;make install

Install GNUTLS
gnutls : http://www.gnu.org/software/gnutls/

Installed Version : gnutls-2.6.3
# ./configure
# make; make install

Install openssl
openssl : http://www.openssl.org

Installed Version : openssl-0.9.8.h
# ./configure --prefix=/usr shared
# make;make install

Install openLDAP Server

Installed Version : openldap-2.4.19
# ./configure --prefix=/usr/local/openldap --sysconfdir=/etc --localstatedir=/var --without-kerberos --without-cyrus-sasl --with-tls=openssl --enable-syslog --disable-ipv6 --enable-lastmod --enable-crypt --enable-ppolicy --enable-syncrepl
# make depend;make
# make install

현재 안정적인 Version인 2.4.23에 대해서도 install을 진행 해 보았고, 문제없이 설치되는 것을 확인 했습니다.
설치 후 OpenLDAP을 위한 Group과 User Account를 만들어 주고 관련 작업들을 진행합니다.

# /usr/sbin/groupadd -g 55 ldap
# /usr/sbin/useradd -u 55 -g 55 -d /usr/local/openldap -M -s /bin/false -c "openLDAP User" ldap
# mkdir /var/run/openldap;chown ldap:ldap /var/run/openldap
# mkdir /var/log/ldap:chown ldap:ldap /var/log/ldap
# mv /var/openldap-data /var/lib/ldap
# mkdir /var/lib/ldap/[Domain Name]
# cp /var/lib/ldap/DB_CONFIG.example /var/lib/ldap/[Domain Name]/DB_CONFIG
# chown -R ldap:ldap /var/lib/ldap
# chown -R ldap:ldap /etc/openldap

OpenLDAP Server가 설치 되었습니다. 다음 내용은 Linux #18 : OpenLDAP Configuration Guide 입니다. 빠른 시일 내에 올리도록 하겠습니다.

Linux #16 : Static Route Configuration

Linux에서 Static Route를 설정은 “route”를 통해서 가능하다. 또, 아래와 같이 routing 된 Network의 정보를 확인 할 수 있다.

$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.37.114.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.37.0.0 10.37.114.1 255.255.0.0 UG 0 0 0 eth0
10.42.0.0 10.37.114.1 255.255.0.0 UG 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 10.37.114.1 0.0.0.0 UG 0 0 0 eth0

기본적인 사용방법은

route add -net [IP Addess Segment] netmask [NetMask Information] gw [Gateway Information]

$ route add -net 10.44.0.0 netmask 255.255.0.0 gw 10.37.114.1

$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.37.114.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.37.0.0 10.37.114.1 255.255.0.0 UG 0 0 0 eth0
10.42.0.0 10.37.114.1 255.255.0.0 UG 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
10.44.0.0 10.37.114.1 255.255.0.0 UG 0 0 0 eth0
0.0.0.0 10.37.114.1 0.0.0.0 UG 0 0 0 eth0

add option을 통해서 10.44.0.0/255.255.0.0가 Gateway 10.37.114.1로 추가 된 것을 확인 할 수 있다.
삭제를 할 경우는 add 대신 del을 사용하면 된다.

route del -net [IP Addess Segment] netmask [NetMask Information] gw [Gateway Information]

$ route del -net 10.44.0.0 netmask 255.255.0.0 gw 10.37.114.1

그런데, 여기서 Server가 부팅이 될 때 자동으로 Static route를 추가한다고 생각해 보자. 그럼, 보통 /etc/rc.local 과 같은 기동시 자동으로 동작하도록 설정을 하거나 하는데, 이럴 경우는 “/etc/init.d/network restart”에 의해 Network가 재기동 될 때는 개별적으로 추가를 해 줘야 한다.
이런 경우 “/etc/sysconfig/static-routes”라는 file을 생성하여 아래와 같이 정보를 입력 해 주시면 Network만 재기동 할 시에도 자동으로 Static Route가 설정 되게 된다. 입력 방법은 아래와 같다.

$ more /etc/sysconfig/static-routes
any net 10.37.0.0/16 gw 10.37.114.1
any net 10.42.0.0/16 gw 10.37.114.1

이 방법이 유용한 것은 Rebooting시에 Static Route을 설정 하고, Online 상태에서 Network 재기동 했을 시 혹시 Static Route를 추가 하는 작업을 잊어 버렸을 때 발생 할 수 있는 문제점을 없애주는 것이다. 인간은 망각의 동물이라.. 필자도 가끔 잊어 버리곤 해서 뒤늦게 문제점을 발견하고 추가를 했던 경우가 간혹 있었다.
또한, 관리하는 서버가 많다보니 매번 똑같은 걸 입력하기 싫어서 아래와 같이 Scripts를 만들었다.

$ more config-static-routes
#!/bin/sh
GATEWAY=`/sbin/ifconfig eth0 | grep "inet addr:" | awk '{print $2};' | awk -F ":" '{print $2};' | awk -F "." '{print $1"."$2"."$3"."1};'`
Printmsg "INFO" "Add route : net 10.37.0.16 gw $GATEWAY"
echo "any net 10.37.0.0/16 gw $GATEWAY" > /etc/sysconfig/static-routes
Printmsg "INFO" "Add route : net 10.42.0.16 gw $GATEWAY"
echo "any net 10.42.0.0/16 gw $GATEWAY" >> /etc/sysconfig/static-routes

간단한거지만, 매번 같은 서버를 구축 할 때 유용하게 사용하고 있다.

Linux #13 : LVM (Logical Volume Manager)의 구성 확인

Logical Volume Manager인 LVM을 통해서 Volume을 생성하고, 확인 하는 방법에 대해서 정리 해 보려고 한다.
LVM은 여러개의 Partition을 한 개의 Disk(File system)으로 사용하기 위한 Disk 관리 기능이다. LVM을 사용하면 아래와 같은 장점이 있다.

1. 여러개의 Disk를 1개의 File System로 구성 가능
2. Partition Size의 변경이 용이
3. Snapshot과 같은 기능의 사용이 가능

우선 Physical Volume(PV) 정보를 확인 할 필요가 있고, 아래와 같이 “pvdisplay”로 확인 가능하다.

$ pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name VolGroup00
PV Size 111.69 GB / not usable 1018.00 KB
Allocatable yes (but full)
PE Size (KByte) 32768
Total PE 3574
Free PE 0
Allocated PE 3574
PV UUID dz7rf6-xEaU-WPEY-RRbg-7Gd5-CbJA-L2NFQy

Physical Volume은 Physical Device를 의미하며 LVM의 관리정보가 추가 된 Partition을 표시 해 주고 있다.
PE Size, Total PE, Free PE, Allocated PE, PE라는 용어가 있는데, 이는 Physical Extent로 저장영역의 최소단위이다.
이후에 만들어지게 될 Logical Volume은 이 PE를 필요한 만큼 배분하여 가상적인 Partition을 작성하는 걸 의미하고, 위 정보에 의하며 PE Size는 32MBytes로, 총수는 3574개이고, Free는 없으며, 모든 PE가 사용되고 있다고 볼 수 있다.

Physical Volume의 다음 단계는 VG(Volume Group)가 되는데, VG는 Physical Volume을 구성하는 가상의 저장장치를 의미한다. Volume Group을 생성하는 것으로 여러개의 Physical Volume을 한개의 큰 File system(Disk)로 System 에서 인식하는게 가능하게 된다. Volume Group에 대한 정보는 “vgdisplay”를 통해서 확인 가능하다.

$ vgdisplay
--- Volume group ---
VG Name VolGroup00
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 3
Open LV 3
Max PV 0
Cur PV 1
Act PV 1
VG Size 111.69 GB
PE Size 32.00 MB
Total PE 3574
Alloc PE / Size 3574 / 111.69 GB
Free PE / Size 0 / 0
VG UUID qKtkYK-FaRH-zUfi-0ECP-A5J7-f1W4-7ffYSa

Volume Group이 구성된 이후엔 마지막 단계인 Logical Volume(LV)이 구성되는데, Logical Volume은 Volume Group상에서 생성된 가상 Partition이고, 이는 “lvdisplay”로 확인 가능하다.

$ lvdisplay
--- Logical volume ---
LV Name /dev/VolGroup00/LogVol02
VG Name VolGroup00
LV UUID S6gx2z-GcWu-9hmx-kHK3-YcpT-RsSy-a9yzcJ
LV Write Access read/write
LV Status available
# open 1
LV Size 107.69 GB
Current LE 3446
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:3

--- Logical volume ---
LV Name /dev/VolGroup00/LogVol01
VG Name VolGroup00
LV UUID fPqNNh-hJTA-N6cU-Ndzh-CRMP-rylz-hK56ay
LV Write Access read/write
LV Status available
# open 1
LV Size 2.00 GB
Current LE 64
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:4

--- Logical volume ---
LV Name /dev/VolGroup00/LogVol00
VG Name VolGroup00
LV UUID W00Fr8-AaxC-nloz-nXmO-j1Ma-qaRY-yOmuQJ
LV Write Access read/write
LV Status available
# open 1
LV Size 2.00 GB
Current LE 64
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:5

따라서, 정리를 해 보면 어떤 Device가 추가 되면 Physical Device에서 Physical Volume을 생성하고, PV에서 Volume Group을 할당하고, Volume Group상에서 Logical Volume이 존재하게 된다는 것이고, 이는 Physical Device -> PV Create -> VG Create -> LV Create를 통해서 순차적으로 생성가능하게 된다.

LVM에서의 File System 생성은 Linux #14 : LVM에서 Logical Volume 생성하기에서 설명하도록 하겠다.

Linux #12 : Default Gateway Configuration

Default Gateway 설정은 route command를 통해서 가능합니다.
현재의 설정을 아래와 같이 확인 가능합니다.

$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.37.114.0 * 255.255.255.0 U 0 0 0 eth0
172.16.111.0 10.37.114.1 255.255.255.0 UG 0 0 0 eth0
10.37.0.0 10.37.114.1 255.255.0.0 UG 0 0 0 eth0
10.42.0.0 10.37.114.1 255.255.0.0 UG 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 10.37.114.1 0.0.0.0 UG 0 0 0 eth0

Default Gateway의 실시간 변경을 위해서는 현재 설정된 Default Gateway를 일단 삭제 할 필요가 있습니다.
따라서 아래와 같이 실행을 해 준 다음 설정을 행하면 됩니다.

$ route delete default
$ route add default gw 10.37.114.1

Redhat 계열의 Linux의 경우 아래 File을 수정함으로서 Reboot시 자동으로 적용되게 할 수 있습니다.

$ vi /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=TESTSERVER
GATEWAY=10.37.114.1

설정이 완료 된 Default를 Network Restart를 통해 반영 할 수 있습니다.

$ /etc/init.d/network restart &

&를 추가하여 Background로 동작하게 하면 보다 안전하게 Restart가 가능합니다.

Linux #9 : could not search LDAP server – Server is unavailable

nss_ldap: could not search LDAP server - Server is unavailable

You can see this message when the LDAP server is down or bad performance.
if the LDAP server is down, you can solve this issue only the LDAP restart.
but, if it caused by bad performance, you should check about connection counts of LDAP.

Local Account(In Base Authentication) is describing their account from LDAP server when nss_swich of the server is configured for LDAP system and the account is trying to use any processes or tasks, jobs.

Sometimes it caused by increasing sessions and decreasing performance of LDAP system.

You can ignore accounts to access to LDAP when the accounts is working their processes or tasks, jobs.

You can reduce a lot of session from local account adding as below the option
URL : http://linux.die.net/man/5/nss_ldap

nss_initgroups_ignoreusers This option directs thenss_ldapimplementation of initgroups(3)
to return NSS_STATUS_NOTFOUND if called with a listed users as its argument.

$ more /etc/ldap.conf
... Add below a line
nss_initgroups_ignoreusers root,nagios,nrpe,www,rancid,oracle,mysql,ntp,postfix,daemon,named

Linux #7 : Dos / DDos 공격에 대한 대처법. #1

수 많은 Site들이 Dos / DDos 공격으로 인해 피해를 보고 있다. 필자도 일본에선 별로 느껴보진 못했지만, 미국에 와서 Dos / Ddos 공격을 여러번 경험하고 실제 지금도 항상 Hacker들을 경계하고 있습니다. 그럼, Dos / DDos 공격이란 무엇인지 먼저 알아보죠.

Dos 공격이란 Daniel of Service attacks의 약자로 Network의 대역을 소비하게 만들거나, 대량의 request를 Server에 보내 connection을 증가시켜 Server를 사용 불능 상태로 만들거나, 더불어 Password를 알아내기 위해 여러 방법을 통해 접근을 시도하는 Brute Force 공격등도 행해지는데,  공격 주체가 1대의 host라면 특정가능하여 해당 IP를 제한하면 되지만 (여기까지가 Dos), 이 공격 주체가 특정할 수 없는 다수일 경우 DDos (Distributed Denial of Service) 공격이라하고, 이를 방지하기 위해선 다른 방법이 필요합니다.

그럼, Dos / DDos와 관련 된 여러 공격에 대한 대처 방법에 대해서 알아보도록 하죠.

SYN Flooding 공격

기본적으로 TCP Packet은 3 Way Handshaking에 의해 초기 Session이 이루어지게 되는데, 즉 SYN -> SYN / ACK -> ACK로 완료가 이루어져야 하지만 정상적인 Session으로 종료가 가능하지만, SYN Packet을 요청하고 SYN / ACK Packet을 Server에서 보내려고 할 때 보내려는 주소가 무의미한 주소여서 Server가 해당 Session을 대기상태 (SYN_RECV)에 놓게 되어 Server 대기 Queue의 증가로 인한 Server Resource가 증가로 정상동작을 할 수 없게 만드는 공격을 말합니다.

확인은 일단 Server가 비정상적으로 느려지고, 접속히 원활하지 않게 되며 netstat 명령어를 통해 SYN_RECV의 수를 체크 했을 시 SYN_RECV의 대기 Queue가 많이 증가하였다고 의심해 볼 필요가 있습니다.

# netstat -an | grep SYN_RECV
...
tcp        0      0 ::ffff:xxx.xxx.xxx.xxx:80    ::ffff:xxx.xxx.xxx.xxx:28719  SYN_RECV
tcp        0      0 ::ffff:xxx.xxx.xxx.xxx:80     ::ffff:xxx.xxx.xxx.xxx:61544   SYN_RECV
...

대처 방법은 아래와 같이 3가지가 있습니다.
첫번째는 Backlog size를 증가시켜 주는 방법으로 Default값에서 1024 ~ 그 이상의 값을 설정합니다.

# SYN Flooding attack block (need to increase backlog size)
net.ipv4.tcp_max_syn_backlog=16000

이 설정을 하게 됨으로 얼마정도 버틸 수 있게 되지만 지속적으로 공격을 당했을 경우 queue가 꽉차게 됨으로 두번째인 SYN Cookies도 활성화를 시켜야 합니다. SYN Cookies가 활성화가 되면 ACK 중에 포함된 확인 응답 번호를 계산하여, 올바른 Session인지를 확인하게 됩니다. Session이 올바른 경우 처리를 행하고, 그렇지 않은 경우의 Connection에 대해서는 System Resource를 낭비하는 걸 막을 수 있습니다.

# Activate SYN Cookies
net.ipv4.tcp_syncookies=1

1인 경우가 활성화된 상태이고, 0인 경우가 비활성 상태입니다. 이 두개의 값은

# echo '16000' > /proc/sys/net/ipv4/tcp_max_syn_backlog
# echo '1' > /proc/sys/net/ipv4/tcp_syncookies

와 같이 설정가능하고 또한,

# sysctl -w net.ipv4.tcp_max_syn_backlog=16000
# sysctl -w net.ipv4.tcp_syncookies=1

또, /etc/sysctl.conf에 추가를 한 뒤

# sysctl -p /etc/sysctl.conf

로도 가능합니다. /etc/sysctl.conf에 넣었을 경우 System Reboot시 자동으로 등록이 되게 됩니다. SYN Cookies를 활성화 하면 확인 응답번호의 계산에 따른 Packet처리에서 Overhead가 발생하게 되고, Packet 량에 따라 CPU 사용량이 증가하여 Bottleneck이 발생 할 가능성이 있습니다.
그리고, 마지막으로 Iptable을 이용하여 비정상적은 IP를 block하면 됩니다.

운영상의 편의를 위해 아래와 같이 Script를 작성해 보았습니다.

### Block_SYN_Flooding.sh
#!/bin/sh
# ================================================================
# -script name
# Block_SYN_Flooding.sh
# -script desc
# Block DDos Attack through the SYN Flooding
# -how to use
# ./Block_SYN_Flooding.sh $1 $2
# $1 Type
# $2 List File
# -NOTE
#
# -directory
# /home/scripts/security
# -create date
# 2010/06/22 NHN USA)Jeff KIM
# -Update
#
# ----------------------------------------------------------------
# -internal variable
# BASE Common lib directory
# LIB_ENV Location of env file
# FUNCTION Location of function file
# SCRIPT_NAME Script name
# APP_VERSion Application & History Number
# ================================================================
BASE=/home/scripts
SCRIPT_NAME="Block_SYN_Flooding.sh"
LIB_ENV=$BASE/setenv.conf
FUNCTION=$BASE/function
APP_VERSION=$BASE/app_version
. $LIB_ENV
. $FUNCTION
. $APP_VERSION
##################################################################
# start script
Startscript
Whoamiroot
MENU_INIT="[ start | stop | start_pp | stop_pp ]"
function Read_Iplist_File {
if [ "${IPS}" == "" ];then
Printmsg "ERROR" "Please, Input IP List File Path!"
Endscript
else
if test -r ${IPS};then
iRC=$?
if [ ${iRC} -eq 0 ];then
chkFile=1
else
chkFile=0
Printmsg "ERROR" "${2} File is not existed."
fi
fi
fi
}
if [ "${1}" == "" ];then
Printmsg "ERROR" "Please, Input Type (Usage: ${MENU_INIT} ) correctly!"
Endscript
else
TYPE=${1}
IPS=${2}
case ${TYPE} in
start)
PRC_NAME="Start IPtables to block ${2}.........."
Startprocess
Read_Iplist_File
if [ "${chkFile}" == "1" ];then
for ipaddress in `cat ${2}`;do
Printmsg "NOTICE" "/sbin/iptables -A INPUT -s ${ipaddress} -j DROP"
/sbin/iptables -A INPUT -s ${ipaddress} -j DROP
done
/sbin/iptables -L
fi
/etc/init.d/iptables save
/etc/init.d/iptables restart
Endprocess
;;
stop)
PRC_NAME="Stop IPTables to remove ${2}.........."
Startprocess
Read_Iplist_File
if [ "${chkFile}" == "1" ];then
for ipaddress in `cat ${2}`;do
Printmsg "NOTICE" "/sbin/iptables -D INPUT -s ${ipaddress} -j DROP"
/sbin/iptables -D INPUT -s ${ipaddress} -j DROP
done
/sbin/iptables -L
fi
/etc/init.d/iptables save
/etc/init.d/iptables stop
Endprocess
;;
start_pp)
PRC_NAME="Start IPtables to block SYN,FIN,RST from ALL IPs.........."
Startprocess
Printmsg "NOTICE" "/sbin/iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP"
/sbin/iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
Printmsg "NOTICE" "/sbin/iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP"
/sbin/iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
Printmsg "NOTICE" "/sbin/iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP"
/sbin/iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
Printmsg "NOTICE" "/sbin/iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP"
/sbin/iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
/sbin/iptables -L
/etc/init.d/iptables save
/etc/init.d/iptables restart
Endprocess
;;
stop_pp)
PRC_NAME="Stop IPTables to remove SYN,FIN,RST from ALL IPs.........."
Startprocess
Printmsg "NOTICE" "/sbin/iptables -D INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP"
/sbin/iptables -D INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
Printmsg "NOTICE" "/sbin/iptables -D INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP"
/sbin/iptables -D INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
Printmsg "NOTICE" "/sbin/iptables -D INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP"
/sbin/iptables -D INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
Printmsg "NOTICE" "/sbin/iptables -D INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP"
/sbin/iptables -D INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
/sbin/iptables -L
/etc/init.d/iptables save
/etc/init.d/iptables stop
Endprocess
;;
*)
Printmsg "ERROR" "Please, Input Type (Usage: ${MENU_INIT} ) correctly!"
Endscript
;;
esac
fi
Endscript

위 Script에서 4개의 선택 메뉴가 있는데, MENU_INIT=”[ start | stop | start_pp | stop_pp ]”
start / stop은 Block_SYN_Flooding.sh start [IP_List_file]과 같이 IP List File을 지정하면 각 IP를 Block 할 수 있도록 되어 있습니다.
Stop을 하면 해제가 되구요. start_pp / stop_pp에 대해서는 IP가 너무많아 대응하기 힘든 경우 SYN Flooding과 관련 된 것들을 Iptable에서 몽땅 Drop 해버리는 겁니다. 실제 Web Service에서 문제없이 사용하고 있습니다. 그러나, 제가 다른 서비스에 대해서는 보장 못 해드립니다. ^ ^;

SYN Flooding 공격에 대한 대처법은 여기까지입니다.  Linux : Dos / DDos 공격에 대한 대처법. #2에서는 Smurf 공격 및 Spoofing 대처법 등에 대해서 다루도록 하겠습니다.

Linux #5 : System File Protection

Linux는 Windows만큼이나 Security에 취약성을 보이지는 않는다고 하지만 그렇다고 해서 그냥 두고 볼 일은 아니죠. Security 침해를 방지하기 위한 최소한의 아니 될 수 있는 한 많은 부분에 대해서 강화를 해야 합니다. 그럼, 먼저 System File Protection 부분에서 Security를 강화 해 보도록 하죠.

System File Protection이라고 하면, Linux System 안에서 사용되고 있는 각 종 File 및 System Directory에 대한 Permission, Ownership, Attribute 등이 될 것 입니다.

1. Boot Loader

chmod 600 /boot/grub/grub.conf
chmod 600 /boot/lilo.conf
chattr +i /boot/grub/grub.conf

2. /tmp, /var/tmp에 1777 permission

chmod 777 /tmp /var/tmp
chmod +t /tmp /var/tmp
chgrp 0 /tmp

3. /, /usr, /var에 755 Permission

755이상의 Permission이 할당되어 있다면 문제의 여지가 많습니다.

chmod 755 / /usr /var

4. User Home Directory Permission

해당 User ID에 대해서만 User Read, Write, Execute만 부여하고 (700), Group, Other에 대해서는 어떠한 Permission도 부여하지 않는 것이 중요합니다.

chmod 700 /home/*

여기서 중요한 건 1회성에 그치지 않도록 User가 생성될 때 자동으로 700을 부여 할 필요가 있는데 이는 아래와 같이 하면 됩니다. UMASK 022가 Default 일텐데, 077로 고쳐주세요.

# vi /etc/login.defs
..
UMASK 077
..

여기서 UMASK는 Permission을 다르게 표기하는데, 그냥 777 – 022 => 755 , 777 – 077 => 700 이렇게 생각하시면 되요.

5. 각종 System File에 각각의 Permission 및 Attribute 부여

/var 관련 부분

chmod 751 /var/log
chmod 644 /var/log/messages
chmod 660 /var/log/wtmp #Who is logged in now. Use who to view
chmod 640 /var/log/lastlog #Who has logged in befor. Use last to view
chmod 600 /var/spool/cron/root

/etc 관련 부분

chmod 600 /etc/crontab
chmod 640 /etc/syslog.conf
chmod 640 /etc/logrotate.conf
chmod 600 /etc/ftpusers
chmod 644 /etc/passwd
chmod 400 /etc/shadow
chmod 400 /etc/gshadow
chmod 750 /etc/pam.d
chmod 600 /etc/hosts.allow /etc/hosts.deny
chmod 600 /etc/securetty #TTY interfaces that allow root logins
chmod 700 /etc/security
chmod 750 /etc/rc.d/init.d /etc/init.d
chmod 751 /etc/sysconfig
chmod 400 /etc/cron.allow /etc/cron.deny
chmod 400 /etc/ssh
chmod 400 /etc/sysctl.conf
chmod 600 /etc/xinetd.conf /etc/inetd.conf
chmod 600 /etc/login.defs
chmod 644 /etc/services /var/run/syslogd.pid
chmod -R g-w /etc

6. System Binary File에 Permission & Attribute 부여

chmod 4750 /bin/su
chattr +i /bin/su
chmod 750 /usr/sbin/useradd
chmod 750 /usr/bin/top
chmod 750 /sbin/fdisk
chmod 750 /sbin/mfs*
chmod 750 /sbin/fsck*
chattr +i /usr/sbin/useradd
chattr +i /usr/bin/top
chattr +i /sbin/fdisk
chattr +i /sbin/mkfs*
chattr +i /sbin/fsck*
chmod 100 /bin/ping /bin/ping6
chmod g-s /usr/bin/wall
chmod g-s /usr/bin/write
chmod u-s /usr/bin/rlogin
chmod u-s /bin/umount
chmod g-s /sbin/netreport
chmod u-s /usr/bin/rsh

필요에 따라서 설정을 잘 조정 해야하니 주의하세요.

Linux #3 : File & File System Management

Cheking Support Filesystem

$ cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   bdev
nodev   proc
nodev   cpuset
nodev   binfmt_misc
nodev   debugfs
nodev   securityfs
nodev   sockfs
nodev   usbfs
nodev   pipefs
nodev   futexfs
nodev   tmpfs
nodev   inotifyfs
nodev   eventpollfs
nodev   devpts
ext2
nodev   ramfs
nodev   hugetlbfs
iso9660
nodev   mqueue
ext3
nodev   rpc_pipefs
nodev   nfs
nodev   nfs4

nodev는 block device에 Mount 되어 있지 않다는 것을 표시합니다.

또한, 아래 Command를 통해서 실제 Kernel Module로서 준비되어 있는 filesystem 확인이 가능합니다. NTFS의 경우, FUSE(Filesystem in Userspa)를 이용하기 때문에 아래 Command로도 표시되지 않습니다.

$ modprobe -l -t kernel/fs
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/autofs4/autofs4.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/cachefiles/cachefiles.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/cifs/cifs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/configfs/configfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/cramfs/cramfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/dlm/dlm.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/ecryptfs/ecryptfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/exportfs/exportfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/ext3/ext3.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/fat/fat.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/freevxfs/freevxfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/fscache/fscache.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/gfs2/gfs2.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/hfs/hfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/hfsplus/hfsplus.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/jbd/jbd.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/jffs2/jffs2.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/gfs2/locking/dlm/lock_dlm.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/gfs2/locking/nolock/lock_nolock.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/lockd/lockd.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/msdos/msdos.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nfs/nfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nfs_common/nfs_acl.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nfsd/nfsd.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp1250.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp1251.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp1255.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp737.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp775.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp850.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp852.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp855.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp857.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp860.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp861.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp862.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp863.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp864.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp865.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp866.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp869.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp874.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp932.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp936.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp949.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_cp950.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_euc-jp.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-1.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-13.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-14.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-15.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-2.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-3.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-4.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-5.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-6.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-7.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_iso8859-9.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_koi8-r.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_koi8-ru.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_koi8-u.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/nls/nls_utf8.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/squashfs/squashfs.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/udf/udf.ko
/lib/modules/2.6.18-92.1.22.el5/kernel/fs/vfat/vfat.ko

FileSystem Benchmark : IOzone (http://www.iozone.org/)

source나 binary로 직접 설치가능하고, 일부 OS는 rpm version로도 설치 할 수 있다.  설치 후 아래와 같은 명령어로 측정이 가능하다.

$ iozone -i 1 -i 2 -Rab bmt.xls

각 Option들에 대한 설명을 덧붙이면,

Option Detail
-a 자동 Test Mode
-b 출력 File의 이름을 지정
-i 숫자 Test 내용을 지정
0
write/rewrite
1
read/re-read
2
random-read/write
3
Read-backwards
4
Re-write-record
5
stride-read
6
fwrite/re-fwrite
7
fread/Re-fread
8
random mix
9
pwrite/Re-pwrite
10
pread/Re-pread
11
pwritev/Re-pwritev
12
preadv/Repreadv
-R Excel로 결과를 출력

Checking i-Node Information

i-Node는 file의 소유권 및 Size, Access 권한, 작성일시, Data 영역으로의 Pointer등의 각종 정보가 기록되는 영역이다. UNIX계열의 OS는 file의 실제 영역을 Data와 i-Node로 구분하고 있다.

Linux에서 일반적으로 사용하는 ext2, ext3등은 file system 작성 시 i-Node size가 최대치로 결정되고 있다. i-Node가 100%가 되는 경우는 그다지 많지 않지만, 경우에 따라 실제 사용량이 적더라도 i-Node가 부족하게 되어 문제가 발생하는 경우가 가끔 있다.

$ df -i
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/cciss/c0d0p2    10487712  241540 10246172    3% /
/dev/cciss/c0d0p6    41779200   48899 41730301    1% /home
/dev/cciss/c0d0p1      26104      39   26065    1% /boot
tmpfs                 505813       1  505812    1% /dev/shm

여기서 Inodes는 할당 가능한 i-Node 수, IUsed는 이미 할당된 i-Node수, IFree는 아직 할당되지 않은 i-Node수이다.

특정 file이나 directory의 i-Node 정보를 확인 할 때에는 “stat” command가 유리하다.

$ stat vpd.properties
File: `vpd.properties'
Size: 1557            Blocks: 8          IO Block: 4096   regular file
Device: 6802h/26626d    Inode: 68927       Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2009-10-13 16:22:20.000000000 -0700
Modify: 2009-10-13 16:23:14.000000000 -0700
Change: 2009-10-13 16:23:14.000000000 -0700

Disk 사용량이 높은 Directory의 확인

du와 sort를 조합하면 가능하다.

$ du -S | sort -n
8       ./archive
8       ./cache
8       ./exports
8       ./lib_ext
8       ./tmp
20      ./lib_ext/xml
24      ./upgrade
76      ./images
80      ./lib_ext/graidle
236     ./lib_int
264     ./lib_ext/pclzip
356     .
608     ./lib_ext/fonts

File System Check Timing의 표시 및 변경

ext3의 경우 Mount/Unmount를 일정 횟수 이상 행하면, 자동적으로 e2fsck에 의한 file system check가 이루어 진다. Mount 횟수는 Super Block(file system의 관리정보를 기록하는 장소)의 Mount count에 보존되어 있고,  check를 행하는 Timing은 Maximum mount count에 보존되어 Mount count = Maximum mount count일 경우 check를 행한다.

Mount count나 Maximum mount count의 현재 상태를 확인 할 경우 “tune2fs” command를 사용한다.

$ tune2fs -l /dev/cciss/c0d0p6
tune2fs 1.39 (29-May-2006)
Filesystem volume name:   /home
Last mounted on:          <not available>
Filesystem UUID:          e2b6586f-7c2c-419c-8728-47f6cb400cfc
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              41779200
Block count:              41758951
Reserved block count:     2087947
Free blocks:              32709952
Free inodes:              41754947
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      1014
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         32768
Inode blocks per group:   1024
Filesystem created:       Wed Aug  5 14:03:26 2009
Last mount time:          Mon Sep 28 15:21:23 2009
Last write time:          Mon Sep 28 15:21:23 2009
Mount count:              6    <= Mount 횟수
Maximum mount count:      -1   <= Check를 실시하는 Mount 횟수
Last checked:             Wed Aug  5 14:03:26 2009
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128
Journal inode:            8
First orphan inode:       9961478
Default directory hash:   tea
Directory Hash Seed:      943c992f-8347-46dd-b47f-a26f4c9882c4
Journal backup:           inode blocks

dumpe2fs -h [Device Name]으로도 동일한 결과를 얻을 수 있다. Check Timing을 변경할 시, tune2fs에 -c 횟수 Option을 넣는다.

$ tune2fs -c 10 /dev/cciss/c0d0p6

/etc/fstab에 기입되어 있는 숫자의 의미

System 기동시에 Mount되는 Device는 /etc/fstab에 설정된다.

$ more /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1
LABEL=/home             /home                   ext3    defaults        1 2
LABEL=/boot             /boot                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
LABEL=SW-cciss/c0d0p3   swap                    swap    defaults        0 0
LABEL=SW-cciss/c0d0p5   swap                    swap    defaults        0 0

첫번째 열은 Mount할 Block Device나 Label 등이, 두번째 열은 Mount Location, 세번째 열은 File system의 종류, 네번째 열은 Mount 시의 Option이된다.

다섯번째, 여섯번째는 숫자가 기입되어 있는데, 전자의 숫자는 File system을 dump할 필요가 있는지의 유무이고(0:Zero이거나 기술이 없는 경우 dump 불필요), 후자의 숫자는 System 기동시 fsck check를 행할 지의 유무로 0:Zero의 경우 check를 하지 않는다. root file system의 경우는 check를 할 경우 1로 설정, 그 외 file system의 경우는 2일경우 check를 행한다.

Linux #2 : About Memory on Linux

System에 장애가 발생 했을 시, 문제를 잘 파악하는게 중요한 Point가 되고,
장애의 원인을 정확하게 파악하고 있다면, 무엇을, 누가, 어떻게 해야 하는지가 명확 해 집니다.
그렇지 못하다면, 인적, 금전적 Resource가 낭비되는 건 당연하구요.

System 상에서 장애 원인을 파악하기 어려운 부분 중의 하나가 Memory인데, 이는 OS 관련 문제 중
20% ~ 30%를 차지하고 있을 정도죠. Memory Trouble은 어려 복잡한 문제가 혼합되어 일어나는데
그 문제는 Application, Middle-Ware, OS, Hardware와 관련되어 더욱더 해결하기 어려워지죠.

일단 Memory를 확인 하기 위한 Command부터 숙지 할 필요가 있을 듯 하네요.
대표적으로 free, vmstat, sar, top, ps가 되죠.

우선,

free : 간단하게 메모리를 파악할 수 있으나, 보기 애매한 부분이 있죠.
vmstat : Memory 상황 및 CPU 사용률도 같이 파악 할 수 있으나, Option이 다양하지 않아 특정
Period에 고부하가 발생 했을 시에는 적합하지 않을 수 있어요.
sar : 위 나열된 Command 중에 가장 취득정보가 많으나,  약간 부적절한 부분도 있어 Memory 감시
관점에서는 vmstat보다 좀 떨어집니다.
top : real time으로 볼수 있는 tool인데, 여러가지 기능이 있고 Log 기록도 가능하죠
( - b batch mode 시)
ps : top과 같이 real time으로 볼 수 있는 tool이고, 여러 Option이 있는데 습관에 따라 쓰는 것
만 쓰게 된다는 예를 들면 "ps ax", "ps aux", "ps -elf" 등이죠.

그럼,  실제 사용 시를 확인 해 볼까요?

# free
total       used       free     shared    buffers     cached
Mem:       4046504    3453500     593004          0     111468    1755760
-/+ buffers/cache:    1586272    2460232
Swap:      4192912    1178400    3014512

각 부분의 의미를 간단하게 설명 하자면

[Mem] total : Total Physical Memory size
[Mem] used : Total Physical Memory size - Free memory size
[Mem] free : 현재 사용되고 있지 않은 여유 Memory
[Mem] shared : 항상 0이고, 현재 사용되고 있지 않음.
[Mem] buffers : File등의 Meta data를 Cache하고 있는 Physical Memory size
[Mem] cached : File의 Real Data를 Cache하고 있는 Physical Memory size
[-/+ buffers/cache] used- : buffers, cached를 포함하고 있지 않은 used size
[-/+ buffers/cache] free+ : buffers, cached를 포함한 free size
[Swap] total : Total Swap size
[Swap] used : Total Swap size - Free size
[Swap] free : 사용하고 있지 않은 Swap size

여기서 [Mem] Free는 “남아있는 Memory Size”가 아닌, 어떠한 용도로도 사용되고 있지 않은
Physical Memory Size
라고 생각하면 되고, 이는 [Mem] Free가 적다  -> 남아 있는 Memory size가
적다 -> 이용가능한 Memory size가 부족하다와 같은 발생을 막기 위함입니다. 따라서, 단순하게
Physical Memory를 추가해도 언젠가는 [Mem] Free가 이전과 같아 지지요.

결론적으로 System 전체의 Memory 사용량의 감시는 [Mem] Free을 판단 기준으로 하는 것이 아니라, 사용가능한 Physical Memory Size로 계산 할 필요가 있죠.

System의 이용가능한 Memory size의 계산은 Linux의 Page Cache에 대해서 이해 할 필요가 있는데,
Linux는 HDD등의 Storage에 저장되어 있는 Data에 대해서 Read / Write 시에 확보 했던 Memory를
Page Cache라는 형태로 보존 합니다.

CPU는 Storage의 Data를 직접 Read 할 수 없어서 Storage Data는 우선 Memory에 Load를 합니다.
이렇게 Read한 Data를 Page Cache로서 재이용합니다. 일단 Load 해 두면 Page Cache는 Read/Write를 Storage에서 Read 해 올 필요가 없으므로 고속처리가 가능하죠.

Page Cache는 새로 Storage Data를 Read/Write로 인해 Memory를 추가 할 필요가 없는 한, Memory를 release 하지 않으므로, 일반적으로 System이 가동하고 있는 것 만으로도 [Mem] Free는 Page Cache로서 계속 활용되고 어느 정도까지 계속 줄어들게 되죠. 서버마다 다르긴 한데, 어떤 건 150MB까지 또 어떤건 202MB 제 경험상 동일한 Application이 계속 돌고 추가 되지 않는 한 항상 같은 Free Memory size를 유지하게 됩니다. 따라서, [Mem] Free가 50MB가 계속 유지된다고 해서 반드시 걱정 할 필요가 없는 거지요.

이 Page Cache는 사용중이 아닌 Storage와 Data Sync 되어 있으면 바로 Release 할 수 있고, Page Cache에 대한 Write가 있을 경우엔 일시적으로 Unsynchronized 상태가 되지만, Storage와의 Sync는 정기적으로 이루어지고 있어 시간이 지나면 Release 가능한 상태가 됩니다. 즉, Page Cache는 “System이 다른 용도로 재이용 가능한” Memory를 포함하고 있죠.

이용 가능한 Physical Memory Size를 free command를 통해 계산 하는 방법

free command에도 어느정도는 Page Cache를 의식하여 개량되어 있고, 그것이 used – 와 free +입니다.

Buffers와 Cached는 Page Cache이고, 정확하게는 Buffers는 Cached에 SwapCached를 추가한 것이 Page Cache의 Total이지만, free command에서는 SwapCached가 표현되지 않죠. 그림을 보면, Buffers와 Cached를 합친 것을 used에서 뺀(used-), free를 더한 (free+)로 보다 현실적인 Physical Memory size와 이용가능한 Physical Memory size를 출력하고 있죠. 따라서, 이 두 수치를 참고하면 됩니다.

그렇다고 해서, System이 이용가능한 Memory size를 파악하기엔 부족하죠. 앞에서, Page Cache를 다른 용도로 재이용하기에는 “Storage와 Sync하고 있음”이라는 조건이 있었죠. Buffers와 cached에는 당연히 “Storage와 Unsynchronized” Page Cache가 포함되어 있죠. 그래서, free+는 실제 이용가능한 Memory size보다 좀 더 부풀려져 있게 되고, 아래와 같이 표현 가능하죠.

free < 실제 사용가능한 Memory size < free+

 

Physical Memory Status 확인 방법

그럼, Storage와의 Sync 정보까지 포함한 Memory 사용상태 감시를 위해서는 ActiveInactive를 감시하면 됩니다.

Active와 Inactive는 vmstat -a cat /proc/meminfo를 통해 취득 가능하죠.

# vmstat -a
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
0  0 1178400 534328 805388 2502796    0    0   161   159    0    0  7  2 89  1  0

$ cat /proc/meminfo
MemTotal:      4046504 kB
MemFree:        424364 kB
Buffers:        117508 kB
Cached:        1845500 kB
SwapCached:     726764 kB
Active:        2610468 kB
Inactive:       803068 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:      4046504 kB
LowFree:        424364 kB
SwapTotal:     4192912 kB
SwapFree:      3014512 kB
Dirty:            9800 kB
Writeback:           0 kB
AnonPages:     1448396 kB
Mapped:          24508 kB
Slab:           152152 kB
PageTables:      27492 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   6216164 kB
Committed_AS:  4136824 kB
VmallocTotal: 34359738367 kB
VmallocUsed:    264576 kB
VmallocChunk: 34359473651 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

 

Active는 Page Cache나 Anonymous Page 중 최근 이용 했거나 아직 Storage와 Unsynchronized인 Release 할 수 없는 Page이고, Inactive는 Page Cache나 Anonymous Page 중 마지막으로 Access 된 이후 어느 정도 시간이 지나 Storage와의 Sync가 완료되어 바로 Release 할 수 있는 Page이죠. 따라서, /proc/meminfo의 MemFree와 Inactive를 더한 것이 정확한 이용 가능 Memory size가 됩니다.
아참 여기서 Anonymous Page란 주로 User Process가 이용하고 있는 Page로, ps 등으로 취득가능한 RSS로 표시되는 값입니다. 실제, Shared Memory가 Page Cache에 포함되어 있거나 해서, 정확하게 파악하는 것은 상당히 번거로운 일이죠.

실제 이용 가능한 Memory size ≒MemFree + Inactive

 Additional information : Kernel Tuning to control the Page Cache

Page Cache가 항상 남아있어 이를 Release 하고 싶은 경우 drop_caches 를 사용하면 되죠. drop caches는 지금 사용되고 있지 않은 Storage와 Unsynchronized Page Cache나 Slab Cache를 MemFree로 Release 합니다.
즉, MemFree ≒ 이용 가능한 Memory가 되죠.

아참 여기서 Slab Cache란 Directory의 Meta Data 정보를 수용하는 dentry나 File의 Meta Data 정보를 수용하는 inode 구조체등을 Cache하고 있는 Kernel내의 Memory 영역입니다. 이는 Page Cache와 별도로 Kernel 안에 확보되어 있고, Storage와 Sync되어 있으면 Release도 언제든지 가능합니다.

아래는 사용방법 입니다.

1. Default 상태로
# echo 0 > /proc/sys/vm/drop_caches
2. Page Cache만 Release
# echo 1 > /proc/sys/vm/drop_caches
3. Slab Cache를 Release
# echo 2 > /proc/sys/vm/drop_caches
4. Page Cache와 Slab Cache를 Release
# echo 3 > /proc/sys/vm/drop_caches

위 drop_caches에 설정 한 parameter는 지속되지 않으므로 필요에 따라 실행해야 합니다.

이 글은 아래 Link의 글을 참조하였습니다.
http://www.atmarkit.co.jp/flinux/rensai/tantei01/bangai01a.html