Programming codifies a process into something that can be executed on a machine. But this is psychologically no different than codifying any other process into a set of rules for any interpreter, not necessarily mechanical.
The link between programming code and law has been noted in the past: the laws try to leave no room for argument, so they become long, and subject to similar problems as computer code. Particularly unintended consequences: witness the spate of sexting prosecutions that try to brand teens as sex offenders for a decade for sending nude—or sometimes even just swimsuit—pics to their significant other.
Laws writ small are the ordinary rules of everyday life. Those Dilbert moments where you receive multiple conflicting rules? Those are bugs.
Tuesday, November 6, 2012
Friday, November 2, 2012
The Pointlessness of sudo's Default Run-As User
Amazon Linux ships with the default configuration*:
This is entirely pointless because it also ships with the common PAM configuration, in which /etc/pam.d/su contains:
When you give any account root access, they probably have the whole machine. I'm not sure what sudo was hoping to accomplish by "limiting" the default Runas_Spec to root.
* It also ships with
ec2-user ALL = NOPASSWD: ALL
Which means, ec2-user is allowed to run any command, without providing a password, while logged in from any machine. But only as root—since the Runas_Spec is missing, the default of (root) is assumed.This is entirely pointless because it also ships with the common PAM configuration, in which /etc/pam.d/su contains:
auth sufficient pam_rootok.so
So the game of Simon Says, in order to bypass the root-only sudo restriction so you can run as any user, password-free, without touching files in /etc in advance, becomes:
sudo su -s /bin/bash $TARGET_USER <pwn.sh
Normally, su uses the shell for the user as listed in /etc/passwd, but if we're interested in a /sbin/nologin account, then we can set any other shell listed in /etc/shells with the -s flag.When you give any account root access, they probably have the whole machine. I'm not sure what sudo was hoping to accomplish by "limiting" the default Runas_Spec to root.
* It also ships with
Defaults requiretty which means you actually need someone to allocate you a controlling terminal for sudo to work, even though ec2-user doesn't need a password, and visiblepw is disabled by default.
Thursday, November 1, 2012
Bugs in Production
The amount that a bug hitting production annoys me turns out to be proportional to
Yeah. I crashed our site the other day over a trivial logging change, intended to gather debugging information for a rare condition of the latter sort. It was so trivial it couldn't possibly go wrong, meaning
log(affected_users / time) * stupidity_of(bug). If nobody can use the core functionality of the app because of something that would have failed a perl -c check, that yields a lot more angst than "some non-critical task doesn't work for one (uniquely configured) client when the day of the month is 29 or more," even though the latter is often more difficult to diagnose.Yeah. I crashed our site the other day over a trivial logging change, intended to gather debugging information for a rare condition of the latter sort. It was so trivial it couldn't possibly go wrong, meaning
stupidity_of(bug) was quite large.
Monday, October 29, 2012
When Layering Goes Bad
A lot of systems are built in layers. Games are often split into engines and scripts. Another classic is the "three tier" architecture with data storage, application model, and view-controllers split out onto individual machines.
But more often, I run into systems where code is taking a core sample instead of building on the layers.
But more often, I run into systems where code is taking a core sample instead of building on the layers.
Thursday, October 25, 2012
War Story: Apache, SSL, and name-based vhosts
Note: this post was written about a year ago, before we completed some major upgrades to our infrastructure. I meant to post it as soon as we were done, but it got buried under too many other posts and drafts. The original post follows, without edits for temporal accuracy.
You can do it The Right Way and use SNI if:
Otherwise, you have to try a bit harder.
You can do it The Right Way and use SNI if:
- You don't care about Internet Explorer (7 and 8) on Windows XP.
- You have Apache 2.2.12 or newer.
- You have openssl 0.9.8f or newer with TLS extensions; extensions are included by default in 1.0.
Otherwise, you have to try a bit harder.
Tuesday, October 23, 2012
Labels
I figured out my underlying problem with Yegge's liberal/conservative (libertarian/authoritarian) division of programming cultures.
People like looking down on those considered inferior. "Conservative" adds another way to do just that.
People like looking down on those considered inferior. "Conservative" adds another way to do just that.
Tuesday, October 2, 2012
Compile Time
You might have heard that in Lisp, the whole language is there all the time. You can read while compiling, eval while reading, and so on. This isn't necessarily exclusive to Lisp—Perl offers BEGIN/CHECK/UNITCHECK—but it isn't exactly common in mainstream languages.
At first, it sounds brilliant. "I can use my whole language to {read the configuration | filter some code on-the-fly | whatever} for super fast run-time performance!" But there's a consequence that nobody seems to realize until they've gone far down that path: if you have a compile-test switch like
This is almost a trivial statement: compile testing has to compile the code; you're running code at compile time; ergo, your compile-time code will run. But beware of the details:
At first, it sounds brilliant. "I can use my whole language to {read the configuration | filter some code on-the-fly | whatever} for super fast run-time performance!" But there's a consequence that nobody seems to realize until they've gone far down that path: if you have a compile-test switch like
perl -c, you can no longer guarantee that using it is safe if you wrote code that runs during compilation.This is almost a trivial statement: compile testing has to compile the code; you're running code at compile time; ergo, your compile-time code will run. But beware of the details:
- If you read your configuration files and exit if something's wrong, then you must now have a valid configuration to run a compile test.
- Generalizing the previous: if you pull anything from an external service, your compile test depends on that service being up. It may also depend on having your credentials for that service available.
- If you do a ton of work to prepare a cache for runtime, you have to wait for that—then the compile test finishes and throws it all away.
- If you have an infinite loop in compile-time code, the compilation test never completes. Not a problem for a human at the keyboard, but could be difficult in a script (e.g. VCS commit hooks).
- If the language allows you to define reader macros or source filters at compile time, then you can't even syntax-check the source without running the compile-time code; the lex phase now depends on the execution state that accumulates during compilation.
- If your code assumes the underlying platform is Unix because that's what the server is, you can't compile test on Windows. Or, you have to write your whole compile phase cross-platform.
Subscribe to:
Posts (Atom)