뭘 이런걸..

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