1. 程式人生 > >Windows下Libvirt Java API使用教程(三)

Windows下Libvirt Java API使用教程(三)

突兀的出來一個libvirt的教程三,您可能會覺得奇怪,其實這是OneCoder以前寫的一個小系列教程,原來發在51cto的部落格上,前兩篇已經發了過來,考慮到完整性,就把第三篇也發過來。前兩篇地址:

之前已經介紹過了libvirt api的上手使用方式,這裡再補充一些細節問題。

TLS安全認證訪問:

之前我們給出的例子都是直接用tcp訪問的,這就需要被訪問的伺服器開放tcp訪問的埠,也就是說,任何機器只要知道了伺服器的ip,都是可以訪問上面的libvirt介面的。這是十分危險的,在生產環境中是不可取的。

所以,libvirt支援基於tls認證的安全訪問協議。連線格式如下:

qemu+tls://10.4.54.10
或者
qemu://10.4.54.10(因為預設就是走tls的)

要想正常訪問,必須在客戶端和服務端配置證書,下面就介紹一個這個配置過程。

  1. 首先自然是證書生成工具的安裝。libvirt官方推薦的工具是:GnuTLS。不過可惜,官網給出的地然居然不正確。GnuTLS專案,官網地址如下:

下載頁面為:

這裡介紹的windows環境下配置,所以進入頁面:

下載即可。

  1. 解壓下載的工具。通過命令列進入\bin目錄(或者將該bin目錄配置到環境變數的path即可在任意路徑訪問):

  1. 首先為你的證書生成私鑰:

Create a private key for your CA:

certtool --generate-privkey > cakey.pem

然後,為你證書進行自簽名。

and self-sign it by creating a file with the signature details called ca.info containing:</p>

cn = Name of your organization
ca
certsigningkey

certtool --generate-self-signed --load-privkey cakey.pem   --template ca.info --outfile cacert.pem (Y)

先在當前路徑下建立一個叫ca.info的檔案,裡面寫上如上第一段內容,

然後執行第二段引用所示命令:

報錯。這下頭疼了。。筆者翻箱倒櫃,翻江倒海找了一通。。實在沒有找到答案。。。考慮到證書的製作過程中沒有與機器相關的資訊,所以,決定求助筆者非常不熟悉的linux。掏出putty,登入,重新執行上面第一個命令。生成私鑰:

然後同樣按照上面的方式進行簽名,果然輕鬆成功!

此時已經可以刪除ca.info檔案了。繼續生成證書,接下來開始生成服務端私鑰:

certtool --generate-privkey > serverkey.pem

然後簽名:

certtool --generate-certificate --load-privkey serverkey.pem  --load-ca-certificate cacert.pem --load-ca-privkey cakey.pem --template server.info --outfile servercert.pem

同樣是依靠一個叫做server.info的檔案。先建立改檔案,寫入如下格式內容:

organization = Name of your organization
cn = oirase
tlswwwserver
encryptionkey
signingkey

這裡只有cn這個屬性需要注意,他應該是當前主機的主機名:(

only the CN field matters, which as explained above must be the server's hostname)- (The CN must match the hostname which clients will be using to connect to the server. In the example below, clients will be connecting to the server using a URI of xen://oirase/, so the CN must be "oirase".)

如果不知道主機名,用ip當然也是可以的。那麼你的訪問就是通過IP訪問了。:)

成功。

將服務端證書拷貝伺服器的相應位置:

Finally we have two files to install:

serverkey.pem is the server's private key which should be copied to the server only as /etc/pki/libvirt/private/serverkey.pem.
servercert.pem is the server's certificate which can be installed on the server as /etc/pki/libvirt/servercert.pem.

最後是客戶端的證書,過程類似,這裡只列出主要過程和命令:

1、建立私鑰:

certtool --generate-privkey > clientkey.pem

2、建立client.info模版檔案:

country = GB
state = London
locality = London
organization = Red Hat
cn = client1
tlswwwclient
encryptionkey
signingkey

然後簽名:

certtool --generate-certificate --load-privkey clientkey.pem \
  --load-ca-certificate cacert.pem --load-ca-privkey cakey.pem \
  --template client.info --outfile clientcert.pem

3、拷貝證書到客戶端的指定位置(linux):

cp clientkey.pem /etc/pki/libvirt/private/clientkey.pem
cp clientcert.pem /etc/pki/libvirt/clientcert.pem

其中client.info中國家等資訊可根據你的情況指定。

至此,需要的證書已經都準備好了。證書有了,服務端也部署了。但是windows的客戶端不知道該部署到什麼地方?因為網上的說明給出的都是linux檔案路徑,沒說windows下的情況。不過筆者相信libvirt的錯誤日誌:)於是:

怎麼樣,位置有了吧。趕緊拷貝過去試試。</p>

有的同學可能發現,這裡只給出了一個位置,我們有三個證書呢。別急,你看這個路徑,比照網上給出的linux的路徑格式:

Location Machine Description Required fields
/etc/pki/CA/cacert.pem Installed on all clients and servers CA's certificate (more info) n/a
/etc/pki/libvirt/ private/serverkey.pem Installed on the server Server's private key (more info) n/a
/etc/pki/libvirt/ servercert.pem Installed on the server Server's certificate signed by the CA. (more info) CommonName (CN) must be the hostname of the server as it is seen by clients.
/etc/pki/libvirt/ private/clientkey.pem Installed on the client Client's private key. (more info) n/a
/etc/pki/libvirt/ clientcert.pem Installed on the client Client's certificate signed by the CA (more info) Distinguished Name (DN) can be checked against an access control list (tls_allowed_dn_list).

其實基本已經可以猜出windows下的目錄組織了。linux在的/etc目錄,就想當於我們這裡的..\libvirt目錄,子目錄的組織相同即可。

沒猜出來也不用擔心,最多我們複製一個證書嘗試一次,錯誤資訊會依次告訴你所有的路徑的:)

再訪問一下,成功~

補充說明一下關於動態連結檔案的問題:

之前介紹的時候,筆者只提到說呼叫libvirt Java api需要一個virt.dll檔案,這個檔案筆者是拷貝的libvirt-0.dll檔案改名而來,然後訪問成功。

筆者後來發現,原來libvirt 安裝目錄的bin資料夾下的所有檔案,其實都是該dll檔案的依賴檔案,當筆者將其他檔案刪除或轉義的時候,依然會報找不到virt.dll檔案的錯誤。所以,如果呼叫libvirt Java API開發,可以將所有的dll拷貝到一個指定位置,然後指定jna.library.path到該位置即可。