Skip to main content

Authenticating Users


Authenticating Users

Rundeck can be configured to use several mechanisms to authenticate a user, and determine the user's authorized roles.

Primarily these are:

For the default installation (Executable War, RPM, Deb), the Servlet Container is Jetty, and the default security mechanism is JAAS, so you are free to use what ever JAAS provider you feel is suitable for your environment. See JAASopen in new window and specifically for Jetty, JAAS for Jettyopen in new window.

Single Sign On

See Security > Single Sign On.

Require Roles For Sign On

By default, when users who are not granted access to any projects try to login, they are directed to a page that says they don't have any roles at the moment. However, if you would like to require roles to even get passed the login screen, that is possible. If you require roles for sign on, then if a user without a role tries to login, they will not be able to get into the Rundeck portal. In order to require roles for sign on, add the following line to the rundeck-config.properties file:

rundeck.security.requiredRole=role1,role2,role3

Where role1, role2, role3 are the names of the groups you wish to grant access to.

Jetty and JAAS authentication

Rundeck has three basic JAAS modules.

  1. PropertyFileLoginModule
  2. LDAP
  3. PAM

By default a new installation uses the realm.properties method.

Each method determines whether the user is authenticated, and what roles they have.

The list of roles can be accepted as-is (default), or you can add a prefix to them using the following config in rundeck-config.properties:

rundeck.security.jaasRolePrefix=PREFIX_

PropertyFileLoginModule

Note

It is recommended to use BCRYPT encrypted passwords with realm.properties as it is the most secure option available. Avoid plain, MD5, and CRYPT.

  • NOTE: The org.eclipse.jetty.jaas.spi.PropertyFileLoginModule JAAS module will automatically add the username as a role to the login credentials.
    If you do not want this behavior please use the org.rundeck.jaas.jetty.ReloadablePropertyFileLoginModule module.*

These instructions explain how to manage user credentials for Rundeck using a text file containing usernames, passwords and role definitions. Usually this file is called realm.properties.

The default Rundeck installation handles user authentication via JAAS using the realm.properties file. This file is created at the time that you install the server.

Location:

  • Executable War: $RDECK_BASE/server/config/realm.properties
  • RPM/DEB: /etc/rundeck/realm.properties

Assuming it wasn't modified, your realm.properties file will probably look something like this:

#
# This file defines users passwords and roles for a HashUserRealm
#
# The format is
#  <username>: <password>[,<rolename> ...]
#
# Passwords may be clear text, obfuscated or checksummed.
#
# This sets the default user accounts for the Rundeck apps
#
admin:admin,user,admin
user:user,user

Adding additional users

You may wish to have additional users with various privileges rather than giving out role accounts to groups. You may also want to avoid having the passwords in plaintext within the configuration file.

To accomplish this, you'll need a properly hashed or encrypted password to use in the config. Rundeck has a built in command line utility to encrypt passwords. The default encryption service is the Jetty password utility.

In this example, we'll setup a new user named "jsmith", with a password of "mypass":

$ java -jar rundeck-5.2.0-20240410.war --encryptpwd Jetty
Required values are marked with: *
Username (Optional, but necessary for Crypt encoding):
jsmith    <-----Type this value
*Value To Encrypt (The text you want to encrypt):
mypass    <-----Type this value

==ENCRYPTED OUTPUT==
obfuscate: OBF:1xfd1zt11uha1ugg1zsp1xfp
md5: MD5:a029d0df84eb5549c641e04a9ef389e5
crypt: CRYPT:jsnDAc2Xk4W4o
bcrypt: BCRYPT:a029d0df84eb5549c641e04a9ef389e5

Note

Some salt revisions for BCRYPT are security concerns in our spring security, so $2a$ works but $2y$ does not.

Then add this to the realm.properties file with a line like so:

jsmith: BCRYPT:a029d0df84eb5549c641e04a9ef389e5,user,admin

Then restart Rundeck to ensure it picks up the change and you're done.

There is also a password encrypter utility user interface in the Rundeck application that can be used to generate encrypted passwords. Click the gear icon and then "Password Utility" to use that interface.

Warning

The use of CRYPT comes with limitations. Only the first 8 characters of the provided password will be validated when authenticating. This encryption scheme should be avoided if possible.

Hot Reloading the realm.properties file

If you want your changes to the realm.properties file to be picked up without having to restart Rundeck change the module specified in the JAAS config file from org.eclipse.jetty.jaas.spi.PropertyFileLoginModule to org.rundeck.jaas.jetty.ReloadablePropertyFileLoginModule

The refresh interval for checking the file is 5 seconds. This is not configurable.

For example, the following configuration uses the non-reloadable realm.properties

RDpropertyfilelogin {
    org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
    debug="true"
    file="/etc/rundeck/server/config/realm.properties";
};

This configuration would enable hot reloading:

RDpropertyfilelogin {
    org.rundeck.jaas.jetty.ReloadablePropertyFileLoginModule required
    debug="true"
    file="/etc/rundeck/server/config/realm.properties";
};

LDAP

LDAP and Active Directory configurations are created in the same way, but your LDAP structure may be different than Active Directory's structure.

Rundeck includes two JAAS login modules you can use for LDAP directory authentication:

These are an enhanced version of the default Jetty JAAS Ldap login module that caches authorization results for a period of time.

JAAS supports evaluating MD5, BCRYPT and CRYPT password hashes.

You must change some configuration values to change the authentication module to use.

Configuration

Configuring LDAP consists of defining a JAAS config file (e.g. "jaas-ldap.conf"), and changing the server startup script to use this file and use the correct Login Module configuration inside it.

Note

The jaas-ldap.conf file cannot have comments. Adding a # character will break parsing in JAAS.

Sync Rundeck profile from LDAP user attributes

You can use LDAP user attributes to update the email, first name, and last name properties of your Rundeck users. To enable this feature, add the property: rundeck.security.syncLdapUser=true to your rundeck-config.properties file.

In your JAAS LDAP login module you can specify the ldap user attributes used to source the email, and name properties. The properties are:

userLastNameAttribute="sn"
userFirstNameAttribute="givenName"
userEmailAttribute="mail"

These LDAP attributes will be checked when a user logs in, and their Rundeck user profile will be updated from them.

Note: By default, all users can log into Rundeck. However, if they do not have the proper authorization, they will not be able to access any projects. If you want to prevent them from even being able to login to rundeck, you can include the following JVM parameter: rundeck.security.requiredRole=Your_Role_Name

Step 1: Setup the LDAP login module configuration file

Create a jaas-ldap.conf file in the same directory as the jaas-loginmodule.conf file.

  • RPM/Deb install: /etc/rundeck/
  • Executable War install: $RDECK_BASE/server/config

Make sure the name of your Login Module configuration is the same as you use in the next step. The Login Module configuration is defined like this (e.g. "jaas-ldap.conf" file):

    ldap {
        // comment line
        ...
    }

Where "ldap" is the module name.

Step 2: Specify login module

To override the default JAAS configuration file, you will need to supply the Rundeck server with the proper path to the new one, and a loginmodule.name Java system property to identify the new login module by name.

The JAAS configuration file location is specified differently between the Executable War and the RPM/Deb.

For the Executable War: the loginmodule.conf.name Java system property is used to identify the name of the config file, which must be located in the $RDECK_BASE/server/config dir.

You can simply specify the system properties on the java commandline:

java -Drundeck.jaaslogin=true \
     -Dloginmodule.name=ldap \
     -Dloginmodule.conf.name=jaas-ldap.conf \
     -jar rundeck-5.2.0-20240410.war

Otherwise, if you are starting the Executable War via the supplied rundeckd script, you can modify the RDECK_JVM value in the $RDECK_BASE/etc/profile file to add two JVM arguments:

export RDECK_JVM="-Drundeck.jaaslogin=true \
    -Dloginmodule.name=ldap \
    -Dloginmodule.conf.name=jaas-ldap.conf"

Note: more information about using the Executable War and useful properties are under Getting Started - Executable War Options.

For the RPM/DEB installation:

Declare variables (as the ones from /etc/rundeck/profile) in /etc/sysconfig/rundeckd (rpm) or /etc/default/rundeckd (deb):

Example:

$ cat /etc/sysconfig/rundeckd
JAAS_LOGIN=true
LOGIN_MODULE=ldap
JAAS_CONF=/etc/rundeck/jaas-ldap.conf

Step 3: Restart rundeckd

RPM/DEB

service rundeckd restart

Step 4: Attempt to logon

If everything was configured correctly, you will be able to access Rundeck using your AD credentials. If something did not go smoothly, look at /var/log/rundeck/service.log for stack traces that may indicate what is wrong. To make troubleshooting easier, you may want to add the -Dcom.dtolabs.rundeck.jetty.jaas.LEVEL=DEBUG Java system property to the RDECK_JVM environment variable above, or as RDECK_JVM_OPTS="$RDECK_JVM_OPTS -Dcom.dtolabs.rundeck.jetty.jaas.LEVEL=DEBUG" in /etc/sysconfig/rundeckd for RPM or /etc/default/rundeck for DEB to have enable DEBUG logging for the authentication module.

Login module configuration

Here is an example configuration file for the JettyCachingLdapLoginModule:

ldap {
    com.dtolabs.rundeck.jetty.jaas.JettyCachingLdapLoginModule required
      debug="true"
      contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
      providerUrl="ldap://server:389"
      bindDn="cn=Manager,dc=example,dc=com"
      bindPassword="secret"
      authenticationMethod="simple"
      forceBindingLogin="false"
      userBaseDn="ou=People,dc=test1,dc=example,dc=com"
      userRdnAttribute="uid"
      userIdAttribute="uid"
      userPasswordAttribute="userPassword"
      userObjectClass="account"
      userLastNameAttribute="sn"
      userFirstNameAttribute="givenName"
      userEmailAttribute="mail"
      roleBaseDn="ou=Groups,dc=test1,dc=example,dc=com"
      roleNameAttribute="cn"
      roleUsernameMemberAttribute="memberUid"
      roleMemberAttribute="memberUid"
      roleObjectClass="posixGroup"
      cacheDurationMillis="300000"
      reportStatistics="true"
      timeoutRead="10000"
      timeoutConnect="20000"
      nestedGroups="false";
};

The JettyCachingLdapLoginModule has these configuration properties:

debug
"true/false" - turn on or off debug output
contextFactory
The LDAP context factory class, e.g. "com.sun.jndi.ldap.LdapCtxFactory"
providerUrl
ldap URL for the server, e.g. "ldap://server:389"
bindDn
Optional. If not using "binding" authentication, set this to the root DN that should bind, e.g. "cn=Manager,dc=example,dc=com"
bindPassword
password for root DN. Note: The bindDn and bindPassword must escape any special characters with \ character. Special characters include \ (backslash), as well as ! (exclamation).
authenticationMethod
Authentication method, e.g. "simple"
forceBindingLogin
"true/false" - if true, bind as the user that is authenticating, otherwise bind as the manager and perform a search to verify user password. NOTE: This module can only verify passwords hashed with MD5 or CRYPT. If your LDAP directory contains other hashes you'll likely need to set this to true to be able to authenticate.
forceBindingLoginUseRootContextForRoles
"true/false" - if true and forceBindingLogin is true, then role membership searches will be performed in the root context, rather than in the bound user context.
userBaseDn
base DN to search for users, example: "ou=People,dc=test1,dc=example,dc=com"
userRdnAttribute
Attribute name for username, used when searching for user role membership by DN, default "uid".
userIdAttribute
Attribute name to identify user by username, default "cn".
userPasswordAttribute
Attribute name for user password, default "userPassword".
userObjectClass
Attribute name for user object class, default "inetOrgPerson".
userLastNameAttribute
Attribute name for user's last name, default "sn".
userFirstNameAttribute
Attribute name for user's first name, default "givenName".
userEmailAttribute
Attribute name for user's email address, default "mail".
roleBaseDn
Base DN for role membership search, e.g. "ou=Groups,dc=test1,dc=example,dc=com".
roleNameAttribute
Attribute name for role name, default "roleName".
roleMemberAttribute
Attribute name for a role that would contain a user's DN, default "uniqueMember".
roleUsernameMemberAttribute
Attribute name for a role that would contain a user's username. If set, this overrides the roleMemberAttribute behavior.
roleObjectClass
Object class for role, default "groupOfUniqueNames".
rolePrefix
Prefix string to remove from role names before returning to the application, e.g. "rundeck_".
cacheDurationMillis
Duration that authorization should be cached, in milliseconds. Default "0". A value of "0" indicates no caching should be used.
reportStatistics
"true/false" - if true, output cache statistics to the log.
supplementalRoles
Comma-separated list of role names. All of the given role names will be automatically added to authenticated users. You can use this to provide a "default" role or roles for all users.
timeoutRead
Read timeout value (ms). Default: 0 (no timeout)
timeoutConnect
Connect timeout value (ms). Default: 0 (no timeout)
nestedGroups
"true/false" - Default: false. If true, will resolve all nested groups for authenticated users. For the first user to login after a fresh start it will take a couple of seconds longer, this is when the cache of all nested groups is built. This will happen as often as the cache is refreshed. Uses the cacheDurationMillis for cache timeout. The groups recognized as nested will depend on the roleBaseDn, any other role outside of this will not be taken.
allGroups
"true/false" - Default: true. If true, will resolve all nested groups, although you have more than 1000 nested groups, regardless of SizeLimit Exceeded Error.

The JettyCombinedLdapLoginModule is extends the previous module, so is configured in almost exactly the same way, but adds these additional configuration options:

ldap {
    com.dtolabs.rundeck.jetty.jaas.JettyCombinedLdapLoginModule required
      ...
      ignoreRoles="true"
      storePass="true"
      clearPass="true"
      useFirstPass="false"
      tryFirstPass="false";
};
ignoreRoles
Do not look up role membership via LDAP. May be used with storePass and combined with another login module for authorization roles. (See JettyRolePropertyFileLoginModule)
storePass
Store the user/password for use by subsequent login module.
clearPass
Clear the user/password that was stored after login is successful. (This would prevent any subsequent login modules from re-using the stored credentials. Set it to false if you want to continue using the credentials.)
useFirstPass
Use the stored user/password for authentication, and do not attempt to use other mechanism (e.g. login callback).
tryFirstPass
Try to use the stored user/password for authentication, if it fails then proceed with normal mechanism.

Combining LDAP with other modules

Use the JettyCombinedLdapLoginModule to do LDAP authentication, then combine it with the JettyRolePropertyFileLoginModule (or some other module) to supply the authorization roles.

The first module should set storePass="true", and the second module should set useFirstPass="true" or tryFirstPass="true".

Finally, see the section Multiple Authentication Modules about the appropriate configuration Flag to use.

The PAM section is a useful comparison as it uses the same method to combine modules.

Active Directory

Here is an example configuration for Active Directory. The string sAMAccountName refers to the short user name and is valid in a default Active Directory installation, but may vary in some environments.

activedirectory {
    com.dtolabs.rundeck.jetty.jaas.JettyCachingLdapLoginModule required
    debug="true"
    contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
    providerUrl="ldap://localhost:389"
    bindDn="cn=Manager,dc=rundeck,dc=com"
    bindPassword="secret"
    authenticationMethod="simple"
    forceBindingLogin="true"
    userBaseDn="ou=users,dc=rundeck,dc=com"
    userRdnAttribute="sAMAccountName"
    userIdAttribute="sAMAccountName"
    userPasswordAttribute="unicodePwd"
    userObjectClass="user"
    roleBaseDn="ou=roles,dc=rundeck,dc=com"
    roleNameAttribute="cn"
    roleMemberAttribute="member"
    roleObjectClass="group"
    cacheDurationMillis="300000"
    reportStatistics="true";
};

Communicating over secure ldap (ldaps://)

The default port for communicating with active directory is 389, which is insecure. The secure port is 636, but the LoginModule describe above requires that the AD certificate or organizations CA certificate be placed in a truststore. The truststore provided with rundeck /etc/rundeck/ssl/truststore is used for the local communication between the cli tools and the rundeck server.

Before you can establish trust, you need to get the CA certificate. Typically, this would require a request to the organization's security officer to have them send you the certificate. It's also often found publicly if your organization does secure transactions.

Another option is to interrogate the secure ldap endpoint with openssl. The example below shows a connection to paypal.com on port 443. The first certificate is the machine and that last is the CA. Pick the last certificate.

note that for Active Directory, the host would be the Active Directory server and port 636. note Certificates are PEM encoded and start with -----BEGIN CERTIFICATE----- end with -----END CERTIFICATE----- inclusive.

$ openssl s_client -showcerts -connect paypal.com:443
CONNECTED(00000003)
depth=1 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = Terms of use at https://www.verisign.com/rpa (c)09, CN = VeriSign Class 3 Secure Server CA - G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=Information Systems/CN=paypal.com
   i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server CA - G2
-----BEGIN CERTIFICATE-----
MIIFDjCCA/agAwIBAgIQL0NdM6l74HplIwrcygDcCTANBgkqhkiG9w0BAQUFADCB
tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwOTEvMC0GA1UEAxMm
VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzIwHhcNMTAwNTAz
MDAwMDAwWhcNMTIwNjExMjM1OTU5WjB/MQswCQYDVQQGEwJVUzETMBEGA1UECBMK
Q2FsaWZvcm5pYTERMA8GA1UEBxQIU2FuIEpvc2UxFTATBgNVBAoUDFBheVBhbCwg
SW5jLjEcMBoGA1UECxQTSW5mb3JtYXRpb24gU3lzdGVtczETMBEGA1UEAxQKcGF5
cGFsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArlvu+86iVb4RXdX+
8MjmGynNSl+Hu2/ZJ7nU1sj5O2jASWwFH7PFUv10qlRtL+gi3Rjw+zFN958iUetz
ef4CxQYf52PA7Uj9YlFEzLz7f8UDotu4WNLM3QGbLrqS28pPb2qKyyOQDvwNpI1c
Jt4JDa0ofVnCdICZEnf+cJB121MCAwEAAaOCAdEwggHNMAkGA1UdEwQCMAAwCwYD
VR0PBAQDAgWgMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9TVlJTZWN1cmUtRzIt
Y3JsLnZlcmlzaWduLmNvbS9TVlJTZWN1cmVHMi5jcmwwRAYDVR0gBD0wOzA5Bgtg
hkgBhvhFAQcXAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5j
b20vcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAfBgNVHSMEGDAW
gBSl7wsRzsBBA6NKZZBIshzgVy19RzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUH
MAGGGGh0dHA6Ly9vY3NwLnZlcmlzaWduLmNvbTBABggrBgEFBQcwAoY0aHR0cDov
L1NWUlNlY3VyZS1HMi1haWEudmVyaXNpZ24uY29tL1NWUlNlY3VyZUcyLmNlcjBu
BggrBgEFBQcBDARiMGChXqBcMFowWDBWFglpbWFnZS9naWYwITAfMAcGBSsOAwIa
BBRLa7kolgYMu9BSOJsprEsHiyEFGDAmFiRodHRwOi8vbG9nby52ZXJpc2lnbi5j
b20vdnNsb2dvMS5naWYwDQYJKoZIhvcNAQEFBQADggEBADbOGDkzZy22y+fW4OR7
wkx+1E3BxnRMZYx89OOykzTEUt2UV5DVuccUbqxTxg9/4pKMYJLywYn9UIOPHpwx
fbvMQNpdqV3JSuGMTwpROrMvC3bT13aCxxDnozeCjd/lH74m6G5ef2EUd3m5Y+iC
fMPo2NMrVyQYOCtpJurh9Tre1gQFHUYAXw8ty0YxfMoR/7FwYbd4spiZJwL2Mvfn
9gn24dWuKY7JaFutomwOM78rGzBDZZ/spEx9rcNa3OuVHcqBamnnXQZlZJilj4LE
buMBx8ti5Oqy4z1u1vzA8HalseiZerqFtBGOIakXdto8qLnwYEHQvVa/ih5iTsi3
Ja8=
-----END CERTIFICATE-----
 1 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server CA - G2
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
-----BEGIN CERTIFICATE-----
MIIGLDCCBZWgAwIBAgIQbk/6s8XmacTRZ8mSq+hYxDANBgkqhkiG9w0BAQUFADCB
wTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQL
EzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1
dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmswHhcNMDkwMzI1MDAwMDAwWhcNMTkwMzI0MjM1OTU5WjCBtTELMAkGA1UEBhMC
VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
cnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93
d3cudmVyaXNpZ24uY29tL3JwYSAoYykwOTEvMC0GA1UEAxMmVmVyaVNpZ24gQ2xh
c3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDUVo9XOzcopkBj0pXVBXTatRlqltZxVy/iwDSMoJWzjOE3JPMu
7UNFBY6J1/raSrX4Po1Ox/lJUEU3QJ90qqBRVWHxYISJpZ6AjS+wIapFgsTPtBR/
RxUgKIKwaBLArlwH1/ZZzMtiVlxNSf8miKtUUTovStoOmOKJcrn892g8xB85essX
gfMMrQ/cYWIbEAsEHikYcV5iy0PevjG6cQIZTiapUdqMZGkD3pz9ff17Ybz8hHyI
XLTDe+1fK0YS8f0AAZqLW+mjBS6PLlve8xt4+GaRCMBeztWwNsrUqHugffkwer/4
3RlRKyC6/qfPoU6wZ/WAqiuDLtKOVImOHikLAgMBAAGjggKpMIICpTA0BggrBgEF
BQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlzaWduLmNvbTAS
BgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4RQEHFwMwVjAo
BggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2NwczAqBggrBgEF
BQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQGA1UdHwQtMCsw
KaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzIuY3JsMA4GA1Ud
DwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglpbWFnZS9naWYw
ITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNodHRwOi8vbG9n
by52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjApBgNVHREEIjAgpB4wHDEaMBgGA1UE
AxMRQ2xhc3MzQ0EyMDQ4LTEtNTIwHQYDVR0OBBYEFKXvCxHOwEEDo0plkEiyHOBX
LX1HMIHnBgNVHSMEgd8wgdyhgcekgcQwgcExCzAJBgNVBAYTAlVTMRcwFQYDVQQK
Ew5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5
OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD
VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrghB92f4Hz6getxB5Z/uniTTGMA0G
CSqGSIb3DQEBBQUAA4GBAGN0Lz1Tqi+X7CYRZhr+8d5BJxnSf9jBHPniOFY6H5Cu
OcUgdav4bC1nHynCIdcUiGNLsJsnY5H48KMBJLb7j+M9AgtvVP7UzNvWhb98lR5e
YhHB2QmcQrmy1KotmDojYMyimvFu6M+O0Ro8XhnF15s1sAIjJOUFuNWI4+D6ufRf
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=Information Systems/CN=paypal.com
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server CA - G2
---
No client certificate CA names sent
---
SSL handshake has read 3039 bytes and written 401 bytes
---
New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
Server public key is 1024 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DES-CBC3-SHA
    Session-ID: A8AAA4F22E9A4B3F12F76303464643525178846D96CA0BC0B81F35368BF55B89
    Session-ID-ctx:
    Master-Key: 9F767B91FC2450E291CBB21E3438CA9A73FE8D5B825AD98F821F5EB912C088DFB66FCBF2D53591E2D1ED77E9B6A22504
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1295242116
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---
^C

Once a certificate has been obtained. There are two options for adding the certificate. The first involves updating the truststore for the JRE. If that is not possible or not desirable, then one can set the truststore to be used by the jvm, using any arbitrary truststore that contains the appropriate certificate.

Both options require importing a certificate. The following would import a certificate called, AD.cert into the /etc/rundeck/ssl/truststore.

keytool -import -alias CompanyAD -file AD.cert -keystore  /etc/rundeck/ssl/truststore -storepass adminadmin

To add the certificate to the JRE, locate the file $JAVA_HOME/lib/security/cacerts and run

keytool -import -alias CompanyAD -file AD.cert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit

To verify your CA has been added, run keytool list and look for CompanyAD in the output.

keytool -list -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit

Refer to: https://docs.oracle.com/javase/1.5.0/docs/tooldocs/solaris/keytool.html for more information how how to import a certificate.

Finally, in your ldap-activedirectory.conf be sure to change the providerUrl to be ldaps://ad-server. Including the port is optional as the default is 686.

Communicating over secure ldap using Windows(ldaps://)

  1. Download certificate from remote site
c:\>  openssl s_client -connect ldaps_server.example:636 > C:\rundeck\certs.out
  1. Import the file to keystore in Java home .
c:\> keytool -importcert -file "C:\rundeck\certs.out" -storepass changeit -keystore "C:\Program Files\Java\jre1.8.0_xxx\lib\security\cacerts" -alias host_ext
  1. Import in rundeck (Optional if using Rundeck with SSL)
c:\> keytool -importcert -file "C:\rundeck\certs.out" -storepass adminadmin -keystore "C:\rundeck\etc\truststore" -alias ldapsserver

PAM

Rundeck includes a PAMopen in new window JAAS login module, which uses libpam4jopen in new window to authenticate.

In order for Rundeck to have the necessary permissions to check user credentials, the user that runs the Rundeck process must be in the shadow group. This can be done with the command:

$ sudo addgroup rundeck shadow

On Debian based systems you need to install libpam4j :

apt install libpam4j-java

This module can work with existing properties-file based authorization roles by enabling shared credentials between the modules, and introducing a Property file module that can be used only for authorization.

Modules:

  • org.rundeck.jaas.jetty.JettyPamLoginModule authenticates via PAM, can add a default set of roles to authenticated users, and can use local unix group membership for role info.
  • org.rundeck.jaas.jetty.JettyAuthPropertyFileLoginModule authenticates via property file, but does not supply user authorization information.
  • org.rundeck.jaas.jetty.JettyRolePropertyFileLoginModule does not authenticate and only uses authorization roles from a property file. Can be combined with previous modules.

sample jaas config:

RDpropertyfilelogin {
  org.rundeck.jaas.jetty.JettyPamLoginModule requisite
        debug="true"
        service="sshd"
        supplementalRoles="readonly"
        storePass="true";

    org.rundeck.jaas.jetty.JettyRolePropertyFileLoginModule required
        debug="true"
        useFirstPass="true"
        file="/etc/rundeck/realm.properties";

};

When combining the two login modules, note that the storePass and useFirstPass are set to true, allowing the two modules to share the user information necessary for the second module to load the user roles.

Common configuration properties:

These JAAS configuration properties are used by all of the Jetty PAM modules:

  • useFirstPass
  • tryFirstPass
  • storePass
  • clearPass
  • debug

JettyPamLoginModule

Configuration properties:

  • serviceName - name of the PAM service configuration to use. (Required). Example: "sshd".
  • useUnixGroups - true/false. If true, the unix Groups defined for the user will be included as authorization roles. Default: false.
  • supplementalRoles - a comma-separated list of additional user roles to add to any authenticated user. Example: 'user,readonly'

JettyRolePropertyFileLoginModule

This module does not authenticate, and requires that useFirstPass or tryFirstPass is set to true, and that a previous module has storePass set to true.

It then looks the username up in the Properties file, and applies any roles for the matching user, if found.

Configuration properties:

  • hotReload - hotReload="true" enables the ability to modify the user list specified by file without having to restart Rundeck. The refresh interval for checking the file is 5 seconds. This is not configurable.
  • file - path to a Java Property formatted file in the format defined under realm.properties
  • caseInsensitive - true/false. If true, usernames are converted to lowercase before being looked up in the property file, otherwise they are compared as entered. Default: true.

Note that since the user password is not used for authentication, you can have a dummy value in the password field of the file, but some value is required in that position.

Example properties file with dummy passwords and roles:

admin: -,user,admin
user1: -,user,readonly

JettyAuthPropertyFileLoginModule

This module provides authentication in the same way as the realm.properties mechanism, but does not use any of the role names found in the file. It can be combined with JettyRolePropertyFileLoginModule by using storePass=true.

Configuration properties:

  • hotReload - hotReload="true" enables the ability to modify the user list specified by file without having to restart Rundeck. The refresh interval for checking the file is 5 seconds. This is not configurable.
  • file - path to a Java Property formatted file in the format defined under realm.properties

Multiple Authentication Modules

JAAS configurations can contain multiple LoginModule definitions, which are processed in order and according to the logic of the configuration Flag.

In your config file, separate the LoginModule definitions with a ; and be sure to select the appropriate Flag for the module, one of required, requisite, sufficient, or optional.

The full syntax and the description of how these Flags work is described in more detail under the JAAS Configuration Documentationopen in new window.

Here is an example combining an LDAP module flagged as sufficient, and a flat file realm.properties config flagged as required:

multiauth {

  com.dtolabs.rundeck.jetty.jaas.JettyCachingLdapLoginModule sufficient
    debug="true"
    contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
    providerUrl="ldap://server:389"
    bindDn="cn=Manager,dc=example,dc=com"
    bindPassword="secret"
    authenticationMethod="simple"
    forceBindingLogin="false"
    userBaseDn="ou=People,dc=test1,dc=example,dc=com"
    userRdnAttribute="uid"
    userIdAttribute="uid"
    userPasswordAttribute="userPassword"
    userObjectClass="account"
    roleBaseDn="ou=Groups,dc=test1,dc=example,dc=com"
    roleNameAttribute="cn"
    roleUsernameMemberAttribute="memberUid"
    roleMemberAttribute="memberUid"
    roleObjectClass="posixGroup"
    cacheDurationMillis="300000"
    reportStatistics="true";

  org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
    debug="true"
    file="/etc/rundeck/realm.properties";
};

Based on the flags, JAAS would attempt the following for authentication:

  1. Check username/pass against LDAP
  2. If auth succeeds, finish with successful authentication
  3. If auth fails, continue to the next module
  4. Check username/pass against the properties file
  5. If auth succeeds, finish with successful authentication
  6. If auth fails, finish with failed authentication

Jaas Authorization Testing

If you would like to test your Jaas configuration without restarting Rundeck every time you make a change to your Jaas configuration, you can add the --testauth option:

ldap example:

$ java -Drundeck.jaaslogin=true -Dloginmodule.conf.name=jaas-ldap.conf -Dloginmodule.name=ldap -jar rundeck-5.2.0-20240410.war --testauth
Checking file: $RDECK_BASE/server/config/jaas-ldap.conf
Checking login module: ldap
Enter user name: ldapuser
Enter password ldapuserPASSWORD <-- This is masked in actual use
Login Succeeded!

The Jaas configuration file you are testing against will be printed out, along with the name of the login module you are testing. You will be prompted to enter a username and password. These will be compared against your current Jaas configuration. If the login is successful you will see: Login Succeeded! If the login fails a stacktrace will be printed out which will contain the details about the failure.

Note: The authentication test will fail if the bind password is set at the rundeck-config.properties file. In order to work, the --testauth flag requires the bind password set at the JAAS file.

Container authentication and authorization

Container Authentication provides the Servlet context used by Rundeck with a few mechanisms to determine what roles the user has.

containerPrincipal
JAAS authentication modules define a "Principal" that represents the authenticated user, and which can list the "roles" the user has.
container
The Container also provides a query mechanism isUserInRole.

Both of these methods are used by default, although they can be disabled with the following configuration flags in rundeck-config.properties:

rundeck.security.authorization.containerPrincipal.enabled=false
rundeck.security.authorization.container.enabled=false

Preauthenticated Mode

Preauthenticated Mode using headers

If you have a proxy sitting in front of your Rundeck installation that authenticates your users, you can send the authenticated user and groups to Rundeck via HTTP headers. Set the following properties in your rundeck-config.properties file.

rundeck.security.authorization.preauthenticated.enabled=true
rundeck.security.authorization.preauthenticated.attributeName=REMOTE_USER_GROUPS
rundeck.security.authorization.preauthenticated.delimiter=,
rundeck.security.authorization.preauthenticated.userNameHeader=X-Forwarded-Uuid
rundeck.security.authorization.preauthenticated.userRolesHeader=X-Forwarded-Roles

#sync user info headers
rundeck.security.authorization.preauthenticated.userSyncEnabled=true
#these are the default headers for passing user details
rundeck.security.authorization.preauthenticated.userFirstNameHeader=X-Forwarded-User-FirstName
rundeck.security.authorization.preauthenticated.userLastNameHeader=X-Forwarded-User-LastName
rundeck.security.authorization.preauthenticated.userEmailHeader=X-Forwarded-User-Email

The attributeName property is the name of the request attribute which stores the user groups for the request. The forwarded headers will be put into this attribute. This attribute must be set for this method to work properly.

The userNameHeader property is the name of the header from which to obtain the authenticated user name.

The userRolesHeader property is the name of the header from which to obtain the list of user roles. The roles should be delimited by the delimiter specified in the delimiter property.

The userSyncEnabled property will enable the use of preauthentication headers to pass the user's first and last name and email The default headers that will be read for the user details are:

X-Forwarded-User-FirstName
X-Forwarded-User-LastName
X-Forwarded-User-Email

To customize the headers used set the following properties

rundeck.security.authorization.preauthenticated.userFirstNameHeader=X-Forwarded-User-FirstName
rundeck.security.authorization.preauthenticated.userLastNameHeader=X-Forwarded-User-LastName
rundeck.security.authorization.preauthenticated.userEmailHeader=X-Forwarded-User-Email

Preauthenticated mode logout redirection

If you are running preauthenticated mode and wish to redirect to a custom logout url on user logout, set the following properties:

# Redirect to upstream logout url
rundeck.security.authorization.preauthenticated.redirectLogout=true
rundeck.security.authorization.preauthenticated.redirectUrl=/customlogouturl