Short Version:
I've written a secure alternative to webmin, and I'd like to make it available to the community. Does anyone want to help? Have interest? Want to throw tomatoes?

Long Version:

Webmin, as you may know, is a web utility that gives you the ability to administer your machine from the web. It does this by providing plugins for different administrative tasks such as DHCP admin, or DNS admin and so on.

A lot of people, myself included, avoid webmin because it's pretty darn scary from a security point of view. Specifically, it runs everything including it's own web server as root.

Over time, I've solved a number of problems specific to my workplace that would fall into the webmin domain and over time my solutions have become more generalized, pluggable, and generally more like a secure alternative to webmin. Here's why my thing is cool:

Before it can have any hope of being useful to anyone other than me, it needs a lot of work. There's a lot of stuff in the code that would need to live in configuration. It would need an installer. The plugin system needs to be standardized, the web ui part needs to be more pluggable. etc... etc... etc....

Does anyone want to help me bring this out into light of day? If you're interested, but don't want to spend a ton of time, even glancing over the code base and giving suggestions would be more than awesome. Even just asking me to clarify this post would probably help me improve my thinking and hence my alternative webmin thingy. Oh, and any help coming up with a name would be good too.

And now a short description of how my alternative webmin actually works:

I have a daemon process that runs as root. It has plugins for various tasks. At this time, those tasks are things like checking disk quota, requesting a higher quota etc.. It listens to a local unix socket and accepts commands over that socket.

The commands are very limited and well defined, so it's hard to trick it into doing something it's not intended to do. Specifically, a valid command is a YAML'ized hash containing details like:

{ command => 'get_quota', username => 'jdoe', password => 'secret', }

This is a good thing because it completely separates the privileged stuff from the user interface. You can use the web interface, or you can create any kind of interface you like. You could make a gui, or a text interface or anything.

On the user interface side, I have a Catalyst app that has a model that sends commands to the privileged daemon process. It's all pretty hard-coded at this point, but I've started heading toward using widgets, where new capabilities/jobs can add a little ui blob to a control panel.

That's about it for a basic description. If anyone's at all interested or curious, ask away.

--Pileofrogs

Update:

I've cobbled togeather a tar file of my privileged daemon. I had to give it a quick review to make sure I didn't have $root_password = "secret" in there anywhere. I'll do the same with the web front-end soon.

I've named it Sysadmin or Sysadmind for now, but a better name is definitely in order.

http://seattlecentral.edu/~dmartin/dist/Sysadmin.tar.gz

Again, this is not in anyway ready for public use, it has tons of site-specific hard-coded stuff that needs configifying.

Replies are listed 'Best First'.
Re: Secure Webmin
by SwellJoe (Scribe) on May 28, 2009 at 02:18 UTC

    I would like to suggest that calling your thing a "secure Webmin" unfairly implies that Webmin is insecure...when, in fact, it has an excellent security history. The last serious exploit was over three years ago, and the security history in general is roughly on par with OpenSSH. Webmin's security history is public: http://www.webmin.com/security.html

    Only a small percentage of security issues in Webmin would have been prevented by having a privilege separation model, and none in the past three years fir that description. Most recent issues have been XSS-related issues rather than direct exploits of the root-level nature of Webmin's web server...and XSS could hit your privsepped model just as well (being careful of XSS is, of course, good practice, but there's nothing inherent about your model that makes XSS easier to avoid).

    But, I would be curious to know more about the privilege separation...and how your root-level daemon is more secure than Webmin's root-level daemon while still being able to perform arbitrary configuration. (Webmin's root daemon happens to be the web server that runs the modules. But it's pretty simple as web servers go, and has 11+ years worth of battle-testing in millions of deployments. I'd happily wager that your code can be broken more easily than Webmin, just by virtue of its age and how many security researchers and crackers have tried to break Webmin over the years.)

    And, have you considered lending some of your security expertise to Webmin itself rather than reinventing the wheel (and the 100+ standard modules, and several hundred third party modules)?

    Anyway, it sounds like an interesting project...but if security is your primary beef with Webmin, it seems like somewhat misplaced effort.

    Full disclosure: I'm one of the Webmin/Usermin/Virtualmin developers. And I find it irritating when folks imply or state emphatically that Webmin is insecure. The facts simply do not justify the accusation.

      ++

      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.

        "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.

        I'm not sure I understand how. Could you explain a bit more?
Re: Secure Webmin
by ruzam (Curate) on May 28, 2009 at 02:13 UTC

    Secure Webmin or a replacement Webmin type application? Maybe a new project name is in order?

    Either way, ++ for the gumption to take it on. If you were in beer distance, I'd offer a round to compare notes.

Re: Secure Webmin
by wazoox (Prior) on May 28, 2009 at 14:30 UTC
    As you may have seen in my post : Building a web-based system administration interface in Perl, I have similar projects. Actually it changed somehow : one of my colleague is working on it right now, and not me :) So obviously it may be really interesting to share code before it all becomes too redundant!
Re: Secure Webmin
by afoken (Chancellor) on May 28, 2009 at 13:22 UTC
    I have a daemon process that runs as root. It has plugins for various tasks. At this time, those tasks are things like checking disk quota, requesting a higher quota etc.. It listens to a local unix socket and accepts commands over that socket.

    How do you prevent an unprivileged user (other than the web server) accessing that socket to gain root rights?

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      My privileged daemon authenticates and validates just like any other server. It could be open on the internet and it would be OK.

      In practice, I have it listening on a unix socket, so only localhost can contact it, and I have the permissions restricted so only the web front-end can talk to it. The web front end is a Catalyst app running fast-cgi as a daemon process which talks to apache over a socket. This lets me run the web proces as yet another user, different from the web server user.

        How do you handle the authentication details for the root daemon?
Re: Secure Webmin
by John M. Dlugosz (Monsignor) on May 28, 2009 at 16:32 UTC
    I'm using Webmin on my server, and for me the best thing to "get it out" is to make it available for Debian's Synaptic or other package manager to install. Get it into the inner circle of stuff that Debian can get directly by default, which I think are properly licenced and well tested with that build.

    How would I change to it, now?

      You wouldn't. You would continue to use webmin. In the unlikely even that my alternative becomes mature and popular and makes it into the debian packages, you'd consider changing.