Difference between revisions of "Projects/HTTP Transport"
(→Commits) |
|||
(21 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | {{project- |
+ | {{project-rel|1.13}} |
==Overview== |
==Overview== |
||
− | This project intends to add |
+ | This project intends to add an HTTPS transport which can be used to send Kerberos and kpasswd protocol requests to an HTTPS proxy which will then send the requests to a KDC or kpasswd server and relay back their response. This change is useful especially for firewall configurations that allow traffic on port 443 but not on port 88. |
==Precedent== |
==Precedent== |
||
Line 11: | Line 11: | ||
===Heimdal=== |
===Heimdal=== |
||
− | Heimdal has such a mechanism [https://github.com/heimdal/heimdal/blob/master/lib/krb5/send_to_kdc.c#L504 as seen here]. It uses a GET request with a base64-encoded version of the UDP traffic. |
+ | Heimdal has such a mechanism [https://github.com/heimdal/heimdal/blob/master/lib/krb5/send_to_kdc.c#L504 as seen here]. It uses a GET request with a base64-encoded version of the UDP traffic. Leaving aside questions of idempotence and RESTfulness, Apache has a URL length for GET of about 4000 characters, and requests of this nature have been measured as close to that limit and may exceed it in practice. It uses a separate field in krb5.conf for specification of the http_proxy to be used. There is almost no evidence of this in use in active deployment. |
===Microsoft=== |
===Microsoft=== |
||
− | Microsoft has documented their mechanism, MS- |
+ | Microsoft has documented their mechanism, MS-KKDCP, [http://msdn.microsoft.com/en-us/library/hh553774.aspx here]. It uses POST requests which is much more in keeping with the HTTP specification than GET, and it also specifies HTTPS to be used in all cases, as Microsoft's implementation does not work over plain HTTP. |
==Implementation Process== |
==Implementation Process== |
||
− | HTTP transport will be implemented first, followed by HTTPS transport. We prefer Microsoft interoperability to Heimdal interoperability because despite the added complexity we feel it to be more in keeping with the HTTP specification. We will implement HTTP and HTTPS transports that correspond to our interpretation of Microsoft's specification. Parallel to implementation, we will attempt to set up a Microsoft KDC with proxying enabled so that we can test our implementation. For HTTPS transportation, we will first implement OpenSSL support, with NSS support to follow. |
||
+ | An HTTPS transport will be implemented. Initial portions of the patch series will focus on refactoring the client library's internal send-to-kdc logic to make the addition of new transports (such as a possible HTTP transport to be added later) less disruptive going forward. The HTTPS transport implementation will follow Microsoft's specification. We will implement it using OpenSSL initially and may add optional support for building using NSS at a later date. |
||
==Implementation Design== |
==Implementation Design== |
||
− | * We will expand the definition of the `kdc` field (and related fields including kpasswd_server and admin_server) in krb5.conf to take a URL (optionally including page) in order to allow HTTP or HTTPS transport. The new syntax will look like this: |
+ | * We will expand the definition of the `kdc` field (and related server location fields including kpasswd_server and admin_server) in krb5.conf to take a URL (optionally including page) in order to allow HTTP or HTTPS transport. The new syntax will look like this: |
− | kdc = |
+ | kdc = https://<proxy.addr>[:<port>][/<page>] |
− | Note that the syntax (and parser) does not change in the non- |
+ | Note that the syntax (and parser) does not change in the non-HTTPS cases. In order to facilitate this change, we will need to stop carrying a socktype around in the code that is either SOCK_DGRAM or SOCK_STREAM, and instead carry around our own protocol designator, an enumerated type called k5_transport. Because the contents of a proxy request also incorporate the realm's name and the `page' portion of the URL, we'll need to start to carry them around, too. |
− | * We will need to build against a cryptography library, and to add options to the build system for such. We will include an option to disable HTTPS support (i.e., |
+ | * We will need to build against a cryptography library, and to add options to the build system for such. We will include an option to disable HTTPS support (i.e., by building against no cryptographic library). |
− | As we have not yet been able to examine traffic from a Microsoft KDC with proxy enabled, our current working protocol for traffic is: POST request to /KdcProxy with body consisting of the base64-encoded version of the Kerberos request, with response from the MS-KKDCP consisting of the base64-encoding of the KDC's reply. Preliminary testing suggests that this is not what Microsoft uses, but the server isn't particularly chatty about errors. |
||
+ | * In order to facilitate self-testing and make the procedure for configuring the set of CAs which a client will trust in production environments clearer, we'll default to using the system-wide default trust store and adding an `http_anchor' option to krb5.conf to allow the location to be overridden. |
||
+ | ** The setting will be read from the realm-specific subsection of the `realms' section. |
||
+ | ** As with PKINIT, we can be describe locations using `FILE:', `DIR:', or `ENV:' prefixes. |
||
+ | |||
+ | * As most HTTPS clients do, when the client library connects to an HTTPS proxy, it will need to check that the naming information in the certificate which the server presents to the client matches the client's notion of the name of the server to which it is connecting. |
||
+ | ** When examining names in a certificate, if a subjectAltName of the type being compared (either hostname or address) is not present, we'll attempt to compare the expected name with the value of a CN attribute in the certificate's subject name. |
||
+ | ** If a name has three or more labels in it, the `*' wildcard will be accepted in the first label. |
||
+ | ** The rest of the name will be compared by lower-casing all ASCII characters and then performing an exact comparison. |
||
==Test Plan== |
==Test Plan== |
||
− | Due to the nature of the changes, it will be extremely difficult to write test cases for the new code. Instead, code has been written to implement the "other side" (on the KDC-end) of HTTP/HTTPS transport as a reference implementation. That code, including its implementation of the client-end of the HTTP/HTTPS pipe, can be found [https://github.com/frozencemetery/krb-proxies here]. |
||
+ | The self-tests will be expanded to make use of a locally-installed copy of [https://pypi.python.org/pypi/kdcproxy kdcproxy] to start up a proxy server, and should issue all of AS, TGS, and kpasswd requests to the test's KDC via the test's proxy. Tests should include cases which succeed and cases in which the client rejects the server's certificate. |
||
+ | |||
+ | ==Discussions== |
||
+ | |||
+ | * http://mailman.mit.edu/pipermail/krbdev/2013-August/011688.html |
||
+ | * https://github.com/krb5/krb5/pull/86 |
||
+ | |||
+ | ==Commits== |
||
+ | |||
+ | 42b3c2ed11c1e62c1691f868a6796983f93c3beb Simplify sendto_kdc.c |
||
+ | f4b1a7e7b80ce68e57912edcd48c39ea62c73e43 Add helper to determine if a KDC is the master |
||
+ | 9c6be00daca0b80aed94ec9680724f95e6be92e1 Use k5_transport(_strategy) enums for k5_sendto |
||
+ | d0be57ac45ea639baa3cff0dd2108c34e834bfa7 Build support for TLS used by HTTPS proxy support |
||
+ | bb89afd7c59deea855d2818fe36ef7472b4abf2e Add ASN.1 codec for KKDCP's KDC-PROXY-MESSAGE |
||
+ | 606e2ccc0a2546a23761f910482a55c5bf0f98ac Dispatch-style protocol switching for transport |
||
+ | d950809ff49e3e7603594186d77135a09ab6b1b2 HTTPS transport (Microsoft KKDCPP implementation) |
||
+ | f220067c2969aab107bd1300ad1cb8d4855389a7 Load custom anchors when using KKDCP |
||
+ | f7825e81b1ebf533c1dba9f84ae9ad36073a89cf Check names in the server's cert when using KKDCP |
||
+ | b52acabf478e8d1aa19f7823aade81eed1553143 Add some longer-form docs for HTTPS |
||
+ | f78f8b1a46534db3a4547323ba952c1fa1b41fe9 Have k5test.py provide 'runenv' to python tests |
||
+ | 142255ba9af4ce1016a8eadf147e599ee490f1f7 Add a simple KDC proxy test server |
||
+ | 3e2c7cc557048faac3400ae41b0228bd37a82a4c Add tests for MS-KKDCP client support |
||
− | ==Review== |
||
+ | Completed in {{bug|7929}}. |
||
− | This section documents the review of the project according to [[Project policy]]. |
||
+ | ==Release notes== |
||
− | It is divided into multiple sections. First, approvals should be listed. To list an approval type |
||
− | :<nowiki>#~~~~</nowiki> |
||
− | (hash mark followed by four tilde characters) on its own line. |
||
− | The next section is for summarizing discussion, which should take place on krbdev@mit.edu. Provide links to the archive at http://mailman.mit.edu/pipermail/krbdev/ if appropriate. Blocking objections can be noted with <nowiki>{{project-block}}</nowiki>. |
||
− | ===Approvals=== |
||
+ | Administrator experience: |
||
− | ===Discussion=== |
||
+ | * Add support for accessing KDCs via an HTTPS proxy server using the MS-KKDCP protocol. |
Latest revision as of 13:54, 12 August 2014
Contents
Overview
This project intends to add an HTTPS transport which can be used to send Kerberos and kpasswd protocol requests to an HTTPS proxy which will then send the requests to a KDC or kpasswd server and relay back their response. This change is useful especially for firewall configurations that allow traffic on port 443 but not on port 88.
Precedent
Both Heimdal and Microsoft Kerberos have such a technology.
Heimdal
Heimdal has such a mechanism as seen here. It uses a GET request with a base64-encoded version of the UDP traffic. Leaving aside questions of idempotence and RESTfulness, Apache has a URL length for GET of about 4000 characters, and requests of this nature have been measured as close to that limit and may exceed it in practice. It uses a separate field in krb5.conf for specification of the http_proxy to be used. There is almost no evidence of this in use in active deployment.
Microsoft
Microsoft has documented their mechanism, MS-KKDCP, here. It uses POST requests which is much more in keeping with the HTTP specification than GET, and it also specifies HTTPS to be used in all cases, as Microsoft's implementation does not work over plain HTTP.
Implementation Process
An HTTPS transport will be implemented. Initial portions of the patch series will focus on refactoring the client library's internal send-to-kdc logic to make the addition of new transports (such as a possible HTTP transport to be added later) less disruptive going forward. The HTTPS transport implementation will follow Microsoft's specification. We will implement it using OpenSSL initially and may add optional support for building using NSS at a later date.
Implementation Design
- We will expand the definition of the `kdc` field (and related server location fields including kpasswd_server and admin_server) in krb5.conf to take a URL (optionally including page) in order to allow HTTP or HTTPS transport. The new syntax will look like this:
kdc = https://<proxy.addr>[:<port>][/<page>]
Note that the syntax (and parser) does not change in the non-HTTPS cases. In order to facilitate this change, we will need to stop carrying a socktype around in the code that is either SOCK_DGRAM or SOCK_STREAM, and instead carry around our own protocol designator, an enumerated type called k5_transport. Because the contents of a proxy request also incorporate the realm's name and the `page' portion of the URL, we'll need to start to carry them around, too.
- We will need to build against a cryptography library, and to add options to the build system for such. We will include an option to disable HTTPS support (i.e., by building against no cryptographic library).
- In order to facilitate self-testing and make the procedure for configuring the set of CAs which a client will trust in production environments clearer, we'll default to using the system-wide default trust store and adding an `http_anchor' option to krb5.conf to allow the location to be overridden.
- The setting will be read from the realm-specific subsection of the `realms' section.
- As with PKINIT, we can be describe locations using `FILE:', `DIR:', or `ENV:' prefixes.
- As most HTTPS clients do, when the client library connects to an HTTPS proxy, it will need to check that the naming information in the certificate which the server presents to the client matches the client's notion of the name of the server to which it is connecting.
- When examining names in a certificate, if a subjectAltName of the type being compared (either hostname or address) is not present, we'll attempt to compare the expected name with the value of a CN attribute in the certificate's subject name.
- If a name has three or more labels in it, the `*' wildcard will be accepted in the first label.
- The rest of the name will be compared by lower-casing all ASCII characters and then performing an exact comparison.
Test Plan
The self-tests will be expanded to make use of a locally-installed copy of kdcproxy to start up a proxy server, and should issue all of AS, TGS, and kpasswd requests to the test's KDC via the test's proxy. Tests should include cases which succeed and cases in which the client rejects the server's certificate.
Discussions
- http://mailman.mit.edu/pipermail/krbdev/2013-August/011688.html
- https://github.com/krb5/krb5/pull/86
Commits
42b3c2ed11c1e62c1691f868a6796983f93c3beb Simplify sendto_kdc.c f4b1a7e7b80ce68e57912edcd48c39ea62c73e43 Add helper to determine if a KDC is the master 9c6be00daca0b80aed94ec9680724f95e6be92e1 Use k5_transport(_strategy) enums for k5_sendto d0be57ac45ea639baa3cff0dd2108c34e834bfa7 Build support for TLS used by HTTPS proxy support bb89afd7c59deea855d2818fe36ef7472b4abf2e Add ASN.1 codec for KKDCP's KDC-PROXY-MESSAGE 606e2ccc0a2546a23761f910482a55c5bf0f98ac Dispatch-style protocol switching for transport d950809ff49e3e7603594186d77135a09ab6b1b2 HTTPS transport (Microsoft KKDCPP implementation) f220067c2969aab107bd1300ad1cb8d4855389a7 Load custom anchors when using KKDCP f7825e81b1ebf533c1dba9f84ae9ad36073a89cf Check names in the server's cert when using KKDCP b52acabf478e8d1aa19f7823aade81eed1553143 Add some longer-form docs for HTTPS f78f8b1a46534db3a4547323ba952c1fa1b41fe9 Have k5test.py provide 'runenv' to python tests 142255ba9af4ce1016a8eadf147e599ee490f1f7 Add a simple KDC proxy test server 3e2c7cc557048faac3400ae41b0228bd37a82a4c Add tests for MS-KKDCP client support
Completed in [krbdev.mit.edu #7929].
Release notes
Administrator experience:
- Add support for accessing KDCs via an HTTPS proxy server using the MS-KKDCP protocol.