November 29, 2019

How to Install IDM Master and Replica on RHEL 7

Minimum Hardware

4 GB RAM

https://bugzilla.redhat.com/show_bug.cgi?id=1436295

Prerequisite

I have created two virtual machine, since this is a development setup I will hardcode hostname and IP in /etc/hosts and manually set hostnames.

  • rhel7.7-idm-master.magnuskkarlsson.local
    • 192.168.122.113
  • rhel7.7-idm-replica1.magnuskkarlsson.local
    • 192.168.122.99

# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 7.7 (Maipo)

# systemctl stop firewalld; systemctl disable firewalld

# hostnamectl set-hostname rhel7.7-idm-master.magnuskkarlsson.local
# hostnamectl set-hostname rhel7.7-idm-replica1.magnuskkarlsson.local

# echo "192.168.122.113 rhel7.7-idm-master.magnuskkarlsson.local" >> /etc/hosts
# echo "192.168.122.99 rhel7.7-idm-replica1.magnuskkarlsson.local" >> /etc/hosts

Update Date & Time

Make sure NTP is setup and synchronized.


systemctl restart chronyd
chronyc sources
chronyc tracking
timedatectl

Installation of IDM Master (version 4.6.5)

Install IDM Master on rhel7.7-idm-master.magnuskkarlsson.local.


# yum install -y ipa-server

# ipa-server-install --domain magnuskkarlsson.local \
    --realm MAGNUSKKARLSSON.LOCAL \
    -p foo123123 -a foo123123 -U 

Installation of IDM Replica (version 4.6.5)

Install IDM Replica on rhel7.7-idm-replica1.magnuskkarlsson.local.

First install idm/ipa client and register host in idm. Then setup host as replica.


# yum install -y ipa-server

# ipa-client-install --server=rhel7.7-idm-master.magnuskkarlsson.local \
    --domain=magnuskkarlsson.local \
    --principal=admin \
    --password=foo123123 -U

# ipa-replica-install --setup-ca --principal=admin --admin-password=foo123123 -U

Test

First kerberos login on master - rhel7.7-idm-master.magnuskkarlsson.local and add a user.


# kinit admin

# ipa user-add --first="Magnus K" \
    --last=Karlsson \
    --cn="Magnus K Karlsson" \
    --principal=magnuskkarlsson \
    --password \
    --all magnuskkarlsson

# ipa user-find magnuskkarlsson

Then kerberos login on replica - rhel7.7-idm-replica1.magnuskkarlsson.local and search for user and check that user is replicated.


# kinit admin

# ipa user-find magnuskkarlsson

November 8, 2019

Eclipse Microprofile LDAP Health Check with Java EE 8 and JBoss EAP 7.2

Introduction

In my previous blog I wrote about Eclipse Microprofile Health with Java EE 8 and JBoss EAP 7.2 and pointed to several Health Checks built in Spring, but for LDAP Springs Health Check is not very good. A better implementation is suggested below. And also based on standard Eclipse Microprofile Health.

Eclipse Microprofile LDAP Health Check


package se.magnuskkarlsson.example.microprofile;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;

@Health
@ApplicationScoped
public class LDAPHealthCheck implements HealthCheck {

    private final Logger log = Logger.getLogger(LDAPHealthCheck.class.getName());

    @Inject
    @ConfigProperty(name = "ldapHealthCheck.providerURL")
    protected String providerURL;

    @Inject
    @ConfigProperty(name = "ldapHealthCheck.securityPrincipal")
    protected String securityPrincipal;

    @Inject
    @ConfigProperty(name = "ldapHealthCheck.securityCredentials")
    protected String securityCredentials;

    @Inject
    @ConfigProperty(name = "ldapHealthCheck.baseCtxDN")
    protected String baseCtxDN;

    @PostConstruct
    public void init() {
    }

    @Override
    public HealthCheckResponse call() {
        List<String> result = null;
        try {
            result = searchBaseContextDN();
        } catch (Exception e) {
            log.log(Level.SEVERE, "Failed to perform LDAP health check search baseCtxDN='" + baseCtxDN + "'.", e);
        }
        boolean state = (result != null && !result.isEmpty()) ? true : false;
        String data = (result != null && !result.isEmpty()) ? result.toString() : null;
        return HealthCheckResponse.named("ldap-health-check").withData(baseCtxDN, data).state(state).build();
    }

    protected List<String> searchBaseContextDN() throws NamingException {
        InitialLdapContext ctx = null;
        try {
            Properties env = new Properties();
            env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.setProperty(Context.PROVIDER_URL, providerURL);
            env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
            env.setProperty(Context.SECURITY_PRINCIPAL, securityPrincipal);
            env.put(Context.SECURITY_CREDENTIALS, securityCredentials);

            log.info("Logging into LDAP server, env=" + env);
            ctx = new InitialLdapContext(env, null);
            log.info("Logged into LDAP server, " + ctx);

            // filter
            String filter = "(objectClass=*)";

            // scope
            SearchControls ctls = new SearchControls();
            ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);

            // search for objects using filter and scope
            NamingEnumeration<SearchResult> answer = ctx.search(baseCtxDN, filter, ctls);
            List<String> result = new ArrayList<String>();
            while (answer.hasMore()) {
                SearchResult searchResult = answer.next();
                if (searchResult != null) {
                    result.add(searchResult.toString());
                }
            }

            log.info("Result base context dn, " + result);
            return result;
        } finally {
            if (ctx != null) {
                try {
                    // Close the context when we're done
                    ctx.close();
                } catch (NamingException IGNORE) {
                }
            }
        }
    }

}

Test

http://127.0.0.1:9990/health


[standalone@localhost:9990 /] /subsystem=microprofile-health-smallrye:check