本章說明 Apache ActiveMQ Artemis 的安全性運作方式以及如何配置它。
1. 基本配置
安全性預設為啟用。若要完全停用安全性,請在 broker.xml
檔案中將 security-enabled
屬性設定為 false
,例如:
<configuration...>
<core...>
...
<security-enabled>false</security-enabled>
...
</core>
</configuration>
2. 快取安全性操作
為了效能考量,身份驗證和授權都會獨立快取。當快取達到其最大大小時,會從快取中移除 (即失效) 項目,在這種情況下會移除最近最少使用的項目,或者當項目在快取中存在「太久」時也會移除。
快取的大小由 authentication-cache-size
和 authorization-cache-size
配置參數控制。兩者預設為 1000
。使用 0
將會停用相應的快取。
快取項目的有效時間由 security-invalidation-interval
控制,以毫秒為單位。預設值為 10000
毫秒。
3. 追蹤已驗證的使用者
為了協助安全審計,存在 populate-validated-user
選項。如果此選項為 true
,則伺服器會使用金鑰 _AMQ_VALIDATED_USER
將已驗證使用者的名稱新增至訊息。對於 JMS 和 Stomp 用戶端,這會對應至金鑰 JMSXUserID
。對於根據其 SSL 憑證驗證的使用者,此名稱是其憑證的 DN 對應到的名稱。如果 security-enabled
為 false
且 populate-validated-user
為 true
,則伺服器將只會使用用戶端提供的任何使用者名稱(如果有的話)。此選項預設為 false
。
也可以設定 reject-empty-validated-user
。如果 true
,伺服器將會拒絕任何沒有已驗證使用者的訊息。此選項預設為 false
。
4. 基於角色的地址安全性
Apache ActiveMQ Artemis 包含一個靈活的基於角色的安全模型,用於根據佇列的地址將安全性套用到佇列。
如 使用核心 中所述,Apache ActiveMQ Artemis 核心主要包含綁定到地址的佇列集。訊息會傳送到一個地址,伺服器會查詢綁定到該地址的佇列集,然後伺服器會將訊息路由到這些佇列集。
Apache ActiveMQ Artemis 允許根據佇列的地址定義佇列的權限集。可以使用地址的完全比對,也可以使用萬用字元比對。
可以向符合地址的佇列集授予不同的權限。這些權限是:
- createAddress
-
此權限允許使用者建立符合
match
的地址。 - deleteAddress
-
此權限允許使用者刪除符合
match
的地址。 - createDurableQueue
-
此權限允許使用者在符合的地址下建立持久佇列。
- deleteDurableQueue
-
此權限允許使用者刪除符合地址下的持久佇列。
- createNonDurableQueue
-
此權限允許使用者在符合的地址下建立非持久佇列。
- deleteNonDurableQueue
-
此權限允許使用者刪除符合地址下的非持久佇列。
- send
-
此權限允許使用者將訊息傳送到符合的地址。
- consume
-
此權限允許使用者從繫結到符合地址的佇列中取用訊息。
- browse
-
此權限允許使用者瀏覽繫結到符合地址的佇列。
- manage
-
此權限允許使用者透過將管理訊息傳送到管理地址來調用管理操作。
以下兩個權限與代理程式的管理 API 的操作有關。它們將管理操作分為兩組,唯讀的 view
和用於變更操作的 edit
。分割由規則運算式控制。符合的方法將需要 view
權限,所有其他方法都需要 edit
權限。可以透過配置屬性 view-permission-method-match-pattern
修改規則運算式。這些權限適用於管理地址和 MBean 存取。它們被授予以符合以 管理首碼開頭的地址。
- view
-
此權限允許存取管理操作的唯讀子集。
- edit
-
此權限允許存取變更的管理操作,即不在
view
集中的任何操作。
對於每個權限,都會指定被授予該權限的角色清單。如果使用者具有任何這些角色,他/她將會被授予該組地址的該權限。
讓我們看一個簡單的範例,以下是 broker.xml
檔案中的安全性區塊
<security-setting match="globalqueues.europe.#">
<permission type="createDurableQueue" roles="admin"/>
<permission type="deleteDurableQueue" roles="admin"/>
<permission type="createNonDurableQueue" roles="admin, guest, europe-users"/>
<permission type="deleteNonDurableQueue" roles="admin, guest, europe-users"/>
<permission type="send" roles="admin, europe-users"/>
<permission type="consume" roles="admin, europe-users"/>
</security-setting>
使用預設的萬用字元語法,#
字元表示「任何單詞序列」。單詞以 .
字元分隔。因此,上述安全性區塊適用於任何以字串「globalqueues.europe.」開頭的地址。
只有具有 admin
角色的使用者才能建立或刪除繫結到以字串「globalqueues.europe.」開頭的地址的持久佇列。
任何具有角色 admin
、guest
或 europe-users
的使用者都可以建立或刪除繫結到以字串「globalqueues.europe.」開頭的地址的臨時佇列。
任何具有角色 admin
或 europe-users
的使用者都可以將訊息傳送到這些地址或從繫結到以字串「globalqueues.europe.」開頭的地址的佇列中取用訊息。
使用者及其所具有的角色之間的對應由安全性管理員處理。Apache ActiveMQ Artemis 附帶一個使用者管理員,可以從磁碟上的檔案讀取使用者憑證,也可以插入 JAAS 或 JBoss 應用程式伺服器安全性中。
如需有關配置安全性管理員的詳細資訊,請參閱「變更安全性管理員」。
每個 xml 檔案中可以有零個或多個 security-setting
元素。如果有多個比對適用於一組地址,則更具體的比對優先。
讓我們看一個範例,以下是另一個 security-setting
區塊
<security-setting match="globalqueues.europe.orders.#">
<permission type="send" roles="europe-users"/>
<permission type="consume" roles="europe-users"/>
</security-setting>
在此 security-setting
區塊中,比對 globalqueues.europe.orders.#
比先前的比對 globalqueues.europe.#
更具體。因此,任何符合 globalqueues.europe.orders.#
的地址都將僅從後面的安全性設定區塊取得其安全性設定。
請注意,設定不會從先前的區塊繼承。所有設定都將從更具體的符合區塊中取得,因此對於地址 globalqueues.europe.orders.plastics
,唯一存在的權限是針對角色 europe-users
的 send
和 consume
。權限 createDurableQueue
、deleteDurableQueue
、createNonDurableQueue
、deleteNonDurableQueue
不會從其他 security-setting
區塊繼承。
由於不繼承權限,您可以在更具體的 security-setting
區塊中透過簡單地不指定權限來有效地拒絕權限。否則,將無法在地址子群組中拒絕權限。
4.1. 使用完整限定佇列名稱的細粒度安全性
在某些情況下,可能需要配置比跨整個地址更細粒度的安全性。例如,考慮一個具有多個佇列的地址
<addresses>
<address name="foo">
<anycast>
<queue name="q1" />
<queue name="q2" />
</anycast>
</address>
</addresses>
您可能希望將 q1
的取用限制為一個角色,而將 q2
的取用限制為另一個角色。您可以使用 security-setting
的 match
中的完整限定佇列名稱(即 FQQN)來執行此操作,例如:
<security-setting match="foo::q1">
<permission type="consume" roles="q1Role"/>
</security-setting>
<security-setting match="foo::q2">
<permission type="consume" roles="q2Role"/>
</security-setting>
萬用字元比對不適用於 FQQN。在此處使用 FQQN 的明確目標是精確。 |
4.2. 將 view
和 edit
權限應用於管理 API
view
和 edit
權限可選擇性地套用到代理程式的管理 API。
對於 JMX MBean 存取的 RBAC,它們可以取代 management.xml 中的授權部分,如 broker.xml 中的 JMX 授權 中所述
對於透過傳送到管理地址的訊息存取的管理資源的 RBAC,其他權限可以透過配置 management-message-rbac
來啟用,如 管理訊息的細粒度 RBAC 中所述
需要 view
和 edit
權限的操作之間的分割可以透過 view-permission-method-match-pattern 來控制
5. 安全性設定外掛程式
除了透過 XML 配置權限集之外,也可以透過實作 org.apache.activemq.artemis.core.server.SecuritySettingPlugin
的外掛程式來配置這些權限,例如:
<security-settings>
<security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
<setting name="initialContextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<setting name="connectionURL" value="ldap://127.0.0.1:1024"/>
<setting name="connectionUsername" value="uid=admin,ou=system"/>
<setting name="connectionPassword" value="secret"/>
<setting name="connectionProtocol" value="s"/>
<setting name="authentication" value="simple"/>
</security-setting-plugin>
</security-settings>
大部分的組態設定是針對外掛程式實作的。然而,有兩個組態細節在每個實作中都會被指定:
- class-name(類別名稱)
-
這個
security-setting-plugin
的屬性表示實作org.apache.activemq.artemis.core.server.SecuritySettingPlugin
的類別名稱。 - setting(設定)
-
每個元素代表一個名稱/值對,將傳遞給實作以進行組態設定。
請參閱 org.apache.activemq.artemis.core.server.SecuritySettingPlugin
的 JavaDoc,以了解有關介面及其每個方法預期行為的更多詳細資訊。
5.1. 可用的外掛程式
5.1.1. LegacyLDAPSecuritySettingPlugin
這個外掛程式會讀取先前由 LDAPAuthorizationMap
和 cachedLDAPAuthorizationMap
在 Apache ActiveMQ “Classic” 中處理的安全資訊,並盡可能將其轉換為 Artemis 安全設定。ActiveMQ “Classic” 和 Artemis 的安全實作並不完全匹配,因此必須進行一些轉換才能實現近乎等效的功能。
以下是外掛程式組態的範例:
<security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
<setting name="initialContextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<setting name="connectionURL" value="ldap://127.0.0.1:1024"/>
<setting name="connectionUsername" value="uid=admin,ou=system"/>
<setting name="connectionPassword" value="secret"/>
<setting name="connectionProtocol" value="s"/>
<setting name="authentication" value="simple"/>
</security-setting-plugin>
- class-name(類別名稱)
-
實作為
org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin
。 - initialContextFactory(初始內容工廠)
-
用於連線到 LDAP 的初始內容工廠。它必須始終設定為
com.sun.jndi.ldap.LdapCtxFactory
(即預設值)。 - connectionURL(連線網址)
-
使用 ldap URL(
ldap://主機:埠號
)指定目錄伺服器的位置。您可以選擇性地使用斜線 (/
) 後接目錄樹中特定節點的 DN 來限定此 URL。例如,ldap://ldapserver:10389/ou=system
。預設值為ldap://127.0.0.1:1024
。 - connectionUsername(連線使用者名稱)
-
開啟與目錄伺服器連線的使用者的 DN。例如,
uid=admin,ou=system
。目錄伺服器通常要求用戶端提供使用者名稱/密碼憑證才能開啟連線。 - connectionPassword(連線密碼)
-
與
connectionUsername
中的 DN 相符的密碼。在目錄伺服器中,在 DIT 中,密碼通常儲存在對應目錄項的userPassword
屬性中。 - connectionProtocol(連線協定)
-
目前唯一支援的值是空白字串。未來,此選項將允許您為連線到目錄伺服器選擇安全通訊端層 (SSL)。
此選項必須明確設定為空字串,因為它沒有預設值。 - authentication(驗證)
-
指定繫結到 LDAP 伺服器時使用的驗證方法。可以採用
simple
(使用者名稱和密碼,預設值)或none
(匿名)的值。目前不支援簡單驗證和安全層 (SASL) 驗證。 - destinationBase(目的地基礎)
-
指定其子項提供所有目的地權限的節點的 DN。在此情況下,DN 是字面值(也就是說,不會對屬性值執行字串替換)。例如,此屬性的典型值為
ou=destinations,o=ActiveMQ,ou=system
(即預設值)。 - filter(篩選器)
-
指定 LDAP 搜尋篩選器,該篩選器在查詢任何類型的目的地的權限時使用。搜尋篩選器會嘗試符合佇列或主題節點的子項或後代之一。預設值為
(cn=*)
。 - roleAttribute(角色屬性)
-
指定由
filter
符合的節點的屬性,其值是角色的 DN。預設值為uniqueMember
。 - adminPermissionValue(管理員權限值)
-
指定符合
admin
權限的值。預設值為admin
。 - readPermissionValue(讀取權限值)
-
指定符合
read
權限的值。預設值為read
。 - writePermissionValue(寫入權限值)
-
指定符合
write
權限的值。預設值為write
。 - enableListener(啟用接聽器)
-
是否啟用一個接聽器,該接聽器將自動接收在 LDAP 伺服器中所做的更新,並即時更新代理程式的授權組態。預設值為
true
。某些 LDAP 伺服器(例如 OpenLDAP)不支援「持續搜尋」功能,這會讓「接聽器」功能無法運作。對於這些伺服器,請將
refreshInterval
設定為大於0
的值。 - refreshInterval(重新整理間隔)
-
從 LDAP 伺服器重新整理安全設定前等待的時間(以秒為單位)。這可以用於不支援使用
enableListener
所需的「持續搜尋」功能的 LDAP 伺服器(例如 OpenLDAP)。預設值為0
(即不重新整理)。請記住,根據重新整理的組態頻率和資料集的大小,這可能是一個潛在的昂貴操作,因此請謹慎組態
refreshInterval
。 - mapAdminToManage(將管理員對應到管理)
-
是否將舊版
admin
權限對應到manage
權限。請參閱以下對應語意的詳細資訊。預設值為false
。 - allowQueueAdminOnRead(允許讀取時的佇列管理員)
-
是否將舊版
read
權限對應到createDurableQueue
、createNonDurableQueue
和deleteDurableQueue
權限,以便 JMS 用戶端可以在不需要admin
權限的情況下建立持久和非持久訂閱。ActiveMQ “Classic” 中允許這樣做。預設值為false
。
在 LDAP 中定義的佇列或主題名稱將作為安全設定的「符合項」,權限值將從 ActiveMQ “Classic” 類型對應到 Artemis 類型,並且角色將按原樣對應。
ActiveMQ “Classic” 只有 3 種權限類型 - read
、write
和 admin
。這些權限類型在其網站上有說明。但是,如先前所述,ActiveMQ Artemis 有 9 種權限類型 - createAddress
、deleteAddress
、createDurableQueue
、deleteDurableQueue
、createNonDurableQueue
、deleteNonDurableQueue
、send
、consume
、browse
和 manage
。以下是舊類型如何對應到新類型:
- read(讀取)
-
consume
、browse
- write(寫入)
-
send
send
-
createAddress
、deleteAddress
、createDurableQueue
、deleteDurableQueue
、createNonDurableQueue
、deleteNonDurableQueue
、manage
(如果mapAdminToManage
為true
)
如前所述,有幾個地方執行了轉換以達到某種程度的等效性。
-
此對應預設不包含 Artemis
manage
權限類型,因為在 ActiveMQ “Classic” 中沒有類似的類型。但是,如果mapAdminToManage
為true
,則舊版admin
權限將對應到manage
權限。 -
ActiveMQ “Classic” 中的
admin
權限與代理程式是否會在目的地不存在的情況下,在使用者向其傳送訊息時自動建立該目的地有關。如果使用者有權限向目的地傳送訊息,Artemis 會自動允許自動建立目的地。因此,外掛程式預設會將admin
權限對應到 Artemis 中上述 6 個權限。如果mapAdminToManage
為true
,則舊版admin
權限也會對應到manage
權限。
6. 安全通訊端層 (SSL) 傳輸
當訊息用戶端連線到伺服器,或伺服器透過不受信任的網路連線到其他伺服器(例如透過橋接器)時,Apache ActiveMQ Artemis 允許使用安全通訊端層 (SSL) 傳輸來加密該流量。
如需有關組態 SSL 傳輸的詳細資訊,請參閱組態傳輸。
7. 使用者憑證
Apache ActiveMQ Artemis 隨附三種安全性管理員實作:
-
彈性的可外掛
ActiveMQJAASSecurityManager
,它支援任何標準 JAAS 登入模組。Artemis 隨附數個登入模組,稍後將進一步討論。這是預設的安全性管理員。 -
ActiveMQBasicSecurityManager
不使用 JAAS,僅支援透過使用者名稱和密碼憑證進行驗證。它還支援透過管理 API 新增、移除和更新使用者。所有使用者和角色資料都儲存在代理程式的繫結日誌中,這表示對主要代理程式所做的任何變更都可以在其備份上使用。 -
舊版、已棄用的
ActiveMQSecurityManagerImpl
從類別路徑上名為artemis-users.properties
和artemis-roles.properties
的屬性檔案中讀取使用者憑證,即使用者名稱、密碼和角色資訊。
7.1. JAAS 安全性管理員
當使用 Java 驗證和授權服務 (JAAS) 時,大部分的組態取決於使用的登入模組。但是,在每種情況下都有一些共通點。首先要看的是 bootstrap.xml
。以下是使用 PropertiesLogin
JAAS 登入模組的範例,該模組會從屬性檔案中讀取使用者、密碼和角色資訊:
<jaas-security domain="PropertiesLogin"/>
無論您使用哪個登入模組,您都需要在這裡的 bootstrap.xml
中指定它。此處的 domain
屬性是指 login.config
中相關的登入模組項目。例如:
PropertiesLogin { org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule required debug=true org.apache.activemq.jaas.properties.user="artemis-users.properties" org.apache.activemq.jaas.properties.role="artemis-roles.properties"; };
login.config
檔案是標準的 JAAS 組態檔案。您可以在Oracle 網站上閱讀有關此檔案的更多資訊。簡而言之,該檔案定義:
-
項目的別名(例如,
PropertiesLogin
) -
登入模組的實作類別(例如,
org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule
) -
一個旗標,表示登入模組的成功是
required
、requisite
、sufficient
或optional
(請參閱JavaDoc 中這些旗標的詳細資訊) -
特定於登入模組實作的組態選項清單
預設情況下,login.config
的位置和名稱是在 Artemis 命令列上指定的,該命令列由 Linux 上的 etc/artemis.profile
和 Windows 上的 etc\artemis.profile.cmd
設定。
7.1.1. 雙重驗證
JAAS 安全性管理員還支援另一個組態參數 - certificate-domain
。當您想要根據用戶端的 SSL 憑證(例如使用以下討論的 CertificateLoginModule
)驗證透過 SSL 連線連線的用戶端時,但您仍然想要使用使用者名稱和密碼等驗證透過非 SSL 連線連線的用戶端時,這很有用。以下是一個 bootstrap.xml
中內容的範例:
<jaas-security domain="PropertiesLogin" certificate-domain="CertLogin"/>
以下是相應的 login.config
:
PropertiesLogin { org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule required debug=false org.apache.activemq.jaas.properties.user="artemis-users.properties" org.apache.activemq.jaas.properties.role="artemis-roles.properties"; }; CertLogin { org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule required debug=true org.apache.activemq.jaas.textfiledn.user="cert-users.properties" org.apache.activemq.jaas.textfiledn.role="cert-roles.properties"; };
當代理程式以此方式配置時,任何使用 SSL 和用戶端憑證連線的用戶端都將使用 CertLogin
進行驗證,而任何不使用 SSL 連線的用戶端都將使用 PropertiesLogin
進行驗證。
7.2. JAAS 登入模組
7.2.1. GuestLoginModule
允許沒有憑證(以及根據配置方式,可能也允許憑證無效的用戶)存取代理程式。通常,訪客登入模組會與另一個登入模組(例如屬性登入模組)鏈結。它由 org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule
實作。
- org.apache.activemq.jaas.guest.user
-
要指派的使用者名稱;預設為 "guest"
- org.apache.activemq.jaas.guest.role
-
要指派的角色名稱;預設為 "guests"
- credentialsInvalidate
-
布林值旗標;如果為
true
,則拒絕包含密碼的登入請求(也就是說,只有在使用者未提供密碼時,訪客登入才會成功);預設為false
- debug
-
布林值旗標;如果為
true
,則啟用偵錯;這僅用於測試或偵錯;通常應將其設定為false
或省略;預設為false
訪客登入模組有兩個基本的使用案例,如下所示
-
沒有憑證或憑證無效的訪客。
-
僅限沒有憑證的訪客。
以下程式碼片段顯示如何為沒有憑證或憑證無效的使用者以訪客身分登入的使用案例配置 JAAS 登入項目。在此範例中,訪客登入模組與屬性登入模組結合使用。
activemq-domain { org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient debug=true org.apache.activemq.jaas.properties.user="artemis-users.properties" org.apache.activemq.jaas.properties.role="artemis-roles.properties"; org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient debug=true org.apache.activemq.jaas.guest.user="anyone" org.apache.activemq.jaas.guest.role="restricted"; };
根據使用者登入資料,驗證程序如下
-
使用者使用有效密碼登入 — 屬性登入模組成功驗證使用者並立即返回。不會叫用訪客登入模組。
-
使用者使用無效密碼登入 — 屬性登入模組無法驗證使用者,並且驗證程序繼續執行到訪客登入模組。訪客登入模組成功驗證使用者並傳回訪客主體。
-
使用者使用空白密碼登入 — 屬性登入模組無法驗證使用者,並且驗證程序繼續執行到訪客登入模組。訪客登入模組成功驗證使用者並傳回訪客主體。
以下程式碼片段顯示如何為僅限沒有憑證的使用者以訪客身分登入的使用案例配置 JAAS 登入項目。若要支援此使用案例,您必須在訪客登入模組的配置中將 credentialsInvalidate 選項設定為 true。您還應該注意到,與前面的範例相比,登入模組的順序已反轉,並且附加到屬性登入模組的旗標已變更為必要。
activemq-guest-when-no-creds-only-domain { org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient debug=true credentialsInvalidate=true org.apache.activemq.jaas.guest.user="guest" org.apache.activemq.jaas.guest.role="guests"; org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule requisite debug=true org.apache.activemq.jaas.properties.user="artemis-users.properties" org.apache.activemq.jaas.properties.role="artemis-roles.properties"; };
根據使用者登入資料,驗證程序如下
-
使用者使用有效密碼登入 — 訪客登入模組無法驗證使用者(因為使用者已提供密碼,同時啟用了 credentialsInvalidate 選項),並且驗證程序繼續執行到屬性登入模組。屬性登入模組成功驗證使用者並返回。
-
使用者使用無效密碼登入 — 訪客登入模組無法驗證使用者,並且驗證程序繼續執行到屬性登入模組。屬性登入模組也無法驗證使用者。最終結果是驗證失敗。
-
使用者使用空白密碼登入 — 訪客登入模組成功驗證使用者並立即返回。不會叫用屬性登入模組。
7.2.2. PropertiesLoginModule
JAAS 屬性登入模組提供一個簡單的驗證資料儲存區,其中相關的使用者資料儲存在一對平面檔案中。這對於示範和測試很方便,但對於企業系統而言,最好與 LDAP 整合。它由 org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule
實作。
- org.apache.activemq.jaas.properties.user
-
包含使用者和密碼屬性的檔案路徑
- org.apache.activemq.jaas.properties.role
-
包含使用者和角色屬性的檔案路徑
- org.apache.activemq.jaas.properties.password.codec
-
要使用的密碼編解碼器的完整類別名稱。如需有關其運作方式的更多詳細資訊,請參閱密碼遮罩文件。
- reload
-
布林值旗標;是否在發生修改時重新載入屬性檔案;預設為
false
- debug
-
布林值旗標;如果為
true
,則啟用偵錯;這僅用於測試或偵錯;通常應將其設定為false
或省略;預設為false
在屬性登入模組的內容中,artemis-users.properties
檔案包含 UserName=Password
格式的屬性清單。例如,若要定義使用者 system
、user
和 guest
,您可以建立如下檔案
system=manager
user=password
guest=password
artemis-users.properties
中的密碼可以雜湊。此類密碼應遵循語法 ENC(<hash>)
。
可以使用 Artemis 實例中的 user
CLI 命令輕鬆將雜湊密碼新增至 artemis-users.properties
。此命令無法從 Artemis 首頁運作,除非已啟動代理程式,否則也無法運作。
./artemis user add --user-command-user guest --user-command-password guest --role admin
這將使用預設編解碼器對密碼執行「單向」雜湊,並使用指定的值變更 artemis-users.properties
和 artemis-roles.properties
檔案。
artemis-roles.properties
檔案包含 Role=UserList
格式的屬性清單,其中 UserList 是以逗號分隔的使用者清單。例如,若要定義角色 admins
、users
和 guests
,您可以建立如下檔案
admins=system
users=system,user
guests=guest
如上所述,Artemis 命令列介面支援 add
使用者的命令。命令列介面以及正常的管理介面(例如 JMX、網頁主控台等)也支援 list
(一個或所有)使用者、remove
使用者和 reset
使用者的密碼和/或角色。
警告
僅在使用
PropertiesLoginModule
時,才能使用管理和 CLI 操作來操作使用者和角色資料。一般而言,不建議將屬性檔案和以代理程式為中心的使用者管理用於非常基本的使用案例以外的任何用途。代理程式旨在處理訊息。它不是在管理使用者,儘管為了方便起見,提供了有限程度的功能。建議將 LDAP 用於企業級生產使用案例。
7.2.3. LDAPLoginModule
LDAP 登入模組可讓您透過檢查傳入憑證與儲存在中央 X.500 目錄伺服器中的使用者資料來執行驗證和授權。對於已經具有 X.500 目錄伺服器的系統,這表示您可以將 ActiveMQ Artemis 與現有的安全資料庫快速整合,並且可以使用 X.500 系統管理使用者帳戶。它由 org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule
實作。
- initialContextFactory(初始內容工廠)
-
必須始終設定為
com.sun.jndi.ldap.LdapCtxFactory
- connectionURL(連線網址)
-
使用 ldap URL(ldap://Host:Port)指定目錄伺服器的位置。您可以選擇性地限定此 URL,方法是新增一個正斜線
/
,後接目錄樹中特定節點的 DN。例如,ldap://ldapserver:10389/ou=system。 - authentication(驗證)
-
指定繫結至 LDAP 伺服器時使用的驗證方法。可以採用值
simple
(使用者名稱和密碼)、GSSAPI
(Kerberos SASL) 或none
(匿名)。 - connectionUsername(連線使用者名稱)
-
開啟與目錄伺服器連線的使用者 DN。例如,
uid=admin,ou=system
。目錄伺服器通常要求用戶端提供使用者名稱/密碼憑證才能開啟連線。 - connectionPassword(連線密碼)
-
與
connectionUsername
中的 DN 相符的密碼。在目錄伺服器中,在 DIT 中,密碼通常儲存為對應目錄項目中的userPassword
屬性。 - saslLoginConfigScope
-
在驗證方法為 SASL
GSSAPI
時,用來取得 Kerberos 啟動器憑證的 JAAS 配置 (login.config) 中的範圍。預設值為broker-sasl-gssapi
。 - connectionProtocol(連線協定)
-
目前,唯一支援的值是空白字串。未來,此選項將允許您為與目錄伺服器的連線選取安全通訊端層 (SSL)。此選項必須明確設定為空字串,因為它沒有預設值。
- connectionTimeout
-
指定代表連線逾時時間(以毫秒為單位)的整數的字串表示。如果 LDAP 提供者無法在該期間內建立連線,則會中止連線嘗試。整數應大於零。小於或等於零的整數表示使用網路通訊協定(即 TCP)的逾時值。
如果未指定
connectionTimeout
,則預設為等待建立連線或直到基礎網路逾時。當已為連線請求連線集區時,此屬性也會決定當集區中的所有連線都在使用中且已達到最大集區大小時,連線的最大等待時間。如果在這種情況下,此屬性的值小於或等於零,則提供者將無限期地等待連線可用;否則,提供者將在超過最大等待時間時中止等待。如需更多詳細資訊,請參閱
connectionPool
。 - readTimeout
-
指定代表 LDAP 作業的讀取逾時時間(以毫秒為單位)的整數的字串表示。如果 LDAP 提供者無法在該期間內取得 LDAP 回應,則會中止讀取嘗試。整數應大於零。小於或等於零的整數表示未指定讀取逾時時間,這相當於無限期等待回應,直到收到回應為止。
如果未指定
readTimeout
,則預設為等待回應,直到收到回應為止。 - userBase
-
選取 DIT 的特定子樹,以搜尋使用者項目。子樹由 DN 指定,DN 指定子樹的基礎節點。例如,將此選項設定為
ou=User,ou=ActiveMQ,ou=system
,則搜尋使用者項目僅限於ou=User,ou=ActiveMQ,ou=system
節點下的子樹。 - userSearchMatching
-
指定 LDAP 搜尋篩選器,該篩選器會套用至
userBase
選取的子樹。在傳遞至 LDAP 搜尋作業之前,您在此處提供的字串值會受到字串替代的處理,如java.text.MessageFormat
類別所實作。基本上,這表示特殊字串{0}
會被從傳入的用戶端憑證中擷取的使用者名稱取代。取代後,該字串會解譯為 LDAP 搜尋篩選器,其中 LDAP 搜尋篩選器語法由 IETF 標準 RFC 2254 定義。Oracle JNDI 教學課程 搜尋篩選器提供了搜尋篩選器語法的簡短介紹。
例如,如果此選項設定為
(uid={0})
,且接收到的使用者名稱為jdoe
,則字串替換後,搜尋篩選器會變成(uid=jdoe)
。如果將產生的搜尋篩選器應用於使用者基礎所選取的子樹ou=User,ou=ActiveMQ,ou=system
,則會符合條目uid=jdoe,ou=User,ou=ActiveMQ,ou=system
(以及可能更深層巢狀的條目,取決於指定的搜尋深度—請參閱userSearchSubtree
選項)。 - userSearchSubtree
-
指定相對於
userBase
指定的節點,使用者條目的搜尋深度。此選項為布林值。false
表示它會嘗試比對userBase
節點的子條目之一(對應至javax.naming.directory.SearchControls.ONELEVEL_SCOPE
)。true
表示它會嘗試比對屬於userBase
節點子樹的任何條目(對應至javax.naming.directory.SearchControls.SUBTREE_SCOPE
)。 - userRoleName
-
指定使用者條目的多值屬性名稱,其中包含使用者的角色名稱清單(其中角色名稱會由代理程式的授權外掛程式解譯為群組名稱)。如果省略此選項,則不會從使用者條目中擷取任何角色名稱。
- roleBase
-
如果您想直接將角色資料儲存在目錄伺服器中,可以使用角色選項(
roleBase
、roleSearchMatching
、roleSearchSubtree
和roleName
)的組合,作為指定userRoleName
選項的替代方案(或補充)。此選項會選取 DIT 的特定子樹,以搜尋角色/群組條目。子樹由 DN 指定,該 DN 指定子樹的基礎節點。例如,將此選項設定為ou=Group,ou=ActiveMQ,ou=system
,則對角色/群組條目的搜尋會限制在ou=Group,ou=ActiveMQ,ou=system
節點下方的子樹。 - roleName
-
指定角色條目的屬性類型,其中包含角色/群組的名稱(例如 C、O、OU 等)。如果省略此選項,則會使用角色的完整 DN。
- roleSearchMatching
-
指定 LDAP 搜尋篩選器,該篩選器會應用於由
roleBase
選取的子樹。此運作方式與userSearchMatching
選項類似,不同之處在於它支援兩個替換字串,如下所示-
{0}
- 替換相符使用者條目的完整 DN(即使用者搜尋的結果)。例如,對於使用者jdoe
,替換的字串可能是uid=jdoe,ou=User,ou=ActiveMQ,ou=system
。 -
{1}
- 替換接收到的使用者名稱。例如,jdoe
。
例如,如果此選項設定為
(member=uid={1})
,且接收到的使用者名稱為jdoe
,則字串替換後,搜尋篩選器會變成(member=uid=jdoe)
(假設 ApacheDS 搜尋篩選器語法)。如果將產生的搜尋篩選器應用於角色基礎所選取的子樹ou=Group,ou=ActiveMQ,ou=system
,則會比對所有具有等於uid=jdoe
的member
屬性的角色條目(member
屬性的值為 DN)。+ 此選項必須始終設定才能啟用角色搜尋,因為它沒有預設值。將其取消設定會停用角色搜尋,且角色資訊必須來自
userRoleName
。+ 如果您使用 OpenLDAP,則搜尋篩選器的語法為
(member:=uid=jdoe)
。 -
- roleSearchSubtree
-
指定相對於
roleBase
指定的節點,角色條目的搜尋深度。此選項可以採用布林值,如下所示-
false
(預設)- 嘗試比對 roleBase 節點的子條目之一(對應至javax.naming.directory.SearchControls.ONELEVEL_SCOPE
)。 -
true
— 嘗試比對屬於 roleBase 節點子樹的任何條目(對應至javax.naming.directory.SearchControls.SUBTREE_SCOPE
)。
-
- authenticateUser
-
用來停用驗證的布林標記。當此模組僅用於 Subject 現有已驗證主體的角色對應時,這可用作最佳化;預設值為
true
。 - referral
-
指定如何處理轉介;有效值:
ignore
、follow
、throw
;預設值為ignore
。 - ignorePartialResultException
-
搜尋 Active Directory (AD) 時使用的布林標記。AD 伺服器不會自動處理轉介,這會導致在搜尋時遇到轉介時擲回
PartialResultException
,即使referral
設定為ignore
也一樣。設定為true
以忽略這些例外狀況;預設值為false
。 - expandRoles
-
表示是否啟用角色展開功能的布林值;預設值為 false。如果啟用,則會找到角色內的角色。例如,角色
A
在角色B
中。使用者X
在角色A
中,這表示使用者X
因為在角色A
中而位於角色B
中。 - expandRolesMatching
-
指定應用於由
roleBase
選取的子樹的 LDAP 搜尋篩選器。在傳遞至 LDAP 搜尋作業之前,您在此處提供的字串值會受到字串替換,如同java.text.MessageFormat
類別所實作。基本上,這表示特殊字串{0}
會替換為從先前的角色搜尋中擷取的角色名稱。此選項必須始終設定才能啟用角色展開,因為它沒有預設值。範例值:(member={0})
。 - noCacheExceptions
-
以逗號分隔的類別名稱或正規表示式清單,以比對與 LDAP 伺服器通訊期間可能擲回的例外狀況;預設值為空。通常,任何驗證失敗都會儲存在驗證快取中,以便讓基礎安全資料儲存區(例如 LDAP)免於不必要的流量。例如,具有錯誤密碼的應用程式嘗試在短時間內多次登入可能會對 LDAP 伺服器造成負面影響。但是,在失敗是因為暫時性網路中斷的情況下,且
security-invalidation-interval
相對較高,則「不」快取此類失敗會更好。使用者可以列舉快取應忽略的任何相關例外狀況(例如java.net.ConnectException
)。例外狀況的名稱或正規表示式應與相關堆疊追蹤中的**根本原因**比對。使用者可以透過啟用org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl
的除錯記錄來確認已略過設定的例外狀況。 - debug
-
布林值旗標;如果為
true
,則啟用偵錯;這僅用於測試或偵錯;通常應將其設定為false
或省略;預設為false
任何 LDAP 登入模組本身無法識別的其他組態選項都會原樣傳遞至基礎 LDAP 連線邏輯。
將使用者條目新增至 userBase
選項指定的節點下。在目錄中建立新的使用者條目時,請選擇支援 userPassword
屬性的物件類別(例如,person
或 inetOrgPerson
物件類別通常適合)。建立使用者條目後,請新增 userPassword
屬性以保存使用者的密碼。
如果您想將角色資料儲存在專用角色條目中(其中每個節點代表特定角色),請依照下列方式建立角色條目。建立 roleBase
節點的新子節點,其中子節點的 objectClass
為 groupOfNames
。將新子節點的 cn
(或任何由 roleName
指定的屬性類型)設定為等於角色/群組的名稱。為角色/群組的每個成員定義 member
屬性,將 member
值設定為對應使用者的 DN(其中 DN 可以完整指定為 uid=jdoe,ou=User,ou=ActiveMQ,ou=system
,或部分指定為 uid=jdoe
)。
如果您想將角色新增至使用者條目,您需要自訂目錄結構描述,方法是將適當的屬性類型新增至使用者條目的物件類別。所選的屬性類型必須能夠處理多個值。
7.2.4. CertificateLoginModule
JAAS 憑證驗證登入模組必須與 SSL 一起使用,且用戶端必須設定自己的憑證。在這種情況下,驗證實際上是在 SSL/TLS 交握期間執行,而不是直接由 JAAS 憑證驗證外掛程式執行。此外掛程式的作用如下
-
進一步限制可接受的使用者集合,因為只有相關屬性檔案中明確列出的使用者 DN 才有資格進行驗證。
-
將群組清單與接收到的使用者身分建立關聯,以促進與授權功能的整合。
-
要求存在傳入的憑證(依預設,SSL/TLS 層會將用戶端憑證的存在視為選用)。
JAAS 憑證登入模組會在兩個平面檔案中儲存憑證 DN 的集合。這些檔案會將使用者名稱和群組 ID 清單與每個 DN 建立關聯。
憑證登入模組是由下列類別實作
org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule
下列 CertLogin
登入項目顯示如何在 login.config 檔案中設定憑證登入模組
CertLogin { org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule debug=true org.apache.activemq.jaas.textfiledn.user="users.properties" org.apache.activemq.jaas.textfiledn.role="roles.properties"; };
在上述範例中,JAAS 領域設定為使用單一 org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule
登入模組。此登入模組支援的選項如下
- debug
-
布林標記;如果為 true,則啟用除錯;這僅用於測試或除錯;通常,應將其設定為
false
或省略;預設值為false
- org.apache.activemq.jaas.textfiledn.user
-
指定使用者屬性檔案的位置(相對於包含登入組態檔案的目錄)。
- org.apache.activemq.jaas.textfiledn.role
-
指定角色屬性檔案的位置(相對於包含登入組態檔案的目錄)。
- reload
-
布林值旗標;是否在發生修改時重新載入屬性檔案;預設為
false
- normalise
-
布林標記;DN 值是否應驗證並正規化為用於比對的 X500Name 字串格式;預設值為 false。使用此選項可以避免下面討論的 DN 字串形式的模糊性。當為 true 時,DN 字串會經過驗證,然後正規化為內部 X500Name 格式。
在憑證登入模組的上下文中,users.properties
檔案包含屬性列表,格式為 UserName=StringifiedSubjectDN
或 UserName=/SubjectDNRegExp/
。例如,要定義使用者 system
、user
和 guest
,以及一個符合多個 DN 的 hosts
使用者,您可以建立如下的檔案:
system=CN=system,O=Progress,C=US
user=CN=humble user,O=Progress,C=US
guest=CN=anon,O=Progress,C=DE
hosts=/CN=host\\d+\\.acme\\.com,O=Acme,C=UK/
請注意,反斜線字元必須進行跳脫,因為它在屬性檔案中有特殊處理。
每個使用者名稱都會對應到一個主體 DN,編碼為字串(字串編碼由 RFC 2253 指定)。例如,系統使用者名稱會對應到 CN=system,O=Progress,C=US
主體 DN。當執行身份驗證時,外掛程式會從接收到的憑證中提取主體 DN,將其轉換為標準字串格式,並透過測試字串相等性來與 users.properties
檔案中的主體 DN 進行比較。因此,您必須小心確保 users.properties
檔案中出現的主體 DN 與從使用者憑證中提取的主體 DN 完全一致。
從技術上講,DN 字串格式存在一些殘留的模糊性。例如,domainComponent 屬性可以用字串表示為 DC ,也可以用 OID 表示為 0.9.2342.19200300.100.1.25 。通常,您不需要擔心這種模糊性。但是,如果您更改 Java 安全層的底層實作,這可能會成為問題。 |
從使用者憑證取得主體 DN 最簡單的方法是呼叫 keytool
公用程式來列印憑證內容。若要列印金鑰儲存區中憑證的內容,請執行以下步驟:
-
將憑證從金鑰儲存區檔案匯出到臨時檔案。例如,要從
broker.ks
金鑰儲存區檔案匯出別名為broker-localhost
的憑證,請輸入以下命令:keytool -export -file broker.export -alias broker-localhost -keystore broker.ks -storepass password
執行此命令後,匯出的憑證會在
broker.export
檔案中。 -
列印出匯出憑證的內容。例如,要列印出
broker.export
的內容,請輸入以下命令:keytool -printcert -file broker.export
這應該會產生類似於此處所示的輸出:
Owner: CN=localhost, OU=broker, O=Unknown, L=Unknown, ST=Unknown, C=Unknown Issuer: CN=localhost, OU=broker, O=Unknown, L=Unknown, ST=Unknown, C=Unknown Serial number: 4537c82e Valid from: Thu Oct 19 19:47:10 BST 2006 until: Wed Jan 17 18:47:10 GMT 2007 Certificate fingerprints: MD5: 3F:6C:0C:89:A8:80:29:CC:F5:2D:DA:5C:D7:3F:AB:37 SHA1: F0:79:0D:04:38:5A:46:CE:86:E1:8A:20:1F:7B:AB:3A:46:E4:34:5C
Owner:
後面的字串會給出主體 DN。輸入主體 DN 使用的格式取決於您的平台。上面的Owner:
字串可以表示為CN=localhost,\ OU=broker,\ O=Unknown,\ L=Unknown,\ ST=Unknown,\ C=Unknown
或CN=localhost,OU=broker,O=Unknown,L=Unknown,ST=Unknown,C=Unknown
。
roles.properties
檔案包含屬性列表,格式為 Role=UserList
,其中 UserList
是以逗號分隔的使用者列表。例如,要定義角色 admins
、users
和 guests
,您可以建立如下的檔案:
admins=system
users=system,user
guests=guest
7.2.5. SCRAMPropertiesLoginModule
SCRAM 屬性登入模組實作了 SCRAM-SHA 機制的 SASL 挑戰回應。透過 org.apache.activemq.jaas.properties.user
參考的屬性檔案中的資料,需要由登入模組本身在使用者註冊過程中產生。它包含密碼知識的證明,而不是密碼本身。如需更多使用細節,請參閱 SCRAM-SHA SASL 機制。
amqp-sasl-scram { org.apache.activemq.artemis.spi.core.security.jaas.SCRAMPropertiesLoginModule required org.apache.activemq.jaas.properties.user="artemis-users.properties" org.apache.activemq.jaas.properties.role="artemis-roles.properties"; };
7.2.6. SCRAMLoginModule
SCRAM 登入模組將有效的 SASL SCRAM-SHA 驗證身分轉換為 JAAS 使用者主體。然後,此主體可以用於角色對應。
{ org.apache.activemq.artemis.spi.core.security.jaas.SCRAMLoginModule };
7.2.7. ExternalCertificateLoginModule
外部憑證登入模組用於將已驗證的 TLS 用戶端憑證的 subjectDN 傳播到 JAAS UserPrincipal 中。這允許後續的登入模組為 TLS 用戶端憑證進行角色對應。
org.apache.activemq.artemis.spi.core.security.jaas.ExternalCertificateLoginModule required ;
7.2.8. PrincipalConversionLoginModule
主體轉換登入模組用於將現有的已驗證主體轉換為 JAAS UserPrincipal。該模組配置了一個類別名稱列表,用於比對現有的主體。如果不存在 UserPrincipal,則會將第一個符合的主體新增為相同名稱的 UserPrincipal。
org.apache.activemq.artemis.spi.core.security.jaas.PrincipalConversionLoginModule required principalClassList=org.apache.x.Principal,org.apache.y.Principal ;
7.2.9. Krb5LoginModule
Kerberos 登入模組用於將已驗證的 SASL GSSAPI Kerberos 權杖身分傳播到已驗證的 JAAS UserPrincipal 中。這允許後續的登入模組為 Kerberos 身分進行角色對應。
org.apache.activemq.artemis.spi.core.security.jaas.Krb5LoginModule required ;
使登入設定可供 JAAS 使用的最簡單方法是將包含 login.config
檔案的目錄新增到您的 CLASSPATH。
7.2.10. KubernetesLoginModule
Kubernetes 登入模組可讓您透過針對 Kubernetes API 驗證 Bearer
權杖來執行身份驗證和授權。身份驗證是透過提交 Kubernetes 叢集驗證的 TokenReview
請求來完成的。回應將告知使用者是否已驗證以及關聯的使用者名稱和角色。它由 org.apache.activemq.artemis.spi.core.security.jaas.KubernetesLoginModule
實作。
- ignoreTokenReviewRoles
-
當為 true 時,不對應來自 TokenReview 使用者群組的角色。預設為 false
- org.apache.activemq.jaas.kubernetes.role
-
包含角色對應的可選檔案路徑,當 ignoreTokenReviewRoles=true 時很有用
- reload
-
布林旗標;是否在修改發生時重新載入屬性檔案;預設為
false
- debug
-
布林值旗標;如果為
true
,則啟用偵錯;這僅用於測試或偵錯;通常應將其設定為false
或省略;預設為false
必須允許登入模組查詢所需的 Rest API。為此,它將使用 /var/run/secrets/kubernetes.io/serviceaccount/token
下可用的權杖。此外,為了信任連線,用戶端將使用同一資料夾中存在的 ca.crt
檔案。這兩個檔案將會掛載到容器中。執行 KubernetesLoginModule 的服務帳戶必須允許 create::TokenReview
。system:auth-delegator
角色通常用於此目的。
可選的角色屬性檔案包含屬性列表,格式為 Role=UserList
,其中 UserList
是以逗號分隔的使用者列表。例如,要定義角色 admins、users 和 guests,您可以建立如下的檔案:
admins=system:serviceaccounts:example-ns:admin-sa
users=system:serviceaccounts:other-ns:test-sa
7.3. SCRAM-SHA SASL 機制
SCRAM(Salted Challenge Response Authentication Mechanism,鹽化挑戰回應身份驗證機制)是一種可以使用密碼建立相互身份驗證的身份驗證機制。Apache ActiveMQ Artemis 支援 SCRAM-SHA-256 和 SCRAM-SHA-512 SASL 機制,為 AMQP 連線提供身份驗證。
SCRAM 的以下特性使其即使在未加密的連線上也可以安全地使用 SCRAM-SHA:
-
密碼不會以明文方式透過通訊通道傳送。會向用戶端提出挑戰,要求其提供知道驗證使用者密碼的證明,並向伺服器提出挑戰,要求其提供已擁有密碼以初始化其身份驗證儲存的證明。只會交換證明。
-
伺服器和用戶端都會為每次身份驗證交換產生新的挑戰,使其能夠抵禦重放攻擊。
7.3.1. 設定伺服器以使用 SCRAM-SHA
必須在 broker.xml
中透過將所需的 SCRAM-SHA 機制新增至 saslMechanisms
列表 URL 參數,在 AMQP 接受器上啟用它們。在此範例中,SASL 僅限於 SCRAM-SHA-256
機制。
<acceptor name="amqp">tcp://127.0.0.1:5672?protocols=AMQP;saslMechanisms=SCRAM-SHA-256;saslLoginConfigScope=amqp-sasl-scram
值得注意的是,參考了保存相關 SCRAM 登入模組的 SASL 登入設定範圍 saslLoginConfigScope=amqp-sasl-scram
。該機制使用 JAAS 來完成 SASL 交換。
使用屬性檔案實作 SCRAM-SHA-256 的 login.config
的範例設定範圍如下:
amqp-sasl-scram { org.apache.activemq.artemis.spi.core.security.jaas.SCRAMPropertiesLoginModule required org.apache.activemq.jaas.properties.user="artemis-users.properties" org.apache.activemq.jaas.properties.role="artemis-roles.properties"; };
7.3.2. 在伺服器上設定具有 SCRAM-SHA 資料的使用者
使用 SCRAM-SHA,伺服器的使用者屬性檔案不包含任何密碼,而是包含可用於回應挑戰的衍生資料。必須使用 artemis-server 模組中的 org.apache.activemq.artemis.spi.core.security.jaas.SCRAMPropertiesLoginModule 的 main 方法產生密碼的安全編碼形式,並將產生的行插入您的 artemis-users.properties 檔案中。
java -cp "<distro-lib-dir>/*" org.apache.activemq.artemis.spi.core.security.jaas.SCRAMPropertiesLoginModule <username> <password> [<iterations>]
可以在 AMQP 範例 examples/protocols/amqp/sasl-scram/src/main/resources/activemq/server0/artemis-users.properties 中找到輸出的範例。
7.4. Kerberos 身份驗證
您必須在部署環境中設定 Kerberos 基礎架構,伺服器才能接受 Kerberos 憑證。伺服器可以使用 JAAS 和 Kerberos 登入模組來取得其 Kerberos 接受器憑證。JDK 提供了 Krb5LoginModule,它會執行必要的 Kerberos 協定步驟來驗證和取得 Kerberos 憑證。
7.4.1. GSSAPI SASL 機制
透過 AMQP 使用 SASL,可以使用 GSSAPI
SASL 機制支援 Kerberos 身份驗證。使用 SASL 進行 Kerberos 身份驗證,TLS 可以以正常方式用於為通訊通道提供完整性和機密性。
必須在 broker.xml
中透過將 GSSAPI
SASL 機制新增至 saslMechanisms
列表 URL 參數來啟用它:saslMechanisms="GSSAPI<,PLAIN, etc>
。
<acceptor name="amqp">tcp://0.0.0.0:5672?protocols=AMQP;saslMechanisms=GSSAPI</acceptor>
伺服器上的 GSSAPI 機制實作將使用名為 amqp-sasl-gssapi
的 JAAS 設定範圍來取得其 Kerberos 接受器憑證。可以使用 URL 參數在 AMQP 接受器上指定替代設定範圍:saslLoginConfigScope=<some other scope>
。
以下是 login.config
的範例設定範圍,它將為 Kerberos 接受器主體 amqp/localhost
擷取 Kerberos keyTab:
amqp-sasl-gssapi { com.sun.security.auth.module.Krb5LoginModule required isInitiator=false storeKey=true useKeyTab=true principal="amqp/localhost" debug=true; };
7.5. 角色對應
在伺服器上,必須使用對應的 Apache ActiveMQ Artemis Krb5LoginModule
或 SCRAMLoginModule
登入模組,將 Kerberos 或 SCRAM-SHA JAAS 驗證的主體新增至主體的實體集中,作為 Apache ActiveMQ Artemis UserPrincipal。它們是分開的,以允許轉換和角色對應盡可能地嚴格或寬鬆。
然後可以使用 PropertiesLoginModule 或 LDAPLoginModule 將已驗證的主體對應到 Apache ActiveMQ Artemis 角色。請注意,在 Kerberos 的情況下,對等主體不會作為 Apache ActiveMQ Artemis 使用者存在,只會作為角色成員存在。
在以下範例中,任何現有的 Kerberos 驗證的對等方都將轉換為 Apache ActiveMQ Artemis 使用者主體,並將由 LDAPLoginModule 適當地套用角色對應。
activemq { org.apache.activemq.artemis.spi.core.security.jaas.Krb5LoginModule required ; org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule optional initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory connectionURL="ldap://127.0.0.1:1024" authentication=GSSAPI saslLoginConfigScope=broker-sasl-gssapi connectionProtocol=s userBase="ou=users,dc=example,dc=com" userSearchMatching="(krb5PrincipalName={0})" userSearchSubtree=true authenticateUser=false roleBase="ou=system" roleName=cn roleSearchMatching="(member={0})" roleSearchSubtree=false ; };
7.6. 基本安全性管理員
顧名思義,ActiveMQBasicSecurityManager
是「基本」的。它不像 JAAS 安全性管理員那樣是可插入的,而且它僅支援透過使用者名稱和密碼憑證進行身份驗證。此外,基於 Hawtio 的 Web 主控台需要 JAAS。因此,如果您打算使用 Web 主控台,您仍然需要設定 login.config
。但是,此安全性管理員可能仍然有一些優勢,具體取決於您的使用案例。
所有使用者和角色資料都儲存在繫結日誌中(如果使用 JDBC,則儲存在繫結表中)。此處的優勢在於,在主要/備份使用案例中,在主要代理程式上執行的任何使用者管理都會在故障轉移時反映在備份上。
通常這類使用案例會採用 LDAP,但並非所有人都想要或能夠管理獨立的 LDAP 伺服器。LDAP 的一個顯著優勢是,使用者資料可以在多個活動的代理程式之間共享。然而,ActiveMQBasicSecurityManager
或其他任何可能開箱即用的配置都無法做到這一點。儘管如此,如果您只想在單一的即時/備份配對之間共享使用者資料,那麼基本安全性管理員可能很適合您。
使用者管理由代理程式的管理 API 提供。這包括新增、列出、更新和移除使用者及角色的功能。與所有管理功能一樣,這可以透過 JMX、管理訊息、HTTP (透過 Jolokia)、Web 主控台等方式使用。這些功能也可以從 ActiveMQ Artemis 命令列介面使用。讓代理程式直接儲存此資料意味著它必須正在執行才能管理使用者。無法手動修改繫結資料。
明確地說,任何透過 HTTP (例如 Web 主控台或 Jolokia) 進行的管理存取都將通過 Hawtio JAAS。透過 JConsole 或其他遠端 JMX 工具進行的 MBean 存取將通過基本安全性管理員。管理訊息也將通過基本安全性管理員。
7.6.1. 配置
ActiveMQBasicSecurityManager
的配置與所有安全性管理員實作一樣,都在 bootstrap.xml
中進行。首先移除 <jaas-security />
區段,然後新增如下所述的 <security-manager />
配置。
ActiveMQBasicSecurityManager
需要一些特殊配置,原因如下:
-
保存使用者和角色資料的繫結資料無法手動修改
-
代理程式必須正在執行才能管理使用者
-
代理程式通常需要從首次啟動就受到保護
例如,如果代理程式被配置為使用 ActiveMQBasicSecurityManager
並且從頭開始啟動,那麼將沒有任何用戶端能夠連接,因為沒有配置任何使用者和角色。但是,為了配置使用者和角色,需要使用管理 API,這需要適當的憑證。這是一個 (邏輯上的)兩難困境。因此,必須配置在代理程式啟動時自動建立的「引導」憑證。可以使用屬性來定義以下兩種方式:
-
單一使用者,其憑證隨後可用於新增其他使用者
-
從中批量載入使用者和角色的屬性檔
以下是單一引導使用者配置的範例
<broker xmlns="https://activemq.dev.org.tw/schema">
<security-manager class-name="org.apache.activemq.artemis.spi.core.security.ActiveMQBasicSecurityManager">
<property key="bootstrapUser" value="myUser"/>
<property key="bootstrapPassword" value="myPass"/>
<property key="bootstrapRole" value="myRole"/>
</security-manager>
...
</broker>
- bootstrapUser
-
引導使用者的名稱。
- bootstrapPassword
-
引導使用者的密碼;支援遮罩。
- bootstrapRole
-
引導使用者的角色。
如果您的使用案例需要在代理程式啟動時提供多個使用者,則可以使用如下配置
<broker xmlns="https://activemq.dev.org.tw/schema">
<security-manager class-name="org.apache.activemq.artemis.spi.core.security.ActiveMQBasicSecurityManager">
<property key="bootstrapUserFile" value="artemis-users.properties"/>
<property key="bootstrapRoleFile" value="artemis-roles.properties"/>
</security-manager>
...
</broker>
- bootstrapUserFile
-
從中載入使用者的檔案名稱。這是一個屬性檔案,其格式與
PropertiesLoginModule
使用的使用者屬性檔案完全相同。此檔案應位於代理程式的類別路徑中 (例如在etc
目錄中)。 - bootstrapRoleFile
-
引導使用者的角色。這是一個屬性檔案,其格式與
PropertiesLoginModule
使用的角色屬性檔案完全相同。此檔案應位於代理程式的類別路徑中 (例如在etc
目錄中)。
無論您是配置單一引導使用者還是從屬性檔案載入多個使用者,任何建立其他使用者的使用者都應該在 activemq.management
位址上具有適當許可的角色中。例如,如果您指定了 bootstrapUser
,則 bootstrapRole
將需要以下許可:
-
createNonDurableQueue
-
createAddress
-
consume
-
manage
-
send
例如
<security-setting match="activemq.management.#">
<permission type="createNonDurableQueue" roles="myRole"/>
<permission type="createAddress" roles="myRole"/>
<permission type="consume" roles="myRole"/>
<permission type="manage" roles="myRole"/>
<permission type="send" roles="myRole"/>
</security-setting>
無論您先前在執行時對 |
8. 對應外部角色
來自外部驗證提供者 (例如 LDAP) 的角色可以對應到內部使用的角色。這是透過安全設定區塊中的角色對應條目來完成的
<security-settings>
[...]
<role-mapping from="cn=admins,ou=Group,ou=ActiveMQ,ou=system" to="my-admin-role"/>
<role-mapping from="cn=users,ou=Group,ou=ActiveMQ,ou=system" to="my-user-role"/>
</security-settings>
角色對應是累加的。這表示使用者將保留原始角色以及新指派的角色。 |
此角色對應只會影響用於授權透過已配置的接收器進行佇列存取的角色。它不能用於對應存取 Web 主控台所需的角色。 |
9. SASL
AMQP 支援 SASL。支援以下機制:PLAIN、EXTERNAL、ANONYMOUS、GSSAPI、SCRAM-SHA-256、SCRAM-SHA-512。已發佈的清單可以透過 amqp 接收器 saslMechanisms
屬性來限制。
只有在 TLS 用戶端憑證提供主體時,才會選擇 EXTERNAL。 |
10. 變更叢集的使用者名稱/密碼
為了使叢集連線正常運作,叢集中的每個節點都必須連線到其他節點。它們用於此的使用者名稱/密碼應始終從安裝預設值變更,以防止安全風險。
請參閱 管理,以取得有關如何執行此操作的說明。
11. 保護主控台
Artemis 附帶一個 Web 主控台,允許使用者透過內嵌伺服器瀏覽 Artemis 文件。預設情況下,Web 存取是純 HTTP。它在 bootstrap.xml
中配置
<web path="web">
<binding uri="https://127.0.0.1:8161">
<app url="console" war="console.war"/>
</binding>
</web>
或者,您可以編輯上述配置以啟用使用 HTTPS 通訊協定的安全存取。例如:
<web path="web">
<binding uri="https://127.0.0.1:8443"
keyStorePath="${artemis.instance}/etc/keystore.jks"
keyStorePassword="password">
<app url="jolokia" war="jolokia-war-1.3.5.war"/>
</binding>
</web>
如範例所示,要啟用 https,首先要做的是將 bind
配置為 https
URL。此外,您還必須配置一些如下所述的額外屬性。
- keyStorePath
-
金鑰儲存檔案的路徑。
- keyStorePassword
-
金鑰儲存的密碼。
- clientAuth
-
布林值旗標,表示是否需要用戶端驗證。預設值為
false
。 - trustStorePath
-
信任儲存檔案的路徑。只有在
clientAuth
為true
時才需要此路徑。 - trustStorePassword
-
信任儲存的密碼。
11.1. 使用用戶端憑證配置存取
Web 主控台支援使用用戶端憑證進行驗證,請參閱以下步驟:
-
將 憑證登入模組新增至
login.config
檔案,例如:activemq-cert { org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule required debug=true org.apache.activemq.jaas.textfiledn.user="cert-users.properties" org.apache.activemq.jaas.textfiledn.role="cert-roles.properties"; };
-
變更 hawtio realm 以符合 憑證登入模組的
login.config
檔案中定義的 realm。這是透過系統屬性-Dhawtio.role=activemq-cert
在artemis.profile
中配置的。 -
為用戶端建立金鑰組,並將公開金鑰匯入信任儲存檔案。
keytool -storetype pkcs12 -keystore client-keystore.p12 -storepass securepass -keypass securepass -alias client -genkey -keyalg "RSA" -keysize 2048 -dname "CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -ext bc=ca:false -ext eku=cA keytool -storetype pkcs12 -keystore client-keystore.p12 -storepass securepass -alias client -exportcert -rfc > client.crt keytool -storetype pkcs12 -keystore client-truststore.p12 -storepass securepass -keypass securepass -importcert -alias client-ca -file client.crt -noprompt
-
啟用使用 HTTPS 通訊協定的安全存取,並使用用戶端驗證,使用在上一個步驟中建立的信任儲存檔案來設定
trustStorePath
和trustStorePassword
。<web path="web"> <binding uri="https://127.0.0.1:8443" keyStorePath="${artemis.instance}/etc/server-keystore.p12" keyStorePassword="password" clientAuth="true" trustStorePath="${artemis.instance}/etc/client-truststore.p12" trustStorePassword="password"> <app url="jolokia" war="jolokia-war-1.3.5.war"></app> </binding> </web>
-
使用在上一個步驟中建立的私密金鑰來設定您的用戶端,也就是說,如果用戶端應用程式是瀏覽器,請在瀏覽器中安裝私密金鑰。
12. 控制 JMS ObjectMessage 還原序列化
Artemis 提供了一個簡單的類別篩選機制,使用者可以使用該機制指定要信任哪些套件和不信任哪些套件。來自受信任套件的類別的物件可以毫無問題地還原序列化,而來自「不受信任」套件的物件將被拒絕還原序列化。
Artemis 保留一個 拒絕清單
來追蹤不受信任的套件,並保留一個 允許清單
來追蹤受信任的套件。預設情況下,這兩個清單都是空的,這表示允許還原序列化任何可序列化的物件。如果物件的類別與拒絕清單中的某個套件相符,則不允許還原序列化。如果物件的類別與允許清單中的某個套件相符,則可以還原序列化該物件。如果一個套件同時出現在拒絕清單和允許清單中,則拒絕清單中的套件優先。如果類別既不與 拒絕清單
也不與 允許清單
相符,則將拒絕類別還原序列化,除非允許清單為空 (表示使用者根本未指定允許清單)。
如果符合以下條件,則認為類別為「符合」:
-
其完整名稱與清單中的其中一個條目完全相符。
-
其套件與清單中的其中一個條目相符,或是其中一個條目的子套件。
例如,如果類別完整名稱為「org.apache.pkg1.Class1」,則一些符合的條目可能是:
-
org.apache.pkg1.Class1
- 完全符合。 -
org.apache.pkg1
- 完全套件符合。 -
org.apache
— 子套件符合。
*
表示拒絕或允許清單中的「符合所有」。
12.1. 透過連線工廠配置
若要指定允許和拒絕清單,可以使用 URL 參數 deserializationDenyList
和 deserializationAllowList
。例如,使用 JMS:
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://0?deserializationDenyList=org.apache.pkg1,org.some.pkg2");
上述陳述式建立了一個工廠,該工廠的拒絕清單包含兩個禁止的套件,「org.apache.pkg1」和「org.some.pkg2」,以逗號分隔。
12.2. 透過系統屬性配置
有兩個系統屬性可用於指定拒絕清單和允許清單
- org.apache.activemq.artemis.jms.deserialization.allowlist
-
允許清單的項目,以逗號分隔。
- org.apache.activemq.artemis.jms.deserialization.denylist
-
拒絕清單的項目,以逗號分隔。
一旦定義,虛擬機器中的所有 JMS 物件訊息反序列化都會受到這兩個清單的檢查。然而,如果您建立一個 ConnectionFactory 並在其中設定一組新的拒絕/允許清單,則新的值將覆蓋系統屬性。
12.3. 資源配接器的配置
使用 JMS 資源配接器接收訊息的訊息 bean 也可以透過為其資源配接器正確配置相關屬性來控制其物件反序列化。您可以在資源配接器的連線工廠中配置兩個屬性
- deserializationDenyList
-
拒絕清單的值,以逗號分隔
- deserializationAllowList
-
允許清單的值,以逗號分隔
這些屬性一旦指定,最終會設定在相應的內部工廠上。
14. 自訂安全性管理器
如果需要,可以變更 Broker 安全性實作的基礎。Broker 使用一個稱為「安全性管理器」的元件來實作實際的身份驗證和授權檢查。預設情況下,Broker 使用 org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager
來提供 JAAS 整合,但使用者可以提供他們自己的 org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager5
實作,並在 bootstrap.xml
中使用 security-manager
元素進行配置,例如:
<broker xmlns="https://activemq.dev.org.tw/schema">
<security-manager class-name="com.foo.MySecurityManager">
<property key="myKey1" value="myValue1"/>
<property key="myKey2" value="myValue2"/>
</security-manager>
...
</broker>
security-manager
範例 展示了如何更詳細地執行此操作。
15. 每個 Acceptor 的安全性網域
可以透過在個別的 acceptor
上指定安全性網域來覆寫 Broker 的 JAAS 安全性網域。只需使用 securityDomain
參數並指示要使用 login.config
中的哪個網域,例如:
<acceptor name="myAcceptor">tcp://127.0.0.1:61616?securityDomain=mySecurityDomain</acceptor>
任何連線到此 acceptor 的用戶端都將使用 mySecurityDomain
來強制執行安全性。