File: README.Windows.md

package info (click to toggle)
libnginx-mod-http-auth-spnego 1.1.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 216 kB
  • sloc: ansic: 1,415; sh: 713; makefile: 32
file content (178 lines) | stat: -rw-r--r-- 7,015 bytes parent folder | download | duplicates (2)
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
Crash course to Windows KDC Configuration
=========================================

On the AD side, you need to:

* Create a new user, whose name should be the service name you'll be using
  Kerberos authentication on. E.g. `app.example`.

* Set the "User cannot change password" and "Password never expires" options
  on the account. If you are using AES-128 or AES-256, set also the "This
  account supports Kerberos AES 128 bit encryption" option or the 256 bit one.
  It is recommended to use AES, see [here](https://blogs.technet.microsoft.com/petergu/2013/04/14/interpreting-the-supportedencryptiontypes-registry-key/)
  for more details.

* Set a strong password on it. Feel free to forget it, you are not going to
  insert it anywhere.

* From a Windows `cmd.exe` window, generate the service principals and keytabs
  for this user using [`ktpass`](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ktpass).
  
  You need an SPN named `host/foo.example.com`, and another named
  `HTTP/foo.example.com`.
  
  It is **crucial** that `foo.example.com` is the DNS name of your web site in the
  intranet, and it is an `A` record. 
  
  Given that `app.example` is the account name you created, you would execute,
  **in this exact order**:

        C:\> ktpass -princ host/foo.example.com@EXAMPLE.COM -mapuser
        EXAMPLECOM\app.example -pass * -out host.foo.keytab -ptype KRB5_NT_PRINCIPAL
        -crypto AES256-SHA1

        C:\> ktpass -princ HTTP/foo.example.com@EXAMPLE.COM -mapuser
        EXAMPLECOM\app.example -pass * -out http.foo.keytab -ptype KRB5_NT_PRINCIPAL
        -crypto AES256-SHA1

* If you need to support multiple host names using the same service account,
  you can issue further `ktpass` commands, but **ensure to issue the `host/`
  one first and the `HTTP/` one after**. Example:

        C:\> ktpass -princ host/bar.example.com@EXAMPLE.COM -mapuser
        EXAMPLECOM\app.example -pass * -out host.bar.keytab -ptype KRB5_NT_PRINCIPAL
        -crypto AES256-SHA1

        C:\> ktpass -princ HTTP/bar.example.com@EXAMPLE.COM -mapuser
        EXAMPLECOM\app.example -pass * -out http.bar.keytab -ptype KRB5_NT_PRINCIPAL
        -crypto AES256-SHA1

* Verify that the correct SPNs are created using [`setspn`](https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spns-setspn-syntax-setspn-exe.aspx)

        C:\> setspn -Q */foo.example.com

  it should yield both the `HTTP/` and `host/` SPNs, both mapped to the
  `app.example` user. Example with a service accessible via both
  `foo.example.com` and `bar.example.com`:

        C:\Temp>setspn -Q */foo.example.com
        Checking domain DC=example,DC=com
        CN=app.example,OU=Service Accounts,DC=example,DC=com
                HTTP/bar.example.com
                host/bar.example.com
                HTTP/foo.example.com
                host/bar.example.com

  `setspn` lists the entries in the reverse order they were created. So **it is crucial
  that the HTTP and host entries are in pairs, in that order**.


Crash course to UNIX KRB5 and nginx configuration
-------------------------------------------------

* Verify that your UNIX machine is using the same DNS server as your DC, most
  likely it'll use the DC itself.

* Create an `/etc/krb5.conf` configuration file, replacing the realm and kdc
  host names with your own AD setup:

        [libdefaults]
          default_tgs_enctypes = aes256-cts-hmac-sha1-96
          default_tkt_enctypes = aes256-cts-hmac-sha1-96
          default_keytab_name  = FILE:/etc/krb5.keytab
          default_realm        = EXAMPLE.COM
          ticket_lifetime      = 24h
          kdc_timesync         = 1
          ccache_type          = 4
          forwardable          = false
          proxiable            = false

        [realms]
          EXAMPLE.COM = {
              kdc            = dc.example.com
              admin_server   = dc.example.com
              default_domain = example.com
          }

        [domain_realm]
          .kerberos.server = EXAMPLE.COM
          .example.com     = EXAMPLE.COM

* Copy the keytab files (`host.foo.keytab`, `http.foo.keytab`, etc) created
  with `ktpass` on Windows to your UNIX machine.

* Create a `krb5.keytab` using `ktutil`, concatenating together the keytabs
  generated by `ktpass`:

        # ktutil
        ktutil:  rkt host.foo.keytab
        ktutil:  rkt http.foo.keytab
        ktutil:  rkt host.bar.keytab
        ktutil:  rkt http.bar.keytab
        ktutil:  wkt /etc/krb5.keytab
        ktutil:  quit

* Verify that the created keytab file has been built correctly:

        # klist -kt /etc/krb5.keytab
        Keytab name: FILE:/etc/krb5.keytab
        KVNO Timestamp         Principal
        ---- ----------------- --------------------------------------------------------
        1 02/19/13 04:02:48 host/foo.example.com@EXAMPLE.COM
        2 02/19/13 04:02:48 HTTP/foo.example.com@EXAMPLE.COM
        3 02/19/13 04:02:48 host/bar.example.com@EXAMPLE.COM
        4 02/19/13 04:02:48 HTTP/bar.example.com@EXAMPLE.COM

  Key version numbers (`KVNO`) will be different in your case.


* Verify that you are able to authenticate using the keytab, without password:

        # kinit -5 -V -k -t /etc/krb5.keytab HTTP/bar.example.com
        Authenticated to Kerberos v5

        # klist
        Ticket cache: FILE:/tmp/krb5cc_0
        Default principal: HTTP/foo.example.com@EXAMPLE.COM

        Valid starting     Expires            Service principal
        02/19/13 17:37:42  02/20/13 03:37:40  krbtgt/EXAMPLE.COM@EXAMPLE.COM
                renew until 02/20/13 17:37:42

  Please note that you will be able to authenticate **only** with the **LAST**
  SPN that has been configured via `ktpass`, as windows user accounts keep the
  mapping only with a single SPN, and that is the one displayed in the "User
  logon name" field in the "Account" pane of an user account details screen of
  Active Directory Users and Computers, or the first result of `setspn -Q`.

* Make the keytab file readable only by root and the nginx group:

        # chmod 440 /etc/krb5.keytab
        # chown root:nginx /etc/krb5.keytab

* Configure a SPNEGO-protected location in the nginx configuration file:

        server {
          server_name foo.example.com;

          ssl on;
          ssl_certificate     example.com.crt;
          ssl_certificate_key example.com.crt;

          location / {
            root /some/where;
            index index.html;
            auth_gss on;
            auth_gss_realm EXAMPLE.COM;
            auth_gss_keytab /etc/krb5.keytab;
            auth_gss_service_name HTTP;
          }
        }

  The SPN will be built as follows:

        $auth_gss_service_name / $server_name @ $auth_gss_realm

  In the above example, it'll be `HTTP/foo.example.com@EXAMPLE.COM`. You can
  specify a fully-qualified SPN in the `auth_gss_service_name` configuration
  option, in this case the `server_name` won't be added automatically.