 Mijn naam is Philip, een paar jaar geleden begon ik te spelen met de DNS, want ik dacht dat het een echt cool lieverde was. Er zijn er dus plenties van talen bij Willem over DNS, maar dat is meestal hoe het met de overal DNS-infrastructuur gaat. Ik dacht, waarom is er geen talen die een beetje van code hebben en hoe je het gebruikt of hoe het verschilt. De andere prootjes, en op hetzelfde tijd ben ik echt interesserend in de DNS-locale vervaring en ook gebruik van stornige knie-materiaal. Dus ik dacht, ik moet dat in één tal verbinden. Ik dacht dat mensen weten over de DNS en de DNS-sack, dus kippen introducties op dat. Ik maakte een comparenslijt over hoe de DNS-sack is, compared met het normale PKI systeem. De DNS-sack heeft een route van geluid, een geluid van geluid die alles schijnt. Alle geluid draait uit dat, waarom het PKI is. Je hebt veel individuele CIs en je kunt gewoon meer hebben. Ik denk dat het echt leuk is dat je de route van geluid, de register en de registreerd moet geluiden. En dat is het, dus je weet dat er een paar componenten zijn die je moet geluiden. En dan heb je het gedaan, want met PKI hebben je zoveel individuele CIs. Dat kan alle certificaten voor je domain zijn. De hele communiteit is er constant vervaring de CIs om te zorgen dat je het goed doet. De andere ding met de DNS is geluid is volledig delegatie. Als je je domain hebt, en er is een trustanker in de parentzone, dan kan je wat je wilt doen in je domain. Waarschijnlijk met PKI, je hebt DV en EV, en je hebt wildcard-sorten, die je soms krijgt en sommige certen kunnen eigenlijk andere certen creëren, maar vaak krijg je ze niet, ze zijn heel complex. De DNS heeft een praktische, een soort van disadvantage, is dat je moet praten met verschillende partijen om alles wat je nodig hebt. Je praat met je recursive resolver, maar dan gaat die resolver eruit en praat met veel partijen. En PKI heeft dat gesloten in een praktische manier, waar je een certificatieverkant krijgt. Waarschijnlijk heeft de DNS een andere security advantage, maar het requiert meer werk. Recentelijk kwam het op de DNS O-Ark mailing list, ik was in mijn naam, dat is hoe ik het heb gevoerd. Er zijn zoveel DNS zones die 1024-bit RSA-kies zijn. Het is zoals, waarom hebben we een toysystem? Ik denk, kunnen we een reale systeem hebben op zo'n punt? Je kunt niet zeggen, ik heb de keymateriaal in het DNS-sec, en ik zeg, oh ja, maar ergens in dit link is 1024-bit RSA-kies, dat is niet de manier waar het moet zijn. En daar, at least de web browser community was veel meer regressief en zei, well, this is insecure, we're just not doing that anymore, and the world has quickly basically deleted all insertive secure ciphers. So, if you do DNS-sec, then you have to verify stuff, and you want to do that locally. I mean, if you let your ISP's resolver do a DNS-sec verification, then do you know if they're a good job, do you know? I mean, it's from a trust point of view, it's just not a good idea. So, you can do two things, the easiest way is to re-cursor a resolver locally, but it has very limited functionality, because in the DNS protocol, basically, you can say it checks or it doesn't check, and you don't know anything else, and it's usually set up, it's very fragile, because then your application reads et cetera, resolve.conf, where there should be a local IP address, but if it can change, suddenly you lose your security. So, I think it's way better if you want to do a DNS-sec and rely on the results to use a DNS-sec validating library that is integrated with your application. So, a number of years ago, people wanted to have a new DNS API, not specific for DNS-sec, but basically to have a more modern way of sending and receiving DNS packets. And the other thing is that most existing DNS solutions have no support for LibEvent or other event-based systems, and that was added to the GetDNS API, but it does support DNS-sec. It's more modern in the way that it's modeled after Python and JavaScript, so you get lists and dictionaries, and basically those data structures can always change without having to introduce new API calls, and that makes it extensible. And the thing I want to point out is there's an API specification and there's a reference implementation, and I, well, just mix the two. Assume that the reference implementation is the API, even though in theory, of course, you could have multiple implementations. Well, lots of text, but to highlight, that's at the top. You create a context, but that's a normal way of doing things with libraries. The way they solved the LibEvent thing is that there can be multiple routines for specific event libraries that hook into the GetDNS API to make the event stuff work, and then there's two sort of the most general calls. One is called GetDNS General, and the other is GetDNS General Sync. Sync is the synchronized version for if you don't want to use an event system and you just gave it a name and the DNS type that you want, and then at some point it says, well, I'm done, and then you have a result structure. And because result structure is like, say, JSON, the API is basically, we'll get an element from an array, look up an element in a dictionary. There's two basic data types. One is an integer and the other is binary data. So basically these calls here are the only other calls that you need to know to get DNS to know how to use the API. So from that point of view, it's very nice. It can be just a simple, stable set of calls that you don't need to change ever. There is, however, I mean, we always get complexity back in a different way. And so GetDNS creates a rather complex namespace because it's a namespace, you can always put extra stuff there. Because well, if you just don't look, then it doesn't work. So you have sort of the traditional DNS things like a decoded DNS reply packet. But as you can see at the top, it has a field, just address answers. And then it gives the addresses as a convenience for, well, if you were interested in the answers, the addresses, then you find them there and you don't have to know about what actual DNS looks like. And of course, you can always make changes to that and say, well, if we want to have a simple way of getting key material or something like that, you could just say, well, this is what you're actually looking for and then here is also the DNS stuff in case you want to know that as well. But it will never affect the actual API calls that you need to make. So, then I get to my first example. Well, I definitely do it. I mean, you see, well, there's an unknown fingerprint. What do you want to do? Do you want to continue? Yes. Who do I ask whether this is the right or not? Do I have time to ask anybody? No, I just continue. If it looks like the right server, it's probably good. So, and you can come up with all kinds of ways of storing fingerprints in a web server or a local wiki or whatever. But my practice is nobody actually does it. So, the obvious thing is, well, why don't you store it in DNS and then try to use that? So, the SSHFP record was created a long time ago and there's actual code in OpenSSH today that uses that. And that's, by default, enabled in FreeBSD. And so, I thought, well, I should play with that. I was really excited about that. And then I found out that it really doesn't work at all. And if you read the code here, then you can see this is sort of a more traditional way of having a DNS library. And then you see at some point that you have an LDNS RR list, RR count thing. It's very much tied to how a DNS packet structure works. You get it from this section and you get it there. And only if you know what a DNS packet is, you can use it. But the code itself, I mean, this code is perfectly fine. I mean, I don't know who wrote it, but there's nothing wrong with it. But it still doesn't work. Yeah. And if you look at... So, then I started, after I found out what the issue is and why it's not going to be fixed, I thought, well, this really cool new thing at DNS, I started working on that. And so, this is basically the first piece of get the DNS code that I wrote. So, there's a couple of things at the top. You can set some extensions and that goes in a generic way because you give a string and you put some values in the string. So, you can always add more strings without changing the API. You do the actual call. And then when I started using get DNS, you actually had to walk the data structure one step at a time. So, you say, well, there's a thing called reply tree. So, get the object of the reply tree. And then that has a subfield and et cetera. So, then I complained about it and then later more support was added to say, well, I want directly this field and know what it is called. So, but basically... So, it does the same thing as the LDNS version. But the difference is that you don't have to know as much about DNS. You have to know about how the get DNS reply structure looks. But if there's convenient functions, then you don't have to understand DNS at all. But now we get to where it went wrong. Is that the LDNS library is just completely standalone library. It doesn't know anything about the world. It's like you send a DNS packet, you get an answer back. But if it needs to do DNSSEC validation, it needs to have a trust anchor. So, LDNS library says, well, tell me where the trust anchor is and then I will start doing that. But then the OpenSSH people said, yeah, but this is such a stupid library. I mean, it should know where to find the trust anchor. We cannot set code in OpenSSH to tell it about trust anchors. So, the net result was, even though all the mechanics were there because of the lack of the trust anchor, it would never do any DNSSEC validation. And then there's an environment variable that LDNS listens to. So, if you have actually set the right environment variable, then it will actually do the validation. But yeah, that's a completely ridiculous way of doing things. So, fortunately, getDNS has a completely different approach. And it's like, well, it should work. And you can set some extensions where it works harder to make it work, like the roadblock affinities feature. But one thing that getDNS also added, sort of around the time of the route K is rolled over, is to directly fetch trust anchors itself from IANA, which is operated by ICANN. So, there it's always feel a bit uneasy about it. It's like, it's something that really works. But you just go to a random website and you get some stuff. And there's some certificate that signs that it's true. En, well, the thing is, it's a certificate. At technical point, it's all fine. But I don't know, maybe anybody at ICANN can edit this file. But at the same time, you have to trust ICANN anyhow, because well, they operate the route. So, yeah. But it shows the difference in philosophy. So, getDNS, it tries to make it work where LDNS and sort of most of the other older DNS libraries, they're very strict in like, well, we do DNS type of things and we're not go out of the way to make it work. A second example is TLSA. I really like TLSA for mail servers. Because one thing is, well, there's no real way that you can enforce a secure connection between mail servers. Because, well, how would you tell? I mean, you can ask the mail server to support start TLS. But yeah, men in the middle can just do a downgrade attack. But if you put a TLSA record in DNS, then it's a very clear statement of the operator of the receiving mail server. It's like, yes, I want TLS to be used. And this is my certificate. That's the other problem with encrypted email because everybody started out with self-signed certificates. There's no way that you can now simply transition. All certificates need to be signed by a CA because their mail would break. And if you do it in TLSA, then there's explicit statements like, well, this is my certificate or this is my CA. Then, as a sort of a hobby project, I'm trying to contain, isolate security things in separate programs. It's mostly for if you have small one-off things and you don't want to figure out, for example, how SSL works. So I created what I call the TLS helper, which basically does all the TLS encoded, whatever, and you just talk to a pipe to it. So then when I started thinking about Dain, it was like, well, maybe I should also create some sort of thing that does the same thing for TLSA lookups. So what it basically does, it tries to gather all the relevant information you need to send mail in one output JSON. And then the mail client can then use that information to set up a secure connection. Or it can know that it is not going to be a secure connection. So this is, well, FOSDEM doesn't have a TLSA record. But it does have DNSSEC. So in all of the fields, it says, well, DNSSEC secure is true. But then you get, for the TLSA record, you get no such domain. So, well, my favorite example for some people who do that. Unfortunately, my own sites are a bit backward in that I still don't have TLSA records. So there you see at the end that you get the key material right at the bottom. So as an application, if you would use that, then you don't have to be aware of anything related to DNS anymore. You just look at the right fields. But mostly this is also a hobby project to play more with this kind of stuff. A few code examples, this code is written, I don't know, a year and a half later than the first one. For some reason, so now I have a lot more extensions that I enable, because there's certain information that I get the DNS gives back by default. And if you want to have more fields, because I want to check the DNSSEC status, then you just pass in more extensions. En because it's all strings, you could basically store it anywhere. So that's the thing that you use to configure it. And then the way you extract stuff is you can see here at the bottom the change that was made. Because now you have a path to something that you want. So if you directly know, I want to look there, then you can ask for that. And so this is all straightforward. It's like, well, you have to have the conceptual model, what the DNS output data structure looks like. And it's like, I want this field, and then you just get it. But I've found one piece of code. And I remember that it actually took me quite a while to get right. En dat is, I also need to know whether the call succeeded or not. And apparently something succeeding or not has an endless number of possibilities. So I don't have no clear idea how to prove it. Maybe this is just how it should be. But it feels like this code is too long. So you basically have to first look, did the actual DNS call succeed or not? Because well, it's possible that you didn't get a reply packet. And you have a timeout or something like that. Then you have the issue that the DNS result could be no such domain or some other error code. And then you have a DNSSEC status, which could be secure, insecure, bogus, et cetera. And you have to have so many combinations that you all sort of have to figure out. It's like, well, if the DNS call didn't work at all, then the others won't be there. I think there's one case where you don't get an answer, but you have to treat it as an answer or continue anyhow. So I found this to be a bit of a minefield. But other than that, it seemed to be all very straightforward. So that's the end of what I wanted to show here. I think that if you would write any sort of DNS client code, then it's definitely worth looking into getDNS, because it's a very stable API, very extensible. Well, I think that definitely from the security point of view that the world needs more DNSSEC. So everybody who doesn't have DNSSEC signs on should immediately do that. Well, one thing is how do we get rid of the weak keys that are there? So one thing could be that if maybe the open source community says, well, one thing could be if getDNS has an option to say, well, a 1024 bit key is not secure, then the DNSSEC validator could say, well, this is either bogus or insecure or something like that. I mean, can easily be added as an extension. But the community could also go further and just say, well, in so many years all validators will just say, well, 1024 bit is just not secure. Well, it's just the default. We don't care anymore. Please registries do something sensible and have real security. Then I think that if those issues can be fixed, then I think DNSSEC and getDNS provide really cool opportunities for key distribution. There's probably a lot of other key distribution applications where people create really complex systems to distribute keys. But if you could rely on DNS to just do it, then you put them in DNS and you're in business. So that's my presentation. On the JSON earlier, I saw you had them in two fields. There was a DNS insecure and a DNS secure. Just to understand what's the reason behind the design. Does that just have the one field in total? No, because. Oh, so the question is, on this JSON output, I have two fields, one called DNSSEC secure and the other one is DNSSEC insecure. And that's because you have three values. If it's secure, then there's a signature chain. If it's insecure, then at some point there's no DS record. So you know that the child zone is not signed. But there's also the bogus status where you can fail to verify it. And of course, if you want to send mail, then you probably, well, it's up to the mail client to decide what to do in a bogus status. And so I wanted to have an explicit test like, well, is it secure that we could test for that? Is it insecure that we know? And then, yes, you have the other stuff. For this one, maybe we have to talk about this one, that this somehow can get incorporated in the library, the ICPB, if it's. Yeah. But we thought of things like for TLSA, there's extension return unsecure answers. Because if it's insecure of before it gets bogus, or if it's insecure, then the TLSA is not secure. No, but the thing is, I wanted to have sort of the generic helper program, dat zei het, well, if you want to know something about this site for sending mail, tell me about this site. So I could just say, well, it was not secure, so you don't get any answer. I want to say, well, it's insecure or bogus, and these are also the answers, because you may still decide to send the mail anyhow. But the flag is basically, if it's not secure, then you don't get any answers or something like that. It was, it did something other than what I wanted. Yes. The question is, did I reach out to the OpenSSH community? Yes. So I put my code on GitHub. I mean, I'm really slow in tracking new OpenSSH versions. I sent them a pointer to that, but I think that OpenSSH maintainers don't like this concept at all. So for them, it's like, yeah, there's no priority in changing the code. Well, the weird thing is, is that the LDNS code is in OpenSSH. So at some point, somebody managed to get that merge, and then it's like, let's make it really work. Nah, not really. So that's the question I just answered. So the question is again, why is there two fields, DNS secure, DNS insecure? I can answer it again. It's because there's a third state at this bogus where validation failed. I hope that doesn't happen. Maar zoals je kunt zien van de code dat is nog op de schrijving, waarschijnlijk, ik initialiseerde alle variables properly to zero. Er zou geen code moeten zijn, maar dat zet ze aan.