2010年9月30日 星期四

用 Ubuntu 將 mysql database 搬到 ramdisk 上

改自同事 P 的筆記:
$ sudo -u mysql cp -rp /var/lib/mysql/DATABASE /var/lib/mysql/DATABASE_tmp  # backup the original one.
$ sudo -u mysql mv /var/lib/mysql/DATABASE /dev/shm/  # move DATABASE to shared memory.
$ sudo -u mysql ln -s /dev/shm/DATABASE /var/lib/mysql/DATABASE
$ sudo vim /etc/apparmor.d/usr.sbin.mysqld  # Add /dev/shm/DATABASE to the allow list
$ sudo /etc/init.d/apparmor restart 

關鍵在於 apparmor 的部份, 沒做的話, 在存取 DATABASE 時, 會出現 "Can't read ... (errno: 13)" 的錯誤訊息。

不過試了幾次將資料庫丟到 ramdisk 上, 好像都沒有變快過。如果要 scan 整個表格的話, 在 ramdisk 上似乎也沒變快。

網路上有人提到有 MEMORY engine 為啥會想放到 ramdisk, 每個人有不同的理由, 我的動機則是表格有欄位超過 512 bytes 無法用 MEMORY engine

2010年9月27日 星期一

Ubuntu 限制 process 的記憶體用量

http://stackoverflow.com/http://serverfault.com/ 找半天, 只看到大家說跑程式前記得先用 ulimit, 卻沒看到要怎麼設定使用者的預設值。最後只好在 /etc/profile 裡加上:
ulimit -v 10000000  # At most 10G

用 help ulimit 可看到說明, ulimit -a 可以看到目前的限制和單位。

2010年9月25日 星期六

寫 alias 切換路徑到 virtualenv 相關目錄

用 virtualenv 時常會需要切入 site-packages 或 src 內做些事, 久了就覺得很麻煩。雖然 virtualenvwrapper 有提供相關指令, 但又不想為了這件事而多裝 virtualenvwrapper, 它的其它功能對我來說幫助不大, 加上我自己有個 script, 用來安裝開發用的 virtualenv, 懶得整合那個 script 和 virtualenvwrapper 的路徑 (也就是指定裝到 ~/.virtualenvs), 所以決定自己寫切換路徑的 alias。

Python 沒提供堪用的單行寫法, 但為此回頭學 awk, sed 也太麻煩了。想想還是回頭寫 Ruby 吧, 相較於 Perl, 至少較熟一些 Ruby 。

alias cdve='cd $(echo $PATH | ruby -ne '"'"'puts split(":")[0].split("/")[0..-2].join("/")'"'"')'
alias cdvesrc='cd $(echo $PATH | ruby -ne '"'"'puts split(":")[0].split("/")[0..-2].join("/")'"'"')/src'
alias cdvesite='cd $(echo $PATH | ruby -ne '"'"'puts split(":")[0].split("/")[0..-2].join("/")'"'"')/lib/python2.5/site-packages/'

如上所示, 進入 virtualenv 後, 打 cdve / cdvesrc / cdvesite 會切到 virtualen 的根目錄、src、site-packages。

其中最難搞的是在單引號內用單引號, 參考 《BASH, escaping single-quotes inside of single-quoted strings》, 用 "'" 來表示單引號, 總算是搞定了。關鍵在於用到單引號時就換成 "'", 但字串間不能有空白, 結果就變成超難懂的 bash code 了。

django 自行新增使用者的作法以及為何密碼檔裡要加 salt

寫測試程式時需要先建個測試帳號, 為了確保任何人取得原始碼後能直接跑成功測試, 我在測試碼執行時檢查是否已建立測試帳號, 若沒有則自己建一個。

單純地新增 User 放入 username 和 password 是行不通的, 順著命令 createsuperuser 看原始碼, 發覺正確的寫法如下:
try:
    user = models.User.objects.get(username='test')
except models.User.DoesNotExist, e:
    print 'Test account doest not exist. Now create it.'
    user = models.User(username='test', is_active=True)
    user.set_password('testtest')
    user.save()

好奇之下看了一下 set_password 怎麼寫的 (./contrib/auth/models.py):
def set_password(self, raw_password):
    import random
    algo = 'sha1'
    salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
    hsh = get_hexdigest(algo, salt, raw_password)
    self.password = '%s$%s$%s' % (algo, salt, hsh)

可以看到 Django Auth 用 sha1 和 salt 產生加密後的字串。於是查了一下 salt 的功效, 這回才真的明白它的用處。

Wikipedia 上舉了幾個情境:
  • 在沒用 salt, 且用單字當密碼的情況, 一但密文被取得後, 攻擊者只要查事先建好的表即可馬上找出原始密碼。表的 key 是 sha1 加密的結果, value 是原碼。
  • 同上, 改用 Rainbow table 建一般性的表, 而不是單純用字典檔。題外話, Rainbow table 的概念滿有趣的, 用到機率和時間空間取捨的技巧。
所以, 若加密時有用 salt, 攻擊者得另外取得 salt 才能開始攻擊。即使 salt 也存在密文裡, 攻擊者也得照「規矩」來試密碼, 不能用事先建好的表。
若整份密碼檔用同一份 salt, 攻擊者可以在取得 salt 後開始建表, 之後整份密文就可以用同一份表查出結果。但是當每個使用者的 salt 都不同時, 攻擊者只好每個密文都全試一次, 無法建表加速破解。換句話說, 破解單一特定使用者密碼的時間一樣, 但用多份 salt 讓破解所有人密碼的時間大增。
當然, 若使用者的密碼較長, 或是有摻雜攻擊者建表時沒用到的字元 (如攻擊者只用字母和數字, 使用者的密碼有含符號), 那加不加 salt 也沒差。不過任何當過系統管理員的人都知道, 絕大多數使用者的密碼都是很簡單的..., 簡單地加個 salt 可以降低不少風險, 讓攻擊者要花更多時間取得明文, 發覺密碼檔外洩時, 可以減少損失。

2010年9月21日 星期二

移除 ~/.ssh/known_hosts 裡特定的 host key

若 known_hosts 不是純文字檔的話, 就得透過指令刪 host key:
$ ssh-keygen -R HOST
大概是被 BBS 影響的緣故, 寫一行文會有種罪惡感, 而忍不住想多打幾句話...。

rsync 來源目錄語法的差異

當目標是目錄或不存在時, src 有加 '/' 時表示產生一樣的目錄結構, 沒加時表示將 src 複製到目標目錄下
$ ls src/
file

$ rsync -av --delete src/ dest
$ ls dest/
file

$ rsync -av --delete src dest2
$ ls dest2
src/

2010年9月7日 星期二

用 DVCS 來記錄系統設定檔

抱著實驗性的心態試用一陣子, 每當要改設定檔時, 就先在當地建個 mercurial repository。目前在這些地方建了 repository:
  • /etc/apache2/conf.d/
  • /etc/mysql/
  • /etc/apt/
一開始的動機是方便知會其它管系統的人我做了什麼修改。後來發現其它好處:
  • 可以明確知道這次到底改了什麼。改壞了也不用擔心。
  • 可以知道過去改了什麼, 弄新機器時, 輕鬆地弄出一樣的設定。或是只想取部份設定也沒問題, 之前的 changeset 都寫得很清楚, 簡單一句話的註解加上 diff, 就很清楚了。
在這個例子裡 DVCS 實在是太方便了。減少設定和管理 VCS 伺服器的負擔。一行 hg init 就是一個新的 repository。反正備份也是整個目錄一起備份, 不用另費心思備份 repository meta data。
不知專業系統管理員是怎麼協同合作管理設定檔的, 目前覺得這樣滿不錯的。

2010-11-07 更新

High performance MySQL 建議將所有系統檔集中管理放到 VCS 裡, 再用 symbolic link 連過去, 感覺上是更好的做法。換句話說, /etc/apache2/conf.d、/etc/memcachd.conf 等都是 link, 本體放在 /home/config/ 裡, 而 /home/config/ 存在 VCS 裡。

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...