Cas

From Newroco tech docs
Jump to navigationJump to search

Cas 6.x.x

Install Tomcat 9

  1.  
  2. apt-get install openjdk-11-jdk tomcat9
  3.  

Copy certificates from proxy with rsync

Add the public key of the user that is going to copy the certificates to the /root directory. More details here http://docswiki.newro.co/index.php/SSHKeyAuth#Install_key_authentication_for_an_account. Create script /opt/bin/letsencrypt-sync.sh:

  1. /usr/bin/rsync -rl --safe-links --rsync-path="/usr/bin/sudo /usr/bin/rsync" <user>@<proxy-ip>:/etc/letsencrypt/ /etc/letsencrypt-proxy/ 2>&1 >> /var/log/letsencrypt_sync.log
  2.  
  3. openssl pkcs12 -export -in /etc/letsencrypt-proxy/live/<domain>/fullchain.pem -inkey /etc/letsencrypt-proxy/live/<domain>/privkey.pem -out /opt/bin/fullchain_and_key.p12 -name tomcat -password pass:<password>
  4.  
  5. systemctl restart tomcat9

Make it executable

  1. chmod +x /opt/bin/letsencrypt-sync.sh

Install rsync if not already

  1. apt-get install rsync

Run the script for initial copy

  1. /opt/bin/letsencrypt-sync.sh

Make the converted certificate readable for everyone

  1. chmod +r /opt/bin/fullchain_and_key.p12

Create a crontab for automatic copy

  1. vi /etc/cron.d/letsencrypt-sync

And add this to the file:

  1. 0 1 * * * root /opt/bin/letsencrypt-sync.sh

Configure Tomcat

Enable encryption by editing /etc/tomcat9/server.xml, uncomment and change appropriately the next section(change password with what you used in script above):

  1.  
  2. <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
  3. maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
  4. clientAuth="false" sslProtocol="TLS"
  5. keystoreFile="/opt/bin/fullchain_and_key.p12" keystoreType="PKCS12"
  6. keystorePass="<password>"
  7. />
  8.  

In the same file, add/modify these lines at the end of the file to let tomcat see the original IP when running behind a reverse proxy

  1. <Valve className="org.apache.catalina.valves.RemoteIpValve" />
  2.  
  3. <!-- Access log processes all example.
  4. Documentation at: /docs/config/valve.html
  5. Note: The pattern used is equivalent to using pattern="common" -->
  6. <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
  7. prefix="localhost_access_log" suffix=".txt"
  8. requestAttributesEnabled="true"
  9. pattern="%h %l %u %t &quot;%r&quot; %s %b" />

Restart tomcat and you should be able to access it at https://my.domain.com:8443

  1. systemctl restart tomcat9


Add the following argumet to the HTTPS proxy vhost:

  1. SSLProxyEngine On

Install CAS

Download the CAS Overlay Template needed for installation.

  1. mkdir /opt/cas
  2. cd /opt/cas
  3. wget https://github.com/apereo/cas-overlay-template/archive/6.1.zip
  4. unzip 6.1.zip
  5. cd cas-overlay-template-6.1

First, you need to open the file build.gradle and add the necessary dependencies. Here are the base dependencies that you'll most probably need:

  1. dependencies {
  2. compile "org.apereo.cas:cas-server-webapp${project.appServer}:${casServerVersion}"
  3. compile "org.apereo.cas:cas-server-support-ldap:${casServerVersion}"
  4. compile "com.unboundid:unboundid-ldapsdk:4.0.14"
  5. compile "org.apereo.cas:cas-server-support-json-service-registry:${casServerVersion}"
  6. }

For more dependencies like SAML, OAuth2, OpenID Connect, 2 Factor Authentication, etc. visit this page: https://apereo.github.io/cas/6.1.x/index.html

By default when building CAS, it doesn't make all the resources available, that you need to configure and customize your CAS instance. So you first need to make those resources available for the war file that you'll build.

  1. ./gradlew explodeWar
  2. mkdir src/main/resources
  3. cp -r build/cas-resources/* src/main/resources/

Note: if you are also building a failover server as well, or you think you'll need to rebuild the app in the future (e.g. to add another dependency) it will be easier to first configure CAS with the resources you just copied and then build it and copy the cas.war into the tomcat folder on all servers needed.

Now we can build the application war file.

  1. ./gradlew clean build

Move the resulted war file into the tomcat folder

  1. cp build/libs/cas.war /var/lib/tomcat9/webapps/

Note: CAS 6.1 requires tomcat 9.0.27 (or newer), so if you have an older version of tomcat 9 it can still work but this will need to be set in /var/lib/tomcat9/webapps/cas/WEB-INF/classes/application.properties

  1. spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration

To be able to manage what services/apps are allowed to authenticate through CAS, you need to add this line to the configuration

  1. cas.serviceRegistry.initFromJson=true
  2. cas.serviceRegistry.json.location=file:/var/lib/tomcat9/webapps/cas/WEB-INF/classes/services

If you plan to implement OAuth2 on CAS you should specifically configure the service URL

  1. cas.server.name=https://cas.domain.com
  2. cas.server.prefix=${cas.server.name}/cas

Uncomment these 2 lines from the configuration to disable the default account.

  1. #cas.authn.accept.users=casuser::Mellon
  2. #cas.authn.accept.name=Static Credentials

To set an LDAP server as the user source use this configuration

  1. cas.authn.ldap[0].providerClass=org.ldaptive.provider.unboundid.UnboundIDProvider
  2. cas.authn.ldap[0].type=AUTHENTICATED
  3. cas.authn.ldap[0].ldapUrl=ldaps://ldap.domain.com
  4. cas.authn.ldap[0].useSsl=true
  5. cas.authn.ldap[0].useStartTls=false
  6. cas.authn.ldap[0].connectTimeout=5000
  7. cas.authn.ldap[0].minPoolSize=0
  8. cas.authn.ldap[0].baseDn=cn=Users,dc=<domain>,dc=local
  9. cas.authn.ldap[0].searchFilter=sAMAccountName={user}
  10. cas.authn.ldap[0].bindDn=cn=<bind-user>,cn=Users,dc=<domain>,dc=local
  11. cas.authn.ldap[0].bindCredential=<password>
  12. cas.authn.ldap[0].trustCertificates=file:/opt/samba-cert/samba-cert.pem
  13. cas.authn.ldap[0].principalAttributeList=sAMAccountName,mail,displayName

Restart tomcat

  1. systemctl restart tomcat9

Change login page design

To add logo to the login page first copy the .png file /cas/WEB-INF/classes/static/images directory and change the file ownership to tomcat user:

  1. sudo chown tomcat:tomcat logo.png

Add following line to /var/lib/tomcat9/webapps/cas/WEB-INF/classes/templates/fragments/header.html before or after the "svg" tag contained in a <a> tag:

  1. <a href="https://newro.co/"><img src="/cas/images/newroco_logo.png" style="width: 375px;height: 55px;"/></a>

To remove the drop down menu, remove all the

  1. "<div class="collapse navbar-collapse" id="navbarSupportedContent">"

class.

Change the head bar background color

Add following file to /cas/WEB-INF/classes/static/css/cas.css line 11755:

  1. header > .navbar {
  2. background-color: #a1b1b9;
  3. color: #fff;

Change the "Reset password?" button

Edit the text message /cas/WEB-INF/classes/messages.properties line 27 and the redirect link from /cas/WEB-INF/classes/templates/fragments/pmlinks.html line 32.

OAuth2

To be able to use the OAuth2 you first need to add this to the dependencies before building CAS

  1. compile "org.apereo.cas:cas-server-support-oauth-webflow:${project.'cas.version'}"

Now create a json file in /var/lib/tomcat9/webapps/cas/WEB-INF/classes/services/ to allow an app to authenticate with CAS using the OAuth2 protocol

  1. {
  2. "@class" : "org.apereo.cas.support.oauth.services.OAuthRegisteredService",
  3. "clientId": "OAuth2AppToBeAllowed",
  4. "clientSecret": "<secret>", ### can be generated with "openssl rand -base64 32"
  5. "serviceId" : "^https://app.domain.com/path/to/OAuth2/endpoint",
  6. "name" : "OAuth for my App",
  7. "id" : 10000002, ### make sure this id is unique
  8. "attributeReleasePolicy" : {
  9. "@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy",
  10. "allowedAttributes" : [ "java.util.ArrayList", [ "sAMAccountName", "mail", "displayName" ] ]
  11. },
  12. "bypassApprovalPrompt" : true, ### this is needed so the user won't be asked at every login if he wants to allow the App to use the info provided by CAS
  13. "evaluationOrder" : 102
  14. }

Troubleshooting

In case you need to see how the response from CAS looks like, here is how you can find out. First install jq

  1. apt-get install jq

Request a token from CAS

  1. curl https://cas.domain.com/cas/oauth2.0/token?grant_type=password'&'client_id=client'&'client_secret=secret'&'username=my.user'&'password=my-password | jq

Then request the info about the user with the received token

  1. curl -k --user client:secret https://cas.domain.com/cas/oauth2.0/profile?access_token=AT-1-wiNsTgaHzXLUIyaaoFoip-znohWPihea

Enable debug mode

  1. logging.level.org.apereo.cas=DEBUG

2 Factor Authentication (2FA)

Note: CAS calls 2 Factor Authentication (2FA) as Multifactor Authentication (MFA). Mainly because it is possible to set multiple 2FA options in a certain order (e.g. user/pass -> 2fa sms -> 2fa email -> successful login)

Email

To be able to use email 2FA you first need to add this to the dependencies before building CAS

  1. compile "org.apereo.cas:cas-server-support-simple-mfa:${project.'cas.version'}"

Next you need to install postfix

  1. apt-get install postfix

Add these lines to the CAS config in /var/lib/tomcat9/webapps/cas/WEB-INF/classes/application.properties

  1. cas.authn.mfa.globalProviderId=mfa-simple
  2. cas.authn.mfa.simple.name=Email MFA
  3. cas.authn.mfa.simple.order=1
  4. cas.authn.mfa.simple.timeToKillInSeconds=180
  5. cas.authn.mfa.simple.tokenLength=6
  6.  
  7. cas.authn.mfa.simple.mail.from=no-reply@my.domain.com
  8. cas.authn.mfa.simple.mail.text=This is your 2FA code for CAS authentication: %s
  9. cas.authn.mfa.simple.mail.subject=CAS 2FA Code
  10. cas.authn.mfa.simple.mail.validateAddresses=false
  11. cas.authn.mfa.simple.mail.html=false
  12.  
  13. cas.authn.mfa.simple.mail.attributeName=mail
  14.  
  15. spring.mail.host=localhost
  16. spring.mail.port=25
  17. spring.mail.testConnection=true
  18. spring.mail.properties.mail.smtp.auth=false
  19. spring.mail.properties.mail.smtp.starttls.enable=false

SMS (Nexmo)

To be able to use SMS 2FA you first need to add this to the dependencies before building CAS

  1. compile "org.apereo.cas:cas-server-support-simple-mfa:${project.'cas.version'}"
  2. compile "org.apereo.cas:cas-server-support-sms-nexmo:${project.'cas.version'}"

Create an account on Nexmo (https://dashboard.nexmo.com/sign-up). After that create a new application, that should give you an api key and a secret.

Add these lines to the CAS config in /var/lib/tomcat9/webapps/cas/WEB-INF/classes/application.properties

  1. cas.authn.ldap[0].principalAttributeList=mail,telephoneNumber #you probably have this already in your config just need to add the phone attribute
  2.  
  3. cas.authn.mfa.globalProviderId=mfa-simple
  4. cas.authn.mfa.simple.name=SMS 2FA
  5. cas.authn.mfa.simple.order=1
  6. cas.authn.mfa.simple.timeToKillInSeconds=180
  7. cas.authn.mfa.simple.tokenLength=6
  8.  
  9. cas.authn.mfa.simple.sms.from=CAS
  10. cas.authn.mfa.simple.sms.text=This is your CAS 2FA code: %s
  11. cas.authn.mfa.simple.sms.attributeName=telephoneNumber
  12.  
  13. cas.smsProvider.nexmo.apiToken=<api-key>
  14. cas.smsProvider.nexmo.apiSecret=<api-secret>

Cas 4.x-5.x (old)

Install Tomcat 8

  1.  
  2. apt-get install openjdk-8-jdk
  3. apt-get install tomcat8
  4.  

Copy certificates from proxy with rsync

Add the public key of the user that is going to copy the certificates to the /root directory. More details here http://docswiki.newro.co/index.php/SSHKeyAuth#Install_key_authentication_for_an_account. Create script /opt/bin/letsencrypt_sync:

  1. /usr/bin/rsync -rl --safe-links --rsync-path="/usr/bin/sudo /usr/bin/rsync" <user>@<proxy-ip>:/etc/letsencrypt/ /etc/letsencrypt-proxy/ 2>&1 >> /var/log/letsencrypt_sync.log
  2.  
  3. openssl pkcs12 -export -in /etc/letsencrypt-proxy/live/<domain>/fullchain.pem -inkey /etc/letsencrypt-proxy/live/<domain>/privkey.pem -out /opt/bin/fullchain_and_key.p12 -name tomcat -password pass:<password>
  4.  
  5. systemctl restart tomcat8

Make it executable

  1. chmod +x /opt/bin/letsencrypt_sync

Install rsync if not already

  1. apt-get install rsync

Run the script for initial copy

  1. /opt/bin/letsencrypt_sync

Create a crontab for automatic copy

  1. crontab -u root -e

And add this to the file:

  1. 0 0 * * * /opt/bin/letsencrypt_sync

Enable SSL

Edit /etc/tomcat8/server.xml, uncomment and change appropriately the next section(change password with what you used in script above):

  1.  
  2. <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
  3. maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
  4. clientAuth="false" sslProtocol="TLS"
  5. keystoreFile="/opt/bin/fullchain_and_key.p12" keystoreType="PKCS12"
  6. keystorePass="<password>"
  7. />
  8.  

Restart tomcat (service tomcat8 restart) and you should be able to access it at https://server-ip:8443


Add the following argumet to the HTTPS proxy vhost:

  1. SSLProxyEngine On

Install CAS

First we need to install maven.

  1.  
  2. apt-get install maven
  3.  

Create a directory to download cas and in that directory create a file pom.xml. The content of pom.xml for the latest CAS version can be taken from https://github.com/apereo/cas-overlay-template/blob/master/pom.xml

  1.  
  2. mkdir ~/cas
  3. vi ~/cas/pom.xml
  4.  

If you want CAS to use LDAP then add this to pom.xml inside <dependencies> tag:

  1.  
  2. <dependency>
  3. <groupId>org.apereo.cas</groupId>
  4. <artifactId>cas-server-support-ldap</artifactId>
  5. <version>${cas.version}</version>
  6. </dependency>
  7.  

Now go to ~/cas directory, download CAS and copy cas.war to tomcats webapp folder.

  1.  
  2. cd ~/cas
  3. mvn clean package
  4. cp target/cas.war /var/lib/tomcat8/webapps/
  5. service tomcat8 restart
  6.  

The CAS login page can be found at https://server-ip:8443/cas/login

Configure CAS

If the samba/LDAP server is using a self-signed certificate copy it (from /var/lib/samba/private/tls/samba-cert.pem) to the CAS server in /opt/bin/samba-cert.pem. Create a samba user for CAS to use. Back on the CAS server, add a line in /etc/hosts:

  1.  
  2. samba-server-ip hostname.domain.local
  3.  

Edit /var/lib/tomcat8/webapps/cas/WEB-INF/classes/application.properties file. Comment if you find a line like this:

  1.  
  2. cas.authn.accept.users=casuser::Mellon
  3.  

And add this at the end of the file, changing it for your case:

  1.  
  2. cas.authn.ldap[0].type=AUTHENTICATED
  3. cas.authn.ldap[0].ldapUrl=ldaps://hostname.domain.local
  4. cas.authn.ldap[0].useSsl=true
  5. cas.authn.ldap[0].connectTimeout=5000
  6. cas.authn.ldap[0].baseDn=dc=DOMAIN,dc=LOCAL
  7. cas.authn.ldap[0].userFilter=sAMAccountName={user}
  8. cas.authn.ldap[0].subtreeSearch=true
  9. cas.authn.ldap[0].usePasswordPolicy=true
  10. cas.authn.ldap[0].bindDn=cn=cas-user,cn=Users,dc=DOMAIN,dc=LOCAL
  11. cas.authn.ldap[0].bindCredential=cas-user-passwords
  12. cas.authn.ldap[0].trustCertificates=file:/opt/bin/samba-cert.pem
  13.  

Change this line at the beginning of /var/lib/tomcat8/webapps/cas/WEB-INF/classes/log4j2.xml

  1. <Property name="baseDir">/etc/cas/logs</Property>

To

  1. <Property name="baseDir">/var/lib/tomcat8/webapps/cas/WEB-INF/classes/logs</Property>

Add a cronjob to delete old logs.

  1. #vi /etc/cron.daily/cas-old-logs
  2.  
  3. #!/bin/bash
  4. find /var/lib/tomcat8/webapps/cas/WEB-INF/classes/logs -mtime +10 -type f -delete

Make it executable

  1. chmod +x /etc/cron.daily/cas-old-logs

Restart tomcat

  1.  
  2. service tomcat8 restart
  3.  

Note: tomcat8 and its apps take a long time to fully restart.

Tomcat logs

By default the logrotate created by tomcat rotates weekly and keeps 52 log files. You probably don't need that much, so to keep the disk to a low, change the rotation to daily and keep 30 files or whatever suits you.

  1. #vi /etc/logrotate.d/tomcat8
  2.  
  3. /var/log/tomcat8/catalina.out {
  4. copytruncate
  5. daily
  6. rotate 30
  7. compress
  8. missingok
  9. create 640 tomcat8 adm
  10. }

Service registry

By default CAS allows all services that come from HTTPS or IMAPS. If you want to change that you can modify /var/lib/tomcat8/webapps/cas/WEB-INF/classes/services/HTTPSandIMAPS-10000001.json or create a another file in the same folder with similar format.

If CAS says that the service is not authorized even if it is, add this line to /var/lib/tomcat8/webapps/cas/WEB-INF/classes/application.properties

  1. cas.serviceRegistry.initFromJson=true

If your LDAP server is case insensitive but one of your services is case sensitive you might want to transform login usernames to lowercase, as LDAP would accept "User.Name" even it is actually "user.name", but your service will see User.Name as a new user.

To do this add the following to the json file from /var/lib/tomcat8/webapps/cas/WEB-INF/classes/services that defines the service

  1. "usernameAttributeProvider": {
  2. "@class": "org.apereo.cas.services.DefaultRegisteredServiceUsernameProvider",
  3. "canonicalizationMode": "LOWER"
  4. }

Ticket Experation

If you want to change the ticket expiration time you can add this to /var/lib/tomcat8/webapps/cas/WEB-INF/classes/application.properties

  1. cas.ticket.tgt.timeout.maxTimeToLiveInSeconds=28800

Internal DNS records

If the CAS server and other web services that use CAS for authentication are behind the same proxy they will probably need internal DNS records pointing to the internal IP of the proxy to avoid loops in the firewall routing.

Failover

If you want to have a failover CAS build a second server exactly as above and configure a floating IP with Keepalived as below.

Keepalived

To setup keepalived, install it on both servers:

  1. sudo apt-get install keepalived

Copy the nagios check "check_http" to /usr/local/bin, from the /usr/lib/nagios/plugins of a server that has nagios-plugins installed (please don't install nagios-plugins on the CAS servers, that package would install many dependencies).

Finally create the following /etc/keepalived/keepalived.conf on the master:

  1. global_defs {
  2. notification_email {
  3. <email>
  4. }
  5.  
  6. notification_email_from <email>
  7. smtp_server 127.0.0.1
  8. }
  9.  
  10. vrrp_script chk_apache {
  11. script "check_http -S -H 127.0.0.1 -u /cas/ -p 8443"
  12. interval 3 # check every 3 seconds
  13. weight 2 # add 2 points of prio if OK
  14. }
  15.  
  16. vrrp_instance floating_ip {
  17. interface ens3
  18. state MASTER
  19. virtual_router_id 31
  20. priority 101
  21. authentication {
  22. auth_type PASS
  23. auth_pass justatestpass
  24. }
  25. virtual_ipaddress {
  26. <floating-IP>
  27. }
  28.  
  29. track_script {
  30. chk_apache
  31. }
  32. }

Create exactly the same file on the failover CAS, just change priority from 101 to 100.

Restart keepalived

  1. service keepalived restart