2013年3月5日 星期二
VirtualBox 的 share folder 功能
安裝在 Oracle VM VirtualBox 中的 Guest OS,可以和 Host OS 分享資料夾。
以下是個人的使用方式:
Guest OS: Fedora 10
Host OS: Windows 7
在 Host OS 中建立一個資料夾名為 Images。
在 VirtualBox 的選單列中選取「裝置->共用資料夾...」。
新增這個 Images 資料夾到共用資料夾中。
在 Guest OS (Linux) 中輸入以下指令:
# mkdir /home/fedora/IMAGE
# mount -t vboxsf Images /home/fedora/IMAGE
做完上述步驟之後,即可在 Guest 和 Host 之間分享檔案。
唯時間上的同步有一點小問題,對於檔案時間有嚴格要求的分享可能會產生問題。
2012年12月28日 星期五
brctl 的簡介
brctl - ethernet bridge administration
工具套件名稱為 bridge-utils
可以依照自己使用的distribution做軟體安裝的動作
# sudo apt-get install bridge-utils
[BRIDGE INSTANCES]
新增橋接器「br0」
# brctl addbr br0
刪除橋接器
# brctl delbr br0
[PORTS]
將網卡「eth0」新增到橋接器「br0」中
# brctl addif br0 eth0
將網卡「eth0」從橋接器「br0」中移除
# brctl delif br0 eth0
檢視橋接器
# brctl show
工具套件名稱為 bridge-utils
可以依照自己使用的distribution做軟體安裝的動作
# sudo apt-get install bridge-utils
[BRIDGE INSTANCES]
新增橋接器「br0」
# brctl addbr br0
刪除橋接器
# brctl delbr br0
[PORTS]
將網卡「eth0」新增到橋接器「br0」中
# brctl addif br0 eth0
將網卡「eth0」從橋接器「br0」中移除
# brctl delif br0 eth0
檢視橋接器
# brctl show
2012年11月16日 星期五
程式設計師的自我修養 - 筆記
所謂同步,即指在一個thread存取資料未結束的時候,其他thread不得存取同一個資料
mutex 與 binary semaphore 的不同點:
mutex 的 acqurie 和 release 需要同一個 thread 執行
也就是 解鈴還需繫鈴人
但binary semaphore 可以由不同的 threads 執行
編譯過程一般可分為六步:
掃描(詞法分析) scanner
語法分析 parser
語意分析 semantic analyer
原始碼最佳化 source code optimizer
目的碼產生 code generator
目的碼最佳化 code optimizer
目的檔的內容:
程式碼區段 code section
=> .text | .code
=> 存放編譯後的machine code
資料區段 data section
=> .data
=> 存放全域變數和區域靜態變數 [已初始化]
定數量未初始化區段 Block Started by Symbol section
=> .bss
=> 存放全域變數和區域靜態變數 [未初始化]
=> 在檔案中不佔據空間
唯讀區段
=> .rodata
=> 存放唯讀變數和字串常數
mutex 與 binary semaphore 的不同點:
mutex 的 acqurie 和 release 需要同一個 thread 執行
也就是 解鈴還需繫鈴人
但binary semaphore 可以由不同的 threads 執行
編譯過程一般可分為六步:
掃描(詞法分析) scanner
語法分析 parser
語意分析 semantic analyer
原始碼最佳化 source code optimizer
目的碼產生 code generator
目的碼最佳化 code optimizer
目的檔的內容:
程式碼區段 code section
=> .text | .code
=> 存放編譯後的machine code
資料區段 data section
=> .data
=> 存放全域變數和區域靜態變數 [已初始化]
定數量未初始化區段 Block Started by Symbol section
=> .bss
=> 存放全域變數和區域靜態變數 [未初始化]
=> 在檔案中不佔據空間
唯讀區段
=> .rodata
=> 存放唯讀變數和字串常數
2012年11月15日 星期四
Linux SDIO driver programming
Open Source 的 standard SDIO stack 大約在 2.6.24 的時候,由 Pierre Ossman 加入 Linux kernel。某種程度上,SDIO stack 是基於 MMC stack 發展出來的,所以蠻多功能會用到 MMC 這個詞。稍微簡介一下檔案放置的位置:
以下節錄自 {kernel_source_tree}/drivers/mmc/card/sdio_uart.c
------------------------------------------------------------------------------------
static const struct sdio_device_id sdio_uart_ids[] = {
{ SDIO_DEVICE_CLASS(SDIO_CLASS_UART) },
{ SDIO_DEVICE_CLASS(SDIO_CLASS_GPS) },
{ /* end: all zeroes */ },
};
MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);
static struct sdio_driver sdio_uart_driver = {
.probe = sdio_uart_probe,
.remove = sdio_uart_remove,
.name = "sdio_uart", /* 驅動程式名稱 */
.id_table = sdio_uart_ids,
};
------------------------------------------------------------------------------------
有寫過 Linux USB device driver 的人,應該會覺得 SDIO 註冊 device driver 的方式非常類似於 USB,寫起 SDIO 版本的驅動應該就比較不陌生。首先是要先填寫 struct sdio_driver 的結構體,填寫 struct sdio_driver 所要準備的有兩個 callback function 成員,一個是 probe,另一個是 remove,即探測和移除函數,它們分別在裝置插入和拔出的時候被呼叫,用於初始化和釋放軟硬體資源。而 struct sdio_driver 的 id_table 成員描述了這個 SDIO 驅動程式所支援的裝置清單,它指向一個 sdio_device_id 的陣列,你可以使用下列巨集來產生該陣列成員:
而在填完 struct sdio_driver 之後,你可以使用下列這兩個函數來註冊和註銷 sdio_driver:
註冊完 sdio_driver 之後,系統便可以在裝置插拔的時候呼叫對應的 probe 和 remove 函數。
可以看到這兩個函數的第一個指標參數型別都是 struct sdio_func,定義如下:
/*
* SDIO function devices
*/
struct sdio_func {
struct mmc_card *card; /* the card this device belongs to */
struct device dev; /* the device */
sdio_irq_handler_t *irq_handler; /* IRQ callback */
unsigned int num; /* function number */
unsigned char class; /* standard interface class */
unsigned short vendor; /* vendor id */
unsigned short device; /* device id */
unsigned max_blksize; /* maximum block size */
unsigned cur_blksize; /* current block size */
unsigned enable_timeout; /* max enable timeout in msec */
unsigned int state; /* function state */
#define SDIO_STATE_PRESENT (1<<0 color="#0000ff" font="font" nbsp="nbsp">0>
/* present in sysfs */
u8 tmpbuf[4]; /* DMA:able scratch buffer */
unsigned num_info; /* number of info strings */
const char **info; /* info strings */
struct sdio_func_tuple *tuples;
};
這個參數應是 kernel 取得 SDIO device 資訊並填好之後傳過來的,之所以要講到這個參數,是因為 driver code 中會利用到下列巨集設定/取得驅動程式私有的資料結構。
假設驅動程式私有資料結構為 struct foo_priv 且其內嵌 struct sdio_func,舉例如下:
static int foo_probe( struct sdio_func *func, const struct sdio_device_id *id )
{
struct foo_priv *priv = kmalloc( sizeof(struct foo_priv), GFP_KERNEL );
priv->func = func;
sdio_set_drvdata(func, priv);
}
static void foo_remove( struct sdio_func *func )
{
struct foo_priv *priv = sdio_get_drvdata(func);
priv->func = NULL;
}
接下來,在與 SDIO device 做 IO 之前,需要在 start 函數中 enable device:
同樣地,做完 IO 之後,需要再 stop 函數之中 disable device:
一些 SDIO 的 Read/Write function 列表如下:
以上的 SDIO R/W functions 都是基於 mmc_io_rw_direct() 發展出來的。
最後,一個完整實作的例子可以參考
{kernel_source_tree}/drivers/mmc/card/sdio_uart.c
作者 Nicolas Pitre 是利用 SDIO interface 實作一個 UART driver,所以對上層 USER space 的介面是 TTY driver,可是底層 IO 的部分利用到 SDIO 提供的 Read/Write API 做讀寫。
[Reference]
Linux kernel source
http://www.varsanofiev.com/inside/WritingLinuxSDIODrivers.htm
http://blog.csdn.net/gangyanliang/article/details/6873578
- mmc/host 包含了 host adapter drivers,其中的 sdhci 是本文主要使用的 adapter
- mmc/core 包含了 mmc subsystem code (mmc_core)
- mmc/card 包含了使用 MMC/SDIO bus 的 device drivers,sdio_uart 是一個例子
以下節錄自 {kernel_source_tree}/drivers/mmc/card/sdio_uart.c
------------------------------------------------------------------------------------
static const struct sdio_device_id sdio_uart_ids[] = {
{ SDIO_DEVICE_CLASS(SDIO_CLASS_UART) },
{ SDIO_DEVICE_CLASS(SDIO_CLASS_GPS) },
{ /* end: all zeroes */ },
};
MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);
static struct sdio_driver sdio_uart_driver = {
.probe = sdio_uart_probe,
.remove = sdio_uart_remove,
.name = "sdio_uart", /* 驅動程式名稱 */
.id_table = sdio_uart_ids,
};
------------------------------------------------------------------------------------
有寫過 Linux USB device driver 的人,應該會覺得 SDIO 註冊 device driver 的方式非常類似於 USB,寫起 SDIO 版本的驅動應該就比較不陌生。首先是要先填寫 struct sdio_driver 的結構體,填寫 struct sdio_driver 所要準備的有兩個 callback function 成員,一個是 probe,另一個是 remove,即探測和移除函數,它們分別在裝置插入和拔出的時候被呼叫,用於初始化和釋放軟硬體資源。而 struct sdio_driver 的 id_table 成員描述了這個 SDIO 驅動程式所支援的裝置清單,它指向一個 sdio_device_id 的陣列,你可以使用下列巨集來產生該陣列成員:
- SDIO_DEVICE( vendor, device )
- SDIO_DEVICE_CLASS( device_class )
而在填完 struct sdio_driver 之後,你可以使用下列這兩個函數來註冊和註銷 sdio_driver:
- int sdio_register_driver(struct sdio_driver *);
- void sdio_unregister_driver(struct sdio_driver *);
註冊完 sdio_driver 之後,系統便可以在裝置插拔的時候呼叫對應的 probe 和 remove 函數。
- int (*probe)(struct sdio_func *, const struct sdio_device_id *);
- void (*remove)(struct sdio_func *);
可以看到這兩個函數的第一個指標參數型別都是 struct sdio_func,定義如下:
/*
* SDIO function devices
*/
struct sdio_func {
struct mmc_card *card; /* the card this device belongs to */
struct device dev; /* the device */
sdio_irq_handler_t *irq_handler; /* IRQ callback */
unsigned int num; /* function number */
unsigned char class; /* standard interface class */
unsigned short vendor; /* vendor id */
unsigned short device; /* device id */
unsigned max_blksize; /* maximum block size */
unsigned cur_blksize; /* current block size */
unsigned enable_timeout; /* max enable timeout in msec */
unsigned int state; /* function state */
#define SDIO_STATE_PRESENT (1<<0 color="#0000ff" font="font" nbsp="nbsp">0>
/* present in sysfs */
u8 tmpbuf[4]; /* DMA:able scratch buffer */
unsigned num_info; /* number of info strings */
const char **info; /* info strings */
struct sdio_func_tuple *tuples;
};
- sdio_get_drvdata(struct sdio_func*)
- sdio_set_drvdata(struct sdio_func*, void *data)
假設驅動程式私有資料結構為 struct foo_priv 且其內嵌 struct sdio_func,舉例如下:
static int foo_probe( struct sdio_func *func, const struct sdio_device_id *id )
{
struct foo_priv *priv = kmalloc( sizeof(struct foo_priv), GFP_KERNEL );
priv->func = func;
sdio_set_drvdata(func, priv);
}
static void foo_remove( struct sdio_func *func )
{
struct foo_priv *priv = sdio_get_drvdata(func);
priv->func = NULL;
}
接下來,在與 SDIO device 做 IO 之前,需要在 start 函數中 enable device:
- sdio_claim_host(priv->func); //取得 MMC host controller 的物理使用權
- ret = sdio_enable_func(priv->func); //Enable SDIO function
- ret = sdio_claim_irq(priv->func, foo_irq); //註冊 IRQ handler
- sdio_release_host(priv->func); //歸還 MMC host controller 的物理使用權
同樣地,做完 IO 之後,需要再 stop 函數之中 disable device:
- sdio_claim_host(priv->func); //取得 MMC host controller 的物理使用權
- sdio_release_irq(priv->func); //Disable SDIO function
- sdio_disable_func(priv->func); //註銷 IRQ handler
- sdio_release_host(priv->func); //歸還 MMC host controller 的物理使用權
一些 SDIO 的 Read/Write function 列表如下:
- 1: sdio_readb
- 2: sdio_readw
- 4: sdio_readl
- 1: sdio_writeb
- 2: sdio_writew
- 4: sdio_writel
以上的 SDIO R/W functions 都是基於 mmc_io_rw_direct() 發展出來的。
最後,一個完整實作的例子可以參考
{kernel_source_tree}/drivers/mmc/card/sdio_uart.c
作者 Nicolas Pitre 是利用 SDIO interface 實作一個 UART driver,所以對上層 USER space 的介面是 TTY driver,可是底層 IO 的部分利用到 SDIO 提供的 Read/Write API 做讀寫。
[Reference]
Linux kernel source
http://www.varsanofiev.com/inside/WritingLinuxSDIODrivers.htm
http://blog.csdn.net/gangyanliang/article/details/6873578
2012年11月5日 星期一
How to become a Linux Device Driver Programmer
本文只是想就自己的經驗與資料作個整理,讓一些有志開發 LDD (Linux Device Driver) 的新手可以有跡可循,畢竟這些只是自己跌跌撞撞的經驗,說不上參考,但還是希望能夠幫助到某些人。
第四步,作為 kernel 開發者來學習 Linux。
之所以要走這一步的原因是因為開發 LDD 跟 kernel 息息相關,kernel 定義了許多介面要求 LDD 開發者遵守,並也提供了大量的 API 供 LDD 開發者使用。這樣有一個好處是分層可以分得很明確,User space program 跟 driver之間就沒有 dependency 的問題。另外,kernel 是由許多的 subsystem 組成,一個 LDD 不可能不跟這些 subsystem 互動,所以理解 kernel 的組成也是很重要的知識。
這部分我推薦閱讀 Robert Love 寫的「Linux kernel Development」,這本書由一種較宏觀的角度來介紹 kernel,細節沒有觸碰得太多,對於 kernel 初學者來說應該是比較好吸收的一本書。另外就是,除了實作需要之外,LDD 開發者也不太需要整個 kernel 都瞭若指掌,用到的時候再深入理解我覺得會比較符合人性,畢竟 kernel 是一隻蠻恐怖的大怪獸。
第一步,作為使用者來學習 Linux。
這其實是個蠻大的門檻,我覺得在這之中有以下兩點特別重要:
這其實是個蠻大的門檻,我覺得在這之中有以下兩點特別重要:
- Linux kernel 是什麼,它又負責做什麼事情?
- 檔案與目錄管理,包含權限的了解
這部分可以參考「鳥哥的 Linux 私房菜」網站,該站有非常豐富的資源,講解也是簡單易懂!
第二步,學習 C,並嘗試在 Linux 底下開發可以在 Linux 執行的程式。
有了 Linux 的基礎之後,接下來就是自己嘗試開發程式,這時候開發的程式屬於 User space 範疇,我建議可以在此時多多使用各種 IO 相關的 Linux C API。
這部分我推薦閱讀 K&R 的「The C Programming Language」,這本書其實不太適合程式設計新手,所以可能還要另外找一本自己看得順眼的 C 入門書輔助閱讀。其實 LDD 的開發並沒有什麼太難的 C 語法,能夠通盤理解 K&R 的 C 語言聖經本就已經是非常熟稔 C 語言了。
第三步,開發 kernel module。
有了 Linux 的基礎之後,接下來就是自己嘗試開發程式,這時候開發的程式屬於 User space 範疇,我建議可以在此時多多使用各種 IO 相關的 Linux C API。
這部分我推薦閱讀 K&R 的「The C Programming Language」,這本書其實不太適合程式設計新手,所以可能還要另外找一本自己看得順眼的 C 入門書輔助閱讀。其實 LDD 的開發並沒有什麼太難的 C 語法,能夠通盤理解 K&R 的 C 語言聖經本就已經是非常熟稔 C 語言了。
第三步,開發 kernel module。
這一步我自己走的有點亂,也還沒整理好自己的經驗,不過我推薦以下幾本好書,讀者一定能從其中得到收穫。(之後有空再來重寫這段 XD)
Linux Device Driver 3rd Edition, O'REILLY 出版
Linux 裝置驅動程式之開發詳解 第二版, 松崗出版
Linux Device Driver Programming, 博碩出版
Linux Device Driver 3rd Edition, O'REILLY 出版
Linux 裝置驅動程式之開發詳解 第二版, 松崗出版
Linux Device Driver Programming, 博碩出版
第四步,作為 kernel 開發者來學習 Linux。
之所以要走這一步的原因是因為開發 LDD 跟 kernel 息息相關,kernel 定義了許多介面要求 LDD 開發者遵守,並也提供了大量的 API 供 LDD 開發者使用。這樣有一個好處是分層可以分得很明確,User space program 跟 driver之間就沒有 dependency 的問題。另外,kernel 是由許多的 subsystem 組成,一個 LDD 不可能不跟這些 subsystem 互動,所以理解 kernel 的組成也是很重要的知識。
這部分我推薦閱讀 Robert Love 寫的「Linux kernel Development」,這本書由一種較宏觀的角度來介紹 kernel,細節沒有觸碰得太多,對於 kernel 初學者來說應該是比較好吸收的一本書。另外就是,除了實作需要之外,LDD 開發者也不太需要整個 kernel 都瞭若指掌,用到的時候再深入理解我覺得會比較符合人性,畢竟 kernel 是一隻蠻恐怖的大怪獸。
2012年3月30日 星期五
SSL Programming
[Reference]
http://www.openssl.org/docs/ssl/ssl.html
http://daydreamer.idv.tw/rewrite.php/read-62.html
http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s03.html
http://www.ibm.com/developerworks/cn/linux/l-openssl.html
http://blog.csdn.net/playmud/article/details/1527438
http://www.rtfm.com/openssl-examples/part1.pdf
http://www.openssl.org/docs/ssl/ssl.html
http://daydreamer.idv.tw/rewrite.php/read-62.html
http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s03.html
http://www.ibm.com/developerworks/cn/linux/l-openssl.html
http://blog.csdn.net/playmud/article/details/1527438
http://www.rtfm.com/openssl-examples/part1.pdf
struct socket & struct sock 分析
User space application 透過下列函式的調用取得 socket descriptor
在system call中,這個sockfd就會被映射成一個表示socket的struct
下面是其完整定義
state用於表示socket所處的狀態,不過此成員只對TCP socket有用
因為TCP是connection-oriented的protocol,需要維護socket狀態
[Reference] http://miox.cc/2009/05/struct-socket.html
int socket(int domain, int type, int protocol); 在system call中,這個sockfd就會被映射成一個表示socket的struct
下面是其完整定義
struct socket {
socket_state state;
unsigned long flags;
const struct proto_ops *ops;
struct fasync_struct *fasync_list;
struct file *file;
struct sock *sk;
wait_queue_head_t wait;
short type;
}; state用於表示socket所處的狀態,不過此成員只對TCP socket有用
因為TCP是connection-oriented的protocol,需要維護socket狀態
[Reference] http://miox.cc/2009/05/struct-socket.html
2012年3月28日 星期三
New API (NAPI)
NAPI 是設計用來增進高速網路的效能。
原本網路封包是利用中斷機制通知核心來收取封包,
但在高速網路下,大量的中斷反而會吃掉大量的CPU運算資源來做context switch
[Reference]
http://lwn.net/Articles/30107/
原本網路封包是利用中斷機制通知核心來收取封包,
但在高速網路下,大量的中斷反而會吃掉大量的CPU運算資源來做context switch
[Reference]
http://lwn.net/Articles/30107/
2012年3月27日 星期二
Linux 等待佇列(Wait queue)機制原理分析
[Reference]
http://blog.chinaunix.net/space.php?uid=20643761&do=blog&id=1594859
2011年12月27日 星期二
2011年6月16日 星期四
Introduction to IPsec
IPsec protocols主要可以分為兩大種類:
1. packet handling
主要工作是將 normal IP packets 轉成 secure IPsec packets
對packets修改的動作有以下幾種,
加密(encryption)
解密(decryption)
簽章(signing)
封裝(encapsulation)
解封裝(decapsulation)
因為由於對packets的修改動作要求速度、效率以及低延遲
所以這些動作都由 kernel 來完成
2. trust relationship management
1. packet handling
主要工作是將 normal IP packets 轉成 secure IPsec packets
對packets修改的動作有以下幾種,
加密(encryption)
解密(decryption)
簽章(signing)
封裝(encapsulation)
解封裝(decapsulation)
因為由於對packets的修改動作要求速度、效率以及低延遲
所以這些動作都由 kernel 來完成
2. trust relationship management
2010年10月8日 星期五
憑證格式的介紹與轉換
X.509是常見通用的憑證格式標準
其他跟憑證有關係的標準則都定義在 PKCS 當中
PKCS 為 Public-Key Cryptography Standard 的縮寫
目前共發布過15個標準,細節可參考 Reference 中的wiki
管理存儲憑證常用的格式有以下幾類:[from wikipedia 公開金鑰密碼編譯標準]
PKCS#6 證書擴展語法標準(Extended-Certificate Syntax Standard)
將原本X.509的證書格式標準加以擴充。
PKCS#7 密碼訊息語法標準(Cryptographic Message Syntax Standard)
規範了以公開金鑰基礎設施(PKI)所產生之簽章/密文之格式。
其目的一樣是為了拓展數位證書的應用。其中,包含了S/MIME與CMS。
PKCS#10 證書申請標準(Certification Request Standard)
規範了向證書中心申請證書之CSR(certificate signing request)的格式。
PKCS#12 個人訊息交換標準(Personal Information Exchange Syntax Standard)
定義了包含私鑰與公鑰證書(public key certificate)的文件格式。
私鑰採密碼(password)保護。常見的PFX就履行了PKCS#12。
X.509 DER encoding 的 postfix 為 .der (BINARY)
X.509 PEM encoding 的 postfix 為 .pem (ASCII)
<格式轉換>
$ openssl rsa -in privatekey.pem -inform PEM -out privatekey.der -outform DER
$ openssl rsa -in privatekey.der -inform DER -out privatekey.pem -outform PEM
PKCS#7 常用的 postfix 有 .p7b .p7c .spc
p7b 以樹狀展示 certficate chain,不含 private key
PKCS#12 常用的 postfix 有 .p12 .pfx(MS)
p12/pfx 用於存放 certificate 加 private key
將此兩樣打包的過程中會要求輸入 Export Password 來保護這個p12檔案
相反地,你要取用p12檔案中的個別資訊時,就需要輸入 Import Password來解開保護
*Import/Export Password為同樣一組,只是方向不同
[Reference]
公開金鑰密碼編譯標準
http://zh.wikipedia.org/zh-hk/公開金鑰密碼編譯標準
常见证书格式及相互转换
http://355665.blog.51cto.com/345665/265679
其他跟憑證有關係的標準則都定義在 PKCS 當中
PKCS 為 Public-Key Cryptography Standard 的縮寫
目前共發布過15個標準,細節可參考 Reference 中的wiki
管理存儲憑證常用的格式有以下幾類:[from wikipedia 公開金鑰密碼編譯標準]
PKCS#6 證書擴展語法標準(Extended-Certificate Syntax Standard)
將原本X.509的證書格式標準加以擴充。
PKCS#7 密碼訊息語法標準(Cryptographic Message Syntax Standard)
規範了以公開金鑰基礎設施(PKI)所產生之簽章/密文之格式。
其目的一樣是為了拓展數位證書的應用。其中,包含了S/MIME與CMS。
PKCS#10 證書申請標準(Certification Request Standard)
規範了向證書中心申請證書之CSR(certificate signing request)的格式。
PKCS#12 個人訊息交換標準(Personal Information Exchange Syntax Standard)
定義了包含私鑰與公鑰證書(public key certificate)的文件格式。
私鑰採密碼(password)保護。常見的PFX就履行了PKCS#12。
X.509 DER encoding 的 postfix 為 .der (BINARY)
X.509 PEM encoding 的 postfix 為 .pem (ASCII)
<格式轉換>
$ openssl rsa -in privatekey.pem -inform PEM -out privatekey.der -outform DER
$ openssl rsa -in privatekey.der -inform DER -out privatekey.pem -outform PEM
PKCS#7 常用的 postfix 有 .p7b .p7c .spc
p7b 以樹狀展示 certficate chain,不含 private key
PKCS#12 常用的 postfix 有 .p12 .pfx(MS)
p12/pfx 用於存放 certificate 加 private key
將此兩樣打包的過程中會要求輸入 Export Password 來保護這個p12檔案
相反地,你要取用p12檔案中的個別資訊時,就需要輸入 Import Password來解開保護
*Import/Export Password為同樣一組,只是方向不同
[Reference]
公開金鑰密碼編譯標準
http://zh.wikipedia.org/zh-hk/公開金鑰密碼編譯標準
常见证书格式及相互转换
http://355665.blog.51cto.com/345665/265679
2010年8月3日 星期二
OpenSSL Certificate Management
#
# 製作 RSA Private Key,並且將 Key 設定為只有 owner 才能存取的權限
#
openssl genrsa -out myhost.key.pem 2048
chmod og-rwx myhost.key.pem
*** genrsa 是 openssl 產生 rsa key 用的 command ***
*** -out 是表示 output 的 key name ***
*** 2048 是 key 的強度,一定要放在最後面 ***
#
# 填寫憑證申請書
#
openssl req -new -key myhost.key.pem -out myhost.req.pem
*** req 是 openssl 產生 CSR 用的 command ***
X.509 Certificate Signing Request (CSR) Management
*** -new 是產生新的 certificate request ***
*** -key 是指定要從哪邊讀 private key ***
*** -out 是表示 output 的 request name ***
#
# 顯示憑證申請書
#
openssl req -text -noout -in myhost.req.pem
*** -text 是印出 CSR 的 text form ***
*** -noout 是不要印出 CSR 的 encoded form ***
*** -in 表明要處理的 request file ***
#
# 簽憑證 (CA certificate)
#
openssl x509 -req -days 7305 -sha1 \
-extfile ~/etc/ssl/openssl.cnf -extensions v3_ca \
-signkey ~/etc/ssl/private/myrootca.key.pem \
-in ~/tmp/myrootca.req.pem -out ~/etc/ssl/certs/myrootca.crt.pem
*** x509 是證書資料管理的 command ***
*** -req 特別表示處理的是 request file,一般都是 certificate ***
*** -days 表明證書的有效天數 ***
*** -sha1 表示要使用的 digest 演算法 ***
*** -extfile 表示包含 certificate extensions 的檔案 ***
file containing certificate extensions to use
If not specified then no extensions are added to the certificate
*** -extensions v3_ca ***
the section to add certificate extensions from
*** -signkey 表示要用哪一把 private key 去 self-sign request ***
this option causes the input file to be self signed using the supplied private key
#
# 簽憑證 (Server certificate)
#
openssl x509 -req -days 3650 -sha1 \
-extfile ~/etc/ssl/openssl.cnf -extensions v3_req \
-CA ~/etc/ssl/certs/myrootca.crt.pem -CAkey ~/etc/ssl/private/myrootca.key.pem \
-CAserial ~/etc/ssl/myrootca.srl -CAcreateserial \
-in /tmp/myhost.req.pem -out ~/etc/ssl/certs/myhost.crt.pem
*** -CA ***
specifies the CA certificate to be used for signing
*** -CAkey ***
sets the CA private key to sign a certificate with.
If this option is not specified then it is assumed that the CA private key is present in the CA certificate file
*** -CAserial ***
sets the CA serial number file to use
*** -CAcreateserial ***
with this option the CA serial number file is created if it does not
#
# 顯示憑證
#
openssl x509 -text -noout -in myhost.crt.pem
[Reference]
如何製作 SSL X.509 憑證
http://www.imacat.idv.tw/tech/sslcerts.html
OpenSSL official Documents
http://www.openssl.org/docs/apps/openssl.html
# 製作 RSA Private Key,並且將 Key 設定為只有 owner 才能存取的權限
#
openssl genrsa -out myhost.key.pem 2048
chmod og-rwx myhost.key.pem
*** genrsa 是 openssl 產生 rsa key 用的 command ***
*** -out 是表示 output 的 key name ***
*** 2048 是 key 的強度,一定要放在最後面 ***
#
# 填寫憑證申請書
#
openssl req -new -key myhost.key.pem -out myhost.req.pem
*** req 是 openssl 產生 CSR 用的 command ***
X.509 Certificate Signing Request (CSR) Management
*** -new 是產生新的 certificate request ***
*** -key 是指定要從哪邊讀 private key ***
*** -out 是表示 output 的 request name ***
#
# 顯示憑證申請書
#
openssl req -text -noout -in myhost.req.pem
*** -text 是印出 CSR 的 text form ***
*** -noout 是不要印出 CSR 的 encoded form ***
*** -in 表明要處理的 request file ***
#
# 簽憑證 (CA certificate)
#
openssl x509 -req -days 7305 -sha1 \
-extfile ~/etc/ssl/openssl.cnf -extensions v3_ca \
-signkey ~/etc/ssl/private/myrootca.key.pem \
-in ~/tmp/myrootca.req.pem -out ~/etc/ssl/certs/myrootca.crt.pem
*** x509 是證書資料管理的 command ***
*** -req 特別表示處理的是 request file,一般都是 certificate ***
*** -days 表明證書的有效天數 ***
*** -sha1 表示要使用的 digest 演算法 ***
*** -extfile 表示包含 certificate extensions 的檔案 ***
file containing certificate extensions to use
If not specified then no extensions are added to the certificate
*** -extensions v3_ca ***
the section to add certificate extensions from
*** -signkey 表示要用哪一把 private key 去 self-sign request ***
this option causes the input file to be self signed using the supplied private key
#
# 簽憑證 (Server certificate)
#
openssl x509 -req -days 3650 -sha1 \
-extfile ~/etc/ssl/openssl.cnf -extensions v3_req \
-CA ~/etc/ssl/certs/myrootca.crt.pem -CAkey ~/etc/ssl/private/myrootca.key.pem \
-CAserial ~/etc/ssl/myrootca.srl -CAcreateserial \
-in /tmp/myhost.req.pem -out ~/etc/ssl/certs/myhost.crt.pem
*** -CA ***
specifies the CA certificate to be used for signing
*** -CAkey ***
sets the CA private key to sign a certificate with.
If this option is not specified then it is assumed that the CA private key is present in the CA certificate file
*** -CAserial ***
sets the CA serial number file to use
*** -CAcreateserial ***
with this option the CA serial number file is created if it does not
#
# 顯示憑證
#
openssl x509 -text -noout -in myhost.crt.pem
[Reference]
如何製作 SSL X.509 憑證
http://www.imacat.idv.tw/tech/sslcerts.html
OpenSSL official Documents
http://www.openssl.org/docs/apps/openssl.html
2010年7月16日 星期五
major number 和 device node 以及 device driver 間的關係
每個 device 會有一組 (Major number, Minor number) 來作為區別的資訊
到 /dev 資料夾底下,使用 ls -l 就可得到各個 device node的資訊
以 ppp 這個 device node為例,ls -l 輸出如下
crw------- 1 root root 108, 0 Apr 21 12:46 ppp
前面的 permission field 中,第一個字元 c 表示這個 device 是 char device
接下來介於 Group name 之後,Modification date 之前
就是 ppp 這個 device 的 (major number, minor number) 資訊 108,0
有了 device node 與 (major,minor) 之間關係的觀念後
接下來就來探討 device driver 和 (major,minor) 有什麼樣的關係
關係圖:device node --- (major,minor) --- device driver
恰巧,這個關係也就是為什麼 kernel 能正確找到 device 其所有的 driver 的原因
答案很簡單
device driver 需要向 kernel 註冊其所屬 device 的 (major,minor) pair
接下來就來解釋為什麼會有(major,minor)這樣的資訊存在
在系統中新增一個硬體,許多環節彼此相扣
driver 向 kernel 註冊一些 handler software 以及一些 hardware 資源 (io ports,etc)
好讓 kernel 得知此 hardware 的存在,並且接受此 hardware 的 interrupt
在 /dev 底下需要替這個 hardware 新建一個 device node 好讓 kernel 可以使用它
但這項工作不是 driver 的 job
因此需要手動建立這個 device node
而 device node 的 (major,minor) 資訊
需要和 driver 中向 kernel 註冊的 (major,minor) 一樣
因此 kernel 就可經由 (major,minor) 搭建起來的橋樑找到 hardware 和 driver 的關連
也就是此關係圖:device node --- (major,minor) --- device driver
到 /dev 資料夾底下,使用 ls -l 就可得到各個 device node的資訊
以 ppp 這個 device node為例,ls -l 輸出如下
crw------- 1 root root 108, 0 Apr 21 12:46 ppp
前面的 permission field 中,第一個字元 c 表示這個 device 是 char device
接下來介於 Group name 之後,Modification date 之前
就是 ppp 這個 device 的 (major number, minor number) 資訊 108,0
有了 device node 與 (major,minor) 之間關係的觀念後
接下來就來探討 device driver 和 (major,minor) 有什麼樣的關係
關係圖:device node --- (major,minor) --- device driver
恰巧,這個關係也就是為什麼 kernel 能正確找到 device 其所有的 driver 的原因
答案很簡單
device driver 需要向 kernel 註冊其所屬 device 的 (major,minor) pair
接下來就來解釋為什麼會有(major,minor)這樣的資訊存在
在系統中新增一個硬體,許多環節彼此相扣
- hardware
- driver
- Linux OS 中配給硬體的 dev node (在 /dev 底下)
driver 向 kernel 註冊一些 handler software 以及一些 hardware 資源 (io ports,etc)
好讓 kernel 得知此 hardware 的存在,並且接受此 hardware 的 interrupt
在 /dev 底下需要替這個 hardware 新建一個 device node 好讓 kernel 可以使用它
但這項工作不是 driver 的 job
因此需要手動建立這個 device node
而 device node 的 (major,minor) 資訊
需要和 driver 中向 kernel 註冊的 (major,minor) 一樣
因此 kernel 就可經由 (major,minor) 搭建起來的橋樑找到 hardware 和 driver 的關連
也就是此關係圖:device node --- (major,minor) --- device driver
Linux 驅動程式的中斷處理
轉貼自 Jollen 的 Blog
Linux 驅動程式的中斷處理, #1: request_irq 基本觀念
http://www.jollen.org/blog/2008/03/interrupt_handling_1.html
Linux 驅動程式的中斷處理, #2: 深入淺出中斷模式
http://www.jollen.org/blog/2008/03/interrupt_handling_semaphore.html
Linux 驅動程式的中斷處理, #3: Bottom Half 的觀念
http://www.jollen.org/blog/2008/03/interrupt_handling_bottom_half.html
[Reference]
http://www.jollen.org/cgi-bin/mt3/mt-tb.cgi/481
Linux 驅動程式的中斷處理, #1: request_irq 基本觀念
http://www.jollen.org/blog/2008/03/interrupt_handling_1.html
Linux 驅動程式的中斷處理, #2: 深入淺出中斷模式
http://www.jollen.org/blog/2008/03/interrupt_handling_semaphore.html
Linux 驅動程式的中斷處理, #3: Bottom Half 的觀念
http://www.jollen.org/blog/2008/03/interrupt_handling_bottom_half.html
[Reference]
http://www.jollen.org/cgi-bin/mt3/mt-tb.cgi/481
2010年6月30日 星期三
網路安全工具 - nmap
nmap - Network Mapper
Network exploration tool and security / port scanner
-PN [No Ping]
$ nmap
This option skips the Nmap discovery stage altogether.
Normally, nmap uses this stage to determine active machines for heavier scanning.
Used to be -P0 <- it's a nubmer zero, not a character O
-sL [List Scan]
$ nmap -sL 192.168.1.0/24
列出子網路所有IP及對應的主機名稱,但不作ping及通訊埠偵測
(degenerate form of host discovery without sending any packets)
-sP [Port Scan]
$ nmap -sP 192.168.1.0/24
僅使用ping掃瞄子網路內的所有IP,並列出有回應的IP,不作進一步測試
-PS [TCP SYN Ping]
$ nmap -PS 192.168.1.1
偵測遠端主機已開啟的通訊埠
為縮短掃瞄時間,可指定特定的port number,例如 -PS22,23,80,25
This option sends an empty TCP packet with the SYN flag set.
-remote host responds with a RST packet (The queried port is closed)
-remote host responds with a SYN/ACK packet (The queried port is open)
利用的原理是 TCP 3-way-handshake mechanism
A --SYN--> B
A <--SYN/ACK-- B
A --ACK--> B
-PU [UDP Ping]
$ nmap -PU 192.168.1.0/24
使用UDP協定 ping 遠端的主機。
-sS [TCP SYN scan]
$ nmap -sS 192.168.1.0/24
使用 TCP SYN packet 掃瞄,這是一個半開放的掃瞄方式,
三方交握不會完成,所以掃瞄速度較快,也比較常被使用。
此選項可以列出有回應的遠端主機已開啟的網路服務埠。
-sT [TCP connect scan]
$ nmap -sT 192.168.1.0/24
如無法以 TCP SYN packet 掃瞄時,就得改用 socket API connect() 來掃瞄
在這種情況底下,connection 會被正式建立完成,花費的時間也較- sS 選項多
-sU [UDP scan]
$ nmap -sU 192.168.1.0/24
用 UDP 協定掃瞄遠端主機群
-sO [IP protocol scan]
$ nmap -sO 192.168.1.1
偵測遠端主機已開啟哪些通訊協定 TCP,UDP,ICMP,等等
-O [Enable OS detection]
nmap -O 192.168.1.1
nmap -A 192.168.1.1
偵測遠端主機的作業系統類型
-v -vv -vvv [Increase verbosity level]
nmap -v scanme.nmap.org
掃瞄遠端主機,並列出相關詳細的資訊
[example]
$ nmap -sS -O 192.168.1.0/24
以 SYN 掃瞄網域為192.168.1.0所屬 C class 網段的所有存在的主機作業系統類型
-sV [Version detection]
-p [Only scan specified ports]
$ nmap -sV -p 22,53,110,143,4564 198.116.0-255.1-127
進行主機列表及TCP掃瞄特定網路服務,-p 指定 22,53,110,143,4564 這幾個 port
遠端主機的網路含括 198.116.(0-255).(1-127) 網段
(version detection is used to determine what application is running)
-iR [Choose random targets]
$ nmap -v -iR 100000 -P0 -p 80
隨機選擇100000台主機,偵測是否開啟 Web 服務,
由於此掃瞄較耗時,所以加上 -P0(ie,-PN) 不作 active machines detection。
(The argument -iR 0(zero) can be specified for a never-ending scan)
[Reference]
http://nmap.org/book/man.html
http://idobest.pixnet.net/blog/post/22040775
Network exploration tool and security / port scanner
-PN [No Ping]
$ nmap
This option skips the Nmap discovery stage altogether.
Normally, nmap uses this stage to determine active machines for heavier scanning.
Used to be -P0 <- it's a nubmer zero, not a character O
-sL [List Scan]
$ nmap -sL 192.168.1.0/24
列出子網路所有IP及對應的主機名稱,但不作ping及通訊埠偵測
(degenerate form of host discovery without sending any packets)
-sP [Port Scan]
$ nmap -sP 192.168.1.0/24
僅使用ping掃瞄子網路內的所有IP,並列出有回應的IP,不作進一步測試
-PS [TCP SYN Ping]
$ nmap -PS 192.168.1.1
偵測遠端主機已開啟的通訊埠
為縮短掃瞄時間,可指定特定的port number,例如 -PS22,23,80,25
This option sends an empty TCP packet with the SYN flag set.
-remote host responds with a RST packet (The queried port is closed)
-remote host responds with a SYN/ACK packet (The queried port is open)
利用的原理是 TCP 3-way-handshake mechanism
A --SYN--> B
A <--SYN/ACK-- B
A --ACK--> B
-PU [UDP Ping]
$ nmap -PU 192.168.1.0/24
使用UDP協定 ping 遠端的主機。
-sS [TCP SYN scan]
$ nmap -sS 192.168.1.0/24
使用 TCP SYN packet 掃瞄,這是一個半開放的掃瞄方式,
三方交握不會完成,所以掃瞄速度較快,也比較常被使用。
此選項可以列出有回應的遠端主機已開啟的網路服務埠。
-sT [TCP connect scan]
$ nmap -sT 192.168.1.0/24
如無法以 TCP SYN packet 掃瞄時,就得改用 socket API connect() 來掃瞄
在這種情況底下,connection 會被正式建立完成,花費的時間也較- sS 選項多
-sU [UDP scan]
$ nmap -sU 192.168.1.0/24
用 UDP 協定掃瞄遠端主機群
-sO [IP protocol scan]
$ nmap -sO 192.168.1.1
偵測遠端主機已開啟哪些通訊協定 TCP,UDP,ICMP,等等
-O [Enable OS detection]
nmap -O 192.168.1.1
nmap -A 192.168.1.1
偵測遠端主機的作業系統類型
-v -vv -vvv [Increase verbosity level]
nmap -v scanme.nmap.org
掃瞄遠端主機,並列出相關詳細的資訊
[example]
$ nmap -sS -O 192.168.1.0/24
以 SYN 掃瞄網域為192.168.1.0所屬 C class 網段的所有存在的主機作業系統類型
-sV [Version detection]
-p
$ nmap -sV -p 22,53,110,143,4564 198.116.0-255.1-127
進行主機列表及TCP掃瞄特定網路服務,-p 指定 22,53,110,143,4564 這幾個 port
遠端主機的網路含括 198.116.(0-255).(1-127) 網段
(version detection is used to determine what application is running)
-iR
$ nmap -v -iR 100000 -P0 -p 80
隨機選擇100000台主機,偵測是否開啟 Web 服務,
由於此掃瞄較耗時,所以加上 -P0(ie,-PN) 不作 active machines detection。
(The argument -iR 0(zero) can be specified for a never-ending scan)
[Reference]
http://nmap.org/book/man.html
http://idobest.pixnet.net/blog/post/22040775
2010年6月29日 星期二
虛擬網卡 TUN/TAP 工作原理
TUN/TAP是一個虛擬網卡的介面,在 Linux 以及 window$ 上面都有支援
一些 VPN projects 像是 OpenVPN 都是基於這個介面實現 tunneling 的機制
tun (network TUNnel) 虛擬的是 點對點 設備
-simulates a network layer device
-layer 3 packets, such as IP packet
-used with routing
tap (network TAP) 虛擬的是 乙太網路 設備
-simulates an Ethernet device
-layer 2 packets, such as Ethernet frames
-used to create a network bridge
下圖是原作者麻利輝所畫的簡圖 (請查閱Reference中的網頁)

以下就已建立好的 VPN 連線來探討封包流經的順序:
1. Outgoing
首先,應用程式會利用 tun 這個網卡將資料送到 VPN 的 peer去
而這個應用程式正是圖中的「使用tun/tap驅動的進程」
在經過 TCP/IP protocol stack 之後來到 tun (Virtual NIC Part) 成為 VPN 封包
下一步,「數據處理進程(OpenVPN)」
會由 tun ( Char device Part) read 出剛剛的VPN封包
再次丟往 TCP/IP protocol stack,最後到達 Real NIC 而送往「物理鏈路」(外部網路)
下圖是就原圖所做的一點更動,明確表示出資料流的順序

2. Incoming
從物理鏈路收到給 OpenVPN 的封包,
接下來此封包經過 protocol stack 被拔掉一層層的 headers
最後就是原始封包的 data payload 部份,也就是 VPN"封包"
OpenVPN 再把這個 VPN"封包"經由 tun (Char device part) write 到 Virtual NIC
Virtual NIC 收到封包後,再把他送往 protocol stack
最後就回到使用 tun interface 的應用程式
圖例與 outgoing 一樣,只是數字順序相反
[Reference]
虛擬網卡 TUN/TAP 驅動程序設計原理 by 麻利輝
http://www.ibm.com/developerworks/cn/linux/l-tuntap/index.html
TUN/TAP - Wikipedia
http://en.wikipedia.org/wiki/TUN/TAP
一些 VPN projects 像是 OpenVPN 都是基於這個介面實現 tunneling 的機制
tun (network TUNnel) 虛擬的是 點對點 設備
-simulates a network layer device
-layer 3 packets, such as IP packet
-used with routing
tap (network TAP) 虛擬的是 乙太網路 設備
-simulates an Ethernet device
-layer 2 packets, such as Ethernet frames
-used to create a network bridge
下圖是原作者麻利輝所畫的簡圖 (請查閱Reference中的網頁)

以下就已建立好的 VPN 連線來探討封包流經的順序:
1. Outgoing
首先,應用程式會利用 tun 這個網卡將資料送到 VPN 的 peer去
而這個應用程式正是圖中的「使用tun/tap驅動的進程」
在經過 TCP/IP protocol stack 之後來到 tun (Virtual NIC Part) 成為 VPN 封包
下一步,「數據處理進程(OpenVPN)」
會由 tun ( Char device Part) read 出剛剛的VPN封包
再次丟往 TCP/IP protocol stack,最後到達 Real NIC 而送往「物理鏈路」(外部網路)
下圖是就原圖所做的一點更動,明確表示出資料流的順序
2. Incoming
從物理鏈路收到給 OpenVPN 的封包,
接下來此封包經過 protocol stack 被拔掉一層層的 headers
最後就是原始封包的 data payload 部份,也就是 VPN"封包"
OpenVPN 再把這個 VPN"封包"經由 tun (Char device part) write 到 Virtual NIC
Virtual NIC 收到封包後,再把他送往 protocol stack
最後就回到使用 tun interface 的應用程式
圖例與 outgoing 一樣,只是數字順序相反
[Reference]
虛擬網卡 TUN/TAP 驅動程序設計原理 by 麻利輝
http://www.ibm.com/developerworks/cn/linux/l-tuntap/index.html
TUN/TAP - Wikipedia
http://en.wikipedia.org/wiki/TUN/TAP
2010年6月28日 星期一
Linux的防火牆 - iptables
防火牆的概念在鳥哥的網站有很棒很詳盡的介紹
鳥哥關於防火牆的介紹文章網址放在reference中
下圖是鳥哥所簡化的 chain 圖,
觀賞度10,實用度10,綜合係數10 (...某足球十大精妙過人影片爛梗XD)

作為普通PC的Linux,其防火牆處理流入本機封包的流程是
1. nat-PREROUTING [跳過]
2. Forward封包轉遞 [走 flow A,因此導向本機 Linux]
3. filter-INPUT [!!本機防火牆主要工作的地方!!]
4. Linux本機的資源
5. nat-OUTPUT [跳過]
6. filter-OUTPUT [!!本機防火牆主要工作的地方!!]
7. nat-POSTROUTING [跳過]
整理以後的流程如下,
1. Forward封包轉遞
2. filter-INPUT --負責把關流入本機的封包
3. Linux本機的資源
4. filter-OUTPUT --負責把關流出本機的封包
===============================================
若是Linux作為NAT(router)的機器,其防火牆處理流入本機封包的流程是
1. nat-PREROUTING --更改 DESTINATION
2. Forward封包轉遞 [走 flow B,NAT]
3. filter-FORWARD
4. nat-POSTROUTING --更改 SOURCE
===============================================
VPN的亂入,tun介面來襲,防火牆流程是?!
首先,先看從VPN安全通道流入的封包
[VPN client] ---> [VPN server with firewall]
(以下內容基於VPN通道已建立好的前提)
一開始,server會從對外開放的 *interface 拿到封包
(*interface,例如擁有 Public IP 的 eth0,:p)
其source IP和destination IP都是public的
source IP 是 client 的 public address
destination IP 是 server 的 public address
也就是該 server 對外的 interface 上的 IP
所以一開始是判斷為流入本機的封包
因此 forward 到 filter-INPUT 檢查
接下來就進入Linux存取本機資源
通過 Protocol Stack,在封包被拔掉 header 之後
便交由 application layer 的 VPN program 處理
此時會發現 application data payload 又是一個"封包"
其 source IP 和 destination IP 都是 private 的
source IP 是 client 的 VPN private address (通道建立過程中,由 server 分配)
destination IP 是:
1. server 的 VPN private address (表示存取 VPN server 本機資源)
2. LAN 內 VPN private address (表示存取企業內部網路的資源,VPN server as NAT-Router)
接下來,就是TUN上場的時候了
這個 VPN program 會把這個"封包"往本機上名為 tun 的 virtual interface 丟
然後呢....
tun 也是主機上的一個 interface (雖然是虛擬的),所以收到"封包"的時候
防火牆處理的過程也跟其他實體 interface 一樣,需要通過罩杯的考驗
在封包進來 tun interface 之後,若是封包是要傳給 server 的
則封包會被 forward 到 filter-INPUT 處理
(由此可知,VPN的使用也需要對防火牆做好適當的設定,免得VPN封包被擋掉...)
過了 filter-INPUT之後,進入本機
一樣也是通過 Protocol Stack,一層層的 header 被拔掉
最後就可以到達 server 的 application layer... finally :)
廢話連篇,一圖解千文

在封包進來 tun interface 之後,若是封包是要傳給 Private LAN 其他主機的話
則封包會被 forward 到 filter-FORWARD 處理
以下是廢圖二連發

[Reference]
鳥哥的Linux私房菜 - 防火牆與NAT
http://linux.vbird.org/linux_server/0250simple_firewall.php
鳥哥關於防火牆的介紹文章網址放在reference中
下圖是鳥哥所簡化的 chain 圖,
觀賞度10,實用度10,綜合係數10 (...某足球十大精妙過人影片爛梗XD)

作為普通PC的Linux,其防火牆處理流入本機封包的流程是
1. nat-PREROUTING [跳過]
2. Forward封包轉遞 [走 flow A,因此導向本機 Linux]
3. filter-INPUT [!!本機防火牆主要工作的地方!!]
4. Linux本機的資源
5. nat-OUTPUT [跳過]
6. filter-OUTPUT [!!本機防火牆主要工作的地方!!]
7. nat-POSTROUTING [跳過]
整理以後的流程如下,
1. Forward封包轉遞
2. filter-INPUT --負責把關流入本機的封包
3. Linux本機的資源
4. filter-OUTPUT --負責把關流出本機的封包
===============================================
若是Linux作為NAT(router)的機器,其防火牆處理流入本機封包的流程是
1. nat-PREROUTING --更改 DESTINATION
2. Forward封包轉遞 [走 flow B,NAT]
3. filter-FORWARD
4. nat-POSTROUTING --更改 SOURCE
===============================================
VPN的亂入,tun介面來襲,防火牆流程是?!
首先,先看從VPN安全通道流入的封包
[VPN client] ---> [VPN server with firewall]
(以下內容基於VPN通道已建立好的前提)
一開始,server會從對外開放的 *interface 拿到封包
(*interface,例如擁有 Public IP 的 eth0,:p)
其source IP和destination IP都是public的
source IP 是 client 的 public address
destination IP 是 server 的 public address
也就是該 server 對外的 interface 上的 IP
所以一開始是判斷為流入本機的封包
因此 forward 到 filter-INPUT 檢查
接下來就進入Linux存取本機資源
通過 Protocol Stack,在封包被拔掉 header 之後
便交由 application layer 的 VPN program 處理
此時會發現 application data payload 又是一個"封包"
其 source IP 和 destination IP 都是 private 的
source IP 是 client 的 VPN private address (通道建立過程中,由 server 分配)
destination IP 是:
1. server 的 VPN private address (表示存取 VPN server 本機資源)
2. LAN 內 VPN private address (表示存取企業內部網路的資源,VPN server as NAT-Router)
接下來,就是TUN上場的時候了
這個 VPN program 會把這個"封包"往本機上名為 tun 的 virtual interface 丟
然後呢....
tun 也是主機上的一個 interface (雖然是虛擬的),所以收到"封包"的時候
防火牆處理的過程也跟其他實體 interface 一樣,需要通過罩杯的考驗
在封包進來 tun interface 之後,若是封包是要傳給 server 的
則封包會被 forward 到 filter-INPUT 處理
(由此可知,VPN的使用也需要對防火牆做好適當的設定,免得VPN封包被擋掉...)
過了 filter-INPUT之後,進入本機
一樣也是通過 Protocol Stack,一層層的 header 被拔掉
最後就可以到達 server 的 application layer... finally :)
廢話連篇,一圖解千文
在封包進來 tun interface 之後,若是封包是要傳給 Private LAN 其他主機的話
則封包會被 forward 到 filter-FORWARD 處理
以下是廢圖二連發
[Reference]
鳥哥的Linux私房菜 - 防火牆與NAT
http://linux.vbird.org/linux_server/0250simple_firewall.php
2010年6月10日 星期四
Dynamic Programming
解釋之,就是一個問題可以細分為許多小問題,而這些分解下去的小問題之間又有順序上的關係,使得小問題的答案可以成為大問題答案的基石。
一般來說,我們會以陣列的形式來依序儲存小問題的答案,以供後續大問題解答時使用。
經典問題包含:
背包問題 (knapsack)
最長遞增序列 (Longest increasing subsequences)
[Reference]
Chapter 6 DP, from "Algorithms"
by S. Dasgupta, C.H.Papadimitriou, and U.V. Vazirani
訂閱:
文章 (Atom)