簡介,GlobusToolkit編寫安全格線服務,簡介,Globus Toolkit 的安全機制,開發安全的格線服務與客戶端,結束語,
簡介
Globus Toolkit具有較為統一的國際標準,有利於整合現有資源,也易於維護和升級換代。現在,一些重要的公司,包括I BM和微軟等都公開宣布支持Globus Toolkit。目前大多數格線項目都是採用基於GlobusToolkit所提供的協定及服務建設的。Globus對資源管理,安全、信息服務及數據管理等格線計算的關鍵理論進行研究並提供了基本的機制和接口。該項目早已開發出了能在各種平台上運行的格線計算工具軟體(Toolkit),支持格線計算和格線套用的一套服務和軟體庫。幫助規劃和組建大型的格線試驗平台,開發適合大型格線系統運行的大型應用程式。目前,Globus工具包機制已經被套用於全球數百個站點和幾十個主要的格線計算項目:NASA格線(NASA IPG)、歐洲數據格線(Data Grid)和美國國家技術格線(NTG)等。
GlobusToolkit編寫安全格線服務
來源:IBM DW 作者:Lavanya Ramakrishnan
在格線這樣的協同計算環境中,安全性是非常重要的問題。我們必須在應用程式的開發過程中正確實現安全機制,並且在部署階段進行精確地配置,這一點十分關鍵。本文作者介紹了 Globus Toolkit 3.0 中的安全術語與機制。還提供了示例代碼,展示了如何用 Globus Toolkit 3.0 在格線服務中實現訊息級的安全性。
簡介
Globus Toolkit 3.0 (GT3) 是開放格線服務基礎設施(Open Grid Service Infrastructure, OGSI)的參考實現。其中提供了基於開放格線服務架構(Open Grid Service Architecture, OGSA)和 Web 服務架構構建格線服務的基礎平台。這些服務可以實現資源共享、任務日程安排與組織,還可以訪問格線上的各種分散式資源。對於格線環境中的應用程式來說,安全性是極其重要的。我們需要根據組織機構以及其他一些不同的策略,來控制對資源和數據的訪問。因此,格線服務和客戶端需要相互進行認證,而且必須訪問經過授權的服務。OGSA 安全架構仍然處在開發階段;所以,GT3 中的某些與安全性有關的 API 將來可能會發生變化。本文的內容基於最新的穩定版本 Globus Toolkit 3.0 。文中相當詳細地介紹了格線服務與客戶端的編寫,並著重強調了安全機制。所以,本文假定您了解格線服務的基本術語,如通知(notification)、服務數據(service data),等等。我們鼓勵您用 GT3 編寫一個簡單的格線服務。GT3 中的程式設計師教程是很好的起點。
Globus Toolkit 的安全機制
GT3 的安全機制與以前的版本一樣,也是基於公鑰基礎設施(Public Key Infrastructure, PKI)。PKI 系統是一種信任層次系統,參與其中的實體通過其持有的證書,以及事前建立的軟體與過程,實現身份的標識和確認。公鑰的認證一般遵從 X.509 標準。對於基於 Globu 的安全格線服務和客戶端而言,這意味著所有參與的實體(包括服務和客戶端)都要具備一個符合 X.509 格式的身份標識。您可能已經有了由公司使用的 X.509 認證標識,或是 Globus Toolkit 以前版本中使用的 Globus 認證標識。有很多的商用產品都可以用來為格線建立認證中心(Certification Authority, CA)。然而,最簡單的方法就是使用 Globus 小組發布的 Simple CA 包了,它可以生成 CA,從而可以在 Globus 格線中發出證書。授權,或稱訪問控制,這項功能用於控制哪些用戶可以訪問系統中的哪些部分。GT3 的授權基於簡單的訪問控制列表,這個列表位於明文檔案 gridmap 中。在任務提交的過程中,Globus Toolkit 2.0 用這個 gridmap 檔案將用戶映射為遠程資源上的用戶 ID。GT3 對這一思路進行了擴展,實現了對 factory 和服務的訪問控制策略。gridmap 檔案與服務和 factory 相關聯,用於限制誰可以訪問所提供的功能。
GT3 同時提供傳輸層和訊息層的安全性。傳輸層的安全性依賴於對傳輸機制自身的保護。這種保護使得格線服務具有天生的安全性,但是卻對傳輸形成依賴。訊息級的安全性依賴於分別保護每一條訊息。這樣的機制很靈活,可以在任意的傳輸層之上傳送訊息。格線安全基礎設施(Grid Security Infrastructure, GSI)基於公鑰基礎設施構建。在 Globus Toolkit 中,安全服務的基礎是安全套接字層(Secure Socket Layer, SSL)。在 GT3 中,傳輸層安全性基於支持 GSI的HTTP 協定。訊息層的安全性基於一些正在形成中的技術和標準,比如說 WS-Security、XML Encryption 以及 XML Signature 等。Globus Toolkit 正在朝訊息級安全性的方向努力,而基於 GSI 的傳輸層安全性在將來的發布中可能會逐步淘汰,因此推薦應用程式使用訊息級的安全機制。本文的其餘部分將著重討論訊息級的安全機制。
Gridmap 檔案的格式 gridmap 檔案為每個可以訪問格線服務的人包含了一個條目。每一行的格式如下:“可區分名稱”用戶 ID
gridmap 檔案示例如下:
/O=Grid/O=Globus/OU=cnidr,org/CN=Lavanya Ramakrishnan"
lavanya "/O=Grid/O=Globus/OU=cnidr,org/CN=John Doe" john
開發安全的格線服務與客戶端
本節中,我們將依次介紹用 GT3 編寫安全格線服務所需的各個步驟。GT3 提供的機制可以對服務進行配置,使其使用認證和服務級授權。GT3 中帶的 API 可以幫助程式設計師將其他的安全機制集成進來,或者進行更細粒度的訪問控制。首先,我們將描述如何設定適合於安全架構的環境。然後,我們會看到如何通過認證和授權來限制對服務的訪問。最後解釋一下如何對這些配置進行擴展,以便為 factory 提供訪問控制機制。下面帶編號的四個小節中包含一些代碼清單,您可以根據您自己的需要使用這些代碼,或是進行修改。
1. 環境設定
GT3 提供的工具有助於您設定開發和部署格線服務的安全環境。請確認一下您是否已經用 $GLOBUS_LOCATION/bin/grid-cert-request 獲取了相關證書。通常用戶的私鑰和公鑰放置在主目錄的 .globus 目錄下。除此之外,您還需要創建 ~/.globus/cog.properties 檔案。這個檔案的內容應該是清單 1 中的格式。
清單 1. cog.properties 檔案格式
usercert=/home//.globus/usercert.pem
userkey=/home//.globus/userkey.pem
proxy=/tmp/x509up_u[digit number]
cacert=/etc/grid-security/certificates/42864e48.0
usercert 和 userkey 兩個變數指向公鑰和私鑰檔案。在 GT3 中,您可以從長期的證據中派生出一個生命期更短的證據,供用戶會話使用。這個較短期的檔案稱為 proxy(代理),生成的方法是使用 $GLOBUS_LOCATION/bin/grid-proxy-init,並在請求證書時使用密碼短語(pass-phrase)。proxy變數指向這個代理檔案。cacert 變數用於指向您所信任的 CA 證書。這些變數通常由 Globus 安裝過程的 setup-gsi 腳本設定。 在啟動任何一次格線會話之前,都不要忘記用 $GLOBUS_LOCATION/bin/grid-proxy-init 生成用戶的代理。GT3 底層的安全庫會找到這個用戶代理,將其作為與這個用戶運行的服務或者客戶端相關聯的代理(通過配置可使情況發生變化,稍後在清單 3 中將會討論到)。GT3 的訊息級安全是通過 Axis/JAX-RPC 處理程式實現的。server-config.wsdd 和 client-config.wsdd 必須定義適當的請求與回響流。默認情況下,GT3 會安裝它們。
Sun JVM 問題 有些人已經知道,Sun JVM 1.4.0/1.4.1 的 xalan.jar 檔案中存在一些問題。這個檔案不能與 GT3 中使用的 xml-security 包協同工作。請參閱 XML Security Library 的 安裝指南 ,找到解決這個問題的方法。如果您使用的是 J2SE 1.3.1 ,需要下載並安裝 JAAS 庫。
2. 編寫安全的服務 本節中我們考慮一個簡單的 HelloWorld 服務。HelloWorld 服務只有一個 sayHello() 方法,並可以訂閱訊息變化的通知。我們將告訴大家,如果想讓這個 HelloWorld 變安全,應該進行哪些必需的修改。為了在服務實例上啟用認證和授權,我們需要在部署描述符中設定若干屬性,如清單 2 所示:
清單 2. 保護服務實例用到的部署描述符
<parameter name="instance-securityConfig"
value="org/globus/ogsa/impl/security/descriptor/gsi-security-config.xml"/>
<parameter name="instance-authorization" value="gridmap"/>
<parameter name="instance-gridmap" value="/home/lavanya/gridmap"/>
instance-securityConfig 為安全屬性指定部署描述符。這個參數用於在服務的安全屬性之上提供粒度更細的控制。必須正確設定 instance-securityConfig 參數,認證才能生效。這裡,我們將使用 GT3 提供的通用 gsi-security-config.xml 來實現 GSI 安全會話認證機制。您可以用可用的元素自己編寫一個簡單的安全描述符。安全部署描述符是從 classpath 處載入的;因此,您可以在實現該服務的 jar 檔案中加入特定於應用程式的安全描述符。instance-authorization 參數定義了使用何種授權機制。可用的選項是 none、selfcode 和 gridmap 如果您在執行認證的時候沒有初始化 instance-authorization,那么默認情況下執行 self 授權。
如果這些安全性參數是在 一節中定義的,那么就適用於容器中的所有服務。默認情況下,用戶環境中底層的庫會取出服務證據和已信任證書。但是您可以在部署描述符中為每一個服務單獨配置一組證據和與之關聯的已信任證書,如清單 3 所示。與此類似,您也可以用 containerProxy 參數或 containerCert 和 containerKey 兩個參數來設定與容器關聯的證據。
清單 3. 部署描述符中的其他選項
// To set the service credential
<parameter name="serviceProxy" value="[proxy file]"/>
OR
<parameter name="serviceCert" value="[certificate file]"/>
<parameter name="serviceKey" value=""/>
// To set the service trusted certificates
<parameter name="trustedCertificates" value="[CA certificate locations]"/>
您可以按照一般格線服務的方式,根據 GWSDL 和 WSDL 生成服務的存根。在清單 4 中,我們展示了如何從服務的上下文中獲取調用者的身份標識。清單中還闡明了其他一些可能的配置,服務端可能要求用這些配置設定安全通知回調。
清單 4. HelloWorldImpl.java 服務的實現
public class HelloWorldImpl extends GridServiceImpl implements
HelloWorldPortType, CredentialRefreshListener {
public helloWorldImpl() {
super("HelloWorld");
}
public String sayHello(String in0) throws java.rmi.RemoteException {
String identity = SecurityManager.getManager().getCaller();
System.out.println("The identity is "+identity);
Subject subject = JaasSubject.getCurrentSubject();
System.out.println("Jaas Subject is "+ subject);
...
...
// Set the properties on the service data for calling
// the callback interface
_state.setProperty(Constants.GSI_SEC_CONV, Constants.ENCRYPTION);
_state.setProperty(Constants.AUTHORIZATION,
NoAuthorization.getInstance());
// notify anyone subscribe to the ServiceData
_state.notifyChange();
return "hello" + in0 ;
}
public void postCreate(GridContext context) throws GridServiceException {
...
...
// The following lines illustrate how the properties specified in
// the deployment descriptor could have been setup during service
// instance creation incase the values were not known
// during deployment.
//String mapPath = "/home/lavanya/gridmap";
//context.getMessageContext().setProperty
("instance-authorization", new String("gridmap"));
//context.getMessageContext().setProperty
("instance-gridmap", mapPath);
}
public void refreshCredentials(org.ietf.jgss.GSSCredential creds){
}
private ServiceData _state; // wrapper for our custom data type
}
清單 4 中展示了在服務端設定的配置項。這項實現服務在通知訂閱應用程式時扮演了客戶端的角色。因此您需要在 ServiceData 中設定 Constants.GSI_SEC_CONV 和 Constants.AUTHORIZATION 兩個屬性。這些屬性在下一節將詳細講述。我們還展示了在 sayHello() 方法調用的過程中,您應該如何使用 SecurityManager 獲得調用者的身份標識。然後,您可以從上下文中獲得 JAAS 調用的 subject。在服務實現的 postCreate() 中您也可以使用 GridContext 設定我們前面設在部署描述符中的參數。這項技術可以讓我們在運行的時候設定服務實例參數,而不是在部署的時候綁定。證據和參與實體之間的信任關係是動態的,通常會在服務生命期中間發生改變。HelloWorld 服務實現了 CredentialRefreshListener 接口,這樣就能自動刷新與服務關聯的證據。在服務生命期中間對 gridmap 檔案所做的任何改變都會反映出來。
3. 編寫安全的客戶端
清單 5. HelloWorldClient
public class HelloWorldClient extends ServicePropertiesImpl implements
NotificationSinkCallback {
public static void main (String[] args) {
helloWorldClient c = new helloWorldClient();
c.doHello();
}
public HelloWorldClient() {
}
public void doHello() {
try {
// Initialize the notification Manager
NotificationSinkManager manager
= NotificationSinkManager.getInstance("Secure");
manager.startListening(NotificationSinkManager.MAIN_THREAD);
// Setup the security properties to be used
// by the NotificationManager
HashMap props = new HashMap();
props.put(Constants.GSI_SEC_CONV, Constants.ENCRYPTION);
props.put(Constants.AUTHORIZATION,
NoAuthorization.getInstance());
manager.init(props);
this.setProperty(Constants.GSI_SEC_CONV, Constants.ENCRYPTION);
this.setProperty(Constants.AUTHORIZATION,
NoAuthorization.getInstance());
// For notification the client acts as a server point
// and hence should specify who all the client
// trusts to receive notifications from.
this.setProperty(Authorization.AUTHORIZATION, "gridmap");
GridMap map = new GridMap();
map.load("/home/lavanya/notification-gridmap");
SecureServicePropertiesHelper.setGridMap(this, map);
//Query service data
OGSIServiceGridLocator locator = new OGSIServiceGridLocator();
String handle
= "http://localhost:9080/ogsa/services/samples/HelloWorld;
GridService gridService
= locator.getGridServicePort(new URL(handle));
//Set the properties on the stub to access the service data
((Stub)gridService)._setProperty
(Constants.GSI_SEC_CONV, Constants.ENCRYPTION);
((Stub)gridService)._setProperty
(Constants.AUTHORIZATION, NoAuthorization.getInstance());
// Get Service Data Element "Our State"
ExtensibilityType extensibility =
gridService.findServiceData
(QueryHelper.getNamesQuery("MyState"));
ServiceDataValuesType serviceData =
AnyHelper.getAsServiceDataValues(extensibility);
MyStateType oData =
(MyStateType) AnyHelper.getAsSingleObject
(serviceData, MyStateType.class);
// Write service data
System.out.println("Queried message:" +oData.getLastMessage());
// Method call on the service
String sink = manager.addListener
("MyState",null,new HandleType(handle,this);
HelloWorldNotificationServiceGridLocator hwLocator =
new HelloWorldNotificationServiceGridLocator();
HelloWorldNotificationPortType hwPort =
hwLocator.getHelloWorldNotificationPort(new URL(handle));
// Set the security properties on the Stub to access the service
((Stub)hwPort)._setProperty(Constants.GSI_SEC_CONV,
Constants.ENCRYPTION);
((Stub)hwPort)._setProperty(Constants.AUTHORIZATION,
NoAuthorization.getInstance());
// Set this property if you want to delegate the
// credential to the service
((Stub)hwPort)._setProperty(GSIConstants.GSI_MODE,
GSIConstants.GSI_MODE_LIMITED_DELEG);
System.out.println(hwPort.sayHello("Lavanya"));
} catch (Exception e) {
e.printStackTrace();
}
}
/*
Called whenever serviceData is modified on the service side
*/
public void deliverNotification(ExtensibilityType any)
throws RemoteException {
...
}
}
對於啟用 GSI Secure Conversation 的客戶端來說,必須設定 Constants.GSI_SEC_CONV 屬性,以用於指示使用的是下面兩種訊息級保護機制中的哪一種:
·簽名 (Constants.SIGNATURE)
·加密 (Constants.ENCRYPTION)
清單 5 中的另一個屬性是為 NoAuthorization.getInstance() 方法設定的 Constants.AUTHORIZATION 它的作用是關閉客戶端授權。還需要在通知管理器中設定安全參數。方法是用想要的屬性初始化一個 HashMap,然後將其與管理器相關聯。此外,當客戶端接收通知的時候,它扮演的是伺服器的角色。因此您需要將訪問控制與回調接口相關聯。將 Authorization.AUTHORIZATION 屬性設定到 gridmap 中,然後使用 SecureServicePropertiesHelper 關聯相應的 gridmap 檔案。與此類似,當您想查詢服務數據,或者是調用了 portType 接口上的方法時,可以看到如何在 Stub 接口上設定相應的屬性。當服務的行為方式需要它用客戶端的證據來訪問另外的服務時,您可以委託一個證據。為了啟用證據委託,可以將 GSIConstants.GSI_MODE 設定為GSIConstants.GSI_MODE_LIMITED_DELEG。
還可能需要使用其他的屬性來配置 GSI Secure Conversation 與 GSI XML Signature 的設定(例如, GSIConstants.GSI_CREDENTIALS、Constants.GSI_XML_SIGNATURE)。可以採用上述類似的方式來設定這些屬性。
4. 安全的 factory
OGSA 中的 factory 接口允許用戶創建多個格線服務實例。您可以完全根據自己的需要,將對服務實例的訪問限制到某組特定的用戶,您還應該限制誰可以創建這些服務。實現的方法是為 factory 實例創建一個訪問控制,這樣就可以限制哪些人可以訪問 factory 和創建服務實例了。在 GT3 中,可以在部署描述符中設定適當的參數,如清單 6 所示。
清單 6. 安全 factory 的部署描述符
<parameter name="securityConfig"
value="org/globus/ogsa/impl/security/descriptor/gsi-security-config.xml"/>
<parameter name="authorization" value="gridmap"/>
<parameter name="gridmap" value="/home/lavanya/gridmap"/>
清單 6 顯示,設定參數的方法與為服務實例設定參數的方法相似。securityConfig 指定安全屬性的部署描述符。這有助於在服務的安全屬性之上提供粒度更細的控制。GT3 附帶的通用 gsi-security-config.xml 可以提供 GSI 安全對話認證機制。authorization 參數指定使用何種授權機制。可選項為 none、selfcode 或 gridmap。如如果您使用了 gridmap 授權,請將 gridmap 參數指向 gridmap 檔案。當您在像清單 6 那樣保護 factory 的時候,調用之前應該在 factory 存根中設定 Constants.GSI_SEC_CONV 和 Constants.AUTHORIZATION,以便創建服務實例。清單 7 展示了具體的方法。
清單 7. 創建安全服務
...
OGSIServiceGridLocator factoryService = new OGSIServiceGridLocator();
Factory factory = factoryService.getFactoryPort(new HandleType(handle));
...
// securing the factory stub
((Stub) factory)._setProperty(Constants.GSI_SEC_CONV,
Constants.ENCRYPTION);
((Stub) factory)._setProperty(Constants.AUTHORIZATION,
NoAuthorization.getInstance());
GridServiceFactory gridFactory = new GridServiceFactory(factory);
LocatorType locator = gridFactory.createService(null, id);
...
結束語
關於作者 Lavanya Ramakrishnan 為 MCNC 研究開發協會(MCNC Research and Development Institute,MCNC-RDI)工作。這是一個非贏利性的研究組織,位於美國北卡羅來納州。MCNC-RDI 還為 MCNC 格線計算與網路服務(MCNC Grid Computing and Networking Services)的很多格線研究活動與項目提供支持,後者正在發起美國第一個州際格線。Ramakrishnan 目前正為使用 Globus Toolkit 3.0 的格線信息獲取系統構建安全基礎設施,還在向格線功能中加入基於門戶(portal)的接口。除此之外,她參與測試和評估了很多格線中間件,以便在若干格線試驗台上部署,其中包括 NASA 資助的虛擬協作中心(Virtual Collaborative Center)。Remakrishnan女士還參加了全球格線論壇(Global Grid Forum,GGF)的安全問題小組。