目次 | 前へ | 次へ | Java Management Extensions (JMX) テクノロジのチュートリアル |
この章では、JMX テクノロジのセキュリティー機能の設定方法の例を、次のセクション内で説明します。
注意:アプリケーションでは、ユーザーがパスワードをコマンド行に入力するのではなく、パスワードの入力をユーザーに求めるようにする必要があります。実稼動システムではセキュアな認証メカニズムを使用してください。
JMX テクノロジを使用して実装できるもっとも簡単なセキュリティーは、暗号化、ユーザー名とユーザーパスワードの認証、およびファイルアクセス制御に基づくものです。
簡単なセキュリティーを使用した RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Security/simple
内にあります。
/jmx_examples
/Security/simple
ディレクトリを開きます。
このディレクトリ内に、次のディレクトリがあります。
/server
、次のファイルを格納しています:Server.java
/config
、セキュリティー構成ファイルを格納しています。/mbeans
、次のファイルを格納しています。/client
、次のファイルを格納しています。*.java
と *.properties
のすべてのファイルを開きます
これらのファイルについて、以降セクションで分析します。
Server.java
クラスをコード例 5-1 に示します。
public class Server { public static void main(String[] args) { try { MBeanServer mbs = MBeanServerFactory.createMBeanServer(); HashMap env = new HashMap(); SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory(); SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory(); env.put(RMIConnectorServer. RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,csf); env.put(RMIConnectorServer. RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,ssf); env.put("jmx.remote.x.password.file", "config" + File.separator + "password.properties"); env.put("jmx.remote.x.access.file", "config" + File.separator + "access.properties"); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); cs.start(); } catch (Exception e) { e.printStackTrace(); } } }
コード例 5-1 に示す Server
クラスは、MBean サーバー mbs
を作成し、環境マップ env
にセキュリティー保護された RMI クライアントソケットファクトリ csf
、セキュリティー保護された RMI サーバーソケットファクトリ ssf
、およびプロパティーファイル password.properties
と access.properties
を渡します。
プロパティーファイル password.properties
には、ユーザー名とパスワードが含まれ、JMX リモート API インタフェース JMXAuthenticator
を使用してアクセスします。プロパティー jmx.remote.x.
password.file
を使用することは、パスワードベースの JMXAuthenticator
を作成し、これを jmx.remote.authenticator
プロパティーを通じて環境マップに渡すのと同じ意味を持ちます。
プロパティーファイル access.properties
には、ユーザー名と一定レベルのアクセス権、readwrite
と readonly
のいずれかが含まれます。これはアクティブなユーザーが、MBean サーバー操作にどのレベルでアクセスできるかを表します。このファイルベースのアクセス制御は、アクセスコントローラ MBean サーバー内に実際の MBean サーバーをラップする、JMX テクノロジのインタフェース MBeanServerForwarder
を使用して実装されます。アクセスコントローラ MBean サーバーは、適切なチェックを実行したあとに、実際の MBean サーバーに要求を転送します。
Server
は RMI コネクタ用に JMX サービス URL、url
を作成します。この RMI コネクタはデフォルトの JRMP トランスポート上で動作し、ローカルホストのポート 9999
の RMI レジストリに RMI コネクタスタブを登録します。
MBean サーバー mbs
、環境マップ env、およびサービス URL url
はすべて JMXConnectorServer
に渡され、セキュアな JMX コネクタサーバー cs
が新規に作成されます。
SimpleStandardMBean
クラスは、第 3 章「JMX コネクタ」で使用されたものと同じ簡単な MBean インタフェースを定義します。
SimpleStandard
クラスは、第 3 章「JMX コネクタ」で使用されたものと同じ簡単な MBean を定義します。
ClientListener
クラスは、第 3 章「JMX コネクタ」で使用されたものと同じ簡単な通知リスナーを定義します。
Client.java
クラスをコード例 5-1 に示します。
public class Client { public static void main(String[] args) { try { HashMap env = new HashMap(); String[] credentials = new String[] { "username" , "password" }; env.put("jmx.remote.credentials", credentials); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url, env); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); String domains[] = mbsc.getDomains(); for (int i = 0; i < domains.length; i++) { System.out.println("Domain[" + i + "] = " + domains[i]); } ObjectName mbeanName = new ObjectName("MBeans:type=SimpleStandard"); mbsc.createMBean("SimpleStandard", mbeanName, null, null); // Perform MBean operations [...] mbsc.removeNotificationListener(mbeanName, listener); mbsc.unregisterMBean(mbeanName); jmxc.close(); } catch (Exception e) { e.printStackTrace(); } } }
コード例 5-1 に示す Client
クラスは、環境マップ env
に Server
が求める資格セット、つまり username
や password
を渡します。これらの資格は、コネクタスタブのサービス URL と環境マップが JMXConnectorFactory.connect()
に渡されるときに、JMXConnector
のインスタンス jmxc
に付与されます。Client
は jmxc
を通じて、Server
側で起動された MBean に接続し、MBean の操作を実行します。
接続が確立すると、環境マップ env
で付与された資格はサーバーに送信されます。サーバーは次に、JMXAuthenticator
インタフェースの authenticate()
メソッドを呼び出し、クライアント資格をパラメータとして渡します。authenticate()
メソッドは、クライアントを認証し、アクセス制御の確認に使用される主体セットを含む被認証者を返します。
簡単なセキュリティーを使用した RMI コネクタの例題を実行するには、次の手順を実行します。
$ javac mbeans/SimpleStandard.java \ mbeans/SimpleStandardMBean.java \ server/Server.java \ client/Client.java \ client/ClientListener.java
Server
を起動します。
$
java -classpath server:mbeans \
-Djavax.net.ssl.keyStore=config/keystore \
-Djavax.net.ssl.keyStorePassword=password \
Server &
MBean サーバーと RMI コネクタの作成の確認が表示されます。
Client
を起動します。
$
java -classpath client:server:mbeans \
-Djavax.net.ssl.trustStore=config/truststore \
-Djavax.net.ssl.trustStorePassword=trustword \
Client
コネクタクライアントと各種の MBean 操作の作成、および作成後の接続の終了の確認が表示されます。
この例からわかるように、すべての処理が、第 3 章「JMX コネクタ」で示す基本的な RMI コネクタの例とまったく同じ方法で進められているように見えます。ただし、password.properties
を開きパスワードを変更する場合、Client
を起動すると java.lang.SecurityException
が表示され、接続に失敗します。
実装において接続のクライアント側が、セクション「簡単なセキュリティー」で示したセキュリティーメカニズムを使用して、複数のユーザーまたはアプリケーションに代わって異なる操作を実行する場合、各ユーザーが操作を実行するたびにセキュアな接続を確立しなければなりません。コネクタクライアントが多くのユーザーと対話することが予測される場合、主体委譲を実装してシステムの負荷を減らすことができます。主体委譲を実装すると、ユーザーごとに 1 つのセキュアな接続が確立され、この接続を使用すると、任意の数のユーザーに代わって関連する操作を実行できます。接続自体は認証されたユーザーによって設定されます。別のユーザーに代わって動作することを許可する SubjectDelegationPermission
が認証ユーザーに付与されている場合、そのユーザーに代わって、接続を使った操作を実行できます。
主体委譲を実装するセキュアな RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Security/subject_delegation
内にあります。
/jmx_examples
/Security/subject_delegation
ディレクトリを開きます。
このディレクトリ内に、次のディレクトリがあります。
/server
。ファイル Server.java
を格納しています。/config
、セキュリティー構成ファイルを格納しています。/mbeans
、次のファイルを格納しています。/client
、次のファイルを格納しています。*.java
と *.properties
のすべてのファイルを開きます
これらのファイルについて、以降セクションで分析します。
Server.java
クラスをコード例 5-1 に示します。
public class Server { public static void main(String[] args) { try { MBeanServer mbs = MBeanServerFactory.createMBeanServer(); HashMap env = new HashMap(); env.put("jmx.remote.x.password.file", "config" + File.separator + "password.properties"); env.put("jmx.remote.x.access.file", "config" + File.separator + "access.properties"); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); cs.start(); } catch (Exception e) { e.printStackTrace(); } } }
コード例 5-1 は、MBean サーバー mbs
の作成から始まります。環境マップ env
には、password.properties
というパスワードファイルと access.properties
というアクセスファイルが格納されます。
次に Server
はコネクタサーバー cs
を作成し、前述の RMI コネクタの例題とまったく同じ方法でコネクタサーバーを起動します。
java.policy
ファイルは username
に SubjectDelegationPermission
を付与し、このユーザーが Client
で作成された JMXPrincipal
のインスタンスである、ユーザー delegate
の代わりに操作を実行することを許可します。java.policy
ファイルが要求されるのは、Server
クラスの起動時です。
SimpleStandardMBean
クラスは、前出の例で使用されたのと同じ簡単な MBean インタフェースを定義します。
SimpleStandard
クラスは、前出の例で使用されたのと同じ簡単な MBean を定義します。
ClientListener
クラスは、前出の例題で使用されたのと同じ簡単な通知リスナーを定義します。
Client.java
クラスをコード例 5-1 に示します。
public class Client { public static void main(String[] args) { try { HashMap env = new HashMap(); String[] credentials = new String[] { "username" , "password" }; env.put("jmx.remote.credentials", credentials); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url, env); Subject delegationSubject = new Subject(true, Collections.singleton(new JMXPrincipal("delegate")), Collections.EMPTY_SET, Collections.EMPTY_SET); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(delegationSubject); String domains[] = mbsc.getDomains(); ObjectName mbeanName = new ObjectName("MBeans:type=SimpleStandard"); mbsc.createMBean("SimpleStandard", mbeanName, null, null); // Perform MBean operations // [...] mbsc.removeNotificationListener(mbeanName, listener); mbsc.unregisterMBean(mbeanName); jmxc.close(); } catch (Exception e) { e.printStackTrace(); } } }
コード例 5-1 は、ユーザー名 username
とパスワード password
が格納された環境マップ env
の作成から始まります。これらの文字列は、Server
がコネクタサーバーにアクセスするユーザーを認証するために保持する password.properties
ファイルに保存されたユーザー名とパスワードに一致します。
JMX テクノロジのコネクタクライアント jmxc
は、前述の RMI コネクタの例題と同じ方法で作成され、ユーザー名とパスワードは環境マップ env
に渡されます。
次に、Client
は、JMXPrincipal
のインスタンスである delegate
という名前の Principal
を使用して、Subject
のインスタンス delegationSubject
を作成します。
MBean サーバー接続 mbsc
は、JMXConnector
の getMBeanServerConnection()
メソッドを呼び出し、パラメータとして delegationSubject
を渡して作成されます。したがって、この MBean サーバー接続を使用すると、delegationSubject
に保存された主体、この例では delegate
という名前の JMXPrincipal
に代わって、リモート MBean サーバー上で操作を実行できます。
この例題ではさらに、これまでの例とまったく同じ方法で、MBean サーバーで SimpleStandard
MBean が作成および登録され、この MBean 上で操作が実行されます。
主体委譲を使用したセキュアな RMI コネクタの例題を実行するには、次の手順を実行します。
$ javac mbeans/SimpleStandard.java \ mbeans/SimpleStandardMBean.java \ server/Server.java \ client/Client.java \ client/ClientListener.java
$
export CLASSPATH=server ; rmiregistry 9999 &
Server
を起動します。MBean サーバーの作成、環境マップの初期化、RMI コネクタの作成、およびコネクタの MBean サーバーへの登録の確認が表示されます。
Client
を起動します。$
java -classpath client:server:mbeans Client
コネクタクライアントの作成、主体委譲の作成、MBean サーバーへの接続、およびさまざまな MBean 操作、その後の接続の終了の確認が表示されます。
Java Authentication and Authorization Service (JAAS) と Java platform Standard Edition (Java SE) セキュリティーアーキテクチャーによってユーザーアクセスを管理することで、より詳細なレベルのセキュリティーをコネクタに実装できます。JAAS と Java SE セキュリティーの基本は、セキュリティーマネージャーとポリシーファイルを使用して、ユーザーごとに異なるアクセスレベルを指定することです。最終的に、どのユーザーにどの操作の実行を許可するかをより正確に決定することができます。
このセクションの 2 つの例題は、セクション「簡単なセキュリティー」に示す例題と非常に似ていますが、異なる点として、簡単なファイルベースのアクセス制御が、ポリシーベースのアクセス制御に置き換えられています。
詳細なセキュリティーを使用した RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Security/fine_grained
内にあります。
/jmx_examples
/Security/fine_grained を開きます。
このディレクトリ内に、次のディレクトリがあります。
/server
、次のファイルを格納しています:Server.java
/config
、セキュリティー構成ファイルを格納しています。/mbeans
、次のファイルを格納しています。/client
、次のファイルを格納しています。*.java
と *.properties
のすべてのファイルを開きます。
この例題で使用される Server.java
クラスは、簡単なセキュリティーを使用した RMI コネクタで使用されるクラスに非常に似ています。ただし、詳細なセキュリティーの例題では、環境マップにマップされる access.properties
ファイルがありません。それ以外は、両クラスは同一です。
java.policy
ファイルは、次の権限を付与します。
server
コードベースのすべての権限。これがあることで、コネクタサーバーはコネクタを作成し、リモートユーザーの呼び出しで要求される操作を実行できるmbeans
コードベースに対する MBeanTrustPermission
。これによって、信頼された MBean を MBean サーバーに登録できるJMXPrincipal
で表されるユーザー、username.
に対する、各種の MBean 操作および MBean サーバー操作を実行する権限SimpleStandardMBean
クラスは、前出の例で使用されたのと同じ簡単な MBean インタフェースを定義します。
SimpleStandard
クラスは、前出の例で使用されたのと同じ簡単な MBean を定義します。
ClientListener
クラスは、前出の例題で使用されたのと同じ簡単な通知リスナーを定義します。
Client.java
クラスは、簡単なセキュリティーを使用した RMI コネクタの例題で使用されるクラスとまったく同じです。
詳細なセキュリティーを使用した RMI コネクタの例題を実行するには、次の手順を実行します。
$ javac mbeans/SimpleStandard.java \ mbeans/SimpleStandardMBean.java \ server/Server.java \ client/Client.java \ client/ClientListener.java
$
export CLASSPATH=server ; rmiregistry 9999 &
Server
を起動します。
$
java -classpath server:mbeans \
-Djavax.net.ssl.keyStore=config/keystore \
-Djavax.net.ssl.keyStorePassword=password \
-Djava.security.manager \
-Djava.security.policy=config/java.policy \
Server &
環境マップの初期化、MBean サーバーと RMI コネクタの作成の確認が表示されます。
Client
を起動します。
$ java -classpath client:server:mbeans \ -Djavax.net.ssl.trustStore=config/truststore \ -Djavax.net.ssl.trustStorePassword=trustword \ Client
コネクタクライアントの作成、RMI サーバーへの接続、各種の MBean 操作、および接続の終了の確認が表示されます。