8a - Configure Leaf with Apache¶
In general, Leaf works quite well when deployed with Apache. In this section, we'll:
- Deploy the Leaf API on the app server.
- Host the Leaf client using Apache on the web server.
Deploying the API as a Service¶
We'll start by deploying the Leaf API as a service using systemctl
.
Once built, the API service should be run with a service account that is not an administrative user
The API host firewall will need to allow inbound communication on the chosen port to the Apache web server
On the app server:
-
Create a nologin user account to isolate the service from the operating system, and give that account ownership over the API -related folders.
useradd -r api_svc_account mkdir /var/log/leaf/ chown api_svc_account /var/log/leaf/ chown -R api_svc_account /var/opt/leafapi/
-
Create a service file for the API instance. The
WorkingDirectory
must be the directory whereAPI.dll
resides./var/opt/leafapi/services/leaf_api.service
[Unit] Description=Leaf API Service [Service] EnvironmentFile=/var/opt/leafapi/services/leaf_api.service.conf User=api_svc_account Type=idle TimeoutStartSec=300 TimeoutStopSec=30 WorkingDirectory=/var/opt/leafapi/api/ ExecStart=/usr/bin/dotnet API.dll [Install] WantedBy=multi-user.target
-
Last, link your service file with
systemd
and make it aware of the service:# Create a symbolic link into the systemd directory ln -s /var/opt/leafapi/services/leaf_api.service /etc/systemd/system/leaf_api.service # Make the systemd aware of the service systemctl daemon-reload # Start the service systemctl start leaf_api.service
Hosting Leaf with Apache¶
Great, at this point the Leaf database and API should be up and running. The status of the Leaf API can be checked with this command:
```sh
systemctl status leaf_api.service
```
-
From the app server, copy the
/build
directory made in Step 5 - Build the Leaf UI to/data/www/
on the web server. This will copy the Leaf Client production files over for Apache to host. -
On the web server, define an
httpd.conf
file to host a single node in a Leaf deployment.Info
Each Leaf client webapp must be hosted at the top level of the
DocumentRoot
of an Apache VirtualHost. Multiple nodes could be hosted on a single Apache instance pointing at that sameDocumentRoot
, however each would need its own VirtualHost and unique DNS name defined (e.g., site1.leaf.school.edu, site2.leaf.school.edu).In the below example, the Shibboleth module is used to authenticate users via SAML2 and provide group membership to the app. If you want to define your own set of groups that limit access to the app via Apache (i.e. during pre-release or evaluation), you can define your own Apache groups via the AuthGroupFile directive and then require those groups.
httpd.conf
<VirtualHost *:443>
ServerName leaf.{subdomain}.{domain}.{tld}
ServerAlias leaf
DocumentRoot /data/www/build
HostnameLookups Off
ErrorLog logs/leaf_ssl_error_log
CustomLog logs/leaf_ssl_access_log combinedio
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite HIGH:!aNULL:!MD5:!AECDH:!ADH
SSLCertificateFile /etc/pki/tls/certs/{leaf-cert}.cert
SSLCertificateKeyFile /etc/pki/tls/private/{leaf-key}.key
SSLCertificateChainFile /etc/pki/tls/certs/{cert-chain}.cert
SetEnvIf User-Agent ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
<Files *.sso>
SetHandler shib-handler
</Files>
<Location />
<RequireAny>
# Optional subnet restriction
Require ip {restricted-subnet}
# Authentication provider Setup
AuthType shibboleth
ShibRequireSession On
ShibUseHeaders On
Require shibboleth
# optional users restriction, although this only determines access to the app, not a user's underlying authorization within the app
# cat /data/leaf/users.conf --> leafusers: eppns...
AuthGroupFile /data/leaf/users.conf
require group leafusers
</RequireAny>
</Location>
# API proxy directive, overall api doesn't require user session
<Location /api>
ProxyPass http://{node1-ip}:{node1-port}/api
ProxyPassReverse http://{node1-ip}:{node1-port}/api
<RequireAny>
AuthType shibboleth
ShibRequireSession Off
Require shibboleth
</RequireAny>
</Location>
# /api/user does require user session
<Location /api/user>
<RequireAny>
AuthType shibboleth
ShibRequireSession On
Require shibboleth
</RequireAny>
</Location>
</VirtualHost>
SELinux and Apache¶
If you have SELinux enabled on your system, you need to be aware of an additional set of controls specifically related to running Apache.
By default with SELinux enabled httpd connections to other apps not located on localhost are regulated. If your API server is located on another host you will need to enable httpd to make outbound connections.
To enable httpd connections to non-standard ports:
$ setsebool -P httpd_can_network_connect on
Depending on which ports you use for your API service you may need enable other booleans (ie httpd_can_network_connect_db, httpd_use_openstack). To see the complete list of variables on your system and their present status:
$ getsebool -a | grep httpd
If you decide to use non-standard directory to host your webapp you will also need to re-label the files in that directory so that httpd can properly access the webapp files. Using the location in the example above:
$ semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
$ restorecon -R -v /data/www