10.5. Configure the Dashboard

10.5.1. Configure Connections and Logging

Before users connect to the dashboard for the first time, the following must be configured in the /etc/openstack-dashboard/local_settings file (sample files are available in the Configuration Reference Guide at https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux_OpenStack_Platform):

Note

Update the following changes as a root user.
  1. Allowed hosts - Set the ALLOWED_HOSTS parameter with a comma-seperated list of host/domain names that the application can serve. For example:
    ALLOWED_HOSTS = ['horizon.example.com', 'localhost', '192.168.20.254', ]
  2. Cache Backend - As the root user, update the CACHES settings with the memcached values:
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    CACHES = {
    	'default': {
    		'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache',
    		'LOCATION' : 'memcacheURL:port',
    	}
    }
    
    Where:
    • memcacheURL is the host on which memcache was installed
    • port is the value from the PORT parameter in the /etc/sysconfig/memcached file.
  3. Dashboard Host - Specify the host URL for your OpenStack Identity service endpoint. For example:
    OPENSTACK_KEYSTONE_URL="127.0.0.1"
  4. Time Zone - To change the dashboard's timezone, update the following (the time zone can also be changed using the dashboard GUI):
    TIME_ZONE="UTC"
  5. To ensure the configuration changes take effect, restart the Apache web server.

Note

The HORIZON_CONFIG dictionary contains all the settings for the Dashboard. Whether or not a service is in the Dashboard depends on the Service Catalog configuration in the Identity service. For a full listing, refer to http://docs.openstack.org/developer/horizon/topics/settings.html (Horizon Settings and Configuration).

Note

It is recommended that you use django-secure module to ensure that most of the best practices and modern browser protection mechanisms are enabled. For more infomation http://django-secure.readthedocs.org/en/latest/ (django-secure).

10.5.2. Configure the Dashboard to Use HTTPS

Although the default installation uses a non-encrypted channel (HTTP), it is possible to enable SSL support for the OpenStack Dashboard. Use the following steps for enable HTTPS (switch out the example domain 'openstack.example.com' for that of your current setup):
  1. Edit the /etc/openstack-dashboard/local_settings file, and uncomment the following parameters:
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
    CSRF_COOKIE_SECURE = True
    SESSION_COOKIE_SECURE = True
    The latter two settings instruct the browser to only send dashboard cookies over HTTPS connections, ensuring that sessions will not work over HTTP.
  2. Edit the /etc/httpd/conf/httpd.conf file, and add the following line:
    NameVirtualHost *:443
  3. Edit the /etc/httpd/conf.d/openstack-dashboard.conf file, and replace the 'Before' section with 'After':
    Before:
    WSGIDaemonProcess dashboard
    WSGIProcessGroup dashboard
    WSGISocketPrefix run/wsgi
    
    WSGIScriptAlias /dashboard /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
    Alias /static /usr/share/openstack-dashboard/static/
    
    <Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
        <IfModule mod_deflate.c>
          SetOutputFilter DEFLATE
          <IfModule mod_headers.c>
            # Make sure proxies don’t deliver the wrong content
            Header append Vary User-Agent env=!dont-vary
          </IfModule>
        </IfModule>
    
      Order allow,deny
      Allow from all
    /Directory>
    
    <Directory /usr/share/openstack-dashboard/static>
      <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresDefault "access 6 month"
      </IfModule>
      <IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
      </IfModule>
    
      Order allow,deny
      Allow from all
    </Directory>
    
    RedirectMatch permanent ^/$ https://xxx.xxx.xxx.xxx:443/dashboard
    
    After:
    WSGIDaemonProcess dashboard
    WSGIProcessGroup dashboard
    WSGISocketPrefix run/wsgi
    LoadModule ssl_module modules/mod_ssl.so
    
    <VirtualHost *:80>
      ServerName openstack.example.com
      RedirectPermanent / https://openstack.example.com/
    </VirtualHost>
                          
    <VirtualHost *:443>
        ServerName openstack.example.com
        SSLEngine On
        SSLCertificateFile /etc/httpd/SSL/openstack.example.com.crt
        SSLCACertificateFile /etc/httpd/SSL/openstack.example.com.crt
        SSLCertificateKeyFile /etc/httpd/SSL/openstack.example.com.key
        SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
        WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
        WSGIDaemonProcess horizon user=apache group=apache processes=3 threads=10
        RedirectPermanent /dashboard https://openstack.example.com
        Alias /static /usr/share/openstack-dashboard/static/
        <Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
          Order allow,deny
          Allow from all
        </Directory>
    </VirtualHost>
    
    <Directory /usr/share/openstack-dashboard/static>
      <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresDefault "access 6 month"
      </IfModule>
      <IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
      </IfModule>
    
      Order allow,deny
      Allow from all
    </Directory>
    
    RedirectMatch permanent ^/$ /dashboard/
    
    In the 'After' configuration, Apache listens on port 443 and redirects all non-secured requests to the HTTPs protocol. The <VirtualHost *:443> section defines the required options for this protocol, including private key, public key, and certificates.
  4. As the root user, restart Apache and memcached:
    # service httpd restart
    # service memcached restart
    When using the HTTP version of the dashboard (through the browser), the user should be redirected to the HTTPs version of the page.

10.5.3. Change Dashboard's default role

By default, the Dashboard service uses the Identity role named _member_ which is created automatically by Identity. This is adequate for regular users.
If you choose to create a different role and wish to set Dashboard to use this role, you must create this role in the Identity service prior to using the Dashboard, then configure Dashboard to use it.
  1. Log in to the system on which your keystonerc_admin file resides and authenticate as the Identity administrator:
    # source ~/keystonerc_admin
  2. Use the keystone role-create command to create the new role:
    # keystone role-create --name NEW_ROLE
    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    | id       | 8261ac4eabcc4da4b01610dbad6c038a |
    | name     |              NEW_ROLE              |
    +----------+----------------------------------+
    Replace NEW_ROLE with the name that you wish to give to the role.
  3. To configure the Dashboard service to use a role other than the default _member_ role, change the value of the OPENSTACK_KEYSTONE_DEFAULT_ROLE configuration key, which is stored in:
    /etc/openstack-dashboard/local_settings
  4. Restart the httpd service for the change to take effect.

10.5.4. Configure SELinux

SELinux is a security feature of Red Hat Enterprise Linux, which provides access control. Possible status values are Enforcing, Permissive, and Disabled. If SELinux is configured in 'Enforcing' mode, you must modify the SELinux policy to allow connections from the httpd service to the Identity server. This is also recommended if SELinux is configured in 'Permissive' mode.
  1. Use the getenforce command to check the status of SELinux on the system:
    # getenforce
  2. If the resulting value is 'Enforcing' or 'Permissive', use the setsebool command as the root user to allow httpd-Identity service connections:
    # setsebool -P httpd_can_network_connect on

Note

You can also view the status of SELinux using:
# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   permissive
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted
For more information, refer to the Red Hat Enterprise Linux SELinux Users and Administrators Guide at the following link:

10.5.5. Configure the Dashboard Firewall

To allow users to connect to the dashboard, you must configure the system firewall to allow connections. The httpd service, and the dashboard, support both HTTP and HTTPS connections.

Note

To protect authentication credentials and other data, it is highly recommended that you only enable HTTPS connections.
Execute the following as the root user:

Procedure 10.1. Configuring the firewall to allow Dashboard traffic (for Red Hat Enterprise Linux 6-based systems)

  1. Edit the /etc/sysconfig/iptables configuration file:
    • Allow incoming connections using just HTTPS by adding this firewall rule to the file:
      -A INPUT -p tcp --dport 443 -j ACCEPT
    • Allow incoming connections using both HTTP and HTTPS by adding this firewall rule to the file:
      -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
  2. Restart the iptables service for the changes to take effect.
    # service iptables restart

Procedure 10.2. Configuring the firewall to allow Dashboard traffic (for Red Hat Enterprise Linux 7-based systems)

  1. Allow incoming connections using just HTTPS by adding this firewall rule:
    # firewall-cmd --permanent --add-port=443/tcp
    Allow incoming connections using both HTTP and HTTPS by adding these firewall rules:
    # firewall-cmd --permanent --add-port=80/tcp
    # firewall-cmd --permanent --add-port=443/tcp
  2. For the change to take immediate effect, add the rules to the runtime mode:
    # firewall-cmd --add-port=80/tcp
    # firewall-cmd --add-port=443/tcp

Important

These rules allow communication from all remote hosts to the system running the Dashboard service on ports 80 or 443. For information regarding the creation of more restrictive firewall rules, refer to the Red Hat Enterprise Linux Security Guide at the following link:

10.5.6. Session Storage Options

10.5.6.1. Configure Local Memory Cache Session Storage

Local memory storage is the quickest and easiest session backend to set up, because it has no external dependencies. However, it does have two significant drawbacks:
  • No shared storage across processes or workers.
  • No persistence after a process terminates.
The local memory backend is enabled as the default for the Dashboard service solely because it has no dependencies. However, it is not recommended for production use, or even for serious development work.
To use local memory for storage, include the following in the /etc/openstack-dashboard/local_settings file:
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
CACHES = {
     'default': {
          'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
     }
}

10.5.6.2. Configure Memcached Session Storage

External caching using an application such as memcached offers persistence and shared storage, and can be very useful for small-scale deployment and/or development. The Dashboard installation process in this guide recommends the use of memcached for external caching (for configuration details, refer to Configuring Connections and Logging).
However, for distributed and high-availability scenarios, memcached has inherent problems which are beyond the scope of this documentation. Memcached is an extremely fast and efficient cache backend for cases where it fits the deployment need, but it’s not appropriate for all scenarios.

10.5.6.3. Configure Database Session Storage

Database-backed sessions are scalable (using an appropriate database strategy), persistent, and can be made high-concurrency and highly-available. The downside to this approach is that database-backed sessions are one of the slower session storages, and incur a high overhead under heavy usage. Proper configuration of your database deployment can also be a substantial undertaking and is far beyond the scope of this documentation.
To enable database session storage, follow the below steps as the root user to initialize the database and configure it for use:
  1. Start the MariaDB command-line client, by executing:
    # mysql -u root -p
  2. Specify the MariaDB root user's password when prompted.
  3. Create the dash database:
    mysql> CREATE DATABASE dash;
  4. Create a MariaDB user for the newly-created dash database who has full control of the database.
    mysql> GRANT ALL ON dash.* TO 'dash'@'%' IDENTIFIED BY 'PASSWORD';
    mysql> GRANT ALL ON dash.* TO 'dash'@'localhost' IDENTIFIED BY 'PASSWORD';
    Replace PASSWORD with a secure password for the new database user to authenticate with.
  5. Enter quit at the mysql> prompt to exit the MariaDB client.
  6. In the /etc/openstack-dashboard/local_settings file, change the following options to refer to the new MariaDB database:
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
    DATABASES = {
    	'default': {
    		# Database configuration here
    		'ENGINE': 'django.db.backends.mysql',
    		'NAME': 'dash',
    		'USER': 'dash',
    		'PASSWORD': 'PASSWORD',
    		'HOST': 'HOST',
    		'default-character-set': 'utf8'
    	}
    }
    Replace PASSWORD with the password of the dash database user and replace HOST with the IP address or fully qualified domain name of the database server.
  7. Populate the new database by executing:
    # cd /usr/share/openstack-dashboard
    # python manage.py syncdb
    Note: You will be asked to create an admin account; this is not required.
    As a result, the following should be displayed:
    Installing custom SQL ...
    Installing indexes ...
    DEBUG:django.db.backends:(0.008) CREATE INDEX `django_session_c25c2c28` ON
    `django_session` (`expire_date`);; args=()
    No fixtures found.
  8. Restart Apache to pick up the default site and symbolic link settings:
    # service httpd restart
  9. Restart the openstack-nova-api service to ensure the API server can connect to the Dashboard and to avoid an error displayed in the Dashboard.
    # service openstack-nova-api restart

10.5.6.4. Configure Cached Database Session Storage

To mitigate the performance issues of database queries, Django’s cached_db session backend can be used, which utilizes both the database and caching infrastructure to perform write-through caching and efficient retrieval.
Enable this hybrid setting by configuring both your database and cache as discussed above and then using:
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"

10.5.6.5. Configure Cookies Session Storage

The cookies-session backend avoids server load and scaling problems because it stores session data in a cookie, which is stored by the user’s browser. The backend uses a cryptographic signing technique, together with the SECRET_KEY, to ensure session data is not tampered with during transport (this is not the same as encryption, session data is still readable by an attacker).
  • Advantages:
    • Does not require additional dependencies or infrastructure overhead.
    • Scales indefinitely as long as the quantity of session data being stored fits into a normal cookie.
  • Disadvantages:
    • Places session data into storage on the user’s machine and transports it over the wire.
    • Limits the quantity of session data which can be stored.

Note

For a thorough discussion of the security implications of this session backend, please read the Django documentation on cookie-based sessions:
To enable cookie-session storage:
  1. In the /etc/openstack-dashboard/local_settings file, set:
    SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
  2. Add a randomly-generated SECRET_KEY to the project by executing on the command line:
    $django-admin.py startproject

    Note

    The SECRET_KEY is a text string, which can be specified manually or automatically generated (as in this procedure). You will just need to ensure that the key is unique (that is, does not match any other password on the machine).