Secure Admin One Pager

(template version 1.92)

1. Introduction

The changes in secure admin for GlassFish focus on allowing users more flexibility in setting up secure admin. Specifically GlassFish will include these enhancements:

  1. The administrator can specify multiple SSL certificates (rather than only one as in 3.1) to be allowed to submit admin requests.
  2. The administrator no longer needs to import into the GlassFish truststore a certificate that has a chain to a certificate authority. (Adding such trusted certs to a truststore is considered a security risk.) Self-signed certs must still be imported into the truststore if they are to be trusted.
  3. The administrator can configure secure admin to use a username and a password alias, in addition to SSL certs. GlassFish will then use the username and password instead of SSL client certs for authenticating admin traffic among GlassFish servers.

These changes, while driven by experience and feedback from 3.1, will also support some possible new requirements from other areas of GlassFish.

Note that the changed described here are planned for GlassFish 3.1.1 as well as 3.next.

1.1. Project/Component Working Name:

Secure Admin

1.2. Name(s) and e-mail address of Document Author(s)/Supplier:

Tim Quinn: tim.quinn@oracle.com

1.3. Date of This Document:

04/25/11
05/09/11 - revised
05/31/11 - revised

2. Project Summary

2.1. Project Description:

Allowing users to keep tight control over administrative access to GlassFish, especially regarding remote administration and the authentication and authorization of admin clients using SSL certificates.

2.2. Risks and Assumptions:

Some other areas of GlassFish might impose some additional requirements on secure admin, for example possible instance-to-instance admin communication. The changes proposed in the one-pager accommodate the possible changes we know about. Others could come up as further details emerge from other teams.

3. Problem Summary

3.1. Problem Area:

GlassFish will address secure admin in several areas.

Improve cert-based admin authentication and authorization

In 3.1 and 3.1.1 secure admin and application security share the same truststore. Secure admin in 3.1 used the shared truststore for two purposes:

  1. authenticating admin connections that offer client SSL certs, to establish the client's identity, and
  2. authorizing such connections to perform admin operations, checking that the alias under which the client's cert was stored in the truststore was the same alias as configured in the secure-admin element in domain.xml as set by the enable-secure-admin command.

Using the truststore this way worked for the default secure admin configuration which uses self-signed certs for the DAS and for the instances, and it worked fairly well for other simple use cases. But even slightly more complicated scenarios were difficult or impossible to handle, for example trusting multiple certs for admin access or configuring GlassFish to accept a trusted cert for admin access. (Because the truststore was used for admin authorization, the administrator had to import the authorizing cert into the truststore. If the cert had a chain to a certificate authority this would introduce a security risk.)

GlassFish will continue to use a single truststore for cert-based authentication of admin (and other) clients, but it will handle authorization using certs differently from 3.1. The administrator will tell GlassFish the distinguished names (DNs) of each cert to be trusted as an administrator. When an admin submitter sends an SSL client cert, GlassFish will make sure the DN in that cert matches one of the ones the administrator has configured.

Users will run several new commands to manage the list of authorized DNs:

Command Result
enable-secure-admin-cert
 [  --alias alias-name |
   distinguished-name ]
GlassFish stores the DN as authorized for submitting admin operations. If the user specifies --alias then GlassFish looks up a cert in the truststore using that alias and, if found, stores the corresponding DN as a valid admin DN. If the user specifies the DN then GlassFish stores that DN.
disable-secure-admin-cert
  [  --alias alias-name |
   distinguished-name ]
GlassFish removes the specified DN as a valid admin DN. If the user specifies --alias then GlassFish looks up a cert in the truststore using that alias and, if found, removes the corresponding DN as a valid admin DN.
list-secure-admin-certs GlassFish displays the currently-enabled admin cert DNs.

Note that by choosing the verbs enable and disable rather than add and remove we emphasize that the commands do not themselves add certs to the truststore or remove them from it.

If specified for enable-secure-admin-cert or disable-secure-admin-cert the alias-name must be an alias associated with a cert currently in the truststore and so typically is useful only for self-signed certs. If the user gives the DN instead of the alias on the command then the truststore does not need to contain a cert with that DN, although it can.

For ease-of-use and for compatibility with GlassFish 3.1, users can continue to run enable-secure-admin without having to run enable-secure-admin-cert. As part of the enable-secure-admin processing if no DNs are enabled GlassFish will automatically enable for admin access the DNs associated with the two generated, self-signed certs: the one for the DAS (alias s1as) and the one for the instances (alias glassfish-instance). This preserves the existing 3.1 behavior.

Improve verification that admin requests from other servers come from servers in the same domain

In 3.1 with secure admin enabled remote instances accept admin traffic from the DAS using cert-based authentication and authorization. By default GlassFish uses the self-signed cert generated when the domain is created to authenticate the DAS to remote instances. Because each DAS has its own self-signed cert the remote instance could be confident it was receiving admin traffic from the DAS in the proper domain.

Some users have their own certs and want to use them differently. For example, if a user assigns a separate certificate to each host and runs more than one DAS on a system then all DAS processes on that host would use the same cert. Remote instances in the different domains cannot use the DAS's cert to make sure the traffic originates from the correct DAS.

GlassFish will include a unique, generated "domain ID" which servers will use to help make sure that admin requests from other GlassFish servers originate from the correct domain. (See https://github.com/javaee/glassfish/issues/16439)

Improve user control over how admin listeners identify themselves using certs

In 3.1, when enabling secure admin the user could specify --adminalias (defaulted to s1as) and --instancealias (defaulted to glassfish-instance) to specify which cert the receiver of the message would accept as a valid admin cert. That is, instances would trust incoming admin messages with the cert specified by the --adminalias value and the DAS would trust incoming messages with the cert specified by the --instancealias value.

Going forward these options will actually affect two settings in a way that is consistent with the 3.1 behavior but is more flexible. First, GlassFish will add the cert(s) specified by the options as valid admin certs (essentially running enable-secure-admin-cert for the specified alias automatically). Second, GlassFish will use the user-specified (or defaulted) alias to set the cert nickname in the Grizzly settings for that server's admin listener. Existing Grizzly logic uses that nickname in identifying the listener to incoming SSL client connections. In GlassFish 3.1 users who wanted this level of control had to use asadmin set to assign this alias in the <ssl> config element for the listener.

As in 3.1, GlassFish will continue to use this alias in choosing which cert to use in identifying itself when sending outbound admin requests to other GlassFish processes.

Support username and password alias admin authentication among servers

With secure admin enabled, GlassFish 3.1 supported only SSL cert-based authentication and authorization of the DAS to other servers in the domain. Going forward GlassFish will allow administrators to configure GlassFish to use an admin username and a password alias instead.

Users will have new commands:

Command Effect
enable-secure-admin-internal-user --passwordalias password-alias admin-username Records the specified admin username and the specified password alias which GlassFish servers should use for internally authenticating and authorizing themselves to other GlassFish components.
disable-secure-admin-internal-user admin-username Discontinues internal authentication and authorizing using the specified admin username.
list-secure-admin-internal-users Lists the usernames and password aliases currently enabled.

To enable a secure admin user the user must already have configured admin-username in the admin realm, made that username a member of the admin group, and have already set up password-alias to map to the password for the admin-username.

If the user enables both a secure admin user and one or more secure admin certs, GlassFish will use the username/password mechanisms to secure internal GlassFish-to-GlassFish admin traffic.

Once the user has set up an admin username and password alias for internal use, he or she can remove it using the disable-secure-admin-internal-user command.

Users will not normally need to enable multiple admin usernames for internal use, but GlassFish will permit it. GlassFish will prefer username-based internal authentication over SSL-based internal authentication. That is, if GlassFish finds at least one admin user enabled for secure admin then it will choose one of them for inter-server authentication. If no admin users have been enabled for secure admin internal use and secure admin itself is enabled, then GlassFish will use SSL authentication between servers. Users who enable multiple internal admin users should not assume anything about which one GlassFish might choose to use.

Note that the documentation and on-line help should make very clear that users need to run enable-secure-admin-internal-user only to have GlassFish use that user for its own internal communication. Any valid admin user can submit admin requests, whether or not the user has run enable-secure-admin-internal-user for those admin accounts. The commands are somewhat long with "internal" in them, but these commands will probably be used rarely and the names are less confusing this way.

Allow users to control remote admin and SSL inter-server traffic separately

In GlassFish 3.1 running enable-secure-admin both enables remote admin and also sets up GlassFish to use SSL cert authentication among GlassFish servers. In GlassFish 3.1.1 users will be able to control these independently thanks to two new options on the enable-secure-admin and disable-secure-admin commands.

New Option Purpose
--ssl[=true/false] Enables or disables only the inter-server SSL behavior.
--remote[=true/false] Enables or disables whether the DAS will accept remote admin requests.

If the user omits both options then both remote admin and inter-server SSL behavior are affected. If the user specifies only one of the options then only that aspect of secure admin is enabled or disabled. If the user specifies both options, then both aspects are enabled or disabled.

The intent is that users would not specify "true" or "false" but use the presence of the option to indicate they want to enable or disable that type of secure admin behavior. So

enable-secure-admin --remote

would enable remote admin without affecting SSL behavior. Similarly,

enable-secure-admin --ssl

would enable SSL admin traffic among the servers without affecting the current remote setting.

This approach allows users to be more selective about what aspect they control while also preserving the 3.1 behavior without creating incompatibilities in the semantics of enable-secure-admin between 3.1 and 3.1.1.

Justification:

These changes address RFEs that reflect user requirements and use cases as well as new situations that are likely to arise due to new features in GlassFish.

4. Technical Description:

4.1. Details:

Recording remote/SSL secure admin state

The existing <secure-admin> element below <domain> will have two new optional attributes which replace the existing "enabled" attribute:

<secure-admin remote="true/false} ssl="true/false"/>

The default values are "true" for both attributes.

Recording enabled admin certs: <admin-cert>

The existing <secure-admin> element (child of the <domain> element) will contain one <admin-cert DN="dn-value"/> child element for each enabled cert. The "key" for the element is the DN attribute. Even if the user enabled the cert using the --alias option GlassFish records only the corresponding DN, not the alias, in the configuration.

During domain creation GlassFish will continue to generate the self-signed certs as in 3.1, one for the DAS and one for all instances. As in 3.1 domain creation will add both certs to the truststore that is bootstrapped to instances when they are created and copied to them during synchronization.

Recording enabled internal admin users: <admin-internal-user

The existing <secure-admin element will contain one <admin-internal-user username="username-value" password-alias="alias-value"/> child element for each enabled internal secure admin user. The "key" for the element is the username attribute.

Internal use of the secure admin user and password alias

With secure admin enabled and with at least one secure admin internal username and password alias configured, whenever a GlassFish server sends an admin request it will add a Basic Auth. HTTP header to the admin request. The header will contain the admin user and password from one of the <admin-internal-user> elements.

Note that if the administrator configures a secure admin user and password alias, GlassFish will not also authenticate itself using an SSL client certificate.

If the user runs enable-secure-admin-internal-user the command will create a <secure-admin-internal-user if none exists and change the password-alias value if the element already exists for the specified user. When the user runs disable-secure-admin-internal-user the corresponding <secure-admin-internal-user element will be deleted.

Changes to admin authorization logic

In 3.1 GlassFish-to-GlassFish admin authorization in the instances made sure that the alias recorded in the <secure-admin adminalias="..."> attribute corresponded to a cert in the truststore matching the client cert presented with the incoming admin request.

Now GlassFish will make sure that any cert presented with the request contains a DN which appears in one of the <admin-cert> child elements of <secure-admin> instead. This removes the awkward coupling between the authorization logic and the alias used to store the cert, and it also allows multiple certs to authorize the client to perform administrative operations.

Guarding against cross-domain admin traffic using the new unique "domain ID"

Any GlassFish server which sends an admin request to another server will include its domain ID in an HTTP header. The receiving server will compare its own domain ID to the sender's and will accept the admin request only if the domain IDs match.

This is not foolproof nor is it intended to be. It is a low-cost, low-overhead way to help avoid user configuration errors that might send admin traffic from a server in one domain to a server in another domain.

Human-oriented admin clients (IDEs, browsers using the REST interface, the asadmin utility, and the admin console) might not have access to the domain ID and, if not, will not include the domain ID header in their requests. So receiving servers will not insist that incoming requests have this header. But if a request has the domain ID header, it must match the receiver's.

Handling per-host certs: Explicit setting of network-listener/ssl@cert-nickname

When the user enables secure admin, GlassFish will use the DAS alias value (user-specified via the --adminalias option on enable-secure-admin, defaulted to s1as) to set the network-listener/ssl@cert-nickname attribute, thus controlling which cert the DAS will use to identify itself when secure clients connect. Similarly GlassFish will assign the instance alias value (user-specified via the --instancealias option on enable-secure-admin, defaulted to glassfish-instance) to set this attribute for the admin network listeners for remote instances.

This gives the user easier control over how the admin listeners identify themselves to secure clients.

The goal is for GlassFish to use a token for the cert nickname attribute value in the configuration and to create a <system-property> element to assign the correct value. As part of enable-secure-admin processing GlassFish will set the property to the --adminalias value for <server-config> and to the --instancealias value for other configurations. This preserves the 3.1 behavior by default.

Users who want to use different aliases on different instances can use asadmin create-system-properties to assign a different value to the property in each of the instances' <server> elements. Such users can also specify the token instead of an actual value when using enable-secure-admin --instancealias.

Open question: Does our command syntax allow a user to specify a token name, presumably using ${token-name}, without substitution happening as the command is processed?

Revised secure admin logic

Admin authentication pseudo-code

Here is how the revised admin authentication and authorization logic will work:

AdminAdapter authentication and authorization logic
/*
 * Grizzly provides the client SSL cert Principal if SSL is on and 
 * if the client submits a cert and if the cert is trusted, either 
 * because it has a chain to a CA or it is self-signed and has been
 * added to the GlassFish truststore.  
 *
 * If the client sent a limited-use authentication token then there
 * will be an HTTP header for that (not a Basic Auth header; a 
 * GF-specific one).  
 *
 * If the client is another GlassFish process and the user has 
 * configured secure admin to use an internal admin username and 
 * password alias then there will be an HTTP Basic Auth header.
 *
 * If the client is another GlassFish process then there will be
 * an HTTP header conveying the domain ID.
 */

if (domain ID header is present) {
    if (domain ID in header != domain ID of current process) {
        reject request with 403 - Forbidden;
        return;
    }
}

if (a limited-use token is present) {
    if (token is valid) {
        consume token and grant access; // token could be extended, as in 3.1
        return;
    }
    reject request with 401 - Unauthorized;
    return;
}

if (request is remote && ! secureAdmin.getRemote()) {
    reject request with 403 - Forbidden;
    return;
}

if (a Basic Auth header is present) {
    if (password is the locally-provisioned local password) {
        grant access;
        return;
    }

    // Next "if" handles both normal client auth. as well as new internal user/pw auth

    if (username and password authenticate and authorize as a valid admin user) {
        grant access;
        return;
     }
     reject request with 401 - Unauthorized;
     return;
}

if ( ! secureAdmin.ssl()) {
     reject request with 401 - Unauthorized;
     return;
}

if (request has an SSL Principal) {
    if (req.getUserPrincipal().getName() matches the DN in 
           one of the <secure-admin><admin-cert> elements) {
        grant access;
        return;
    }
    reject request with 401 - Unauthorized;
    return;
}

Pseudo-code for submitting internal admin requests

This example does not cover the locally-provisioned password case which is unchanged from 3.1.

Send internal admin request
add HTTP header with unique domain ID;
if (secureAdmin.getSecureAdminInternalUser() is non-empty) {
    prepare HTTP Basic Auth header with the username 
      from secureAdminInternalUser.getUsername() and the
      password with alias matching secureAdminInternalUser.getPasswordAlias();
    // Request is encrypted but not authenticated using SSL
    send request;
    return;
}
if (current process is DAS) {
    connect to https authenticating using alias secureAdmin.getAdminAlias();
} else {
    connect to https authenticating using alias secureAdmin.getInstanceAlias();
}

4.2. Bug/RFE Number(s):

https://github.com/javaee/glassfish/issues/16437 Accept multiple certs for admin authentication
http://java.net/jira/browse /GLASSFISH-16438 Ensure that admin traffic from other servers is in fact from the same domain
https://github.com/javaee/glassfish/issues/16545 Allow secure admin to use username and password alias for inter-server authentication and authorization

4.3. In Scope:

Automatic configuration of the simple cases in which the DAS has one cert and all instances share a second cert.

4.4. Out of Scope:

Support in the enable-secure-admin command for configuring separate cert aliases for each instance. Users can use asadmin set to do this (with suitable documentation).

Direct admin support for adding certs to truststores. Users will continue to use keytool to do this.

Direct admin support for per-host certs. Users can define properties in the configuration and use asadmin set to refer to those properties so each instance can use a different for SSL client authentication.

4.5. Interfaces:

4.5.1 Public Interfaces

List new, public interfaces this project exports.

New enable-secure-admin options --remote and --ssl.

New enable-/disable-secure-admin-internal_user commands.

New enable-/disable-secure-admin-cert command.

In domain.xml GlassFish will use existing features of Grizzly listener configuration and property token and value substitution to control what alias the network listener uses to identify itself.

4.5.2 Private Interfaces

List private interfaces which are externally observable.
none

4.5.3 Deprecated/Removed Interfaces:

none

4.6. Doc Impact:

  1. Expansion of the existing discussion of enable-secure-admin. The internal usage of the two alias-related options is slightly different. To users the options still identify the credentials to be associated with the DAS, and the credentials to be associated with the instances, using aliases. The difference is that they will indicate how a secure admin network listeners identifies itself to incoming client connections. In 3.1 they indicated which other incoming client connections to trust. Add explanation of the new --remote and --ssl options.
  2. Add discussion of the new commands enable-/disable-secure-admin-internal-user commands.
  3. Discussion of the new enable-/disable-secure-admin-cert and list-secure-admin-certs commands.
  4. Discussion (blog?) about setting up per-host cert environments. This could be fairly rare and might not warrant treatment in the formal documentation.

4.7. Admin/Config Impact:

How will this change impact the administration of the product?

(see technical details section earlier)

4.8. HA Impact:

none

4.9. I18N/L10N Impact:

none

4.10. Packaging, Delivery & Upgrade:

4.10.1. Packaging

No impact.

4.10.2. Delivery

No impact.

4.10.3. Upgrade and Migration:

If secure admin is enabled in a 3.1 installation, then upgrade will need to:

  • Add as an admin cert the cert indicated or implied by the instancealias value.
  • Add as an admin cert the cert indicated or implied by the adminalias value.

4.11. Security Impact:

As described already

4.12. Compatibility Impact

No incompatible changes to interfaces

4.13. Dependencies:

4.13.1 Internal Dependencies

4.13.2 External Dependencies

none

4.14. Testing Impact:

Need to add admin devtests to make sure the new truststores are used correctly and that the cert-nickname values are used correctly.

5. Reference Documents:

See bug/RFE numbers section.

6. Schedule:

6.1. Projected Availability:

Indicate which milestones from the current schedule the project
will be:

  • Initially integrated (may not be feature complete): MS 4
  • Feature complete (ready for handoff to QA) MS 5
  • At production quality level: MS 5