서버의 보안점검을 실시한 결과 php 패키지를 업데이트하라고 권고해서
업데이트하기로 결정.

To upgrade to PHP 5.2.x on CentOS/RHEL/Fedora:
http://www.atomicorp.com/wiki/index.php/PHP

yum update를 해보니..업데이트할패키지가 거의 1G정도..

업데이트가 끝나면 php.ini 와 php.conf 파일을 복구해주자.

mv /etc/php.ini.rpmnew /etc/php.ini
mv /etc/httpd/conf.d/php.conf.rpmnew /etc/httpd/conf.d/php.conf

이전에 사용하던 설정들이 있다면 *.rpmsave 에서 다시 확인해서 수정해준다.

웹서비스 재시작
service httpd restart



업데이트 전
[root@ns ~]# cat /etc/redhat-release
CentOS release 5.2 (Final)

업데이트 후
[root@ns ~]# cat /etc/redhat-release
CentOS release 5.5 (Final)
[root@ns ~]# php --version
PHP 5.2.5 (cli) (built: Sep 22 2008 14:55:04)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    with Zend Extension Manager v1.2.2, Copyright (c) 2003-2007, by Zend Technologies
    with Zend Optimizer v3.3.0, Copyright (c) 1998-2007, by Zend Technologies
[root@ns ~]#


Inline Translator가 로드되지 못했습니다. 다시 시도시려면 새로고침해주세요.
Inline Translator가 로드되지 못했습니다. 다시 시도하시려면 새로고침해주세요.

'오픈소스SW' 카테고리의 다른 글

보안서버 구축에 사용되는 무료인증서 StartSSL  (0) 2010.06.13
iptable rule  (0) 2010.06.10
Apache 웹방화벽 ModSecurity 사용하기  (1) 2010.06.08
jquery datepicker 사용  (0) 2010.06.05
php 문자열처리 관련 function  (0) 2010.06.05
SW개발자에게 웹어플리케이션의 보안부분은 항상 머리가 아픈 부분입니다.
웹어플리케이션의 보안이슈를 웹서버에서 차단가능한 방법이 있으면, SW개발자는 개발에 집중할 수 있겠죠.

오늘 취약점 점검툴을 이용해서 배포하려는 사이트를 분석해보니, 해결해야 하는 취약점의 숫자가 좀 많습니다. ㅡ.ㅡ
서버측에서 접근하는 패킷에 대한 룰셋을 적용하는 방법과,  개발한 소스코드를 보정하는 방법 중, 해당 서버의 전체 어플리케이션에 대해서 웹방화벽을 설치하기로 결정하고 ModSecurity 를 적용하기로 했습니다..

ModSecurity의 설치법에 대해서는 KISA 홈페이지 를 방문해보시면. 한글로 된 가이드가 있습니다.
소스코드 설치를 원하시면 위 링크에서 컴파일에 대한 과정을 설명한 내용을 참고하시기 바랍니다.

저는 최근에는 부득이한 경우를 제외하고는 소스컴파일을 하지 않고, 설치한 패키지에 대한 운영상의 편리함을 생각해서 가능하면 apt, yum, rpm 등의 설치방식을 사용합니다. ModSecurity를 설치할 수 있는 repository를 구글링해서 Yum repository를 찾아냈습니다. (원문 url : http://portugalcode.com/index.php?topic=2850.0;wap2)

How to install mod_security by yum(Redhat-Centos 5)

(1/1)

@Scroll:
1.Download the EPEL repo :

Código
GeSHi (bash):
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
Created by GeSHI 1.0.7.20

2.Then type the following command :

Código
GeSHi (bash):
yum install mod_security
Created by GeSHI 1.0.7.20

Note : Mod_security require liblua-5.1.so, If you don’t have this , it will throw an error while installing by yum.


Código
GeSHi (bash):
--> Processing Dependency: liblua-5.1.so for package: mod_security
--> Finished Dependency Resolution
mod_security-2.5.9-1.el5.i386 from epel has depsolving problems
--> Missing Dependency: liblua-5.1.so is needed by package mod_security-2.5.9- 1.el5.i386 (epel)
Error: Missing Dependency: liblua-5.1.so is needed by package mod_security-2.5.9 -1.el5.i386 (epel)
Created by GeSHI 1.0.7.20

Solution: You can download the rpm from this website

http://rpm.pbone.net/index.php3/stat/4/idpl/12580541/com/lua-5.1.4-1.i386.rpm.html

If your server complain you have installed already newer version then you can reinstall the installed version by using

Código
GeSHi (bash):
-bash-3.2# rpm -qa | grep lua
lua-5.1.4-1.el5.rf
-bash-3.2# rpm -e lua-5.1.4-1.el5.rf
-bash-3.2# rpm -Uvh lua-5.1.4-1.i386.rpm
Preparing… ########################################### [100%]
1:lua ########################################### [100%]
 
Created by GeSHI 1.0.7.20

Now type

Código
GeSHi (bash):
-bash-3.2# updatedb
 
-bash-3.2# locate liblua-5.1.so
/usr/lib/liblua-5.1.so
 
Created by GeSHI 1.0.7.20

So it shows that your server has the required file for it to install mod_security

Now run

Código
GeSHi (bash):
yum install mod_security
Created by GeSHI 1.0.7.20

It should installed now mod_security configuration files

/etc/httpd/conf.d/mod_security.conf – main configuration file for the mod_security Apache module.
/etc/httpd/modsecurity.d/ – all other configuration files for the mod_security Apache.
/etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf – Configuration contained in this file should be customized for your specific requirements before deployment.
/var/log/httpd/modsec_debug.log – Use debug messages for debugging mod_security rules and other problems.
/var/log/httpd/modsec_audit.log – All requests that trigger a ModSecurity events (as detected) or a serer error are logged (”RelevantOnly”) are logged into this file.
After installing mod_security , Edit modsecurity_crs_10_config.conf file and make sure bellow line is enabled.

SecRuleEngine On

Now restart the httpd server by

Código
GeSHi (bash):
service httpd restart
Created by GeSHI 1.0.7.20

Check the /var/log/httpd/error_log for this lines
[Fri Aug 28 10:48:24 2009] [notice] ModSecurity for Apache/2.5.9 (http://www.mod security.org/) configured.

영문사이트는 아니지만 중요한 정보는 다 들어있으니 그대로 설치하기로 했습니다.

1) mod_security 설치
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
위 명령으로 epel repository가 잘 설치되었다면

yum install mod_security
를 실행합니다.

두어번 의존패키지 설치를 묻는데 y를 눌러주면 설치는  끝납니다.(너무쉽죠?)


2) 방화벽에서 사용할 룰셋의 생성
설치를 마쳣으면 아파치 환경설정 디렉토리안의 mod_security.conf 파일을 확인합니다..



방화벽에서 적용할 룰셋은 자신이 직접 만들어서 사용가능하지만, 일단은 KISA에서 배포하는 룰셋을 다운로드 받아서 사용하자.
룰셋 다운로드 : http://toolbox.krcert.or.kr/ > ModSecurity 자료실 > 차단샘플 룰 을 찾아서 다운로드.

다운받은 룰셋을 yum 설치시 생성된 디렉토리에 복사하자.
아래의 modsecurity_kisa.conf 파일이 다운로드 받은 룰셋이다.
룰셋의 설정에 대한 자세한설명은 KISA홈페이지를 이용하거나 파일내의 주석을 참고하자.







룰셋파일의 내용중(modsecurity_kisa.conf)
# 웹서버의 헤더 정보 변경
# Apache 설정의 ServerTokens값이 Full로 설정되 있어야 함.
SecServerSignature "Microsoft-IIS/5.0"

# 아규먼트 구분자
SecArgumentSeparator "&"

# 다음의 메소드 이외에는 허용하지 않음.
SecRule REQUEST_METHOD "(PUT|DELETE|TRACE)" "deny, log"

SecRequestBodyAccess Off
SecResponseBodyAccess Off
SecResponseBodyMimeType (null) text/html text/plain
SecResponseBodyLimit 524288

#############################
# 3. PHP 인젝션 취약 공격 방지(공개 게시판 솔루션 대상 공격 포함)
SecRule REQUEST_URI "\.php" "chain, msg:'PHP Injection Attacks'"
# dir|page 가 들어가 있으면서 https가 요청되는 경우가 fckeditor 에서 발생하기 때문에 수정
SecRule REQUEST_URI "(dir|page|)" chain
#SecRule REQUEST_URI "=(http|https|ftp)\:/"
SecRule REQUEST_URI "=(https|ftp)\:/"
SecRule REQUEST_URI "shell_exec\(" "msg:'PHP Injection Attacks'"


참고) 저의 경우 RPM 패키지에서 제공되는 설정을 그대로 사용해서 kisa에서 배포하는 설정을 복사한 후 , 바로 룰셋을 적용하니 웹사이트가 열리지 않았습니다. 로그를 보면서 확인해본 결과
/etc/httpd/modsecurity.d/base_rules/modsecurity_crs_50_outbound.conf 파일의 설정이 문제를 일으켰고.
이 파일을 제거하고 서비스에 적용했을때 이상없는 서비스가 가능했습니다.


3) 설치 후 적용 확인

설치 및 룰셋의 설정이 완료되었으면 제대로 동작하는지 확인합니다.

modsecurity 로그파일에 아래와 같은 로그가 남는경우
ModSecurity: Failed to access DBM file "E:/tmp/resource": The system cannot find the path specified

로그를 확인하니 오류메세지가 보여서 구글링한 결과
기본설치시 제공되는 modsecurity_crs_10.config.conf 의 설정에 아래의 내용을 추가해야 한다는것을 알았습니다.
웹서버가 접근가능한 경로를 하나 생성해서 아래와 같은 내용을 추가해주어야 한다.
vi /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf

SecUploadDir /var/www/tmp
SecDataDir /var/www/tmp
SecTmpDir /var/www/tmp

웹서버를 재시작하면 이제 방화벽이 작동하게 됩니다.

룰셋이 작동하는 상태를 확인하려면 환경설정파일에서 지정한 로그파일을 확인하면 됩니다.
다운받은 룰셋을 아무수정없이 사용하는경우라면 로그파일은 아파치설치디렉토리/logs/modsec_audit.log 에 남게 되고,
파일의 내용을 확인하면 아래처럼 룰셋이 작동되고 있는 상태가 보여집니다.
















지금까지는 룰셋이 작동되기는 하지만, 차단시키지 않고 있는 상태입니다.
정상적인 작동여부를 확인하고, 자신이 원하는 형태로 룰셋이 적용되는것을 확인한 후, 반드시 환경설정파일에서 pass 부분을 deny 로 변경해야 차단이 시작됩니다.

방화벽을 적용했더니 작동안되는 부분이 있다면 항의가 많겠죠? 실 서버에 적용시에는 당연히 방화벽으로 인한 서비스의 중단이 없도록 정상적인 서비스를 방해하는 룰셋이 있다면 반드시 확인하고 사용해야 합니다.

변경 전
SecDefaultAction "pass,log,auditlog,phase:2,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"

변경 후
SecDefaultAction "deny,log,phase:2,status:406,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"

여기까지 하면 방화벽의 설치는 끝났습니다.

4) 기타
로그파일의 비대해지는 것을 방지하기 위해서 로그를 날짜별로 나누어서 보관하는것이 좋겠죠.
KISA에서 제공하는 FAQ를 보니 잘 설명되어있어서 그대로 적용했습니다. 아래 링크에서 상세내용을 확인할 수 있습니다
http://toolbox.krcert.or.kr > ModSecurity FAQ > 로그파일의 사이즈가 너무 큰데 이를 날짜나 시간별로 분할할 수 없나요?






KISA에서 제공하는 룰셋의 주요 점검 항목

PHP 인젝션 취약 공격 방지(공개 게시판 솔루션 대상 공격 포함)
명령어 실행 방지
XSS 공격 방지
SSI 인젝션 관련 공격 차단
악성 프로그램 봇, User-Agent
검색엔진 Recon/Google 이용한 해킹 방지
PHPMyAdmin 관련 공격 취약점 적용
SQL Injection 공격 차단
WebShell 공격 방지
Tomcat 취약점 이용한 공격 방지


기타) 적용 후 추가한 내용
# dir|page 가 들어가 있으면서 https가 요청되는 경우가 fckeditor 에서 발생하기 때문에 수정
SecRule REQUEST_URI "(dir|page|)" chain
#SecRule REQUEST_URI "=(http|https|ftp)\:/"
SecRule REQUEST_URI "=(https|ftp)\:/"
SecRule REQUEST_URI "shell_exec\(" "msg:'PHP Injection Attacks'"

공개SW 웹방화벽 mod_security를 이용해서  여러분의 어플리케이션을 보호해보시는 것이 어떨까요?

'오픈소스SW' 카테고리의 다른 글

iptable rule  (0) 2010.06.10
CentOS 5.2.x PHP UPDATE  (0) 2010.06.09
jquery datepicker 사용  (0) 2010.06.05
php 문자열처리 관련 function  (0) 2010.06.05
JavaScript Tree Menu  (0) 2010.05.24


웹페이지에서 날짜와 관련한 입력을 받아야 할때
오픈소스로 각광받는 jquery의 플러그인 datepicker를 자주 사용하는 편이다.
우리에게 맞는 형태로 localization 하기 위해서 몇가지 설정을 조정하면 쉽게 사용가능하므로
사용해보지 않은분이 있다면 오픈소스 jquery ui를 사용해보자.

아직 jquery ui framework에 대해서 잘 모른다면 jquery ui 에 대한 다른 글을 참고해보는것도 좋다.


1) 우선 jquery-ui framework을 다운로드 받아야 사용가능하다.[다운로드]
datepicker만 사용하려면 구성요소중 해당 모듈만 선택한 후 다운로드하자.

2) 다운받은 css를 수정하여 폰트관련 설정을 변경하자(폰트종류, 폰트크기 등)

3) 한국어가 나오도록 조정한다.
- jquery 1.3.2 라면 별도의 한글부분이 담겨있는 i18n 이라는 디렉토리안에 ui.datepicker-ko.js라는 파일을 준비해야 한다.
- jquery 1.4.2 에는 기본으로 포함되어 있으므로 locale 설정만 변경하면 한글로 표시된다.

4) 년도표시가 왼쪽으로 나오도록 변경하자(기본은 년도가 오른쪽에 나오는 외국의 달력방식이다)
showMonthAfterYear:true 라는 옵션을 사용하면 된다.

5) 년도와 월이 셀렉트박스로 변경할수있도록 하는것이 사용자에게 좋으니 변경하자.
changeMonth: true
changeYear: true

6) 달력모양의 작은 아이콘이미지를 이용하여 표시하자.
showOn: 'button'
buttonImage: '/image/calendar.gif'
buttonImageOnly: true

7) 날씨의 표현형식을 yyyy-mm-dd 형태로 표시하도록 변경하자.
dateFormat: 'yy-mm-dd'

8) 모두 적용하고 나면 아래와 같은 형태가 된다.



jquery ui 중 datepicker는 여러가지 형태의 UI를 제공해주고 확장플러그인을 이용하면 다양한 방식의 사용이 가능하다.
jquery daterangepicker
http://www.filamentgroup.com/lab/date_range_picker_using_jquery_ui_16_and_jquery_ui_css_framework/

'오픈소스SW' 카테고리의 다른 글

CentOS 5.2.x PHP UPDATE  (0) 2010.06.09
Apache 웹방화벽 ModSecurity 사용하기  (1) 2010.06.08
php 문자열처리 관련 function  (0) 2010.06.05
JavaScript Tree Menu  (0) 2010.05.24
jqGrid 3.6.5 PHP CRUD  (2) 2010.05.23
yyyy년mm월dd일 포멧의 날짜를 yyyymmdd 형식으로 바꾸는 다양한 방법들.

$date = '2010년04월20일'; // 형태는 4년2월2일

이 값에서 숫자 부분인 '20100420'만 뽑는 방법입니다.



먼저 문자열(배열 관련 함수를 많이 사용하지만) 처리 방법입니다.


▶ 문자열 처리 #1

고정 길이기 때문에 substr() 함수를 이용합니다.

────────────────────────────────────────
$date = substr($date,0,4).substr($date,6,2).substr($date,10,2);
────────────────────────────────────────

substr() : http://php.net/manual/kr/function.substr.php

참고로 .은 문자열 결합 연산자입니다.
String Operators : http://php.net/manual/kr/language.operators.string.php



▶ 문자열 처리 #2

str_replace() 함수를 이용해 년, 월, 일 문자를 제거합니다.

────────────────────────────────────────
$date = str_replace('년','',$date); // 201004월20일
$date = str_replace('월','',$date); // 20100420일
$date = str_replace('일','',$date); // 20100420
────────────────────────────────────────

str_replace() : http://php.net/manual/kr/function.str-replace.php

참고로 해석이 필요없는 문자열 값은 '(Single Quote)로 감싸주세요.
문자열 관련 : http://php.net/manual/en/language.types.string.php


▶ 문자열 처리 #3

strtr() 함수를 이용하면 #2 과정을 한 번에 처리할 수 있습니다.

────────────────────────────────────────
$remove['년'] = '';
$remove['월'] = '';
$remove['일'] = '';

// 또는

$remove = array('년'=>'','월'=>'','일'=>'');

// 둘 중 편한 형태로 미리 연관 배열을 할당합니다.

$date = strtr($date,$remove);

// 물론 변수에 담지 않고 바로 이용도 가능합니다.

$date = strtr($date,array('년'=>'','월'=>'','일'=>''));
────────────────────────────────────────

strtr() : http://php.net/manual/en/function.strtr.php
연관 배열 : http://php.net/manual/kr/language.types.array.php


▶ 문자열 처리 #4

explode() 함수를 이용해 년, 월, 일을 잘라줍니다.

────────────────────────────────────────
$a = explode('년',$date); // [0] => 2010 [1] => 04월20일
$b = explode('월',$a[1]); // [0] => 04 [1] => 20일
$c = explode('일',$b[1]); // [0] => 20 [1] =>
$date = $a[0].$b[0].$c[0];
────────────────────────────────────────

reset() 함수로 배열의 첫 번째 값을 쉽게 가져올 수 있습니다.
array_shift() 함수로 배열의 첫 번째 값을 뺄 수 있습니다.

explode() : http://php.net/manual/kr/function.explode.php
reset() : http://php.net/manual/kr/function.reset.php
array_shift() : http://php.net/manual/kr/function.array-shift.php


▶ 문자열 처리 #5

list() 함수를 이용하면 #4 변수 사용이 좀 더 간편해집니다.

────────────────────────────────────────
list($y,$date) = explode('년',$date); // $y=2010, $date=04월20일
list($m,$d) = explode('월',$date); // $m=04, $d=20일
list($d) = explode('일',$d); // $d=20
$date = $y.$m.$d;
────────────────────────────────────────

list() : http://php.net/manual/kr/function.list.php


▶ 문자열 처리 #6

explode()와 함께하는 implode() 함수를 이용해보겠습니다.

────────────────────────────────────────
$date = implode('',explode('년',$date));
$date = implode('',explode('월',$date));
$date = implode('',explode('일',$date));
────────────────────────────────────────

implode() : http://php.net/manual/kr/function.implode.php


▶ 문자열 처리 #7

sscanf() 함수를 이용하면 형식에 맞게 값을 뽑을 수 있습니다.
다 만, 앞에 0이 붙었으면 0을 제거해주기 때문에 조정이 필요합니다.

────────────────────────────────────────
$temp = sscanf($date,'%4d년%2d월%2d일'); // [0] => 2010 [1] => 4 [2] => 20
if ( $temp[1]<10 ) $temp[1] = '0'.$temp[1]; // 4 => 04
if ( $temp[2]<10 ) $temp[2] = '0'.$temp[2];
$date = implode('',$temp); // $date = $temp[0].$temp[1].$temp[2];
────────────────────────────────────────

sscanf() : http://php.net/manual/kr/function.sscanf.php


▶ 문자열 처리 #8

#7의 코드에 그 위에서 언급한 list() 함수를 이용해볼까요?

────────────────────────────────────────
list($y,$m,$d) = sscanf($date,'%4d년%2d월%2d일'); // $y=2010, $m=4, $d=20
if ( $m<10 ) $m = '0'.$m;
if ( $d<10 ) $d = '0'.$d;
$date = $y.$m.$d;
────────────────────────────────────────

참고로 each() 함수를 살펴보세요. list() 함수와 궁합이 좋습니다.
each() : http://php.net/manual/kr/function.each.php


▶ 문자열 처리 #9

sscanf()에서 곧바로 변수 할당도 가능합니다.
이번에는 sprintf() 함수로 형식에 맞는 문자열을 만들어보겠습니다.

────────────────────────────────────────
sscanf($date,'%4d년%2d월%2d일',$y,$m,$d); // $y=2010, $m=4, $d=20
$date = sprintf('%04d%02d%02d',$y,$m,$d);
────────────────────────────────────────

sprintf() : http://php.net/manual/kr/function.sprintf.php


▶ 문자열 처리 #10

strpos() 함수를 이용하면 지정한 문자(열)의 위치를 구할 수 있습니다.

────────────────────────────────────────
$py = strpos($date,'년'); // 4
$pm = strpos($date,'월'); // 8
$pd = strpos($date,'일'); // 12
$date = substr($date,0,$py).substr($date,$py+2,2).substr($date,$pm+2,2);
────────────────────────────────────────

strpos() : http://php.net/manual/kr/function.strpos.php


▶ 문자열 처리 #11

이번에는 고전적인 방법을 이용해보겠습니다.
문자열의 길이만큼 반복하며 1바이트씩 읽어 숫자일 때 붙여주는 것이죠.
먼저 풀어쓴 코드부터 보시죠.

────────────────────────────────────────
$original = $date; // $original에 기존 $date값을 할당
$len = strlen($date); // 문자열 길이 구해주고
$date = ''; // 결과값을 이곳에 담기 위해 빈 문자열로
for ($i=0;$i<$len;$i++) // 길이만큼 반복
{
    if ( is_numeric($original[$i]) ) $date.= $original[$i]; // 숫자인 경우 붙임
}
────────────────────────────────────────

for() : http://php.net/manual/kr/control-structures.for.php
strlen() : http://php.net/manual/kr/function.strlen.php
is_numeric() : http://php.net/manual/kr/function.is-numeric.php
ctype_digit() : http://php.net/manual/kr/function.ctype-digit.php

편 의상 is_numeric() 함수를 이용했습니다.
그리고 위에서 보다시피 '2010년04월20일'은 문자열 값이지만
[] 를 이용해 배열처럼 접근할 수 있습니다.


▶ 문자열 처리 #12

#11보다 더 고전적인 방법입니다. 아스키 값을 이용합니다.

────────────────────────────────────────
$original = $date; // $original에 기존 $date값을 할당
$len = strlen($date); // 문자열 길이 구해주고
$date = ''; // 결과값을 이곳에 담기 위해 빈 문자열로
for ($i=0;$i<$len;$i++) // 길이만큼 반복
{
    $c = $original[$i]; // 1바이트 문자
    $asc = ord($c); // 아스키 코드
    if ( $asc<48 || $asc>57 ) continue; // 숫자 범위 아니면 Skip
    $date.= $c;
}
────────────────────────────────────────

숫자 범위가 아니면 위와 같은 조건이면 됩니다.
숫자 범위로 조건을 바꾼다면? ( $asc>47 && $asc<58 )입니다.

참고로 <= 비교보다 < 비교가 빠릅니다.
그래 서 ( $asc>=48 && $asc<=57 )로 하기보다 위 조건을 권장합니다.
누누이 강조하는 부분이지만 쓰기 나름이니까 편한 대로 쓰면 됩니다.

또는 어차피 숫자 외의 문자열이라봐야 년, 월, 일이니
아 스키 값이 127 이상인 경우를 걸러주면 됩니다.

ord() : http://php.net/manual/kr/function.ord.php
ASCII Table : http://www.asciitable.com/


▶ 문자열 처리 #13

#11, #12의 for()문을 줄인 형태입니다.

────────────────────────────────────────
for($i=0,$o=$date,$date='',$l=strlen($o);$i<$l;$i++)if(is_numeric($o[$i]))$date.=$o[$i];
────────────────────────────────────────


▶ 문자열 처리 #14

#13 을 아예 for()문으로 끝내는 것도 가능합니다.

────────────────────────────────────────
for ($i=0,$l=strlen($o=$date),$date='';$i<$len;$i++,$date.=is_numeric($o[$i-1])?$o[$i-1]:'');
────────────────────────────────────────

빠질 뻔 했는데 값의 할당은 오른쪽부터 왼쪽으로 진행됩니다.
$l=strlen($o=$date)
$o에 $date가 할당되고, $o의 길이가 $l에 할당됩니다.
할당 연산자 : http://php.net/manual/kr/language.opera ··· ment.php
연산자 우선권 : http://php.net/manual/kr/language.opera ··· ence.php


▶ 문자열 처리 #15

"키=값" 형태로 가공해 parse_str() 함수를 이용하는 방법입니다.

────────────────────────────────────────
$date = 'y='.substr($date,0,-2); // y=2010년04월20
$date = str_replace('년','&m=',$date); // y=2010&m=04월20
$date = str_replace('월','&d=',$date); // y=2010&m=04&d=20
parse_str($date);
$date = $y.$m.$d;

────────────────────────────────────────

parse_str() 함수를 보면, extract() 함수가 떠오르죠.

parse_str() : http://php.net/manual/kr/function.parse-str.php
extract() : http://php.net/manual/kr/function.extract.php

두 번째 인자를 주면 그 변수에 값을 받게 됩니다.

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
// 위 3줄 동일
parse_str($date,$t); // 'y'=>'2010', 'm'=>'04', 'd'=>'20'
$date = implode('',$t); // $date = $t['y'].$t['m'].$t['d'];
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥


▶ 문자열 처리 #16

#11 ~ #14의 코드와 비슷합니다.
[]를 이용해 문자열도 배열 형태로 접근이 가능하다고 했죠?
이번에는 문자열을 정말 배열로 만들어 처리해보겠습니다.
그리고 똑같은 코드로 하면 재미없으니 다른 코드를 부르겠습니다.

────────────────────────────────────────
$temp = str_split($date);
$date = '';
foreach ( $temp as $char )
{
    if ( ord($char)<128 ) $date.= $char;
}
────────────────────────────────────────

1바이트로 나눠 배열 끝까지 반복, 아스키 값 비교로 결과값을 구합니다.
foreach()도 참 유용한 제어 구조 중 하나입니다. 배열과 찰떡 호흡!

str_split() : http://php.net/manual/kr/function.str-split.php
foreach() : http://php.net/manual/kr/control-structures.foreach.php


‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
$t=str_split($date);$date='';
foreach($t as $c)if(ord($c)<128)$date.=$c;
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥


▶ 문자열 처리 #17

substr_replace()를 깜빡했군요. str_replace()와 비교해보는 재미를···.

────────────────────────────────────────
$date = substr_replace($date,'',4,2); // 201004월20일
$date = substr_replace($date,'',6,2); // 20100420일
$date = substr_replace($date,'',8,2); // 20100420
────────────────────────────────────────

substr_replace() : http://php.net/manual/en/function.substr-replace.php



정규식으로 처리하는 방법 역시 다양합니다.


■ 정규식 처리 #1

제 일 간단한 방법은 숫자 외의 문자를 제거하는 것입니다.

────────────────────────────────────────
$date = preg_replace('/\D/','',$date);
────────────────────────────────────────

10진 숫자가 아닌 임의의 문자(\D)를 ''로 치환해주는 방법이죠.

정규 표현식 상세 : http://php.net/manual/kr/regexp.reference.php
정규 표현식 : http://php.net/manual/en/reference.pcre ··· ntax.php

임의의 10진 숫자는 \d로 표현합니다. 또는 [0-9]로 표현하죠.
여기에 부정 클래스를 사용하면 반대가 됩니다.

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
$date = preg_replace('/[^0-9]/','',$date);
$date = preg_replace('/[^\d]/','',$date);
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥

preg_replace() : http://php.net/manual/kr/function.preg-replace.php

참 고로 ereg_replace(), eregi_replace() 등 POSIX Regex 관련 함수들은
PHP 5.3 버전부터 중지됩니다.
POSIX Regex 관련 함수 : http://php.net/manual/kr/ref.regex.php

그러니 어서 펄 호환 정규식으로 갈아타시길···.
Regular Expressions (Perl-Compatible) : http://php.net/manual/kr/book.pcre.php


■ 정규식 처리 #2

숫자만 뽑아 묶어주는 방법입니다.

────────────────────────────────────────
preg_match_all('/\d/',$date,$matches);
$date = implode('',$matches[0]);
────────────────────────────────────────

위 와 같이 실행했을 때 $matches의 값입니다.
문자열 처리 과정에서 언급한 implode() 함수로 깔끔하게 묶어주면 됩니다.

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Array
(
    [0] => Array
        (
            [0] => 2
            [1] => 0
            [2] => 1
            [3] => 0
            [4] => 0
            [5] => 4
            [6] => 2
            [7] => 0
        )
)
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥

preg_match_all() : http://php.net/manual/kr/function.preg-match-all.php


■ 정규식 처리 #3

preg_split() 함수로 대놓고 년, 월, 일로 잘라줘도 됩니다.

────────────────────────────────────────
list($y,$m,$d) = preg_split('/년|월|일/',$date);
$date = $y.$m.$d;
────────────────────────────────────────

preg_split() : http://php.net/manual/kr/function.preg-split.php

차근차근 읽어본 경우라면 위 두 줄의 코드를 한 줄로 바꿀 수 있겠죠?

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
$date = implode('',preg_split('/년|월|일/',$date));
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥


■ 정규식 처리 #4

#1의 코드와 기본은 같고 메타 문자만 다릅니다.

────────────────────────────────────────
$date = preg_replace('/\W/','',$date);
────────────────────────────────────────

어떠한 문자나 숫자, _가 \w며, \W는 그 반대입니다.
특성이 있지만, 년, 월, 일 정도야···. ^^);;;


■ 정규식 처리 #5

preg_grep()의 활용 예를 위해 하나 더 추가합니다.
str_split() 함수와 마찬가지로 잘라주고, 숫자 부분만 가져다 묶어줍니다.

────────────────────────────────────────
$split = preg_split('//',$date,-1,PREG_SPLIT_NO_EMPTY);
$date = implode('',preg_grep('/\d/',$split));
────────────────────────────────────────

preg_grep() : http://php.net/manual/kr/function.preg-grep.php

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
$date = implode('',preg_grep('/\d/',preg_split('/()/',$date,-1,PREG_SPLIT_NO_EMPTY)));
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥


■ 정규식 처리 #6

#2 에서 preg_match_all()을 사용했죠? 이번에는 preg_match() 사용입니다.

────────────────────────────────────────
preg_match('/(\d+)년(\d+)월(\d+)일/',$date,$match);
$date = implode('',array_slice($match,1));
────────────────────────────────────────

$match의 값은 아래와 같습니다.

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Array
(
    [0] => 2010년04월20일
    [1] => 2010
    [2] => 04
    [3] => 20
)
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥

여기서 array_slice() 함수를 이용해 두 번째 배열부터 가져와 묶어줍니다.
문자열의 substr() 함수와 사용 방법이 같습니다. 대상만 배열이죠.

preg_match() : http://php.net/manual/kr/function.preg-match.php
array_slice() : http://php.net/manual/kr/function.array-slice.php



■ 정규식 처리 #7

응용 예입니다.

────────────────────────────────────────
preg_match('/(\d+)(\W.)(\d+)(\W.)(\d+)(\W.)/',$date,$matches);
$date = $matches[1].$matches[3].$matches[5];
────────────────────────────────────────

$matches 값은 아래와 같습니다.

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Array
(
    [0] => 2010년04월20일
    [1] => 2010
    [2] => 년
    [3] => 04
    [4] => 월
    [5] => 20
    [6] => 일
)
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥



▣ 날짜 함수 이용

문자열 처리 응용, strtotime() 함수와 date() 함수가 등장합니다.
년, 월, 일을 제거하면 그것으로 끝이지만 응용 차원에서 추가했습니다.
참. 꼭 -으로 바꿀 필요는 없습니다.

────────────────────────────────────────
$date = str_replace('년','-',$date); // 2010-04월20일
$date = str_replace('월','-',$date); // 2010-04-20일
$date = str_replace('일','',$date); // 2010-04-20
$date = date('Ymd',strtotime($date));
────────────────────────────────────────

strtotime() : http://php.net/manual/en/function.strtotime.php
date() : http://php.net/manual/kr/function.date.php

한 줄로 줄이려면? 문자열 처리 #3에서 언급한 strtr()을 사용하면 됩니다.

‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
echo date('Ymd',strtotime(strtr($date,array('년'=>'/','월'=>'/','일'=> ''))));
‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥

'오픈소스SW' 카테고리의 다른 글

Apache 웹방화벽 ModSecurity 사용하기  (1) 2010.06.08
jquery datepicker 사용  (0) 2010.06.05
JavaScript Tree Menu  (0) 2010.05.24
jqGrid 3.6.5 PHP CRUD  (2) 2010.05.23
fckeditor에서 이미지경로를 위한 Tip  (0) 2010.05.13
자바스크립트만을 사용한 트리메뉴.

'오픈소스SW' 카테고리의 다른 글

jquery datepicker 사용  (0) 2010.06.05
php 문자열처리 관련 function  (0) 2010.06.05
jqGrid 3.6.5 PHP CRUD  (2) 2010.05.23
fckeditor에서 이미지경로를 위한 Tip  (0) 2010.05.13
PHP 게시판  (0) 2010.05.12
jqGrid 최신버전이 업데이트되어서 새롭게 작성한 소스코드
환경 : LAMP, UTF-8
기능
- 한글화 적용
- 인라인 에디팅
- 엑셀 다운로드
- 검색
- 다중선택삭제 구현

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko">
<head>
    <link rel="stylesheet" type="text/css" media="screen" href="/jqgrid/themes/redmond/jquery-ui-1.7.1.custom.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="/jqgrid/themes/ui.jqgrid.css" />
    <script src="/jqgrid/js/jquery-1.4.2.min.js" type="text/javascript"></script>
    <script src="/jqgrid/js/i18n/grid.locale-kr.js" type="text/javascript"></script>
    <script src="/jqgrid/js/jquery.jqGrid.min.js" type="text/javascript"></script>

    <link rel="stylesheet" type="text/css" media="screen" href="/jqgrid/themes/ui.datepicker.css" />
    <script type="text/javascript" src="/jqui/development-bundle/ui/ui.datepicker.js"></script>
    <script type="text/javascript" src="/jqui/development-bundle/ui/i18n/ui.datepicker-ko.js"></script>
</head>
<body>
    <table id="htmlTable" class="scroll"></table>
    <div id="htmlPager" class="scroll"></div>
   
<script type="text/javascript">
var lastsel;
jQuery(document).ready(function(){
  jQuery("#htmlTable").jqGrid({
    url:'/jqgrid/jqgridCRUD.php',
    datatype: 'json',
    mtype: 'POST',
    colNames:['PK(sno)','등록일', '권역','사이트','URL','siteID','제품군','제품명','컨텐츠유형','컨텐츠포멧','활동유형','조회수','소속그룹'],
    colModel :[
        {name:'sno',index:'sno',width:30},
        {name:'sdate',index:'sdate',width:70,editable:true,sorttype:"date"},
        {name:'sarea',index:'sarea',width:70,align:'left',editable:true},
        {name:'site',index:'site',width:70,align:'left',editable:true},
        {name:'siteurl',index:'siteurl',width:250,align:'left',editable:true ,formatter: 'link',formatoptions:{target:"_blank"}
            ,editoptions:{size:'40',maxlength:'255'}
        },
        {name:'seedid',index:'seedid',width:100,align:'left',editable:true,formatter: 'link'},
        {name:'prodcat',index:'prodcat',width:50,align:'left',editable:true,edittype:'select',editoptions:{value:"CAM:CAM;DSC:DSC"},editrules:{required:true}},
        {name:'pname',index:'pname',width:50,sortable:true,editable:true},
        {name:'contype',index:'contype',width:60,align:'center',editable:true,edittype:'select',editoptions:{value:"Feature:Feature;Review:Review;Interview:Interview;Unboxing:Unboxing;Lifestyle Img:Lifestyle Img;Preview:Preview;Article:Article;Event:Event;Exhibition:Exhibition;News:News"},editrules:{required:true}
        },
        {name:'conformat',index:'conformat',width:60,align:'center',editable:true, edittype:'select',editoptions:{value:"Video:Video;Document:Document;Image:Image;Text:Text"},editrules:{required:true}},
        {name:'seedtype',index:'seedtype',width:60,align:'center',editable:true, edittype:'select',editoptions:{value:"Upload:Upload;Comment:Comment;Diary:Diary;Review:Review;Url:Url;Etc:Etc"},editrules:{required:true}},
        {name:'sitehit',index:'sitehit',width:30,align:'center',editable:true},
        {name:'grpid',index:'grpid',width:50,align:'left',editable:true},
    ],
    pager: jQuery('#htmlPager'),
    loadtext: 'Loading Data...',
    height: 350,
    width: 1000,
    rowNum:40,
    rowList:[10,15,20,30,50],
    sortname: 'sno',
    sortorder: "asc",
    viewrecords: true,
    multiselect: true,
    onSelectRow: function(id){
        if(id && id!==lastsel){
            jQuery('#htmlTable').saveRow(lastsel,true,null,checksave);
            jQuery('#htmlTable').editRow(id,true,pickdates);
            lastsel=id;
        }
    },

    cellurl:'/jqgrid/jqgridCRUD.php?act=inlineEdit',
    editurl:'/jqgrid/jqgridCRUD.php',
    caption: 'Viral Marketing Seeding List - inline Editing',
  }).navGrid('#htmlPager',{edit:false,add:true,del:true,search:true})
      .navButtonAdd("#htmlPager",{ caption:'', buttonimg:'/image/excel.png', onClickButton:function(){ document.down.submit();},title:'Excel 다운로드'})
      ;

});/* end of on ready event */

function pickdates(id){ jQuery("#"+id+"_sdate","#htmlTable").datepicker({dateFormat:"yymmdd"}); }

function checksave(result)
{
    if(result.responseText!='') alert(result.responseText);
    else $("#htmlTable").trigger("reloadGrid");
}

</script>
</body>
</html>

'오픈소스SW' 카테고리의 다른 글

php 문자열처리 관련 function  (0) 2010.06.05
JavaScript Tree Menu  (0) 2010.05.24
fckeditor에서 이미지경로를 위한 Tip  (0) 2010.05.13
PHP 게시판  (0) 2010.05.12
Automating Linux Unix  (0) 2009.08.11
fckeditor 설치후 정상적인 사용을 위한 몇가지 설정.

1) 파일업로드를 위한 공간을 생성하고 권한을 변경해준후 업로드에 사용되는 컨넥터파일들의 환경을 수정해야 한다.

2) 메일발송폼에 사용하거나이나 서버의 이미지를 다른도메인에서 링크시키기 위해서는 이미지 경로의 수정이 필요하다.
php connector 의 경우라면 editor/filemanger/connectors/php/config.php 파일에서 두가지를 설정해주면 된다.

$Config['UserFilesPath']
 를 찾아서 도메인을 포함한 전체 경로로 셋팅해준다.
예를들면 http://www.example.com/userfiles/ 같은 식으로.

$Config['UserFilesAbsolutePath']를 찾아서 서버의 절대경로로 셋팅해준다.
윈도우서버라면 "C:/inetpub/mysite/userfiles/" 식으로 ,유닉스, 리눅스서버라면 "/usr/me/public_html/mysite/userfiles/" 식으로 설정해준다.

두가지 설정을 동시에 하면. 도메인이 붙어있는 이미지경로가 작동된다.
참고 : http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/Configuration/Built_in_File_Browser

3) fckconfig.js 파일을 이용해서 적당한크기의 툴바셋을 만들고, 엔터치면 br이 작동되도록 변경해준다.


'오픈소스SW' 카테고리의 다른 글

JavaScript Tree Menu  (0) 2010.05.24
jqGrid 3.6.5 PHP CRUD  (2) 2010.05.23
PHP 게시판  (0) 2010.05.12
Automating Linux Unix  (0) 2009.08.11
CentOs 5.2 vsftpd 설치  (0) 2009.08.10


php 버전업에 따른 배포용 게시판 업데이트
============================================
Program : FOSSBORARD ver 1.0
Version : 1.0.0 (2010.05.10)
Developer : chaeya@gmail.com
Site : http://sysinfo.kldp.net/

OS : Linux
Language : PHP 5.2.5 (cli) (built: Sep 22 2008 14:55:04)
=============================================
라이센스 : GPL

주의: wiswig 스킨의 사용을 위해서는 fckeditor 첨부파일도 같이 설치해야 한다.


KLDP에 예전 저장소를 업데이트하려고 했지만, cvs인 관계로 그냥 여기등록.

'오픈소스SW' 카테고리의 다른 글

jqGrid 3.6.5 PHP CRUD  (2) 2010.05.23
fckeditor에서 이미지경로를 위한 Tip  (0) 2010.05.13
Automating Linux Unix  (0) 2009.08.11
CentOs 5.2 vsftpd 설치  (0) 2009.08.10
CentOS 5.2 Final + BIND 9.3.4  (0) 2009.08.02

'오픈소스SW' 카테고리의 다른 글

fckeditor에서 이미지경로를 위한 Tip  (0) 2010.05.13
PHP 게시판  (0) 2010.05.12
CentOs 5.2 vsftpd 설치  (0) 2009.08.10
CentOS 5.2 Final + BIND 9.3.4  (0) 2009.08.02
UML 지원 CASE Tool  (0) 2009.04.29
설치
yum install vsftpd


블랙리스트 확인
다음의 리스트에 등록되어 있는경우 원격접속이 불가능하다.
리스트를 확인후 수정이 필요

/etc/vsftpd/ftpusers // 다른 ftp의 경우 /etc에 있기도 했다.
/etc/vsftpd/user_list


포트 개방 20번 21번 (TCP만)
vi /etc/sysconfig/iptables

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 20 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

service iptables restart

ip_nat_ftp, ip_conntrack_ftp
방화벽을 사용할 경우 다음의 커널 모듈을 로딩해 줘야 된다.
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp

vsftpd 서비스가 실행될때 마다 로딩 하도록
/etc/init.d/vsftpd의 스타트부분에 넣어버렸다. 대략 아래와 같은 느낌으로

start() {
# Start daemons.

if [ -d /etc/vsftpd ] ; then
for i in `ls /etc/vsftpd/*.conf`; do
site=`basename $i .conf`
echo -n $"Starting $prog for $site: "
daemon /usr/sbin/vsftpd $i
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
echo
done

# for ftp connection error
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp

else
RETVAL=1
fi
return $RETVAL
}



부팅시 기동 설정
chkconfig --list | grep ftp
chkconfig --level 2345 vsftpd on
chkconfig --list | grep ftp


실행
service vsftpd start

'오픈소스SW' 카테고리의 다른 글

PHP 게시판  (0) 2010.05.12
Automating Linux Unix  (0) 2009.08.11
CentOS 5.2 Final + BIND 9.3.4  (0) 2009.08.02
UML 지원 CASE Tool  (0) 2009.04.29
Timeline 소개  (0) 2008.12.26

+ Recent posts