2010年8月5日 星期四

Gitosis HOWTO

話說git的傳輸協定有許多種, 包括ssh://, http(s)://, git://, file:///, 但若小規模的專案, 透過ssh進行傳輸與驗正式最方便的, 而若是要有集中式的權限管理, 靠gitosis就對了, 以下說明一下安裝過程...

出場角色: git-server, git-client-foo, git-client-bar

在git-server下載gitosis.git
[git-server]$ cd ~
[git-server]$ git clone git://eagain.net/gitosis.git
[git-server]$ cd gitosis
[git-server]$ sudo python setup.py install

在git-server新增git使用者
[git-server]$ sudo useradd git

在git-client-foo上產生foo使用者的公鑰
[git-client-foo]$ ssh-keygen -t rsa

將foo以rsa產生的公鑰(id_rsa.pub)交到git-server, 假設儲存在/tmp下 (via scp/ftp/email...)

在git-server初始化gitosis
[git-server]$ sudo -H -u git gitosis-init < /tmp/id_rsa.pub
Initialized empty Git repository in /home/git/repositories/gitosis-admin.git/
Reinitialized existing Git repository in /home/git/repositories/gitosis-admin.git/

在不同distribution的linux下可能會遇到這樣的問題 (CentOS 5.4, 用source裝的git)
Traceback (most recent call last):
...
File "/usr/lib/python2.4/subprocess.py", line 993, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

解決方法是將原來的一步拆成兩步, 並且確定git使用者的環境變數有git指令
[git-server]$ sudo -H -u git -s
[git-server]$ gitosis-init < /tmp/id_rsa.pub



在git-server修改權限
[git-server]$ sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update
現在foo@git-client-foo的使用者可以存取git-server的服務了...

測試foo@git-client-foo的登入是否正確
[git-client-foo]$ ssh git@git-server

如果出現錯誤訊息如
PTY allocation request failed on channel 0
ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
Connection to git.server closed.

表示git@git-server的無法以ssh登入shell, 但這是正常的. 但如果無法登入的錯誤訊息如
Agent admitted failure to sign using the key.
git@git-server's password:

則表示git-server和git-client的key交換有問題, 先在git-client檢查是否ssh agent有無啟動
[git-client-foo]$ ps aux|grep agent

在git-client-foo重新啟動ssh agent, 加入私鑰(id_rsa)幫忙代理
[git-client-foo]$ exec ssh-agent /bin/bash
[git-client-foo]$ ssh-add ~/.ssh/id_rsa
Identity added: .ssh/id_rsa (.ssh/id_rsa)

測試在git-client-foo上下載gitosis的repository
[git-client-foo]$ git clone git@git-server:gitosis-admin.git
Cloning into gitosis-admin...
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 0), reused 5 (delta 0)
Receiving objects: 100% (5/5), done.

查看一下目錄是否正確
[git-client-foo]$ cd gitosis-admin
[git-client-foo]$ ls
gitosis.conf keydir/

gitosis.conf是用來設定用戶、repository和權限的控制文件, keydir目錄則是保存所有具有讀取權限用戶公鑰的地方

比如我們想建立一個新的群組kernel team, 裡面的成員包括foo@git-client-foo和bar@git-client-bar, 此一群組可讀/寫的project為kernel_source, 另外想建立一個群組一樣是kernel team, 裡面的成員是foobar@git-client-foobar, 此一群組對kernel_source只有唯讀的權限, 參考權限設定如下
[group kernel-team-rw]
writable = kernel_source
members = foo@git-client-foo bar@git-client-bar

[group kernel-team-ro]
readonly = kernel_source
members = foobar@git-client-foobar

[repo kernel_source]
owner = foo@git-client-foo
description = kernel source development

若要印出更多存取過程的訊息, 可在gitosis.conf加入loglevel的等級
[gitosis]
loglevel = DEBUG

在git-client-foo存檔離開後, 先將用戶bar@git-client-bar的公鑰放在keydir目錄下. 而bar的公鑰產生方式與上述相同, 一樣假設先放到/tmp下, 名稱取為bar@git-client-bar.pub(需與gitosis.conf中使用者名稱相同)
[git-client-foo]$ cp /tmp/bar@localhost.localdomain.pub keydir/bar@git-client-bar.pub

修改過得資料需新增至暫存區(staged)並提交(commit)回local repository
[git-client-foo]$ git add .
[git-client-foo]$ git commit -am 'add new project kernel_source and new group kernel-source'
[master 168490e] add new project kernel_source and new group kernel-source
2 files changed, 5 insertions(+), 0 deletions(-)

上傳到git-server以交由git server管理
[git-client-foo]$ git push origin master
Counting objects: 8, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 839 bytes, done.
Total 5 (delta 0), reused 0 (delta 0)
To git@git-server:gitosis-admin.git
928edf2..537d576 master -> master
7f9546c..168490e master -> master

這時候foo@git-client-foo和bar@git-clinet-bar就可以存取kernel_source的repository, 例如
[git-client-bar]$ git clone git@git-server:kernel_source

由於git-server上的kernel_source repository上還是空的, 所以你有可能會出現這樣的警告訊息
Cloning into kernel_souce...
Initialized empty Git repository in /home/git/repositories/kernel_source.git/
warning: You appear to have cloned an empty repository.

在bar@git-clinet-bar下查看, 可以看到多了一目錄kernel_source, 表示已經加入群組無誤
[git-client-bar]$ ls
kernel_source

在bar@git-client-bar新增一文件測試寫入權限, 例如
[git-client-bar]$ cd kernel_source
[git-client-bar]$ vim README
[git-client-bar]$ git add .
[git-client-bar]$ git commit -am 'add README'

在push回git-server之前, 先增加一remote機器的名稱
[git-client-bar]$ git remote add origin git@git-server:kernel_source
[git-client-bar]$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 212 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@git-server:kernel_source
* [new branch] master -> master

以上是小型案子使用gitosis的設定方式, 由於工作模式有很多, 若開發人員不只是公司內部人員, 權限模式會比較複雜, 如果有心瞭解更細部的運作與各種工作模式, 先聽聽Scott ChaconRailsConf 2008做的演講, 而且一定要閱讀全世界講解git寫的最好的投影片, 或者是閱讀pro git的線上英文版, 中文版, 都是非常有幫助的

參考資料:
* How to setup a GIT server with gitosis and gitweb

2010年8月4日 星期三

SQLite on Android

這篇只是隨手紀錄一下, 未來還會再補充...

話說Android上的資料庫是採用SQLite, 指令當然跟我熟悉的MySQL有所不同, 比如說今天我要開啟某個資料庫, 東看西看不知道如何操作@@, 最後才發現在SQLite的shell下沒辦法切換資料庫(有錯請指正), 因此要直接開請打完整路徑, 如
# sqlite3 /path/to/sqlite/db

列出該資料庫下的所有資料表
sqlite>.tables

列出某資料表的schema
sqlite>.schema tablename

馬上看看有啥好康
sqlite>SELECT * FROM tablename;

離開
sqlite>.quit

寫一個能在Android執行的shell script(解除screen lock)
#!/bin/sh
sqlite3 /system/com.android.providers.settings/databases; "UPDATE "system" SET value='-1' WHERE name='screen_off_timeout';"
sqlite3 /system/com.android.providers.settings/databases; "UPDATE "secure" SET value='0' WHERE name='device_provisioned;"

而官方網站也提供GUI的參考資訊,最後我是採用wxSQLite+,支援Windows和GNU/Linux

2010年7月28日 星期三

[Tips] Change keyboard mapping

IBM鍵盤的上下左右鍵旁有兩個按鍵, 原本是設計往左往右, 可是我習慣使用Acer的鍵盤配置, 也就是這兩個鍵是PgUp和PgDn, 因此就需要作些小修改啦, 在Windows上, 有個好用的軟體AutoHotkey可以讓你自己撰寫script改變鍵盤對應, 而在Linux上, 就只要觀察實體鍵盤的代碼, 修改對應的key code即可, 廢話不多說, 筆記...
# xmodmap -e "keycode 166 = Prior"
# xmodmap -e "keycode 167 = Next"

相關的修改可參考keyboard/mouse mapping

2010年7月25日 星期日

[Tips] 常用的LAMP設定檔

安裝Linux+Apache+MySQL+PHP我的習慣順序就是照字面上的順序, 而安裝過程大部份是從source編譯, 有些library則是用套件管理程式先安裝好的, 使用的是RedHat/CentOS/Fedora Linux, 不同的Linux除了套件管理程式使用不同以外, 其他操作都是相同的(#開頭的是RedHat系列,$開頭的是Ubuntu系列), 以下開始筆記...

安裝libtool
# yum install libtool
$ sudo apt-get install libtool

安裝ltdl
# yum install libtool-ltdl
# yum install libtool-ltdl-devel
$ sudo apt-get install libltdl-dev

安裝gnutls
# yum install gnutls
# yum install gnutls-devel
# yum install gnutls-utils
$ sudo apt-get install libgnutls-dev

安裝openssl
# yum install openssl
$ sudo apt-get install openssl
$ sudo apt-get install libssl-dev

下載subversion-deps(ver. 1.6.12)
解壓縮subversion-deps到subversion目錄

安裝apr (with subversion source)
# cd {/path/to/subversion/src}/apr
# ./configure --prefix=/usr/local/apr
# make && make install && make clean

安裝apr-util (with subversion source)
# cd {/path/to/subversion/src}/apr-util
# ./configure --prefix=/usr/local/apr --with-apr=/usr/local/apr
# make && make install && make clean

安裝apr-iconv (ver. 1.2.1)
# ./configure --prefix=/usr/local/apr --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr
# make && make install && make clean

安裝pcre(配合httpd-2.3.x才需要)
# ./configure --prefix=/usr/local/pcre --enable-utf8
# make && make install && make clean

安裝httpd (ver. 2.2.16)
# ./configure --prefix=/usr/local/apache2 --enable-mods-shared=most --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr/bin/apu-1-config --enable-dav --enable-dav-fs --enable-dav-lock --enable-maintainer-mode --enable-unique-id --enable-speling --enable-deflate --enable-file-cache --enable-cache --enable-disk-cache --enable-mem-cache --enable-filter --enable-isapi --enable-mime-magic --enable-rewrite --enable-usertrack --enable-static-rotatelogs --enable-static-logresolve --enable-ssl --with-mpm=worker
# make && make install && make clean
# vim /usr/local/apache2/conf/httpd.conf
[add]
CustomLog "logs/access_log" combined
ServerTokens ProductOnly
ServerSignature Off
<Directory "/var/www/html">
AddDefaultCharset utf-8
Options FollowSymLinks
AllowOverride all
Order allow,deny
Allow from all
</Directory>
[/add]

note: 當要進行動態編譯modules時, 就不需要加上--enable-so
reference: apache動態編譯/靜態編譯問題

下載neon (ver. 0.29.3)
# tar zxvf neon.tar.gz
# mv neon {/path/to/subversion/src}

安裝libexpat (ver. 2.0.1)
# ./configure
# make && make install && make clean
# ln -s /usr/local/lib/libexpat.la {/path/to/subversion/src}/apr-util/xml/expat/lib

安裝subversion (ver. 1.6.12)
# ./configure --prefix=/usr/local/svn --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apr/bin/apr-1-config --with-apr-util=/usr/local/apr/bin/apu-1-config --with-ssl
# make && make install & make clean

設定https(openssl已安裝)
# openssl x509 -req -days 7 -in my.demo.csr -signkey my.demo.key -out my.demo.crt
# openssl genrsa -out my.demo.key 1024
# openssl req -new -key my.demo.key -out my.demo.csr
# vim /usr/local/apache2/conf/httpd.conf
Listen 443
<VirtualHost _default_:443>
ServerName localhost
SSLEngine on
SSLCertificateFile /usr/local/apache2/conf/ca/my.demo.crt
SSLCertificateKeyFile /usr/local/apache2/conf/ca/my.demo.key
</VirtualHost>

安裝mysql (ver. 5.1.49)
# ./configure --prefix=/usr/local/mysql --datadir=/usr/local/mysql/data --with-unix-socket-path=/tmp/mysql.sock --enable-assembler --with-big-tables --with-readline --with-ssl --with-charset=utf8 --with-extra-charsets=all --enable-thread-safe-client
# make && make install && make clean
# useradd mysql
# /usr/local/mysql/bin/mysql_install_db --user=mysql --no-defaults
# cp support-files/my-medium.cnf.sh /etc/my.cnf
# chown mysql:mysql /etc/my.cnf
# vim /etc/my.cnf
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld]
port=3306
socket=/tmp/mysql.sock
datadir=/usr/local/mysql/var
# chown -R mysql:mysql /usr/local/mysql/var
# cp /usr/local/mysql/data/mysql/mysql.server /etc/rc.d/init.d/mysqld
# chkconfig --add mysqld [Start As Service]
# service mysqld start
# /usr/local/mysql/bin/mysql -u root -p [ENTER]
mysql>UPDATE mysql.user SET password=PASSWORD('NEW_PASSWORD') WHERE user='root';
mysql>flush privileges;
mysql>exit

安裝libgpg-error (ver. 1.9)
# ./configure
# make && make install && make clean
$ sudo apt-get install libgpg-error-dev libgpg-error0

安裝libgcrypt (ver. 1.4.6)
# ./configure
# make && make install && make clean
$ sudo apt-get install libgcrypt11 libgcrypt11-dev

安裝libmcrypt (ver. 2.5.7)
# ./configure --enable-ltdl-install
# make && make install && make clean
$ sudo apt-get install libmcrypt4 libmcrypt-dev mcrypt

reference: http://bojack.pixnet.net/blog/post/3983596

安裝libxml (ver. 2.7.7)
# ./configure
# make && make install && make clean
$ sudo apt-get install libxml2 libxml2-dev

安裝curl (ver. 7.21)
# ./configure
# make && make install make clean

安裝t1lib
$ sudo apt-get install libt1-5 libt1-dev

安裝freetype (ver. 2.4.2)
# ./configure --prefix=/usr/local
# make && make install && make clean
$ sudo apt-get install libfreetype6 libfreetype6-dev

安裝libjpeg (ver. 8b)
# ./configure --prefix=/usr/local
# make && make install && make clean
$ sudo apt-get install libjpeg62 libjpeg62-dev

安裝libXpm (ver. 3.5.8)
# ./configure --prefix=/usr/local
# make && make install && make clean
$ sudo apt-get install libxpm4

安裝php (ver. 5.2.14)
# ./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache2/bin/apxs --enable-debug --enable-magic-quotes --enable-libgcc --enable-ftp --enable-mbstring --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --enable-sockets --with-gnu-ld --with-curl=/usr/local/lib --with-mcrypt=/usr/local/src/libmcrypt --with-zlib-dir=/usr/local/src/zlib --with-gd --with-t1lib --with-jpeg-dir=/usr/local --with-xpm-dir=/usr/local --with-freetype-dir=/usr/local --with-gettext
# make && make install && make clean
# cp php.ini-recommended /usr/local/php/lib/php.ini
# vim /usr/local/apache2/conf/httpd.conf
[add]
AddType application/x-httpd-php .php .phtml
DirectoryIndex index.php index.html
[/add]

測試gd
<?php
echo '<div style="margin: 10px;">';
echo '<p style="color: #444444; font-size: 130%;">GD is ';
if (function_exists("gd_info")) {
echo '<span style="color: #00AA00; font-weight: bold;">supported</span> by your server!</p>';
$gd = gd_info();
foreach ($gd as $k => $v) {
echo '<div style="width: 340px; border-bottom: 1px solid #DDDDDD; padding: 2px;">';
echo '<span style="float: left;width: 300px;">' . $k . '</span> ';
if ($v)
echo '<span style="color: #00AA00; font-weight: bold;">Yes</span>';
else
echo '<span style="color: #EE0000; font-weight: bold;">No</span>';
echo '<div style="clear:both;"><!-- --></div></div>';
}
} else {
echo '<span style="color: #EE0000; font-weight: bold;">not supported</span> by your server!</p>';
}
echo '<p>by <a href="http://www.dagondesign.com">dagondesign.com</a></p>';
echo '</div>';
?>

reference: Checking for GD support on your server

安裝xdebug
# /usr/local/php/bin/phpize
# ./configure --prefix=/usr/local/xdebug --enable-xdebug --with-php-config=/usr/local/php/bin/php-config
# make && make install && make clean
# vim /usr/local/php/lib/php.ini
[add]
zend_extension="/usr/local/php/lib/php/extensions/debug-zts-20060613/xdebug.so"
xdebug.profiler_enable=on
xdebug.trace_output_dir="/tmp/xdebug"
xdebug.profiler_output_dir="/tmp/xdebug"
[/add]
# required glibc

安裝suhosin
# /usr/local/php/bin/phpize
# ./configure --prefix=/usr/local/suhosin --with-php-config=/usr/local/php/bin/php-config
# make && make install && make clean
# cp /usr/local/php/lib/php/extensions/debug-zts-20060613/suhosin.so /usr/local/php/lib/php/extensions/
# vim php.ini
extension_dir = "/usr/local/php/lib/php/extensions"

reference:
How To Harden PHP5 With Suhosin On CentOS 5.3 | HowtoForge - Linux Howtos and Tutorials
Hardened-PHP Project - PHP Security - Installation!

安裝memcached (ver. 2.2.5)
# /usr/local/php/bin/phpize
# ./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-conifg --with-zlib-dir
# make && make install && make clean
# cp /usr/local/php/lib/php/extensions/debug-zts-20060613/memcache.so /usr/local/php/lib/php/extensions/
# vim /usr/local/php/lib/php.ini
[add]
extension=memcache.so
[/add]

reference:
如何使用 memcached 做快取

安裝eaccelerator
# /usr/local/php/bin/phpize
# ./configure --with-php-config=/usr/local/php/bin/php-config
# make; make install
# cp /usr/local/php/lib/php/extensions/debug-zts-20060613/eaccelerator.so /usr/local/php/lib/php/extensions/
# vim /usr/local/php/lib/php.ini
[add]
extension=eaccelerator.so
eaccelerator.shm_size="512"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="0"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.log_file = "/var/log/eaccelerator_log"
[/add]

reference:
Installing from source
PHP - PHP 加速器的調校(php-eaccelerator)

特殊的php連結sql server需求
安裝freetds (ver. 0.82)
# ./configure --prefix=/usr/local/freetds --enable-msdblib --with-openssl=/usr/local src/openssl --with-gnutls
# make && make install && make clean
需重新編譯PHP
# cd {/path/to/php/src}
# ./configure --with-mssql=/usr/local/freetds
# make && make install && make clean

reference:
* How To Install Apache 2 with SSL on Linux (with mod_ssl, openssl)

2010年7月23日 星期五

[Tips] Fedora 13安裝設定

之前用了一陣子的ubuntu, 實在是用不習慣, 只好轉回用fedora當工作環境, 發現有些地方需要稍微修改一下比較順手, 就筆記一下了...

1. 網路設定的問題
剛安裝完fedora時, 網路經常無法正常啟動, 需先將網卡啟動, 修改/etc/sysconfig/network-scripts/ifcfg-eth0, 將ONBOOT=no改為yes, 另外再啟動NetworkManager方便網路設定

2. Yum遇到的錯誤訊息
Loaded plugins: presto, refresh-packagekit
Existing lock /var/run/yum.pid: another copy is running as pid XXXX
先kill所有正在執行的yum程序, 並且清掉所有cache的資料即可
[root@localhost]# yum clean all

若遇到repository站台回應速度緩慢的錯誤訊息, 例如:
Error: Cannot retrieve repository metadata (repomd.xml) for repository: fedora. Please verify its path and try again
則註解掉/etc/yum.repos.d/fedora.repo和/etc/yum.repos.d/fedora-updates.repo中的baseurl, 並且在/etc/hosts加上兩筆資料
80.239.156.215 mirrors.fedoraproject.org
213.129.242.84 mirrors.rpmfusion.org
另外再安裝yum-fastestmirror套件, 未來在搜尋套件時, 可搜尋速度較快的mirror站台


/** update @ 2010-08-19 **/
這幾天又試裝了一下ubuntu 10.04, 發現fedora 13上面遇到的一些鳥問題在新版本的ubuntu都不會遇到, 為了不想搞環境搞太久, 我還是先把工作環境轉過去吧...

2010年7月7日 星期三

PHP Obfuscator

若是不想要PHP的原始碼讓別人看到, 可以使用open source的PHP Screw, 以下是1.5的安裝步驟:

0.系統需求
PHP 5.x的環境
具有zlib的支援(可透過<?php gzopen(); ?>來檢查)

1.解壓縮
修改my_screw.h, 裡面的數字就是seed, 可視為密碼

2.編譯成so
$ phpize
$ ./configure –with-php-config=/path/to/php-config
$ make

若發生錯誤如
/path/to/php_screw-1.5/php_screw.c:78: error: too few arguments to function 'org_compile_file'
/path/to/php_screw-1.5/php_screw.c:84: error: too few arguments to function 'org_compile_file'
/path/to/php_screw-1.5/php_screw.c:91: error: too few arguments to function 'org_compile_file'
/path/to/php_screw-1.5/php_screw.c:93: error: too few arguments to function 'org_compile_file'
從官方bug列表找到解決方法:
modify php_screw.c
org_compile_file(file_handle, type);
to
org_compile_file(file_handle, type TSRMLS_CC);

或發生錯誤如
/path/to/php_screw-1.5/php_screw.c: In function 'zm_startup_php_screw':
/path/to/php_screw-1.5/php_screw.c:124: error: 'zend_compiler_globals' has no member named 'extended_info'
/path/to/php_screw-1.5/php_screw.c: In function 'zm_shutdown_php_screw':
/path/to/php_screw-1.5/php_screw.c:133: error: 'zend_compiler_globals' has no member named 'extended_info'
閱讀source後
modify php_screw.c
CG(extended_info) = 1;
to
// CG(extended_info) = 1;

3.修改php.ini設定
[php_screw]
extension=php_screw.so

4.編譯混淆器
$ cd tools $ make )

5.使用(對foo.php做混淆)
$ ./tools/screw foo.php
$ Success Crypting(foo.php)

若要對多個檔案進行混淆,可以簡單的使用兩行指令搞定
$ find . -name "*.php" -exec /path/to/tools/screw -exec {} \;
$ find . -name "*.screw" -exec rm -f {} ;

注意, 混淆過的檔案, 對方主機需安裝php_screw才能讀取, 所以虛擬主機類的應該就沒辦法用這一招了...

參考資料:
* 使用自由加密軟件PHP screw對PHP源碼加密
* 用php_screw加密PHP代碼