1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
# Getting started with gssproxy
In this folder is detailed documentation on how gssproxy works internally
(Behavior, ProtocolDocumentation) as well as configuration walkthroughs for
specific services (Apache, NFS) and information on our releases
(ReleaseProcess, Releases).
This document attempts to cover how to use gssproxy with any simple,
well-behaved service, and explain in broad strokes what each step
accomplishes. All commands should be run as root.
## Background
The GSSAPI (Generic Security Services API) is a RFC-standardized interface for
applications that wish to use security libraries. Most commonly, GSSAPI is
used as an interface to Kerberos, though there are other mechanisms provided
as well (e.g., SPNEGO for Single-Sign On on the web; see the Apache docs in
this folder for more information on that).
When an application uses GSSAPI, typically it will have direct access to its
security credentials, and all cryptographic operations are performed in the
application's process. This is undesirable, but fortunately gssproxy can help
in almost all use cases! gssproxy provides privilege separation to
applications using the GSSAPI: the gssproxy daemon runs on the system, holds
the application's credentials, and performs operations on behalf of the
application.
This is completely transparent to the application. However, some
configuration is required, which we'll now go through.
## Configuring gssproxy
(For a detailed explanation of any of the options described in this section,
see the man page for gssproxy.conf (`man 5 gssproxy.conf`).)
gssproxy configuration typically lives in **/etc/gssproxy**. On most systems,
this directory will already contain a couple files, which can usually be
ignored (but will be explained briefly anyway).
- **gssproxy.conf** is the main gssproxy configuration file: options affecting
operation of the daemon itself live here (e.g., logging levels).
- **##-servicename.conf** are the service configuration files (where "##" is a
two-digit number; the files are loaded in numeric order by gssproxy).
We will be making one of the latter file for your application. Pick a useful
name for your service - it will be used in log files.
gssproxy configuration snippets are INI-style, so start with a service header:
`[service/my_app]`.
Then set the mechanisms we wish to allow: `mechs = krb5`.
If the application has any keytabs, tell gssproxy about them: `cred_store =
keytab:/etc/path/to.keytab`. Then change the user and group permissions on
the keytab so that the application can't read them (but gssproxy can): `chown
root:root /etc/path/to.keytab`.
The next step is to figure out what sets your application apart from others
that may be running on the system. gssproxy requires specifying a uid (`euid
= appuser`), but if it runs as root, that may not be enough.
Fortunately, gssproxy also allows executable name matching. This checks the
canonical, full path to an executable. Your program must be a native ELF (or
similar) - it cannot be an interpreted program (as that would allow all
programs running under the interpreter to access gssproxy as if they were
yours). This field is therefore optional.
(If that's still not enough to distinguish your application, don't worry -
just see the later section on using a custom socket.)
In the end, we would end up with a config file that looks a bit like this:
```INI
[service/my_app]
mechs = krb5
cred_store = keytab:/etc/path/to.keytab
euid = appuser
program = /usr/local/bin/my_app
```
And tell gssproxy to use the new configuration file: `systemctl
try-reload-or-restart gssproxy`
## Configuring the application
In order for the application to attempt to use gssproxy, it needs an
environment variable set: `GSS_USE_PROXY=yes`. (For more information on
environment variable configuration, see the man page for gssproxy-mech - `man
8 gssproxy-mech`.)
How this is configured will of course vary application to application.
If launching by hand from a shell, just prepend it to the invocation:
`GSS_USE_PROXY=yes my_app`.
If launching using sysvinit, you'll probably need to edit the invocation in
**/etc/init.d/my_app** (there may be a nicer way, but it's system-dependent).
If launching using systemd (these instructions assume Fedora), create a new
file at **/etc/systemd/system/my_app.service** and make it look like this:
```INI
.include /lib/systemd/system/my_app.service
[Service]
Environment=GSS_USE_PROXY=1
```
and then reload the systemd state: `systemctl daemon-reload`.
From there, (re)start your application and you're off to the races!
## Aside: using a custom socket
Normally, gssproxy traffic all runs over the same socket, which typically
lives in **/var/lib/gssproxy/default.sock**. However, gssproxy can listen on
many sockets, and can distinguish services this way. Using a custom socket
for your service is a two part configuration: configure the client, and
configure gssproxy.
To configure gssproxy, we need to tell the daemon to open another socket.
Pick a path (**/var/lib/gssproxy/my_app.sock** is good) and modify the service
configuration to use it: `socket = /var/lib/gssproxy/my_app.sock`. Then
reload gssproxy's configuration: `systemctl try-reload-or-restart gssproxy`.
To configure the client, we need to set another environment variable:
`GSSPROXY_SOCKET`. So, we set that in the same way we set `GSS_USE_PROXY`
(i.e., `GSSPROXY_SOCKET=/var/lib/gssproxy/my_app.sock`), and launch.
## How to know it's working
By far the easiest way to tell is to have a configuration working *without*
gssproxy, and then migrate to one *with* gssproxy. If the environment
variable is set in the process, and everything keeps working, then you know
everything is all set.
A similar thing is true of the keytabs: if the application can't read them,
but continues to function, then everything is working correctly.
That's not always possible, though. In that case, you can look at gssproxy's
logs to see connections from your service. First, set `debug_level = 1` in
**/etc/gssproxy/gssproxy.conf**, and then have gssproxy reload its
configuration (`systemctl reload gssproxy`). Then, in the gssproxy logs (for
systemd, this is `journalctl -xfu gssproxy`), you should see lines like:
may 08 12:48:52 freeipa.rharwood.biz gssproxy[27144]: [CID 13][2018/05/08 16:48:52]: gp_rpc_execute: executing 6 (GSSX_ACQUIRE_CRED) for service "ipa-httpd", euid: 48,socket: (null)
This happens to be taken from a user connecting to the webui on a freeipa
instance. It was preceeded at some point by a line announcing the conection.
This line says that it's executing a call to (something like)
`gss_acquire_cred()` on behalf of the "ipa-httpd" configured service, which is
uid 48 (i.e., apache), and that it's assigned ID 13 to this session.
|