삽질하는플머

우분투에 IRC서버 설치후 닉네임 길이와 동접자 조절.

이런저런잡다구리/LinuxHeaven

심플즈 팁란에 올렸던 글... 갑자기 쓸 일이 생겨 옮겨둠. 

http://simples.kr/28949



얼마전 게임채팅에 써먹어볼까 싶어 우분투에 IRC 서버를 까느라 삽질한 내용이 있어서 함 올려봅니다. 

일단 ircd는 ircu 를 사용하기로 했습니다. 설치는 간단히 이렇게..


$ sudo apt-get install ircd-ircu



문제는 여기서부터인데, 닉네임의 최대값이 12자로 되어있군요. 저는 30자가 필요. 

설정 문서에 나온대로 /etc/ircd/ircd.conf 내에 features 안에 다음라인 삽입해 봤습니다. 


features {

 .....

 "NICKLEN" = "30";

};



하지만 이 설정은 ircd-ircu 의 소스중 ircd_def.h 에 정의된 값을 넘을 수 없습니다. 

여기에는 15로 정의되어있기 때문에 아무리 30자를 때려줘도 넘어가지 않지요. 


패키지로 설치한 ircd-ircu 는 지워버리고 소스를 받아 수정해봅시다. 


일단 컴파일 환경을 만들어주고


$ sudo apt-get install build-essential flex autoconf  bison



소스를 내려받아 압축을 풀어줍니다. 


$ wget http://prdownloads.sourceforge.net/undernet-ircu/ircu2.10.12.12.tar.gz

$ tar xzf ircu2.10.12.12.tar.gz

$ cd ircu2.10.12.12



여기서 ./include 안의 ircd_defs.h 에서 NICK_LEN 값을 30으로 수정해줍니다. (41번째 줄)


#define NICKLEN         30



이제 다음과같이 해 주면 닉네임을 30자로 쓸 수 있는 데몬을 얻을 수 있습니다. 


$ ./configure

$ make all



../bin 에 컴파일된 ircd 실행파일이 들어갑니다. 이제 이놈의 버전을 출력해봅시다. 


$ ./ircd -v 

ircd u2.10.12.12

Event engines: epoll_*() poll()

Compiled for a maximum of 1020 connections.



최대접속자가 1020으로 되어있습니다. 아쉬움이 있지요. 

이 내용은 ./configure 실행시 생성되는 config.h 에 기록되며, 

이 때 사용되는 configure.in 을 살펴보면 다음과 같은 값을 받아오도록 되어있습니다. 


ulimit -Hn



한마디로 시스템에서 열 수 있는 파일갯수를 의미하지요. 

sudo ulimit -n 4096 해주면 이 값이 바뀝니다만 재부팅하면 도로묵이죠. 

예전에는 이 값을 늘려주려면 커널을 새로 컴파일해야 했나본데... 전 리눅스 뉴비라 그런건 모르고...

/etc/security/limits.conf 에 다음항목 추가한 뒤 재부팅해봅시다.  


*               hard    nofile            4096

*               soft    nofile            4096



이제 ircd-ircu 를 재컴파일하면 최대접속자수가 늘어난 것을 볼 수 있습니다. 


마지막으로 닉네임에서 한글사용문제... 원래 irc 규정이 닉네임에서는 한글을 못써먹게 되어있습니다. 

한글 패치된 데몬들은 규격외의 물건들인 셈이죠. 

table_gen.c 를 들여다봅시다. 

116번 줄에보면 NTL_RICNK 의 속성을 설정하는 부분이 보입니다. 


moveMacro(NTL_DIGIT | NTL_ALPHA, NTL_IRCNK);

markString(NTL_IRCNK, "-_`");



숫자, 알파벳, 그리고 " - _ ` " 를 추가해주고 있지요. 따라서 여기에 " + / " 를 추가하면 UTF-7 사용이 가능해집니다.


markString(NTL_IRCNK, "-_`+/");



사실 이것도 "+/" 때문에 규약을 어기는 건 마찬가지네요. ㅠㅠ;;

UTF-8이면 더 좋겠지만 어차피 게임내에서 자체 클라를 제공하기 때문에 일단 이정도로 만족하고 있습니다. 


우분투 10.04 + phpLiteAdmin 에서 SQLCipher 사용.

탐구생활/Others

phpLiteAdmin 은  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 supportenabled
PDO driversmysql, sqlite, sqlite2

pdo_mysql

PDO Driver for MySQLenabled
Client API version5.1.61

pdo_sqlite

PDO Driver for SQLite 3.xenabled
SQLite Library3.7.10

........

SQLite

SQLite supportenabled
PECL Module version2.0-dev $Id: sqlite.c 293036 2010-01-03 09:23:27Z sebastian $
SQLite Library2.8.17
SQLite EncodingUTF-8

DirectiveLocal ValueMaster Value
sqlite.assoc_case00

sqlite3

SQLite3 supportenabled
SQLite3 module version0.7
SQLite Library3.7.10

DirectiveLocal ValueMaster Value
sqlite3.extension_dirno valueno 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

# sudo make install



윈도에서 빌드는 개삽질인데, 리눅스에서는 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" 명령으로 새 암호를 할당해 배포하면 됨. 



phpliteadmin.7z


모노 2.10 설치. MySql 연결 테스트.

여가생활/Unity,Mono&.Net

시작은 유니티였는데... 옆길로 참 많이 새고 있다. 


굳이 이런 시도를 해보는 이유는? 모노가 WCF를 지원하고 있다는 것에 눈이 번쩍 띄었기 때문이다. 

현재 XMLRPC+PHP로 DB를 호출하고, 이 PHP를 HipHop으로 빌드해 바이너리로 서비스하는 방식을 쓰는 중인데...

닷넷으로 WCF 서비스를 만들고 델파이로 접근해 사용하도록 바꿔준다면 손도 편하고 머리속도 간단해지니까. 

게다가 C#은 디버깅도 되잖아? 디버거 없이 날코딩하는 PHP같은 인터프리터 언어는 나이가 먹을수록 부담스러워~~


기왕에 삽질할 꺼면 모노 2.8 이상을 설치해 새 바닥에서 놀자. 


우분투에 모노 2.10 설치는 트위터의 @nbridgewater 님이 작성한 스크립트를 쓰면 한방에 해결. 

중간 중간에 sudo 암호만 넣어주면 된다. 시간은 좀 오래 걸림. 


http://www.integratedwebsystems.com/2011/02/mono-2-10-install-script-for-ubuntu-fedora/


# wget --no-check-certificate https://github.com/nathanb/iws-snippets/raw/master/mono-install-scripts/ubuntu/install_mono-2.10.sh

# chmod 755 install_mono-2.10.sh

# ./install_mono-2.10.sh



위치는 /opt/mono-2.10 에 설치된다. 다음과 같이 윈도에서 #Develop 로 작성한 .Net 4.0 바이너리를 실행시킬 수 있다. 


# /opt/mono-2.10/bin/mono ./test.exe

Hello World!

#



MySql의 닷넷용 커넥터는 MySQL 에서 직접 개발 및 배포하고 있다. 라이센스는 GPL. 

http://dev.mysql.com/downloads/connector/net/


현재 버전은 6.5.4 이다. 일단 윈도용을 내려받아 설치하자. 







#Develop 에서 mysql-test 솔루션을 시작한다. 프로젝트 탐색기의 "참조" 에서 우측키를 누른 뒤 "참조 추가" 메뉴를 클릭하자. 

GAC 탭에서 "MySql.Data" 를 선택한 뒤 "확인"을 눌러준다. 




http://www.mono-project.com/MySQL 에 MySql 에 접근하는 좋은 예제가 있다. 

int형 ID와 varchar형 Name 을 필드로 가지는 테스트용 DB에 접근하는 코드를 다음과 같이 만들어주었다. 


using System;
using System.Data;
using MySql.Data.MySqlClient;

namespace mysql_test
{
    class Program
    {
        public static void Main(string[] args)
        {
            string connectionString =     
              "Server=hostname;" +
              "Database=test;" +
              "User ID=user;" +
              "Password=password;" +
              "Pooling=false";
            
            IDbConnection dbcon;
            dbcon = new MySqlConnection(connectionString);
            dbcon.Open();
            IDbCommand dbcmd = dbcon.CreateCommand();
            
            string sql =
               "SELECT ID, Name " +
               "FROM test";
            
            dbcmd.CommandText = sql;
            IDataReader reader = dbcmd.ExecuteReader();
            while(reader.Read()) {
                int ID = (int) reader["ID"];
                string Name = (string) reader["test"];
                Console.WriteLine("Data: " + ID + " " + Name);
            }
            // clean up
            reader.Close();
            reader = null;
            dbcmd.Dispose();
            dbcmd = null;
            dbcon.Close();
            dbcon = null;

            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}

(#Develop 에서 코드를 복사해 블로그에 붙여넣으면 하이라이팅이 그대로 살아있네~ 좋다!!)



실행시켜보면 자알~ 동작한다. 





이제 모노의 GAC에 MySql 라이브러리를 설치해보자. http://dev.mysql.com/downloads/connector/net/ 에서 ".Net & Mono" 를 선택한 뒤 "mysql-connector-net-6.5.4-noinstall.zip" 파일을 다운받아 압축을 푼다. 이 압축파일에 포함된 dll은 모두 소문자로 되어있지만 GAC에 등록하기 위해서는 실제 C#에서 참조할 때와 동일하게 대소문자를 맞춰주어야 한다는 것에 주의!


# cd mysql-connector-net-6.5.4-noinstall/

# cd v2

# cp mysql.data.dll MySql.Data.dll

# sudo /opt/mono-2.10/bin/gacutil -i MySql.Data.dll
 Installed MySql.Data.dll into the gac (/opt/mono-2.10/lib/mono/gac)


윈도에서 작성된 바이너리를 옮겨와 다음과 같이 실행시켜보자. 


/opt/mono-2.10/bin/mono ./mysql-test.exe



결과는 짜잔~




덤으로, 앞에서 작성한 CS 코드를 우분투에서 직접 빌드하려면 다음과 같이 하면 된다. 

/opt/mono-2.10/bin/mcs mysql-test.cs  -r:System.Data.dll -r:/opt/mono-2.10/lib/mono/gac/MySql.Data/6.5.4.0__c5687fc88969c44d/MySql.Data.dll


당연한 이야기지만, 이렇게 빌드한 실행파일도 윈도에서 잘 돌아간다. 



크로스 플랫폼으로서의 모노...

여가생활/Unity,Mono&.Net
유니티 얘기하다가 왜 뜬금없이 모노냐고? 취미는 중간에 샛길로 빠지는 맛에 즐기는 거거덩.

오래전 셀빅이라는 물건이 대한민국 PDA의 대명사이던 시절, 
도스나 윈도 이외의 플랫폼이 주는 상큼 발랄했던 청량감은 내게 오랫동안 잊기 힘든 깊은 자욱을 남겼고
그때문인지 발은 윈도에 묶여있으면서도 마음은 항상 다른 플랫폼을 지향하며 살게 된 듯 하다. 

시스템 잡동사니 -> 게임클라이언트 -> 게임서버 프로그래머의 삶을 살아가는 입장에서 
네이티브 바이너리가 아닌 자바나 닷넷은 쉽게 경험하기 힘든 영역이었다. 
그러다보니 머리가 꽉꽉 막혀버려서 뻘생각과 잡짓을 삶의 낙으로 삼으면서도 보수적인 생각에서 한치도 벗어나지 못했는데
유니티 덕분에 모노디벨롭과  SharpDevelop(귀찮으니 앞으로는 #Develop 이라고 쓰자) 을 설치하고
초보수준이지만 C#을 건드리면서 저절로 튀어나온 탄성!!
야~! 이거 신세상이네~~!! 

어쩌면 모노는 내가 그리도 찾아 해메던 크로스 플랫폼에 대한 종착점이 아닐까 하는 생각까지...
거기에 모노 2.6 부터는 LLVM도 지원하지.
LLVM 의 자바스크립트 백엔드인 emscripten 의 강력함을 생각하면
네이티브 바이너리에 대한 집착을 버려야 할 시점이 생각보다 빨리 올지도 모르겠다. 

아무튼 똥인지 된장인지 알려면 일단 찍어먹어 봐야지.

테스트용으로 구동중인 우분투 10.04 서버에 모노를 설치하자. 
2.8을 설치하면 .Net 4.0 도 지원한다고 하지만... 뭐 나중에 병렬 프레임웍을 사용할 때나 해보고~
나와라~ apt-get~~!!!

sudo apt-get install mono-1.0-gac mono-2.0-gac



이제 #Develop 에서 C#으로 콘솔 응용 프로그램을 하나 만들자. 



모노 1.0과 2.0을 깔았으니 .NET Framework는 4.0이 아닌 3.5!!! 로 설정한다. 

자동으로 만들어지는 Hello World 밑에 한글이 UTF-8 로 잘 빠지는지도 확인할 겸 적절한 메시지를 하나 더 출력하자. 

using System;

namespace console_test
{
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine("우하하하!!");
            
            Console.Write("Press any key to continue . . .\n");
            Console.ReadKey(true);
        }
    }
}


 
윈도에서 실행시킨 화면은 



생성된 console.exe 파일을 리눅스로 옮겨서 돌려보면




정말 세상 좋아졌네.


은양의 프로그래밍 세상에서 C# 서버 코드를 참고, 전송된 바이트값을 바로 리턴하는 간단한 에코서버를 만들었다. 
우분투로 옮기고 실행시킨 뒤 텔넷으로 접속해보니 아주 잘 동작한다. 



이거 짭짤한데~??


내친김에 가상머신에 코분투 10.04 를 설치했다.
데스크탑 폰트는 나눔고딕으로 맞춰주었고 mono-2.0-gac 가 이미 깔려있는 상태. 
여기에 윈폼을 돌리려면  mono-winforms 패키지를 추가로 설치해주어야 한다. 

sudo apt-get install mono-winforms-a11y 




#Develop 에서 간단한 윈폼기반의 실행파일을 하나 만들어 본다. 

 

이 실행파일을 방금 설치한 따끈따끈한 코분투로 이동시킨 뒤 돌려보자. 두근두근~~



첫술에 배부를까마는... 폼 타이틀을 제외한 나머지 글자들이 모두 깨져버린다. 
실망감은 잠시 미루고, 찬찬히 뜯어보면 네모로 표시된 글자의 갯수가 윈도에서 찍으려던 한글의 갯수와 동일하다.  
즉 이것은 유니스크라이브 때도 지겹게 겪었던 폰트문제...

코분투에서 윈폼에 인식된 기본폰트와  다이얼로그 폰트를 다음 코드로 찍어보았다. 

            MessageBox.Show(SystemFonts.DefaultFont.Name);
            MessageBox.Show(SystemFonts.DialogFont.Name);



결과는 "DejaVu sans".
영문폰트라 한글이 없으니 네모로 치환된 것이겠지. 폰트 폴백도 자동으로 되면 좋겠지만... 흠냐리... 

다행히 예전에 링크해 둔 우분투 글꼴 설정에 대한 블로그가 떠올랐다. 
http://anothertimes.tistory.com/22
 

/etc/fonts/conf.d/69-language-selector-ko-kr.conf 에서 sans 구성의 DejaVu Sans 를 아예 날려버리고 나눔고딕만 남겨두자. 

                 <edit name="family" mode="prepend" binding="strong">

                        <string>DejaVu Sans</string> // 이 라인 삭제
                        <string>NanumGothic</string>
                </edit>



재부팅 후 다시 돌려보면 짜잔~~

 

글자 크기가 조금 작은게 불만이네~ 이건 다음에 심심할 때 또 다뤄보자~~