Phreebird

Phreebird is a DNSSEC proxy that operates in front of an existing DNS server (such as BIND, Unbound, PowerDNS, Microsoft DNS, or QIP) and supplements its records with DNSSEC responses. Features of Phreebird include automatic key generation, realtime record signing, support for arbitrary responses, zero configuration, NSEC3 “White Lies”, caching and rate limiting to deter DoS attacks, and experimental support for both Coarse Time over DNS and HTTP Virtual Channels. The suite also contains a large amount of sample code, including support for federated identity over OpenSSH. Finally, “Phreeload” enhances existing OpenSSL applications with DNSSEC support.

Download: Phreebird Suite 1.02

  1. Ed
    January 8, 2011 at 8:16 pm

    Thank you Dan for making this available.

  2. January 10, 2011 at 5:53 pm

    I have deployed KEY1 on mattmccutchen.net.

    There seems to be a gap in the security of phreeload: it checks for KEY1 at the certificate’s common name, but OpenSSL-based applications will also accept the certificate for its subjectAltNames. Unfortunately, the way the OpenSSL API is designed, there is no single X509_verify_cert_for_host function that phreeload could override to supply the right semantics. That functionality is generally only brought together in application protocol implementations such as libcurl and libsoup. You could consider patching some of those instead.

    • January 11, 2011 at 3:03 am

      Matt,

      Glad to hear from you. The case you refer to should be handled by the fact that, if one of the SAN names is browsed to, there will be a message of authoritative nonexistence for that domain. Then, I’ll fail over to the existing x509_verify_cert, which will catch the SAN.

      Alternatively, you can push KEY1 to both the normal domain and the SAN domain, and do everything in DNSSEC.

      • January 11, 2011 at 3:10 am

        Suppose I generate a certificate with CN = mattmccutchen.net, SAN = dankaminsky.com and post the corresponding KEY1 at mattmccutchen.net. You try to connect to dankaminsky.com with phreeload, and I intercept the connection and present my certificate. Phreeload queries DNSSEC at the CN and sees my KEY1, so you accept the certificate. What am I missing?

  3. January 11, 2011 at 3:14 am

    Matt–

    Oh yeah, I forgot. The API sucks right now; Phreeload doesn’t know at the moment that this was a connection attempt to mattmccutchen.net, so it only checks the domain in the CN, not the SAN. It’s safe, because of the assumption that something else later will check CN.

    I’ll add parallel SAN support to 1.03.

    I say the API sucks because x509_verify_cert doesn’t actually know the name to compare against.

  4. January 11, 2011 at 5:32 pm

    Dan Kaminsky :
    It’s safe, because of the assumption that something else later will check CN.

    Not a good assumption. Almost all clients check the SAN.

    I’ll add parallel SAN support to 1.03.

    What does that mean? Phreeload would check for KEY1 at all of the names in the SAN? That would be slow, but maybe server operators would adapt by not using certificates with many names. What if the SAN contains *.foo.com? Even if there is a KEY1 at *.foo.com (a DNS wildcard), strictly speaking, you still need to know it hasn’t been overridden at somesub.foo.com, and there is no way to test all possible subdomains.

    I say the API sucks because x509_verify_cert doesn’t actually know the name to compare against.

    Of course it doesn’t, that’s not a defect. The defect is that determination of cert acceptability for a server name (which is what Phreeload needs to replace) is not encapsulated in a single function in any of the major open source SSL/TLS libraries. NSS and GnuTLS make applications call one function for X509 verification and another for a name check, while OpenSSL makes applications implement the name check themselves (way to get bugs!).

    The “proper” solution would be to add better API to the libraries and port applications to use it. In the meantime, replacing ssl_verify_cert_chain and using the tlsext_hostname may work for most SNI clients. Alternatively, one could use Phoxie. Do you plan to release it to the public?

  5. January 11, 2011 at 6:53 pm

    Matt McCutchen :

    Dan Kaminsky :
    It’s safe, because of the assumption that something else later will check CN.

    Not a good assumption. Almost all clients check the SAN.

    Yeah, they’ll check the CN *and* the SAN. Sorry.

    I’ll add parallel SAN support to 1.03.

    What does that mean? Phreeload would check for KEY1 at all of the names in the SAN? That would be slow, but maybe server operators would adapt by not using certificates with many names. What if the SAN contains *.foo.com? Even if there is a KEY1 at *.foo.com (a DNS wildcard), strictly speaking, you still need to know it hasn’t been overridden at somesub.foo.com, and there is no way to test all possible subdomains.

    A SAN entry for *.foo.com should map fairly to a KEY1 entry at foo.com. It’s a reasonable place for the key hash to reside. Can you see an attack? (Not saying there isn’t one.)

    I say the API sucks because x509_verify_cert doesn’t actually know the name to compare against.

    Of course it doesn’t, that’s not a defect. The defect is that determination of cert acceptability for a server name (which is what Phreeload needs to replace) is not encapsulated in a single function in any of the major open source SSL/TLS libraries. NSS and GnuTLS make applications call one function for X509 verification and another for a name check, while OpenSSL makes applications implement the name check themselves (way to get bugs!).

    CryptoAPI also follows the OpenSSL model, and yes, way to get bugs.

    The “proper” solution would be to add better API to the libraries and port applications to use it. In the meantime, replacing ssl_verify_cert_chain and using the tlsext_hostname may work for most SNI clients.

    I thought I had some reason that API wouldn’t work. Specifically, the name checking functionality just wasn’t there. Could be wrong though.

    Alternatively, one could use Phoxie. Do you plan to release it to the public?

    It’s super sketchy python right now. Interested in helping me make a solid C port?

  6. January 12, 2011 at 2:42 am

    In the meantime, replacing ssl_verify_cert_chain and using the tlsext_hostname may work for most SNI clients.

    I thought I had some reason that API wouldn’t work. Specifically, the name checking functionality just wasn’t there. Could be wrong though.

    The OpenSSL function does not do a name check, but your replacement can. That will ensure that KEY1 endorsement, when applicable, is a necessary condition for a cert to be accepted. The application may do additional name checking, but that just means the admin has to use a cert containing the appropriate names, which is generally easy to arrange. If you take this approach, then the complexity of having to check all the SANs goes away.

    Alternatively, one could use Phoxie. Do you plan to release it to the public?

    It’s super sketchy python right now. Interested in helping me make a solid C port?

    Interested, but unlikely to actually find the time. I’d encourage you to go ahead and release what you have so people can start playing with it.

    In keeping with your goal of easy deployment, have you thought about making Phreebird automatically generate KEY1 records:
    from the cert presented by the host, if the organization is confident in the security of their internal network
    after verifying the presented cert against an existing X.509 CA operated by the organization?

  7. February 1, 2011 at 10:49 am

    Does phreebird support ipv6?

    And can I support multiple views or will I have to have two phreebird processes with the same key?

  8. February 16, 2011 at 5:34 am

    Matt McCutchen :
    The defect is that determination of cert acceptability for a server name (which is what Phreeload needs to replace) is not encapsulated in a single function in any of the major open source SSL/TLS libraries. NSS and GnuTLS make applications call one function for X509 verification and another for a name check

    Correction: NSS has such a function, SSL_AuthCertificate.

    I have made a proof-of-concept DANE implementation for NSS by modifying SSL_AuthCertificate. The DNSSEC is done with libunbound, inspired by Phreeload.

  1. December 13, 2010 at 3:41 pm
  2. January 13, 2011 at 2:14 pm

Leave a comment