얼마전 메타 태그를 이용하여 페이지 새로고침을 해야하는 상황이 생겼습니다.
바로 사이트헤더에 meta정보를 이용하여 새로고침하는 거였는데..
얼마전 메타 태그를 이용하여 페이지 새로고침을 해야하는 상황이 생겼습니다.
바로 사이트헤더에 meta정보를 이용하여 새로고침하는 거였는데..
자바스크립트로 숫자 또는 특수문자를 제거 해봅시다 ^0^;
브라우저에서 1차적으로 한번 체크해주고 다시 서버에서 2차적으로 검증을…ㅎ
1차적으로 클라이언트에서 (브라우저) 폼 검증을 위해 많이 쓰이죠..
정규식 공부 꾸준히 합시다. ^,^
<script type="text/javascript"> //<![CDATA[ //정규식 특수문자 제거하기 function specialCharRemove(obj) { var val = obj.value; var pattern = /[^(가-힣ㄱ-ㅎㅏ-ㅣa-zA-Z0-9)]/gi; // 특수문자 제거 //var pattern = /[^(0-9)]/gi; // 숫자이외는 제거 if(pattern.test(val)){ obj.value = val.replace(pattern,""); } } //]]> </script>
정규식…알아두면 좋습니다 . 쓰임세가 많고 유용합니다.
[mysql] 쿼리에서 조건문 사용
if 문, case 문, ifnull문
IF 문
형식 : if ( 조건문, 참일때 값, 거짓일때 값)
EX) select member_id, if ( isnull(birthday), ‘-‘, birthday ) from member
설명 – 멤버 테이블에서 아이디(member_id) 와 생일을 뽑는데 null 일경우는 – 를 출력,
아니면 생일을 출력
Case 문
형식 : case (조건 또는 값)
when 값1 then 표시값
when 값2 then 표시값
else 표시값
end
EX) select case a when ‘1’ then a when ‘2’ then b else c end from table_name
설명 – a 값이 ‘1’이면 a, ‘2’ 이면 b, 둘다 아닐경우 c 를 출력
ifnull문 ( mysql 에서 사용 )
형식 : ifnull ( 값1, 값2)
EX ) select ifnull ( price, 0 ) from books
설명 – price 값이 Null 이면 0을, Null 이 아니면 price 값을 출력
isnull문 ( MS-SQL 에서 사용 )
형식 : ifnull ( 값1, 값2)
EX ) select isnull ( price, 0 ) from books
설명 – price 값이 Null 이면 0을, Null 이 아니면 price 값을 출력
NVL문 ( Oracle 에서 사용 )
형식 : NVL ( 값1, 값2)
EX ) select nvl ( price, 0 ) from books
설명 – price 값이 Null 이면 0을, Null 이 아니면 price 값을 출력
alias(명령어 간소화하기) apropos(관련된 명령어 찾기) arch(컴퓨터 종류 알기) arp(같은 서브넷의 IP 보여주기) at(작업 시간 정하기) atd(계획성 있는 작업 실행하기) awk(특정 패턴 문자 처리하기) a2p(펄 파일로 바꾸기) badblocks(배드 블럭 검사하기) bc(계산기) biff(메일 수신 소리로 확인하기) bg(후면작업; 배경화면 설정) bind(키나 함수 순서 결합하기) break(루프 빠져나가기) cal(달력보기) builtin(내부 명령어 알아보기) case(조건 처리하기) cat(화면상에서 파일 보기) cd(디렉토리 변경하기) cfdisk(디스크 설정하기) chattr(파일 속성 변경하기) chfn(사용자 정보 변경하기) chgrp(파일, 디렉토리가 속했던 그룹 바꾸기) chmod(파일 권한 바꾸기) chown(파일 주인 바꾸기) chsh(지정된 셸 바꾸기) cksum(CRC값을 점검한다) clear(화면 청소하기) clock(CMOS 시각을 조정하기) cmp(파일 비교하기) colcrt(문자 변환 필터) colrm(열 삭제하기) column(가로 정렬하기) comm(파일 비교 출력하기) command(명령어 알아보기) continue(루프 계속돌기) cp(파일 복사하기) cpio(복사본 만들기) crontab(cron을 관리한다) csplit(파일에 서식, 규칙 정하기) cut(필요한 필드만 출력하기) date(날짜 보기) dd(블럭장치 읽고 쓰기) debugfs(ext2 파일 시스템 디버깅하기) declare(변수 선언하기) df(파일 시스템의 사용량 보기) dirs(디렉토리 목록 표시하기) dmesg(부팅 메시지 보기) dnsdomainname(DNS 이름 출력) domainname(NIS 이름 출력&설정) du(디렉토리와 파일의 용량 파악하기) dumpe2fs(파일 시스템 정보 보기) echo(표준 출력하기) eject(장치 해제하기) elm(메일 관련) enable(내부 명령어 지정) env(환경변수 출력하기) eval(인수 읽기) exec(셸 명령어 실행하기) exit(종료하기) expand(탭을 공백으로 변환하기) export(변수 지정하기) e2fsck(파일 시스템 복구하기) fc(지정된 편집기 받기) fdformat(플로피 디스크 포맷하기) fdisk(파티션 나누기) fg(지정된 작업을 전면 프로세스로 시작하기) file(파일 종류 보기) find(파일 찾기) finger(사용자 정보 알기) fold(정형화하기) fmt(정형화하기) for(반복 실행하기) free(메모리 사용량 알아보기) fsck(파일 시스템 검사하기) fstab(파일 시스템에 대한 고정적인 정보 저장하기) ftp(파일 전송 프로그램) fuser(프로세스 ID 출력) getkeycodes(매핑 테이블 출력하기) grep(특정 문자(열) 검색하기) gzexe(실행 파일 압축하기) gzip(압축하기) halt(시스템 종료하기) hash(기억해 두기; index 역할) head(파일의 앞부분 출력하기) help(도움말 보여주기) host(호스트 정보 보기) history(사용 명령어 목록보기) hostname(서버 이름 알기) id(계정 정보 알기) if(조건문 실행하기) ifconfig(랜카드에 주소 할당하기) imolamod(모듈 설치하기) inetd(인터넷 서비스의 최상위 데몬) init(실행 단계 정하기) ispell(철자법 검사하기) jobs(수행중인 프로세스 알기) kbd_mode(키보드 모드 출력하기) kill(프로세스 죽이기) klogd(커널 로그 데몬) ldd(공유 라이브러리의 의존성 알기) less(페이지 단위로 출력하기) let(정규식 표현하기) lilo(부팅하기) ln(링크하기) locate(패턴에 맞는 파일 찾기) login(로그인하기) logger(시스템 로그 기록하기) logname(사용자 로그인명 보여주기) logout(로그인 셸 종료하기) look(특정 단어 검색하기) losetup(중복 장치 확인하기) lpd(프린트 데몬) lpq(현재 프린트 작업 상태 출력하기) lpr(출력하기) lprm(대기열에 있는 문서 삭제하기) ls(디렉토리 내용보기) lsattr(파일 시스템의 속성 보여주기) lsdev(하드웨어 장치 출력하기) lsmod(모듈 정보 출력하기) mail(메일 관련) make(컴파일하기) man(매뉴얼 보기) mattrib mbadblocks mcd mcopy mdel mdeltree mdir mesg(메시지를 받을 수 있는지 확인하기) mformat minfo mkdir (디렉토리 만들기) mke2fs(파일 시스템 생성하기) mkfs(파일 시스템 만들기) mknod(특수 파일 만들기) mkswap(스왑 영역 지정하기) mlabel mmd mmount mmove mpartition mount(장치 연결하기) more(화면 단위로 출력하기) mrd mren mtoolstest mtype mutt(메일 관련) mv(파일 옮기기) mzip netstat(현재 네트웍 상황 보기) nice(프로세스 우선 순위 변경하기) od(8진수로 파일 보기) passwd(암호 입력하기) pidof(실행중인 프로그램의 프로세스 ID 찾기) pine(메일 관련) ping(네트웍 확인하기) popd(pushd 취소) ps(프로세스 상태 알기) pstree(프로세스 상관관계 알기) pwd(절대경로 보여주기) quota(디스크 한계량 알기) rarp(rarp 테이블 관리하기) rcp(원격 호스트에 파일 복사하기) rdev(루트, 스왑장치, 램 크기, 비디오 모드를 조사하고 설정하기) rdate(네트웍으로 시간 설정하기) reboot(재부팅하기) rmmod(모듈 지우기) readonly(읽기 전용으로 표시하기) renice(프로세스 우선 순위 바꾸기) reset(터미널 초기화하기) restore(다시 저장하기) rlogin(바로 접속하기) rm(파일 지우기) rmdir (디렉토리 지우기) route(라우팅 테이블 추가/삭제하기) rpm(프로그램 추가/삭제) rpm2cpio(rpm을 cpio로 변환하기) rsh(원격으로 명령어 실행하기) rup(호스트 상태 출력하기) rusers(호스트에 로그인한 사용자 출력하기) rwall(호스트 사용자에게 메시지 뿌리기) script(기록하기) set(변수값 설정하기) setup(시스템 관련 설정하기) showmount(호스트의 마운트 정보 보여주기) shutdown(전원 끄기) sleep(잠시 쉬기) source(스크립트 번역하기) split(파일 나누기) ssh(암호화된 원격 로그인하기) stty(터미널라인 설정 보여주기) su(계정 바꾸기) suspend(셸 중단하기) swapoff (스왑 해제하기) swapon(스왑 활성화하기) sync(버퍼 재설정하기) syslogd(로그인 과정 설정하기) tac(거꾸로 보기) tail(문서 끝부분 출력하기) talk(이야기하기) tar(파일 묶기) tcpdchk(tcp wrapper 설정하기) tcpmatch(네트웍 요청에 대해 예측하기) tee(표준 입력으로부터 표준 출력 만들기) telnet(원격접속하기) test(테스트하기) times(셸에서의 사용자와 시스템 시간 출력하기) top(cpu 프로세스 상황 보여주기) tr(문자열 바꿔주기) true(종료 코드 리턴하기) type(유형 보기) ul(밑줄 처리해서 보여주기) ulimit(제한하기) umask(매스크 모드 설정하기) umount(장치 해제하기) unalias(별명 제거하기) uname(시스템 정보 보기) unexpand(공백 문자를 탭으로 변환하기) uniq(중복된 문장 찾기) useradd(사용자 계정 만들기) userdel(계정 삭제하기) usermod(사용자 계정정보 수정하기) unset(설정 변수 해제) uptime(시스템 부하 평균 보여주기) users(로그인된 사용자 보여주기) w(시스템에 접속한 사용자 상황 알아보기) wait(프로세스 기다리기) wall(모든 사용자에게 메시지 보내기) wc(문자, 단어, 라인수 세기) whatis(명령어의 간단한 설명보기) while(루프 명령어) who(사용자 알기) write(콘솔 상에서 간단한 메시지 보내기) xcopy(반복적으로 복사하기) XFree86 ypchfn(NIS에서 사용하는 chfn 명령어) ypchsh(NIS에서 사용하는 chsh 명령어) yppasswd(NIS에서 사용하는 passwd 명령어) zcat(압축 파일 보기) zcmp(압축 파일 비교하기) zforce(강제로 gz 만들기) zgrep(압축 상태에서 grep 실행하기) zmore(압축 상태에서 more 실행하기) znew(.Z 파일을 .gz로 다시 압축하기)
http://wiki.nginx.org/Configuration
MB는 m, GB는 g 를 숫자 뒤에 붙임.
유닉스소켓의 경우 unix:/tmp/php-fpm.sock 와 같은 형식으로 표시.
구분자는 공백 또는 탭 모두 가능.
기본 구조이며, http지시자 안에 기능에 따라 적절한 server 지시자를 삽입하여 사용한다. |
||
user nobody; worker_processes 4; error_log logs/error.log; pid logs/nginx.pid; events { worker_connections1024; } http { includemime.types; default_type application/octet-stream; ########################################## # performance ########################################## sendfileon; #tcp_nopushon; #keepalive_timeout0; keepalive_timeout 65; #gzip on; ########################################## server{ …. } } |
||
Directive |
Example |
Description |
user |
user nobody nobody; |
nginx가 root권한으로 실행될 때, 웹 계정 및 그룹 |
worker_processes |
worker_processes 1; worker_processes 2; |
작업 프로세스 수. (CPU 코어 수와 맞추는게 좋을 듯.) SMP를 활용하고, disk IO에 의한 지연을 감소 시킴. |
error_log |
error_log logs/error.log; error_log logs/error.log debug; error_log logs/error.log info; error_log /dev/null; |
에러 로그 설정. 로그 레벨 종류는 debug/info/notice/warn/error/crit 임. |
pid |
pid logs/nginx.pid; |
nginx 종료시 사용. |
worker_connections |
worker_connections 1024; worker_connections 4096; |
최대 접속자수(max_clients)는 아래 처럼 계산됨. max_clients = worker_processes * worker_connections (단, reverse proxy일 때에는 위 값을 4로 나눠줌. |
include |
include [file name] |
다른 설정 파일을 포함한다. |
default_type |
default_type application/octet-stream; |
conf/mime.types에 파일 확장자별 타입 목록이 있는데, 여기에 없는 확장자에 대한 타입을 설정한다. |
sendfile |
sendfile off; sendfile on; |
read(), write() 대신 커널내부에서 파일복사로 속도향상. sendfile을 설정할 경우 directio 지시자는 취소됨. |
keepalive_timeout |
keepalive_timeout 65; keepalive_timeout 0; |
클라이언트 접속 유지 시간 몇 초 후에 클라이언트 접속을 끊을지 결정. |
tcp_nopush |
tcp_nopush off; tcp_nopush on; |
소켓옵션 TCP_CORK 사용 여부. sendfile on; 일 때에만 사용 가능 HTTP Header를 한 패킷에 전송하므로서, 서버 트래픽을 감소 시킴. |
gzip |
gzip off; gzip on; |
gzip 압축 사용 여부. |
directio |
directio off; directio 4m; |
운영체제의 버퍼를 사용하지 않고, 직접 IO수행. 메모리 감소 효과. 큰 파일 전송에 유용. (O_DIRECT 플래그 이용) |
파일로 정적 컨텐츠를 캐싱할 때 – http://www.localhost.com:7942로 접속하면, 웹서버 127.0.0.1:9001와 127.0.0.1:9002로 로드밸런싱한다. – 만약 파일 캐싱을 사용하려면, proxy_cache…로 시작되는 음영처리된 부분의 주석을 해제하면 된다. 파일 캐시는 www/nginx/cache디렉토리에 저장된다. |
||
########################################## # Load Balancer & Reverse Proxy(using file cache) ########################################## upstream backend { server 127.0.0.1:9001 weight=2; server 127.0.0.1:9002; } # proxy_cache_path /www/nginx/cache levels=1:2 keys_zone=CACHE1:10m # inactive=24h max_size=1g; server { listen7942; server_namewww.localhost.com; location / { proxy_pass http://backend; proxy_set_header Hostwww.localhost.com; # proxy_cache CACHE1; # proxy_cache_valid 200 302 10m; # proxy_cache_valid 404 1s; # proxy_cache_use_stale error timeout invalid_header updating # http_500 http_502 http_503 http_504; } } ########################################## |
||
Directive |
Example |
Description |
upstream |
upstream [이름]{ server [아이피];[포트] weight=[숫자]; server unix:[유닉스소켓경로]; } |
로드밸런싱할 서버 목록. weight옆의 숫자는 가중치이며, 정수로 표시 |
proxy_set_header |
proxy_set_header Host $host; proxy_set_header Host www.localhost.com; proxy_set_header Connection Close; |
프록시되는(backend) 서버로 전송할 때 포함시킬 HTTP HEADER. |
proxy_cache_path |
proxy_cache_path [파일캐시경로] levels=[캐시경로레벨] keys_zone=[키존이름]:[키존용량] inactive=[유효시간] max_size=[캐시최대용량]; |
파일캐시 설정. [키존이름]은 캐시저장소 이름. [키존용량]은 키 저장 공유메모리 사용량. [유효시간]은 요청이 없을때 삭제할 시간. [캐시최대용량]은 최대 디스크사용량. |
proxy_pass |
proxy_pass http://127.0.0.1:9001; proxy_pass http://backend; proxy_pass http://unix:/tmp/php-fpm.sock; |
프록시되는(backend) 서버 설정. IP, upstream 이름, Unix 소켓중에서 선택. |
proxy_cache |
proxy_cache [키존이름] |
파일캐시를 이용할 때 사용. proxy_cache_path 에서 설정한 키존 이름. |
proxy_cache_valid |
proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1s; |
프록시 되는 서버(backend)로부터의 응답에 따른 캐시의 유효 기간 설정. |
proxy_cache_use_stale |
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; |
어떤 경우에 과거캐시를 전송할지 여부.옵션의 종류는 proxy_next_upstream와 같음.예를 들어, updating 옵션을 붙인 경우 한 스레드가 캐시를 업데이트할 때, 다른 스레드는 과거캐시를 전송한다. |
memcached로 정적 컨텐츠를 캐싱할 때 – http://mem.localhost.com:7942?abc 형식으로 호출하면 192.168.20.49:11211의 memcached 서버에서 키값이 abc인 데이타를 조회하여 클라이언트에게 전송한다. 만약 없을 경우 웹서버 127.0.0.1:9001과 127.0.0.1:9002에서 읽는다. – 아래에서 PHP FastCGI설정은 memcached에 set을 하기 위한 설정이므로 Reverse Proxy에는 필요없다. (주의) 단, 단일 memcached 서버만 사용가능하며, 클러스터링(upstream지시자)를 사용할 수 없다. 따라서 유용성이 떨어진다. |
||
########################################## # Reverse Proxywith Memcached Server) for Image Files ########################################## upstream backend { server 127.0.0.1:9001 weight=2; server 127.0.0.1:9002; } server { listen7942; server_namemem.localhost.com; location / { set $memcached_key $request_uri; memcached_pass 192.168.20.49:11211; default_type text/html; error_page 404 @fallback; } location @fallback { proxy_passhttp://backend; proxy_set_header Host www.localhost.com; } ########################################## # PHP FastCGI ########################################## location ~ \.php$ { root/www/nginx/mem.localhost.com; charsetutf8; access_loglogs/access.log; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME$document_root$fastcgi_script_name; include fastcgi_params; } ########################################## } ########################################## |
||
Directive |
Example |
Description |
memcached_pass |
memcached_pass 192.168.20.49:11211; |
memcached 서버 정보 |
$memcached_key |
set $memcached_key $request_uri; |
memcached 서버에 요청할 때 키로 어떤 값을 전송할지 여부 $request_uri, $uri, $args중에 하나를 설정한다. |
$request_uri |
/foo/bar.html?a=10&b=100 |
URL에서 Host이후의 전체경로. |
$uri |
/foo/bar.html |
URL에서 Host이후의 파일경로만. |
$args |
a=10&b=100 |
URL에서 파라미터만. |
HTML만 처리할 때 – http://www2.localhost.com:9002 로 접속하면, 기본적인 웹 서버로 동작한다. |
||
########################################## # Sub Web Server #2 ########################################## server { listen9002; server_namewww2.localhost.com; root/www/nginx/www2.localhost.com; charsetutf8; access_loglogs/access.log; error_page404/404.html; error_page500502503504/50x.html; location / { indexindex.html index.htm; } } |
||
Directive |
Example |
Description |
listen |
listen 80; listen 7942; |
서버 포트 설정 |
server_name |
server_name localhost; server_name abc.com; server_name abc.com def.com hij.com; |
가상 호스트용 (HTTP의 Host헤더 값과 비교) server_name_in_redirect가 on일 경우 redirect용으로 사용. |
root |
root html; root /www/nginx/html.localhost.com |
웹 디렉토리를 설정. |
charset |
charset koi8-r; charset utf8; charset off; |
응답 헤더의 “Content-Type”에 charset을 추가. |
access_log |
access_log logs/access.log combined; access_log logs/access.log off; access_log logs/access.log [format_name] |
접속 로그 설정. |
log_format |
log_format combined; log_format [format_name] [format_ string] |
접속 로그 포맷 설정 |
error_page |
error_page 404 /404.html; error_page 500 502 503 504 /50x.html; |
오류 발생시 표시할 페이지 결정. 오른쪽 예제의 경우 404.html, 50x.html 파일 이용. |
location |
location / location ^~ /images/ location ~ \.php$ |
URI에 대해서 정규식 매칭하여 각각 다른 설정을 한다. |
index |
index index.html index.htm; |
웹 인덱스파일 설정. |
PHP와 HTML을 모두 처리할 때 – http://www1.localhost.com:9001에 접속하면, 확장자가 PHP로 끝나는 경우에는 PHP-FPM 서버(127.0.0.1:9000)에 요청하여 PHP FastCGI를 처리하며, 그 외는 자체적으로 처리한다. |
||
########################################## # Sub Web Server #1 & WAS ########################################## server { listen9001; server_namewww1.localhost.com; root/www/nginx/www1.localhost.com; charsetutf8; access_loglogs/access.log; error_page404/404.html; error_page500502503504/50x.html; ########################################## # for HTML ########################################## location / { indexindex.html index.htm; } ########################################## ########################################## # for PHP ########################################## location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME$document_root$fastcgi_script_name; include fastcgi_params; } ########################################## } ########################################## |
||
Directive |
Example |
Description |
fastcgi_pass |
fastcgi_pass 127.0.0.1:9000; |
IP:Port 형태의 php fast cgi 서버 접속 경로 |
fastcgi_index |
fastcgi_index index.php; |
기본 index 파일 |
fastcgi_param |
PHP-FastCGI 서버에 전송할 정보 목록. 예를 들어, “SCRIPT_FILENAME”는 파일경로를 의미. include fastcgi_params;를 하여 “conf/ fastcgi_params”을 인쿠르드 하면 편하다. |
http://h264.code-shop.com/trac/wiki/Mod-H264-Streaming-Nginx-Version2
MP4 Streaming Module을 이용하여 MP4 파일을 스트리밍 할 때 – http://mp4.localhost.com:7942/abc.mp4와 같이 접속하면 abc.mp4파일을 mp4 지시자에 의하여 Streaming으로 처리한다. 확장자가 mp4가 아닌 경우에는 웹서버처럼 처리한다. – http://mp4.localhost.com:7942/abc.mp4?start=10&end=30 와 같이 접속하면 10초에서 30초 사이의 영상만 출력된다. |
||
########################################## # MP4 Streaming ########################################## server { listen7942; server_namemp4.localhost.com; root/www/nginx/mp4.localhost.com; charsetutf8; access_loglogs/access.log; error_page404/404.html; error_page500502503504/50x.html; location / { indexindex.html index.htm; } location ~ \.mp4$ { mp4; } } |
||
Directive |
Example |
Description |
mp4 |
mp4; |
H246 Streaming Module을 이용하여 스트리밍한다. |
테스트를 위해, 클라이언트의 hosts 파일에 아래와 같이 등록한다. IP는 Nginx가 설치된 서버로 수정한다. |
######################################################### # Nginx TEST ######################################################### 222.231.18.61 www.localhost.com 222.231.18.61 mem.localhost.com 222.231.18.61 www1.localhost.com 222.231.18.61 www2.localhost.com 222.231.18.61 mp4.localhost.com ######################################################### |
웹 브라우저를 실행하여, 기능별로 테스트해 보자. |
||
Uses |
URL |
Description |
Load Balancer & Reverse Proxy with File Cache |
||
Reverse Proxy with Memcached |
||
WAS (PHP FastCGI) + Memcached, MSSQL |
||
Web Server |
||
MP4 Streaming |
configure
전에 include/config/ftoption.h
의 FT_CONFIG_OPTION_SUBPIXEL_RENDERING
을 언코멘트 하면 서브픽셀렌더링을 사용할 수 있지만, 기본적으로 비활성화되어있다. 마이크로소프트의 특허때문이다. FreeType & Patents를 읽어보자.“/usr/local/include/ft2build.h”, line 56: cannot find include file: <freetype/config/ftheader.h>와 유사한 오류가 나면
/usr/local/include/ft2build.h
파일을 지운다. 이 파일은 더이상 사용되지 않으며 /usr/local/include/freetype2/ft2build.h
으로 대체되었다.# wget http://download.savannah.gnu.org/releases/freetype/freetype-2.5.5.tar.bz2 # tar xvfj freetype-2.5.5.tar.bz2 # cd freetype-2.5.5 # GNUMAKE="/usr/sfw/bin/gmake" ./configure --with-harfbuzz=no # /usr/sfw/bin/gmake # /usr/sfw/bin/gmake install
# wget --no-check-certificate https://bitbucket.org/libgd/gd-libgd/downloads/libgd-2.1.1.tar.bz2 # tar xvfj libgd-2.1.1.tar.bz2 # cd libgd-2.1.1 # ./configure --with-xpm=/usr --with-tiff=/usr ... Support for Zlib: yes Support for PNG library: yes Support for JPEG library: yes Support for VPX library: no Support for TIFF library: yes Support for Freetype 2.x library: yes Support for Fontconfig library: yes Support for Xpm library: yes Support for pthreads: yes .... # /usr/sfw/bin/gmake # /usr/sfw/bin/gmake install
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.bz2
# tar xvfj pcre-8.36.tar.bz2
# cd pcre-8.36
# ./configure CFLAGS="-I/usr/local/include"\
--enable-utf \
--enable-unicode-properties \
--enable-pcregrep-libz \
--enable-pcregrep-libbz2 \
--enable-newline-is-anycrlf \
--enable-pcre16 \
--enable-pcre32 \
--enable-jit \
--enable-pcretest-libedit 1)
# make
# make install
1) pcretest에 라인 편집 기능이 필요하지 않다면 이 줄을 제외하고 컴파일 해도 된다.
# wget http://www.maxmind.com/download/geoip/api/c/GeoIP-latest.tar.gz
# tar xvfz GeoIP-latest.tar.gz
# cd GeoIP-1.6.0
# CC=/usr/sfw/bin/gcc CFLAGS="-std=gnu99" ./configure
# make
# make install
# vi /usr/local/include/GeoIPCity.h 1)
// union {
// int metro_code; /* metro_code is a alias for dma_code */
int dma_code;
// };
1) Solaris Studio 는 anonymous union 을 허용하지 않기 때문에 주석처리 한다.
이 섹션을 실행하기 전에 윈디하나의 솔라나라: OpenSSL을 참조해 OpenSSL 소스를 받은 후, 압축을 풀어놓는다.
root@wl ~/src # wget http://nginx.org/download/nginx-1.6.1.tar.gz root@wl ~/src # tar xvfz nginx-1.6.1.tar.gz root@wl ~/src # cd nginx-1.6.1 root@wl ~/src/nginx-1.6.1 # vi auto/lib/openssl/make 1) ... && ./Configure --prefix=$ngx_prefix no-shared solaris-x86-cc $OPENSSL_OPT \\ ... root@wl ~/src/nginx-1.6.1 # ./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_realip_module \ --with-http_addition_module \ --with-http_xslt_module \ --with-http_image_filter_module \ --with-http_geoip_module \ --with-http_sub_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gzip_static_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_degradation_module \ --with-http_stub_status_module \ --with-http_auth_request_module \ --with-http_spdy_module \ --with-pcre-jit \ --with-pcre=../pcre-8.35 \ --with-cc-opt="-O4" \ --with-openssl=../openssl-1.0.1i 2) root@wl ~/src/nginx-1.6.1 # make root@wl ~/src/nginx-1.6.1 # make install root@wl ~/src/nginx-1.6.1 # /usr/local/nginx/sbin/nginx -v nginx version: nginx/1.6.1
1) 59번째 라인의 [&& ./config –prefix=$ngx_prefix no-shared $OPENSSL_OPT \\]을 변경한다.
2) 64비트로 컴파일 하려면 –with-cpu-opt=amd64 을 붙인다.
문서 루트를 정의하고 php 와의 연동을 위한 설정을 한다.
root@wl ~ # vi /usr/local/nginx/conf/nginx.conf ... events { use eventport; 1) ... } http { ... server { ... # 문서의 루트를 정의. /usr/local/nginx/html location / { ... root html; ... } # NGINX 상태 보기(http_stub_status_module 사용) 2) location /nginx_status { stub_status on; access_log off; allow w.x.y.z; deny all; } ... # Fast-CGI로 PHP와 연동한다. location ~ \.php$ { try_files $uri =404; root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } ... root@wl ~ #
1) 솔라리스 10에 추가된 Event Port를 사용하도록 해준다. 하지만 솔라리스 10의 커널 패치(102485이상)를 하지 않으면 커널 패닉이 일어날 수 있으니 반드시 패치한다. (솔라리스 10 u10을 사용하고 있다면 이미 패치 되어있다. Sun Alert 102485 Security Vulnerabilities in The Solaris Event Port API May Result in a Denial of Service (DoS) Condition을 읽어보자) 이 옵션을 지정하지 않으면 /dev/poll 을 사용한다. 이외에도 리눅스에서는 epoll, BSD계열은 kqueue 를 사용할 수 있다. 자세한 사항은 Optimizations – Nginx Community을 참고하자.
2) http://w.x.y.z/nginx_status 에 접속해보면 아래와 유사한 화면을 볼 수 있다.
Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106
text/plain 형식으로 제공되기 때문에 커맨드라인 툴로 잘라내서 원하는 곳에서 사용할 수 있다. 의미는 다음과 같다.
따라서 Active connections = Reading + Writing + Waiting 이 성립한다.
GeoIP, GeoLiteCity 를 사용해 특정 국가를 블록할 수 있다. 속도는 생각만큼 느리지 않은 것으로 생각한다.
root@wl ~ # mkdir /usr/local/geoip root@wl ~ # cd /usr/local/geoip root@wl /usr/local/geoip # wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz root@wl /usr/local/geoip # gunzip GeoIP.dat.gz root@wl /usr/local/geoip # wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz root@wl /usr/local/geoip # gunzip GeoLiteCity.dat.gz
nginx.conf 는 아래와 같은 설정을 추가한다. 이 설정은 중국IP를 블록한다.
root@wl ~ # vi /usr/local/nginx/conf/nginx.conf ... http { ... geoip_country /usr/local/geoip/GeoIP.dat; geoip_city /usr/local/geoip/GeoLiteCity.dat; ... map $geoip_country_code $ip_allow { default yes; cn no; } server { ... if ($ip_allow = no) { return 403; } } } root@wl ~ #
root@wl ~ # cat /usr/local/nginx/conf/nginx.conf user nobody; worker_processes 2; error_log logs/error.log; pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; access_log logs/access.log; sendfile on; tcp_nopush on; keepalive_timeout 5; server_tokens off; limit_conn_zone $binary_remote_addr zone=zoneone:10m; gzip on; gzip_comp_level 5; gzip_http_version 1.0; gzip_min_length 0; gzip_types text/plain text/css image/x-icon application/x-javascript; gzip_vary on; geoip_country /usr/local/geoip/GeoIP.dat; geoip_city /usr/local/geoip/GeoLiteCity.dat; map $geoip_country_code $ip_allow { default yes; cn no; } proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-PORT $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; client_header_buffer_size 64k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 16k; proxy_buffers 32 16k; proxy_busy_buffers_size 64k; server { listen 80; server_name www.xxx.com; access_log logs/www.xxx.com.access.log; error_log logs/www.xxx.com.error.log debug; location / { proxy_pass http://localhost:81/; limit_conn zoneone 10; } location = /_.gif { empty_gif; } location /admin { proxy_pass http://localhost:81/admin; allow 127.0.0.1; deny all; } location /images { proxy_pass http://localhost:81/images; expires max; } location /thumbimages { proxy_pass http://localhost:81/images; image_filter resize 150 100; image_filter_buffer 1M; image_filter_jpeg_quality 75; error_page 415 = /_.gif; } location /share { root /share/; expires max; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } if ($ip_allow = no) { return 403; } } } root@wl ~ #
아파치 로그파일에는 접속IP가 모두 nginx 가 설치된 서버의 IP로 저장된다. 따라서 http.conf 의 로그 포맷을 바꿔야 한다.
root@wl ~ # vi /usr/local/apache2/conf/httpd.conf ... LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio LogFormat "%{X-Real-IP}i:%{X-Real-PORT}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio-forward ... SetEnvIf X-Real-IP "^.*\..*\..*\..*" forward CustomLog "/var/log/httpd-access.log" combinedio-forward env=forward CustomLog "/var/log/httpd-access.log" combinedio env=!forward ...
※ nginx는 별도의 실행 스크립트를 제공하지 않는다. 아래와 같이 시작한다.
root@wl ~ # /usr/local/nginx/sbin/nginx
※ 실행한 후 http://localhost/ 을 보면 아래와 같은 화면이 나온다.
※ 종료는 아래와 같이 할 수 있다.
root@wl ~ # /usr/local/nginx/sbin/nginx -s stop
아래와 같이 실행해 http://localhost/phpinfo.php 에서 잘 실행되는지 확인하자. 만약 php에 접근할때 [No input file specified.] 가 나오면 SCRIPT_FILENAME 부분을 다시 한번 살펴보자.
root@wl ~ # vi /usr/local/nginx/html/phpinfo.php
<?php phpinfo(); ?>
root@wl ~ # /etc/init.d/php-fpm start 1)
1) 이 스크립트는 윈디하나의 솔라나라: AMP에서 PHP, PHP-FPM 설치및 설정 섹션에 설명했다.
nginx 홈페이지에서는 아래와 같은 실행 파일을 제공해준다. 적당히 수정했다.
출처: http://wiki.nginx.org/Standalone_daemon
nginx.sh |
다운로드 (774 바이트) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#!/bin/sh NGINX_BASE_DIR= "/usr/local/nginx" NGINX_DAEMON= "${NGINX_BASE_DIR}/sbin/nginx" NGINX_CONF= "${NGINX_BASE_DIR}/conf/nginx.conf" __launch_signal( ) { ${NGINX_DAEMON} -s ${1} &> /dev/null } __checkconfig( ) { ${NGINX_DAEMON} -c ${NGINX_CONF} -t &> /dev/null } __start( ) { [ -r ${NGINX_CONF} ] || exit 1 __checkconfig && ${NGINX_DAEMON} -c ${NGINX_CONF} &> /dev/null || return ${?} } __stop( ) { __launch_signal stop } __reload( ) { __checkconfig && __launch_signal reload || return ${?} } __restart( ) { __stop && __start } __show_usage( ) { echo "Usage: ${0} {start|stop|restart|reload}" exit 3 } case "${1}" in start|stop|restart|reload) [ -x ${NGINX_DAEMON} ] || exit 2 __${1} ;; *) __show_usage ;; esac |
웹서버를 마스터 슬레이브 구조로 구성하기 위해 nginx를 이용해 reverse proxy 구성을 했다. 이전에 포스팅했던 내용이 있긴 하지만 이번에는 테스트 환경이 아니라 실제 서비스에 적용하는 것으로 보안서버 관련 설정도 추가됐다. 아직 실제 서비스에 적용은 되지 않았지만 hosts 파일에서 ip를 변경해서 테스트해보니 제대로 작동이 되는 듯 하다. 좀 더 테스트를 진행해보고 실제 서비스에 적용해야할 것이다. 아래는 nginx.conf 파일의 설정이다.
#user nobody; worker_processes 4; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; error_log logs/error.log error; pid logs/nginx.pid; events { multi_accept on; worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; server_tokens off; keepalive_disable msie6; keepalive_timeout 180s; keepalive_requests 100; open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; gzip on; gzip_http_version 1.1; gzip_vary on; gzip_comp_level 1; gzip_proxied any; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js; gzip_buffers 16 8k; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; upstream web { server 192.168.0.2:80 max_fails=3 fail_timeout=10s; server 127.0.0.1:8080 backup; #server 127.0.0.1:8080; } upstream web-ssl { server 192.168.0.2:443 max_fails=3 fail_timeout=10s; server 127.0.0.1:8083 backup; } # reverse proxy server { listen 80; server_name example.com www.example.com; #charset koi8-r; #access_log logs/host.access.log main; log_not_found off; client_max_body_size 30m; large_client_header_buffers 4 16k; location / { proxy_pass http://web; proxy_set_header Accept-Encoding ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } } server { listen 443; server_name example.com www.example.com; ssl on; ssl_certificate cert.pem; ssl_certificate_key cert.key; ssl_session_timeout 5m; #ssl_protocols SSLv2 SSLv3 TLSv1; #ssl_ciphers HIGH:!aNULL:!MD5; #ssl_prefer_server_ciphers on; #charset koi8-r; #access_log logs/host.access.log main; log_not_found off; client_max_body_size 30m; large_client_header_buffers 4 16k; location / { proxy_pass https://web-ssl; proxy_set_header Accept-Encoding ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } } # virtual host server { listen 8080; server_name example.com www.example.com; #charset koi8-r; access_log logs/exampl.com.access.log main; log_not_found off; root /home/example/www; index index.html index.htm index.php; client_max_body_size 30m; #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # php in data execution block location ~* /(?:data)/.*\.php$ { deny all; } location ~* \.(jpg|jpeg|png|gif|js|css)$ { expires max; access_log off; valid_referers none blocked example.com www.example.com; if ($invalid_referer) { return 444; } } location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { expires max; access_log off; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_index index.php; include fastcgi_params; #fastcgi_pass 127.0.0.1:9000; fastcgi_pass unix:/var/run/fpm-default.sock; include mime.types; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } } # https virtual host server { listen 8083; server_name example.com www.example.com; ssl on; ssl_certificate cert.pem; ssl_certificate_key cert.key; ssl_session_timeout 5m; #ssl_protocols SSLv2 SSLv3 TLSv1; #ssl_ciphers HIGH:!aNULL:!MD5; #ssl_prefer_server_ciphers on; access_log logs/example.com.access.log main; log_not_found off; root /home/example/www; index index.html index.htm index.php; client_max_body_size 30m; #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # php in data execution block location ~* /(?:data)/.*\.php$ { deny all; } location ~* \.(jpg|jpeg|png|gif|js|css)$ { expires max; access_log off; valid_referers none blocked example.com www.example.com; if ($invalid_referer) { return 444; } } location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { expires max; access_log off; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_index index.php; include fastcgi_params; #fastcgi_pass 127.0.0.1:9000; fastcgi_pass unix:/var/run/fpm-default.sock; include mime.types; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } } }
위 설정은 Linux Virtual Server(LVS)의 ip가 192.168.0.1 이고 연결 도메인이 exampl.com이라면 example.com 으로 접속시 lvs에서 192.168.0.2 웹서버로 요청을 넘기고 192.168.0.2 서버에서 처리 후 사용자에게 전송하는 것이다. 만약 192.168.0.2 서버가 다운되어 접속이 안되면 lvs 에서 요청을 직접 처리하도록 되어 있는데 127.0.0.1 즉 로컬 호스트로 요청을 넘긴다. 요청 처리후 사용자에게 전송한다. 이렇게 구성하면 일단 서버가 한대만 살아있어도 접속은 된다. 물론 문제는 남아있는데 마스터 서버와 슬레이브 서버의 첨부파일 등의 data 동기화 문제이다. 이 부분은 직접 수동으로 처리하는 수 밖에 없을 듯 하다. 단순 웹서버 데몬의 다운이라면 rsync 등으로 동기화 시켜두면 해결되지만 네트웍이나 기기의 문제라면 동기화는 안될테니까 말이다.
upstream 블록에서 80포트와 443 포트를 따로 분리해둔 것은 reverse proxy에서 백엔드 서버로 요청을 넘길 때 포트 번호를 지정해주지 않으면 특히 https 접속시에는 포트 번호가 없으면 502 bad gateway 에러를 뿜어낸다. 이 부분때문에 꽤 많은 시간을 낭비했는데 미리 포트 번호를 지정해주는 것이 여러모로 나와 같은 삽질을 피할 수 있는 길이 아닐까 싶다. 로컬 호스트의 포트를 8080이나 8083을 사용한 것은 lvs에서 이미 80포트와 443포트를 사용하기 있기 때문이다. 이런 식으로 구성을 해서 테스트를 해보고 있는데 아직까지는 문제가 없는 듯 하다. 실제로 방문자가 많거나 했을 때는 어떻게 작동할 지는 내일 적용해서 테스트를 해보는 수 밖에 없을 것 같다.