New OOD install: shows me the Apache welcome screen. delete that conf, shows the autoindex. delete that, just get "/."

Hi there,

On Rocky 8, have followed all the instructions for CentOS 8 but when I try to navigate to the server it seems not to know where to go. Is there something I have to do to “enable” the OOD config?

Thanks.

Hello!

There shouldn’t be anything that you need to set or “enable”. The configs need to be in the /etc/ood/config location and have permissions set correctly in order to work at the most basic level.

After making your changes to the ood_portal.yml did you issue sudo /opt/ood/ood-portal-generator/sbin/update_ood_portal to generate the apache config?

When you say the server doesn’t know where to go, do you mean when you try to hit the web-node for login that you never hit the auth page or any page at all? I just want to make sure I am understanding where the routing problem is happening.

Is it possible to see the ood_portal.yml?

Yep.

Yes, exactly.

Sure:

---
servername: server.domain.tld
ssl: null
#  - 'SSLCertificateFile "/etc/pki/tls/certs/ServerCertificate.crt"'
#  - 'SSLCertificateKeyFile "/etc/pki/tls/private/ca.key"'
#  - 'SSLCertificateChainFile "/etc/pki/tls/certs/ChainBundle2.crt"'

#^-- I'm not sure what's going on with these certs/keys, but when I tried to use them originally I saw from Apache that the key and cert #didn't match, so I've turned off SSL for now.

#
# Portal configuration
#

# The address and port to listen for connections on
# Example:
#     listen_addr_port: 443
# Default: null (don't add any more listen directives)
#listen_addr_port: null

# The server name used for name-based Virtual Host
# Example:
#     servername: 'www.example.com'
# Default: null (don't use name-based Virtual Host)
#servername: null

# The server name used for rewrites
# Example:
#     proxy_server: 'proxy.example.com'
# Default: The value of servername
#proxy_server: null

# The port specification for the Virtual Host
# Example:
#     port: 8080
#Default: null (use default port 80 or 443 if SSL enabled)
#port: null

# List of SSL Apache directives
# Example:
#     ssl:
#       - 'SSLCertificateFile "/etc/pki/tls/certs/www.example.com.crt"'
#       - 'SSLCertificateKeyFile "/etc/pki/tls/private/www.example.com.key"'
# Default: null (no SSL support)
#ssl: null

# Root directory of log files (can be relative ServerRoot)
# Example:
#     logroot: '/path/to/my/logs'
# Default: 'logs' (this is relative to ServerRoot)
#logroot: 'logs'

# Error log filename
# Example:
#     errorlog: 'error.log'
# Default: 'error.log' (If 'servername' and 'ssl' options are defined 
# the default value will be <servername>_error_ssl.log)
#errorlog: 'error.log'

# Access log filename
# Example:
#     accesslog: 'access.log'
# Default: 'access.log' (If 'servername' and 'ssl' options are defined 
# the default value will be <servername>_access_ssl.log)
#accesslog: 'access.log'

# Apache access log format (Don't specify log nickname see: http://httpd.apache.org/docs/current/mod/mod_log_config.html#transferlog)
# Example:
#     logformat: '"%v %h \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %{SSL_PROTOCOL}x %T"'
# Default: Apache combined format

# Should RewriteEngine be used
# Example:
#     use_rewrites: false
# Default: true
#use_rewrites: true

# Should Maintenance Rewrite rules be added
# Example:
#   use_maintenance: false
# Default: true
#use_maintenance: true

# List of IPs to whitelist when maintenance is enabled
# Example:
#   maintenance_ip_whitelist:
#     - 192.168.0..*
#     - 192.168.1..*
# Default: [] (no IPs whitelisted)
#maintenance_ip_whitelist: []

# Set Header Content-Security-Policy frame-ancestors.
# Example:
#   security_csp_frame_ancestors: https://ondemand.osc.edu
# Example to disable setting:
#   security_csp_frame_ancestors: false
# Default: based on servername and ssl settings
#security_csp_frame_ancestors:

# Set Header Strict-Transport-Security to help enforce SSL
# Example:
#   security_strict_transport: false
# Default: true when ssl is enabled, false otherwise
#security_strict_transport: false

# Root directory of the Lua handler code
# Example:
#     lua_root: '/path/to/lua/handlers'
# Default : '/opt/ood/mod_ood_proxy/lib' (default install directory of mod_ood_proxy)
#lua_root: '/opt/ood/mod_ood_proxy/lib'

# Verbosity of the Lua module logging
# (see https://httpd.apache.org/docs/2.4/mod/core.html#loglevel)
# Example:
#     lua_log_level: 'warn'
# Default: 'info' (get verbose logs)
#lua_log_level: 'info'

# Lua regular expression used to map authenticated-user to system-user
# This configuration is ignored if user_map_cmd is defined
# Example:
#     user_map_match: '^([^@]+)@.*$'
# Default: '.*'
# user_map_match: '.*'

# System command used to map authenticated-user to system-user
# This option takes precedence over user_map_match
# Example:
#     user_map_cmd: '/usr/local/bin/ondemand-usermap'
# Default: null (use user_map_match)
#user_map_cmd: null

# Use an alternative CGI environment variable instead of REMOTE_USER for
# determining the authenticated-user fed to the mapping script
# Example:
#     user_env: 'OIDC_CLAIM_preferred_username'
# Default: null (use REMOTE_USER)
#user_env: null

# Redirect user to the following URI if fail to map there authenticated-user to
# a system-user
# Example:
#     map_fail_uri: '/register'
# Default: null (don't redirect, just display error message)
#map_fail_uri: null

# System command used to run the `nginx_stage` script with sudo privileges
# Example:
#     pun_stage_cmd: 'sudo /path/to/nginx_stage'
# Default: 'sudo /opt/ood/nginx_stage/sbin/nginx_stage' (don't forget sudo)
#pun_stage_cmd: 'sudo /opt/ood/nginx_stage/sbin/nginx_stage'

# List of Apache authentication directives
# NB: Be sure the appropriate Apache module is installed for this
# Default: (see below, uses OIDC auth with Dex)
#auth:
#  - 'AuthType openid-connect'
#  - 'Require valid-user'

# Redirect user to the following URI when accessing root URI
# Example:
#     root_uri: '/my_uri'
#     # https://www.example.com/ => https://www.example.com/my_uri
# Default: '/pun/sys/dashboard' (default location of the OOD Dashboard app)
#root_uri: '/pun/sys/dashboard'

# Track server-side analytics with a Google Analytics account and property
# (see https://github.com/OSC/mod_ood_proxy/blob/master/lib/analytics.lua for
# information on how to setup the GA property)
# Example:
#     analytics:
#       url: 'http://www.google-analytics.com/collect'
#       id: 'UA-79331310-4'
# Default: null (do not track)
#analytics: null

#
# Publicly available assets
#

# Public sub-uri (available to public with no authentication)
# Example:
#     public_uri: '/assets'
# Default: '/public'
#public_uri: '/public'

# Root directory that serves the public sub-uri (be careful, everything under
# here is open to the public)
# Example:
#     public_root: '/path/to/public/assets'
# Default: '/var/www/ood/public'
#public_root: '/var/www/ood/public'

#
# Logout redirect helper
#

# Logout sub-uri
# Example
#     logout_uri: '/log_me_out'
# NB: If you change this, then modify the Dashboard app with the new sub-uri
# Default: '/logout' (the Dashboard app is by default going to expect this)
#logout_uri: '/logout'

# Redirect user to the following URI when accessing logout URI
# Example:
#     logout_redirect: '/oidc?logout=https%3A%2F%2Fwww.example.com'
# Default: '/pun/sys/dashboard/logout' (the Dashboard app provides a simple
# HTML page explaining logout to the user)
#logout_redirect: '/pun/sys/dashboard/logout'

#
# Reverse proxy to backend nodes
#

# Regular expression used for whitelisting allowed hostnames of nodes
# Example:
#     host_regex: '[\w.-]+\.example\.com'
# Default: '[^/]+' (allow reverse proxying to all hosts, this allows external
# hosts as well)
#host_regex: '[^/]+'

# Sub-uri used to reverse proxy to backend web server running on node that
# knows the full URI path
# Example:
#     node_uri: '/node'
# Default: null (disable this feature)
#node_uri: null

# Sub-uri used to reverse proxy to backend web server running on node that
# ONLY uses *relative* URI paths
# Example:
#     rnode_uri: '/rnode'
# Default: null (disable this feature)
#rnode_uri: null

#
# Per-user NGINX Passenger apps
#

# Sub-uri used to control PUN processes
# Example:
#     nginx_uri: '/my_pun_controller'
# Default: '/nginx'
#nginx_uri: '/nginx'

# Sub-uri used to access the PUN processes
# Example:
#     pun_uri: '/my_pun_apps'
# Default: '/pun'
#pun_uri: '/pun'

# Root directory that contains the PUN Unix sockets that the proxy uses to
# connect to
# Example:
#     pun_socket_root: '/path/to/pun/sockets'
# Default: '/var/run/ondemand-nginx' (default location set in nginx_stage)
#pun_socket_root: '/var/run/ondemand-nginx'

# Number of times the proxy attempts to connect to the PUN Unix socket before
# giving up and displaying an error to the user
# Example:
#     pun_max_retries: 25
# Default: 5 (only try 5 times)
#pun_max_retries: 5

# The PUN pre hook command to execute as root
#
# Example:
#    pun_pre_hook_root_cmd: '/opt/hpc-site/ood_pun_prehook'
# Default: null (do not run any PUN pre hook as root)
#pun_pre_hook_root_cmd: null

# Comma separated list of environment variables to pass from the apache context
# into the PUN pre hook. Defaults to null so nothing is exported.
#
# Example:
#    pun_pre_hook_exports: 'OIDC_ACCESS_TOKEN,OIDC_CLAIM_EMAIL'
# Default: null (pass nothing)
#pun_pre_hook_exports: null

#
# Support for OpenID Connect
#

# Sub-uri used by mod_auth_openidc for authentication
# Example:
#     oidc_uri: '/oidc'
# Default: null (disable OpenID Connect support)
#oidc_uri: null

# Sub-uri user is redirected to if they are not authenticated. This is used to
# *discover* what ID provider the user will login through.
# Example:
#     oidc_discover_uri: '/discover'
# Default: null (disable support for discovering OpenID Connect IdP)
#oidc_discover_uri: null

# Root directory on the filesystem that serves the HTML code used to display
# the discovery page
# Example:
#     oidc_discover_root: '/var/www/ood/discover'
# Default: null (disable support for discovering OpenID Connect IdP)
#oidc_discover_root: null

#
# Support for registering unmapped users
#
# (Not necessary if using regular expressions for mapping users)
#

# Sub-uri user is redirected to if unable to map authenticated-user to
# system-user
# Example:
#     register_uri: '/register'
# Default: null (display error to user if mapping fails)
#register_uri: null

# Root directory on the filesystem that serves the HTML code used to register
# an unmapped user
# Example:
#     register_root: '/var/www/ood/register'
# Default: null (display error to user if mapping fails)
#register_root: null

# OIDC metadata URL
# Example:
#     oidc_provider_metadata_url: https://example.com:5554/.well-known/openid-configuration
# Default: null (value auto-generated if using Dex)
#oidc_provider_metadata_url: null

# OIDC client ID
# Example:
#     oidc_client_id: ondemand.example.com
# Default: null (value auto-generated if using Dex)
#oidc_client_id: null

# OIDC client secret
# Example:
#     oidc_client_secret: 334389048b872a533002b34d73f8c29fd09efc50
# Default: null (value auto-generated if using Dex)
#oidc_client_secret: null

# OIDC remote user claim. This is the claim that populates REMOTE_USER
# Example:
#     oidc_remote_user_claim: preferred_username
# Default: preferred_username
#oidc_remote_user_claim: preferred_username

# OIDC scopes
# Example:
#     oidc_scope: "openid profile email groups"
# Default: "openid profile email"
#oidc_scope: "openid profile email"

# OIDC session inactivity timeout
# Example:
#     oidc_session_inactivity_timeout: 28800
# Default: 28800
#oidc_session_inactivity_timeout: 28800

# OIDC session max duration
# Example:
#     oidc_session_max_duration: 28800
# Default: 28800
#oidc_session_max_duration: 28800

# OIDC max number of state cookies and if to automatically clean old cookies
# Example:
#     oidc_state_max_number_of_cookies: "10 true"
# Default: "10 true"
#oidc_state_max_number_of_cookies: "10 true"

# OIDC Enable SameSite cookie
# When ssl is defined this defaults to 'Off'
# When ssl is not defined this defaults to 'On'
# Example:
#     oidc_cookie_same_site: 'Off'
# Default: 'On'
#oidc_cookie_same_site: 'On'

# Additional OIDC settings as key-value pairs
# Example:
#     oidc_settings:
#       OIDCPassIDTokenAs: serialized
#       OIDCPassRefreshToken: On
# Default: {} (empty hash)

# Dex configurations, values inside the "dex" structure are directly used to configure Dex
# If the value for "dex" key is false or null, Dex support is disabled
# Dex support will auto-enable if ondemand-dex package is installed
#dex:
  # Default based on if ssl key for ood-portal-generator is defined
#  ssl: false
  # Only used if SSL is disabled
#  http_port: "5556"
  # Only used if SSL is enabled
#  https_port: "5554"
  # tls_cert and tls_key take OnDemand configured values for ssl and copy keys to /etc/ood/dex maintaining file names
#  tls_cert: null
#  tls_key: null
#  storage_file: /etc/ood/dex/dex.db
#  grpc: null
#  expiry: null
  # Client ID, defaults to servername or FQDN
#  client_id: null
#  client_name: OnDemand
  # Client secret, value auto generated
  # A value that is a filesystem path can be used to store secret in a file
#  client_secret: /etc/ood/dex/ondemand.secret
   # The OnDemand redirectURI is auto-generated, this option allows adding additional URIs
#  client_redirect_uris: []
  # Additional Dex OIDC clients to configure
#  static_clients: []
  # The following example is to configure OpenLDAP
  # Docs: https://github.com/dexidp/dex/blob/master/Documentation/connectors/ldap.md
#  connectors:
#    - type: ldap
#      id: ldap
#      name: LDAP
#      config:
#        host: openldap.my_center.edu:636
#        insecureSkipVerify: false
#        bindDN: cn=admin,dc=example,dc=org
#        bindPW: admin
#        userSearch:
#          baseDN: ou=People,dc=example,dc=org
#          filter: "(objectClass=posixAccount)"
#          username: uid
#          idAttr: uid
#          emailAttr: mail
#          nameAttr: gecos
#          preferredUsernameAttr: uid
#        groupSearch:
#          baseDN: ou=Groups,dc=example,dc=org
#          filter: "(objectClass=posixGroup)"
#          userMatchers:
#            - userAttr: DN
#              groupAttr: member
#          nameAttr: cn
#  frontend:
#    theme: ondemand
#    dir: /usr/share/ondemand-dex/web
dex:
  connectors:
    - type: ldap
      id: ldap
      name: LDAP
      config:
        host: myaddomaincontroller.domain.tld:636
        insecureSkipVerify: true
        bindDN: CN=serviceaccount,OU=ServiceAccounts,DC=domain,DC=tld
        bindPW: mybindpw
        userSearch:
          baseDN: ou=Users,dc=domain,dc=tld
          filter: "(objectClass=user)"
          username: sAMAccountName
          idAttr: sAMAccountNAme
          emailAttr: mail
          nameAttr: gecos
          preferredUsernameAttr: sAMAccountNAme
        groupSearch:
          baseDN: OU=Groups,DC=domain,DC=tld
          filter: "(objectClass=group)"
          userMatchers:
            - userAttr: sAMAccountName
              groupAttr: member
          nameAttr: sAMAccountName

Thanks for all the info. Can I see the actual URL you are hitting as well to see what port you are hitting?

It is https://server.domain.tld/.

I think https may be the problem since no ssl looks to be setup. What is the behavior if you do:

http://server.domain.tld/:80

It redirects to https.

Uncomment and add the following to the ood_portal.yml:

listen_addr_port: 8080
port: 8080

Issue the sudo /opt/ood/ood-portal-generator/sbin/update_ood_portal command and restarts of services as needed and then hit:

http://server.domain.tld/:8080

and see if that gets you to a login.

1 Like

So that got me a LOT further. (Although I’m still not quite sure how to make https work.)

Now when I log in I get this:

That is the correct gid for me in AD. (NB: it is pre-populated with uidNumber and gidNumber.) We are using realmd/SSSD to join machines like this one to the domain and I get a similar error at the command line when I log in – but I’m not using PAM or anything to authenticate, just the standard LDAP lookup with Dex. How can I figure out what’s going on here?

To get the https portion working you would need to add the needed paths to the certs under the ssl portion of the ood_portal.yml since right now they are commented out (going off the previuosly posted config).

You will also need to make sure to set listen_addr_port and port to 443 to listen on that port instead of the 8080 we set previously to get you to a login over http. Apply the update and that should get https to work.

For the LDAP issue I’m not quite sure what is happening, but something is not right at the SSSD layer. It doesn’t look like anything is wrong in the Dex portion of the config though.

@tdockendorf do you have any insight into this issue with realmd/SSSD?

The fact you get the error can't find group for leads me to believe group looks are broken with how you have SSSD setup. If you log into the OnDemand web node you should be able to do id $USERNAME so if you logged into Dex with foobar run id foobar and you should be populated with both user name, UID and group memberships with their GIDs. If you don’t have group names populated and just GIDs then you likely have some issue with either /etc/nsswitch.conf not doing group lookups through SSSD or you have SSSD not correctly pulling down group information. I personally don’t have much experience with SSSD and AD, I’ve only ever connected SSSD to either OpenLDAP or 389DS.

so I think I know what the problem is, but don’t know how to fix it.

In this environment, AD provides uidNumber and gidNumber attributes which are provided to SSSD for association with users. but while the uidNumbers are real, there literally are no groups that match the gidNumbers. they’re actually set to be the same, but no group is created in AD to accompany the number. does anyone know if you can filter that gidNumber attribute out so that OOD stops choking on it?

(or, I guess, create local groups that match the received gidNumber?)

AHA! 2.7. Creating User Private Groups Automatically Using SSSD Red Hat Enterprise Linux 7 | Red Hat Customer Portal

auto_private_groups = true in the [domain/{NETBIOS DOMAIN NAME}] section does the trick for creating local groups that match!

This is all set, so will open a new topic for a different problem, because of course one popped up. :wink: