You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 28 Next »

Get a server and database

Here is an example with AWS, basically for this example you need a Unix-based server (or Mac), and a postgres (recommended), or mysql or oracle database.  Install Docker as well

Install the container

  1. Install docker (note, using a server with systemd is easier)
  2. See if docker is running

    bin $ docker info
    Client:
     Debug Mode: false
    
    Server:
     Containers: 5
      Running: 0
      Paused: 0
    
    
  3. List containers

    bin $ docker ps --all
    CONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS                       PORTS                                                                                               NAMES
    ca762df952a6        tier/gte:101.1.1-201906               "/usr/local/bin/entr…"   9 months ago        Exited (137) 9 months ago                                                                                                        101.1.1
    bin $ 
    
    
  4. Remove unneeded containers if necessary

    bin $ docker rm -f ca762df952a6
    ca762df952a6
    
    
  5. See which version of Grouper to run
  6. Pull the image

    bin $ docker pull i2incommon/grouper:2.5.XX
  7. (Reference command) List images

    [root@ip-172-30-3-152 ~]# docker image ls
    REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
    my-grouper-2.5.XX    latest              918f5dd01bd5        6 hours ago         1.23GB
    i2incommon/grouper   2.5.XX              f939770b7d91        34 hours ago        1.23GB
    [root@ip-172-30-3-152 ~]# 
  8. (Reference command) Remove old images

    [root@ip-172-30-3-152 ~]# docker rmi 918f5dd01bd5
    [root@ip-172-30-3-152 ~]# docker rmi f939770b7d91
  9. Create a directory to mount files and folder in and out of container

    2.5 $ mkdir -p /opt/grouperContainer
    2.5 $ mkdir -p /opt/grouperContainer/slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes
    
    
  10. Create a local database (e.g. mysql, utf8, bin collation, create a user and password, and grant all to the new database from username and password)
  11. Set grouper.hibernate.properties.  Note, for DB URL, "localhost" is the container itself, not the enclosing server.  You need to use an IP address that the container can communicate with.  

    2.5 $ vi /opt/grouperContainer/slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes/grouper.hibernate.properties
    
    hibernate.connection.url = jdbc:mysql://192.168.86.71:3306/grouper_v2_5?useSSL=false
    
    hibernate.connection.username         = grouper_v2_5
    
    hibernate.connection.password         = ************
    
    # what version should we auto install DDL up to.  You should put the major and minor version here (e.g. 2.5.*).  Or you could go to a build number if you like, 
    # or nothing to not auto DDL.  e.g. 2.5.32     or     2.5.*
    # {valueType: "string"}
    registry.auto.ddl.upToVersion = 2.5.*
    
    
    # UI basic auth is for quick start. Set to false when you migrate to shib or something else
    grouper.is.ui.basicAuthn=true
    grouper.is.ws.basicAuthn=true
    grouper.is.scim.basicAuthn = true
  12. If you cant connect to the database, go in the container (instructions later (smile) ) and test the communication with telnet 

    grouperContainer $ docker exec -it grouper-daemon /bin/bash
    [root@0d9054515bed WEB-INF]# yum install telnet
    [root@0d9054515bed WEB-INF]# telnet database-2.cstlzkqw179p.us-east-1.rds.amazonaws.com 3306
    Trying 172.30.3.40...
    Connected to database-2.cstlzkqw179p.us-east-1.rds.amazonaws.com.
    Escape character is '^]'.
    X
    5.5.5-10.4.8-MariaDBK;&I~bLþ8pOz8H?EzW(\mysql_native_password^CConnection closed by foreign host.
    [root@0d9054515bed WEB-INF]# 
    
    
  13. The container contains jdbc drivers for hsql, msyql and postgres.  If you're using Oracle, you'll need to add the jar.  Might want to use: https://repo1.maven.org/maven2/com/oracle/ojdbc/ojdbc8/19.3.0.0/ojdbc8-19.3.0.0.jar
    2.5 $ ls -al /opt/grouperContainer/slashRoot/opt/grouper/grouperWebapp/WEB-INF/lib/ojdbc6_g.jar
  14. Set morphString.properties unique key for encryption

    2.5 $ vi /opt/grouperContainer/slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes/morphString.properties
    # random 16 char alphanumeric upper/lower
    encrypt.key = *******************
  15. Configure logging

    2.5 $ mkdir -p /opt/grouperContainer/logs
    2.5 $ vi /opt/grouperContainer/slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes/log4j.properties
    ## Log messages to stderr
    log4j.appender.grouper_stderr = org.apache.log4j.ConsoleAppender
    log4j.appender.grouper_stderr.Target = System.err
    log4j.appender.grouper_stderr.layout = org.apache.log4j.PatternLayout
    log4j.appender.grouper_stderr.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n
    
    ## Grouper API error logging
    log4j.appender.grouper_error = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.grouper_error.File = /opt/grouper/logs/grouper.log
    log4j.appender.grouper_error.DatePattern = '.'yyyy-MM-dd
    log4j.appender.grouper_error.MaxBackupIndex = 30
    log4j.appender.grouper_error.layout = org.apache.log4j.PatternLayout
    log4j.appender.grouper_error.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n
    
    log4j.appender.grouper_daemon = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.grouper_daemon.File = /opt/grouper/logs/grouperDaemon.log
    log4j.appender.grouper_daemon.DatePattern = '.'yyyy-MM-dd
    log4j.appender.grouper_daemon.MaxBackupIndex = 30
    log4j.appender.grouper_daemon.layout = org.apache.log4j.PatternLayout
    log4j.appender.grouper_daemon.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n
    
    log4j.appender.grouper_pspng = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.grouper_pspng.File = /opt/grouper/logs/pspng.log
    log4j.appender.grouper_pspng.DatePattern = '.'yyyy-MM-dd
    log4j.appender.grouper_pspng.MaxBackupIndex = 30
    log4j.appender.grouper_pspng.layout = org.apache.log4j.PatternLayout
    log4j.appender.grouper_pspng.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n
    
    
    # Loggers
    
    ## Default logger; will log *everything*
    log4j.rootLogger = WARN, grouper_stderr, grouper_error
    
    log4j.logger.edu = ERROR, grouper_stderr
    log4j.logger.com = ERROR, grouper_stderr
    log4j.logger.org = ERROR, grouper_stderr
    
    log4j.logger.edu.internet2.middleware.grouper.app.loader.GrouperLoaderLog = DEBUG, grouper_daemon
    log4j.additivity.edu.internet2.middleware.grouper.app.loader.GrouperLoaderLog = false
    
    log4j.logger.edu.internet2.middleware.grouper.pspng = INFO, grouper_pspng
    log4j.additivity.edu.internet2.middleware.grouper.pspng = false
  16. (UI ONLY) Allow grouper db config from all (dev only)

    2.5 $ vi /opt/grouperContainer/slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes/grouper-ui.properties
    
    grouperUi.configurationEditor.sourceIpAddresses = 0.0.0.0/0
  17. Self-signed SSL (no need to do this anymore, this is now an env var instead)

    This is the old way:

    slashRoot $ mkdir -p /opt/grouperContainer/slashRoot/etc/httpd/conf.d
    slashRoot $ vi /opt/grouperContainer/slashRoot/etc/httpd/conf.d/ssl-enabled.conf
    
    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite          ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    SSLHonorCipherOrder     on
    SSLCompression          off
    # OCSP Stapling, only in httpd 2.3.3 and later
    SSLUseStapling          on
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off
    SSLStaplingCache        shmcb:/var/run/ocsp(128000)
    Listen 443 https
    <VirtualHost *:443>
      RewriteEngine on
      RewriteRule   "^/$"  "/grouper/"  [R]
      SSLEngine on
      #SSLCertificateChainFile /etc/pki/tls/certs/localhost.crt
      SSLCertificateFile /etc/pki/tls/certs/localhost.crt
      SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
      # HSTS (mod_headers is required) (15768000 seconds = 6 months)
      Header always set Strict-Transport-Security "max-age=15768000"
    </VirtualHost>
  18. Make a Dockerfile and subcontainer (optional, not needed)

    slashRoot $ vi /opt/grouperContainer/Dockerfile
    
    # this matches the version you decided on from release notes
    FROM i2incommon/grouper:2.5.XX
    
    
    
  19. Make container (optional, not needed)

    grouperContainer $ docker build -t my-grouper-2.5.XX .
    Sending build context to Docker daemon  216.1kB
    Step 1/2 : FROM i2incommon/grouper:2.5.XX
     ---> 04ced0374ad5
     ---> Running in 7bd1a51c3552
    Removing intermediate container 7bd1a51c3552
     ---> ff79b4b2afb9
    Successfully built ff79b4b2afb9
    Successfully tagged my-grouper-2.5.XX:latest

  20. Set the owner and permissions of the log dir

    At first, set it world writable
    [root@ip-172-30-3-152 logs]# chmod 777 /opt/grouperContainer/logs
  21. Start container init database, note if not creating new container with Dockerfile, just use the container label i2incommon/grouper:2.5.XX

    grouperContainer $ docker run --detach --mount type=bind,src=/opt/grouperContainer/logs,dst=/opt/grouper/logs \
    --mount type=bind,src=/opt/grouperContainer/slashRoot,dst=/opt/grouper/slashRoot --name grouper-daemon my-grouper-2.5.XX:latest daemon
    
    grouperContainer $ docker ps
    CONTAINER ID 		IMAGE 						COMMAND 					CREATED 			STATUS 				PORTS 							NAMES
    a63006217009        my-grouper-2.5.XX:latest   "/usr/local/bin/entr…"   11 minutes ago       Up 10 minutes       80/tcp, 443/tcp                grouper-daemon
    grouperContainer $ 
    
    
  22. Set the owner and permissions of the log dir

    after running container, see what user the docker container used to write logs to the host
    
    [root@ip-172-30-3-152 logs]# ls -latr
    total 0
    drwxr-xr-x. 4 root root 53 Apr 8 05:44 ..
    -rw-r-----. 1 polkitd systemd-coredump 0 Apr 8 05:56 grouper.log
    -rw-r-----. 1 polkitd systemd-coredump 0 Apr 8 05:56 grouperDaemon.log
    -rw-r-----. 1 polkitd systemd-coredump 0 Apr 8 05:56 pspng.log3. change the owner and permissions back
    
    [root@ip-172-30-3-152 logs]# chown polkitd.systemd-coredump .
    [root@ip-172-30-3-152 logs]# chmod 755 .
    [root@ip-172-30-3-152 logs]#
  23. Check logs if there is a problem.  Look for errors.  Shell into the container to troubleshoot

    grouperContainer $ docker logs grouper-daemon | grep -i error
    grouperContainer $ cat /opt/grouperContainer/logs/grouper.log
    
    
    grouperContainer $ docker exec -it grouper-daemon /bin/bash
    
    grouperContainer $ ps -ef | grep tomee
    
  24. Note: the database is initialized.  See the tables in the database




  25. If tables arent there, go in and run gsh

    grouperContainer $ docker exec -it grouper-daemon /bin/bash
    [root@0d9054515bed WEB-INF]# cd /opt/grouper/grouperWebapp/WEB-INF/bin/
    [root@0d9054515bed bin]# ./gsh.sh -registry -check -runscript
  26. (UI/WS/SCIM) Take out shib, adjust the proxy directives (this is now an env var)

    This is the old way


    slashRoot $ docker cp 058adff0568c:/etc/httpd/conf.d/grouper-www.conf /opt/grouperContainer/slashRoot/etc/httpd/conf.d/grouper-www.conf
    slashRoot $ vi /opt/grouperContainer/slashRoot/etc/httpd/conf.d/grouper-www.conf
    
    Timeout 2400
    ProxyTimeout 2400
    ProxyBadHeader Ignore
    
    ProxyPass /grouper ajp://localhost:8009/grouper  timeout=2400
    ProxyPass /grouper-ws ajp://localhost:8009/grouper  timeout=2400
    ProxyPass /grouper-ws-scim ajp://localhost:8009/grouper  timeout=2400
    
    RewriteEngine on
    RewriteCond %{REQUEST_URI} "^/$"
    RewriteRule . %{REQUEST_SCHEME}://%{HTTP_HOST}/grouper/ [R=301,L]
    
    #<Location /grouper>
    #  AuthType shibboleth
    #  ShibRequestSetting requireSession 1
    #  ShibRequireSession on
    #  ShibUseHeaders On
    #  require shibboleth
    #</Location>
    
    



  27. (UI ONLY) Run the container

    grouperContainer $ docker ps --all
    CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                                                   NAMES
    058adff0568c        my-grouper-2.5.XX:latest   "/usr/local/bin/entr…"   3 minutes ago       Up 3 minutes        80/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:8443->443/tcp   grouper-ui
    grouperContainer $ docker rm -f 058adff0568c
    058adff0568c
    
    grouperContainer $ docker run --detach --mount type=bind,src=/opt/grouperContainer/logs,dst=/opt/grouper/logs \
    --mount type=bind,src=/opt/grouperContainer/slashRoot,dst=/opt/grouper/slashRoot -e RUN_SHIB_SP='false' \
    -e SELF_SIGNED_CERT='true' --name grouper-ui --publish 443:443 my-grouper-2.5.XX:latest ui
    
    
    
  28. Shell in there

    2.5 $ docker exec -it grouper-ui /bin/bash
  29. (UI ONLY) Create a UI username and password

    cd /opt/grouper/grouperWebapp/WEB-INF/bin
    vi createUiPass.gsh
    
    grouperPasswordSave = new GrouperPasswordSave();
    grouperPasswordSave.assignUsername("GrouperSystem").assignPassword("****").assignEntityType("username");
    grouperPasswordSave.assignApplication(GrouperPassword.Application.UI);
    new Authentication().assignUserPassword(grouperPasswordSave);
    
    [root@d588628876f7 bin]# ./gsh.sh createUiPass.gsh 
    [root@d588628876f7 bin]# rm createUiPass.gsh 
    
    
  30. (UI ONLY) The Grouper UI should now be accessible at https://whatever.server.edu:8443/grouper and will prompt for credentials via basic auth.
  31. (WS/SCIM ONLY) Create a WS/SCIM username and password

    docker exec -it grouper-ui /bin/bash
    cd /opt/grouper/grouperWebapp/WEB-INF/bin
    vi createWsPass.gsh
    
    grouperPasswordSave = new GrouperPasswordSave();
    grouperPasswordSave.assignUsername("GrouperSystem").assignPassword("****").assignEntityType("username");
    grouperPasswordSave.assignApplication(GrouperPassword.Application.WS);
    new Authentication().assignUserPassword(grouperPasswordSave);
    
    [root@d588628876f7 bin]# ./gsh.sh createWsPass.gsh 
  32. (WS ONLY) Run the container

    Since the UI is on 443 on this same server, stop that.  (note you can change ports or run on different servers)
    2.5 $ docker stop grouper-ui
    2.5 $ docker run --detach --mount type=bind,src=/opt/grouperContainer/logs,dst=/opt/grouper/logs \
    --mount type=bind,src=/opt/grouperContainer/slashRoot,dst=/opt/grouper/slashRoot -e SELF_SIGNED_CERT='true' \
     --name grouper-ws --publish 443:443 my-grouper-2.5.XX:latest ws
  33. (SCIM ONLY) Run the container

    2.5 $ docker run --detach --mount type=bind,src=/opt/grouperContainer/logs,dst=/opt/grouper/logs \
    --mount type=bind,src=/opt/grouperContainer/slashRoot,dst=/opt/grouper/slashRoot -e SELF_SIGNED_CERT='true' \
    --name grouper-scim --publish 443:443 my-grouper-2.5.XX:latest scim
  34. (DAEMON ONLY) Run the daemon

    2.5 $ docker run --detach --mount type=bind,src=/opt/grouperContainer/logs,dst=/opt/grouper/logs \
    --mount type=bind,src=/opt/grouperContainer/slashRoot,dst=/opt/grouper/slashRoot --name grouper-daemon my-grouper-2.5.XX:latest daemon
    
    
  35. Want to use tomcat authn?  Here is an example with tomcat ldap authn.

    grouper.hibernate.properties configures which Grouper 2.5 built in basic authn, these should not be set or set to false

    [root@ip-172-30-3-152 grouperContainer]# more slashRoot/opt/grouper/grouperWebapp/WEB-INF/classes/grouper.hibernate.properties
    # skip the important stuff #
    
    # added by grouper-installer
    grouper.is.ui.basicAuthn = false
    
    # added by grouper-installer
    grouper.is.ws.basicAuthn = false
    
    



    web.xml: 

    [root@ip-172-30-3-152 grouperContainer]# more slashRoot/opt/grouper/grouperWebapp/WEB-INF/web.xml   (from host, inside container is /opt/grouper/slashRoot)
    
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
             version="2.4">
    
      <!-- FOR WS ONLY -->
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>Web services</web-resource-name>
          <url-pattern>/services/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <role-name>grouper_user</role-name>
        </auth-constraint>
      </security-constraint>
    
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>Web services</web-resource-name>
          <url-pattern>/servicesRest/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <!-- NOTE:  This role is not present in the default users file -->
          <role-name>grouper_user</role-name>
        </auth-constraint>
      </security-constraint>
      
      <!-- FOR UI ONLY -->  
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>UI</web-resource-name>
          <url-pattern>/grouperUi/app/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <role-name>grouper_user</role-name>
        </auth-constraint>
      </security-constraint>
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>UI</web-resource-name>
          <url-pattern>/grouperUi/appHtml/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <role-name>grouper_user</role-name>
        </auth-constraint>
      </security-constraint>
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>UI</web-resource-name>
          <url-pattern>/grouperExternal/app/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <role-name>grouper_user</role-name>
        </auth-constraint>
      </security-constraint>
      <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>Grouper Application</realm-name>
      </login-config>
    
      <!-- FOR BOTH -->
      <security-role>
        <description>
          The role that is required to log in to the Grouper UI
        </description>
        <role-name>grouper_user</role-name>
      </security-role>
      
    
    </web-app>


    tomcat server.xml has some settings too, copy from inside the container to outside, and adjust it a bit

    [root@ip-172-30-3-152 grouperContainer]# this is slashRoot/opt/tomee/conf/server.xml
    FROM:
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" tomcatAuthentication="false" ...
    TO:
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" tomcatAuthentication="true" ...Might need to add something like this in the right place:
    
    <Realm className="org.apache.catalina.realm.JNDIRealm"
    connectionURL="ldaps://ldap.ad.ufl.edu:636"
    connectionName="CN=something-grouper,OU=Grouper,OU=Service Accounts,OU=somead,DC=ad,DC=school,DC=edu"
    connectionPassword="XXXXX"
    userBase="OU=users,DC=ad,DC=ufl,DC=edu"
    userSubtree="true"
    userSearch="(userPrincipalName={0})"
    adCompat="true"
    allRolesMode="authOnly"
    />
    </Realm>
    
    
  36. df
  • No labels