Implementing and using gssproxy, example guide on how to use it to authenticate ssh, samba, nfs with no password via kerberos protocol
GSS-Proxy is a daemon that safely performs GSSAPI (Kerberos) operations on behalf of other processes. It’s useful when services running as unprivileged users need to accept or initiate Kerberos GSSAPI authentication but shouldn’t hold or access long‑lived keys (keytabs) or raw credentials themselves. Typical users: OpenSSH, SSSD, Samba, NFS idmap, and custom daemons.
This article walks through what gssproxy does, how it works, how to install and configure it, example integrations (sshd and an unprivileged service), testing, debugging and common pitfalls.
1. What gssproxy does (quick conceptual summary)
- Runs as a privileged system daemon (typically root) and holds access to keytabs or system credentials.
- Exposes a local IPC (Unix socket) and controlled API so allowed clients can ask it to perform GSSAPI accept/init operations on their behalf.
- Enforces access controls by client PID/user and by named service configuration (you map a client identity to the allowed service name and keytab).
- Minimizes the need to distribute keytabs or give services direct access to Kerberos credentials.
2. Installation
On many modern Linux distributions (Fedora, RHEL/CentOS, Debian/Ubuntu) gssproxy is packaged.
Example (RHEL/Fedora/CentOS):
# RHEL/CentOS 7/8/9 (dnf or yum)
sudo dnf install gssproxy
# or
sudo yum install gssproxy
Example (Debian/Ubuntu):
sudo apt update
sudo apt install gssproxy
If you must build from source:
# get source, then typical autotools or meson/ninja workflow per upstream README
./configure
make
sudo make install
After install, systemd unit gssproxy.service should be available.
3. Main configuration concepts
The main config file is usually /etc/gssproxy/gssproxy.conf. It consists of mechs (mechanisms), services, clients, and possibly mappings. Key elements:
- mech: declares a GSSAPI mechanism (e.g., krb5) and default keytab(s) for acceptor credentials.
- service: logical service names (e.g., ssh, nfs, httpd) with attributes: user (the Unix user running the service), keytab, cred_store, mechs, and whether the service is allowed to be client (initiate) and/or server (accept).
- client: rules mapping local client sockets / users / pids to allowed services.
A minimal working example that allows sshd to use gssproxy:
mechs = {
krb5_mech = {
mech = krb5;
default_keytab = /etc/krb5.keytab;
};
};
services = {
ssh = {
mech = krb5_mech;
user = "sshd";
keytab = /etc/krb5.keytab;
# allow both acceptor (server) and initiator (client) ops if needed
client = yes;
server = yes;
};
};
Client rules are often implicit: gssproxy can enforce that calls on a given service socket originate from the configured Unix user. For more complex setups you add policy and client blocks. Example to allow a specific PID or user to use the ssh service:
clients = {
ssh_clients = {
clients = [
{ match = "uid:0" }, # root can ask for ssh service
{ match = "user:sshd" }, # or the sshd user
];
service = "ssh";
};
};
Paths and sockets: gssproxy listens on a socket (e.g. /var/run/gssproxy/socket) and possibly per-user sockets (e.g. /run/gssproxy/uid_1000). The systemd unit usually creates the runtime directory with correct permissions.
4. Example: Integrate with OpenSSH server (sshd)
Goal: allow sshd and session processes to accept delegated GSS credentials and let unprivileged child processes use those credentials via gssproxy.
Server side config
- Ensure sshd is built/installed with GSSAPI support. On SSH server:
- In /etc/ssh/sshd_config:
- GSSAPIAuthentication yes
- GSSAPICleanupCredentials yes
- GSSAPIKeyExchange yes # optional: if you want GSS key exchange
- Configure gssproxy with an ssh service entry pointing to the host keytab (so gssproxy can accept SPNEGO/kerberos accept_sec_context calls):
mechs = {
krb5 = {
mech = krb5;
default_keytab = /etc/krb5.keytab;
};
};
services = {
ssh = {
mech = krb5;
user = "sshd";
keytab = /etc/krb5.keytab;
server = yes;
client = yes;
};
};
- Ensure /etc/krb5.keytab contains the host principal host/fqdn@REALM (or host/short@REALM depending on SPN strategy). Use ktutil or kadmin to create/populate.
- Restart gssproxy and sshd:
sudo systemctl restart gssproxy
sudo systemctl restart sshd
Client side
- ssh client configuration (usually ~/.ssh/config or /etc/ssh/ssh_config):
Host myhost.example.com
GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes
Client must have a TGT in the credential cache (kinit user), or use a client that acquires one.
Result
When the client initiates GSSAPI authentication and delegates credentials (GSSAPIDelegateCredentials yes or -K for older OpenSSH), gssproxy on the server handles acceptor functions. If a session process needs to use the delegated credentials (e.g., to access network resources as that user), gssproxy arranges a per-session credential store that unprivileged processes can use via the kernel keyring or other mechanisms gssproxy supports.
5. Example: Allow an unprivileged service to acquire initiator creds via gssproxy
Suppose a service mydaemon runs as myuser and needs to initiate Kerberos-authenticated connections using a specific service principal stored in /etc/mydaemon.keytab but you don’t want to expose that keytab to myuser.
Add a mech and service:
mechs = {
krb5 = {
mech = krb5;
default_keytab = /etc/krb5.keytab;
};
mydaemon_mech = {
mech = krb5;
default_keytab = /etc/mydaemon.keytab;
};
};
services = {
mydaemon = {
mech = mydaemon_mech;
user = "myuser";
keytab = /etc/mydaemon.keytab;
client = yes; # allow initiator operations
server = no;
};
};
Configure a client mapping so the mydaemon process (uid myuser) is allowed to use the mydaemon service. Once gssproxy runs, mydaemon uses the gssapi libraries (GSSAPI libs detect gssproxy via environment or library probe) and calls the GSSAPI functions; gssproxy will perform gss_acquire_cred using /etc/mydaemon.keytab and return a handle to the calling process. The service itself never directly reads the keytab.
6. Testing and tools
- kinit / klist: manage and list Kerberos TGTs on clients.
- journalctl -u gssproxy -f (or systemctl status gssproxy) to watch logs.
- ss -l or ls -l /run/gssproxy to inspect sockets.
- If you have gssproxy command-line utilities installed (may vary by distro), some installations include gssproxy CLI helpers. Otherwise use the service that relies on gssproxy and watch logs.
Example basic tests:
- Ensure gssproxy is running:
sudo systemctl status gssproxy
- On server, check socket and permissions:
sudo ls -l /run/gssproxy
# or
sudo ss -x -a | grep gssproxy
- Attempt SSH from a client with a TGT:
kinit alice
ssh -o GSSAPIDelegateCredentials=yes alice@server.example.com
# then on server, check journalctl logs for gssproxy/sshd messages
7. Debugging tips
- Journal logs: journalctl -u gssproxy -xe will be your first stop.
- Permissions: Ensure that gssproxy can read the keytab(s) (typically root-owned with restrictive perms). In config you may point to a keytab readable only by gssproxy.
- Clients blocked: If a client is denied, check the clients block and match rules (uid/pid/user).
- Keytab issues: Use klist -k /etc/krb5.keytab to list principals in a keytab. Ensure correct SPN and realm.
- Clock skew: Kerberos is time-sensitive. Ensure NTP/chrony is working.
- DNS / SPNs: Ensure hostnames and reverse DNS match the principal names expected for the service.
- SSHD integration: If sshd still complains it can’t accept GSSAPI creds, enable debug logging (LogLevel DEBUG), and check gssproxy logs.
- SELinux: On SELinux-enabled systems, you may need to ensure file contexts and SELinux policies allow gssproxy to access keytabs and sockets. Check audit.log for AVC denials and use semanage fcontext/restorecon or local policy modules when needed.
8. Common pitfalls & best practices
- Don’t expose keytabs to unprivileged users. Let gssproxy hold them.
- Principals & SPNs must match service hostnames used by clients. Consistent DNS is essential.
- Minimal privileges: configure services and clients narrowly: allow only the minimum users/PIDs and only the required mech ops.
- Rotation: when rotating keytabs, reload/restart gssproxy or send a signal if supported. Plan for keytab updates.
- Logging: enable adequate logging during deployment and revert to normal verbosity in production.
- Testing in staging: GSSAPI behavior across SSH clients and other daemons can be subtle — test across your client set (Linux, macOS, Windows via native Kerberos clients, etc.).
9. Security considerations
- gssproxy centralizes credential access: secure the host and the gssproxy process.
- Protect keytab files using strict filesystem permissions and (if needed) SELinux policy.
- Restrict which local processes may request operations for a service — map by UID/PID carefully.
- Monitor logs for unexpected use of gssproxy.
10. Example full config (simple)
Save as /etc/gssproxy/gssproxy.conf:
mechs = {
krb5 = {
mech = krb5;
default_keytab = /etc/krb5.keytab;
};
};
services = {
ssh = {
mech = krb5;
user = "sshd";
keytab = /etc/krb5.keytab;
server = yes;
client = yes;
};
mydaemon = {
mech = krb5;
user = "myuser";
keytab = /etc/mydaemon.keytab;
client = yes;
server = no;
};
};
clients = {
allow_root_for_ssh = {
clients = [
{ match = "uid:0" },
];
service = "ssh";
};
mydaemon_client = {
clients = [
{ match = "user:myuser" },
];
service = "mydaemon";
};
};
Restart: sudo systemctl restart gssproxy and then restart dependent services (sshd, mydaemon, etc.) if needed.
Useful resources for gssproxy and further integrations
- Read your distribution’s /usr/share/doc/gssproxy/ or man pages (man gssproxy, man gssproxy.conf) — they contain distribution-specific details.
- Check integrations: Samba/Winbind, SSSD, NFS idmap — many modern stacks support gssproxy as an option to avoid exposing keytabs to many daemons.
- For production: automate keytab distribution, rotation and monitor gssproxy usage.
More helpful Articles
Tags: clients, configure, Example Integrate, GSSAPI, Main, server side, services, sshd, sudo, Useful







