Author Archives: AR-CHI-VES

Linux #8 : How to Implement Dovecot, DKIM, DomainKey, MySQL in Postfix #2

5. Making and checking each configuration files for Postfix and dovecot

지난 시간에 이어서 각 file들의 대략적인 설정 내용을 확인 해 보도록 하자. 해당 설정 파일은 필자가 구축한 시스템에서 적용된 내용으로 모든 시스템에 적합하다고는 할 수 없다.

그럼, dovecot.conf를 살펴보자.

$ /etc/dovecot.conf
## Dovecot configuration
..
# Protocols we want to be serving: imap imaps pop3 pop3s
# If you only want to use dovecot-auth, you can set this to "none".
#protocols = imap imaps pop3 pop3s
protocols = imaps pop3s - 원하는 Protocol을 설정한다.

## Mailbox locations and namespaces
#mail_location = maildir:/home/popmail/%d/%u
mail_location = maildir:/home/popmail/%u <- Maildir 형식을 사용하고 /home/popmail을 Mailbox Directory로 지정했을 경우

# Don't use mmap() at all. This is required if you store indexes to shared
# filesystems (NFS or clustered filesystem).
#mmap_disable = no
mmap_disable=yes <- NFS나 clustered filesystem 사용 여부에 따라..

# Valid UID range for users, defaults to 500 and above. This is mostly
# to make sure that users can't log in as daemons or other system users.
# Note that denying root logins is hardcoded to dovecot binary and can't
# be done even if first_valid_uid is set to 0.
#first_valid_uid = 500
last_valid_uid = 80000 <- Mailbox에 대한 Permission을 80000으로 설정

# Valid GID range for users, defaults to non-root/wheel. Users having
# non-valid GID as primary group ID aren't allowed to log in. If user
# belongs to supplementary groups with non-valid GIDs, those groups are
# not set.
#first_valid_gid = 1
last_valid_gid = 80000

auth default {
# Space separated list of wanted authentication mechanisms:
# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi
# NOTE: See also disable_plaintext_auth setting.
mechanisms = plain login digest-md5 cram-md5 apop -> 인증 관련 mechanism을 설정

#passdb pam {
#{
<- comment passdb pam.
passdb sql {
# Path for SQL configuration file, see doc/dovecot-sql-example.conf
args = /etc/dovecot-mysql.conf
}
..
# It's possible to export the authentication interface to other programs:
socket listen {
..
client {
# The client socket is generally safe to export to everyone. Typical use
# is to export it to your SMTP server so it can do SMTP AUTH lookups
# using it.
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = root

}
}
}

다음은 postfix 설치시 mysql 연동을 위한 설정을 하였으므로, dovecot을 통해 mysql안의 user table을 참조 할 수 있도록 한다.

$ /etc/dovecot-mysql.conf
driver = mysql
#default_pass_scheme = PLAIN
default_pass_scheme = CRAM-MD5
connect = dbname=postfix user=postfix host=XXXXXXX password=XXXXXXX
password_query = SELECT password FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT concat('/home/popmail/', maildir) as home, 80000 as uid, 80000 as gid FROM mailbox WHERE username = '%u' AND active = '1'

필자는 위에서 “CLAM-MD5″를 사용하였는데, Webmail, postfixadmin, dovecot의 암호화 방식을 통일하기 위해서 입니다. PLAIN을 사용하면 dovecot의 log에서 바로 보이는게 문제가 되고, 다른 MD5를 쓰면 webmail에서 지원을 안하기도 하고 해서..

다음은 postfix의 main.cf의 설정이다. 이 또한 dovecot 연동을 위한 설정을 한다.

$ /etc/postfix/main.cf
..
# INTERNET HOST AND DOMAIN NAMES
#
..
#myhostname = host.domain.tld
myhostname = [my.domain.com] <- FQDN을 지정
..
# SENDING MAIL
#
..
#myorigin = $mydomain
myorigin = $myhostname <- Mail 송신시 Sending address@dlgndml Domain 명을 기입

# RECEIVING MAIL
..
#inet_interfaces = localhost
inet_interfaces = all <- 외부로부터 Mail 수신을 허가

# TRUST AND RELAY CONTROL
..
mynetworks = [Add Trust IPs] , localhost, 127.0.0.1
..
# DELIVERY TO MAILBOX
#
..
#home_mailbox = Mailbox
home_mailbox = Maildir/ <- Mailbox 형식을 Maildir로 설정
..
# SHOW SOFTWARE VERSION OR NOT
#
#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
smtpd_banner = $myhostname ESMTP unknown <- Version 정보의 제거
..
message_size_limit = 10485760 <- 수신 Mail Size를 제한 10485760은 10MB
...
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination

...
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.pem
smtpd_tls_key_file = /etc/pki/tls/certs/mail.pem
smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache
tls_daemon_random_source = dev:/dev/urandom
...

local_transport = virtual
virtual_transport = virtual
virtual_mailbox_base = /home/popmail
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_alias_domains = $virtual_alias_maps
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 80000
virtual_uid_maps = static:80000

virtual_gid_maps = static:80000
mailbox_size_limit = 51200000
message_size_limit = 10240000
virtual_mailbox_limit = 51200000
#virtual_mailbox_limit_maps = hash:/etc/postfix/vquota
virtual_mailbox_limit_override = yes
virtual_overquota_bounce = yes
virtual_mailbox_limit_inbox = yes

virtual_alias_maps = mysql:/etc/postfix,virtual_mailbox_domains = mysql:/etc/postfix,virtual_mailbox_maps = mysql:/etc/postfix 위 설정과 관련 된 DB 접근을 위한 설정 파일도 준비한다. Files은 mysql_virtual_alias_maps.cf mysql_virtual_domains_maps.cf mysql_virtual_mailbox_maps.cf와 같다.

$ more mysql_virtual_alias_maps.cf
user = [db username]
password = [password]
hosts = [hostname]
dbname = postfix
table = alias
select_field = goto
where_field = address

$ more mysql_virtual_domains_maps.cf
user = [db username]
password = [password]
hosts = [hostname]
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and active = '1'

$ more mysql_virtual_mailbox_maps.cf
user = [db username]
password = [password]
hosts = [hostname]
dbname = postfix
table = mailbox
select_field = maildir
where_field = username

일단 여기까지라면 Postfix와 Dovecot, MySQL까지의 단계가 완료 된다.

6. Install DKIM, Domain Key Module on Postfix

• Crypt::OpenSSL::RSA
• Digest::SHA
• Digest::SHA1
• Error
• Mail::Address
• MIME::Base64
• Net::DNS
• Net::Server
• Test::More

DKIM, Domain Key Module을 설치하기 위해서 위와 같은 Perl module들이 필요하게 되고, 물론 Perl도 설치되어 있어야 한다. CPAN으로 설치가 가능한 환경이라면 아래와 같이 하면 된다.

cpan> install Crypt::OpenSSL::RSA Digest::SHA Digest::SHA1 Error Mail::Address MIME::Base64 Net::DNS Net::Server Test::More

그렇지 않다면 상당히 번거로운 작업이 되는데, 아래와 같이 각 Source들을 직접 download 받은 뒤 순서대로 작업을 하면 된다. 각 Module들이 각각 dependency가 존재 해 먼저 설치되어야만 하는 것들이 있다.

[PERL :Error] Error-0.17016.tar.gz
[PERL :Crypt::OpenSSL::RSA]
WITH Crypt::OpenSSL::Random
Crypt-OpenSSL-Random-0.04.tar.gz
Crypt-OpenSSL-RSA-0.26.tar.gz
[PERL :Net::DNS]
WITH Digest-HMAC
WITH Digest::SHA1
WITH Net::IP
WITH Digest::SHA
Digest-SHA1-2.12.tar.gz
Digest-HMAC-1.02.tar.gz
Net-IP-1.25.tar.gz
Digest-SHA-5.48.tar.gz
Net-DNS-0.66.tar.gz
[PERL :Mail::Address]
WITH Date::Format
WITH Date::Parse
WITH Test::Pod
TimeDate-1.20.tar.gz
Test-Pod-1.41.tar.gz
MailTools-2.06.tar.gz
[PERL :Mail-DomainKeys-0.80]
Mail-DomainKeys-0.80.tar.gz
[PERL :AppConfig-1.56]
AppConfig-1.56.tar.gz

위 추가적인 Perl Module을 설치해야만 Mail-DKIM과 DKIMPROXY가 설치가능하게 된다. Perl의 경우 압축 해제 후 perl Makefile.PL;make;make install 명령어로 설치한다.

[PERL :MAIL-DKIM]
Mail-DKIM-0.36.tar.gz
[DKIMPROXY : http://dkimproxy.sourceforge.net/download.html]
WITH PERL :Net::Server
Net-Server-0.97.tar.gz
tar zxvf dkimproxy-1.2.tar.gz
cd dkimproxy-1.2
./configure --prefix=/usr/local/dkimproxy
make;make install

이후 Rebooting시 자동으로 시작 되도록 등록하면 설치 완료.

$ cp source-directory/dkimproxy /etc/init.d/dkimproxy
$ vi dkimproxy
..
### BEGIN CONFIGURABLE BITS
DKIMPROXYDIR=/usr/local/dkimproxy
DKIMPROXYUSER=postfix
DKIMPROXYGROUP=postfix
### END CONFIGURABLE BITS
..
$ chkconfig dkimproxy on

7. Configure DKIM, Domain Key Module on Postfix

위 과정대로 설치를 하였다면 dkimproxy는 /usr/local/dkimproxy에 설치되어 있을 것이다. 그럼, inbound, outbound와 관련 된 설정파일을 설정하는데, 이 파일의 Inbound, outbound Port 즉 아래 설정 내용은 10025, 10026, 10027, 10028은 Postfix의 master.cf의 설정과 연동이 된다.

## Inbound
$ more /usr/local/dkimproxy/etc/dkimproxy_in.conf
# specify what address/port DKIMproxy should listen on
listen 127.0.0.1:10025

# specify what address/port DKIMproxy forwards mail to
relay 127.0.0.1:10026

## Outbound
$ more /usr/local/dkimproxy/etc/dkimproxy_out.conf
# specify what address/port DKIMproxy should listen on
listen 127.0.0.1:10027

# specify what address/port DKIMproxy forwards mail to
relay 127.0.0.1:10028

# specify what domains DKIMproxy can sign for (comma-separated, no spaces)
domain [each domain information]

# specify what signatures to add
signature dkim(c=relaxed)
signature domainkeys(c=nofws)

# specify location of the private key
keyfile /etc/domainkeys/default

# specify the selector (i.e. the name of the key record put in DNS)
selector default

그리고, Domain Key를 생성하고, 아래와 같이 Permission과 Ownership 설정을 한다.

mkdir -p /etc/domainkeys
cd /etc/domainkeys
openssl genrsa -out rsa.private 768
openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
chown -R root.postfix /etc/domainkeys
chmod 755 /etc/domainkeys

$ rsa.private
-----BEGIN RSA PRIVATE KEY-----
MIIBygIBAAJhALgNMgOmSOtOSD3wcDBKb+y2tM1ZOQGTgWIYzzY/TivZvGAaQWMW
K1XuLscr89pqw9tIXrJYrlN0lLhtiddXc9FZwL0AE3LtQQQFUjMgc4JtAHZ13PR7
DNYWFGcF+oQh3QIDAQABAmB5VGGLHFxnmjRveIhMnVWJQ6yOzmmRC284fship3rd
12yiIczHCD9LJ3f43pWjf8s9G6NmpbYO5PZlhGMI9Sc0CM+ZOSfzQgaa2T/Jp7ol
GxgA+PIR+I8uvA7+3iNtIfUCMQDZfEaqFxl2X/Vx7HDIlkioN05Rq4JWIR0e60Ot
vZ6Swy1naK55hCmKJ4GqR+rzRu8CMQDYpTCaied2MJbAbdAf1jKB2GjqHroCCDI0
rqu4Nkp2vW/vt7k6C/I9MBTTkphtA/MCMQCkkKsPzUbREa8xsw1sWntD/gVfOv32
mjvkx3SApPi2aMWUd9t9y4l7JoWxCZY42zUCMDHXBvB2i1ZIZVYNrVS1rVbr128M
9JPlGM+/42d0rfrVJ/xJEwbEmszy08e8sO5bewIwaPvjrQG6sepZ3gSWcL+8Lg5f
dX2fJEbvJjNUFOgzqvmqaPujOR6nvhArLc/ZViDx
-----END RSA PRIVATE KEY-----

$ rsa.public
-----BEGIN PUBLIC KEY-----
MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALgNMgOmSOtOSD3wcDBKb+y2tM1ZOQGT
gWIYzzY/TivZvGAaQWMWK1XuLscr89pqw9tIXrJYrlN0lLhtiddXc9FZwL0AE3Lt
QQQFUjMgc4JtAHZ13PR7DNYWFGcF+oQh3QIDAQAB

여기서 rsa.public에 있는 내용이 DNS TXT record의 p value로서 사용되게 된다. 아래 예를 참조.

k=rsa; t=y; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALgNMgOmSOtOSD3wcDBKb+y2tM1ZOQGT
gWIYzzY/TivZvGAaQWMWK1XuLscr89pqw9tIXrJYrlN0lLhtiddXc9FZwL0AE3Lt
QQQFUjMgc4JtAHZ13PR7DNYWFGcF+oQh3QIDAQAB;

여기서 주의 할 점은 해당 Key는 한줄짜리 임으로 copy & paste 시 line 넘김이 발생하지 않도록 하는 것이다. 이것 때문에 문제가 생긴 적이 있었다.

그럼, Postfix에 dkimproxy를 적용 해 보자. Inbound, outbound에서 설정한 내용대로 Receive & Send가 적절하게 이루어 질 수 있도록 Postfix의 master.cf를 설정해야 한다.

## inbound and outbound filter
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
smtp inet n - n - - smtpd
-o smtpd_proxy_filter=127.0.0.1:10024
-o smtpd_client_connection_count_limit=10
dksign-in unix - - n - 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
127.0.0.1:10026 inet n - n - - smtpd
-o content_filter=
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=
-o mynetworks=127.0.0.0/8
-o receive_override_options=no_unknown_recipient_checks
submission inet n - n - - smtpd
-o smtpd_etrn_restrictions=reject
-o smtpd_sasl_auth_enable=yes
-o content_filter=dksign:[127.0.0.1]:10027
-o receive_override_options=no_address_mappings
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
# -o smtpd_enforce_tls=yes
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_client_restrictions=permit_sasl_authenticated,reject
smtps inet n - n - - smtpd
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
# -o smtpd_client_restrictions=permit_sasl_authenticated,reject
dksign unix - - n - 10 smtp
-o smtp_send_xforward_command=yes
-o smtp_discard_ehlo_keywords=8bitmime
127.0.0.1:10028 inet n - n - 10 smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o smtpd_authorized_xforward_hosts=127.0.0.0/8

여기서 일반 Mail을 보낼 때는 Port 25를 사용하면 되고 Domain Key가 Signed 된 Mail을 보낼 때는 submission Port 587을 사용하면 된다.

$ more /etc/services | grep 587
submission 587/tcp msa # mail message submission
submission 587/udp msa # mail message submission

8. Configure Domain Key on DNS

DNS는 아래와 같이 TXT 형식으로 저장을 하고,

[Zone File]
_domainkey TXT "t=n; o=-;"
[select name]._domainkey TXT "k=rsa; t=n; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALgNMgOmSOtOSD3wcDBKb+y2tM1ZOQGT
gWIYzzY/TivZvGAaQWMWK1XuLscr89pqw9tIXrJYrlN0lLhtiddXc9FZwL0AE3Lt
QQQFUjMgc4JtAHZ13PR7DNYWFGcF+oQh3QIDAQAB;"

dig로 확인을 하면 아래와 같다.

$ dig _domainkey.[domain.com] txt
..
;; ANSWER SECTION:
_domainkey.[domain.com]. 300 IN TXT "t=y\; o=-\;"

$ dig [select name]._domainkey.[domain.com] txt
..
;; ANSWER SECTION:
_domainkey.[domain.com]. 300 IN TXT "k=rsa; t=y; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALgNMgOmSOtOSD3wcDBKb+y2tM1ZOQGT
gWIYzzY/TivZvGAaQWMWK1XuLscr89pqw9tIXrJYrlN0lLhtiddXc9FZwL0AE3Lt
QQQFUjMgc4JtAHZ13PR7DNYWFGcF+oQh3QIDAQAB;"

또한, 아래 Site에서 정상 등록 여부 확인이 가능하다.
http://domainkeys.sourceforge.net/policycheck.html
http://domainkeys.sourceforge.net/selectorcheck.html

9. Start Postfix with Dovecot, DKIM, DomainKey, MySQL

각 Daemon의 기동은 간단하고, netstat를 통해 각 Port를 확인 할 수 있다.

$ /etc/init.d/dovecot start
$ /etc/init.d/dkimproxy start
$ /etc/init.d/postfix start
$ /etc/init.d/httpd start

$ netstat -an
..
tcp 0 0 127.0.0.1:10025 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:10026 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:10027 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:10028 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp 0 0 :::993 :::* LISTEN
tcp 0 0 :::995 :::* LISTEN
tcp 0 0 :::80 :::* LISTEN

각 Port의 대한 정보는 아래와 같다.

DKIM, DomainKey Processing => Local : 10025, 10026, 10027, 10028
DKIM, DomainKey Signed SMTP => 587
Normal SMTP => 25
POP3S => 995
IMAPS => 993
HTTP(WebMail) => 80 (Web Mail 서버가 설치되고, 기동 되었다면)

다음 시간에 위 Mail Server상에 Spam Filtering 설치 해 보도록 하겠습니다.

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 #6 : Implement Postfix with Dovecot, DKIM, DomainKey, MySQL. #1

나는 이전엔 Q-Mail Platform을 상당히 선호하고 있었는데, Postfix로 전향을 하게 된 계기는 DSN(Delivery Status Notification) 기능의 구현을 위해서 였다. Q-Mail을 통한 구현을 여기저기 찾아 보았는데, 결국 허탕을 치고 모든 E-Mail Platform을 Postfix로 바꾸게 되었다. 일본에 있을 때도 그렇고 쭉 5년 넘게 Q-Mail을 다루었던 경험으로 인해 처음엔 Postfix가 어찌 그리 귀찮고 낯설었는지.. 시간이 지난 지금 Postfix가 이젠 Q-Mail보다 좋은 느낌이다.

1. Installation of Postfix

간단하게 Source RPM으로 설치해도 문제가 없으므로, Lastest Version은 아래에서 구하면 된다.
http://ftp.wl0.org/official/2.7/SRPMS/

rpm -ivh [PostFix SRPM]

* 참고로 필자가 사용한 Version은 postfix-2.3.3-2.1.el5_2.src.rpm, 또한 2.3.3 version을 위한 Patch가 있으므로 postfix-2.3.3-vda.patch.gz와 postfix-sleep.patch도 download 받는다.

# cp postfix-2.3.3-vda.patch.gz /usr/src/redhat/SOURCES
# cd /usr/src/redhat/SOURCES
# gunzip postfix-2.3.3-vda.patch.gz
# cp postfix-sleep.patch /usr/src/redhat/SOURCES
# cd /usr/src/redhat/SPECS/
# cp postfix.spec postfix.spec.old

후 MySQL과 Dovecot을 사용하기 위해 Parameter를 변경 해 줄 필요가 있다.

# cd /usr/local/redhat/SPECS/
# vi postfix.spec
..
%define with_mysql  0  ->  1
%define with_dovecot 0 -> 1
..

또한, Patch를 위해 아래와 같은 정보를 추가 해 준다.
(예제에서의 84, 85, 141, 142는 Line Number, Patch Number인 Patch11, 12는 실제와 다를 수 있다.)

84 Patch11: postfix-2.3.3-vda.patch
85 Patch12: postfix-sleep.patch

141 %patch11 -p1 -b .vda
142 %patch12 -p1 -b .sleep

추가적으로 RPMBUILD 및 Authentication 관련 Libary가 필요 하게 되는데 System 상에 설치되어 있지 않을 수도있으므로 아래 command를 실행 해 준다.

# yum -y install pkgconfig rpm-build db4-devel zlib-devel openldap-devel cyrus-sasl-devel pcre-devel mysql-devel openssl-devel

RPMBUILD를 통해 rpm 파일을 생성 후, 설치를 한다.

# rpmbuild -ba postfix.spec
# cd /usr/src/redhat/RPMS
# rpm -Uhv /usr/src/redhat/RPMS/x86_64/[PostFix RPM] (if x86_64)
# rpm -Uhv /usr/src/redhat/RPMS/i386/[PostFix RPM] (if i386)

YUM을 통해 Postfix가 Updating 되지 않도록 아래와 같이 설정을 한다.

# vi /etc/yum.conf
..
exclude=postfix*
..

Booting시 자동 기동을 위해

# chkconfig postfix on

해주면 Postfix 설치는 일단 끝이난다.

2. Installation of Dovecot

Dovecot은 POP3 및 IMAP Server로 Postfix와 같이 구성할 수 있다. Yum을 사용할 수 있다면 설치는 간단하다.

# yum install dovecot
# chkconfig dovecot on

TLS통한 인증 접근을 구성(POP3S, IMAPS)하고 싶다면 인증 Key를 아래와 같이 생성한다.

# cd /etc/pki/tls/certs
# make [Key_Name].pem
# openssl x509 -in [Key_Name].pem -outform DER -out [Key_Name].der

Additional : 필요한 경우 아래 Library도 설치

# yum -y install cyrus-sasl-md5 cyrus_sasl_sql cyrus-sasl-plain
# yum install gnutls

3. Installation of MySQL DB

MySQL은 Account 관련 정보 / Virtual Domain 관련 정보 / Domain 관련 정보를 관리하기 위함이다.

# version : 5.0.77 (필자가 사용한 Version임)
# ./configure --prefix=/usr/local/mysql --enable-thread-safe-client --with-innodb
# make;make install
# cd /usr/local/mysql
# cp /usr/local/mysql/share/mysql/my-[select].cnf /usr/local/mysql/my.cnf

* 환경에 맞춰 my.cnf file을 선택 설정을 한다.

4. Intallation of Apache with PHP

Apache Web Server는 Web-Mail Service를 제공하거나, Postfix Admin을 사용하고 싶은 경우 설치하면 된다.

# yum install httpd
# chkconfig --level 235 httpd off
** Apache도 환경에 맞게 설정을 한다.

5. Making and checking each configuration files for Postfix and dovecot

Postfix configuration files들은 /etc/postix Directory안에 있다.

Edit /etc/postfix/master.cf
Edit /etc/postfix/main.cf

Dovecot configuration files :
Edit /etc/dovecot.conf
Edit /etc/dovecot-mysql.conf   (MySQL DB의 Account 정보를 획득을 위한 파일)

Postfix with MySQL configuration files :
Edit /etc/postfix/mysql_virtual_alias_maps.cf
Edit /etc/postfix/mysql_virtual_domains_maps.cf
Edit /etc/postfix/mysql_virtual_mailbox_maps.cf

위 3 files은 Postfix의 virtual alias, domains, mailbox 정보를 관리하기 위한 파일이다.

설정과 관련 된 자세한 내용은 Implement Postfix with Dovecot, DKIM, DomainKey, MySQL. #2에서..

Trend #2 : 앞으로 10년은 4개의 Trend가 IT 업계를 바꿀 듯 – Gartner Symposium

Gartner Symposium에 의하면 앞으로 10년은 4개의 Trend가 IT 업계를 바꿀 거라고 한다.
그 중심에 있는 것이 Open Social 인 듯 한데..

Gartner 왈 지금 YouTube에서 과거 2년간 Upload된 Data량이 미국 3대 TV의 60년 분량보다 많다고 한다. Wikipedia의 Data 증가량도 그렇고, 특히나 Facebook의 사용자도 5억을 넘었다고 하니(그래서 요즘 장애가 끊이지 않는 Facebook 흐~), Mobile의 발전도 처음 나왔을 때보다 1000배 활용적이고, 10만분의 1정도로 작아졌고..

생각해 보면 IT 즉 과학은 우리가 배워왔던 것 처럼 배수가 아닌 승으로 증가한다고 하니 앞으로 어떻게 될지..  그런데, 나는 20세기 후반에만 해도 21세기 초, 중반에 인류가 화성에 갈 줄  만 알았다. 그것보다 날으는 자동차의 상용화도..

Gartner는 정보는 경제와 Business를 움직이는 것으로 우리가 상상하는 것 이상의 힘을 가지고 있고, 그 Trend는 우리가 너무나도 잘 알고 있는 Clouding Computing, Social Computing, Context Aware Computing, Pattern-Based Strategy라고 한다.  2개는 알겠는데 나머지는 좀 생소하기도 하다.

Cloud Computing의 영향력은 슬슬 나오고 있고, 주류가 되어 가고 있다고 하는데 Engineer 입장으로 아직 근처까지 온 것 같지는 않다. 아직까지는 Social computing이 가장 근접해 있는 듯 한데 Entertainment나 Marketing의 방법, 그리고 Customer Service, Project Managment에 이르기까지 그 형태를 바꿀 거라고 한다.

이건 Twitter의 위력에서도 알 수 있듯이 Garner는 세계와 문화에도 변화가 일고, 기업에도 이미 영향을 끼치고 있다. 오늘날 기업에 존재하는 Business Process는 Rootine적으로 예측 가능한 Business에 적합하지만, 발견과 해석, 교섭, 복잡한 판단을 요구하는 업무에는 적합하지 않다. Knowledge Work은 협력적이고, Social이라고 한다.  Social Computing은 모든 기업과 기업간에 관계가 형성될 것이고, 이는 기업의 생산성 향상에 도움을 줄 것이라고 했다.

Context Aware Computing*(1) .. Wireless 기술의 보급, Laptop, Tablet PC, Smart Phone등의 Device의 다양화로 새로운 Internet 구조가 생겨나 그것이 Context Aware Computing으로 발전해 가고 있다.

Gartnet는 Text나 Data, Graphic, Audio, Video등과 위치, 언어, 혹은 User가 무엇을 원하고 있는지까지를 포함한 Context를 조합하여 이것을 Base로 한 Software나 Service가 등장 할 거라고 한다.  이후 User의 위치정보를 통해 User의 행동패턴을 분석/판단 가능하게 되고, 여러가지 언어에 대응해 장치간/사람과 장치간의 언어변환도 가능해 지고, 이것이 Business에 변화를 줄것이라고 한다.

Pattern-Based Strategy는 SNS분석과 Context Aware Technology, 예측 분석 Tool등의 Pattern Base 기술을 기반으로 정보안에 존재하는 Pattern을 찾아내 Model화 하는 전략이다. Pattern을 예측하는것이 앞으로의 Trend가 되고, 2016년까지 모든 기업이 이 방법을 선택할 거라고 Gartner에서 논의되고 있다.

정보를 어떻게 잘 처리하고 분석하고 관찰할 수 있는지가 앞으로 주력이냐 아니냐를 결정하는 척도가 되고 기술로 그걸 예측분석 가능하게 되어가고 있다 이것을 정확하게 Business에 활용하는 것으로 추가가치를 만들어 낼 수 있는 힘을 얻는 것일 것이다.

그리고, 이 모든 것은 기업에 큰 영향을 줄 것이다.

*(1) Context Aware Computing : 많은 정보통신기술이 지금까지 목표로 해온 누구든지, 언제든지, 어디든지, 여러가지 정보에 간단하게 접근 가능한 환경이 만들어지고 있다. 그러나, 정보유통의 비용 절감에 따라, 사람의 힘으로 처리 할 수 없을 정도의 방대한 량의 유용하거나 쓸모없는 정보들이 넘쳐나기 시작했다. 이 같은 방대한 정보 중에 사용자의 Context에 따라 나를 위한, 지금을 위한, 지금 이 장소를 위한 정보를 제공하는게 중요하게 되었다. 따라서 정보 중심이 아닌 인간 중심형의 Network를 제공하는 것이 목적으로 맞춤형이란 말이 어울리겠고, 위치정보를 고려한 Social Networking Platform, Sensor 정보와 행동패턴을 이용한 Service Platform, Smart Material, 일상 생활의 Monitoring Guidance 등등으로 연구되고 있음.

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 #4 : Basic of Shell & Shell Scripting #1

Shell은 Interface의 한 부분으로 Command Base의 User Interface라고 할 수 있습니다. 그 이유는 Keyboard를 통해 입력하여 Enter Key를 누르는 순간 동작 및 결과 값을 보여주기 때문이죠. 이는 Unix(Linux)의 기초라고도 할 수 있습니다.

Shell을 이용함에 있어 중요한 것 중 하나가 Stream인데, 이는 여러 Command를 조합하여 사용할 수 있는 걸 말하죠.  Input -> Command -> Command -> Output과 같은 식으로 결과를 조작 할 수 있게 됩니다.

$ cat file1 file2 | grep "hello world" | sort -r | less
여기서는 cat, grep, sort, less라는 command가 사용되었죠.

위에서 command는 Input과 Output을 가지게 되는데 이걸 Standard Input, Standard Output으로 표현 합니다. 여기서 Standard가 붙은 이유는 변경 가능하기 때문이죠. 이 변경을 Redirect라고 합니다.

$ cat < file1 | grep "hello world" | sort -r > result_file
두 기호 "<"과 ">"로 Redirect를 행합니다. Standard Input은 file1, Standard Output은 result_file이 됩니다.

그럼, 일단 변수에 대해서 정의를 해보면, Shell 변수는 미리 선언 할 필요가 없고 처음 사용될 때 만들어지며, 대소문자를 구별하며 기본적으로 문자열로 저장하게 된다. 만약 계산이 필요하다면 수치로 변환되어 계산되고 이후 문자열로 저장되고, “$“을 붙여서 사용한다. 단, 변수에 값을 대응 할 시에는 “$“을 사용하지 않습니다.

변수를 미리 선언하는 경우 ex) float a, b;
Shell 변수의 경우(값 대입시) ex) HOME="Hello World"
Shell 변수의 경우(사용시) ex) echo $HOME

변수는 환경 변수, 인자 변수, 일반 변수로 구분된다.
환경 변수의 경우는 Shell 기동 후 기본적으로 Setting 되어 있는 변수입니다.

$0 : 실행 된 Shell Script Name
$# : Scripts에 넘겨진 인자의 갯수
$$ : Shell Script의 Process ID

이고, 일반 변수를 export를 사용하여 환경 변수로 처리할 수 있습니다.

export HOME

인자 변수의 경우는 Shell Script에 인자를 넘겨 줄 때 그 인자들에 대한 정보를 가지는 변수입니다.

$1 ~ $nnn : 넘겨진 인자들
$* : 스크립트에 전달된 인자들을 모아놓은 문자열
$@ : $*과 동일함

그리고, 마지막으로 일반 변수인데 특별한 제약이 없고 대소문자 만 구별하면 됩니다.

#!/bin/sh
echo "Test Script #1 : $0"
echo "Process ID : $$"
echo "Argument Count : $#"
echo "Argument List(*) : $*"
echo "Argument List(@) : $@"
echo "Argument #1 : $1"
echo "Argument #2 : $2"

위 Script를 아래와 같이 실행하면

$./Test_Script_#1 1_hello 2_world
Test Script #1 : ./Test_Script_#1
Process ID : 12342
Argument Count : 2
Argument List(*) :  1_hello 2_world
Argument List(@) : 1_hello 2_world
Argument #1 : 1_hello
Argument #2 : 2_world

의 결과값이 나오겠죠.

간단하게 순서대로 명령어만 실행되는 Script라면 Script라고 하긴 좀 그렇고, 조건문들을 다루어 봐야 합니다.  조건문은 Programing을 하셨다면 아시다시피 if, for, while, case 크게 다르진 않습니다. 한가지 재미있는 건 조건문을 끝낼 때 if는 fi, case는 esac같이 거꾸로 쓰는게 있다는 거 for나 while의 경우는 do로 시작해 done이죠.

if 구문 : 조건에서 이게 없으면 시체나 다름 없죠. 삶은 case와 같이 여러 갈래가 있기도 하지만, Yes or No 만큼 중요한 건 없습니다.(거의 일상 생활이나 다름 없죠)

CHK_EXT3=`cat /etc/fstab | grep -c "ext3"`
if [ $CHK_EXT -eq 0 ];then
echo "There is no ext3 filesystem."
else
echo `cat /etc/fstab | grep "ext3"`
fi

여기서 “`(Back quote)“가 사용되고 있는데, “`[command line]`” Command Line을 실행한 결과 값을 변환 해 주는 겁니다. 그리고, 여기선 /etc/fstab에 ext3 filesystem이 있으면 grep으로 count하여 없으면 There is no ext3 filesystem 있으면 해당 line을 보여주는 겁니다. 또, 수식에 따른 조건 연산자(산술 연산자) -eq를 사용하였는데 각 연산자를 설명하면 아래와 같습니다.

-lt : 보다 작다 (Lesser Than)
-le : 이하 (Less or Eaqual)
-eq : 같다 (Eaqual)
-ge : 이상 (Greater or Eaqual)
-gt  : 보다 크다 (Greater Than)
-ne : 같지 않다 (Not Eaqual)

위에서는 A가 아니면 B(if ~ else문)인데, 아래와 같이 elif(if~elif문)를 쓰는 경우 조건을 더욱 확장 가능합니다.

# Source function library
if [ -f /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
elif [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/functions ]; then
. /etc/rc.d/functions
fi

여기선 if와 함께 file의 속성확인에 사용되는 연산자가 사용 되었는데, File 조건 연산자는 아래와 같습니다.

-d FILE : Directory로서 존재(Directory)
-e FILE : File이 존재(Exist)하나 Directory일 수도 있음
-f FILE : File로서 존재(File)
-r FILE : Readable file임
-s FILE : File is not empty (Size가 있음)
-w FILE : Writable file이고, 또한 Directory안을 확인 가능
-x FILE : 실행가능(eXecute)
-O FILE : 소유권이 있음(Owner)
-G FILE : 그룹에 포함되어 있음(Group)

추가로 File의 시각확인을 위한

FILE1 -nt FILE2 : FILE1이 FILE2보다 새거임 (Newer Than)
FILE1 -ot FILE2 : FILE1이 FILE2보다 오래됨 (Older Than)

추가로

if [ \( -d FILE1 \) -a \( -x FILE2 \) ];then
-a : &&과 같이 둘 다 성립할 때만 조건 만족
if [ \( -d FILE1 \) -o \( -x FILE2 \) ];then
-o : ||과 같이 둘 중에 하나만 성립해도 조건 만족

마지막으로 문자열 비교 연산자를 확인 해 보면,

[ String ] : String이 NULL이 아니면 조건 만족
[ String1 = String2 ] : 두 문자열이 같으면 조건 만족
[ String1 != String2 ] : 두 문자열이 다르면 조건 만족
[ -n String1 ] : String1이 NULL이 아니면 조건 만족
[ -z String2 ] : String1이 NULL이면 조건 만족

아래 예제를 참고 해 보세요.

CONTINUE="$INIT_CONTINUE"
if [ -z "$CONTINUE" ];then
cat <<EOF

$DATE_TIME [INFO] Continue....
EOF
CONTINUE=`Prompt "[INFO] Press ('Any Key' for Continue): "`
fi

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를 행한다.

Tech #4 : VMware VSphere 4.1의 Network 구성

VMware VSphere 4.1에서는 Network의 자원 관리를 보다 적절하게 실현하기 위한 기능으로 “Network I/O Control”가 도입되었다고 한다. 또, NIC Teaming의 Load Balance Algorizm 으로 “Load Based Teamin”이라고 하는 신 Algorizm이 이용가능하게 되었다고 한다.

일단, 이전의 ESX(Classic)은 가상화을 행하는 “VMKernel”의 영역과 관리기능을 제공하는 “Service Console” 영역이었으나, Server의 처리 능력 향상에 비례하여, 가상 Machine의 집약 능력도 향상하는데 이는 보다 광대역의 Network 환경이 요구된 다는 걸 의미한다. 그걸 말해 주듯 이제 10Gbits Internet도 보급되기 시작했고, 10Gbits EtherNet의 Controller나 Switch를 포함하는 Blade Server도 등장하여 본격적인 궤도에 올랐다고 볼 수 있다.

10Gbis Ethernet의 사용을 전제로 System을 구축 할 경우 여러가지 Data 통신을 통합하는 시도도 많아 질 수 있고, 가상 Machine이 이용하는 Network를 포함한 관리 Network, iSCSI나 NFS 등의 Storge Network, vMotion이나 VMware FT가 이용하는 Data Transfer 등도 통합 해야 할 것이다. 통합을 위해서는 다른 Resource에 의해 대부분의 Performance가 점유되어 가상 Machine 전체가 Slow down 되는 경우를 피해야 하고, 그에 맞는 설계를 할 필요가 있다.

여기서, Network 자원 관리가 중요 해 지는데, Previous Version에서도 “Traffic Shaving”란 기능을 제공 했었고, 이건 가상 Port 또는 Port Group가 이용가능한 대역의 상한치를 지정하는 기능으로, 표준 가상 Switch에서는 Outbound Traffic, 분산가상 Switch에서는 Inbound, Outbound Traffic 가각의 Traffic에 대한 설정이 가능, 단 Traffic Shaving은 간단하게 이용가능한 상한치를 제어하는 기능 뿐으로 Unused 대역에 대한 다른 용도로의 전환은 불가능 하다. 아래 그림 처럼 Unused 영역이 있어도 상한치 이상을 사용 할 수 없다.

 

보다 이상적인 Network 자원 관리를 실현 하기 위하여 자원의 간섭이 있을 시, 미리 설정을 해 둔 비율로 Balance를 맞춰, 자원이 비어 있는 상황에서는 그 자원을 필요한 용도로 전환 하는 것이 가능 해야 한다. 아래의 그림과 같다.

 

CPU자원과 Memory 자원에 관해서도 위와 같은 자원 관리 구성이 Previous Version에 대해서도 제공 되었다. vSphere 4.1에서는 Network 자원에 관한 동일한 기능이 제공 되어 지는데, Network I/O Control이 그것이다.

Network I/O Control

vSphere 4.1의 new function “Network I/O Control”은 앞에서 설명 했던 것 처럼 유연한 Network 자원 관리를 실현하는 메카니즘이고, 현재 Enterprise Plus Edition에서 제공하고 있다. 또, 이 기능은 분산 가상 Switch 상에서 제공되는 기능이고, 표준 가상 Switch상에서는 이용 할 수 없다.

Network I/O Control에서 Network Traffic을 아래와 같이 6 class로 구분할 수 있다.

  1. FT Traffic
  2. iSCSI Traffic
  3. vMotion Traffic
  4. Management Traffic
  5. NFS Traffic
  6. Virtual Machine Traffic

User는 각각의 Class에 대해 “Limit” 혹은 “Share”라는 값을 설정 할 수 있고, “Limit”는 해당 Class가 사용 가능한 최대치이고, Mbps로 설정한다. “Share”는 “자원 간섭이 있을 시 Balance 값”으로 1 ~ 100의 정수값을 설정한다.

Network I/O control의 동작

Network I/O Control은 ESX로부터의 Outbound Traffic에 대해서만 유효하고, Inbound Traffic은 제어 대상이 아니다. 또, “Share 값의 계산은 최종적으로 각 ESX Host 단위” 도 주의 할 점이다. 분산 가상 Switch를 구성할 경우, 보통 각 ESX에 구성하는 Uplink의 수나 물리 Adapter의 대역등은 공통이지만, 그렇지 않은 경우는 주의가 필요하다. 1Gbps의 NIC으로만 구성되는 Host와 10Gbps의 NIC을 보유하는 Host가 같이 있는 경우는 Share 값의 계산 결과로 확보되는 대역이 Host에 따라 다른 경우가 있다. 

“Limit”나 “Share”의 설정은 동시에 유효화가 가능하고, Share값 계산의 결과 획득 가능한 대역이 Limit에서 제한하고 있는 값보다 큰 경우 Limit의 값이 적용된다.

Load Based Teaming

LBT는 복수의 물리 NIC을 통합 가능한 대역의 확보와 이중화를 제공하는 “NIC Teamng”이 적용된다. 복수의 물리 NIC으로 Link을 구성함과 더불어 각 Traffic이 어떻게 물리 NIC을 결정하는 가의 알고리즘이 필요하게 된다. 해당 알고리즘은 아래와 같다.

  1. Port ID Based
    Default로 이용되는 알고리즘으로 Port ID란 가상 Switch내의 Port ID. 가상 NIC이 접속하고 있는 가상 Port별로 이용하는 물리 NIC이 결정 된다. 즉, 하나의 가상 NIC을 하나의 물리 NIC을 대응하는 방식이지만, 복수의 가상 Machine인 환경에선 부하 분산도 기대 할 수 있다.
  2. Source MAC
    Traffic의 Source측의 MAC Address, 말하자면 가상 NIC의 MAC Address 정보를 기초로 한 Hash값을 두고 물리 NIC을 결정하는 알고리즘. 하나의 가상 NIC이 최종적으로 하나의 물리 NIC을 댕응하는 점에서는 Port ID Based와 같다.  많은 경우 Port ID Based의 부하분산은 유효하지만, 운영하는 형태에 따라서는 물리 NIC의 사용률이 균일하지 않은 경우가 있다. 예를 들면 물리 NIC x 2로 Teaming된 가상 Switch에 20대의 가상 Machine이 접속되어 있는 상황을 가정하면  System 운영 특성 상 홀수번째의 가상 Machine이 Active로 동작하고, 짝수번째의 가상 Machine은 대기하고 있다면, 이 경우 부하분산 알고리즘으로 Port ID Based를 이용하면 결과적으로 한쪽의 물리 NIC에 Traffic이 집중되어 버린다. 이런 경우 Source MAC을 이용하여 양측의 물리NC이 균일하게 사용되도록 할 수 있다.
  3. IP Hash
    IP Hash는 각 Traffic의 Source IP Address, Destination IP Address들을 바탕으로 Hash값을 계산하고, 이용하는 물리 NIC을 결정한다. 복수의 Destniation이 있는 경우, 하나의 가상 NIC이 복수의 물리 NIC을 사용 할 때 유리하다. IP Hash를 사용할 때는 물리 Switch측에 IEEE 802.3ad Link Aggregation을 유효화 시킬 필요가 있다.
  4. Load Based
    물리 NIC의 대역 사용 상황에 따라, 동적인 가상 Port와 물리 NIC간의 관계를 변경 한다. 초기 배치는 Port ID Based와 같은 방식으로 구성되지만, 운영 중 부하의 쏠림이 발생할 것 같으면 자동적으로 이 Mapping 을 변경 한다. vSphere 4.1로 부터 제공되는 기능으로 분산가상 Swtch만 지원 한다.

Load Based Teaming의 동작

LBT를 선택하면, 물리 NIC의 부하상황에 맞춰 가상 Port와 물리 NIC의 Mapping을 자동적으로 변경하게 된다. 이 때의 판단 기준은 Default로는 “물리 NIC의 대역 사용률이 75%를 넘는 경우가 30초이상 지속적으로 발생 할 때” .  Network Traffic은 순간적인 것, 지속적인 것이 있는데, 너무 과민하게 설정을 할 경우 오히려 역효과가 날 수 있다.

Network I/O Control, Load Based Teamin은 Enterprise Plus License가 필요하다.  쩝.. 슬픈 일이군..

Trend #1 : Early Warning Signs of IT Project Failure : The Dominant Dozen

“Early Warning Signs of IT Project Failure : The dominant Dozen” 라는 논문이 있는데, 제목 그대로 실패하는
IT Project에 대해서는 12가지 징후가 있다고 한다. 따라서,  이런 문제가 있다면 미리 바로 잡을 필요가 있을 것이고
아래와 같다.

인재면에서의 Risk

  • Management 상층부로부터의 Support가 불충분
  • Project Manager의 역량이 부족
  • 이해관계자에 따른 관여나 참여가 불충분
  • Project Team의 열의가 부족
  • Team Member의 지식이나 Skill이 부족
  • 담당업무를 대상으로 하는 전문가의 Schedule 과다

Process면에서의 Risk

  • Project의 투자 대비 효과에 대한 검토가 결여 됨
  • 요건이나 성공 기준에 관한 docuement가 존재하지 않음
  • 변경 관리를 위한 Process가 결여 됨
  • Schedule 초안이나 관리 부족
  • 이해관계자 간의 Communication이 원만하게 이루어 지지 않음
  • Resource가 보다 우선 순위가 높은 Project에 대해서만 할당 되어 있음

무언가 더 있을 거라고 생각 했는데, 위 12가지는 당연하게 지켜야 할 것들 같아 보인다. 사실 모든 Project를 함에 있어
지켜야 할 기준이 있고, 그걸 잘 지켜나간 다면 실패할 가능성도 적어지리라…

Tech #3 : What is the Virtualization Technology?

(2007년 3월 1일)

“Server의 가상화”는 기업에 있어 이미 필수 기술이 되었다고 해도 과언이 아니다. 가상화에 있어 처리능력의 증강을 원한다면, 새로운 H/W를 구입할 필요는 없다. 그것은 말하자면, H/W구입비라고 하는 지출을 줄이는 것이기도 하고, Data Center의 Space와 전기 및 냉각에 드는 Cost를 절약하는 것이기도 하다. 물리적인 Server가 아닌 가상 Server를 선택하는 것은 기업에게 재무의 건전성을 부여하고, IT지출을 삭감하는 효과가 있다라고 하는 것이다. 여기에서 그런 Merit를 가진 가상화 Architecture 면으로부터 다시금 정리 해 보았다.

Nill Macarista
InforWorld Online 미국판

가상화의 기술, 가상화라는 Concept자체는 결코 새로운 것이 아니다. 실제, 이미 1970년대에 Main Frame Computer는 복수의 OS Instance를 동시에 실행하고 있었따. 그것이 가상화의 시작이 된다. 그 후, S/W와 H/W가 진화하여, 가상화는 더욱 가깝게 체감할 수 있는 기술이 되었다. 현재, 업계표준이 되어 있을 정도로 일반적인 Server에서도 가상화를 행하는 것이 가능하다.

지금, 시장에서는 proprietary로부터 Open Source까지, Data Center Manager가 선택하기 곤란할 정도로 많은 종류의 가상화 Solution이 넘쳐나고 있다. 여기서는 가상화에 대한 Approach 방법(Achitecture)에 있어 “완전 가상화” “모의 가상화” “OS Level의 가상화”의 3가지로 분류하고, 각각의 기술적인 특징을 소개한다.

※ Proprietary란,“전용의” “독자의” “독점적인” “소유권, 점유권이 있는” “비공개의”의 이미로, Computer관련용어로서는 Open의 Opposite word이다.
표준화가 진행된 PC (Client / Server System, Web System)에 따라 System을 “Open System”이라고 부를 때, Main Frame System과 같은 특정 Maker등에 따른 특정의 독자사양으로 구성된 Computer System을 “Proprietary System”이라고 한다.
또, Linux에 대표되는 Source Code가 공개된 S/W를 “Open Source Software” “Free Software”라고 부르는 것에 반해, Windows나 MAC OS와 같은 Software Maker가 Source Code(지적소유권)을 독점 소위 점유하고 있는 Soft는 “Proprietary Soft”라고 불린다.

완전 가상화 (Full Virtualization)
가상화 Solution 중에 가장 많이 보급된 것이 “Hipervisor”라고 불리우는 Architecture를 사용한 “완전 가상화”이다. 이것은 가상 Server와 H/W간에 추상적인 Layer(가상화 Layer를 실장한 전용 Kernel)을 배치하는 Architecture이다.
이 Approach를 채용하고 있는 상용제품으로는 “WMware”와 Micro Soft의 “Virtual PC”가 있고, Linux용 Open Source 제품으로는 “KVM (Kernel-based Virtual Machine)”가 있다.
Hipervivor는 CPU명령에 관여하여, H/W Controller와 주변기기로의 Access를 중개한다. 사실상, 어떤 OS라도 수정없이 가상 Server상에 Install할 수 있고, 그 Guest OS는 가상환경에 있다는 인식없이 가동한다. 더불어 이 Architecture의 결점은 Hipervivor에 의해 Processor에 큰 Overhead가 걸리는 것이다.
완전 가상화 환경에 있어 Hipervivor는 H/W상에서 직접 가동하고, Host OS(Kernel)로서 기능(다른 말로 하자면, Windows나 Linux 같은 일반 Host OS를 필요로하지 않음)한다. 그 Hipervivor가 관리하는 가상 Server상에서 Guest OS가 움직이는 셈이다.

 

모의 가상화 (Para Vritualization)
완전 가상화에서는 여러가지 가상 Server를 관리하고, 나아가 각각을 독립 가동시키고 있는 Hipervivor의 요구가 모든 Processor에 집약(그 때, Guest OS는 일절 가상화에는 관여하지 않음)된다.
이 부담을 경감시키기위한 수단의 한가지가 Guest OS에 관여 가상화 환경을 인식시키도록 함과 더불어 Hipervivor와 연계시키는 것이다. 이것이 “모의 가상화”라고 불리는 Approach이다.
이 모의 가상화 방식을 채용하고 있는 대표적인 제품이 Open Source “Xen”이다. Xen에서는 Kernel부분에 변경을 가함으로서 처음으로 Xen Hipervivor의 가상 Server상에서 Guest OS가 가동가능하게 된다. 이로 인해 BSD, Linux, Solaris와 같은 Open Source OS는 Support하지만, 수정을 할 수 없는 Windows등의 Proprietary System의 가상화에는 적합하지 않다.
모의 가상화의 우위성은 “Performance”에 있다. Hipervivor와 연계하는 모의 가상화 Server는 가상화되고 있지 않은 Server와 거의 동등한 성능을 발휘한다. Micro Soft와 VMware가 각각 자사제품을 보완하기 위해 모의 가상화기술에 힘을 쏟고 있는 상황을 보면, 그것이 충분히 매력적인 기술이라는 것을 알려주는 것이다.

 

OS Level의 가상화 (OS Level Virtualization)
OS Level의 가상화로는 문자그 의미대로 OS(Host OS)의 기능에 의해 가상화를 실현하는 Architecture가 있다. Hipervivor Layer는 존재하지 않고, Host OS가 스스로 H/W Resource를 분할 하거나, 각 Server를 독립 운영시키거나 한다. 모든 가상 Server가 동일 OS상에서 가동하는 점이, 다른 가상화 기술과의 큰 차이(그러나, 각 Instance는 고유의 Application과 User Account를 보유함)이다.
이 Architecture의 결점은 “유연성”이 결여되어 있는 것이지만, 그 반면 “Native Speed 향상이 가능하다”라는 이점도 있다. 또, 모든 가상 Server에 단일 표준의 OS가 적용되어지기 때문에, 다른 환경에 비해서 관리가 용이하다는 점도 Merit로 여겨진다.

CPU의 가상화 대응
Main Frame과는 다르게 PC의 H/W는 원래 가상화를 고려하여 설계되었다고 말 할 수 없다. 그로인해 최근까지 부하는 모든 S/W에 걸리지만, AMD와 Intel이 최신세대 Processor에서 처음으로 CPU Level에의 가상화를 Support하기 시작한 걸로 인해, 상황은 크게 바뀌려고 하고 있다.
더불어, AMD와 Intel의 Technology는 동일한 Merit를 가지고 있지만, 불행하게도 Code의 호환성은 없다.
그렇다하더라고, H/W Level의 가상화 Support로 인해, 가상 Server로부터 I/O Channel이나 H/W Resource로의 Access관리는 H/W측에서 행해지게 되고, Hipervivor가 부담해 오던 관리부하는 상당히 경감되었다. 또, OS(Windows를 포함)에 관여하지 않고도, 모의 가상화 환경으로 가동시킬 수 있게 되었다.
더욱이, CPU Level의 가상화 환경을 실현하기 위해서는 가상화 S/W를 다시 만들어야 하는 절차가 필요하다고 한다. 그러면서도, 이 기술이 가져다 주는 Merit는 그 부분을 고려하고도 남을 정도로 크기 때문에, 결국 이런 저런 종류의 가상화 S/W가 이 기술을 Support하게 될 것이다.

각각의 기술의 비교
지금까지 소개했던 가상화 방법 중 어느것을 채용할지는 각각의 기업(Data Center)이 놓여있는 상황에 따라 다를 것이다. 예로, 단일 OS Platform을 기반으로 하는 Server군의 경우에는 OS Level의 가상화로 통합하는 방법이 적합하다고 말 할 수 있다.
한편, 모의 가상화 방법을 채용하면 – 특히 가상화에 대응하는 Processor와의 연계가 완성되어 있는 경우에는 – 높은 성능을 유지하면서, 다른 종류의 Guest OS System 환경이 구축가능한 Merit를 흡수하는 것이 가능하다.
또, 완전 가상화는 3가지의 가상화 방법 중 성능면에서는 가장 떨어지지만, Guest OS간의 완전한 독립성을 유지할 수 있는 Merit를 가진다. 많은(종류의) Guest OS를 Support하고 싶을 때, 소위 S/W 품질보증이나 Test를 행하고 싶을 때에는 이 방법이 적합하다고 할 수 있다.
완전 가상화 Solution은 그 외에도 여러가지 특징이 있다. 예로, 가상 Server의 특정시점에서의 상태 정보를 취득하고, 보존해 두는 “Snapshot”기능을 이용하면, 여지껏 간단하게 장애복구 대책을 실시 할 수 있다. 또, 최근에 이 기능을 활요하여, 자사제품의 평가판을 Pre-Package화한 가상 Server Image로서 Download 제공하고 있는 S/W 기업도 증가하고 있다.
그렇다하더라도, 가상화 기술/Architecture를 막론하고, 가상 Server에는 물리 Server라는 지금까지와 같은, 계속적인 Support와 Maintenance를 필요로 한다. 이미, 기존의 IT환경으로부터 효율적인 Cost 효과에 우수한 가상화 환경으로의 이행을 간단하게 행하기 위한 Tool을 시작, 여러가지 가상 Server 용 관리제품이 시장에 투입되고 있기 때문에, 그것들을 활용하면서 보다 좋은 가상화 환경의 실현 해 나갈 수 있다.

 

※ 위 글은 아래의 링크의 기사를 번역한 글입니다. 다소 오역이 있을 수 있습니다.

http://www.computerworld.jp/topics/vt/59310-1.html