티스토리 툴바


################################################################3
### 쓴것 : Sendmail 로그분석 스팸 탐지 관련 삽질
### 쓴이 : 권성재(nonots@hanmail.net, http://www.badaweb.co.kr)
### 쓴때 : 2011-12-02
################################################################3

1. 개요

서버관리자들에게 있어서 스팸메일 보내는 인간들은 때려죽이고 싶은 충동을 
불러일으킵니다.
다른 해킹과 달리 스팸공격하는 건 로그분석해서 찾기도, 막기도 어렵습니다.
더구나, 많은 스팸이 한메일이나 네이버,구글 메일서버로 보내지다 보니,
한메일이나 네이버 메일서버 측에서 멀쩡한 메일서버 ip 를 차단해서
선량한 일반 메일 사용자들이 메일이 발송되지 않아 피해를 입습니다.
아래에,
리눅스 서버에서 sendmail 데몬 관련해서 삽질하면서 알게 된 정보를 공개합니다. 
허접합니다만, 나보다 더 허접한 관리자들에게 조금이나마 도움이 되었으면 합니다.


2. 서버환경
	- OS : CentOs 5.x (레드햇 계열)
	- Sendmail 버전 : 12.x, 13.x
	- POP3 데몬 : dovecot, qpopper 등
	- 메일 로그 파일 : /var/log/maillog


3. 웹소스 통한 스팸 발송 관련

	- 그누보드나 제로보드등 웹사이트 게시판의 첨부파일 업로드 기능의 헛점을
	이용해서 서버에 .php 같은 실행파일을 저장한 후 외부에서 이 파일을 통해서 
	스팸을 발송하는 방법입니다.
	문제는, 이렇게 웹경로에 업로드한 후 스팸메일을 보내면 해당 서버에 있는 sendmail 
	로그에 잘 기록이 안됩니다.	
	php 모듈이 웹서버권한을 이용해서 막바로 보내므로 특정 사용자 계정을
	알수가 없습니다. 또 한 외부 서버에 포트 접속해서 발송한다면 내부 메일서버에는
	기록이 남지 않게됩니다.
	이건 maillog 분석으로는 알기어렵고, 반드시 무단으로 업로드된 해킹 파일을
	찾아서 삭제해야 합니다.
	여기서는 간단한 방법만 소개합니다.
	
	만약 웹로트가 /home/mywebsite_home/public_html 인 곳에 그누보드가 설치됐고
	freeboard 라는 게시판아이디를 사용했다면
	/home/mywebsite_home/public_html/data/file/freeboard 이곳에 첨부파일이 
	저장되므로 보통 이런 곳에 해킹파일이 업로드 됩니다.

	# pwd 
	/home/mywebsite_home/public_html/data/file/freeboard 
	# ls *.php
	Iist.php corp.php meixia.php each.php dm.php yh.php lele.php  mem.php

	와 같이 게시판 저장경로에 이상한 php 파일이 저장되어 있으면 해킹당한겁니다.
	파일 이름과 확장자는 수시로 바뀌더군요.
	http://mywebsite.co.kr/data/file/freeboard/lele.php
	같이 웹접속 해서 불순한 짓을 쥐도새도 모르게 하게 됩니다.

	- 일단 http://www.krcert.or.kr/index.jsp 에 있는 whistl 같은 도구로
	웹루트 디렉토리의 전체 소스를 점검해서 해킹된 파일을 점검해 보는 것이
	좋습니다.  사용법은 위 사이트를 참조하시기 바랍니다.

	- 가장 강력한 해결책은 위 첨부파일이 저장되는 웹서버의 data 같은 디렉토리에서 
	php 같은 서버 사이드 스크립트가 실행이 안되게 해야 합니다.
	data 디렉토리 안에 .htaccess 파일을 아래와 비슷하게 시행안될 확장자를 지정해서
	생성합니다.
	
	# cat .htaccess 
	<FILES ~ "\.ph(p[2-6]?|tml)$|\.htm$|\.html$|\.inc$"> 
			Order allow,deny 
			Deny from all 
	</Files> 
	와 같이 넣어두면 위에 나열된 확장자 파일에 대한 접근이 거부되어 실행이 안됩니다.
	한가지 주의할 건
	아파치 웹서버 설정파일 httpd.conf 등에서 php 스크립트가 실행될 확장자에 맞게
	나열해야합니다.
	httpd.conf 파일에	

	AddType application/x-httpd-php .html .htm .php .php3 .php4 .php5 .phtml .cgi .inc
	이런 방식이나 혹은
	<FilesMatch "\.ph(p[2-6]?|tml)$|\.htm$|\.html$|\.inc$">
		SetHandler application/x-httpd-php
	</FilesMatch>
	와 같은 방식으로 php 실행 확장자를 넣는데, 이렇게 httpd.conf 에서 지정된 확장자를 
	모두 .htaccess 파일에서 지정을 해줘야 php 파일 실행을 막을 수 있습니다.
	이런 차이를 이용해서 좀 생소한 .phtml 이나 php2 등으로 확장자를 바꾸어서 저장하여
	공격하는 경우도 있습니다.
	자신의 웹서버 설정에 따라서 .htaccess 파일의 내용이 달라질겁니다.



4. POP 접속을 이용한 sendmail 공격

	1) 아이디 비번 해킹
	해커는 스팸을 보내기 위해 서버의 메일 계정 아이디 비번을 
	탈취하려고합니다.
	비밀번호를 1234 나 1111 혹은 아이디끝에 1234 등을 붙이는 등 단순하게 하면
	무차별 대입공격으로 쉽게 알아낼 수 있습니다.
	이런 공격은 ssh 나 ftp, telnet 등을 통해서도  자주 이루어 집니다.
	/var/log/message 나 ,/var/log/secure 파일등에서 가끔 무지막지한 기록을 볼 수 
	있을겁니다.
	여기서는 pop3 를 통해 시도한 공격흔적을  maillog 파일에서 찾아보겠습니다.

	- POP3 데몬으로 dovecot 을 사용할 경우

	# grep "Aborted login:" /var/log/maillog
	...
	9861 Nov 28 09:39:18 home7 dovecot: pop3-login: Aborted login: user=<chung>, method=PLAIN, rip=64.31.40.137, lip=222.122.server.ip
	9862 Nov 28 09:39:18 home7 dovecot: pop3-login: Aborted login: user=<hwan>, method=PLAIN, rip=64.31.40.137, lip=222.122.server.ip
	9863 Nov 28 09:39:18 home7 dovecot: pop3-login: Aborted login: user=<choi>, method=PLAIN, rip=64.31.40.137, lip=222.122.server.ip
	9864 Nov 28 09:39:19 home7 dovecot: pop3-login: Login: user=<chung>, method=PLAIN, rip=64.31.40.137, lip=222.122.server.ip
	9865 Nov 28 09:39:19 home7 dovecot: POP3(chung): Disconnected: Logged out top=0/0, retr=0/0, del=0/2, size=11095
	9866 Nov 28 09:39:20 home7 dovecot: pop3-login: Aborted login: user=<chen>, method=PLAIN, rip=64.31.40.137, lip=222.122.server.ip
	9867 Nov 28 09:39:20 home7 dovecot: pop3-login: Aborted login: user=<sung>, method=PLAIN, rip=64.31.40.137, lip=222.122.server.ip

	메일로그에서 "Aborted login:" 문구로 grep 했을때 동일한 rip= 값으로 수백
	수천 줄이 길게  나온다면 이건 비밀번호 해킹이 이루어 진겁니다.
	보통 자주 쓰는 아이디인 web, admin, root,webmaster 같은 계정이나 혹은
	한국에서 자주 쓰는 sung,yong,choi 같이 추측 가능한 아이디를 이용해서 
	비번이 1234 같이 간단한걸 무작위로 연속 대입해서 알아내는 겁니다.
	위 로그에서는 64.31.40.137 라는 듣보잡 ip 에서 공격한 예입니다.
	9864 라인에 chung 라는 계정이 결국 재수없게 뚫려서 정상 로그인 처리된 걸 확인할 
	수 있습니다.
	나중에 확인해 보니 이 사용자는 비밀번호로 chung1234 를 사용하고 있었다고 합니다.

	- POP3 데몬으로 qpopper 을 사용할 경우
	만약 pop3 로 qpopper 를 사용한다면 아래와 같이 "Password supplied" 라는 걸로
	grep 하면 비슷하게 확인 가능합니다.
	여기서는  222.179.203.46 에서 수천번의 비밀번호 넘겨짚으려는 시도가 있었습니다.

	# zgrep "Password supplied" ./maillog.1.gz  
	...
	Nov 21 14:21:33 home3 popper[20898]: web at 46.203.179.222.broad.cq.cq.dynamic.163data.com.cn (222.179.203.46): -ERR [AUTH] Password supplied for "web" is incorrect.
	Nov 21 14:21:33 home3 popper[20899]: user at 46.203.179.222.broad.cq.cq.dynamic.163data.com.cn (222.179.203.46): -ERR [AUTH] Password supplied for "user" is incorrect.
	Nov 21 14:21:35 home3 popper[20906]: admin at 46.203.179.222.broad.cq.cq.dynamic.163data.com.cn (222.179.203.46): -ERR [AUTH] Password supplied for "admin" is incorrect.
	Nov 21 14:21:37 home3 popper[20911]: webmaster at 46.203.179.222.broad.cq.cq.dynamic.163data.com.cn (222.179.203.46): -ERR [AUTH] Password supplied for "webmaster" is incorrect.


	2) pop3 클라이언트 사용시 로그 형태
	- 일반적으로 사용하는 아웃룩과 같은 메일 클라이언트로 접속해서 메일을 발송할 경우
	sendmail 로그에 어떻게 기록되는지 먼저 보겠습니다.

	## POP 아웃룩 연결
	..
	Dec  1 16:35:59 home5 sendmail[31579]: AUTH=server, relay=[112.187.xxx.xx], authid=nonots, mech=LOGIN, bits=0
	Dec  1 16:35:59 home5 sendmail[31579]: pB17ZvAS031579: from=<nonots@home5.myhome.co.kr>, size=1272, class=0, nrcpts=1, msgid=<777699E70A5C4270BEEF016962B9C39F@mycom>, proto=ESMTP, daemon=MTA, relay=[112.187.xxx.xx]
	Dec  1 16:35:59 home5 sendmail[31579]: pB17ZvAS031579: Milter add: header: X-Virus-Scanned: clamav-milter 0.97.2 at home5.myhome.co.kr
	Dec  1 16:35:59 home5 sendmail[31579]: pB17ZvAS031579: Milter add: header: X-Virus-Status: Clean 
	Dec  1 16:35:59 home5 sendmail[31583]: pB17ZvAS031579: to=<nonots@hanmail.net>, ctladdr=<nonots@home5.myhome.co.kr> (501/501), delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=121272, relay=mx9.hanmail.net. [211.43.198.80], dsn=2.0.0, stat=Sent (fB1GZwhE5580598200 Message accepted for delivery)

	내가 사용하는 PC 아이피인  112.187.xxx.xx 에서 nonots 아이디로 home5.myhome.co.kr 
	서버에 접속해서, 한메일 nonots@hanmail.net 주소로 메일 보낸 기록입니다.
	한메일서버 mx9.hanamil.net 으로 메일을 보내서 stat=Sent 가 나와서
	정상적으로 발송됐음을 알 수 있습니다.
	첫 라인에 authid=nonots 라는 접속 기록이 보이고, 접속한 sendmail 프로세스
	번호가 [31579] 번입니다. 
	이 프로세스에 의해 식별자  pB17ZvAS031579 가 부여되는데, 이 식별자의 마지막 부분에 
	31579 라는 프로세스 아이디값을 사용한다는 점을 유의해야 합니다.
	이 식별자에 의해서 /var/spool/mqueue 에 메일 헤더파일인 hfpB17ZvAS031579 와 
	데이타파일인 dfpB17ZvAS031579 가 일시적으로 생기고, 발송 완료한 후에는 mqueue
	에서 일정기간 후 자동으로 삭제가 됩니다.
	이제 이 특징을 이용해서 메일서버 해킹 여부를 점검해 보겠습니다.


	3) maillog 점검
	- 보통 sendmail 로그는 /var/log에 저장되고 1 주일마다 서버 logrotate cron 에 의해 
	백업이 됩니다.
	maillog.1, maillog.2,maillog.3 와 같이 백업되는데, 어떤 서버에서는
	압축백업을 해서, maillog.1.gz, maillog.2.gz.. 와 같이 gz 압축되어
	저장되기도 합니다.
	로그 분석을 위해서는 지난 백업파일까지 전체를 검색하기 위해 /var/log/maillog* 와
	같이 옵션을 주는 것이 좋습니다.
	아래 grep 이 아니라 zgrep 을 사용한 이유는 gz 로 압축된건 자동으로 풀어서 
	검색하기 위해 zgrep 을 사용했습니다. 
	만약 백업파일이 업축되지 않았다면 그냥 grep 을 사용해도 됩니다.

	# zgrep "authid=" /var/log/maillog* | awk '{print $8}' | sort | uniq -c | grep authid | sort -r
	   2972 authid=chung,
		 20 authid=kmlee,
		 13 authid=aychoi,
		  8 authid=keom,
		  7 authid=hyseong,
		  6 authid=tsshyang,
	...
	이 명령어는 아웃룩 같은 메일클라이언트에서 정상적으로 계정에 로그인한 정보를 
	메일로그에서  추출하여서 각 아이디 별로 통계를 낸 겁니다.
	auth=?? 와 같이 로그인 성공한 라인에서 공백문자를 기준으로 cut 을 해서 8 번째
	필드를 뽑아낸 후 같은 아이디를 합산한 후 정렬한겁니다.
	위에서, 해킹당한 chung 라는 계정이 2972번으로 가장 많이 접속했음을 알 수 있습니다.
	그리고 메일을 발송한 ip 별로 보려면

	# zgrep "authid=" /var/log/maillog* |  awk '{print $7}' | sort | grep relay |  uniq -c | sort -r
	   2972 relay=[194.51.238.89],
		 23 relay=[121.166.xxx.xxx],
		 19 relay=[112.158.73.131],
		 12 relay=[183.98.111.130],
		  8 relay=[116.121.255.202],
	...
	와 같이 194.51.238.89 아이피에서 제일 많이 접속한걸 알수 있습니다.
	이 아이피가 chung 계정을 이용한 것으로 추측할 수 있습니다.
	실제로 maillog 파일을 에디터로 열어서 authid=chung 나 194.51.238.89 등을
	검색해서 보면
	..
	41628 Nov 28 20:07:23 home7 sendmail[15541]: AUTH=server, relay=[194.51.238.89], authid=chung, mech=LOGIN, bits=0 41629 Nov 28 20:07:23 home7 sendmail[15539]: AUTH=server, relay=[194.51.238.89], authid=chung, mech=LOGIN, bits=0
	41630 Nov 28 20:07:23 home7 sendmail[15540]: AUTH=server, relay=[194.51.238.89], authid=chung, mech=LOGIN, bits=0  41631 Nov 28 20:07:23 home7 sendmail[15554]: AUTH=server, relay=[194.51.238.89], authid=chung, mech=LOGIN, bits=0
	41632 Nov 28 20:07:23 home7 sendmail[15555]: AUTH=server, relay=[194.51.238.89], authid=chung, mech=LOGIN, bits=0
	41633 Nov 28 20:08:13 home7 sendmail[15540]: pASB7Bop015540: from=<co@e-lupeni.ro>, size=596, class=0, nrcpts=50, msgid=<201111281107.pASB7Bop01554       0@home7.myhome.co.kr>, proto=ESMTP, daemon=MTA, relay=[194.51.238.89] 
	41634 Nov 28 20:08:13 home7 sendmail[15540]: pASB7Bop015540: Milter add: header: X-Virus-Scanned: clamav-milter 0.97.2 at home7.myhome.co.kr
	41635 Nov 28 20:08:13 home7 sendmail[15540]: pASB7Bop015540: Milter add: header: X-Virus-Status: Clean
	41636 Nov 28 20:08:14 home7 sendmail[15542]: pASB7Bi0015542: from=<co@e-lupeni.ro>, size=596, class=0, nrcpts=50, msgid=<201111281107.pASB7Bi001554       2@home7.myhome.co.kr>, proto=ESMTP, daemon=MTA, relay=[194.51.238.89] 
	..
	와 같이 되어 있습니다.
	11월 28일 20시 7분에 접속해서 co@e-lupeni.ro 를 발송자로 해서 스팸메일을 
	발송한걸 알 수 있습니다. 
	아마 이런 발송이 수백 수천건이 보일겁니다. 빌어먹을..


	3) 실시간 스팸 발송 대응
	- 만약 현재 시각으로 서버에서 스팸이 열나게 발송되고 있을 경우
	우선 아래와 같이 ps 명령어로 보면 아래와 같은 sendmail 프로세스가 보입니다.

	# ps aux
	...
	root      6839  0.0  0.1  69232  2996 ?        S    15:14   0:00 sendmail: ./pB26E7mm006835 from queue
	...
	이 경우 식별자 pB26E7mm006835 에서 끝부분 숫자 6835 번 프로세스에 의해서 
	발송됐음을 알 수 있습니다.
	위에서 말했듯이 /var/spool/mqueue 에 dfpB26E7mm006835, hfpB26E7mm006835 파일이 있을 겁니다.
	로그파일에서 이 번호로 발송기록을 찾아보면

	# grep "\[6835\]" /var/log/maillog
	..
	Dec  2 15:14:10 home7 sendmail[6835]: AUTH=server, relay=[121.166.xxx.xxx], authid=jychoi, mech=LOGIN, bits=0
	Dec  2 15:14:10 home7 sendmail[6835]: pB26E7mm006835: from=<jychoi@aaabbb.com>, size=90127, class=0, nrcpts=1, msgid=<000001ccb0b9$9b14ed20$d13ec760$@com>, proto=ESMTP, daemon=MTA, relay=[121.166.xxx.xxx]
	Dec  2 15:14:10 home7 sendmail[6835]: pB26E7mm006835: Milter add: header: X-Virus-Scanned: clamav-milter 0.97.2 at home7.myhome.co.kr
	Dec  2 15:14:10 home7 sendmail[6835]: pB26E7mm006835: Milter add: header: X-Virus-Status: Clean
	..
	와 같이 검색이 될겁니다
	grep 검색에서 [, ] 문자를 사용하려면 위와 같이 역슬래시로 처리해 줘야 합니다.
	만약 너무 길어서 보기 힘들다면 authid= 부분만 검색해서 어느 계정으로
	발송 중인지 알 수 있습니다.

	# grep "\[6835\]" /var/log/maillog | grep authid
	Dec  2 15:14:10 home7 sendmail[6835]: AUTH=server, relay=[121.166.xxx.xxx], authid=jychoi, mech=LOGIN, bits=0
	..
	와 같이 jychoi 라는 계정으로 121.166.xxx.xxx 에서 접속해서 메일을
	발송 중입니다.
	만약 이 발송이 정상이 아니라 스팸 의심이 된다면 위에서 검색한
	# zgrep "authid=" /var/log/maillog* | awk '{print $8}' | sort | uniq -c | grep authid | sort -r
	의 결과를 보거나 기타 방법으로 스팸 여부를 판단하면 됩니다.
	실제 jychoi 사용자에게 전화해서 지금 메일 발송중인지 물어볼 수있다면 제일 정확하겠죠.
	그리고 보통 스팸은 늦은밤이나 새벽 시간대에 보내므로 발송 시간을 보고
	어느정도 추정할 수도 있습니다.


	5) 스팸발송일 경우 대처 방법
	- 장난이 아니라면 모든 메일로그를 압축해서 보관하고 "기관"에 신고하면 됩니다.
	  귀찮아서 그냥 자체 해결하려면,

		(0) sendmail 데몬을 중지합니다.

		(1) 우선 스팸 발송한 ID 계정을 폐쇄하거나, 혹은 실제 사용자에게 연락해서
		비밀번호를 수정하도록 강제합니다.

		(2) 해킹 의심되는 IP 를 차단합니다. 아래와 같이 iptables 로 해도 되고
		# iptables -I INPUT -s 194.51.238.89 -j DROP
		# iptables -I OUTPUT -s 194.51.238.89 -j DROP
		/etc/mail/access 파일이나, /etc/hosts.deny 등을 이용하거나
		하여튼, 방화벽에서 막을 수 있는 모든 수단을 동원해 막습니다.

		(3) /var/spool/mqueue 를 청소합니다.
		아이디나 아이피를 차단해도 sendmail 데몬의 큐에 저장된 건 일정시간 계속
		발송하려고 시도하게 됩니다.
		194.51.238.89 이 아이피로 생성된 큐의 임시파일을 
		아래와 같이 일괄 삭제 가능합니다.
		# grep -l 194.51.238.89 /var/spool/mqueue/* | xargs -i rm -f {}

		(4) sendmail 데몬을 재시작합니다.
		아마 재시작해도 일정시간 동안  큐에 있는 파일 때문에 일부 스팸 발송
		시도가 있을수 있습니다. 그건 수동으로 큐파일 이름을 확인해서 
		삭제해 주면 됩니다.



5. 마무리

	진인사대천명했는 데도 계속 스팸메일이 발송된다면
	그냥 즐.기.시.길. -_-;;
Posted by 권성재
### 쓴것 : 리눅스 centos5에 오라클 10g 설치및 php 연동 
### 쓴때 : 2011-07-04 
### 쓴이 : 권성재 (nonots@hanmail.net

1. 시작하며 

2002년 월드컵 이후 오라클과 인연이 더이상 없을줄 알았는데 
10g 짜리를 또 만지는 사태가 벌어졌다. 
다행히 옛날 8i 시절과는 다르게 엑스윈도우나 자바 가상머신등에 
신경쓰지 않고도 쉽게 설치가 되는 rpm 버전으로 배포가 된다는 점. 
또 php 연동도 아파치와 php 전체를 새로 컴파일 할 필요없이 
보통 DSO 로 모듈을 사용하므로 간단하게 phpize 해서 
oci8 모듈 추가가 가능하다는 점. 
그리고 요즘 서버 하드웨어 사양이 좋아져서 리눅스 커널 값 수정에 
그리 신경안써도 된다는 점 등등..  여러 가지가 좋은 점도 있지만 
오라클이란 건 한번 만지기 시작하면 사람을 열받게 하는 재주가 있다. 
어제 오늘, 장마철 열받으며 삽질한 이 기록으로 
다른 사람의 삽질량이 줄어 들지는 내 관심사 아니다. 


2. 사용환경 및 사전 작업 
- 서버 사양 : CPU 64비트, 2기가 메모리 
- OS 사양 : 리눅스 centos 5.6 x86_64, 아파치웹서버2.2, php 5.2.17(RPM 설치) 
- 오라클 : 다국어 rpm 버전 10.2.0.1 


2. 오라클 설치 

1) 사전 작업 
배포하는 오라클은 32비트환경에서 컴파일된 거라서 64비트 리눅스 서버에서는 
그냥 설치가 안된다. 서버가 32 비트라도 오라클을 컴퍼일한 glibc 버전등이 
오래되서 역시 문제가 될 소지가 있으므로 라이브러리 호환을 위한 별도 
rpm 패키지를 설치해야 한다. 
보통 compat- 으로 시작하는 패키지들이 필요하다. 

[root@home3 ~]# rpm -qa |grep -i compat- 
compat-libstdc++-33-3.2.3-61 
compat-glibc-2.3.4-2.26 
compat-libcom_err-1.0-7 
compat-db-4.2.52-5.1 
compat-libstdc++-296-2.96-138 
compat-glibc-headers-2.3.4-2.26 
compat-libgcc-296-2.96-138 
compat-gcc-34-3.4.6-4.1 
compat-glibc-2.3.4-2.26 
compat-libcom_err-1.0-7 
compat-gcc-34-c++-3.4.6-4.1 
compat-db-4.2.52-5.1 
compat-libstdc++-33-3.2.3-61 
이런 것들도 필요하고 libaio libaio-devel 도 필요하고 
기타 php 연동 컴파일을 위한 gcc, gcc-c++, make, glibc-devel, php-devel,php-pear 같은 
패키지도 당연히 있어야 한다. 
그리고 오라클에서 기본쉘로 사용하는 ksh 나 pdksh 도 설치한다. 
리눅스 설치시  최소 설치만 했다면 오라클 rpm 설치를 위해 의존성 걸리는거 
해결하기 위해 여러가지 추가 로 설치해야 할꺼다. 


2) 다운로드 : 
  http://www.oracle.com/technetwork/database/express-edition/downloads/102xelinsoft-102048.html 
에서 다국어 버전 oracle-xe-univ-10.2.0.1-1.0.i386.rpm  를 다운받는다 
그냥 rpm 설치하면 된다. 

[root@home3 ~]# rpm -Uvh oracle-xe-univ-10.2.0.1-1.0.i386.rpm 
준비 중...                  ########################################### [100%] 
  1:oracle-xe-univ        ########################################### [100%] 
Executing Post-install steps... 
You must run '/etc/init.d/oracle-xe configure' as the root user to 
configure the database. 

이렇게 별 문제 없이 설치가 되면 oracle-xe configure 를 실행하라고 나온다. 
실행한다. 

[root@home3 ~]# /etc/init.d/oracle-xe configure 

Oracle Database 10g Express Edition Configuration 
------------------------------------------------- 
This will configure on-boot properties of Oracle Database 10g Express 
Edition.  The following questions will determine whether the database should 
be starting upon system boot, the ports it will use, and the passwords that 
will be used for database accounts.  Press <Enter> to accept the defaults. 
Ctrl-C will abort. 

Specify the HTTP port that will be used for Oracle Application Express [8080]: (엔터) 
Specify a port that will be used for the database listener [1521]: (엔터) 
Specify a password to be used for database accounts.  Note that the same 
password will be used for SYS and SYSTEM.  Oracle recommends the use of 
different passwords for each database account.  This can be done after 
initial configuration: (시스템 비밀번호 입력) 
Confirm the password:  (비번 재입력) 
Do you want Oracle Database 10g Express Edition to be started on boot (y/n) 
[y]: y 

Starting Oracle Net Listener...Done 
Configuring Database...Done 
Starting Oracle Database 10g Express Edition Instance...Done 
Installation Completed Successfully. 
To access the Database Home Page go to "http://127.0.0.1:8080/apex" 
[root@home3 ~]# 

오라클이 설치가 되면 기본 $ORACLE_HOME 위치는 
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server 가 된다. 
나중에 php 컴파일을 위한 $LD_LIBRARY_PATH 는 $ORACLE_HOME/lib 디렉토리가 된다. 
오라클을 사용하려면 이런 환경변수를 인식해야 한다. 
이 환경변수는 
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh 파일을 
읽어들여한다. 

[root@home3 ~]#cd /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin 
[root@home3 bin]# . ./oracle_env.sh 
와 같이 한번 해주고. 
루트가 로그인할 때 자동인식하려면 
[root@home3 bin]# cat ./oracle_env.sh  >> ~/.bashrc 
와 같이 파일에 추가해준다. 
.bashrc 뿐만 아니라 나중에 아파치 웹서버와도 연동해야하므로 
/etc/init.d/httpd 파일 상단 적당한 곳에 oracle_env.sh 파일의 내용을 
적어주는 것도 좋다. 

이제 아래 방식으로 오라클을 중시,시작하면 된다. 다시 중지 후 시작해본다. 
시작시 좀 오래 걸린다. 
[root@home3 ~]# /etc/init.d/oracle-xe stop 
Shutting down Oracle Database 10g Express Edition Instance. 
Stopping Oracle Net Listener. 
[root@home3 ~]# /etc/init.d/oracle-xe start 
Starting Oracle Net Listener. 
Starting Oracle Database 10g Express Edition Instance. 

이제 sqlplus 접속을 해본다. 

[root@home3 ~]# sqlplus sys/비번 as sysdba 
SQL*Plus: Release 10.2.0.1.0 - Production on 화 7월 5 12:18:34 2011 
Copyright (c) 1982, 2005, Oracle.  All rights reserved. 
다음에 접속됨: 
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production 
SQL> select * from tab; 
.. 
FLOW_SQLAREA     VIEW 
FLOW_SGA     VIEW 
3528 개의 행이 선택되었습니다. 
SQL> exit;  
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production에서 
분리되었습니다. 

위와같이 되면 일단 오라클 설치는 된거다. 
그런데 간혹 sqlplus 실행을하면 

ORA-27121: unable to determine size of shared memory segment 
SVR4 Error: 13: Permission denied 
이런 에러가 나고 sqlplus 접속이 안되는 경우가 있다 이때는 

chmod 6751 $ORACLE_HOME/bin/oracle 
와 같이 oracle 이라는 명령어 자체의 퍼미션을 변경해 준다. 

그리고 위에서 "http://127.0.0.1:8080/apex" 웹브라우저로 접속 
가능하다고 했는데 이건 로컬에서만 가능하다. 
원격에서 접속하려면, 
만약 방화벽 있다면 방화벽에서 8080 포트 열어주고 
sqlplus 에 접속해서 

SQL>EXEC DBMS_XDB.SETLISTENERLOCALACCESS(FALSE); 

와 같이 외부 접속을 가능하게 해줘야 한다. 
만약  8080 포트가 아니라 다른 포트 쓰려면 
SQL>EXEC DBMS_XDB.SETHTTPPORT(원하는포트번호); 
와 같이 해주고 
오라클을 재시작하면 이제 외부에서 웹브라우저로 접속가능하다. 
마치 phpmyadmin 같이 오라클을 관리가능하다. 참 편리한 기능이다. 

여기까지 됐다면 거의 다 된거다. 
만약 원인 모를 에러가 있다면 로그파일을 보고 해결한다. 
로그파일은 
$ORACLE_HOME/log 
$ORACLE_HOME/config/log 
$ORACLE_HOME/network/log 
특히 network/log 에 있는건 리스너 로그이다. 잘 본다. 

서버 프로세스를 보면 
[root@home3 ~]# ps aux |grep -i ora 
oracle  11151  0.0  0.1  66076  6128 ?        Ss  12:33  0:00 
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/tnslsnr LISTENER 
-inherit 
oracle  11159  0.0  0.3 870304 10244 ?        Ss  12:33  0:00 xe_pmon_XE 
oracle  11161  0.0  0.2 869732  8852 ?        Ss  12:33  0:00 xe_psp0_XE 
oracle  11163  0.0  0.7 869732 24224 ?        Ss  12:33  0:00 xe_mman_XE 
oracle  11165  0.0  0.3 871804 11472 ?        Ss  12:33  0:00 xe_dbw0_XE 
oracle  11167  0.0  0.9 885284 28240 ?        Ss  12:33  0:00 xe_lgwr_XE 
oracle  11169  0.0  0.4 869736 14108 ?        Ss  12:33  0:00 xe_ckpt_XE 
oracle  11171  0.0  1.4 870268 44372 ?        Ss  12:33  0:00 xe_smon_XE 
oracle  11173  0.0  0.4 869732 14108 ?        Ss  12:33  0:00 xe_reco_XE 
oracle  11175  0.0  0.6 871336 20504 ?        Ss  12:33  0:00 xe_cjq0_XE 
oracle  11177  0.1  1.3 872388 42844 ?        Ss  12:33  0:00 xe_mmon_XE 
oracle  11179  0.0  0.3 869732  9892 ?        Ss  12:33  0:00 xe_mmnl_XE 
oracle  11181  0.0  0.2 870240  9000 ?        Ss  12:33  0:00 xe_d000_XE 
oracle  11183  0.0  0.2 870300  8692 ?        Ss  12:33  0:00 xe_s000_XE 
oracle  11185  0.0  0.2 870300  8684 ?        Ss  12:33  0:00 xe_s001_XE 
oracle  11187  0.0  0.2 870300  8684 ?        Ss  12:33  0:00 xe_s002_XE 
oracle  11189  0.0  0.2 870300  8688 ?        Ss  12:33  0:00 xe_s003_XE 
oracle  11212  0.0  0.3 869732  9952 ?        Ss  12:33  0:00 xe_qmnc_XE 
oracle  11225  0.0  0.3 869728 11024 ?        Ss  12:33  0:00 xe_q000_XE 
oracle  11238  0.0  0.3 869728  9272 ?        Ss  12:34  0:00 xe_q001_XE 

와 같고 서버 포트는 
[root@home3 ~]# lsof -i 
.. 
tnslsnr  11151  oracle  12u  IPv4 573561      TCP *:ncube-lm (LISTEN) 
tnslsnr  11151  oracle  14u  IPv4 573787      TCP home3.aaa.co.kr:ncube-lm->home3.aaa.co.kr:12630 (ESTABLISHED) 
tnslsnr  11151  oracle  15u  IPv4 573995      TCP *:webcache (LISTEN) 
oracle    11159  oracle  16u  IPv4 573655      UDP localhost.localdomain:elad 
oracle    11159  oracle  17u  IPv4 573786      TCP home3.aaa.co.kr:12630->home3.aaa.co.kr:ncube-lm (ESTABLISHED) 
oracle    11181  oracle  15u  IPv4 573777      UDP localhost.localdomain:52881 
oracle    11181  oracle  187u  IPv4 573780      TCP *:64308 (LISTEN) 
oracle    11183  oracle  15u  IPv4 573795      UDP 

와 같이 열려있음을 알수 있다.  여기까지 대강 설치가 됐다. 
사용자 추가와 테스트 테이블 사용은 위의 apex 웹모드를 사용해도 되고 
sqlplus 로 직접 입력해도 된다. 간단한 nonots 사용자를 추가하고 
member 이라는 테이블을 만들어 본다. 

[root@home3 bin]# sqlplus sys/비번 as sysdba 
SQL*Plus: Release 10.2.0.1.0 - Production on 월 7월 4 20:45:27 2011 
Copyright (c) 1982, 2005, Oracle.  All rights reserved. 
다음에 접속됨: 
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production 
SQL> create user nonots identified by mypassword 
default tablespace users 
temporary tablespace temp; 
사용자가 생성되었습니다. 
SQL> grant connect,resource to nonots; 
권한이 부여되었습니다. 
SQL> commit; 
커밋이 완료되었습니다. 
SQL> quit 
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production에서 
분리되었습니다. 

[root@home3 bin]# sqlplus nonots/mypassword 
SQL*Plus: Release 10.2.0.1.0 - Production on 월 7월 4 20:46:13 2011 
Copyright (c) 1982, 2005, Oracle.  All rights reserved. 
다음에 접속됨: 
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production 
SQL> create table member ( id number ,username varchar2(30)); 
테이블이 생성되었습니다. 

SQL> insert into member (id,username) values(1,'일좀해라'); 
1 개의 행이 만들어졌습니다. 
SQL> insert into member ( id,username) values(2,'PHP슥훌만세'); 
1 개의 행이 만들어졌습니다. 
SQL> select * from member;  
ID USERNAME 
---------- ------------------------------------------------------------ 
1 일좀해라 
2 PHP슥훌만세 
SQL> 


3. PHP 연동 
차라리 오라클 설치는 쉽다. php 모듈만 컴파일해서 추가하는게 
의외로 사람 열받게 했다. 
방법은 http://pecl.php.net/package/oci8  여기서 
최신 소스를 가져와서 컴파일해서 oci8.so 파일을 만든후 
php.ini 등에서 extention 항목에 추가해 주고 웹서버 재시작하면 된다. 

그런데 가장 큰 문제가, 설치한 오라클의 라이브러리로는 최근 
php 모듈 컴파일이 안된다는 점이다. 이걸 해결하기 위해서는 
http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html 
에서 환경에 맞는 인스턴트 클라이언트라는 걸 다운받아야 한다. 
위 링크에서 리눅스 64 비트에서 오라클 버전 10 에서 최신인 
Version 10.2.0.5  에 있는 
basic-10.2.0.5.0-linux-x64.zip, sdk-10.2.0.5.0-linux-x64.zip 
2개 파일을 다운받는다. 둘다 압축을 풀면 동일하게 
instantclient_10_2 디렉토리가 생긴다. 날짜를 보면 오라클 lib에 있는 .so파일들 보다 
더 최근에 생성된 것을 알수 있다. 
이 디렉토리를 적당한 곳으로 옮긴다.  예를 들면, 이 instantclient_10_2 를 
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib_tmp 
라고 변경한다. 
즉 오라클 자체는 
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib/libclntsh.so 등을 사용하고 
php 모듈 컴파일을 위해서는 다운받은 instantclient의 
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib_tmp/libclntsh.so 
같은 so 파일을 사용한다는 뜻이다. 
아래에서 php  oci8 컴파일을 할때 --with-oci8 옵션을 이 위치로 지정해 준다. 

1)방법 :  pecl install oci8 
보통 이 방법이 가장 간단한데 내 경우 안됐다. 

[root@home3 tmp]# pecl install oci8 
downloading oci8-1.4.5.tgz ... 
Starting to download oci8-1.4.5.tgz (154,284 bytes) 
.........................done: 154,284 bytes 
10 source files, building 
running: phpize 
Configuring for: 
PHP Api Version:        20041225 
Zend Module Api No:      20060613 
Zend Extension Api No:  220060519 
/usr/bin/phpize: /tmp/tmpLFrGmq/oci8-1.4.5/build/shtool: /bin/sh: bad 
interpreter: 허가 거부됨 
Cannot find autoconf. Please check your autoconf installation and the 
$PHP_AUTOCONF environment variable. Then, rerun this script. 
ERROR: `phpize' failed 

와 같이 에러가 나면서 실패했는데. 
원인은 서버 보안을 위해서 /tmp 를 별로 파티션으로 잡고 마운트했는데 
보안때문에 마운트할 때 noexec 니 nosuid 같은 옵션을 줘서 
/tmp 에서 컴파일 등이 제한된다. pecl 이 이 다운받은 파일을 /tmp 
아래에서 압축풀어 컴파일하려고 하기 때문에 실패한것으로 추정된다. 
이런 제한없는 다른 서버에서는 간단하게 모듈 컴파일 될것이다. 
아님말고. 


2)방법 :  직접 컴파일 
위 경로에서 최신버전 oci-81.4.5.tgz 을 가져와 
압축을 풀고  phpize 를 실행한다. 
[root@home3 oci8-1.4.5]# phpize 
[root@home3 oci8-1.4.5]# ./configure --with-oci8=instantclient,/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib_tmp 
[root@home3 oci8-1.4.5]# make 혹은 make install 

정상적으로 컴파일 된다면 ./modules/oci8.so 라는 파일이 만들어 진다. 
이 파일을 php 모듈디렉토리에 
복사하고 php.ini 에서 extension항목에 넣어준다. 
make install 하면 저절로 oci8.so 를 복사할 것이다. 

이제 웹서버를 재시작한다. 에러 로그파일을 보고 특별한 이상이 없으면 
된거다.  확인하려면 phpinfo() 화면을 보거나 

[root@home3 ~]# php -i |grep oci8 
/etc/php.d/oci8.ini, 
oci8 
oci8.connection_class => no value => no value 
oci8.default_prefetch => 100 => 100 
oci8.events => Off => Off 
oci8.max_persistent => -1 => -1 
oci8.old_oci_close_semantics => Off => Off 
oci8.persistent_timeout => -1 => -1 
oci8.ping_interval => 60 => 60 
oci8.privileged_connect => Off => Off 
oci8.statement_cache_size => 20 => 20 

와 같이 나오면 된거다.  이제 oci php 함수로 사용하면 된다. 
위에서 nonots 사용자가 만든 MEMBER 테이블을 불러와 보면 

[root@home3 tmp]# cat ora.php 
<?php 
// 아래 127.0.0.1/XE 이부분은 리스너 참조, 다를수 있음 
$conn = oci_connect('nonots', 'mypassword', '127.0.0.1/XE'); 
if (!$conn) { 
$e = oci_error(); 
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR); 

$stid = oci_parse($conn, 'SELECT * FROM MEMBER WHERE ROWNUM < 3'); 
oci_execute($stid); 
$nrows = oci_fetch_all($stid, $res); 
echo "$nrows rows fetched<br>\n"; 
echo '<pre>'; 
var_dump($res); 
?> 

실행 결과는 
2 rows fetched 
array(2) { 
  ["ID"]=> 
  array(2) { 
[0]=> 
string(1) "1" 
[1]=> 
string(1) "2" 
  } 
  ["USERNAME"]=> 
  array(2) { 
[0]=> 
string(8) "일좀해라" 
[1]=> 
string(8) "PHP슥훌만세" 
  } 

와 같이 되면 성공한거다. 


4. 마무리 
덜 마른 빨래에서 쿰쿰한 역겨운 냄새가 난다. 
다시 하나 마나.
Posted by 권성재

맨날 스팸메일이나 딱딱한 업무용 메일만 보다가
오랜만에 진지한 네 편지 잘 읽었다.
..
함박눈이 엄청 날리다가 지금은 그쳤다만
금방 또 하얗게 쏟아질거 같이 흐린 초겨울 오후다.
한해도 가라앉으며 저물어가고.. 
세간도 뒤숭숭하니 답답하고..
거기다가.. 니 말대로 낼모레 "40대". 
빼도박도 못하는 아저씨 세대. 마흔.
..
위에 욕심껏 쌓아올린 건 많아지는데
아래 기초는 시간이 갈수록 부실해지니
점점 위태로움만 늘어나는구나.
..
그래도 걱정마라.. 창조주가 장난친 결과는
창조주 지가 알아서 책임지기 마련이니
힘듦에도 이유가 있고 가치가 있지 않을까..
아니..
이유나 가치 같은건 없다손 치더라도 
보험에도 안들고 함부로 피조물 제조행위를 하지는 않았을테니
사소한 감정에 건.방.지.게 책임 범위를 넘어선 자책일랑 하지말고
자.중.자.애 하시게나..



'횡설수설' 카테고리의 다른 글

오랜 친구 보시게..  (0) 2010/12/08
핵폭탄과 외계인  (0) 2010/03/05
타임머신  (1) 2010/03/02
트위터 해봤다.  (0) 2009/12/07
2012 스포일러..  (0) 2009/11/13
늙었나 보다..  (0) 2009/11/08
Posted by 권성재
##########################################################################
### 제목  : 리눅스서버의 PHP 에서  MySQL 연결시 ODBC 함수 사용하기
### 쓴때 : 2010-09-06 벌초하다가 죽을 뻔한 다음날
### 쓴이 : 카폐인 (nonots@hanmail.net)


1. 개요
 여태껏 리눅스 서버에서 PHP 로 웹프로그래밍 하면서  MySQL DBMS 에 
ODBC 로 연결해 본 적도 없고, 그렇게 할 필요도 전혀 못느꼈는데, 
어쩌다 보니 ..  그렇게 해야만 "돈준다"는 "갑"의 요청에, 
또 비장한 심정으로 삽질을 해보니 되긴 된다.
암튼 덕분에 새로운 경험이었다.


2. 서버 환경 
	- 리눅스 CentOS 4.8, 
		아파치웹서버 : 2.0, 
		PHP 5.13, 
		MySQL : 5.0


3. 설정방법

	1) php 에서 odbc 모듈이 활성화 되어야 한다. 
	만약 php 소스컴파일 당시 odbc 옵션이 없었다면 새로 컴파일 해야 할꺼다. 
	좀 짜증나는 일이다.
	만약 rpm 이나 deb 로 설치를 했다면 그냥 yum 혹은 apt-get 등으로 
	php-odbc 패키지만 설치하면 된다. 내경우 다행히  APM 이 rpm 으로 설치가 되어서 
	php-odbc 를 yum 으로 간단하게 설치했다.
	웹서버 재시작 후 phpinfo() 로 봤을 때 ODBC 항목이 제대로 나타나면 일단은 된거다.
	구체적 방법은 각자가.

	2) unixODBC 패키지를 설치한다.
	보통 서버 설치시 기본으로 설치가 되어 있을꺼다.
	안되어 있다면 역시 rpm 등으로 설치한다. 
	/etc/odbc.ini 나 /etc/odbcinst.ini 이런 파일이 존재한다면 이미 unixODBC 가
	설치되어 있다는 증거다.

	3) mysql odbc 커넥터를 설치한다.
	centos 리눅스의 경우 기본 배포디렉토리에는 없고,  
	http://ftp.neowiz.com/pub/centos/4.8/centosplus/x86_64/RPMS/ 와 같이
	cenosplus 라는 추가 배포 디렉토리에 mysql-connector-odbc-3.51 이름의 rpm이 있다.
	이걸 설치하면 된다.

		[root@home6 ~]# rpm -ql mysql-connector-odbc
		/usr/lib64/libmyodbc3-3.51.26.so
		/usr/lib64/libmyodbc3.so (요 파일경로가 아래에 사용)
		/usr/lib64/libmyodbc3_r-3.51.26.so
		/usr/lib64/libmyodbc3_r.so
		...

	아니면
	http://mysql.com/downloads/connector/odbc/ 와 같이 mysql 홈페이지에서 제공하는
	커넥터를 직접 다운 받아 설치하면 된다. 
	설치된 *.so 파일의 위치를 잘 기억해야한다.


	4) /etc/odbc.ini, /etc/odbcinst.ini 파일을 적절하게 수정한다.

		>>>>>>>
		[root@home6 ~]# cat /etc/odbc.ini 
		[ODBC Data Sources]
		myodbc3      = MySQL ODBC 3.51 Driver

		[myodbc3]
		Driver         = /usr/lib64/libmyodbc3.so
		Description  = MySQL ODBC 3.51 Driver
		Server        = localhost
		Port           = 3306
		User           = mydb_user  ( <= db 연결 아이디 적절하게 수정)
		Password    = mydb_password ( <= 적절하게 수정)
		Database    = mydb_name ( <= 적절하게 수정)
		Option        = 3   
		Socket       = /var/lib/mysql/mysql.sock ( <= 소켓파일위치 적절하게 수정)


		>>>>>>>
		[root@home6 ~]# cat /etc/odbcinst.ini 
		# Example driver definitinions
		#
		# Driver from the MyODBC package
		# Setup from the unixODBC package
		[MySQL ODBC 3.51 Driver]
		Description     = MySQL ODBC 3.51 Driver
		Driver          = /usr/lib64/libmyodbc3.so  
                                            ( 요건 mysql-connector-odbc  에서의 위치 )
		Setup           = /usr/lib64/libodbcmyS.so  
                                            ( 요건 unixODBC 에 포함된 위치, 아마 기본값)
		FileUsage       = 1
			 

		위 2 개 파일에서 db이름,아이디,비번과 mysql소켓파일을 적절하게 입력하고 
		특히, odbcinst.ini 파일에서 Driver 항목의 커넥터 so 파일의 위치를 적는다.
		이제 unixODBC 패키지 자체 포함된 isql 이라는 명령어로 odbc세팅이 잘된건지 
		아래와 같이 확인해 보자. 
		/etc/odbc.ini 에 설정한 db 와 db 아이디로 접속된다.

		[root@home6 ~]# isql -v myodbc3
		+---------------------------------------+
		| Connected!                            |
		|                                       |
		| sql-statement                         |
		| help [tablename]                      |
		| quit                                  |
		|                                       |
		+---------------------------------------+
		SQL> 
		 	

		그리고 마지막으로 위 설정파일에서 Description = MySQL ODBC 3.51 Driver 를
		잘 기억해 둔다.


4. PHP 소스에서 사용하기.
	이건 간단하다.
	아래 예제보면 금방 이해가 갈꺼다.

		<? 
		//phpinfo(); exit; 
		error_reporting(E_ALL);  // 디버깅 위한
		ini_set("display_errors",1);  // 디버깅 위한 2

		// 여기 DRIVER  부분이 /etc/odbc.ini 의 Description 부분이다. 주의한다.
		$conn = odbc_connect(
                  "DRIVER={MySQL ODBC 3.51 Driver};Server=localhost;Database=my_db_name", 
		  "my_db_user", "my_db_password"); 

		$sql = "SELECT * from users"; 
		$rs = odbc_exec($conn,$sql); 
		echo "<table><tr>"; 
		echo "<th>이름</th><th>이메일</th></tr>"; 
		while (odbc_fetch_row($rs)) 
		 { 
		 $user = odbc_result($rs,"username"); 
		 $email = odbc_result($rs,"email"); 
		 echo "<tr><td>$user</td><td>$email</td></tr>"; 
		} 
		odbc_close($conn); 
		echo "</table>"; 

		?>

	제대로 데이타를 불러오는가? 그럼 된거다. 
	이제 "을"의 설움을, 
        새로운 기술을 습득한 기쁨의 눈물로 승화시켰다고 자위하면 된다.

5. 마무리

	그런거 없다.

Posted by 권성재

자연주의자의 충고

어떤 일이 일어나도
당신이 할 수 있는 최선을 다하라.

마음의 평정을 잃지 말라.
당신이 좋아하는 일을 찾으라.

집, 식사, 옷차림을 간소하게 하고 번잡스러움을 피하라.
날마다 자연과 만나고 발밑에 땅을 느껴라.

농장일이나 산책, 힘든 일을 하면서 몸을 움직여라.
근심 걱정을 떨치고 그날 그날을 살라.

날마다 다른 사람과 무엇인가 나누라.
혼자인 경우는 누군가에게 편지를 쓰고,

무엇인가 주고,
어떤 식으로든 누군가를 도우라.

삶과 세계에 대해 생각해 보는 시간을 가지라.
할 수 있는 한 생활에서 웃음을 찾으라.

모든 것 속에 들어 있는 하나의 생명을 관찰하라.
그리고 세상의 모든 것에 애정을 가지라.

헬렌 니어링, 스코드 니어링
(조화로운 삶을 실천한 유명한 자연주의자 부부)


======================================================================
흙을 밟고 싶다.
사람의 발바닥은 퇴화된 뿌리의 흔적일지도.
스스로 잘라버린 땅속 뿌리의 기억을 떠올려본다.
매정하게 등지고 떠났던 대지의 촉촉한 속살이 그리워진다.
Posted by 권성재