テンプレート処理中にエラーが発生しました。
Java method "com.liferay.portal.json.JSONFactoryImpl.createJSONObject(String)" threw an exception when invoked on com.liferay.portal.json.JSONFactoryImpl object "com.liferay.portal.json.JSONFactoryImpl@2ad66ae2"; see cause exception in the Java stack trace.

----
FTL stack trace ("~" means nesting-related):
	- Failed at: navigationJSONObject = jsonFactoryUti...  [in template "17855804202317#32484267#LEARN-ARTICLE-NAV" at line 4, column 9]
----
1<#assign 
2	groupFriendlyURL = themeDisplay.getScopeGroup().getFriendlyURL() 
3	groupPathFriendlyURLPublic = themeDisplay.getPathFriendlyURLPublic() + groupFriendlyURL 
4	navigationJSONObject = jsonFactoryUtil.createJSONObject(navigation.getData()) 
5	navigationMenuItems = 
6
7			"Analytics Cloud": { 
8				"image": "/documents/d${groupFriendlyURL}/analytics_c-svg", 
9				"title": "Analytics Cloud", 
10				"url": "analytics-cloud" 
11			}, 
12			"Commerce": { 
13				"image": "/documents/d${groupFriendlyURL}/commerce_product-svg", 
14				"title": "Commerce", 
15				"url": "commerce" 
16			}, 
17			"DXP": { 
18				"image": "/documents/d${groupFriendlyURL}/dxp_p-svg", 
19				"title": "DXP / Portal", 
20				"url": "dxp" 
21			}, 
22			"Liferay Cloud": { 
23				"image": "/documents/d${groupFriendlyURL}/dxp_c-svg", 
24				"title": "Liferay Cloud", 
25				"url": "liferay-cloud" 
26			}, 
27			"Reference": { 
28				"image": "/documents/d${groupFriendlyURL}/reference-svg", 
29				"title": "Reference", 
30				"url": "reference" 
31
32
33 
34	breadcrumbJSONArray = navigationJSONObject.getJSONArray("breadcrumb") 
35	childrenJSONArray = navigationJSONObject.getJSONArray("children") 
36	parentJSONObject = navigationJSONObject.getJSONObject("parent") 
37	productJSONObject = breadcrumbJSONArray.getJSONObject(breadcrumbJSONArray.length()-1)!navigationJSONObject.getJSONObject("self") 
38	siblingsJSONArray = navigationJSONObject.getJSONArray("siblings") 
39/> 
40 
41<div class="learn-article-nav"> 
42	<#if productJSONObject?has_content && productJSONObject.getString("title")?has_content && navigationMenuItems[productJSONObject.getString("title")]?has_content && navigationMenuItems[productJSONObject.getString("title")].title?has_content> 
43		<div 
44			class="dropdown learn-article-nav-root learn-dropdown" 
45
46			<div class="learn-article-nav-item"> 
47				<div class="d-flex"> 
48					<div class="learn-article-nav-image"> 
49						<img 
50							class="lexicon-icon lexicon-icon-caret-bottom product-icon" 
51							role="presentation" 
52							src='${navigationMenuItems[productJSONObject.getString("title")].image}' 
53							viewBox="0 0 512 512" 
54						/> 
55					</div> 
56 
57					<span class="learn-article-nav-text">${navigationMenuItems[productJSONObject.getString("title")].title}</span> 
58				</div> 
59 
60				<div id="dropdown-icon"> 
61					<svg 
62						class="lexicon-icon lexicon-icon-caret-bottom" 
63						role="presentation" 
64						viewBox="0 0 512 512" 
65
66						<use xlink:href="/o/admin-theme/images/clay/icons.svg#caret-bottom"></use> 
67					</svg> 
68				</div> 
69			</div> 
70 
71			<ul class="dropdown-menu learn-dropdown-menu"> 
72				<#list navigationMenuItems as key, value> 
73					<li> 
74						<a 
75							class="dropdown-item learn-article-nav-item" 
76							href="/w/${navigationMenuItems[key].url}/index" 
77							tabindex="4" 
78
79							<span class="d-flex"> 
80								<span class="learn-article-nav-image"> 
81									<img 
82										class="lexicon-icon lexicon-icon-caret-bottom product-icon mt-0 mr-2" 
83										role="presentation" 
84										src="${value.image}"height: 25px; margin-left: 5px; max-width: none; width: 25px; 
85										viewBox="0 0 512 512" 
86									/> 
87								</span> 
88								<span class="learn-article-nav-text">${value.title}</span> 
89							</span> 
90 
91							<#if navigationMenuItems[productJSONObject.getString("title")].url == value.url> 
92								<span> 
93									<@clay["icon"] symbol="check" /> 
94								</span> 
95							</#if> 
96						</a> 
97					</li> 
98				</#list> 
99			</ul> 
100		</div> 
101	</#if> 
102 
103	<div class="learn-article-nav-content"> 
104		<#if parentJSONObject?has_content && parentJSONObject.getString("url")?has_content> 
105			<div class="learn-article-nav-item learn-article-nav-parent liferay-nav-item p-2"> 
106				<div class="mr-2"> 
107					<a 
108						href='${parentJSONObject.getString("url")}' 
109
110						<svg 
111							class="lexicon-icon lexicon-icon-angle-left" 
112							role="presentation" 
113							viewBox="0 0 512 512" 
114
115							<use xlink:href="/o/admin-theme/images/clay/icons.svg#angle-left"></use> 
116						</svg> 
117					</a> 
118				</div> 
119 
120				<span>${parentJSONObject.getString("title")}</span> 
121			</div> 
122		</#if> 
123 
124		<#if childrenJSONArray.length() gt 0> 
125			<ul class="m-0 p-2"> 
126				<#list 0..childrenJSONArray.length()-1 as i> 
127					<li class="learn-article-nav-item"> 
128						<a 
129							class='liferay-nav-item ${(navigationJSONObject.getJSONObject("self").url == childrenJSONArray.getJSONObject(i).url)?then("selected", "")}' 
130							href="${childrenJSONArray.getJSONObject(i).url}" 
131
132							<span>${childrenJSONArray.getJSONObject(i).getString("title")}</span> 
133						</a> 
134					</li> 
135				</#list> 
136			</ul> 
137		<#elseif siblingsJSONArray.length() gt 0> 
138			<ul class="m-0 p-2"> 
139				<#list 0..siblingsJSONArray.length()-1 as i> 
140					<li class="learn-article-nav-item"> 
141						<a 
142							class='liferay-nav-item ${(navigationJSONObject.getJSONObject("self").url == siblingsJSONArray.getJSONObject(i).url)?then("selected", "")}' 
143							href="${siblingsJSONArray.getJSONObject(i).url}" 
144
145							<span>${siblingsJSONArray.getJSONObject(i).getString("title")}</span> 
146						</a> 
147					</li> 
148				</#list> 
149			</ul> 
150		</#if> 
151	</div> 
152</div> 

Elasticsearchの保護

Elasticsearchを保護するために最初に行う必要があるのは、 X-Pack Securityを有効にする ことです。 その後、認証と暗号化通信の設定を開始できます。

note

Elasticsearch 6.x: Elasticsearch 6を使用している場合、ElasticのX-Pack Securityを使用するにはLiferay Enterprise Search (LES)サブスクリプションとLiferay Enterprise Search セキュリティアプリケーションが必要です。 Liferay Connector to Elasticsearch 7( Customer Downloads Portal で入手可能で、Liferay 7.3以降にバンドルされている)から、ElasticのX-Packセキュリティのサポートがデフォルトで含まれています。 Elastic社のX-Packモニタリングと連携するには、LESが必要です。

X-Pack Securityの有効化

セキュリティを有効にするには、各Elasticsearchノードの[Elasticsearch Home]/config/elasticsearch.ymlファイルに次の設定を追加します。

xpack.security.enabled: true

これで、X-Packユーザーを設定できます。

X-Packユーザーの設定

X-Packを使用するシステムでは、次の 組み込みX-Packユーザー が重要です。

  • kibana_system
  • elastic

Elasticsearchサーバーで、 setup-passwordsコマンド を使用してパスワードを設定します。

./bin/elasticsearch-setup-passwords interactive
note

以下の設定では、すべてのパスワードが「liferay」に設定されているものとします。 インストールの際には、独自のパスワードを使用してください。

note

内蔵ユーザーのパスワードを更新するには、KibanaのUIまたは Change Password API を使用します。

Elasticsearch通信の暗号化

トランスポート層セキュリティ(TLS)を有効にするには、ノード証明書と鍵を生成し、ElasticsearchサーバーとLiferayサーバーに適用する必要があります。

ノード証明書の生成

ノードごとに 証明書を生成する か、Liferayなどのすべてのノードとクライアントで使用する証明書を生成します。 または、認証局を使用してノード証明書を取得します。

  1. X-Packの certutil コマンドを使用してX-Pack認証局を生成します。

    ./bin/elasticsearch-certutil ca --ca-dn CN=elastic-ca
    

    elastic-stack-ca.p12というファイルが生成されます。

    認証局の証明書と秘密鍵をPEM形式で生成するには、

    ./bin/elasticsearch-certutil ca --pem --ca-dn CN=elastic-ca
    
  2. 認証局ファイルを[Elasticsearch Home]/config/certsフォルダに移動します。

  3. 作成したCAを使用して、X.509証明書と秘密鍵を生成します。

    PKCS#12形式で証明書と鍵を生成するには、次のコマンドを実行します。

    ./bin/elasticsearch-certutil cert --ca config/certs/elastic-stack-ca.p12 --ca-pass liferay --dns localhost --ip 127.0.0.1 --name elastic-nodes
    

    PEM形式で証明書と鍵を生成するには、次のコマンドを実行します。

    ./bin/elasticsearch-certutil cert --pem --ca-cert config/certs/ca.crt --ca-key config/certs/ca.key --dns localhost --ip 127.0.0.1 --name elastic-nodes
    

    PKSC#12認証局からPEM形式のノード証明書と鍵を生成するには、次のコマンドを実行します。

    ./bin/elasticsearch-certutil cert --pem --ca config/certs/elastic-stack-ca.p12 --ca-pass liferay --dns localhost --ip 127.0.0.1 --name elastic-nodes
    
    note

    Liferay 7.3+ では、 Elasticsearch connector configuration で以下の keystore タイプのみが使用できます。

    複数のホストで動作する証明書を生成するには(たとえば、すべてのElasticsearchおよびLiferayサーバーで同じ証明書を使用するには)、DNS名とIPアドレスを列挙する際にカンマ区切りのリストを使用します。

    ./bin/elasticsearch-certutil cert --ca config/certs/elastic-stack-ca.p12 --ca-pass liferay --dns localhost,example.com,es-node1,es-node2,es-node3 --ip 127.0.0.1,<IPv4-address-2>,<IPv4-address-3>,<IPv4-address-4>
    

    elasticsearch-certutil cert コマンドは、 elastic-nodes.p12 という別のファイルを生成します(他の名前でかまいません)。

    note

    certutilコマンドのデフォルトでは、証明書の生成にPKCS#12形式を使用しており、これはElastic Stack 7.xで動作します。 Kibana 6.xはPKCS#12証明書では動作しないため、Liferay 7.2とKibana 6.xをLiferay Enterprise Search Monitoringで使用している場合は、--pemオプション(証明書をPEM形式で生成)が重要になります。 それぞれのケースのPEMコマンドは2つのZIPファイルを生成します。ca.crtca.keyelastic-nodes.crtelastic-nodes.key`の2つのZIPファイルが生成されます。 アーカイブの内容を解凍して、[Elasticsearch Home]/config/certsフォルダに入れてください。

  4. elastic-nodes.p12[Elasticsearch Home]/config/certsフォルダに移動します。

    チェックポイント: [Elasticsearch Home]/config/certsフォルダに次のファイルができました。

    elastic-nodes.p12
    elastic-stack-ca.p12
    

    または

    ca.crt
    ca.key
    elastic-nodes.crt
    elastic-nodes.key
    
  5. ファイルを各Elasticsearchノードの同じフォルダと各Liferayサーバーノードの適切な場所にコピーします。

証明書と鍵が、Elasticsearch設定で使用できるようになりました。

Elasticsearch用のTLSを設定する

[Elasticsearch Home]/config/elasticsearch.ymlファイルを介して各ノードで TLSを有効 にします。

  1. ノード間通信のためにelasticsearch.ymlで次の設定を使用してトランスポート層TLSを有効にします。

    xpack.security.transport.ssl.enabled: true
    
  2. トランスポートレイヤーTLSの設定 証明書、鍵、認証局のパスを各ノードのelasticsearch.ymlに追加します。

    # PKCS#12
    xpack.security.transport.ssl.keystore.path: certs/elastic-nodes.p12
    xpack.security.transport.ssl.keystore.password: liferay
    xpack.security.transport.ssl.truststore.path: certs/elastic-nodes.p12
    xpack.security.transport.ssl.truststore.password: liferay
    # PEM
    #xpack.security.transport.ssl.certificate_authorities: [ "certs/ca.crt" ]
    #xpack.security.transport.ssl.certificate: certs/elastic-nodes.crt
    #xpack.security.transport.ssl.key: certs/elastic-nodes.key
    
    xpack.security.transport.ssl.verification_mode: certificate
    

    上記のパスの例は、[Elasticsearch Home]/config/certsに証明書を追加したことを前提としています。

  3. HTTPレイヤーでTLSを有効にして、クライアント通信を暗号化します。

    xpack.security.http.ssl.enabled: true
    
  4. HTTPレイヤーのTLSを設定します。 各ノードの elasticsearch.ymlに、証明書、鍵、認証局のパスを追加します。

    # PKCS#12
    xpack.security.http.ssl.keystore.path: certs/elastic-nodes.p12
    xpack.security.http.ssl.keystore.password: liferay
    xpack.security.http.ssl.truststore.path: certs/elastic-nodes.p12
    xpack.security.http.ssl.truststore.password: liferay
    # PEM
    #xpack.security.http.ssl.certificate_authorities: [ "certs/ca.crt" ]
    #xpack.security.http.ssl.certificate: certs/elastic-nodes.crt
    #xpack.security.http.ssl.key: certs/elastic-nodes.key
    

Elasticsearchのセキュリティ設定の例

以下はElasticsearchの完全な設定です (elasticsearch.yml; Elasticsearch 6.5.x+にも同様に適用されます):

cluster.name: LiferayElasticsearchCluster

# X-Pack Security
xpack.security.enabled: true

## TLS/SSL settings for Transport layer (PKCS#12)
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.path: certs/elastic-nodes.p12
xpack.security.transport.ssl.keystore.password: liferay
xpack.security.transport.ssl.truststore.path: certs/elastic-nodes.p12
xpack.security.transport.ssl.truststore.password: liferay
xpack.security.transport.ssl.verification_mode: certificate

# TLS/SSL settings for HTTP layer (PKCS#12)
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/elastic-nodes.p12
xpack.security.http.ssl.keystore.password: liferay
xpack.security.http.ssl.truststore.path: certs/elastic-nodes.p12
xpack.security.http.ssl.truststore.password: liferay

# Comment out when Kibana and Liferay's X-Pack Monitoring are also configured
#xpack.monitoring.collection.enabled: true

LiferayでElasticsearchへの安全な接続を設定する

Liferayでは、セキュリティはコントロールパネルまたは設定ファイルを使用して構成できます。 [コントロールパネル] → [設定] → [システム設定] に移動します。 [検索機能] カテゴリを見つけて、Liferay 7.3+の [Elasticsearch 7] エントリまたはLiferay 7.2の [X-Pack Security] エントリをクリックします。 ここにプロパティ値を入力することもできますが、[Liferay Home]/osgi/configsにデプロイされている設定ファイルを使用するのが一般的です。

ファイルの正確なコンテンツは、X-Packの設定によって異なります。 passwordは、上記のX-Packユーザーパスワードのセットアップ中に設定したものと一致する必要があります。

ここで参照されている証明書と鍵のファイルは、Elasticsearchサーバーノードで使用されているものと同じです。 それらをLiferayサーバーにコピーし、それに応じて設定内のパスを更新します。

TLSの設定に加えて、authenticationEnabled/requiresAuthenticationtrueに設定し、LiferayがElasticsearchへの認証に使用するElasticsearchユーザーの認証情報を提供することにより、以下の設定で認証を有効にします。

セキュリティの設定が完了したら、Elasticsearchを再起動します。 これらの手順では、Elasticsearchクラスターを完全に再起動する必要があります。

Liferay 7.3および7.4でElasticsearchへの安全な接続を設定する

tip

ElasticsearchのインストールElasticsearchへの接続 では、セキュリティを有効にし設定する方法を紹介していますので、 7.3 適用対象のセキュリティ設定についてはそちらを参照してください。

Liferay 7.3+にバンドルされているElasticsearchコネクタはX-Pack Securityをサポートしています。 Elasticsearch コネクタの設定で使用できるサポートされているキーストアタイプのリストについては、 Java 11 セキュリティドキュメント を参照してください。

以下のようなファイルを作成します。

com.liferay.portal.search.elasticsearch7.configuration.ElasticsearchConfiguration.config

次のようにファイルにデータを入力します。

operationMode="REMOTE"
productionModeEnabled=B"true"
username="elastic"
password="liferay"
authenticationEnabled=B"true"
httpSSLEnabled=B"true"
networkHostAddresses=["https://localhost:9200"]
truststorePassword="liferay"
truststorePath="/PATH/TO/elastic-nodes.p12"
truststoreType="pkcs12"

Liferay 7.2でElasticsearchへの安全な接続を設定する

Elasticsearch 7以上へのLiferayコネクタはすべてX-Pack Securityをサポートしています。

note

Liferay 7.2とElasticsearch 6.xを使用していて、Liferay Enterprise Searchのサブスクリプションを持っている場合、 download 「Liferay Enterprise Search Security」アプリケーションを使用します。 LPKGファイルを[Liferay Home]/deployフォルダにコピーしてインストールします。

以下のようなファイルを作成します。

com.liferay.portal.search.elasticsearch7.configuration.XPackSecurityConfiguration.config

(またはElastic Stack 6.xとLiferay Enterprise Search Securityアプリケーションを使用している場合はcom.liferay.portal.search.elasticsearch6.configuration.XPackSecurityConfiguration.config

次のようにファイルにデータを入力します(PKCS#12):

certificateFormat="PKCS#12"
sslKeystorePath="/PATH/TO/elastic-nodes.p12"
sslKeystorePassword="liferay"
sslTruststorePath="/PATH/TO/elastic-nodes.p12"
sslTruststorePassword="liferay"
requiresAuthentication=B"true"
username="elastic"
password="liferay"
transportSSLVerificationMode="certificate"
transportSSLEnabled=B"true"

PEM形式の証明書を使用している場合は、次のような設定を使用します。

certificateFormat="PEM"
sslKeyPath="/PATH/TO/elastic-nodes.key"
sslCertificatePath="/PATH/TO/elastic-nodes.crt"
requiresAuthentication=B"true"
username="elastic"
password="liferay"
sslCertificateAuthoritiesPaths="/PATH/TO/ca.crt"
transportSSLVerificationMode="certificate"
transportSSLEnabled="true"

Liferay 7.3と7.4におけるElasticsearchコネクタのセキュリティ設定

以下は、7.3+ の Elasticsearch コネクタのセキュリティ設定の完全なリストです(カッコ内はデフォルト値):

authenticationEnabledtrue):ユーザー名とパスワードを使用したElasticsearchへの認証を有効または無効にします。

usernameelastic):[認証が有効]がオンになっている場合、認証用のユーザー名をElasticsearchに設定します。

password:[認証が有効]がオンになっている場合、認証用のパスワードをElasticsearchに設定します。

httpSSLEnabledfalse):TLS/SSLを有効または無効にします。

truststoreTypepkcs12):[HTTP SSLが有効]がオンになっている場合、トラストストアの種類を設定します。

truststorePath/path/ro/localhost.p12):[HTTP SSLが有効]がオンになっている場合、トラストストアファイルへのパスを設定します。

truststorePassword:[HTTP SSLが有効]がオンになっている場合、パスワードをトラストストアに設定します。

Liferay 7.2のエンタープライズ・サーチセキュリティ/X-Pack Securityの設定

Liferay 7.2のX-Pack Security構成の設定の完全な一覧は次のとおりです。

sslKeyPath/path/to/instance.key):秘密鍵を含むPEMエンコードファイルへのパスを設定します。

sslCertificatePath/path/to/instance.crt):クライアントが接続するときにクライアントに提示される証明書(または証明書チェーン)を含むPEMエンコードファイルへのパスを設定します。 デフォルトは/path/to/instance.crtです。

sslcertificateAuthoritiesPaths ([“/path/to/ca.crt”]) です。信頼できるPEMエンコードされた証明書ファイルのパスのリストを提供します。

certificateFormat (PKCS#12) を指定します。証明書のフォーマットを指定します (PEM または PKCS#12)。

requireAuthenticationfalse):有効にすると、Elasticsearch/X-Packとの接続は設定されたユーザー名とパスワードで認証されます。

usernameelastic):[認証を要求]が有効になっている場合は、認証用のユーザー名をElasticsearchに設定する必要があります。

password:[認証を要求]が有効になっている場合、パスワードが必要です。

transportSSLVerificationModecertificate):LDAPを使用して中間者攻撃や証明書の偽造から保護する場合は、検証タイプ(nonecertificate、または full)を指定します。

transportSSLEnabledfalse):TLS/SSLを設定または無効にします。

sslKeystorePath/path/to/elastic-certificates.p12):秘密鍵と証明書を保持しているキーストアへのパスを設定します。

sslKeystorePassword: PKCS#12ファイルのパスワードを設定します。

sslTruststorePath/path/to/elastic-certificates.p12):トラストストアファイルへのパスを設定します。

sslTruststorePassword:パスワードをトラストストアに設定します。

TLSプロトコルと暗号スイートの設定

LiferayのJVMでTLSのプロパティを設定することで、ElasticsearchとLiferayの接続を暗号化する際に使用するTLSプロトコルのバージョンと暗号スイートを制御することができます。 これらのプロパティは、Tomcatサーバーの setenv.shで設定することができる:

CATALINA_OPTS="$CATALINA_OPTS -Djdk.tls.client.protocols=TLSv1.2
CATALINA_OPTS="$CATALINA_OPTS -Djdk.tls.client.cipherSuites=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"

なお、これらは一例である。

これらの設定は、対応するXPackの設定と連動して機能する。

Liferay 7.3または7.4でREST Client接続を設定している場合は、 elasticsearch.ymlにあるような HTTPレイヤー設定 を使用してください:

xpack.security.http.ssl.supported_protocols: [ "TLSv1.2" ]
xpack.security.http.ssl.cipher_suites : TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

Liferay 7.1と7.2でトランスポートクライアントを設定している場合は、 elaticsearch.ymlにあるような トランスポート設定 を使用してください:

xpack.security.transport.ssl.supported_protocols: [ "TLSv1.2" ]
xpack.security.transport.ssl.cipher_suites : TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

関連トピック