2012年12月22日 星期六

檢查磁碟使用量的工具


通常 notebook 的硬碟都不會太大,再加上使用 lvm 裝了七、八個 OS,所以很快就滿了,因此常常處於需要清理磁碟空間的狀況,但是這卻不是件容易的事,要找出哪些該清、哪些能清要耗掉滿多時間的。

當然,能用的工具多不勝數,底下只介紹幾個工具:

一、du 指令:

$ du -hax --max-depth=1 ./ | sort -h
7.9M ./Fonts
54M ./Scratch
352M ./nitdroid
398M ./proxmox-ve_2.2-7f9cfa4c-28.iso
3.8G ./raspberrypi
6.1G ./

檢查目前目錄中所有檔案的使用情形,只列出第一層目錄,並將結果由小到大排列。
這樣就可以很容易的看出哪些檔案或目錄佔掉大部份的磁碟空間。
假設我們要再檢查 ./raspberrypi 裡的資料, 要再下一次指令:
$ du -hax --max-depth=1 ./raspberrypi | sort -h
2.8M ./raspberrypi/apps
149M ./raspberrypi/games
160M ./raspberrypi/archlinux
273M ./raspberrypi/gentoo-raspberry
279M ./raspberrypi/opensuse
539M ./raspberrypi/raspbian
575M ./raspberrypi/fedora
659M ./raspberrypi/xbian
742M ./raspberrypi/qtonpi
3.8G ./raspberrypi

加 --time 可顯示最後修改時間

二、ncdu:

$ ncdu -x ./
--- /media/share/download
3.8GiB [##########] /raspberrypi
397.4MiB [# ] proxmox-ve_2.2-7f9cfa4c-28.iso
384.6MiB [ ] RacyPy2.iso
351.6MiB [ ] /nitdroid
70.5MiB [ ] /wine
53.6MiB [ ] /Scratch
47.1MiB [ ] GIMP+Magazine+Issue+1.pdf
46.5MiB [ ] slitaz-armhf-mini-2012-12-14.zip

非常直覺,以上下左右鍵來移動光棒,在目錄上按 Enter 即可進入下層目錄,一目瞭然。


三、 xdiskusage:

上二個都是在命令列或終端機執行,有些人看到醜醜的就不想用,沒關係,有圖形介面的。
$ xdiskusage -a ./
出現一個視窗,最左方是第一層起始目錄,右方則是裡面的子目錄,也是滿直覺的,一看就知道哪個目錄佔掉大部份空間。


圖1 顯示 ./ 使用 6.052G,而中間 raspberrypi 用掉 3.797G,接著看到 raspberrypi 裡最下層子目錄 games 佔掉 148.5M,可是再下去太小了,看不清楚,以滑鼠左鍵點 games 二下即可以 games 為第一層目錄,這樣就全部跟著放大,不會看不清楚了。也可以用上下左右鍵來移動,Enter 來進入該層目錄,左鍵回上一層。


圖2為 games 裡的資料,經過放大後看得很清楚。


xdiskusage 還可以從 standard input 來輸入 du 的資料:
$ du -k . | xdiskusage


四、agedu:

先掃描要檢查的目錄,並記錄在 ./agedu.dat 中
$ agedu -s ./

讀入 ./agedu.dat 並 listen localhost tcp port 34769
$ agedu --files -w
Using Linux /proc/net magic authentication
URL: http://localhost:34769/


以瀏覽器打開 http://localhost:34769 即可,如圖3。
agedu 有一項別套沒有的特點,就是可直接看顏色來判斷這個目錄有多久前存取,紅色表示二個月以上沒修改,對於我們判斷要不要清除很好用的。滑鼠移至顏色上方,能看見這目錄多久前存取過。

agedu 預設只能看目錄,無法看到各個檔案大小,可加 --files 來看所有檔案。
$ agedu --files -w

也可以像 du 指令一樣在 terminal 中使用
$ agedu -t ./

還有滿多參數的,請自行參考
$ man agedu


有了這些工具後,對於清理磁碟榨出空間的工作,不再是那麼煩人了。

2012年12月5日 星期三

Raspberry Pi GPIO 介紹及基本使用

開始要玩 gpio 時,才發現買的外殼不合,要拆開蓋子才能插排線,所以若有買殼時要注意一下,若不合不如不要用外殼。不過,最近看新版的壓克力殼有在上方開一條縫能走 gpio 排線就是。最好買只有上下二片的外殼最適合玩 gpio(註1)。

樹莓派連麵包板的 gpio 排線,可以拿現成的磁碟機或硬碟排線來改,不過要注意,有些排線中間是有跳過的(註2)。小弟本身是用硬碟排線來改,花了些錢買一堆小零件,加工了好幾個小時,終於做好,結果拍賣上賣的一條也不過 70 元,又精緻又美觀(註3),光買零件就花了大概 30 元,弄了好久,後來還發現有時會接觸不良,實在不划算,因此建議直接買現成的就好。

一開始看文件時,由於型號分成 model A、model B,然後版本又分 rev 1、rev 2,版本間的 port 又有小部份修改,有些文章寫出要接在哪個 port,甚至連圖都有,但麵包板插好還是不會動,而且很多網頁都有提到要小心,否則會將 Raspberry Pi 給燒掉,所以文件 k 到第三天後才敢開始在麵包板上插零件。而且一開始還鬼打牆真的弄錯,上下顛倒,還好沒燒掉。最主要不要去接到 5V 就好。
建議先做個保護電路來用(註4),否則燒掉了可惜,但是,完全看不懂啦,只好小心點就是。

gpio 腳位:
P1: The Main GPIO connector:

wiringPi Pin BCM GPIO Name Header Name BCM GPIO wiringPi Pin
– – 3.3v 1 | 2 5v – –
8 R1:0/R2:2 SDA0 3 | 4 DNC – –
9 R1:1/R2:3 SCL0 5 | 6 0v – –
7 4 GPIO7 7 | 8 TxD 14 15
– - DNC 9 | 10 RxD 15 16
0 17 GPIO0 11 | 12 GPIO1 18 1
2 R1:21/R2:27 GPIO2 13 | 14 DNC – –
3 22 GPIO3 15 | 16 GPIO4 23 4
– – DNC 17 | 18 GPIO5 24 5
12 10 MOSI 19 | 20 DNC – –
13 9 MISO 21 | 22 GPIO6 25 6
14 11 SCLK 23 | 24 CE0 8 10
– – DNC 25 | 26 CE1 7 11


P5: The auxilliary GPIO connector on Rev. 2 boards:

wiringPi Pin BCM GPIO Name Header Name BCM GPIO wiringPi Pin

– – 5v 1 | 2 3.3v – –
17 28 GPIO8 3 | 4 GPIO9 29 18
19 30 GPIO10 5 | 6 GPIO11 31 20
– – 0v 7 | 8 0v – –
表1

其中 DNC -> Do Not Connect 接腳就是不要使用的意思,因為未來可能會改變配置。

P1 總共有 26 支腳,有 8 個 GPIO port,其他的有 i2c, UART, SPI, 3.3V, 5V, GND 等等。

其中 2 個 5V、2 個 3.3 V、5 個 GND,除了這 9 個以外,其他都可以設定成 GPIO 來使用,加起來共有 17 個。

rev 2 則多加了 P5,只要焊上針腳,又多了4個 gpio 可使用,總共 21 個。


如何控制 gpio port

- 從命令列直接控制
- 使用 WiringPi
- 使用 python
- 使用 Webiopi
- 多種語言範例(註5)


從命令列操作 :


$ ls -l /sys/class/gpio/
--w------- 1 root root 4096 Nov 30 19:37 export
lrwxrwxrwx 1 root root 0 Nov 30 19:34 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
--w------- 1 root root 4096 Nov 30 19:34 unexport

假設要使用 gpio17,送出一個 port number 到 export 即可起始這個 port
$ sudo sh -c “echo 17 > /sys/class/gpio/export”

由於使用到輸出入轉向,又用 sudo 的話,命令變得不易閱讀,所以乾脆切到 root 去
$ sudo su -

重覆剛才指令
# echo 17 > /sys/class/gpio/export

# ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Nov 30 19:37 export
lrwxrwxrwx 1 root root 0 Nov 30 19:38 gpio17 -> ../../devices/virtual/gpio/gpio17
lrwxrwxrwx 1 root root 0 Nov 30 19:34 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
--w------- 1 root root 4096 Nov 30 19:34 unexport
執行完就可看到多出一個 gpio17 連結

# ls -l /sys/class/gpio/gpio17/
total 0
-rw-r--r-- 1 root root 4096 Nov 30 19:58 active_low
-rw-r--r-- 1 root root 4096 Nov 30 19:58 direction
-rw-r--r-- 1 root root 4096 Nov 30 19:58 edge
drwxr-xr-x 2 root root 0 Nov 30 19:58 power
lrwxrwxrwx 1 root root 0 Nov 30 19:37 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 Nov 30 19:37 uevent
-rw-r--r-- 1 root root 4096 Nov 30 19:58 value

顯示目前 gpio17 是輸入或輸出
# cat /sys/class/gpio/gpio17/direction
in

將方向改成輸出
# echo out > /sys/class/gpio/gpio17/direction

已改變為輸出
# cat /sys/class/gpio/gpio17/direction
out

顯示目前 gpio17 的值
# cat /sys/class/gpio/gpio17/value
0

更改 gpio17 的值
# echo 1 > /sys/class/gpio/gpio17/value

檢查看是否有改過
# cat /sys/class/gpio/gpio17/value
1


使用 WiringPi:

看過上面直接在 console 下指令由 /sys 對 gpio 做修改,是不是覺得滿麻煩的,所以有人寫出 Wiring 來簡化整個設定過程。

由於 gpio 編號並沒有按照順序排,跳來跳去的,初學者根本弄不清楚,常常會搞錯。
Wiring,原本是 Arduino 系統在用的,將 gpio 重新編號,由 0 開始,循序往上的命名方式的工具,好處是若哪天板子改版,gpio 編號有跳動,wiring 編號也是不變。

後來樹莓派出來後,移植到樹莓派的版本就叫 WiringPi。當然,也支援原本的編號方式。

網頁:
https://projects.drogon.net/raspberry-pi/wiringpi/

安裝:
https://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/

$ tar xvf wiringPi.tgz
$ cd wiringPi
$ sudo ./build

可直接下載 tarball 安裝,完成後在命令列下就有 gpio 這指令可用。

由於使用及存取 gpio port 都必需有 root 權限,但 gpio 這指令有 setuid,所以用一般使用者來執行即可。

檢查這塊板子的版本是 rev 1 或 rev 2
$ gpio -v
gpio version: 1.4
Copyright (c) 2012 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

This Raspberry Pi is a revision 2 board.


$ gpio readall
+-----------------+--------+------------+-----------+
| wiringPi | GPIO | Name | Value |
+-----------------+--------+------------+-----------+
| 0 | 17 | GPIO 0 | Low |
| 1 | 18 | GPIO 1 | High |
| 2 | 27 | GPIO 2 | Low |
| 3 | 22 | GPIO 3 | Low |
| 4 | 23 | GPIO 4 | Low |
| 5 | 24 | GPIO 5 | Low |
| 6 | 25 | GPIO 6 | Low |
| 7 | 4 | GPIO 7 | High |
| 8 | 2 | SDA | High |
| 9 | 3 | SCL | High |
| 10 | 8 | CE0 | Low |
| 11 | 7 | CE1 | Low |
| 12 | 10 | MOSI | Low |
| 13 | 9 | MISO | Low |
| 14 | 11 | SCLK | Low |
| 15 | 14 | TxD | High |
| 16 | 15 | RxD | High |
+----------------+---------+------------+------------+
| 17 | 28 | GPIO 8 | Low |
| 18 | 29 | GPIO 9 | Low |
| 19 | 30 | GPIO10 | Low |
| 20 | 31 | GPIO11 | Low |
+----------------+---------+-------------+----------+

顯示所有 port 的目前狀況(板子上的 P1),0 - 16 共 17 port,最後面 4 個為 P5 (rev 2 才有) 在板子上 P1 的旁邊有 8 個小洞,要使用自己焊。聽說未來的板子,連現在的 P1 的 26 port 出廠都不會焊好,使用者買回家後,要直的、彎的接腳都可以自己來,以後要玩樹莓派 gpio 要先準備好烙鐵和吸鍚器了。

第一列為 wiring 的編號,第二列為 broadcom 的 BCM_GPIO 編號方式,第三列為原本每個 port 的名稱,最後一行為目前的值。

存取方式:(預設為 wiring 編號模式)
$ gpio read 0
0

以 BCM_GPIO 編號來讀取( -g):
$ gpio -g read 17
0

二個指令都讀取同一個 port

將 17 port mode 改成輸出
$ gpio -g mode 17 out

寫入:
$ gpio -g write 17 1

檢查值果然改變為 1
$ gpio -g read 17
1

好像沒參數可看目前是輸出或輸入,不過沒關係,每次要用前都直接先設定一次就好。



使用 python:

檢查看看 Python GPIO module for Raspberry Pi 有沒有安裝,若是官方的 rasbian 已經安裝好,其他的可能要檢查看看。

$ dpkg --list|grep gpio
ii python-rpi.gpio 0.4.1a-1 armhf Python GPIO module for Raspberry Pi
ii python3-rpi.gpio 0.4.1a-1 armhf Python 3 GPIO module for Raspberry Pi

python-rpi.gpio 為 python 2.6 及 2.7 版
python3-rpi.gpio 為 python 3.x 版


若沒有則手動安裝:
$ sudo apt-get install python-pip
$ sudo pip install rpi.gpio


範例: test.py
import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)

try:
while True:
GPIO.output(17, True)
time.sleep(2)

GPIO.output(17, False)
time.sleep(2)
except KeyboardInterrupt:
GPIO.cleanup()

執行:
$ sudo python test.py
執行後,GPIO 17 上的 led 就會閃二秒、滅二秒,一直重覆,按 Ctrl-C 結束程式。



使用 Webiopi:

http://code.google.com/p/webiopi/

下載並安裝:
$ tar xvf WebIOPi-0.5.1.tar.gz
$ cd WebIOPi-0.5.1
$ sudo ./setup.sh

執行
$ sudo /etc/init.d/webiopi start
$ sudo python -m webiopi [port]


開機就啟動:
$ sudo update-rc.d webiopi defaults


以瀏覽器開啟:
http://192.168.1.105:8000

預設帳號 "webiopi" 及密碼 "raspberry"


實作:


- 紅綠燈模擬

http://www.skpang.co.uk/blog/archives/656

$ wget http://skpang.co.uk/dl/traffic_light.py
由於 rev 1 和 rev 2 腳位有改變,所以這裡的 code 也要跟著改
$ vi traffic_light.py
第9 行 21 → 27 即可

$ chmod +x traffic_light.py
$ sudo ./traffic_light.py


- Ladder Game

http://www.youtube.com/watch?v=35YXhS-NfPM
https://projects.drogon.net/raspberry-pi/gpio-examples/ladder-game/

下載並編譯,不過系統上要有裝 wiringPi 才行
$ wget http://project-downloads.drogon.net/files/gpioExamples/ladder.c
$ cc -o ladder -Wall -I/usr/local/include -L/usr/local/lib ladder.c -lwiringPi -lm
$ sudo ./ladder




參考連結:


1. http://moebiuslinux.sourceforge.net/hardwarehacks/raspberry-pi-barebone-development-case/
2. http://www.drobe.co.uk/extra/usbmedia/cable1.jpg
3. http://search.ruten.com.tw/search/s000.php?searchfrom=indexbar&k=gpio+%B1%C6%BDu&t=0
4. http://elinux.org/RPi_Tutorial_EGHS:GPIO_Protection_Circuits
5. http://elinux.org/Rpi_Low-level_peripherals

2012年11月29日 星期四

將 firefox 及 adobe flash 與目前系統隔離完整版


上次寫了將 firefox 執行於 chroot 環境下,用來與目前系統隔離,但由於 chroot 只隔離檔案系統,而核心卻還是共用的,依然沒有很安全,只保護了半套。這篇就直接將 firefox 跑在 kvm 虛擬機器上,畫面及聲音傳回目前桌面系統。

有很多種方法來達到這功能,包括 vnc,nx server,xspice server + spice client,x2go server,ssh x11 forwarding,以及最古早的 X11 access control (xhost),另外還有 dxpc,也就是今天的主角。

但由於 vnc 及 nx server 和 xpice server + spice client 都是出現一個完整的 root window,裡面再有一些應用程式,等於直接操作二台機器,使用上滿不方便的,因此在這邊就不使用。


範例有二台機器,一台是 desktop-host, 另一台為 firefox-host,記憶體給至少 768M 以上,不用啟動 X。


首先介紹最簡單的 ssh x11 forwarding:

ssh x11 forward 是最簡單的,不用安裝額外軟體,直接使用即可。
預設 ssh server 的 x11 forwarding 已經是開啟的,只要直接在本機下指令:
$ ssh -X firefox-host firefox

這時虛擬機器上的 firefox 視窗就會開啟,和平常本機上執行沒二樣,不過檔案就要使用如 sshfs 來分享。
有一點要注意的,就是要先將本機的 firefox 給關掉,若沒關的話,就算是在別台機器開 firefox,也會變成是開啟本機的 firefox,這個功能很奇怪,之前被騙過,下載檔案在別台機器上找不到。

但是,有一個大問題,就是在看 youtube 時 “沒有聲音”,因為是在另一台機器上執行,所以聲音沒傳過來。

沒關係,有功能強大的 pulseaudio 可用,可取代以前的 esd,在本機設定 pulseaudio sound server,由遠端將聲音傳送過來。

on desktop-host 端設定:
$ sudo apt-get install pulseaudio paprefs

$ paprefs
設定 Network Server 標籤,將 Enable network access to localhost sound devices 打抅

然後將 ~/.pulse-cookie 給拷貝到虛擬機器中同樣位置即可。
$ scp -p ~/.pulse-cookie firefox-host:~/.pulse-cookie

若不想這麼麻煩,直接設定同樣 Network Server 標籤下
Don’t require authentication 也打抅,就不用認證即可連接。


 啟動 pulseaudio
$ pulseaudio --start

此時用 netstat -an 可看到 pulseaudio listen tcp port 4713
firewall 記得打開給 firefox-host 連

on firefox-host 端設定:
$ sudo apt-get install pulseaudio

執行:
$ export PULSE_SERVER=desktop-host:4713
$ firefox &

這樣看 youtube 時就有影像及聲音了,從 firefox 下載後也可透過 sshfs 來取得。

當然多開 port 總是不好的,而且聲音流量不大,也可透過 ssh port forwarding 來取代開 port。
將 desktop-host 的 4713 port 由 ssh tunnel 轉到 firefox-host 的 4713 port,這樣在 firefox-host 就可直接將聲音送到 localhost:4713,desktop-host 也就不用防火牆打開 tcp 4713 。

on desktop-host:
$ ssh -X -R 4713:localhost:4713 firefox-host

on firefox-host:
$ export PULSE_SERVER=localhost:4713
$ firefox &

寫個 script start-firefox-ssh-x11-forwarding
#!/bin/bash
export PULSE_SERVER=localhost:4713
firefox &
firefox 下載回來的檔案如何取得,直接安裝 sshfs 掛載起來即可。

簡化上面步驟,一切設定完整後,以後只要下指令:
on desktop-host:
$ ssh -X -R 4713:localhost:4713 firefox-host start-firefox-ssh-x11-forwarding
$ sshfs firefox-host:/home/username/Downloads/ /home/username/Downloads 

即可遠端使用 firefox



使用 x2go server :

x2go server 基本上和 nx server 差不多,之前介紹過,這次就不多做說明。
x2go server 可以單獨執行某一程式,做到 rootless 的功能,只會有一個應用程式的視窗,和本機開啟的看起來一樣。
而聲音部份,x2go 也支援 pulseaudio, arts, esd 等,在設定裡抅好即可,其他的 x2go 會處理,也不用在 desktop-host 上 listen tcp 4713 的設定。
至於檔案分享部份,也在設定裡面直接設定即可,後端也是採用 sshfs。

設定時選擇 Session 標籤 -> 最下方 Session type 改成 single application,並於 Command: 空格中打上 firefox 指令即可,按 ok 關閉視窗。

連接後只會出現 firefox 視窗,而不是整個桌面環境。




最古早的 X11 access control (xhost):

因為直接用 X protocol,沒經過 ssh 什麼的加密,因此是效能最好的,可惜要在本機 desktop-host 上開 tcp 6000 port 給 firefox-host 連,不建議用這個方法,因為這裡是用虛擬機器,基本上是沒出去這台 desktop-host 外面,所以才勉強用看看,若為真實二台機器透過網路連接,千萬不要用這方法。

on desktop-host:
現在預設啟動 X 時,都會自動加上 -nolisten tcp 參數,因此要修改 gdm 類的工具,將這參數拿掉。
若是使用 startx 來啟動 X,則修改:
/etc/X11/xinit/xserverrc
exec /usr/bin/X -nolisten tcp "$@"
改成
exec /usr/bin/X "$@"

這樣在啟動 X 後,就會 listen tcp port 6000
firewall 打開 tcp 6000 給 firefox-host 連

然後設定那幾台機器可以連 X server
$ xhost +firefox-host

on firefox-host:
$ export DISPLAY=desktop-host:0
$ firefox

這樣畫面就會丟過來,而且看 youtube 什麼的,都和原本本機上執行差不多。
聲音一樣使用 pulseaudio,檔案分享一樣用 sshfs。

不過,這樣風險滿大的,如果 firefox-host 被入侵,有現成工具(之前在管系統時,有遇到這種後門),可以由 firefox-host 連到 desktop-host 6000 port,並截取所有鍵盤按鍵及畫面,包括密碼什麼的,所以就違反了當初安全的目的。



使用 dxpc 來執行遠端程式,並丟到目前 display 來:

當初 nx server 就是受這套 dxpc 所啟發,而開始發展的。

由於 dxpc 的 client 要先啟動,因此先從 firefox-host 開始
on firefox-host:
$ sudo apt-get install dxpc
$ dxpc &
會 listen tcp port 4000 及 6008 port,4000 是 client 及 server 端溝通的,而 6008 是 X 的 display :8 所用的 port
firefox-host 的防火牆只需要開 tcp port 4000 給 desktop-host 連即可。

將 display 指向 localhost:8
$ export DISPLAY=localhost:8

聲音一樣用 pulseaudio
$ export PULSE_SERVER=desktop-host:4713

等 desktop-host 連結過來後,再來執行 firefox,我的 script 裡面是設定 sleep 5 秒

start-firefox-dxpc
#!/bin/bash
export DISPLAY=localhost:8
export PULSE_SERVER=desktop-host:4713
sleep 5
firefox &

$ start-firefox-dxpc
執行後在5秒內趕快去另一端執行 dxpc


on desktop-host:
$ sudo apt-get install dxpc

$ dxpc firefox-host &

預設 dxpc 和 dxpc 間是用 lzo 來壓縮再傳送,若 cpu 不夠力(如虛擬機器),可以關掉。
$ dxpc -i 0 firefox-host &

通道建立後,就會彈出 firefox 視窗,像平常一樣的使用。
播放 youtube 上 html5 的影片很正常,有點頓就是,應該是機器不夠高檔。不過,好像 flash 及 dxpc 有點不相容,若是去播放 flash 的影片,很容易就將整個 X 都卡住,完全不會動,要按 Ctrl-Alt-F1 回到 console 底下,將 dxpc 給砍了,再按 Alt-F7 回來才正常。

那古早 xhost 方式和這個 dxpc 有什麼不同,其實差很多。
最主要差別在:
xhost 方式是由 desktop-host listen tcp 6000,然後由 firefox-host 連進來
dxpc 是由 firefox-host listen tcp 4000,然後由 desktop-host 連進來,方向不同,自然安全性也不同。當然 dxpc 也可以下 -w 參數,來讓連線方向對調,某些狀況下會用到,如 firefox-host 在 nat 底下。


基本上,這麼多種方法可用,大致上為:
ssh x11 forwarding: 一般使用及瀏覽網頁沒問題,但要看影片滿頓的,手動搭配 pulseaudio 及 sshfs
古早 xhost: 效能最好,但最危險,手動搭配 pulseaudio 及 sshfs
x2go server: 最簡單,看影片滿頓的,聲音及檔案分享都幫你做好
dxpc: 介於中間,安全性不錯及效能勉強可接受,手動搭配 pulseaudio 及 sshfs,不過會 hang,要再多測試看看。

 感覺機器要再高檔些,才有辦法應付影片播放。

2012年11月25日 星期日

以 schroot 在 chroot 環境下執行 firefox

由於前陣子 google 公佈說在 chrome 中執行 flash 已經 “fully sandboxed”(註1),就算 adobe flash 有漏洞,也不容易影響到系統。

但對於 firefox 使用者來說就沒這麼好康了,由於 adobe flash 的安全性一向是滿糟的,在 mozilla 沒做好防護前,只好自己來,這篇是在 debian wheezy 下將 firefox 放到 chroot 底下去執行,以達到隔離目的。

當然最安全的是建立另一台虛擬器,只拿來跑 firefox,但是這樣很麻煩,消耗的系統資源又多,實在不划算。用 lxc 的話也滿不錯,但是只跑 firefox,殺雞焉用牛刀,chroot 就很夠用。

使用 chroot 麻煩地方在於,要掛載原本 root 底下的 /proc、/dev/pts 到 chroot 環境,要有音效,還要掛載 /dev/snd,webcam 的話,就要將整個 /dev 也掛載,就要手動建立 /dev/video0 這個裝置,再將 /dev/shm 也掛載到 chroot 底下才行。

若僅使用一次,那手動掛載沒問題,可是一天要使用幾十次的話,真的會煩死人。因此就要使用 schroot 來做 chroot 的功能,會自動幫忙掛載預先設定好的 filesystem,而且可以一般使用者來呼叫 schroot (因為有 setuid),chroot 則一定要使用 root 才行,在只有單人的桌面系統上使用 schroot 沒什麼問題,多人系統就比較危險了。


首先以 debootstrap 建立一個基本的 chroot 環境:
$ sudo apt-get install debootstrap

$ sudo debootstrap wheezy /media/share/chroots/wheezy http://free.nchc.org.tw/debian

裝上 schroot
$ sudo apt-get install schroot

設定 schroot
/etc/schroot/schroot.conf

[wheezy]
description=Debian Wheezy compiling environment
type=directory
directory=/media/share/chroots/wheezy/
users=john
setup.fstab=mysetup/fstab.wheezy

[iceweasel]
description=Debian Wheezy only run iceweasel
type=directory
directory=/media/share/chroots/iceweasel
users=john
preserve-environment=true
setup.fstab=mysetup/fstab.iceweasel

上面有二個 chroot 的範例,第一台是 wheezy,平常拿來編譯程式用,因為想讓平常的桌面環境乾淨點,沒有裝如 build-essential gcc make 等工具,要編程式,就到 chroot 底下去編譯。

第二個 iceweasel 則是專門用來執行 firefox,而且只執行 firefox,由於 license 的問題,在 debian 中的 firefox 叫做 iceweasel(註2)。

description: 文字說明
type: chroot 種類,可分成 plain(註3), directory, file, loopback, block-device, btrfs-snapshot, lvm-snapshot
directory: 若 type 為 plain 或 directory,則這裡指向 chroot 所在目錄
users: 以哪個身份來執行
setup.fstab: 進入 chroot 要自動掛載哪些 filesystem,檔案在 /etc/schroot 底下,不能指定絕對路徑,否則會失敗。
preserve-environment: 保留目前環境變數,方便執行 chroot 裡的圖形介面程式,否則還要手動 export DISPLAY, xauth 等等。

還有很多其他參數,請自行 man schroot.conf

接著設定進入 chroot 後要掛載的檔案系統
/etc/schroot/mysetup/fstab.wheezy
/proc /proc none rw,bind 0 0
/dev/pts /dev/pts none rw,bind 0 0

/etc/schroot/mysetup/fstab.iceweasel
/proc /proc none rw,bind 0 0
/dev/pts /dev/pts none rw,bind 0 0
/dev/snd /dev/snd none rw,bind 0 0


自動執行 script
schroot 會自動執行 /etc/schroot/setup.d/ 底下所找到的 scripts,當 chroot 啟動時會用檔名順序並且以 「setup-start」選項執行,而離開 chroot 時會用相反順序並以「setup-stop」選項執行。可以在現有的檔案中增加你想進行的動作,也可以自己建立新的 script。


設定好後以指令檢查是否正確:

列出所有 chroots:
$ schroot --list
chroot:iceweasel
chroot:wheezy

檢視某個 chroot 詳細資訊:
$ schroot --info wheezy

檢視所有參數及目前設定值:
$ schroot --config

只執行一行指令就跳出:
$ schroot -c wheezy -- ls /tmp

進入 chroot:
$ schroot -c wheezy

在進入 chroot 後,再安裝其他相關程式
$ schroot -c iceweasel
(iceweasel)$ sudo apt-get install iceweasel xfonts-arphic-ukai xfonts-arphic-uming

以後要執行 chroot 裡的 firefox 就下指令:
$ schroot -c iceweasel iceweasel &

小弟都是用 xbindkeys 熱鍵啟動,放在 ~/.xbindkeysrc 中即可,和在原本的環境中沒二樣。也可自己寫個 desktop file 放在桌面( ~/.local/share/applications/ ),一點擊就啟動,完全忘了是在 chroot 環境中。


要共享下載的東西,也要將 /home/john/Downloads 目錄也加入才行。
/etc/schroot/mysetup/fstab.iceweasel
/home/john/Downloads /home/john/Downloads none rw,bind 0 0


至於更新,將 /var/cache/apt/archives 也掛載到 chroot 中即可,才不用重覆下載更新檔。


schroot 真的是非常好用,讓原本麻煩的 chroot 一下子就變得輕鬆多了,另外還支援 union fs 或 aufs 讓多個 chroot 可共享一個 base,又可同時寫入資料,可節省很多空間。



參考連結:

1. http://thenextweb.com/google/2012/11/13/google-declares-flash-is-now-fully-sandboxed-in-chrome-for-windows-mac-linux-and-chrome-os/

2. 大致上是因為 firefox 官方只支援少數 2,3 個平台 debian 為了支援 10 幾個平台,所以有對 firefox 上了很多 patch,但 mozilla 又不接受 debian 所做的 patch 整合到 firefox 裡,然後 mozilla 不允許 debian 改過的版本還叫 firefox,所以 debian 只好用 fork 出一個 iceweasel。而 thunderbird 則改用 icedove。
http://en.wikipedia.org/wiki/Iceweasel
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=354622
http://lists.debian.org/debian-legal/2004/12/msg00328.html

3. 基本上 plain 和 directory 是一樣的,差別在於 plain 就和一般 chroot 一模一樣,全部都手動來,而 directory 則會自動幫忙掛載 filesystem 等等。

4. 好用的 chroot
http://novus.pixnet.net/blog/post/29322140