Wandering Thoughts archives

2016-07-23

My current set of Chrome extensions (as of July 2016)

I know, I've said bad things about Chrome extensions before. Still, I seem to have slowly accumulated a number of extensions that I use, some of which I even trust, and that means it's worth actually documenting them so I can keep track (and easily put them into a new Chrome instance someday).

Unsurprisingly, my Chrome extensions are broadly similar in spirit to my normal set of Firefox extensions. Some of these Chrome extensions date back to years ago when I made a serious attempt to set up a Chrome equivalent of my Firefox environment so I could give Chrome a fair trial.

The obvious cases:

  • uBlock Origin works just as well in Chrome as it does in Firefox, and is good for the same things and the same reason.

  • HTTPS Everywhere because I feel that this is a good idea and why not.

User interface issues:

  • The bluntly named Don't Fuck With Paste (also, and, via) makes it so that websites can't stop you from pasting things into form input fields. These websites are basically wrong and they make me very annoyed, since how I manage website passwords requires paste to work.

    (The Firefox equivalent is disabling dom.event.clipboardevents.enabled in about:config.)

  • MiddleButtonScroll makes it so that you can scroll the page around with the middle mouse button. I'm extremely used to this behavior in Firefox, so I was happy to be able to get it in Chrome too.

  • CLEAN crxMouse Gestures is a giant experiment that makes me nervous. There have historically been no good, non-spyware gestures extensions for Chrome (when one existed, it wound up corrupted). This extension at least claims and appears to be a 'clean' (ie non-spyware) version of the relatively good but spyware crxMouse Gestures extension. I'm not sure if I trust it, but I really, really want mouse gestures so I'm willing to take the chance as an experiment. If someone tells me that it too is bad, I will be sad but not surprised.

    (Adding this extension is what pushed me into writing this entry.)

Security, sort of:

  • ScriptBlock is what I'm currently using as my NoScript equivalent on Chrome. Because my only major usage of Chrome is my hack use of incognito mode, I don't actually get much exposure to this extension so I don't really have any opinions on how well it works.

  • FlashBlock for Chrome is theoretically there for the same reasons that I have it in Firefox, but again in practice I mostly use Chrome in a way that deliberately disables it so I don't really have many opinions. Plus, Chrome is increasingly disabling Flash all on its own.

Things that I should probably remove:

  • Stylish is the Chrome version of the Firefox extension of the same name, which I used to make significant use of before I sadly discovered that it was part of my big Firefox memory leaks. In practice I don't use this in Chrome, but it seems harmless (and at the time I initially set up Chrome many years ago, it seemed like something I was going to want).

  • Protect My Choices seemed like a good idea at the time that I ran across it but the more I look at it the more I'm not sure I should have this extension sitting around doing things.

    (It turns out that I only have this installed in my work Chrome, not my home Chrome. So it's going to get removed the next time I'm in the office.)

Since Chrome's incognito mode is mostly how I use Chrome, I have a number of these extensions enabled in it. Right now, the list is uBlock Origin, MiddleButtonScroll, Don't Fuck With Paste, and CLEAN crxMouse Gestures (because there isn't much point in adding a mouse gestures extension I don't entirely trust if I'm not going to use it).

In Firefox, I consider It's All Text! to be essential. Unfortunately Chrome's very different extension model means that the Chrome equivalents have always had to do terribly awkward things that made them unattractive to me.

Since incognito mode discards cookies when I close it down, I haven't tried to find any sort of cookie management extension. As usual, this might be a bit of a mistake, as I do use non-incognito Chrome just a bit and so I've probably picked up a certain amount of cookie lint in the process.

(For me, Linux Chrome is significantly faster than Linux Firefox for Flickr. Since logging in all the time is annoying, I use the regular Chrome in order to retain the necessary login cookies.)

web/ChromeExtensions2016-07 written at 02:18:12; Add Comment

2016-07-22

Ubuntu 16.04's irritatingly broken MySQL updates

I tweeted:

So, Ubuntu 16.04 can't apply MySQL server updates if you have the server installed but have disabled it running. Good show, you lot.

We install the MySQL server package on a few machines but deliberately don't start the daemon. In older versions of Ubuntu, this worked reasonably well; you could do it, you could keep the daemon from starting on boot, and you could apply updates (although doing so generally started the daemon up, so you had to remember to then go stop it). In 16.04, if you've disabled the daemon your attempts to apply updates will error out:

mysql_upgrade: Got error: 2002: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) while connecting to the MySQL server
Upgrade process encountered error and will not continue.
mysql_upgrade failed with exit status 11

The direct cause of this problem is that the mysql-server-5.7 postinstall script needs to run mysql_upgrade, which requires the server to be running. Perhaps at this point you sigh, run 'service mysql start', and try the upgrade again. It'll still fail, because the postinstall script is more complicate and more wrong than that.

The postinstall script needs to stop the MySQL daemon, do some things, and then start the daemon again and run mysql_upgrade (and then restart the daemon yet again). It does all of this starting and restarting by running invoke-rc.d, and invoke-rc.d specifically refuses to start disabled daemons. In the grand Unix tradition, this behavior is burried in an innocuous phrasing in the invoke-rc.d manpage:

invoke-rc.d is a generic interface to execute System V style init script /etc/init.d/name actions, obeying runlevel constraints as well as any local policies set by the system administrator.

Via a complex chain of actions, what 'obeying runlevel constraints' translates to here is that if you do 'systemctl disable <whatever>', invoke-rc.d will decided that <whatever> is specifically blocked from running and not start it.

(Invoke-rc.d in general is the wrong tool in Ubuntu 16.04, because it's actually fairly tied to the System V init framework. The system goes through ugly hacks in order to make it work 'right' on things that are actually native systemd .service units, as the MySQL daemon is.)

This selectivity is the wrong approach, or at least it's in the wrong place. What the postinst script should really be doing is unconditionally shutting down the server, unconditionally starting it to run mysql_upgrade, unconditionally shutting it down again, and only then using invoke-rc.d to conditionally start it again. This would achieve the twin goals of upgrading MySQL while not leaving the daemon running if it's disabled. This would actually be an improvement over the 14.04 situation, instead of a massive headache.

(Of course I expect that the real answer is simply that no one thought about this possibility, and that if we were to file a bug report we'd be told that disabling the daemon is not a supported configuration.)

The workaround is simple. Before you try to apply a MySQL server pack update, do 'systemctl enable mysql'. After it's done, do 'systemctl disable mysql; systemctl stop mysql' to return to the original state.

Sidebar: 'Runlevel constraints' and invoke-rc.d

Invoke-rc.d checks to see whether something is enabled or disabled by looking for S* and K* symlinks in /etc/rc<runlevel>.d. In 16.04, the 'runlevel' is arbitrary and is reported as '5', so we're looking at /etc/rc5.d. When you do 'systemctl disable' or 'systemctl enable' on an Ubuntu 16.04 system and the service also has an /etc/init.d file, systemctl helpfully maintains rcN.d S* and K* symlinks for you. So running 'systemctl disable mysql' also creates a /etc/rc5.d/K02mysql, which invoke-rc.d will then see as saying that mysql is specifically constrained to not start in runlevel 5, and so should not be started.

(If there was no /etc/rc5.d symlink at all, invoke-rc.d would also conclude that it shouldn't start the MySQL daemon.)

linux/Ubuntu1604MySQLUpdatePain written at 02:20:33; Add Comment

2016-07-21

My current set of essential extensions for Firefox profiles

For reasons beyond the scope of this entry, I recently set up a new Firefox profile. As a new profile it needs to be (re) customized for my preferences, including extensions. I can't just use my regular browser's set of extensions because this profile is for staying logged in to Twitter and needs to be set up so that Twitter is usable. Also, I don't want to spend a lot of time maintaining it, because I'm only going to use it once in a while.

Since there may be more single-use profiles like this in my future, I'm writing down my current set of essential Firefox extensions for this sort of environment. They are:

Although I've considered it, I'm not currently using NoScript in this profile. In theory NoScript shouldn't be blocking anything because I only use this profile on Twitter and I'd have to whitelist Twitter's JavaScript; in practice, it's likely to need at least periodic attention to whitelist some new domain that now has JavaScript that's necessary to keep Twitter working.

(If I follow links from Twitter to other sites in this profile, I may regret this choice. But I generally don't do that, since I read Twitter almost entirely through choqok and choqok is set to open links in my regular browser session.)

A number of my regular extensions are okay here and potentially useful, but aren't compelling enough to bother installing in a new profile that I'm using this way. Part of this is that Twitter allows you to control video autoplay in your settings, so I have it turned off; if that changed, FlashStopper or some equivalent might become important.

(Things would be a bit different if you could build bundles of extensions and extension preferences that would all install together. Then I'd probably roll in more of my standard extensions, because each additional extension wouldn't be a little additional drip of hassle to get and customize.)

web/FirefoxProfilesCoreExtensions written at 00:23:27; Add Comment

2016-07-20

Official source release builds should not abort on (compilation) warnings

I will put my conclusion up front:

Official source releases should not build software with -Werror or the equivalent.

(By official source releases I mean things like 'we are releasing version 1.x.y of our package today'.)

Perhaps you disagree. Then the rest of this entry is for you.

As I write this, the current release version of Rust is 1.10.0. This version (and probably all previous ones) won't build on the recently released Fedora 24 because of a C compiler issue. This isn't because of bug in the Fedora 24 version of gcc, and it's not due to the Fedora 24 gcc uncovering a previously unrecognized bug in Rust. Instead it's because of, well, this:

src/rt/miniz.c: In function ‘tinfl_decompress’:
src/rt/miniz.c:578:9: error: this ‘for’ clause does not guard... [-Werror=misleading-indentation]
         for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
         ^~~
src/rt/miniz.c:578:47: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘for’
         for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
                                               ^~~
[...]
cc1: all warnings being treated as errors

Rust has opted to compile much or all of the C in its source tree with the gcc options -Wall -Werror, which mean 'emit more or less all warnings that you can, and if you emit any warnings consider this an error and stop'. Fedora 24 is one of the first Linux distributions to ship with gcc 6, and gcc 6 has added some more warnings, which now pick up more nits in the C code, and now Rust doesn't build.

It would be one thing if this was pointing out a previously undiscovered error. But it's not. The code in the Rust 1.10.0 release is merely not ideal, and this example neatly illustrates the problem with making 'not ideal' a fatal error in official source releases. Put simply, the compiler's definition of 'not ideal' changes over time.

When you set your official releases to build with -Wall -Werror or the equivalent, you're putting yourself on quicksand. It's basically guaranteed that future compiler versions will have different opinions on what to warn about, which means that official releases of your software are going to stop building at some point in the future for no good reason. Having your software stop building for no good reason is not helping people.

(I say 'for no good reason' because if it actually built, the release would be no more broken than it was before the new nits were reported. The nits were always there, after all, even on all the systems that didn't report them.)

I think it's fine to use -Werror in development if you want to. But the moment you make a release, my very strong sysadmin opinion is that the job of that release is to build correctly in as many environments as possible, including future environments. An attempt to build a release should fail on a system only if the end result would be incorrect in a new way.

(If a release is incorrect on both system X and system Y but this is only uncovered on system Y, that should not be a fatal error. It's sufficient for release builds to be bug for bug equivalent to each other. This is probably too tricky to do in most cases, although maybe you should provide a 'I don't care, just force it to build' configuration option that suppresses as many compiler errors as possible.)

Another way to put this is that -Wall -Werror is a service for the developers; it surfaces nits and forces developers to fix them. However, releases are not made for developers, they're made for outside people. Forcing developer issues on outside people is both futile (since outside people are not developers) and annoying. Thus actual releases should have things like compiler options reoriented to serve the needs of outside people instead of developers.

programming/ReleaseBuildsNoAbortOnWarnings written at 01:51:08; Add Comment

2016-07-19

How not to set up your DNS (part 23)

Presented in the traditional illustrated form, more or less:

; dig ns megabulkmessage218.com @a.gtld-servers.net.
[...]
megabulkmessage218.com. IN NS ns1.megabulkmessage218.com.
megabulkmessage218.com. IN NS ns2.megabulkmessage218.com.
[...]
ns1.megabulkmessage218.com. IN A 5.8.32.218
ns2.megabulkmessage218.com. IN A 8.8.8.8
[...]

One of these two listed nameservers is not like the other.

8.8.8.8 is of course the famous open resolving DNS server that Google operates. It is in no way an authoritative DNS server for anyone, even if you try to use it as one. Lookups will probably fail, because I believe that most DNS resolvers set the 'no recursion' flag in their queries to what they believe are authoritative DNS servers and when it sees that, 8.8.8.8 doesn't answer even when it almost certainly has the data in cache (instead it returns a SERVFAIL).

(This is thus an extreme case of an informal secondary, although I suppose it was probably inevitable and there are likely plenty of other people using 8.8.8.8 this way with other domains. After all, it appears to work if you test it by hand, since tools like dig normally set the recursive flag on their queries.)

Since this is a spammer's DNS server (as you might have guessed from the domain name), things are a little bit peculiar with its results.

; dig ns megabulkmessage218.com. @5.8.32.218
[nothing; we get the standard 'no such data' response]
; sdig a gadswoonsg.megabulkmessage218.com. @5.8.32.218
178.235.61.115
; sdig mx gadswoonsg.megabulkmessage218.com. @5.8.32.218
10 mail.megabulkmessage218.com.
; sdig a mail.megabulkmessage218.com. @5.8.32.218
149.154.64.43

(The MX target is SBL295728, the A record is in the SBL CSS and listed in the CBL and so on. Basically, you name a DNS blocklist and 178.235.61.115 is probably in it. And the domain name is currently in the Spamhaus DBL.)

But:

; dig a randomname.megabulkmessage218.com. @5.8.32.218
[nothing; we get the standard 'no such data' response]

So this spammer is clearly making up random names for their spam run and running a very custom nameserver that only responds to them. Anything else gets a no such data response, including SOA and NS queries for the domain itself. Since there's nothing entirely new under the sun, we've seen this sort of DNS server cleverness before.

It's interesting that trying to get the NS records for the domain from your local resolving DNS server will fail even after you've looked up the A record for the hostname. The NS records (and glue) from the .com nameservers don't have particularly low TTLs, and given that the A record resolves your local DNS server was able to get and use them. But these days clearly it immediately throws them away again to avoid cache poisoning attacks (or at least won't return them for direct queries).

sysadmin/HowNotToDoDNSXXIII written at 14:24:05; Add Comment

An interesting (and alarming) Grub2 error and its cause

I upgraded my office workstation from Fedora 23 to Fedora 24 today, following my usual procedure of doing a live upgrade with dnf. Everything went smoothly, which is normal, and it was pretty fast, which isn't my normal experience but was probably because my root filesystem is now on SSDs. After the updates finished, I ran the grub2-install command that you're instructed to do and rebooted. My machine made it into Grub's menu but trying to start any kernel immediately halted with an error about the symbol grub_efi_secure_boot not being found (as in this Fedora 24 bug report or this old Ubuntu one).

This could politely be called somewhat alarming. Since it seemed to involve (U)EFI booting in some way, I went through the BIOS settings for my motherboard to see if I could turn that off and force a pure BIOS boot to make things work. Naturally I wound up looking through the boot options screen, at which point I noticed that the boot order looked a little odd. The BIOS's boot list didn't have enough room to display full names for drives, but the first and second drives had names that started with 'ST31000', and things called 'Samsung ...' were way down the list at the bottom.

At this point the penny dropped: my BIOS was still booting from my older hard drives, from before I'd moved the root filesystem to the SSDs. The SSDs were definitely considered sda and sdb by Linux and they're on the first two SATA links, but the BIOS didn't care; as far as booting went, it was sticking to its old disk ordering. When I'd updated the Grub2 boot blocks with grub2-install, I'd of course updated the SSD boot blocks because that's what I thought I was booting from; I hadn't touched the HD boot blocks. As a result the old Fedora 23 Grub boot blocks were trying to load Fedora 24 Grub modules, which apparently doesn't work very well and is a classic cause of these Grub 'undefined symbol' errors.

Once I realized this the fix was pleasantly simple; all I had to do was put the SSDs in their rightful place at the top of the (disk) boot priority list. Looking at the dates, this is the first Fedora version upgrade I've done since I added the SSDs, which explains why I didn't see it before now.

There's an argument that the BIOS's behavior here is sensible. If I'm correct about what's going on, it has essentially adopted a 'persistent boot order' in the same way that Linux (and other Unixes) are increasingly adopting persistent device names. I can certainly see people being very surprised if they add an extra SSD and suddenly their system fails to boot or boots oddly because the SSD is on a channel that the BIOS enumerates first. However, it's at least surprising for someone like me; I'm used to BIOSes cheerfully renumbering everything just because you stuck something into a previously unused SATA channel. A BIOS that doesn't do that for boot ordering is a bit novel.

(This may be especially likely on motherboards with a mix of 6G and 3G SATA ports. You probably want the 6G SATA ports enumerated first, and even if HDs live there for now, they're going to wind up being used for SSDs sooner or later.)

In the process of writing this entry I've also discovered that while I moved my root filesystem over to the SSDs, I seem to never have moved /boot; it's still a mirrored partition on the HDs. I'm not sure if this was something I deliberately planned, if I was going to move /boot later but forgot, or if I just plain overlooked the issue. I have some notes from my transition planning, but they're silent on this.

(Since /boot is still on the HDs, I'm now uncertain both about how the BIOS is actually numbering my drives and how Grub2 is finding /boot. Maybe the Grub boot blocks (technically the core image) have a hard-coded UUID for /boot instead of looking at specific BIOS disks.)

linux/GrubDiskMismatchError written at 00:02:06; Add Comment

2016-07-17

A good solution to our Unbound caching problem that sadly won't work

In response to my entry on our Unbound caching problem with local zones, Jean Paul Galea left a comment with the good suggestion of running two copies of Unbound with different caching policies. One instance, with normal caching, would be used to resolve everything but our local zones; the second instance, with no caching, would simply forward queries to either the authoritative server for our local zones or the general resolver instance, depending on what the query was for.

(Everything would be running on a single host, so the extra hops queries and replies take would be very fast.)

In many organizational situations, this is an excellent solution. Even in ours, at first glance it looks like it should work perfectly, because the issue we'd have is pretty subtle. I need to set the stage by describing a bit of our networking.

In our internal networks we have some machines with RFC 1918 addresses that need to be publicly reachable, for example so that research groups can expose a web server on a machine that they run in their sandbox. This is no problem; our firewalls can do 'bidirectional NAT' to expose each such machine on its own public IP. However, this requires that external people see a different IP address for the machine's official name than internal people do, because internal people are behind the BINAT step. This too is no problem, as we have a full 'split horizon' DNS setup.

So let's imagine that a research group buys a domain name for some project or conference and has the DNS hosted externally. In that domain's DNS, they want to CNAME some name to an existing BINAT'd server that they have. Now have someone internally do a lookup on that name, say 'www.iconf16.org':

  1. the frontend Unbound sees that this is a query for an external name, not one of our own zones, so it sends it to the general resolver Unbound.
  2. the general resolver Unbound issues a query to the iconf16.org nameservers and gets back a CNAME to somehost.cs.toronto.edu.
  3. the general resolver must now look up somehost.cs itself and will wind up caching the result, which is exactly what we want to avoid.

This problem happens because DNS resolution is not segmented. Once we hand an outside query to the general resolver, there's no guarantee that it stays an outside query and there's no mechanism I know of to make the resolving Unbound stop further resolution and hot-potato the CNAME back to the frontend Unbound. We can set the resolving Unbound instance up so that it gives correct answers here, but since there's no per-zone cache controls we can't make it not cache the answers.

This situation can come up even without split horizon DNS (although split horizon makes it more acute). All you need is for outside people to be able to legitimately CNAME things to your hosts for names in DNS zones that you don't control and may not even know about. If this is forbidden by policy, then you win (and I think you can enforce this by configuring the resolving Unbound to fail all queries involving your local zones).

sysadmin/UnboundZoneRefreshProblemII written at 23:05:07; Add Comment

DNS resolution cannot be segmented (and what I mean by that)

Many protocols involve some sort of namespace for resources. For example, in DNS this is names to be resolved and in HTTP, this is URLs (and distinct hosts). One of the questions you can ask about such protocols is this:

When a request enters a particular part of the namespace, can handling it ever require the server to go back outside that part of the namespace?

If the answer is 'no, handling the request can never escape', let's say that the protocol can be segmented. You can divide the namespace up into segments, have different segments handled by a different servers, and each server only ever deals with its own area; it will never have to reach over to part of the namespace that's really handled by another server.

General DNS resolution for clients cannot be segmented this way, even if you only consider the answers that have to be returned to clients and ignore NS records and associated issues. The culprit is CNAME records, which both jump to arbitrary bits of the DNS namespace and force that information to be returned to clients. In a way, CNAME records act similarly to symlinks in Unix filesystems. The overall Unix filesystem is normally segmented (for example at mount points), but symlinks escape that; they mean that looking at /a/b/c/d can actually wind up in /x/y/z.

(NS records can force outside lookups but they don't have to be returned to clients, so you can sort of pretend that their information doesn't exist.)

Contrasting DNS with HTTP is interesting here. HTTP has redirects, which are its equivalent of CNAMEs and symlinks, but it still can be segmented because it explicitly pushes responsibility for handling the jump between segments all the way back to the original client. It's as if resolving DNS servers just returned the CNAME and left it up to client libraries to issue a new DNS request for information on the CNAME's destination.

(HTTP servers can opt to handle some redirects internally, but even then there are HTTP redirects which must be handled by the client. Clients don't ever get to slack on this, which means that servers can count on clients supporting redirects. Well, usually.)

I think this protocol design decision makes sense for DNS, especially at the time that DNS was created, but I'm not going to try to justify it here.

tech/DNSResolutionIsNotSegmented written at 01:03:58; Add Comment

2016-07-16

A caching and zone refresh problem with Unbound

Like many people, we have internal resolving DNS servers that everyone's laptops and so on are supposed to use for their DNS. These used to run Bind and now run Unbound, mostly because OpenBSD switched which nameservers they like. Also like many people, we have a collection of internal zones and internal zone views, which are managed from a private internal master DNS server. This has led to a problem with our Unbound setup that we actually don't know how to solve.

When we make an update to internal DNS and reload the private master with it, we want this to be reflected on the resolving DNS servers essentially immediately so that people see the DNS change right away. In the days when we ran Bind on the resolving servers, this was easy; we configured the resolving Bind to be a secondary for our internal zones and set the master up with also-notify entries for it. When the master detected a zone change, it sent notifications out and the resolving Bind immediately loaded the new data. Done.

It's not clear how to achieve something like this with Unbound. Unbound doesn't listen to NOTIFY messages and do anything with them (although it's listed as a TODO item in the source code). While you can force an incredibly low TTL on DNS records so that the new DNS information will be seen within a minute or two, this setting is global; you can't apply it to just some zones, like say your own, and leave everything else cached as normal. In theory we could set absurdly low TTLs on everything in the internal views on the private master, which would propagate through to Unbound. In practice, how the internal views are build makes this infeasible; it would be a major change in what is a delicate tangle of a complex system.

(With low TTLs there's also the issue of cached negative entries, since we're often adding names that didn't exist before but may have been looked up to see that nope, there is no such hostname.)

Unbound can be told to flush specific zones via unbound-control and in theory this works remotely (if you configure it explicitly, among other things). In practice I have a number of qualms about this approach, even if it's scripted, and Unbound's documentation explicitly says that flushing zones is a slow operation.

Given that Unbound explicitly doesn't support NOTIFY yet, there's probably no real good solution to this. That's sometimes how it goes.

(We have what I'm going to call a workaround that we currently feel we can live with, but I'm not going to tell you what it is because it's not really an appealing one.)

sysadmin/UnboundZoneRefreshProblem written at 00:30:58; Add Comment

2016-07-15

Sudo and changes in security expectations (and user behaviors)

Sudo has a well known, even famous default behavior; if you try to use sudo and you don't have sudo privileges, it sends an email alert off to the sysadmins (sometimes these are useful). In my view, this is the sign of a fundamental assumption in sudo's security model, namely that it's only going to be used by authorized people or by malicious parties. If you're not a sysadmin or an operator or so on, you know that you have no business running sudo, so you don't. Given the assumption that unauthorized people don't innocently run sudo, it made sense to send alert email about it by default.

Once upon a time that security model was perfectly sensible, back in the days when Unix machines were big and uncommon and theoretically always run by experienced professionals. Oh, sure, maybe the odd sysadmin or operator would accidentally run sudo on the wrong machine, but you could expect that ordinary people would never touch it. Today, however, those days are over. Unix machines are small and pervasive, there are tons of people who have some involvement in sysadmin things on one, and sudo has been extremely successful. The natural result is that there are a lot of people out there who are following canned howto instructions without really thinking about them, and these instructions say to use sudo to get things done.

(Sometimes the use of sudo is embedded into an installation script or the like. The Let's Encrypt standard certbot-auto script works this way, for instance; it blithely uses sudo to do all sorts of things to your system without particularly warning you, asking for permission, or the like.)

In other words, the security model that there's basically no innocent unauthorized use of sudo is now incorrect, at least on multi-user Unix systems. There are plenty of such innocent attempts, and in some environments (such as ours) they're the dominant ones. Should this cause sudo's defaults to change? That I don't know, but the pragmatic answer is that in the grand Unix tradition, leaving the defaults unchanged is easier.

(There remain Unix environments where there shouldn't be any such unauthorized uses, of course. Arguably multi-user Unix environments are less common now than such systems, where you very much do want to get emailed if, eg, the web server UID suddenly tries to run sudo.)

unix/SudoAndSecurityAssumptions written at 01:03:59; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.