DNS DDos of the Day

My phone got a call recently from a systems administrator whose network was under attack. I was busy getting my twice-weekly dose of humility, but a couple hours later, my phone delivered the message.

The attacker was flooding their primary DNS server with requests for isc.org. This is a not-uncommon attack. As DDos attacks go, it’s not terribly effective; it can overwhelm the DNS server’s resources, but doesn’t utterly destroy the victim’s network. You can easily defend against this by controlling which hosts can perform recursive lookups on your server.

This particular sysadmin was running a DNS server that didn’t permit access control for recursive lookups. It ran fine for years, until someone wanted to attack it, much as your house doesn’t need a lock on the door until someone tries to break in. We discussed various ways he could blunt the attack, and a strategy for moving to a public-facing DNS server that supported access control lists.

I could start with “here’s a nickel, kid, go buy a better operating system.” But that’s not exactly helpful. A lot of Unix sysadmins are just as guilty of offering insecure services on their networks, thinking that nobody is going to attack their petty little operation. But you never know when you’ll anger some dweeb who cannot express their emotions in any way other than clicking a few buttons and giggling. This particular sysadmin had run his server for years without difficulty. But you only need to lock your car when someone tries to steal it.

If you’re running a DNS server, use one that supports ACLs. I’ve written about unbound as a recursive DNS server. Or, if you’re running BIND, you can use an ACL:

options {
...
allow-recursion {our_stuff; };
};

acl "our_stuff" {
192.0.2.0/24;
};

Poof! Recursion attacks are stopped.

Nobody wants to attack you? Nobody will EVER want to attack you? You are such an awesome human being that you will never accidentally annoy someone? Fine. I believe you. Wholeheartedly But did you know that open DNS resolvers can be used to amplify DNS-based DDos attacks? And these attacks are growing more common? And that a large number of Internet appliances have open resolvers? Do you issue those devices to your clients? Open resolvers are the new open mail relays.

Today is a good day to check your network for open resolvers. Or you can use a free shell account to run dig against your servers. Check your appliances, too.

This principle applies to services other than SSH, of course. Use keys to authenticate via SSH, or at least restrict the IP addresses that can log in via passwords. Apply your patches regularly. Think about what you’d do if you were under attack, and the points on your network where you could defend. You probably already know about some security holes on your network. Quit playing Angry Birds and go fix them.

But if you run an open resolver, you are ruining another sysadmin’s weekend.

publishers versus self-publishing

People keep asking me why I use a publisher when self-publishing has become more and more possible over the last few years. Today, 38% of Amazon’s top 100 titles are self-published. Authors with a long track record in publishing, like Bob Mayer and Joe Konrath, extol the advantages of self-publishing your work rather than going through a publisher. Dean Wesley Smith and Kristine Kathryn Rusch, authors with decades of respectable mainstream publishing behind them, make solid business cases for skipping publishers and selling directly to your audience.

These authors write fiction. How well do their arguments apply to non-fiction? Well enough, if you want to do the work or pay someone to do the work. Here’s what you must do to produce a professional-quality nonfiction book. (If you want to produce an amateur, feeble book, you can skip any or all of these.)

  • Tech review: Someone who knows the subject has to review your work. Even if you crowdsource an initial tech review, as I’ve done for my BSD books, you still need an acknowledged subject matter expert to double-check your work. Your technical reviewer will expect paying. Most publishers pay a couple grand for tech review, or offer a cut of the royalties.
  • Editing: An editor is not a proofreader. An editor helps transform your manuscript from the disjointed babblings of a subject matter expert into something that can be understood by your reader. You can expect to pay $1-2/page for a decent technical editor.
  • Copyediting/proofreader: This is your proofreader. $1-2/page, again.
  • Layout: A good book is invisible. The layout disappears from the reader’s perceptions, leaving only a stream of words flowing from the book in the reader’s brain. I have never met a technical person who really had this skill. There are people who will format your manuscript for publishing on Kindle, Smashwords, and other ebook retailers, as well as paper formats for CreateSpace or Lightning Source. This runs anywhere from $100 for a novel up to $500 or more for complicated technical documents.
  • Publicity: Different publishers offer different levels of publicity. My publisher, the inimitable No Starch Press, publicizes every book heavily, in every appropriate channel. Other publishers just put new books in the catalog and let the author hope. Publicity can cost as much as you want to spend.
  • Graphics: Most authors can’t draw, even if they think they can. Publishers usually have internal artists recreate author art. You need to make sure that your own art is adequate.
  • Management: Your book has a project manager who keeps track of all the disparate threads of producing your book. If you self-publish, that project manager is you.

    Overall, you can expect to spend a few thousand dollars self-publishing a professional-quality book, and a fair amount of extra time. Miss any step, handle any step less than perfectly, and your book will suffer.

    What do you miss out on when you self-publish?

  • Translations: Advances for foreign language rights range from $1000-$2000, plus royalties if and when the advance is earned out. You will not be able to pursue translation rights — you don’t have the contacts or the contract expertise.
  • Bookstores: You will not see your self-published book at Barnes & Noble. End of discussion.
  • Competence: Nonfiction publishers are experts at helping non-authors produce good, readable books. A good publisher will help you make your book the best it can be. If you’re not a writer, anything you self-publish will read poorly, no matter how much outside help you have. If you think you’re a writer, but you’ve never worked with a publisher, you have a lot to learn.
  • Cameraderie: You’re a team with your publisher. They will work with you. You’ll make friends. Everybody wants the book to succeed, and believes that the book can succeed. It’s hard to put a price tag on that.

    Nonfiction authors have some potential advantages, however. If you have a truly unique book, with no competition, you can do well self-publishing. If you want to compete in an existing, well-established topic, however, you’ll have a much harder slog. I wouldn’t recommend self-publishing a FreeBSD book, for example.

    How do these affect me?

    I want an editor, tech editor, and copyeditor who are interested in producing the best book possible. An editor I hire is not going to tell me “Wow, this book is horrible and pointless.” An editor who works for my publisher will voice his concerns to the publisher, and the publisher will intervene as necessary. I can honestly say that none of my publishers have ever had to have this meeting with me, but I want them to have the freedom to do so.

    Publicity? I have enough trouble with the little publicity I do now. I resisted blogging, Facebook, and Twitter for years. The less I talk to people, the more people like me. (It’s not that I’m an obnoxious person, but a little bit of me goes a long way.) An outside publicity person is an excellent idea. I try to give my publisher’s publicity person everything he asks for, follow his suggestions, and get out of his way.

    Bookstores: I don’t see my books in stores in Detroit, but I know that some people buy my books in bookstores. It seems that Amazon owns my publishing career.

    Graphics: I am an author, not an artist. Producing the graphics for PGP & GPG took as long as writing the manuscript itself. I need outside help with art.

    I don’t want to do all this for my technology books. The tech publishing industry is in much better shape than the fiction industry, and I’m confident that I will be able to find a home for my nonfiction. I might self-publish my fiction some day, just to escape the submission treadmill. But I haven’t given up on that mainstream success… yet.

  • NYCBSDCon Video

    The video of my NYCBSDCon 2010 talk, BSD Needs Books, is now available at http://blip.tv/file/4844882. At the moment, it’s the top link on BSD TV.

    This is the first time I’ve seen my own presentation, at any conference. I’ve always suspected that I look daft in front of an audience. It turns out that the slim chance I was wrong was a nice thing to have.

    OpenLDAP search filters

    I use LDAP authentication on several Web servers. For the first time, I have a Web application that I want to open to customers as well as staff. Usually, I just put the users into a group. Apache validates the password against LDAP and checks for group membership, and either accepts or rejects the request. The relevant Apache configuration looks like this:

    AuthLDAPURL “ldap://ldap1.domain.com/ou=people,dc=domain,dc=com” STARTTLS
    AuthLDAPGroupAttribute memberUid
    require ldap-group cn=groupname,ou=groups,dc=domain,dc=com

    Apache requires that I specify where to look for accounts, as shown in bold above. My customers are in a different OU than my coworkers. (It would have made more sense to name the “people” container “staff,” but I didn’t realize that at the time.) Apache will accept a filter in AuthLDAPURL, letting you check in multiple groups. I’ve never taken the time to understand LDAP filters, so I guess I better start now. I’ll write my first filters for ldapsearch(1), and then carry them over to Apache.

    Normally, I run ldapsearch like so:

    # ldapsearch -WxZD "cn=manager,dc=domain,dc=com"
    Enter LDAP Password:

    -W tells ldapsearch to ask for a password, -x sets simple auth, -Z toggles startTLS, and -D indicates a bind DN follows. While I have an inherent dislike of typing a password on the command line, I’m going to run many LDAP searches in quick succession on a test machine. My test machine doesn’t use the same password as my production environment, so I’m willing to make an exception for convenience. Drop the -W, and add the password with -w. Specify the password in quotes to escape symbols and such.

    # ldapsearch -xZD "cn=manager,dc=domain,dc=com" -w "password"

    You should get a dump of your LDAP directory.

    Now to build up a filter iteratively, figuring out how they work as we go. ldapsearch expects the filter to be the last item on the command line. Put it in quotes, to escape special characters.

    # ldapsearch -xZD "cn=manager,dc=domain,dc=com" -w "password" "(uid=mwlucas)"

    This returns only my user account, as I would expect. Now let’s search for one of two accounts, joined by an OR. I’m going to stop including the entire command line, and only list the filter at the end.

    "(|(uid=mwlucas)(uid=mwlucas2))"

    The OR operator is a pipe symbol (|). It’s followed by the two possible choices, each in parenthesis. This filter matches any entry where the uid is either mwlucas or mwlucas2. I get information for two accounts back.

    Similarly, I can search for a group by CN as well as a username. I want to see everything with a UID of “mwlucas” or matching the CN “cacti”.

    "(|(uid=mwlucas)(cn=cacti))"

    Entries for my account and this group appear.

    About this time I realize that I can probably fix my Apache problem by removing the ou=people entry in AuthLDAPURL, giving me:

    AuthLDAPURL “ldap://ldap1.domain.com/dc=domain,dc=com” STARTTLS

    I try it and, yes, users from both OUs can now log in. But I'm going to learn about search filters, anyway.

    I can use two additional logical operators, AND (&) and NOT(!).

    Also, filters support wildcards. For example, here I want to see all accounts that have the initials "mwl" in them. I've created more than one test account, and want to be sure that I remember all of them.

    (uid=*mwl*)

    That generates a lot of output, though. I'm more interested in a list of UIDs. If you specify an attribute after the filter, ldapsearch will only print that attribute. Here's the whole command string for this search.

    # ldapsearch -xZD "cn=manager,dc=domain,dc=com" -w "password" "(uid=*mwl*)" uid
    ...ldap internal stuff deleted...
    # mwlucas, people, domain.com
    dn: uid=mwlucas,ou=people,dc=domain,dc=com
    uid: mwlucas

    # mwltest, people, domain.com
    dn: uid=mwltest,ou=people,dc=domain,dc=com
    uid: mwltest

    # mwlstaff, people, domain.com
    dn: uid=mwlstaff,ou=people,dc=domain,dc=com
    uid: mwlstaff

    # mwlucas2, customers, domain.com
    dn: uid=mwlucas2,ou=customers,dc=domain,dc=com
    uid: mwltest2

    That's enough filtering to make my day-to-day life easier, so I'll get back to the problem I'm really trying to solve today.

    Fail Quickly

    I’ve started the next book for No Starch Press. There’s an outline, and I’ve written both the introduction and the afterword. All that’s left is the hard stuff in between, twenty-some chapters of it.

    Where to start writing? That’s easy: First, I write the stuff that’s most likely to make the book fail.

    Every project has easy parts that are fun and go quickly. Those are the tasks you’re most familiar with, that leverage your existing skills. Then there’s the parts that require you to learn new things, or demand that you actually spend time and energy breaking them down so others can understand you. These are the parts of the project that are most likely to make the project fail. I want to get those parts over with as quickly as possible.

    If the entire book is going to collapse because four chapters are impossible to write, it’s better to know that up front than after I’ve written the eighteen easy chapters leading up to them. I’m writing about 500 words an hour on this part, where I normally write 1000 words an hour. It’s drudgery, but they’ll get done.

    I’ve seen a lot of IT projects fail by spending their initial burst of energy on the easy stuff. If you do the easy part first, the hard part gets time to grow in your mind. You’ll spend energy dreading it. Worse, the time you spend doing the easy stuff might be completely wasted — after all, if you can’t do the hard part, then you have to throw everything else away. You can always do the easy part after you succeed at the hard bit, and it’ll make the rest of the project go more quickly.

    Now if you’ll excuse me, I have to finish this section of this chapter tonight…

    Public Service Announcement on Painting Old Brick

    A modern hand scraper and wire brush can strip peeling, mildewy paint from a concrete basement wall almost easily — at least, much easier than when I was a kid and had to do the same job with a pointed stick and piece of chalk. The equipment comes with warnings in big black letters. “Wear Goggles!” “Wear Gloves!” “May Sever Fingers!” And so on. You don’t want to get a flying paint chip in your eye.

    Unfortunately, it doesn’t come with a warning that says “Keep Mouth Shut.”

    Describing the taste of a hundred-year-old mildewed paint chip as “Lovecraftian” would leave me without adequate vocabulary to describe the texture.

    The moral is: when you need to shut up and do the job, don’t forget the “shut up” part.

    Adding IPv6 to a FreeBSD Mail/Web Server

    We’ve run out of IPv4 addresses. If you’re not already on IPv6, start hoarding gasoline and canned potted meat food product. Doomsday is here, film at eleven. Or, failing that, start running IPv6 on something so you can have a little familiarity with the new Internet protocol before you absolutely must. My personal FreeBSD 9 server (which hosts my email, this blog, web sites for my books, and a whole bunch of other equally trivial cruft) is now IPv6-enabled, even though the local site doesn’t have IPv6 connectivity. Here’s how I did it.

    Establishing IPv6 connectivity to and from an IPv4-only server breaks requires:

  • Get an IPv6 tunnel from a tunnel provider
  • Configure a generic IPv4 tunnel to the tunnel provider
  • Assign IPv6 addresses to your IPv4 generic tunnel
  • Assign your IPv6 default route over the tunnel
  • Establish IPv6 DNS resolution
  • Configure services to run on IPv6
  • Offer IPv6 DNS records

    If you’re reading this , you probably don’t have IPv6 at your facility. You’ll need an IPv6 tunnel, offered for free by many providers. I used Hurricane Electric, but use any broker you like. Sign up for an account, respond to the verification mail, and request a tunnel. The Web interface will give you a bunch of details about your tunnel.

    The gif interface provides a generic IPv4 tunnel that can be used for many protocols. Configuring an IPv4 tunnel requires only the IP addresses on each end. ifconfig(8) creates a tunnel with just:

    # ifconfig gif0 tunnel 198.22.63.8 209.51.181.2

    You must be able to ping the tunnel’s remote address.

    Now assign IPv6 addresses to your gif0 tunnel.

    # ifconfig gif0 inet6 your-IPv6-address remote-IPv6-address prefixlen 128

    For example, my HE-assigned IPv6 tunnel endpoint is 2001:470:1f10:b9c::2. The he.net IPv6 address is 2001:470:1f10:b9c::1. I assign my IPv6 addresses as:

    # ifconfig gif0 inet6 2001:470:1f10:b9c::2 2001:470:1f10:b9c::1 prefixlen 128

    Verify that your IPv6 addresses are correctly configured by using ping6 to hit the far end. Remember, standard ping will not work — ping is specific to IPv4.

    # ping6 2001:470:1f10:b9c::1
    PING6(56=40+8+8 bytes) 2001:470:1f10:b9c::2 –> 2001:470:1f10:b9c::1
    16 bytes from 2001:470:1f10:b9c::1, icmp_seq=0 hlim=64 time=19.209 ms
    16 bytes from 2001:470:1f10:b9c::1, icmp_seq=1 hlim=64 time=21.661 ms

    At this point, you have IPv6. Now assign the IPv6 default route to the remote end of the tunnel.

    # route -n add -inet6 default 2001:470:1f10:b9c::1

    Your server will now send all IPv6 traffic across your IPv4 tunnel, while still routing IPv4 traffic as usual. Remember, IPv4 and IPv6 are different protocols.

    Some Internet sites, such as Google, have special requirements for accessing their IPv6 DNS. Your tunnel broker provides an IPv6-aware DNS server. Now that you have a default route, see if you can ping6 it. If you can ping the DNS server, edit /etc/resolv.conf. Remove your IPv4 nameservers. Add the IPv6 nameserver. Check DNS for IPv4 (A records) and IPv6 (AAAA records) with dig(1).

    # dig www.google.com A

    ;; ANSWER SECTION:
    www.google.com. 20478 IN CNAME www.l.google.com.
    www.l.google.com. 222 IN A 209.85.225.99
    www.l.google.com. 222 IN A 209.85.225.147
    www.l.google.com. 222 IN A 209.85.225.104
    www.l.google.com. 222 IN A 209.85.225.105
    www.l.google.com. 222 IN A 209.85.225.103
    www.l.google.com. 222 IN A 209.85.225.106

    This looks correct. Let’s try AAAA records.

    # dig www.google.com AAAA

    www.google.com. 20368 IN CNAME www.l.google.com.
    www.l.google.com. 180 IN AAAA 2001:4860:b007::63

    This is an IPv6 answer. Google has fewer IPv6 servers than IPv4 servers, but that’s to be expected these days.

    Now configure services on your server to listen on IPv6 addresses. Daemons included in FreeBSD listen to IPv6 by default. Run sockstat -6 to see what programs are listening to your new IPv6 address. In my case, Apache only listened to IPv4. At some point in the foggy past, I had turned off IPv6 when configuring the port. I rebuilt devel/apr1 and www/apache22 with IPv6 support, restarted Apache, and it listened to my IPv6 address without issue.

    Last, you must publish AAAA records for the hosts you want to offer over IPv6. By gradually adding AAAA records, you can slowly increase the amount of traffic you deliver over IPv6, letting your your IPv6 traffic grow slowly.

    www IN A 198.22.63.8
    www IN AAAA 2001:470:1f10:b9c::2

    Properly-configured hosts will attempt to connect to services on IPv6 first. If those connection attempts fail, they will try IPv4 instead.

    To make your FreeBSD changes permanent, use your addresses in the /etc/rc.conf entries below.

    gif_interfaces=”gif0″
    gifconfig_gif0=”198.22.63.8 209.51.181.2″
    ipv6_network_interfaces=”gif0 lo0″
    ifconfig_gif0_ipv6=”inet6 2001:470:1f10:b9c::2 2001:470:1f10:b9c::1 prefixlen 128″
    ipv6_defaultrouter=”2001:470:1f10:b9c::1″

    Lastly, tell your users that you have IPv6. Otherwise, nobody will notice. It’s that transparent.

  • tracking latency, loss, and jitter with SmokePing

    Most network monitoring tools retry failed connections. snmpwalk sends multiple SNMP queries, giving the agent multiple chances to respond. Nagios lets you configure how often you retry queries, and specifically delays alarms to avoid transient issues. You do not want your pager going off at 3AM because something dropped a single packet! Losing a packet or two on occasion is fine, but losing one or two every time you run a check is a problem — and most monitoring tools can’t tell the difference. Don’t just crank up your monitoring software’s loss tolerance. You must know how often your network drops requests. That’s where SmokePing comes in. SmokePing measures loss, latency, and jitter for ICMP and application-level requests.

    SmokePing is in the FreeBSD ports as /usr/ports/net-mgmt/smokeping, OpenBSD ports as /usr/ports/net/smokeping, and NetBSD as /usr/pkgsrc/net/smokeping. My example server is FreeBSD 9, with SmokePing 2.4.2.

    The SmokePing port offers several different probes, or utilities for performing checks. In this example we’ll use the default probe, fping. While other probes, such as measuring DNS response time, are useful, they don’t address today’s day job problem.

    SmokePing is configured in /usr/local/etc/smokeping/config. The config file is a little different than most; it’s neither XML-ish nor C-esque. A hash mark is still a comment. Three asterisks marks off a configuration section. SmokePing uses a hierarchical configuration for monitoring hosts, and an item’s depth in the hierarchy is dictated by the number of plus signs before it. Variables are set with equals signs. It’s easy enough once you work through it a bit.

    Here’s the basic settings:


    *** General ***
    owner = mwlucas
    contact = mwlucas@blackhelicopters.org
    mailhost = mail.blackhelicopters.org
    sendmail = /usr/sbin/sendmail

    The Web interface needs some paths. I put my Web sites under /var/www/site/application. On this server, I want any local SmokePing stuff under /var/www/monitor/smoke. I’ll also use Apache aliases to direct part of the site to the directory where the port installed the files.

    imgcache = /var/www/monitor/smoke/images
    imgurl = https://monitor.blackhelicopters.org/smoke-images/
    datadir = /var/db/smoke
    piddir = /usr/local/var/smokeping/
    cgiurl = https://monitor.blackhelicopters.org/smoke/smokeping.cgi
    smokemail = /usr/local/etc/smokeping/smokemail
    tmail = /usr/local/etc/smokeping/tmail
    # specify this to get syslog logging
    syslogfacility = local0

    Create the directories assigned to datadir and imagesdir. The user smokeping must own the directory assigned to datadir. The Web server user (www) must own the imagesdir.

    As a general rule, I don’t permit applications write to files in the same directory that they’re installed in. It interfered with package management and added to security problems. Perhaps that’s not such a big concern these days, but I’m kind of old-school.

    Configure /etc/syslog.conf to log local0 to /var/log/smokeping.

    local0.* /var/log/smokeping

    I’m not configuring alarms right now, so you can comment out the line *** Alerts *** and everything beneath it until the next section. Similarly, comment out the entire *** Slaves *** section.

    Leave “Presentation” and “Database” alone, unless you a) understand RRD and want to muck with the innards of how SmokePing stores its data, and b) understand SmokePing. If you’re reading this article to learn about SmokePing, you automatically fail b).

    Under the Probes header, ensure the path to FPing is correct.

    The interesting bit is the Targets section. Here’s where you define which hosts you want to ping. SmokePing uses a hierarchical configuration that both lists the hosts you want to monitor and how you want the results displayed.

    *** Targets ***
    probe = FPing

    menu = Top
    title = Network Latency Grapher
    remark = Welcome to BH.org SmokePing.

    This header tells SmokePing that we’re configuring objects to be checked with FPing. We set a menu section and title, then proceed to the first target.


    + Southfield
    menu = Southfield
    title = Southfield

    ++ router6
    host = router6.blackhelicopters.org
    ++ router8
    host = router8.blackhelicopters.org

    + chi
    menu = Chicago
    title = Chicago
    ++ chi-1
    host=chi-1.blackhelicopters.org

    Here I’ve set up two first-level menus, Southfield (a suburb of Detroit) and Chicago. The Southfield menu has two entries beneath it. Each sub-entry has a title (indicated with ++) and a host. SmokePing will check these routers with FPing, and will create an interactive menu on the Web site arranging them as you have here.

    Set smokeping_enable=YES in /etc/rc.conf, and run /usr/local/etc/rc.d/smokeping start. Check /var/log/smokeping (you did set up syslog, didn’t you?) for any errors.

    Now the Web interface. FreeBSD’s package installed SmokePing’s CGI and related files in /usr/local/smokeping/htdocs. I want to use /var/www/monitor/smoke/images/ as the image cache. My httpd.conf for this is:

    Alias /smoke/ "/usr/local/smokeping/htdocs/"

    Options ExecCGI
    AllowOverride None
    Allow from All
    AddHandler cgi-script cgi

    Alias /smoke-images/ "/var/www/monitor/smoke/images/"

    I control access to my network management Web sites with LDAP. If you want to restrict with Apache’s IP address ACLs instead, change the Allow from All to something more suitable. Don’t open SmokePing to the world. Your customers and/or users will find it and ask a lot of inconvenient questions.

    SmokePing creates graphs indicating the average ping request latency in a green line, with smoky grey/black bars indicating jitter. When SmokePing loses packets, the line color changes.

    I’ll probably write more about SmokePing, as this hardly touches the surface. Tracking things like DNS query latency can help narrow down server-side problems.

    Microsoft’s BSD support

    On the NetBSD blog you’ll find an announcement that Microsoft has donated working code to support an experimental hardware platform to NetBSD.

    Microsoft has a mixed relationship with open source software. There’s the perennial discussions about Windows using BSD’s TCP/IP stack, .NET for FreeBSD, Microsoft buying and killing a NetBSD-based phone, and any amount of blather ranging from the absurd to the paranoid. What makes this different?

    First, it’s a gift. No strings attached — the BSD license doesn’t support strings. Copyright has been assigned to the NetBSD Foundation. It’s ours now, and there’s nothing Microsoft — or anyone — can do to take it back.

    Second, the extensible MIPS hardware can be reconfigured in software to support application-specific tasks. This is cool. I’m sure that someone will tell me that this was done twenty years ago and that the prior work has been unfairly ignored since, and someone else will tell me that this is really no big deal, but it sure sounds interesting to my uneducated ears.

    Third, NetBSD support will help get extensible MIPS running on other BSD platforms, and to a lesser extent on other operating systems. If the hardware ever becomes widespread, that is.

    I doubt that this means any sea change in Microsoft’s relationship with open source. This code is of limited use today, given the scarcity of hardware. Microsoft Research offering eMIPS patches would not surprise me, but there’s a difference between cooperation in research and cooperation anywhere else.