in reply to Re: Secure Webmin
in thread Secure Webmin

++

Interesting post! I really don't know anything about webmin. I just know I've heard bad rumours, which could be totally unfounded, and then seeing that everything runs as root and yikes! Maybe I'm just scared of the big bad root wolf.

I didn't actually set out to make an alternative to webmin, I just started solving problems at work and over time an alternative webmin began to evolve. I've seen posts from people saying "I want an alternative to webmin" and I said to myself "Hey, I have one of those laying around here..."

How is my privileged server more secure than webmin's privileged server: Two reasons. First, it does less. Fewer lines of code running as root means fewer bugs that translate to root compromise. Second, by not handling HTML, HTTP etc.. etc.. and instead handling only a simplified restrictive RPC-ish protocol, the job of discriminating between legitimate input and illegitimate is much simpler. It doesn't have to be forgiving of users and web browsers like a web interface does.

And no, this doesn't solve the XSS problems at all. Maybe it just solves a PR problem.

I wonder how hard it would be to make webmin itself use privilege separation? If you followed the same idea as I have, you'd take out the web server code and replace it with RPC-of-choice code, JSON RPC, YAML, SOAP, whatever... Really simple stuff in practice. Then take the web code and build it into a separate non-root app that talks your RPC protocol with the privileged webmin bit. One of the drawbacks is you have to authenticate everything twice. Once in the web server and once in the privileged server. That doesn't bother me, but it might have repercussions I haven't thought of.

Does that sound totally crazy? I'll take a look at the webmin code and see if I can see a way to do that...

Updated: added "How is my privileged server more secure than webmin's privileged server" paragraph.

Replies are listed 'Best First'.
Re^3: Secure Webmin
by SwellJoe (Scribe) on May 30, 2009 at 11:12 UTC
    "First, it does less. Fewer lines of code running as root means fewer bugs that translate to root compromise."

    Certainly a valid theory. miniserv.pl (the Webmin web server that runs as root) is currently 3,912 lines of code according to sloccount. It pulls in the following standard Perl modules: Socket, POSIX, Time::Local, and optionally MD5, PAM, and Net::SSLeay.

    But, everything else that Webmin runs (subject to ACLs and module access rules) is running as root, which is several hundred thousand lines of code...then again, it is a system administration tool. Only root has the necessary privileges to do all of that work. So, privilege separation in the OpenSSH sense (which is truly/deeply awesome) won't be useful here, since we can't just spin up a process running as a less privileged user once we know who they are (Usermin forks a user-owned process, though, so it is roughly similar).

    "Second, by not handling HTML, HTTP etc.. etc.. and instead handling only a simplified restrictive RPC-ish protocol, the job of discriminating between legitimate input and illegitimate is much simpler. It doesn't have to be forgiving of users and web browsers like a web interface does."

    This is, perhaps a valid direction for Webmin to go. Webmin already has a standard XML-RPC interface, as well as a lightweight RPC interface of its own (and Virtualmin has a mostly REST interface for making simple requests, though it has a very limited repertoire). However, I'm not entirely sure HTTP is a particularly bad protocol for this purpose. It's pretty light, pretty well-defined, and pretty flexible. Having it serve something other than HTML would obviously be necessary, though.

    "If you followed the same idea as I have, you'd take out the web server code and replace it with RPC-of-choice code, JSON RPC, YAML, SOAP, whatever..."

    XML-RPC is already supported by Webmin; though I believe it has a separate execution path that is not subject to ACLs or module access (it is effectively a root-level account).

    So, one could, I suppose, run miniserv.pl locally, and build a web or whatever UI frontend using whatever tools you liked. Converting XML-RPC to a lighter protocol (I also like JSON for this; I've recently done some conversions of some modules to provide JSON rather than HTML for us with a jQuery frontend) wouldn't be overwhelming. Adding the ACLs back in probably would be...but you might want control over that in your front end anyway, if you're wanting to leverage Catalyst, which already has some conception of users and groups and such.

    "One of the drawbacks is you have to authenticate everything twice. Once in the web server and once in the privileged server. That doesn't bother me, but it might have repercussions I haven't thought of."

    There's the obvious security concern of where the password for the backing root-level daemon comes from and where it is stored while in use, since the web server isn't running as a privileged user. If it's the same as the web application login, you're not gaining as much from the separation (I'm assuming here that at some point you'd have feature parity with Webmin, wherein most administrative functions have a UI analog). If it's stored somewhere on the system, you'll have to have a setuid binary to interact with it which opens a new can of worms from the perspective of local users (not insurmountable, and not dramatically more risky than anything else we're talking about here).

    I think there might actually be something to this separation idea, though I wonder how much impact it has had on OpenSSH. There have been a couple of serious issues in various OpenSSH variants since privsep was introduced, and it didn't prevent those particular problems. Since the goal of privilege separation is to minimize the damage when a hole is found, it's worth thinking about whether it's actually had that impact on a popular implementation. I probably just don't understand the issues well enough, but looking over OpenSSH' security advisories since the introduction of the feature, there haven't been any situations where privilege separation has been the saving grace...but maybe there are issues that never existed or were never reported as issues because of privilege separation.

    I'll mention a couple of things that Jamie has been working on lately, as they are relevant to this discussion. In Virtualmin, we have a command line tool called "virtualmin", which allows things like:

    virtualmin create-user --domain virtualmin.com --user joe --random-pass

    Doesn't matter what it does (though it's probably obvious)...what matters is that right now, it loads the WebminCore module, and then the necessary libraries within Virtualmin to perform this task. Thus, it must run as root, and so only root can use it. This limitation didn't seem so onerous at first, when the command line tools were mostly for batch operations and such...but now that everything in the Virtualmin UI is accessible via the command line, it means that even though a less privileged user (like the owner of the virtualmin.com domain in the example above) could perform this action in the UI, they couldn't perform it on the command line, even if they have ssh login privileges. So, now it's been acknowledged as a problem.

    The possible solutions are obvious, I guess, since we're all on the same page here now I think. The command line needs to either be setuid and have ACL awareness added in, or it needs to connect to the running Webmin daemon and work indirectly (and also be subject to ACLs). The latter is actually probably much less work, while also being a more likely to be secure design (I'm hesitant to say "more secure" or "less secure" since a good design with poor implementation will still be exploitable, and a poor architecture with a perfectly bug-free implementation could potentially be secure).

    So, while it's being implemented for somewhat mundane reasons (some users want to be able to do things from the command line that they can already do in the UI), the end result is that it seems likely that Webmin is going to be moving in that direction. Also, like the "virtualmin" command there will likely be a "webmin" and "usermin" command, eventually...which makes this direction seem all the more likely.

      Yes! The Webmin daemon should not care if the commands come from the command line or a web ui or a GUI or whatever. If a user knows JSON, they should be able to connect via telnet over SSL and run webmin commands.

      Important conceptual difference: In my system there is no difference between Usermin and Webmin. All users authenticate and different users are allowed to run difference commands. For instance, anyone on the IT staff can change anyone elses quota for them, but normal users can only change their own quota.

      The conversation between the client (web ui) and the privileged daemon takes place over one TCP connection and contains only one transmission and one response. Every request contains the username and password. There is no concept of sessions in the privileged daemon.

      Here's how authentication/authorization works on my system. Lets say my users are listed in LDAP. I want to let any user check their own quota. Bob logs into the web UI. His username and password are stored in plain text in the Catalyst session stuff somewhere. (This may be horribly horribly wrong.) The Catalyst app uses an LDAP module to check if Bob is really Bob. Bob is now logged into the web ui. Bob clicks the 'check my quota' link. Because Bob does not need to be a special user to check his own quota, no further authz checks are performed. The web ui forms a YAML request containing his username and password from the session data and the request for Bob's quota, and sends that to the privileged daemon. The privileged daemon gets this information and uses an LDAP module to check if Bob really is Bob. Since Bob needs no special privileges to check his own quota, he is considered authorized ( a check against a role database would be performed if he was trying to check someone else's quota). Then the privileged daemon performs the actual check and returns the result.

      Here's a bit of security philosophy I picked up as an OpenBSD admin: Don't think about exploits, think about better code. The reason is, you don't know what new exploits are going to look like. You shouldn't need to know a thing about attacking servers to write secure code.

      So, one could, I suppose, run miniserv.pl locally, and build a web or whatever UI frontend using whatever tools you liked. Converting XML-RPC to a lighter protocol (I also like JSON for this; I've recently done some conversions of some modules to provide JSON rather than HTML for us with a jQuery frontend) wouldn't be overwhelming. Adding the ACLs back in probably would be...but you might want control over that in your front end anyway, if you're wanting to leverage Catalyst, which already has some conception of users and groups and such.

      I just re-read this and realised an important point: miniserv.pl and the web front-end both need to have all the ACLs and any other protective logic. You can't trust your web front end.

      It shouln't be that hard to implement, though. You put your ACLs or whatever into a module and use the same module in both.

      Catalyst is a great example of code that makes it really easy to implement your own ACLs, roles, whatever, so I really recommend taking some time with it if you haven't already.