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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
Nginx module for HTTP SPNEGO auth
=================================
This module implements adds [SPNEGO](http://tools.ietf.org/html/rfc4178)
support to nginx(http://nginx.org). It currently supports only Kerberos
authentication via [GSSAPI](http://en.wikipedia.org/wiki/GSSAPI)
Prerequisites
-------------
Authentication has been tested with (at least) the following:
* Nginx 1.2 through 1.15
* Internet Explorer 8 and above
* Firefox 10 and above
* Chrome 20 and above
* Curl 7.x (GSS-Negotiate), 7.x (SPNEGO/fbopenssl)
The underlying kerberos library used for these tests was MIT KRB5 v1.12.
Installation
------------
1. Download [nginx source](http://www.nginx.org/en/download.html)
1. Extract to a directory
1. Clone this module into the directory
1. Follow the [nginx install documentation](http://nginx.org/en/docs/install.html)
and pass an `--add-module` option to nginx configure:
./configure --add-module=spnego-http-auth-nginx-module
Note that if it isn't clear, you do need KRB5 (MIT or Heimdal) header files installed. On Debian based distributions, including Ubuntu, this is the krb5-multidev, libkrb5-dev, heimdal-dev, or heimdal-multidev package depending on your environment. On other Linux distributions, you want the development libraries that provide gssapi_krb5.h.
Configuration reference
-----------------------
You can configure GSS authentication on a per-location and/or a global basis:
These options are required.
* `auth_gss`: on/off, for ease of unsecuring while leaving other options in
the config file
* `auth_gss_keytab`: absolute path-name to keytab file containing service
credentials
These options should ONLY be specified if you have a keytab containing
privileged principals. In nearly all cases, you should not put these
in the configuration file, as `gss_accept_sec_context` will do the right
thing.
* `auth_gss_realm`: Kerberos realm name. If this is specified, the realm is only passed to the nginx variable $remote_user if it differs from this default. To override this behavior, set *auth_gss_format_full* to 1 in your configuration.
* `auth_gss_service_name`: service principal name to use when acquiring
credentials.
If you would like to authorize only a specific set of principals, you can use the
`auth_gss_authorized_principal` directive. The configuration syntax supports
multiple entries, one per line.
auth_gss_authorized_principal <primary1>@<realm>
auth_gss_authorized_principal <primary2>@<realm>
Principals can also be authorized using a regex pattern via the `auth_gss_authorized_principal_regex`
directive. This directive can be used together with the `auth_gss_authorized_principal` directive.
auth_gss_authorized_principal <primary1>@<realm>
auth_gss_authorized_principal_regex ^(<primary2>)/(<instance>)@<realm>$
The remote user header in nginx can only be set by doing basic authentication.
Thus, this module sets a bogus basic auth header that will reach your backend
application in order to set this header/nginx variable. The easiest way to disable
this behavior is to add the following configuration to your location config.
proxy_set_header Authorization "";
A future version of the module may make this behavior an option, but this should
be a sufficient workaround for now.
If you would like to enable GSS local name rules to rewrite usernames, you can
specify the `auth_gss_map_to_local` option.
Credential Delegation
-----------------------------
User credentials can be delegated to nginx using the `auth_gss_delegate_credentials`
directive. This directive will enable unconstrained delegation if the user chooses
to delegate their credentials. Constrained delegation (S4U2proxy) can also be enabled using the
`auth_gss_constrained_delegation` directive together with the `auth_gss_delegate_credentials`
directive. To specify the ccache file name to store the service ticket used for constrained
delegation, set the `auth_gss_service_ccache` directive. Otherwise, the default ccache name
will be used.
auth_gss_service_ccache /tmp/krb5cc_0;
auth_gss_delegate_credentials on;
auth_gss_constrained_delegation on;
The delegated credentials will be stored within the systems tmp directory. Once the
request is completed, the credentials file will be destroyed. The name of the credentials
file will be specified within the nginx variable `$krb5_cc_name`. Usage of the variable
can include passing it to a fcgi program using the `fastcgi_param` directive.
fastcgi_param KRB5CCNAME $krb5_cc_name;
Constrained delegation is currently only supported using the negotiate authentication scheme
and has only been testing with MIT Kerberos (Use at your own risk if using Heimdal Kerberos).
Basic authentication fallback
-----------------------------
The module falls back to basic authentication by default if no negotiation is
attempted by the client. If you are using SPNEGO without SSL, it is recommended
you disable basic authentication fallback, as the password would be sent in
plaintext. This is done by setting `auth_gss_allow_basic_fallback` in the
config file.
auth_gss_allow_basic_fallback off
These options affect the operation of basic authentication:
* `auth_gss_realm`: Kerberos realm name. If this is specified, the realm is
only passed to the nginx variable $remote_user if it differs from this
default. To override this behavior, set *auth_gss_format_full* to 1 in your
configuration.
* `auth_gss_force_realm`: Forcibly authenticate using the realm configured in
`auth_gss_realm` or the system default realm if `auth_gss_realm` is not set.
This will rewrite $remote_user if the client provided a different realm. If
*auth_gss_format_full* is not set, $remote_user will not include a realm even
if one was specified by the client.
Troubleshooting
---------------
###
Check the logs. If you see a mention of NTLM, your client is attempting to
connect using [NTLMSSP](http://en.wikipedia.org/wiki/NTLMSSP), which is
unsupported and insecure.
### Verify that you have an HTTP principal in your keytab ###
#### MIT Kerberos utilities ####
$ KRB5_KTNAME=FILE:<path to your keytab> klist -k
or
$ ktutil
ktutil: read_kt <path to your keytab>
ktutil: list
#### Heimdal Kerberos utilities ####
$ ktutil -k <path to your keytab> list
### Obtain an HTTP principal
If you find that you do not have the HTTP service principal,
are running in an Active Directory environment,
and are bound to the domain such that Samba tools work properly
$ env KRB5_KTNAME=FILE:<path to your keytab> net ads -P keytab add HTTP
If you are running in a different kerberos environment, you can likely run
$ env KRB5_KTNAME=FILE:<path to your keytab> krb5_keytab HTTP
### Increase maximum allowed header size
In Active Directory environment, SPNEGO token in the Authorization header includes
PAC (Privilege Access Certificate) information, which includes all security groups
the user belongs to. This may cause the header to grow beyond default 8kB limit and
causes following error message:
400 Bad Request
Request Header Or Cookie Too Large
For performance reasons, best solution is to reduce the number of groups the user
belongs to. When this is impractical, you may also choose to increase the allowed
header size by explicitly setting the number and size of Nginx header buffers:
large_client_header_buffers 8 32k;
Debugging
---------
The module prints all sort of debugging information if nginx is compiled with
the `--with-debug` option, and the `error_log` directive has a `debug` level.
NTLM
----
Note that the module does not support [NTLMSSP](http://en.wikipedia.org/wiki/NTLMSSP)
in Negotiate. NTLM, both v1 and v2, is an exploitable protocol and should be avoided
where possible.
Windows
-------
For Windows KDC/AD environments, see the documentation [here](README.Windows.md).
Help
----
If you're unable to figure things out, please feel free to open an
issue on Github and I'll do my best to help you.
|