시큐리티 - xrath.com 에서 번역됨

목차 | 전의 항목 | 다음의 항목 | Java Management Extensions (JMX) 테크놀러지의 튜토리얼

## 제 5 장

## 시큐리티

이 장에서는, JMX 테크놀러지의 시큐리티 기능의 설정 방법법의 예를, 다음의 섹션내에서 설명합니다.

- 「5.1 간단한 시큐리티」 에서는, 패스워드 인증과 파일 액세스 제어에 근거한 간단한 시큐리티를 구현하는, 연결기의 예를 나타냅니다.
- 「5.2 주체 위양」 에서는, 특정의 인증된 접속으로 조작을 실행하는 경우에, 복수가 다른 ID 대신에 주체 위양 모델을 사용하는 연결기의 예를 나타냅니다.
- 「5.3 상세한 시큐리티」 에서는, 개개의 조작을 실행하는 권한이 제어되는, 보다 고도의 시큐리티 기구를 구현하는 연결기의 예를 나타냅니다.

## 5.1 간단한 시큐리티

JMX 테크놀러지를 사용해 구현할 수 있는 가장 간단한 시큐리티는, 암호화, 사용자명과 사용자 패스워드의 인증, 및 파일 액세스 제어에 근거하는 것입니다.

### 5.1. 1 간단한 시큐리티를 사용한 RMI 연결기

간단한 시큐리티를 사용한 RMI 연결기의 예는, 디렉토리 work_dir`/jmx_examples/Security/simple` 내에 있습니다.

1. work_dir`/jmx_examples``/Security/simple` 디렉토리를 엽니다.

이 디렉토리내에, 다음의 디렉토리가 있습니다.

- `/server`. 파일 `Server.java` 를 거두고 있습니다.
- `/config`. 시큐리티 설정 파일을 거두고 있습니다.

- `access.properties`
- `keystore`
- `password.properties`
- `truststore`

- `/mbeans`. 다음의 파일을 거두고 있습니다.

- `SimpleStandardMBean.java`
- `SimpleStandard.java`

- `/client`. 다음의 파일을 거두고 있습니다.

- `Client.java`
- `ClientListener.java`

2. 텍스트 문자 편집기로,`*. java` 와 `*. properties` 의 모든 파일을 엽니다.

이러한 파일에 대해, 이후시에로 분석합니다.

#### 5.1. 1.1 Server.java

`Server.java` 클래스를코드예 5-1 에 나타냅니다.

코드예 5-1 RMI 연결기의 예제 (간단한 시큐리티) 클래스 Server.java

    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 연결기 Stub를 등록합니다.

MBean 서버 `mbs`, 환경 맵 env, 및 서비스 URL `url` 는 모두 `JMXConnectorServer` 에게 건네져 안전한 JMX 연결기 서버 `cs` 가 신규에 작성됩니다.

#### 5.1. 1.2 SimpleStandardMBean.java

`SimpleStandardMBean` 클래스는,「 제 3 장 JMX 연결기」 로 사용된 것과 같은 간단한 MBean 인터페이스를 정의합니다.

#### 5.1. 1.3 SimpleStandard.java

`SimpleStandard` 클래스는,「 제 3 장 JMX 연결기」 로 사용된 것과 같은 간단한 MBean 를 정의합니다.

#### 5.1. 1.4 ClientListener.java

`ClientListener` 클래스는,「 제 3 장 JMX 연결기」 로 사용된 것과 같은 간단한 통지 청취자를 정의합니다.

#### 5.1. 1.5 Client.java

`Client.java` 클래스를코드예 5-2 에 나타냅니다.

코드예 5-2 RMI 연결기의 예제 (간단한 시큐리티) 클래스 Client.java

    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-2 에 나타내는 `Client` 클래스는, 환경 맵 `env` 에 `Server` 가 요구하는 자격 세트, 즉 `username` 나 `password` 를 건네줍니다. 이러한 자격은, 연결기 Stub의 서비스 URL 와 환경 맵이 `JMXConnectorFactory.connect()` 에게 건네질 때,`JMXConnector` 의 인스턴스 `jmxc` 에 부여됩니다. `Client` 는 `jmxc` 를 통해서,`Server` 측에서 기동된 MBean 에 접속해, MBean 의 조작을 실행합니다.

접속이 확립하면(자), 환경 맵 `env` 로 부여된 자격은 서버에 송신됩니다. 서버는 다음에,`JMXAuthenticator` 인터페이스의 `authenticate()` 메소드를 호출해, 클라이언트 자격을 파라미터로서 건네줍니다. `authenticate()` 메소드는, 클라이언트를 인증해, 액세스 제어의 확인에 사용되는 주체 세트를 포함한 피인증자를 돌려줍니다.

### 5.1. 2 간단한 시큐리티를 사용한 RMI 연결기의 예제의 실행

간단한 시큐리티를 사용한 RMI 연결기의 예제를 실행하려면 , 다음의 순서를 실행합니다.

    $ javac
          mbeans/SimpleStandard.java \
          mbeans/SimpleStandardMBean.java \
          server/Server.java \
          client/Client.java \
          client/ClientListener.java

- 로컬 호스트의 포트 9999 로 RMI 레지스트리를 기동합니다.

    $ export CLASSPATH=server ; rmiregistry 9999 &

- `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` 가 표시되어 접속에 실패합니다.

## 5.2 주체 위양

구현에 대해 접속의 클라이언트측이,「5.1 간단한 시큐리티」 로 가리킨 시큐리티 기구를 사용해, 복수의 사용자 또는 어플리케이션에 대신해 다른 조작을 실행하는 경우, 각 사용자가 조작을 실행할 때마다 안전한 접속을 확립하지 않으면 안됩니다. 연결기 클라이언트가 많은 사용자라고 대화하는 것이 예측되는 경우, 「주체 위양」을 구현해 시스템의 부하를 줄일 수가 있습니다. 주체 위양을 구현하면(자), 사용자 마다 1 개(살)의 안전한 접속이 확립되어 이 접속을 사용하면(자), 임의의 수의 사용자에 대신해 관련하는 조작을 실행할 수 있습니다. 접속 자체는 「인증되었다」사용자에 의해 설정됩니다. 다른 사용자에 대신해 동작하는 것을 허가하는 `SubjectDelegationPermission` 가 인증 사용자에게 부여되고 있는 경우, 그 사용자에 대신해, 접속을 사용한 조작을 실행할 수 있습니다.

### 5.2. 1 주체 위양을 사용한 안전한 RMI 연결기

주체 위양을 구현하는 안전한 RMI 연결기의 예는, 디렉토리 work_dir`/jmx_examples/Security/subject_delegation` 내에 있습니다.

1. work_dir`/jmx_examples``/Security/subject_delegation` 디렉토리를 엽니다.

이 디렉토리내에, 다음의 디렉토리가 있습니다.

- `/server`. 파일 `Server.java` 를 거두고 있습니다.
- `/config`. 시큐리티 설정 파일을 거두고 있습니다.

- `access.properties`
- `java.policy`
- `password.properties`

- `/mbeans`. 다음의 파일을 거두고 있습니다.

- `SimpleStandardMBean.java`
- `SimpleStandard.java`

- `/client`. 다음의 파일을 거두고 있습니다.

- `Client.java`
- `ClientListener.java`

2. 텍스트 문자 편집기로,`*. java` 와 `*. properties` 의 모든 파일을 엽니다.

이러한 파일에 대해, 이후시에로 분석합니다.

#### 5.2. 1.1 Server.java

`Server.java` 클래스를코드예 5-3 에 나타냅니다.

코드예 5-3 안전한 RMI 연결기 (주체 위양) 예제 클래스 Server.java

    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-3 는, MBean 서버 `mbs` 의 작성으로부터 시작됩니다. 환경 맵 `env` 에는,`password.properties` 라고 하는 패스워드 파일과 `access.properties` 라고 하는 액세스 파일이 포함됩니다.

- 패스워드 파일에는, 사용자명과 패스워드의 편성을 거둘 수 있어 접속을 시도하는 사용자의 인증에 사용된다
- 액세스 파일에는, 사용자명과 액세스 레벨의 편성이 포함되어 MBean 서버의 MBean 에의 액세스의 인증에 사용된다. 액세스 레벨은, 읽고 쓰기 가능한가 read 전용의 언젠가

다음에 `Server` 는 연결기 서버 `cs` 를 작성해, 전술의 RMI 연결기의 예제와 완전히 같은 방법으로 연결기 서버를 기동합니다.

#### 5.2. 1.2 java.policy

`java.policy` 파일은 `username` 에 `SubjectDelegationPermission` 를 부여해, 이 사용자가 `Client` 로 작성된 `JMXPrincipal` 의 인스턴스인, 사용자 `delegate` 대신에 조작을 실행하는 것을 허가합니다. `java.policy` 파일이 요구되는 것은,`Server` 클래스의 기동시입니다.

#### 5.2. 1.3 SimpleStandardMBean.java

`SimpleStandardMBean` 클래스는, 전출의 예제로 사용된 것과 같은 간단한 MBean 인터페이스를 정의합니다.

#### 5.2. 1.4 SimpleStandard.java

`SimpleStandard` 클래스는, 전출의 예제로 사용된 것과 같은 간단한 MBean 를 정의합니다.

#### 5.2. 1.5 ClientListener.java

`ClientListener` 클래스는, 전출의 예제로 사용된 것과 같은 간단한 통지 리스너를 정의합니다.

#### 5.2. 1.6 Client.java

`Client.java` 클래스를코드예 5-4 에 나타냅니다.

코드예 5-4 안전한 RMI 연결기 (주체 위양) 예제 클래스 Client.java

    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-4 는, 사용자명 `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 상에서 조작이 실행됩니다.

### 5.2. 2 주체 위양을 사용한 안전한 RMI 연결기의 예제의 실행

주체 위양을 사용한 안전한 RMI 연결기의 예제를 실행하려면 , 다음의 순서를 실행합니다.

    $ javac  mbeans/SimpleStandard.java \
      mbeans/SimpleStandardMBean.java \
      server/Server.java \
      client/Client.java \
      client/ClientListener.java

- 로컬 호스트의 포트 9999 로 RMI 레지스트리를 기동합니다.

`$` export CLASSPATH=server ; rmiregistry 9999 &

- `Server` 를 기동합니다.

    $ java -classpath server:mbeans \
      -Djava.security.policy=config/java.policy Server &

MBean 서버의 작성, 환경 맵의 초기화, RMI 연결기의 작성, 및 연결기의 MBean 서버에의 등록의 확인이 표시됩니다.

- `Client` 를 기동합니다.

`$` java -classpath client:server:mbeans Client

연결기 클라이언트의 작성, 주체 위양의 작성, MBean 서버에의 접속, 및 다양한 MBean 조작, 그 후의 접속의 종료의 확인이 표시됩니다.

## 5.3 상세한 시큐리티

Java Authentication and Authorization Service (JAAS)와 Java platform Standard Edition (Java SE) 시큐리티 아키텍쳐(architecture)에 의해 사용자 액세스를 관리하는 것으로, 보다 상세한 레벨의 시큐리티를 연결기에 구현할 수 있습니다. JAAS 와 Java SE 시큐리티의 기본은, 시큐리티 매니저와 정책 파일을 사용해, 사용자 마다 다른 액세스 레벨을 지정하는 것입니다. 최종적으로, 어느 사용자에게 어느 조작의 실행을 허가할까를 보다 정확하게 결정할 수가 있습니다.

이 마디의 2 개의 예제는,「5.1 간단한 시큐리티」 에 나타내는 예제와 매우 닮습니다만, 다른 점으로서 간단한 파일 베이스의 액세스 제어가, 정책 베이스의 액세스 제어로 옮겨지고 있습니다.

### 5.3. 1 상세한 시큐리티를 사용한 RMI 연결기

상세한 시큐리티를 사용한 RMI 연결기의 예는, 디렉토리 work_dir`/jmx_examples/Security/fine_grained` 내에 있습니다.

1. work_dir`/jmx_examples`/Security/fine_grained 를 엽니다.

이 디렉토리내에, 다음의 디렉토리가 있습니다.

- `/server`. 파일 `Server.java` 를 거두고 있습니다.
- `/config`. 시큐리티 설정 파일을 거두고 있습니다.

- `java.policy`
- `keystore`
- `password.properties`
- `truststore`

- `/mbeans`. 다음의 파일을 거두고 있습니다.

- `SimpleStandard.java`
- `SimpleStandardMBean.java`

- `/client`. 다음의 파일을 거두고 있습니다.

- `ClientListener.java`
- `Client.java`

2. 텍스트 문자 편집기로,`*. java` 와 `*. properties` 의 모든 파일을 엽니다.

#### 5.3. 1.1 이러한 파일에 대해, 이후의 섹션으로 분석합니다.

이 예제로 사용되는 `Server.java` 클래스는, 간단한 시큐리티를 사용한 RMI 연결기로 사용되는 클래스에 매우 닮았습니다. 다만, 상세한 시큐리티의 예제에서는, 환경 맵에 맵 되는 `access.properties` 파일이 없습니다. 그 이외는, 양클래스는 동일합니다.

#### 5.3. 1.2 java.policy

`java.policy` 파일은, 다음의 권한을 부여합니다.

- `server` 코드 베이스의 모든 권한. 이것이 있는 것으로, 연결기 서버는 연결기를 작성해, 원격 사용자-의 호출로 요구되는 조작을 실행할 수 있다.
- `mbeans` 코드 베이스에 대한 `MBeanTrustPermission`. 이것에 의해, 신뢰된 MBean 를 MBean 서버에 등록할 수 있다.
- `JMXPrincipal` 로 나타내지는 사용자,`username` 에 대한, 각종의 MBean 조작 및 MBean 서버 조작을 실행하는 권한

#### 5.3. 1.3 SimpleStandardMBean.java

`SimpleStandardMBean` 클래스는, 전출의 예제로 사용된 것과 같은 간단한 MBean 인터페이스를 정의합니다.

#### 5.3. 1.4 SimpleStandard.java

`SimpleStandard` 클래스는, 전출의 예제로 사용된 것과 같은 간단한 MBean 를 정의합니다.

#### 5.3. 1.5 ClientListener.java

`ClientListener` 클래스는, 전출의 예제로 사용된 것과 같은 간단한 통지 리스너를 정의합니다.

#### 5.3. 1.6 Client.java

`Client.java` 클래스는, 간단한 시큐리티를 사용한 RMI 연결기의 예제로 사용되는 클래스와 완전히 같습니다.

### 5.3. 2 상세한 시큐리티를 사용한 RMI 연결기의 예제의 실행

상세한 시큐리티를 사용한 RMI 연결기의 예제를 실행하려면 , 다음의 순서를 실행합니다.

    $ javac
          mbeans/SimpleStandard.java \
          mbeans/SimpleStandardMBean.java \
          server/Server.java \
          client/Client.java \
          client/ClientListener.java

3. 로컬 호스트의 포트 9999 로 RMI 레지스트리를 기동합니다.

`$` export CLASSPATH=server ; rmiregistry 9999 &

4. `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 연결기의 작성의 확인이 표시됩니다.

5. `Client` 를 기동합니다.

    $ java -classpath client:server:mbeans \
         -Djavax.net.ssl.trustStore=config/truststore \
         -Djavax.net.ssl.trustStorePassword=trustword \
         Client

연결기 클라이언트의 작성, RMI 서버에의 접속, 각종의 MBean 조작, 및 접속의 종료의 확인이 표시됩니다.

목차 | 전의 항목 | 다음의 항목 | Java Management Extensions (JMX) 테크놀러지의 튜토리얼 Java Management Extensions (JMX), Java Platform, Standard Edition 6

Copyright © 2006 Sun Microsystems, Inc. All rights reserved.