우분투 10.04 + phpLiteAdmin 에서 SQLCipher 사용.
탐구생활/OthersphpLiteAdmin 은 sqlite 의 웹 어드민 툴로서 phpMyAdmin 에 익숙하다면 눈이 번쩍 뜨일만한 물건이다.
이름부터 비슷하다. 사용법도 아주 유사하다.
게다가 단일 php파일 하나로 되어있어 별다른 설치 없이 웹서버에 올리고 디렉토리에 쓰기 권한만 설정하면 동작한다.
SQLCipher 는 sqlite3 위에 OpenSSL 기반의 암호화를 지원하는 라이브러리이다.
PRAGMA key = 'password' 명령을 실행한 뒤 이후 입력되는 테이블, 필드 정보는 모두 인코딩되어 저장된다.
설정된 암호의 변경은 PRAGMA rekey = 'newpassword' 명령으로 처리할 수 있다.
문제는, 기존에 만들어진 암호화되지 않은 DB파일에 암호를 설정하는 기능이 없다는 것.
때문에 phpLiteAdmin 같은 sqlite 어드민 툴에서 작업한 내용을 적용하려면, 적절한 형식으로 출력한 뒤 다시 암호화된 DB파일에 밀어넣어주어야 한다. 적어도 기본 암호라도 설정할 수 있게 해주면 이후 이 파일의 키값만 새로 지정하는 방식으로 작업할 수 있을텐데...
뭐 DB설계에 경험이 많다면야 이런 도구 없이도 좋은 스키마를 쭉쭉 뽑아내겠지만, 눈으로 봐야만 뭔가 만들 수 있는 나같은 놈에겐 다른 나라 이야기.
안되면 되게 한다. 삽질은 그래서 의미를 가지지.
먼저 우분투의 php5에서 sqlite 를 사용할 수 있게 하자.
# sudo apt-get install php5-sqlite phpt-sqlite3
phpinfo()로 찍어보면 pdo_mysql, pdo_sqlite 가 설치되며 sqlite3 는 따로 설정되어있는 것을 볼 수 있다.
PDO
PDO support | enabled |
---|---|
PDO drivers | mysql, sqlite, sqlite2 |
pdo_mysql
PDO Driver for MySQL | enabled |
---|---|
Client API version | 5.1.61 |
pdo_sqlite
PDO Driver for SQLite 3.x | enabled |
---|---|
SQLite Library | 3.7.10 |
........
SQLite
SQLite support | enabled |
---|---|
PECL Module version | 2.0-dev $Id: sqlite.c 293036 2010-01-03 09:23:27Z sebastian $ |
SQLite Library | 2.8.17 |
SQLite Encoding | UTF-8 |
Directive | Local Value | Master Value |
---|---|---|
sqlite.assoc_case | 0 | 0 |
sqlite3
SQLite3 support | enabled |
---|---|
SQLite3 module version | 0.7 |
SQLite Library | 3.7.10 |
Directive | Local Value | Master Value |
---|---|---|
sqlite3.extension_dir | no value | no value |
phpLiteAdmin은 PDO, SQLite3, SQLiteDatabase 세종류의 모듈을 지원한다.
이 드라이버의 설정은 phpLiteAdmin.php 의 130번째 줄 근처의
define("FORCETYPE", false);
이 부분을 다음과 같이 수정해 강제로 설정할 수 있다.
define("FORCETYPE", "PDO");
또는
define("FORCETYPE", "SQLite3");
그런데 무슨 이유에서인지 이 부분을 SQLite3 로 설정하면 제대로 동작하지 않는다.
PDO 모듈을 써서 생성된 파일을 메모장에서 열어보면 다음과 같다.
앞부분에 보이듯 sqlite3 형식인 것으로 보아 PDO의 sqlite 가 sqlite3 를 기본으로 하는 것 같은데...
좀 더 확실히 하기 위해 ldd로 pdo_sqlite.so 의 dependency 를 살펴보자.
# cd /usr/lib/php5/20090626+lfs
# ldd pdo_sqlite.so
linux-gate.so.1 => (0x00bfe000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x007d5000)
libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0x00a98000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x002f4000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x0045e000)
/lib/ld-linux.so.2 (0x00e93000)
libcrypto.so.0.9.8 => /lib/i686/cmov/libcrypto.so.0.9.8 (0x00110000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0x00eb7000)
libz.so.1 => /lib/libz.so.1 (0x006ca000)
예상대로 libsqlite3.so 를 참조하고 있다.
phpLiteAdmin이 SQLite3 모듈로 잘 동작했다면 sqlcipher 를 기반으로 php5의 모듈을 재빌드해 올리기만 하면 될텐데 싶지만...
그래도 그나마 다행이다.
일단 sqlcipher 를 빌드하자.
# sudo apt-get install tcl tcl-dev libssl libssl-dev
# git clone git://github.com/sqlcipher/sqlcipher.git
# cd sqlcipher
# ./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto"
# make
윈도에서 빌드는 개삽질인데, 리눅스에서는 TCL만 깔아주면 한방에 끝나네~~
이제 pdo_sqlite.so 가 참조하는 라이브러리를 /usr/local/lib 에 생성된 libsqlite3.so.0.8.6 로 바꿔주면 되는데,
어차피 sqlcipher는 sqlite3의 모든 기능을 가지고 있고 테스트머신에 이런저런 신경쓰기도 귀찮아서 그냥 /usr/lib 에 복사해 버렸다.
# sudo cp /usr/local/lib/libsqlite3.so.0.8.6 /usr/lib/
내친김에 기존의 sqlite3 모듈도 새로 만들어 넣어두자. sqlcipher 홈페이지에 잘 설명되어있으니 그대로 따라하면 된다.
다만 php-5.4.0/ext/sqlite3 소스에 config.m4 파일이 config0.m4 로 되어있으니 phpize 전에 이 이름을 바꿔주는 것만 신경쓰자.
이렇게 만들어진 sqlite3.so 를 apt-get 으로 설치한 /usr/lib/php5/20090626+lfs/sqlite3.so 와 교체해주고 아파치를 재구동하면 완료.
남은 문제는 phpLiteAdmin에서 언제, 어떻게 기본 암호를 설정해주느냐 하는 것.
여기저기 살펴보니 660줄 근처에 Database class 에 정의된 쿼리에 대한 래퍼함수가 눈에 띈다. 이 함수 도입부분에 다음 코드를 추가하자.
........
//generic query wrapper
public function query($query, $ignoreAlterCase=false)
{
$this->db->query("PRAGMA key = '1234';");
if (strtolower(substr(ltrim($query),0,5))=='alter' && $ignoreAlterCase==false) // ......
........
이제 수정된 phpLiteAdmin을 우분투의 아파치에서 접근할 수 있게 해주고 DB파일을 만들어보자.
생성된 DB파일을 열어보면 알아볼 수 없도록 암호화되어 저장된 것을 알 수 있다.
스키마 설계 및 기본정보 입력이 마무리된 파일은 나중에 "PRAGMA rekey" 명령으로 새 암호를 할당해 배포하면 됨.