Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it easier to set up Apache httpd as a proxied service and a proxied NFS client #40

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 38 additions & 7 deletions docs/Apache.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# Using GSS-Proxy for Apache httpd operation

The traditional approach for performing Kerberos authentication in Apache 2.* is to use the mod_auth_gssapi (historically, mod_auth_kerb would have been used) module. When using this module, the Apache process must have read access to a keytab (configured with the ```GssapiCredStore``` option, or the default ```/etc/krb5.keytab```) containing keys for the HTTP service. This is not optimal from a security point of view as all websites can potentially get access to the key material. GSS-Proxy allows to implement privilege separation for the Apache httpd server by removing access to the keytab while preserving Kerberos authentication functionality.
The traditional approach for performing Kerberos authentication in Apache 2.* is to use the mod_auth_gssapi (historically, mod_auth_kerb would have been used) module. When using this module, the Apache process must have read access to a keytab (configured with the ```GssapiCredStore``` option, or the default ```/etc/krb5.keytab```). This is not optimal from a security point of view as all websites can potentially get access to the key material. GSS-Proxy allows you to implement privilege separation for the Apache httpd server by removing access to the keytab(s) while preserving Kerberos authentication functionality.

This page describes a setup which works starting with Fedora 21 with
gssproxy-0.4.1-1.fc21.x86_64, httpd-2.4.16-1.fc21.x86_64, and
mod_auth_gssapi-1.3.0-2.fc21.x86_64. It works on similar versions of RHEL as
well.
well. It describes two concurrent goals that can be implemented together or independently.

Goals:
1. authenticate web clients to the httpd service
1. authenticate the ```apache``` user (running the httpd process) to access and serve network filesystem content mounted with Kerberos, e.g., NFS using ```sec=krb5``` (in some form)

## Setting up GSS-Proxy

The proxy will need access to the HTTP/server-name@realm's keytab. When using IPA server, command
For the first goal, the proxy will require a keytab for the service principal (HTTP/server-name@REALM). When using IPA server, command

```
# ipa service-add HTTP/server-name
Expand All @@ -21,7 +25,7 @@ will create the service principal. On an IPA-enrolled client machine, the
# ipa-getkeytab -s $(awk '/^server =/ {print $3}' /etc/ipa/default.conf) -k /etc/gssproxy/http.keytab -p HTTP/$(hostname -f)
```

will retrieve the keytab for the principal. In the following configuration snippet we assume it is stored in ```/etc/gssproxy/http.keytab```. The permissions are set to 400, owner root. The Apache user does not have access to the keytab.
will retrieve the keytab for the principal. In the following configuration snippets we assume it is stored in ```/etc/gssproxy/http.keytab```. The permissions are set to 400, owner root. The Apache user does not have access to the keytab.

We need to know the Apache user numerical id to put it in the configuration
file, because GSS-Proxy uses the effective uid to distinguish the services. On
Expand All @@ -31,7 +35,22 @@ my installation, the uid is 48. Symbolic uids are also supported (e.g.,
We add a new section to the gssproxy configuration. To do this, copy the
```examples/80-httpd.conf``` file to ```/etc/gssproxy/80-httpd.conf```. (If
you are using a monolithic config file at ```/etc/gssproxy/gssproxy.conf```,
make sure the HTTP stanza preceeds any ```allow_any_uid=yes``` sections.)
make sure the HTTP stanza precedes any ```allow_any_uid=yes``` sections.)

For the second goal, the proxy will require a keytab for the user principal (apache@REALM). Again, the uid used here is 48, but it must match whatever httpd is running as.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So while this is a valid choice, it is not required. It is as well possible to simply map the HTTP/fqdn principal to an "apache" user on the server for example.
So I think we should rephrase this bit something like "a principal that maps to the correct user on the server", then you can make an example using apache@REALM...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"NFS Server"


```
# ipa user-add apache --uid 48 --gidnumber 48 --homedir /usr/share/httpd --shell /sbin/nologin --first Apache --last 'web server'
```

This keytab is retrieved much like above, but the destination is different to match the following config snippet. Again, it's important that the Apache user does not have access to this keytab either.

```
# ipa-getkeytab -s $(awk '/^server =/ {print $3}' /etc/ipa/default.conf) -k /var/lib/gssproxy/clients/48.keytab -p apache/$(awk '/^realm =/ {print $3}' /etc/ipa/default.conf)
```

We now need one more gssproxy configuration section. Copy ```examples/99-network-fs-clients.conf``` to ```/etc/gssproxy/99-network-fs-clients.conf``` (preferred) or add to the monolithic config file.


We then start the service:

Expand All @@ -42,7 +61,7 @@ We then start the service:

## Setting up Apache

For Apache, we need to know the location or directory that we want to protect. For testing purposes, we can create a simple file
For this first goal (described above), we need to know the location or directory that we want to protect. For testing purposes, we can create a simple file

```
# echo OK > /var/www/html/private
Expand All @@ -58,7 +77,7 @@ and configure mod_auth_gssapi to protect that location:
</Location>
```

in some ```/etc/httpd/conf.d/*.conf``` file. Note that the path to the keytab is not configured here since it will not be needed -- communication with GSS-Proxy via ```/var/lib/gssproxy/default.sock``` will be used instead.
in some ```/etc/httpd/conf.d/*.conf``` file. Note that no keytab is configured here since direct access is not needed or wanted -- instead the keytab(s) are accessed indirectly by communication with GSS-Proxy via ```/var/lib/gssproxy/default.sock```.

Furthermore, we need to tell the libraries to use the GSS-Proxy - create ```/etc/systemd/system/httpd.service``` with content

Expand All @@ -74,6 +93,18 @@ Reload the configuration:
systemctl daemon-reload
```

The second goal may get rather specific to while the networked file system is needed and how it is used, but a trivial example would be to let Apache just provide a file index and serve everything in a given directory.

~~~
<Directory "/srv/www/pub/">
Options Indexes MultiViews
Require all granted
</Directory>
~~~

Note that there is no GSSAPI configuration here. The gssproxy configuration above sufficiently authenticates the apache user principal as a file system client. You might however add the GSSAPI settings similiar to above if you *also* wanted to authenticate the web clients trying to acess this directory.


When we now (re)start the Apache service

```
Expand Down
3 changes: 2 additions & 1 deletion examples/80-httpd.conf.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[service/HTTP]
mechs = krb5
cred_store = keytab:/etc/gssproxy/http.keytab
cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_%U
cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_http_%U
euid = apache
program = /usr/sbin/httpd
2 changes: 1 addition & 1 deletion examples/99-network-fs-clients.conf.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[service/network-fs-clients]
mechs = krb5
cred_store = keytab:/etc/krb5.keytab
cred_store = ccache:FILE:@gpclidir@/krb5cc_%U
cred_store = ccache:FILE:@gpclidir@/krb5cc_fs_%U
cred_store = client_keytab:@gpclidir@/%U.keytab
cred_usage = initiate
allow_any_uid = yes
Expand Down