뭘 이런걸..

Posted
Filed under Tech/안녕리눅스
이번에는 PHP 성능을 높일 수 있는 방법 2가지에 대해서 기술해 봅니다. 아래의 내용은 안녕 리눅스의 PHP package를 빌드할 때 성능을 높이기 위하여 한 작업을 기술 하는 것입니다.

먼저 PHP VM type을 변경하여 성능을 높이는 방법에 대해서 알아 보겠습니다.

PHP 5 까지 configure 옵션에 보면 --with-zend-vm 이라는 옵션이 있습니다. (7.0 부터는 없어졌습니다.) configure --help를 해 보면 아래 와 같이 설명이 나옵니다.

Zend: 
--with-zend-vm=TYPE Set virtual machine dispatch method. Type is
one of "CALL", "SWITCH" or "GOTO" TYPE=CALL


즉, zend vm type에는 "CALL", "SWITCH", "GOTO" 모드가 있고, 기본값은 "CALL" 이라는 내용입니다. 그리고 이 옵션으로 zend vm type을 변경할 수 있다고 되어 있습니다.

하지만, 실제로 configure 시에 이 옵션은 동작하지 않습니다. 그래서 7.0 부터는 제거가 되었습니다.
configure 얘기를 한 이유는, 검색을 하다 보면, 이 옵션을 이용하여 VM type을 변경할 수 있다는 글들이 나오기 때문입니다. configure 옵션으로는 VM type 변경이 되지 않기 때문에 언급을 한 것입니다. 7.0 부터 제거가 되었다는 것은 configure 옵션이 실제 동작을 하지 않기 때문에 제거가 되었다는 의미이지 7.0에서는 여기서 설명하는 것이 적용이 안된다는 의미가 아닙니다. 7.0 이후에서도 동일하게 성능을 높일 수 있습니다.

그럼, zend vm type이 뭔지, 그리고 어떻게 하면 변경할 수 있는지에 대해서 설명을 합니다. (빌드 후에 변경은 불가하고, 빌드 시에 선택을 해야 합니다.)

일단, zend vm에 대한 기본 내용은

https://github.com/php/php-src/blob/master/Zend/README.ZEND_VM

에서 확인하실 수 있습니다. 간략하게 설명을 하면, opcode optimize 방법이라고 보시면 됩니다. (설명 파일에는 executor 방법이라고 나오는데, 표현하기 쉽게 최적화라고 했습니다.) 일단 성능은 다음과 같습니다.

GOTO > SWITCH > CALL

일단,  GOTO를 기준으로 하면, php source code 안에 있는 bench.php를 기준으로 CALL보다 20% 정도의 성능 향상이 이루어 집니다.

그러면 왜 기본값이 GOTO가 아니라 가장 성능이 안 좋은 CALL이냐.. 에 대한 건 저도 아직 제대로 된 설명을 못 찾았습니다. (어쩌면 영어 자료만 있어서 그럴 수도 있습니다. ^^;)

다만, 빌드시에 GOTO의 경우에는 memory가 아주 많이 필요하며, 빌드 시간이 CALL로 빌드하는 것 보다 3~4배 정도가 더 걸립니다. build machine 성능에 따라 차이가 더 커질수도 있습니다. (특정 아키텍쳐나 compiler에 따라 case by case로 발생 합니다.) RHEL 5의 i686 시스템에서 php 5.2를 GOTO로 빌드 할 때 memory가 12G 정도를 잡아 먹어서, mameory가 모잘라  swap을 늘려서 빌드 했던 적도 있습니다. 이건 case by case이기 때문에 꼭 나타나는 증상이라고 할 수는 없지만 CALL로 빌드할 때 보다는 많은 메모리가 필요 합니다.

일단, 빌드 방법은 다음과 같습니다. ./configure를 실행하기 전에 php-src/Zend 디렉토리에서 다음의 명령을 실행합니다.

[root@an3 php-7.1.0]$ cd Zend
[root@an3 Zend]$ php zend_vm_gen.php --with-vm-kind=GOTO
[root@an3 Zend]$ cd ..
[root@an3 php-7.1.0]$ ./configure --with-옵션....
[root@an3 php-7.1.0]$ make -j 8 && make install
 

이 명령을 실행하면, zend_vm_execute.h 와 zend_vm_opcodes.h 파일이 새로 생성이 됩니다.

참고:
5.6 에서는 GOTO로 이 파일들을 생성하면, 빌드시에 syntax error가 발생하는 버그가 있습니다. 5.6에서는 zend_vm_execute.h에서 "constant_fetch_end"이 duplicate되었다는 에러가 발생 합니다. zend_vm_execute.h에서 중복된 constant_fetch_end 라벨을 constant_fetch_end1, constant_fetch_end2, constant_fetch_end3 과 같이 중복되지 않게 변경해 주면 됩니다.
zend_vm_gen.php 스크립트를 이용하여 zend_vm_execute.h 와 zend_vm_opcodes.h 파일을 GOTO type을 새로 생성한 후에, 기존의 configure; make; make install 을 이용하여 설치를 진행하면 됩니다.

안녕 리눅스 1/2/3 에 들어있는 PHP는 모두 GOTO 모드로 빌드 되어 있고, 네오위즈에서 사용하는 PHP와 TMON에서 사용하는 PHP도 모두 GOTO로 빌드되어 동작하고 있습니다. 실제 상용 시스템에서 사용하여 검증은 되었으니, 직접 빌드해서 사용하는 분들은 빌드시에 적용을 해 보시면 좋을 겁니다.

OS 선택을 고려해야 하고 CentOS 6/7 을 생각하고 계신 분들이라면 안녕 리눅스를 선택하는 것을 고려해 보심이 ^^; CentOS 6/7 호환이라 전환을 한다고 해서 특별하게 달라질 것은 없습니다.

다음은 realpath_cache_force 기능에 대해서 기술 합니다.

이 기능에 대해서는 안녕 리눅스 3 사용자 가이드의 PHP 문서의 4.7 realpath_cache_force 항목에서 자세히 설명을 하고 있습니다.

위의 링크의 내용을 간략히 말하자면, PHP 파일에서 realpath_cache 라는 기능이 있습니다. 이 기능은 PHP가 파일 시스템에 접근을 할 때에 mtime(modify time) 을 체크하여 일정 시간동안 caching을 하여 성능을 높이는 것인데, link()와 symlink() function으로 race condition을 이용해서 open_basedir 을 무력화 시킬 수 있는 보안 버그가 발견이 되어, PHP 개발자들이 open_basedir을 사용할 경우에는 realpath_cache를 사용하지 못하도록 코드를 변경해 버렸습니다. 그래서 open_basedir을 사용할 경우에 접속이 많은 사이트의 경우에는 30% 정도의 성능이 감소되는 문제가 있습니다. (이것 역시 case by case로 접속이 많은 수록 성능의 차이가 많이 나게 됩니다.)

안녕 리눅스 2.0 부터는 realpath_cache_force 라는 옵션을 추가하여, open_basedir을 사용하더라도, 이 옵션이 활성화가 되어 있으면, realpath_cache를 할 수 있도록 해 주며, 문제가 되는 link()와 symlink() 함수들을 사용하지 못하게 하여 문제를 해결하고 성능을 높일 수 있도록 합니다.

이 기능은 TMON에서 주유권 이벤트시에 접속이 너무 몰려서 최적화 작업을 하면서 만든 기능으로 안녕 리눅스 2.0의 PHP에 반영이 되었습니다.

CentOS 6 또는 7 사용자들의 경우에는 CentOS를 안녕 리눅스로 전환을 시키면 이 기능을 사용할 수 있습니다. (물론 PHP 버전이 다르므로 약간의 migration은 필요할 수 있습니다.)


안녕 리눅스 전환을 얘기를 하면 강요같이 받아들이는 분들도 계셔서 안녕 리눅스에 반영된 patch file을 아래에 공유 합니다. 다음은 안녕 리눅스 3의 php 7.1.0에 적용된 패치 파일 입니다. (copy & paste 이기 때문에 tab이 space로 변환이 되어 copy & paste로는 patch가 적용이 안되니 어디를 수정하는지 부분만 참고를 하세요.)

diff -urNp php-7.1.0.org/ext/standard/link.c php-7.1.0/ext/standard/link.c
--- php-7.1.0.org/ext/standard/link.c 2016-12-02 11:07:40.000000000 +0900
+++ php-7.1.0/ext/standard/link.c 2016-12-09 17:28:34.301410867 +0900
@@ -126,6 +126,16 @@ PHP_FUNCTION(symlink)
char dirname[MAXPATHLEN];
size_t len;

+ if (PG(open_basedir) && *PG(open_basedir) && PG(realpath_cache_force)) {
+ php_error_docref(
+ NULL TSRMLS_CC,
+ E_ERROR,
+ "The relapath_cache_force option is enabled. "
+ "For security issue, symlink function is not usable."
+ );
+ RETURN_FALSE;
+ }
+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
return;
}
@@ -182,6 +192,16 @@ PHP_FUNCTION(link)
char source_p[MAXPATHLEN];
char dest_p[MAXPATHLEN];

+ if (PG(open_basedir) && *PG(open_basedir) && PG(realpath_cache_force)) {
+ php_error_docref(
+ NULL TSRMLS_CC,
+ E_ERROR,
+ "The relapath_cache_force option is enabled. "
+ "For security issue, link function is not usable."
+ );
+ RETURN_FALSE;
+ }
+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
return;
}
diff -urNp php-7.1.0.org/main/main.c php-7.1.0/main/main.c
--- php-7.1.0.org/main/main.c 2016-12-09 17:28:25.502936720 +0900
+++ php-7.1.0/main/main.c 2016-12-09 17:28:34.302410921 +0900
@@ -725,6 +725,7 @@ PHP_INI_BEGIN()

STD_PHP_INI_ENTRY("realpath_cache_size", "16K", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_size_limit, virtual_cwd_globals, cwd_globals)
STD_PHP_INI_ENTRY("realpath_cache_ttl", "120", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_ttl, virtual_cwd_globals, cwd_globals)
+ STD_PHP_INI_ENTRY("realpath_cache_force", "0", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_force, php_core_globals, core_globals)

STD_PHP_INI_BOOLEAN("upload_image_check", "0", PHP_INI_SYSTEM, OnUpdateBool, upload_image_check, php_core_globals, core_globals)
STD_PHP_INI_BOOLEAN("upload_image_check_log", "0", PHP_INI_ALL, OnUpdateBool, upload_image_check_log, php_core_globals, core_globals)
@@ -1779,7 +1780,7 @@ int php_request_startup(void)
}

/* Disable realpath cache if an open_basedir is set */
- if (PG(open_basedir) && *PG(open_basedir)) {
+ if (PG(open_basedir) && *PG(open_basedir) && !PG(realpath_cache_force)) {
CWDG(realpath_cache_size_limit) = 0;
}

@@ -2362,7 +2363,7 @@ int php_module_startup(sapi_module_struc
zend_register_standard_ini_entries();

/* Disable realpath cache if an open_basedir is set */
- if (PG(open_basedir) && *PG(open_basedir)) {
+ if (PG(open_basedir) && *PG(open_basedir) && !PG(realpath_cache_force)) {
CWDG(realpath_cache_size_limit) = 0;
}

diff -urNp php-7.1.0.org/main/php_globals.h php-7.1.0/main/php_globals.h
--- php-7.1.0.org/main/php_globals.h 2016-12-09 17:28:25.503936774 +0900
+++ php-7.1.0/main/php_globals.h 2016-12-09 17:28:34.303410975 +0900
@@ -154,6 +154,7 @@ struct _php_core_globals {
zend_long max_input_nesting_level;
zend_long max_input_vars;
zend_bool in_user_include;
+ zend_bool realpath_cache_force;

zend_bool upload_image_check;
zend_bool upload_image_check_log;
diff -urNp php-7.1.0.org/php.ini-development php-7.1.0/php.ini-development
--- php-7.1.0.org/php.ini-development 2016-12-09 17:22:39.522475756 +0900
+++ php-7.1.0/php.ini-development 2016-12-09 17:28:34.304411028 +0900
@@ -351,6 +351,12 @@ disable_classes =
; http://php.net/realpath-cache-ttl
;realpath_cache_ttl = 120

+; If set on safe_mode or open_basedir, realpth_cache is disable. Set 1 this
+; directive, realpath_cache is enable with realpath_cache_size and realpath_cache_ttl
+; although safe_mode or open_basedir set enable. If you want to enable this variable,
+; We recommand that symlink function is set to disable_functions
+;realpath_cache_force = 0
+
; Enables or disables the circular reference collector.
; http://php.net/zend.enable-gc
zend.enable_gc = On
diff -urNp php-7.1.0.org/php.ini-production php-7.1.0/php.ini-production
--- php-7.1.0.org/php.ini-production 2016-12-09 17:22:39.523475809 +0900
+++ php-7.1.0/php.ini-production 2016-12-09 17:28:34.305411082 +0900
@@ -351,6 +351,12 @@ disable_classes =
; http://php.net/realpath-cache-ttl
;realpath_cache_ttl = 120

+; If set on safe_mode or open_basedir, realpth_cache is disable. Set 1 this
+; directive, realpath_cache is enable with realpath_cache_size and realpath_cache_ttl
+; although safe_mode or open_basedir set enable. If you want to enable this variable,
+; We recommand that symlink function is set to disable_functions
+;realpath_cache_force = 0
+
; Enables or disables the circular reference collector.
; http://php.net/zend.enable-gc
zend.enable_gc = On
2016/12/14 02:29 2016/12/14 02:29
Posted
Filed under Tech/프로그래밍
요즘 IT 업계에서 보안이 화두이기는 한 것 같습니다. 지인에게서 ISMS 인증이 빡세어 졌다는 등의 소식도 있고..

근래 free lancer로 일을 하면서 진행하는 project에서도 역시 보안이 화두인가 봅니다. project 마무리를 하고 있는 상황에서, 갑자기 설정 파일을 암호화를 해 달라는 요청을 받았습니다. 그것도 다른 파일들은 나두고 설정 파일만..

대충 복호화가 가능한 알고리즘을 이용해서 eval로 실행을 시킬까 고민을 잠시 하기는 했었는데, 영 eval 은 아닌 것 같고 검색을 해 보니 php_screw 라는 것이 보이더군요. 그래서 이 놈을 사용하려고 code를 좀 살펴 보았는데, 좀 걸리는 부분들이 많더군요.

  1. php_unscrew로 복호화가 가능하다.
  2. decode api (zencode.c) 에서 전역 변수를 사용하여 thread safe 하지 못하다. (프로젝트와는 상관이 없지만...)
  3. 복호시에 temp file을 생성한다.
  4. decode 시에 memory realloc을 너무 자주 한다. 사이즈가 큰 암호화 파일의 경우 성능을 떨어뜨릴 수 있다.
  5. 파일 몇 개를 암호화 하기 위해서, 모든 파일의 magic key 체크를 한다.

등등.. 복호화 문제와 성능의 문제가 고민이 되었습니다.

성능의 문제의 경우, 처음 php_screw를 살펴 보던 시점에서는 opcode cache를 고려하지 않았고 또한 테스트를 해 보지 않은지라 성능상의 문제가 좀 커 보였었던 점이 있습니다. 지금 시점에서 말하자면, opcacheAPC와 같은 PHP code cache 프로그램을 이용하면, magic key 체크, decode 등의 이슈는 상당히 많이 줄어들게 됩니다.

다만, 하고 있는 프로젝트가 순간 폭주가 가능한 서비스인지라, cache time이 짧을 경우 문제가 될 소지가 있었고, 또한 php_uncrew에 의한 복호화의 문제도 있어 어쩔수 없이 코드를 건드리게 되었고, mod_screwim (PHP Screw Improved)라는 fork 버전을 릴리즈 했습니다.

대략적인 개선 사항은, 다음과 같습니다.

  1. temp flie을 생성하는 방식에서 신성욱님의 개선사항을 반영하여 PHP memstream을 이용한 방식으로 개선
    1. 개선 사항에 있던 memory leak 수정
    2. 반환값이 없을 경우 segfault 발생하는 문제 수정
    3. 파일을 2번 open 하는 버그 수정
  2. 전역 변수를 없애 thread safe하도록 수정
  3. memory reallocation 로직을 수정하여 사이즈가 큰 암호화된 파일을 decode 시에 성능 개선
  4. 암호화 SEED key 자동 random 생성
  5. screwim.enable ini 옵션이 enable 상태에서만 decodeing을 한다. (ini_set 이용 가능하며, magic key 검사 이슈)
  6. runtime encrypt/decrypt API 제공 (screwim_encrypt(), screwim_decrypt(), screwim_seed())
  7. php_unscrew 방식의 복호화를 어렵게 수정

뭐, 그 외에도 자잘한 것들이 있기는 하지만 그리 중요한 것 같지는 않고, 자세한 사항은 https://github.com/OOPS-ORG-PHP/mod_screwim/ 을 참고 하시기 바랍니다.

그리고, 이 모듈(mod_screwim)을 사용하려면 (또는 php_screw를 사용하려면) 꼭 (opcache 또는 APC 같은..) cache를 같이 사용해야 decode 시의 성능 손실을 최소화 할 수 있습니다.
2016/11/30 01:36 2016/11/30 01:36
Posted
Filed under Tech/프로그래밍
VIM 에서 PHP를 작성할 때, indent 기능을 사용할 경우 switch가 아래와 같이 정렬이 됩니다. 

<?php 
switch ($a) {
case '1' :
echo "1\n";
break;
default :
echo "12\n";
}
?>


즉, case 문의 depth가 switch와 동일하게 되는 현상인데, 이걸 싫어 하는 사람도 많습니다. 그래서 case를 indent 시키고 싶다면 .vimrc 에 다음의 설정을 추가해 주세요.

let g:PHP_vintage_case_default_indent = 1


그리고 다시 indent 시켜 보면 다음과 같이 정렬이 됩니다.

<?php
switch ($a) {
case '1' :
echo "1\n";
break;
default :
echo "2\n";
}
?>


2016/07/08 17:50 2016/07/08 17:50
Posted
Filed under security
자 5월 말에 Chrome browser가 51로 업그레이드 되면서 NPN 기능을 제거 했습니다.

NPN 기능이 대표적으로 사용되는 것은 SPDY와 HTTP2 protocol 입니다. SPDY는 NPN 기반으로 동작을 하고, HTTP2는 ALPN 기능을 이용하여 동작을 하는데, NPN 기반에서도 동작이 가능 합니다.

그럼, Browser에서 NPN 기능을 제거한 것이 무엇이 문제냐는 점인데.. Browser에서 NPN 기능을 제거를 하면 서버에서도 ALPN 기반으로만 HTTP2 서비스가 가능하며 서버가 NPN 기반일 경우에는 불가능 합니다. 또한, 기존의 SPDY는 chrome에서는 불가능 하다는 의미입니다.

즉, Chrome browser는 서버에서 ALPN을 지원하지 않으면, 아무리 서버에서 spdy나 http2 protocol을 지원하도록 해도 HTTP/1 로 통신을 해 버리게 되는 것입니다.

뭐, 다 좋습니다. NPN이 사장된 기능이고, 사장된 기능은 빨리 제거를 하는 것이 좋을 테니까요.

그럼 무엇이 문제일까요?

현재 ALPN은 openssl 1.0.2 부터 지원을 합니다. 1.0 은 NPN을 하고요. 문제는 이 openssl 버전에 있습니다.

openssl은 대부분의 OS 배포본에서 core 패키지로 분류가 됩니다. 즉, openssl을 함부로 업그레이드 했다가는 시스템 동작이 원할하지 못하게 된다는 것을 의미합니다. 일단 ssh 연결이 불가능 하게될 가능성이 가장 큽니다. 즉, openssl 은 함부로 업그레이드가 불가능한 패키지로 봐야 하기 때문에, 상위 버전의 openssl을 사용하려면 별도의 위치에 openssl을 설치한, 별도 위치의 openssl library를 link를 해야 합니다. 문제는 이 부분이 누구나 쉽게 할 수 있는 부분이 아니라는 것이죠.

또한, openssl은 심각한 보안버그가 자주 나오는 편인데, 별도로 관리되지 않는 openssl을 설치해서 사용한다는 것도 보안 운영상 아주 취약한 문제이고요.

현재 리눅스 우리나라에서 서버로 많이 사용되는 배포본과 openssl library 버전은 다음과 같습니다.

Operating System OpenSSL Version ALPN and NPN Support
CentOS/Oracle Linux/RHEL 5.10+ 0.9.8e Neither
CentOS/Oracle Linux/RHEL 6.5+, 7.0+ 1.0.1e NPN
Ubuntu 12.04 LTS 1.0.1 NPN
Ubuntu 14.04 LTS 1.0.1f NPN
Ubuntu 16.04 LTS 1.0.2g ALPN and NPN
안녕 리눅스 2 1.0.1e NPN
안녕 리눅스 3 1.0.1e NPN + ALPN (back porting)

일단 안녕 리눅스는 많이 사용되는 배포본은 아니지만, 제가 배포하는 거라 살짝 끼워 넣었습니다.

위의 상황을 보시면 바로 아실 수 있을 겁니다. 현재 운영되는 대부분의 배포본들이 ALPN을 지원하지 않는다는 의미입니다. 즉, 브라우저에서 NPN 기능을 제거해 버리면 대부분의 spdy나 http2 기능을 제공하던 시스템들이 무력화가 되는 것이나 마찬가지라는 것입니다.

NPN 기능이 activeX 처럼 악의 축도 아니고, 상황이 바쳐주지 않은 상태에서 이렇게 NPN을 제거해 버림으로서 일단 SPDY 서비스는 완전히 무력화가 되어 버렸습니다.

가장 많이 사용하는 브라우저인 Chrome이 과감하게 NPN을 제거함으로서 이제 OS 배포본 업체들의 행보가 궁금해 집니다. 운영되고 있는 대부분의 배포본에서 제공하는 openssl 1.0.0, 1.0.1 버전에 ALPN 기능을 back porting을 해 줄 것인지 아니면, 고객들 보고 알아서 하라고 할 것인지.. 재미있는 상황이 되어 버렸습니다.


일단, 구글의 조치로 인하여, 구글을 제외한 http2 환경은 지랄 맞는 상황이 되어 버렸습니다. :-)


P.S.
안녕 리눅스 3은 http2의 지원을 위해서 openssl 1.0.2의 ALPN을 back porting을 해 놓았으며, 안녕 리눅스 2도 현재 back porting을 진행 하고 있습니다.

2016/06/24 01:04 2016/06/24 01:04
김정균

안녕 리눅스 2에서 openssl-1.0.1e-48.an2.1 부터 ALPN patch 가 적용이 되었습니다. 적용이 되지 않은 시스템들은 다음 명령으로 업데이트 하세요.

yum update "openssl*"

Posted
Filed under 주절주절
얼마전 NHN에서 나눔 고딕 코딩 후속으로 D2 coding 이라는 코딩용 font를 공개했습니다. (나눔 고딕 코딩도 그렇고 참 감사히 잘 쓰고 있습니다. ^^)

본인은 보통 가변폭 폰트보다 고정폭 폰트를 선호하는 경향이 있어, 이렇게 고정폭 폰트가 나오면 참 감사히 사용합니다.

하지만, 출시된지 얼마되지 않아서인지, D2 coding의 웹폰트가 아직은 없더군요.

그래서 제가 사용하려고 만든 D2 coding webfont를 공유 합니다.

http://cdn.kldp.org/fonts/D2-Coding/D2Coding-Webfont.tar.xz

에서 받으실 수 있습니다. 누가 jsdelivr에 올려 주실 수 있으면 올려 주세요.

형식은, eot, woff, woff2, ttf 형식으로 지원합니다.

압축은 xz 압축으로, tar 명령으로는 "xvfpJ' 옵션으로 해제 가능 하며, 윈도우즈에서는 7-zip 같이 xz 압축 지원하는 압축도구에서 해제 가능 합니다.
2016/04/08 15:26 2016/04/08 15:26
makalu

감사합니다^^

한태승

D2Coding 웹폰트는 네이버 개발자 페이지에 건의해도 진행되지 않던 부분인데,
공유해주셔서 감사합니다. 덕분에 유용하게 이용하겠습니다.

김정균

d2coding 웹폰트 다운로드 위치가 https://github.com/Joungkyun/font-d2coding/releases 로 변경이 되었습니다.

jsdelivr에 올리려고 하는데 등록이 되지를 않네요. 왜 등록이 안되는지는 모르겠음. pull request 주소는 다음과 같습니다. 혹시 이유 아시는 분 도와주세요 :-0

https://github.com/jsdelivr/jsdelivr/pull/13355

김정균

8/21에 full request 요청을 했는데 11/30에 merge가 되었네요. 3달 10일 걸렸습니다. :-)

http://www.jsdelivr.com/projects/font-d2coding

jsdelivr 에 있는 1.2 는 공식 1.2 버전이 아니라, 1.1 버전에서 css 수정 사항이 반영된 것입니다. 공식 1.2 버전은 금일 full request를 올렸고 1.2.1로 배포가 될 예정입니다.

공식 버전과 웹폰트간의 변경 사항이 틀려서 웹폰트 버전을 3자리로 하여, 두번째 자리 까지는 공식 버전을 따라가고, 웹폰트의 변경 사항은 마지막 자리에서 할 예정입니다.

Posted
Filed under Tech/Tip & Trick
Note: OS X 10.11 El Capitan에서의 방법이 업데이트 되었습니다.

아.. Mac Lion에서 동작하는 Apple Script를 찾느라 힘이 들어 공유 합니다. (일단 한글 자료가 없어서..)

일단, finder > 응용 프로그램 > Apple Script 편집기를 실행 해서 다음의 코드를 넣습니다.

주의할 것은, Apple Script를 사용하기 위해서는 "시스템 설정" > "손쉬운 사용" 의 하단에 "보조 장비에 대한 접근 활성화"가 체크되어 있어야 합니다.

Safari Private Browsing 한국어 모드



OS X 10.11 El Capitan 에서는 다음과 같이.. (https://discussions.apple.com/message/29223652#29223652 참조)

Safari Private Browsing 한국어 모드



영문판은 다음과 같이 하셔야 합니다.

Safari Private Browsing 영문 모드

2016/01/20 18:26 2016/01/20 18:26
Posted
Filed under Tech/프로그래밍
안녕 리눅스 3의 PHP 버전을 7로 올려서 release 하려고 하다보니.. 별 개삽질을 다하고 있다.
일단, PHP wiki에서 https://wiki.php.net/phpng-upgrading 를 참고하여 작업을 하면 되는데, 문제는 여기에 나와있지 않은 경우가 너무나 많다.

결국에는 PHP 소스 코드를 뒤져서 구현해야 하는.. 더군다나 여기에 나와있지 않은 hole들도 굉장히 많다. 대표적으로..

char * input;
int ilen;
int no;
 
if ( zend_parse_parameters (ZEND_NUM_ARGS(), "sl", &input, &ilen, &no) == FAILURE )
    RETURN_FALSE;
이 코드는 컴파일을 잘 되나, 그냥 segfault 가 발생한다. s(String)과 l(integer)는 다음과 같이 해 줘야 한다.

zend_string * Zinput = NULL;
zend_long no;

char * input;
int ilen;

if ( zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", &input, &no) == FAILURE )
    RETURN_FALSE;

input = ZSTR_VAL (input);
ilen = ZSTR_LEN (input);
zend_parse_parameters 에서 string은 zend_string으로 변경해 줘야 하고, long은 zend_long로 선언을 변경해 줘야 한다. 이 외에도, string을 zval 변수로 변환하는 경우도 짜증난 케이스

zval *zv;
MAKE_STD_ZVAL (zv)
ZVAL_STRING (zv, "문자열");
이 코드는 다음과 같이 변경 되어야 한다.
zval zv;
ZVAL_STRING (&zv, "문자열");
,,,
zval_ptr_dtor (&zv);
이 외에도 너무 많아서 정리가 힘들다. PHP7은 잘못하면 python 3 꼴이 날지도 모르겠다. 3party module 중에서 PHP 7을 지원을 얼마나 빨리 해 주ㄴ냐가 관건인 듯.. 물론 php code 호환 문제 까지는 바라보기도 전에 말이다. (갈 길이 너무 멀다....) 내가 만든 3party 확장들은 PHP 7 지원을 위한 코드 변경이 너무 많아서, 아예 PHP 7 지원하는 버전은 하위 호환성을 포기하고 컴파일을 막아 버렸다. --;
#if PHP_API_VERSION < 20151012
#error "************ PHP version dependency problems *******************"
#error "This package requires over php 7.0.0 !!"
#error "If you build with php under 7.0.0, use mod_krisp 2.x version"
#error "You can download mod_krisp 2.x at http://mirror.oops.org/pub/oops/libkrisp/APIs/php/"
#endif
참고로.. mod_korean migraion diff 를 보면.. 얼마나 많이 변경을 해야 하는지 대충 감이 올 듯.. 이 링크는 아직도 작업이 완료되지 않은 상태이다. --;
2015/12/29 05:15 2015/12/29 05:15
김정균

ncurses extension 작업 완료

ncurses: https://bugs.php.net/bug.php?id=71299

김정균

하.. 숨어있는 문제들이 훨씬 더 많군요 :-(

내부 구조의 많은 변경으로, 단순하게 API 변경만 따라가다가는 엉뚱한 문제들이 송송 터지네요. 예를 들면 https://github.com/expressif/pecl-event-libevent/issues/3 요런 문제들이..

PHP 7의 걸림돌은 3rd party extension 들이겠군요.

참고로 PHP 7을 지원하도록 수정된(거의 비공식적인) 3rd party extension 목록을 공유합니다.

memcache: https://github.com/websupport-sk/pecl-memcache/tree/php7
libevent: https://github.com/expressif/pecl-event-libevent/
event: https://bitbucket.org/osmanov/pecl-event/src/7f233a23b34bb100753971766c5ea2611fe8d023/?at=php7-dev
mongodb: http://pecl.php.net/package/mongodb/1.1.1

등등..

Posted
Filed under security
며칠전 지인에게서 시스템이 이상하다고 봐달라고 하여 확인을 하다가 발견한 사항 입니다.
특이사항으로는 다음의 공통점이 있습니다.

  1. iDrac이 달려 있는 Dell server (R610 제품군..)
  2. iDrac이 public IP로 설정 되어 있음

증상은 다음과 같습니다.
  1. CPU nice가 100% 사용 됨. (Nice는 shell의 nice를 의미하며, nice 우선권이 높은 cpu time을 말하므로, CPU usr 사용량이 100%라고 봐도 무방합니다.)
  2. find 명령을 실행하면 무조건 'file not found'
  3. ls 실행시에 astrik(*)가 처리되지 않음.
일단, 증상 2,3으로 보아 직감적으로 cracking을 당한것으로 보였고, hidden process를 처리하는 rootkit이 실행이 된 것으로 판단하여 시스템을 뒤지기 시작했으며, 보통 hidden process 처리는 kernel module이나 library preload를 이용해서 부팅시에 처리하므로 다음의 단계로 확인을 해 보았습니다.

  1. rpm -Va 명령으로 변조된 binary file 여부 확인
  2. /etc와 /boot 의 모든 파일 검사
    1. rc.local 에서 다음의 내용 확인

      nohup /bin/_-pud 111.111.111.111 >/dev/null&
      nohup /bin/_-minerd -c /bin/_-config 2> /dev/null&

      /bin/_-pud
      /bin/_-minerd
      /bin/_-config
      /usr/bin/_-minerd

    2. 111.111.111.111:8080 으로 접근해 보면 "mining server online" 라고 뜸. 아마 bit coin 채굴 사이트가 아닐까 의심
    3. 이 프로세스 kill 후 CPU nice 정상화 됨
    4. /etc/ld.so.preload 에 libncom.so.4.0.1 등록된 것 확인
    5. /lib64/libncom.so.4.0.1 이 어느 패키지에도 포함되지 않은 것 확인
      1. /etc/ld.so.preload 제거
      2. /lib64/libncom.so.4.0.1 제거
      3. reboot
    6. find 동작과, ls 시에 astrik 처리 안되는 문제 해결 됨

iDrac과 _-pud로 검색을 해 보면, 2015는 9월말 경에 이 경우와 동일한 건이 1건 검색이 됩니다. 여기서는 iDrac의 firmware의 버그 때문이다는 의견과, iDrac의 암호 관리 때문이다 (모두 iDrac이 public IP로 셋팅되어 있는 경우이네요)라는 의견이 있습니다.
  • http://stackoverflow.com/questions/32536518/i-cannot-start-qemu-kvm-on-a-centos-6-server
  • http://www.webhostingtalk.com/showthread.php?p=9534226

일단, 이 시스템도, iDrac에 접근한 로그는 확인이 되었는데, iDrac에서 OS영역으로의 cracking을 어떻게 했는지에 대해서는 아직 확인이 되지 않았습니다. 뭐 또 제가 hacking이 주영역이 아니다 보니.. 확인하기도 좀 귀찮고.. :-)

위의 내용 참고 하시기 바랍니다. 관련 시스템들은

R610  iDrac enterprise 6 firmware 1.99(2015.07) 입니다.
2015/11/04 16:46 2015/11/04 16:46
김정균

오늘 동일한 증상을 또 확인하여, 분석해 본 결과, iDrac6 에 보안홀이 있고, 여기서 root console을 이용하여 OS로 접근을 한 것이네요.

iDrac6 사용자는 firmware를 2.80 이상으로 업데이트 해야 합니다.

현 시점 최신은 2.85 입니다.

http://www.dell.com/support/home/kr/ko/bsdt1/Drivers/DriversDetails?driverId=J7YYK

보안홀 관련 수정 사항은 2.80 changelog 에서 확인할 수 있습니다.

http://www.dell.com/support/home/kr/ko/bsdt1/Drivers/DriversDetails?driverId=9Y5XD

highjacking을 하는 libncom 에 대해서는 https://packetstormsecurity.com/files/99782/Ncom-Libcall-Hijacking-Rootkit.html 를 참조 하세요.

Posted
Filed under Tech/안녕리눅스
* 참고: 이글의 코멘트로 진행 사항이 계속 업데이트 되고 있습니다.

안녕리눅스 3 소식이라고 10개월 전에 올려놓고 금방 나올것 처럼 포스팅을 했습니다만, 역시나 공수표가 되고 말았습니다.

2015년 한해가 제게는 완전히 고난의 해 이군요. 2015년의 키워드는 '배신'이며, 제 인생에서 지워버리고 싶을 정도로 엄청난 일들을 겪었고, 또 현재 진행형 입니다. 그러다 보니 안녕리눅스 개발 역시 뒷전이 되고 말았습니다.

현재 안녕 리눅스 3의 개발 단계는 기본 패키징은 완료된 상태이며, kickstart 설치 테스트를 하고 있습니다. RHEL의 설치 프로그램인 anaconda 역시 systemd의 도입으로 많이 변경된 관계로 테스트가 꽤 많이 필요하네요.

앞으로의 남은 작업은 다음과 같습니다.

  1. kickstart 설치 정리
  2. systemd 관련 daemon package 정리
  3. KLDP system에 적용 및 테스트
  4. Release
단계상으로는 얼마 안남은 듯 싶은데, 현재 진행형인 제 개인사가 어떻게 방해를 하지 몰라서 일정은 감히 언제 된다고 하기는 힘들 것 같습니다. 하지만 8월 말 부터 계속 꾸준하게 저녁 시간을 할애해서 작업이 진행되고 있으며, 아마도 올해 안에는 공개가 가능하지 않을까 싶습니다.

공개는 일차적으로 RHEL의 패키지를 수정한 base repository를 공개할 수도 있을 듯 싶습니다.
2015/10/07 00:56 2015/10/07 00:56
김정균

https://open.kldp.org 가 안녕 리눅스 3으로 migration 되었습니다. migration을 하면서 apache의 http 2 protocol 지원 문제를 해결 하였고, JAVA 환경에 대한 fix가 있었습니다.

그리고, 안녕 리눅스 패키지 일람이 완성 되었습니다.

https://joungkyun.gitbooks.io/annyung-3-user-guide/content/AnNyung3-Package-Catalog.html

이제 안녕 리눅스 운영에 대한 문서만 완성하면, 안녕 리눅스 3 GA 선언이 가능할 것 같습니다.

김정균

여전히 삽질 중입니다. :-)

apache 2.4.17 부터 mod_http2를 지원하여, apache는 2.4.18로 올려 놓았는데, 어제부터 테스트를 해 본 결과 mod_http2가 동작을 하지 않더군요.

결국에는 문제가 mod_http2가 openssl 1.0.2에서 지원하는 ALPN 을 이용하여 서비스를 하고, CentOS7의 openssl은 이를 지원하지 않는 다는 것이 문제점 입니다.

그리고, Major browser들이 NPN을 이용한 h2 protocol을 depcreated 시킨 것도 문제고요. 인터넷상에서 보면 chrome의 경우에는 다시 NPN을 지원한다고 하였으나, 여전히 48에서는 지원을 하지 않고 있습니다.

그래서 혹시 누군가가 openssl 1.0.1에 ALPN을 backport 하지 않았을까 하여 열심히 검색해 본바 찾을 수가 없더군요. --;

고민에 고민을 하다가 (수정했다가 관리해야 할 패키지가 늘어나는 관계로.. --;) 결국 openssl 1.0.1에 ALPN을 backporting 하여 패키지룰 추가하고, 이 openssl로 httpd를 rebuild하여 mod_http2가 동작을 하게 해 놓았습니다.

엉뚱한데서 계속 시간을 잡아먹네요 --;

openssl-1.0.1e-51.an3.2.x86_64
httpd-2.4.18-2.an3.x86_64

버전이 설치 되어 있어야 mod_http2가 동작 합니다.

P.S.
아 깜빡.. 설치 가이드가 완성 되었습니다.

https://www.gitbook.com/book/joungkyun/annyung3-installation-guide/details

김정균

마지막으로 문제가 되었던 php7 libevent extension 문제 해결(https://github.com/php/pecl-event-libevent/pull/2)과 GeoIP kernel module이 제대로 동작하지 않는 bug를 해결하고 드디어 package freeze 상태로, 설치 테스트를 하고 있습니다. package freeze 상태란, package-version-release.an3.x86_64.rpm 이라는 패키지가 파일 이름 그대로 rebuild가 되는 일이 없을 거라는 의미입니다. 변경 사항이 있으면 무조건 version 업데이트가 된다는 의미입니다. (금일 까지는 동일한 파일이름으로 pcakage가 rebuild 된 경우가 있었습니다.)

일단, 설치 테스트를 하면서 설치 문서를 만들고 있으며, 이 작업이 완료가 되면, Beta 선언을 할 예정이고, open.kldp.org에서 동작하는 서비스들을 AnNyung3으로 migration하여 실테스트 에 들어간 이후 문제가 없으면 GA 선언을 할 예정입니다. 이 작업은 대략 2월 말 정도까지 걸릴 것으로 예상이 됩니다.

김정균

* 2016.01.15 작업 완료

- php 7.0.2 update + official bug fix
- php56 5.6.17
- httpd event mpm 동작 안하는 문제 fix. 기본 MPM을 event 로 변경. php 환경은 mod_php 보다 php-fpm을 사용하는 것을 권장. php56은 mod_php 지원하지 않고 php-cli/php-fpm 만 지원
- php subpackage 중 이름이 php-xxx 에서 php-pecl-xxx 로 변경된 것 다수

* 다음 진행할 작업

- 서비스 환경에 투입하여 동작 확인
- 설치 문서 및 기타 문서 작업
- GE 선언

김정균

2015-12-22 마지막 커멘트 후 소식이 뜸했습니다. :-)

현재 안녕 3의 php 5.6을 php 7 로 변경을 했습니다. 기존의 php 5.6은 php5 package(기본 패키지 아님)으로 지원할 예정이며, php7과의 공존을 위하여 php5-cli와 php5-fpm만 지원할 예정입니다.

현재 남은 작업은 다음과 같습니다.

1. php7 용 3rd party 확장 migration (oauth/sqlrealy)
2. php5 package 제작
3. 안녕 3 실환경 migration 테스트 (http://open.kldp.org ..)
4. 문서 작성 및 GE 선언

node-js와 mongodb 관련은 릴리즈가 너무 지연이 되어 GE 선언 이후로 미루기로 결정했습니다.

김정균

현재 PHP 7 반영을 하고 있는데, 여기서 의외의 복병을 만나 시간을 잡아 먹고 있습니다.

기존 char * 형식으로 사용하던 변수들이 php 7로 오면서 zen_string 이라는 구조체를 사용하게 되었고, 이로 인하여, 기존의 patch에서 이를 다 변경해야 하는 이슈가 발생하네요.(패키들을 거의 새로 다시 작성 해야 한다는 --;) 그리고 기존의 third party extension들도 다 php 7 API로 변경을 해야 하는 문제가 발생하네요. 아쉽게도 시간이 조금 더 소요가 될 것 같습니다.

아직도, php 5.6 으로 갈것이냐 php 7로 갈것이냐가 갈등의 요지이네요 --;

김정균

RHEL 7.2 update pakcage의 변경 사항 반영이 완료 되었습니다.

php 7 작업과 문서 작업 후 beta release 예정 입니다. (fix된 날자는 아직.. ^^) beta release는 open.kldp.org 서버를 an3로 업데이트 후에 re-pack된 패키지들에 문제 여부를 확인 후 GA 선언 예정 입니다.

김정균

RHEL 7.2의 package 버전 의존성과 RHEL 7.2와 EPEL package와의 충돌 (안녕 3은 기본으로 EPEL을 포함하고 있습니다.) 때문에 CentOS 7.2 release를 기다리고 있어 릴리즈가 좀 늦어지고 있습니다.

기다리면서, php 7.0 도입을 아주 심각하게 고민하면서 일단 시도를 해 보고 있습니다.

김정균

어흑.. RHEL 7.2 가 나오고 말았네요. ....

rebuild 해야될 패키지들이 꽤 있습니다. 조금 더 딜레이 되겠군요.

release 까지의 남은 job list는 다음과 같습니다.

1. PHP 7 upgrade (할까 말까 고민중입니다만, 작업은 하고 있습니다.)
2. nodejs를 4.x로 할지 5.x로 할지 고민 중
3. RHEL 7.2 변경 사항 rebuild

이 작업이 끝나면 배포본 작업은 완료된 상태로 다음의 job list가 남습니다.

1. 문서 작업
2. 실전 투입(KLDP 서버중 하나..)하여 버그 테스트

이 과정을 마치면 정식 릴리즈가 될 예정입니다. 문서 작업이 완료되는 대로 일단 beta 오픈은 가능할 것 같습니다. RHEL 7.2가 release 변수를 만들어 버리네요 ^^;

김정균

이 글을 포스팅한지 한달 정도가 지났고, 현재 진행 상태를 공유 합니다.

일단, 제가 회사를 퇴사하여 백수가 된 상태라 시간이 많이 나게 되었습니다. 물론 쉬는 동안에 육아를 하고 있으므로, 아주 많이는 아닙니다. :-) 현재 12월 중 release를 목표로 달리고 있습니다만, 테스트 machine이 부족한 것이 흠이네요 ^^;

일단, 설치 테스트는 완료 되었습니다. 문서만 만들면 안녕 3설치는 가능합니다. 다만, RHEL 7부터 systemd 를 도입함으로서 설치 installer 가 많이 변경이 되어, 안녕 2 보다 설치는 타이핑을 좀 많이 해야 한다는 단점이 있습니다. --;

현재 남은 작업은 다음과 같습니다.

1. 몇몇 3rd party packaging
. sendmail - systemd 처리
. redis - memcached 처럼 init script로 process 여러개 관리 할 수 있도록
. proftpd - systemd 처리
. tomcat - systemd 처리
. l4vip - systemd 처리
. nodejs - version 4 upgrade
. httpd nis/ntlm 모듈 재작성 (apache 2.4부터 인증 모듈 변경)

2. 알려진 bug 수정
. /etc/login.def.exception 반영 안되는 문제 ( shadow-utils)
. jfbterm 에서 한글 입력 안되는 문제 (출력은 문제 없음)

1번 작업은 11월 안에 완료가 될 것 같고, jfbterm과 nodejs 만 빼면 12월 중에 안녕 3 릴리즈는 가능할 것 같습니다.

일단 재취업은 안녕 3릴리즈 후로 생각하고 있으므로, 안녕 3 릴리즈에는 매진을 할 수 있을 것 같습니다.