CentOS 7.x Deploy Apereo CAS 5.3 and integrate with AD
Home > CentOS > CentOS 7.x > Web Based Tools > CentOS 7.x Apereo CAS > CentOS 7.x Deploy Apereo CAS 5.3 and integrate with AD
Install required packages
Install required packages for deploying CAS 5.3 using:
yum group mark install "Development Tools" yum group mark convert "Development Tools" yum install @"Development Tools" yum -y install perl-Module-Load-Conditional yum -y install perl-Test-Simple git config --global user.name "Saurabh Barjatiya" git config --global user.email "saurabh@example.com" git config --global core.editor "vim" yum -y install epel-release yum -y install haveged systemctl enable haveged systemctl start haveged yum -y install java-1.8.0-openjdk-devel java -version vim ~/.bashrc export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/" #get path using "rpm -qa | grep openjdk" followed by "rpm -ql java-1.8.0-openjdk-devel-1.8.0.242.b08-0.el7_7.x86_64 | less" #Exit all running terminals and relogin so that JAVA_HOME is defined #Ensure firewalld is disabled or required ports 8443 etc. are allowed in firewall systemctl disable firewalld systemctl stop firewalld systemctl status firewalld
Clone CAS git repository and build 5.3 version
Clone CAS git repository and build 5.3 version using:
mkdir /opt/workspace cd /opt/workspace git clone https://github.com/apereo/cas-overlay-template.git cd cas-overlay-template/ git branch grep '<cas.version>' pom.xml #Should result into pom.xml not found in latest branch git branch -a #Check all versions git checkout 5.3 grep '<cas.version>' pom.xml git checkout -b rndtest-casdev #Create our own branch ./mvnw clean package ls -l target/
Configure CAS with hostname, encryption keys, etc.
- Edit etc/cas/config/cas.properties #Enter hostname
- Generate various encryption keys as follows:
- Visit https://mkjwk.org/ and generate encryption key for cas.tgc.crypto.signing.key using 512 “Key Size” and select HS256 as “Algorithm”
- cas.tgc.secure: true
- cas.tgc.crypto.signing.key:
- cas.tgc.crypto.encryption.key:
- cas.webflow.crypto.signing.key:
- cas.webflow.crypto.encryption.key:
- From same generator generate cas.tgc.crypto.encryption.key using 256 as “Key Size” and HS256 from the “Algorithm”
- From same generator generate value of the cas.webflow.crypto.signing.key using HS256 key size 512
- For cas.webflow.crypto.encryption.key use "openssl rand -base64 16" command
- Visit https://mkjwk.org/ and generate encryption key for cas.tgc.crypto.signing.key using 512 “Key Size” and select HS256 as “Algorithm”
- Edit etc/cas/config/log4j2.xml and specify '/var/log/cas' as log dir
- Create required folders and keystore:
- mkdir /var/log/cas
- rsync -vtrp etc/cas/ /etc/cas/
- vim /etc/hosts #Ensure entry for short hostname and FQDN for local LAN IP, if not added to DNS
- hostname <CAS-FQDN>
- vim /etc/hostname #Enter <CAS-FQDN> as hostname
- #These steps do not work perhaps due to use of wrong openssl 1.0 instead of openssl 1.1Vvvvvvvvv
- cd /etc/pki/tls/private
- openssl req -x509 -nodes -days 9999 -newkey rsa:2048 -sha256 -keyout cas.pem -out cas.pem
- openssl x509 -outform der -in cas.pem -out cas.der
- openssl pkcs12 -export -out cas.p12 -inkey cas.pem -in cas.pem -certfile cas.pem
- secret123
- keytool -importkeystore -srckeystore cas.p12 -srcstoretype pkcs12 -destkeystore keystore.jks
- changeit (Twice)
- secret123
- cp keystore.jks /etc/cas/thekeystore
- sudo keytool -import -file /etc/pki/tls/private/cas.der -alias cas -keystore $JAVA_HOME/jre/lib/security/cacerts
- changeit
- keytool -export -file /etc/pki/tls/private/cas.der -keystore /etc/cas/thekeystore -alias cas
- changeit
- Refer: https://apereo.github.io/cas/developer/Build-Process-5X.html
Install tomcat and other source based software
Install and configure tomcat using:
mkdir /opt/tomcat cd /opt/tomcat #Get tomcat download link from https://tomcat.apache.org/download-80.cgi curl -LO 'http://apachemirror.wuchna.com/tomcat/tomcat-8/v8.5.51/bin/apache-tomcat-8.5.51.tar.gz' tar xzf apache-tomcat-8.5.51.tar.gz ln -s apache-tomcat-8.5.51 latest mv apache-tomcat-8.5.51.tar.gz /root cd /root #Get openssl download link from https://www.openssl.org/source/ curl -LO 'https://www.openssl.org/source/openssl-1.1.1d.tar.gz' tar xzf openssl-1.1.1d.tar.gz cd openssl-1.1.1d mkdir -p /opt/openssl/openssl-1.1.1d ln -s openssl-1.1.1d /opt/openssl/latest ./config --prefix=/opt/openssl/openssl-1.1.1d shared make depend make make test make install_sw cd /root #Get apr download link from https://apr.apache.org/download.cgi curl -LO 'http://mirrors.estointernet.in/apache//apr/apr-1.7.0.tar.gz' tar xzf apr-1.7.0.tar.gz cd apr-1.7.0 mkdir -p /opt/apr/apr-1.7.0 ln -s apr-1.7.0 /opt/apr/latest ./configure --prefix=/opt/apr/apr-1.7.0 make make test make install cd /root tar xzf /opt/tomcat/apache-tomcat-8.5.51/bin/tomcat-native.tar.gz cd tomcat-native-1.2.23-src/native/ ./configure --with-java-home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/ \ --with-apr=/opt/apr/latest/bin/apr-1-config \ --with-ssl=/opt/openssl/latest \ --prefix=/opt/tomcat/apache-tomcat-8.5.51 make make install cd /root tar xzf /opt/tomcat/apache-tomcat-8.5.51/bin/commons-daemon-native.tar.gz cd commons-daemon-1.2.2-native-src/unix ./configure --with-java=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/ make cp jsvc /opt/tomcat/apache-tomcat-8.5.51/bin/ cd /opt/tomcat/latest cp -rp conf /etc/tomcat rm -rf conf ln -s /etc/tomcat conf cd /opt/tomcat/latest cp -rp logs /var/log/tomcat rm -rf logs ln -s /var/log/tomcat logs cd /opt/tomcat/latest cp -rp webapps /var/lib/tomcat rm -rf webapps ln -s /var/lib/tomcat webapps mv webapps/webapps/* webapps/ rmdir webapps/webapps/ cd /opt/tomcat/latest mkdir /var/cache/tomcat cp -rp work /var/cache/tomcat/work rm -rf work ln -s /var/cache/tomcat/work work rmdir work/work cd /opt/tomcat/latest cp -rp temp /var/cache/tomcat/temp rm -rf temp ln -s /var/cache/tomcat/temp temp mv temp/temp/* temp/ rmdir temp/temp/ groupadd -r tomcat usermod -d /opt/tomcat -g tomcat -s /sbin/nologin tomcat getent passwd tomcat mkdir -p /opt/tomcat/latest/conf/Catalina/localhost for dir in . conf webapps do cd /opt/tomcat/latest/$dir chown -R root.tomcat . chmod -R u+rwX,g+rX,o= . chmod -R g-w . done for dir in logs temp work do cd /opt/tomcat/latest/$dir chown -R tomcat.tomcat . chmod -R u+rwX,g+rX,o= . chmod -R g-w . done cd /opt/tomcat/latest rm -rf temp/* work/* cd webapps rm -rf docs examples host-manager manager
Configure tomcat
- Edit /opt/tomcat/latest/conf/server.xml and set
- <Server port="-1" shutdown="SHUTDOWN">
- <Host name="localhost" appBase="webapps" unpackWARs="false" autoDeploy="false">
- <!-- <Connector port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443" /> -->
- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
- sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
- SSLEnabled="true" connectionTimeout="20000" maxThreads="150">
- <SSLHostConfig
- ciphers="ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
- honorCipherOrder="true" protocols="all,-SSLv2Hello,-SSLv2,-SSLv3"
- disableSessionTickets="true">
- <Certificate certificateKeystoreFile="/opt/tomcat/keystore.jks" certificateKeystorePassword="changeit" type="RSA" />
- </SSLHostConfig>
- <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
- </Connector>
- <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
- /> -->
- cp /etc/cas/thekeystore /opt/tomcat/keystore.jks
- cd /opt/tomcat/
- chown root.tomcat keystore.jks
- chmod 640 keystore.jks
- Edit /opt/tomcat/latest/conf/web.xml and insert
- <async-supported>true</async-supported>
- before "</servlet>" for default and jsp servlets
- Edit /opt/tomcat/latest/conf/context.xml and insert
- <Resources cachingAllowed="true" cacheMaxSize="40960" cacheTtl="60000" />
- before "</Context>"
- Edit /opt/tomcat/latest/conf/catalina.properties and search for jarsToSkip and update below line
- jmx-tools.jar,jta*.jar,mail*.jar,slf4j*.jar,\
- Basically uncomment log4j jars by removing them from above line
- Create /etc/systemd/system/tomcat.service using following content:
- [Unit]
- Description=Apache Tomcat Web Application Container
- After=network.target
- [Service]
- Type=forking
- PIDFile=/var/run/tomcat.pid
- UMask=0007
- # Tomcat variables
- Environment='JAVA_HOME=/usr/lib/jvm/java-openjdk'
- Environment='CATALINA_PID=/var/run/tomcat.pid'
- Environment='CATALINA_HOME=/opt/tomcat/latest'
- Environment='CATALINA_BASE=/opt/tomcat/latest'
- Environment='CATALINA_OPTS=-Xms512M -Xmx2048M -XX:+UseParallelGC -server'
- # Needed to make use of Tomcat Native Library
- Environment='LD_LIBRARY_PATH=/opt/tomcat/latest/lib'
- ExecStart=/opt/tomcat/latest/bin/jsvc \
- -Dcatalina.home=${CATALINA_HOME} \
- -Dcatalina.base=${CATALINA_BASE} \
- -Djava.awt.headless=true \
- -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
- -Djava.util.logging.config.file=${CATALINA_BASE}/conf/logging.properties \
- -cp ${CATALINA_HOME}/bin/commons-daemon.jar:${CATALINA_HOME}/bin/bootstrap.jar:${CATALINA_HOME}/bin/tomcat-juli.jar \
- -pidfile ${CATALINA_PID} \
- -java-home ${JAVA_HOME} \
- -user tomcat \
- $CATALINA_OPTS \
- org.apache.catalina.startup.Bootstrap
- ExecStop=/opt/tomcat/latest/bin/jsvc \
- -pidfile ${CATALINA_PID} \
- -stop \
- org.apache.catalina.startup.Bootstrap
- [Install]
- WantedBy=multi-user.target
- Setup tomcat as systemd service using:
- chmod 644 /etc/systemd/system/tomcat.service
- systemctl enable tomcat.service
- systemctl start tomcat.service
- systemctl status tomcat.service
- Edit /opt/tomcat/latest/webapps/ROOT/index.jsp and insert this immediately after Congratulations!
- <p>Server:
- <%= request.getLocalName() %> /
- <%= request.getLocalAddr() %> /
- <%= request.getLocalPort() %></p>
- <p>Client:
- <%= request.getRemoteHost() %> /
- <%= request.getRemoteAddr() %> /
- <%= request.getRemotePort() %></p>
- Restart tomcat using 'systemctl restart tomcat'
Look at logs and resolve errors
- 'less /var/log/tomcat/catalina.YYYY-MM-DD.log' should not have any errors
- If there is error
- java.lang.ClassNotFoundException: org.apache.catalina.core.JasperListener
- Edit file /opt/tomcat/latest/conf/server.xml and comment
- <!-- <Listener className="org.apache.catalina.core.JasperListener" /> -->
OpenSSL cannot recover key error
Further due to below error
Caused by: java.lang.IllegalArgumentException: Cannot recover key at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:100) at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:72) at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:246) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1118) at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:223) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:587) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74) at org.apache.catalina.connector.Connector.initInternal(Connector.java:1030) ... 17 more Caused by: java.security.UnrecoverableKeyException: Cannot recover key
Delete all existing keys created so far:
rm -rf /etc/cas/thekeystore rm -rf /opt/tomcat/keystore.jks cd /etc/pki/tls/private/ ls rm -f *
Add latest Openssl installed via source in ld path by editing '/etc/ld.so.conf' and appending:
/opt/openssl/openssl-1.1.1d/lib
Run ldconfig and check that latest openssl libraries are loaded:
ldconfig ldconfig -p | grep openssl
Validate that latest openssl is running /opt/openssl/latest/bin/openssl version
If not edit '~/.bashrc' and prepend path for openssl installed by source to current path
export PATH=/opt/openssl/latest/bin:$PATH
Exit from all shells and reconnect. Now openssl version should be 1.1.1d
Regenerate various keystores and keys again
Regenerate various keystores and keys again using:
cd /etc/pki/tls/private mkdir -p /opt/openssl/openssl-1.1.1d/ssl/ cp /root/openssl-1.1.1d/apps/openssl.cnf /opt/openssl/openssl-1.1.1d/ssl/ openssl req -x509 -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM #Remember various values given to create CA with case sensitivity openssl req -nodes -newkey rsa:2048 -sha256 -keyout cas.key -out cas.csr #Keep Organization name and other values same with case sensitivity as while creating CA touch index.txt echo '01' > serial.txt vim /opt/openssl/openssl-1.1.1d/ssl/openssl.cnf Under [CA_default] update at least dir = . serial = $dir/serial.txt private_key = $dir/private/privkey.pem mkdir newcerts openssl ca -in cas.csr -out cas.crt -cert cacert.pem -keyfile privkey.pem cat cas.crt cacert.pem > /opt/tomcat/cas-all.crt cd /opt/tomcat openssl pkcs12 -export -inkey /etc/pki/tls/private/cas.key -in cas-all.crt -name tomcat -out cas.p12 changeit (Twice) keytool -importkeystore -srckeystore cas.p12 -srcstoretype pkcs12 -destkeystore keystore.jks changeit (Thrice) chown root.tomcat keystore.jks chmod 640 keystore.jks systemctl restart tomcat
Validate all errors are resolved
Now 'less /var/log/tomcat/catalina.YYYY-MM-DD.log' and validate log line similar to
04-Mar-2020 18:23:43.609 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 926 ms
is present
Test standalone CAS without tomcat
Test standalone CAS without tomcat using:
systemctl stop tomcat cp /opt/tomcat/keystore.jks /etc/cas/thekeystore cd /opt/workspace/cas-overlay-template java -jar target/cas.war #Access server at https://<CAS-FQDN>:8443/cas and login with casuser:Mellon
- Ctrl-C to stop standalone cas
- Now start tomcat
- systemctl start tomcat
- Access tomcat page at https://<CAS-FDQN>:8443/
- Validate certificate details
In "less /var/log/tomcat/catalina.YYYY-MM-DD.log" validate for following logs are present
04-Mar-2020 18:30:31.636 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.23] using APR version [1.7.0]. 04-Mar-2020 18:30:31.637 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. 04-Mar-2020 18:30:31.637 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] 04-Mar-2020 18:30:31.652 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1d 10 Sep 2019]
Create important shell-scripts
cassrv-tarball.sh
We will need below commands may times. Perhaps save them as 'cassrv-tarball.sh'
cd /opt/workspace/cas-overlay-template tar czf /root/cassrv-files.tgz --owner=root --group=tomcat --mode=g-w,o-rwx \ etc/cas -C target cas --exclude cas/META-INF ls -asl /root/cassrv-files.tgz
Execute this script once.
cassrv-install.sh
We will need below commands many times. Perhaps save them as 'cassrv-install.sh'
systemctl stop tomcat cd / rm -rf etc/cas/config etc/cas/services tar xzf /root/cassrv-files.tgz etc/cas cd /opt/tomcat/latest/ rm -rf webapps/cas work/Catalina/localhost/cas cd /opt/tomcat/latest/webapps tar xzf /root/cassrv-files.tgz cas systemctl start tomcat
Execute this script once.
In "less /var/log/tomcat/catalina.YYYY-MM-DD.log" look for
04-Mar-2020 19:05:37.535 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/var/lib/tomcat/cas] has finished in [41,460] ms 04-Mar-2020 19:05:37.545 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-nio-8443"] 04-Mar-2020 19:05:37.554 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 42398 ms
Access server at https://<CAS-FQDN>:8443/cas and login with casuser:Mellon
Commit existing build and add JSON support
Commit existing changes:
cd /opt/workspace/cas-overlay-template git add etc/cas/config/cas.properties git add etc/cas/config/log4j2.xml git commit -m "Initial CAS build"
Edit pom.xml and search for dependencies and then under dependencies of default profile add dependency for json service
<dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-json-service-registry</artifactId> <version>${cas.version}</version> </dependency>
Rebuild CAS with JSON service support using:
./mvnw clean package
Edit etc/cas/config/cas.properties and append following to enable JSON files based services from desired folder
cas.serviceRegistry.json.location: file:/etc/cas/services
mkdir etc/cas/services
Create 'etc/cas/services/HTTPSandIMAPSwildcard-1503925297.json' with following contents:
{ /* * Wildcard service definition that applies to any https or imaps url. * Do not use this definition in a production environment. */ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https|imaps)://.*", "name" : "HTTPS and IMAPS wildcard", "id" : 1503925297, "evaluationOrder" : 99999 }
After this run shell-scripts: 1. cassrv-tarball.sh 2. cassrv-install.sh
Commit changes related to enabling JSON service registory to git:
cd /opt/workspace/cas-overlay-template git add etc/cas/config/cas.properties git add etc/cas/services git add pom.xml git commit -m "Added JSON service registry"
Add support for LDAP or AD
Edit pom.xml and add dependency for LDAP:
<dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-ldap</artifactId> <version>${cas.version}</version> </dependency>
Rebuild CAS with LDAP support
./mvnw clean package
Edit etc/cas/config/cas.properties and append below line to disable casuser:Mellon login:\
cas.authn.accept.users:
Commit LDAP support to git
cd /opt/workspace/cas-overlay-template git add etc/cas/config/cas.properties git add pom.xml git commit -m "Added LDAP support"
In etc/cas/config/cas.properties add configuration to authenticate against AD using:
cas.authn.ldap[0].order: 0 cas.authn.ldap[0].name: Active Directory cas.authn.ldap[0].type: AUTHENTICATED #cas.authn.ldap[0].type: AD #Replace below with desired bind dn cas.authn.ldap[0].bindDn=cn=Administrator,CN=Users,DC=<Domain>,DC=COM cas.authn.ldap[0].bindCredential=<Administrator-password> cas.authn.ldap[0].ldapUrl: ldap://<AD-Server-FQDN-or-IP>/ cas.authn.ldap[0].validatePeriod: 270 cas.authn.ldap[0].poolPassivator: BIND cas.authn.ldap[0].searchFilter: sAMAccountName={user} cas.authn.ldap[0].baseDn: DC=<Domain>,DC=COM #cas.authn.ldap[0].dnFormat: cn=%s,ou=Users,DC=<Domain>,DC=COM cas.authn.ldap[0].subtreeSearch=true cas.authn.ldap[0].enhanceWithEntryResolver=true cas.authn.ldap[0].derefAliases=ALWAYS cas.authn.ldap[0].useSsl=false cas.authn.ldap[0].useStartTls=false
Note that since in our case it is not possible to come up with dnFormat directly based on username, it is not possible to use LDAP type AD. We are using LDAP type authenticated with bind credentials and search filter to search correct user with matching sAMAccountName
Run shell-scripts: 1. cassrv-tarball.sh 2. cassrv-install.sh
- Open https://<CAS-FQDN>:8443/cas/login
- Try to login with AD user. Vaidate that only with correct password login is working.
Refer:
Home > CentOS > CentOS 7.x > Web Based Tools > CentOS 7.x Apereo CAS > CentOS 7.x Deploy Apereo CAS 5.3 and integrate with AD