Check out the new USENIX Web site.

Home About USENIX Events Membership Publications Students
Freenix 2000 USENIX Annual Technical Conference Paper    [Technical Index]

Check out the new USENIX Web site.

Webmin
A web-based system administration tool for Unix

Jamie Cameron (jcameron@calderasystems.com)
Caldera Systems

Abstract

This paper describes the design and implementation of the Unix administration tool Webmin, available from https://www.webmin.com/webmin/ . Webmin allows moderately experienced users to manage their Unix system through a web browser interface, instead of editing configuration files directly. The most recent version supports Apache, Squid, BIND, Samba and many other servers and services. It supports multiple operating systems and distributions, different languages, multiple users each with different levels of access, and SSL encryption.

The first part of the paper explains why Webmin was developed and the initial design goals, and compares the design to other similar tools such as Linuxconf. Subsequent sections cover the design and implementation of the detailed multi-user security model, the implementation of Webmin itself, how support for multiple operating systems is handled and how internationalization works. Finally, two Webmin modules are discussed in more detail and various problems explained before the conclusion.



1 Introduction

For the inexperienced user, Unix system administration can be daunting. Almost all services have configuration files that must be edited manually and often have complex formats. While these files are usually well documented in man pages, it is often unclear exactly how different sections and directives fit together. Furthermore, a single misspelling or missing punctuation character can ruin an entire configuration file.

To make matters worse, similar services have configuration files with different structures and locations on different kinds of Unix systems. For example, Solaris stores NFS exports in /etc/dfs/dfstab, while Linux, FreeBSD and HPUX use /etc/exports - and all four use different formats. For an inexperienced system administrator in charge of several different types of systems, these inconsistencies can make life difficult.

My aim in writing a system administration tool was to solve both these problems. It needed to provide a friendly user interface with basic error checking, and consistency across the many different Unix systems and distributions. Additional goals were completeness (all reasonable options for the service being configured should be settable) and non-destructiveness (comments and unknown options should be unharmed).

This paper describes the design, implementation and future of my system administration tool Webmin. Section 2 explains the design of the system, section 3 the implementation, section 4 covers two modules in detail, section 5 discusses problems encountered and finally section 6 concludes the paper.



2 Design

2.1 System architecture

I decided early on that the easiest and best administration user interface was one accessible through a web browser. A web-based interface is platform independent, easy to develop and accessible locally or over the network. I then began writing CGI programs in perl to be run under an Apache webserver, but eventually developed my own webserver written entirely in perl to remove the dependency on Apache, which may not be available on users' systems and dislikes running as root.

Perl was the natural choice of implementation language for this project, as it has strong string processing facilities for reading and updating configuration files, and is available on every Unix platform that I might want my administration tool to run on. Avoiding the need for compilation was also an important goal, as some Unix variants do not even ship with a compiler and there are many ways compilation can fail due to the lack of a key library. With perl, all these problems have effectively been already solved by the perl installation process.

While the web / perl / CGI architecture is simple and easy to develop, it is not perfect. Because almost every Webmin screen is generated by a CGI program, the web server must fork a new process for each page, which can be slow on underpowered or heavily loaded systems. This has been resolved in the most recent versions by having the web server execute CGI programs in-process, in a similar way to mod_perl. Response time can also be a problem when managing distant servers, as every form submission must be processed by the web server. The user interface capabilities of HTML are also inferior to what is possible with a real user interface toolkit such as Qt or Swing, although they can be improved somewhat through the use of Javascript.




2.2 Alternative architectures and tools

I considered two other possible architectures before deciding on the perl / CGI design :

  • A standard X11 application, written in C or C++ and using Motif or Qt
    This would have some advantages from a user-interface point of view, as X applications have far more controls and inputs available than web applications. However, C is not a good language for writing string and file manipulation code in and remote access would only be possible if the user was running an X server. Because remote access was a major design goal, a browser-based solution was preferable.

  • A Java applet client and server
    This option solves the remote access problem (because applets run in a web browser), while still allowing complex user interfaces to be developed. Unfortunately, at the time Webmin was designed Java applets were still rather unreliable, especially large and complex programs. In addition, Java's string manipulation capabilities are not much better than C and far inferior to Perl.

When I started development in 1997, Webmin was not the only administration tool for Unix system. Others available were :

  • Linuxconf
    While today Linuxconf is a very impressive tool with many of the same functions as Webmin, at the time its development had only just begun. Its internal design is different to Webmin in that instead of writing to config files directly, it stores an internal list of changes, which is only written out when the Activate Changes button is clicked. It has a modular architecture like Webmin, though the modules are shared libraries written in C++ rather than sets of CGI programs, and it supports multiple languages for the user interface and help screens.

    Linuxconf's method of batching config file changes has some advantages, such as the ability to have multiple related changes applied simultaneously. The biggest disadvantage is the possibility that changes made manually or by other tools could be overwritten unexpectedly if Linuxconf's modifications have not been applied for some time.

    While it supports text, GTK and browser-based user interfaces, most of the effort seems to have gone into the GTK interface. This makes Linuxconf excellent for local administration, but not as good for remote administration through a web browser. Other problems are the lack of support for non-Linux systems and the inability to handle multiple users with different levels of permissions.

  • Redhat Control Panel
    This is a collection of small programs shipped with Redhat Linux for configuring users, printers, networking and a few other services. While it is good for those few services, it can only run as an X application and only supports Redhat Linux config files.

  • SAM
    This is a X/Motif administration application shipped with the HP/UX operating system. Like the Redhat control panel, it does not support remote access and only allows the configuration of a few services such as NIS, users accounts and networking.

2.3 Modules

Almost all of Webmin's functions are divided into modules, each of which is a mostly independent set of CGI programs responsible for managing some Unix feature or service. The programs for each module are stored in a separate subdirectory below the base Webmin directory (the webserver document root), and thus each module is accessed by a URL like https://server:10000/module/ . Every module has some information associated with it, such as a human-readable description, the operating systems it supports, and the other modules that it depends upon.

When a user first logs in to the server, he will be presented with a list of all the installed modules to which he has access, with each module displayed as an icon from its directory. Each module is displayed in one of five categories (Webmin, System, Servers, Hardware and Others), with the module itself determining which category it is in. This layout was adopted after the original method of showing all modules on one page became too large and cluttered.

The module system makes the distribution and addition of new third-party modules simple. Third-party modules can be distributed as Unix TAR files (normally with a .wbm extension) for installation into existing Webmin servers. Because each is fully self-contained, the installation process consists of nothing more than untarring the module file and adding it to the access list of the current user.

At the time of writing Webmin has 38 standard modules, capable of configuring the Apache webserver, Unix users and groups, Samba, Squid, Sendmail, NFS exports, disk partitions and more. There are also 17 third-party modules for services such as IPchains, Qmail, NetSaint and others.

2.4 User interface design

Because Webmin uses a web / CGI architecture, all user interfaces are simply HTML pages and forms. The major goals in designing the Webmin user interface were :

  • Consistency
    I wanted all screens to have a consistent look and feel, so that novice users could easily find their way around. This meant using a standard color scheme, title layout, footer and common interface elements, such as tables of icons.

  • Simplicity
    To make screens easy to use (and to avoid the problem with large forms in some browsers), I wanted to limit the amount of information and form inputs displayed on each screen. To achieve this, many functions are broken down into multiple screens although it would be possible to put all the information on one page.

  • Compatibility
    Because there are so many web browser types and versions in use, I chose to use only the lowest level of features possible. This meant no frames, DHTML, Javascript or Java unless the there was no alternative (for example, the File Manager feature is written in Java because it could not be done any other way), or for adding non-vital features (such as the optional file selection dialog in some screens).


2.5 Security

Because Webmin runs through a web server, the first level of security is a standard HTTP login prompt displayed when the user attempts to access the server. To prevent brute-force attacks, Webmin can be configured to delay an increasing amount of time before responding to each incorrect login. This will not defend against sniffing the network for the password of a valid user, which is why Webmin is also capable of running in SSL mode if the OpenSSL library has been installed on the system it is running on.

A key feature of Webmin is support for multiple users, each with different levels of access. The initial design only supported granting each user either total access to a module, or no access at all. This turned out to be inadequate however, as many modules could be used in ways to gain root access and thus total control of the system - for example, a Webmin user granted access to all cron jobs could just create a job run as root and thus take over the system.

The solution to this problem was the creation of an additional more fine-grained level of security. This allowed the granting to users only certain functions of each module, rather than total control. For example, it is possible to give a Webmin user the right to edit cron jobs only for selected Unix users, or the right only to manage certain Apache virtual servers. This feature can be very useful if a master administrator wants to delegate some tasks to other admins, without giving them access to the entire system.



3 Implementation

3.1 Introduction

Webmin is implemented as a large number of perl CGI programs, arranged into subdirectories called modules. Each module handles the configuration of some Unix service, such as Apache, NFS exports or cron. Each module has one or more libraries of common functions, included by each CGI program with the require command. Typically, these functions deal with the actual configuration files, converting them to and from data structures used by the actual programs. That way, there is a layer of abstraction between most of the CGI programs and the system - although this abstraction is not enforced, and is bypassed in some cases.

By abstracting the user interface away from the actual configuration files, not only is much repeated code avoided, but also the possibility is opened up for modules to call each other. For example, the module fdisk (Partitions on Local Disks) has a library fdisk-lib.pl that contains functions for discovering the disks and partitions on Linux systems. These functions are called by the raid (Linux RAID) module to find disks available for inclusion into a RAID array, by the lilo (Linux Bootup Configuration) module to display bootable partitions, and by the mount (Disks and Filesystems) module to display mountable partitions.

Webmin has its own web server called miniserv that comes as part of the distribution. Unlike a general-purpose webserver such as Apache, it has very few features and only supports the retrieval of files and the execution of CGI programs. Because it is written in Perl like the rest of the Webmin programs, it has the ability to run CGIs in-process without the need to fork and exec a new Perl interpreter, in a similar manner to the mod_perl Apache module. This provides a substantial speed increase on slow or low memory systems.

3.2 Common functions

In addition to the function library in each module, there is a file named web-lib.pl in the top-level Webmin directory that contains functions used by all modules. Every CGI program must require this library, either directly or by via its module library. In addition, every CGI program must call the function init_config to read in the module configuration file, perform security checks and set several global variables. Typically, this function is called by the module's function library just after including web-lib.pl.

web-lib.pl includes many different functions, which can be roughly broken down into the following categories :

  • Standard user interface functions for generating headers and footer, icon tables, user and file dialogs and so on. These help provide a consistent look across all Webmin screens.

  • File manipulation functions for inserting, replacing and deleting lines in configuration files.

  • Network functions, for downloading files via FTP and HTTP.

  • Functions for making 'foreign' function calls. These are calls from CGI programs in one module to functions in another module's library, done in such a way that the called function has its environment set up just as if it was being called by one of its own CGI programs.

  • Webmin-specific functions for getting information about other modules, access control, the Webmin version and so on.

  • Assorted convenience functions, including CGI functions for reading form inputs into perl variables.

3.3 Platform Independence

In order for Webmin to work on the many different Unix variants and Linux distributions, it needs to know exactly which operating system and version the user is running. This information is determined at install time, either by asking the user or automatic detection from the /etc/issue file or the output of uname. Once the operating system is known, the appropriate configuration for the OS is selected from each module and used to find and parse system config files. Activate configuration files are stored in the /etc/webmin directory, with each module having its own subdirectory for its configuration file and any other temporary files that it might create.

For example, the location of the Apache httpd.conf file differs between every Linux distribution, and even between different versions of the same distribution. Webmin can deal with this though, as it knows where httpd.conf is located on all the different operating systems and distributions that it supports. Possible alternatives would be to ask the user where every config files is (not very user friendly) or to find the config files automatically by searching the entire filesystem (not always possible, as many config files do not exist initially).

Because some operating system behavior is too complex to encode in the simple Webmin config files, some modules have separate Perl libraries for each OS. For example, in the Disk Quotas module each OS library implements the same set of functions, but in a different way to handle the different ways quotas work on each operating system.

3.4 Internationalization

In order to support different languages, all the text strings from most Webmin modules are no longer hard-coded into the programs, but are instead stored in separate language files. Each module has one file per supported language, the one to use being selected by the user's current choice of language. When a program needs to display some text or message, it uses a message code that is looked up in the appropriate language file and converted to the actual text is the correct language.

Because some words like Save, Create and Default are used by many modules, there is a master set of language files that contain these messages for the use of all modules. These master files also store messages used by the main Webmin menu and some programs that are used by all modules.

The online help system also supports multiple languages, with each help page stored in all the supported languages. When a help page is requested, the file for the current language is read and displayed. A similar selection process is also used for displaying the module configuration page in the correct language.

With all translation in Webmin, if a message or page is not available in the user's currently selected language then the default language (currently English) will be used instead. This means that partial translations can be contributed and are still useful, and that the addition of new messages will not require the immediate update of all language files.

3.5 Security Implementation

Because Webmin runs through a web server, the first level of security is simply HTTP authentication enforced by the web server using usernames and passwords from a standard Apache-style users file. Because the server also enforces checks against brute-force attacks and because the authentication protocol is relatively simple, there is little chance of an attacker breaching this level of security.

The second security level is enforced by module CGI programs themselves, all of which check the HTTP username against the list of allowed users for the module. This checking is done by the common init_config function which every program directly or indirectly calls. Because of this, any program that does not check whether the current user is allowed to access it could theoretically be a security hole. A better alternative would be to have this level enforced by the webserver, although that would complicate running Webmin under other webservers such as Apache, as any change to the list of modules a user has access to would require changing the Apache configuration as well.

The third security level of fine-grained module access control is also enforced by the CGI programs, but the complexity and variability of this access control means that there is no common function that the programs can call. Instead, each program checks a list of actions allowed by the current user and displays an error message if the action the user requested is unavailable. This means that the potential for accidentally creating a security hole is much greater, but I see no other alternative.

The Webmin webserver can also use the OpenSSL and Net::SSLeay libraries to encrypt communication between the server and browser with SSL. Thanks to these libraries, the implementation of SSL is relatively simple - the only difficulty is the provision of an SSL certificate, which normally must be come from a trusted source like Verisign, and associated with the hostname of the server. Because Webmin's certificate is not valid, there is no defense against man in the middle attacks that trick the user into thinking he is accessing his Webmin server when he really is not.



4 Module Discussions

4.1 Apache Webserver

The Apache Webserver module is one of the most complex, due to the massive number of configuration file directives supported by Apache. My objective was to support all common Apache versions, and as many different directives as possible. This was made more complex by the large number of Apache modules, an unknown combination of which could be compiled into each user's Apache installation, and each of which could add several new directives.

Fortunately, it is possible to query an Apache installation for version number, compiled in modules and dynamically loaded modules. This information combined with the Webmin module's built-in knowledge of the availability of each directive in each Apache release makes it possible to edit the Apache config files correctly. However, keeping up with the changes in each Apache release can be difficult.

Once the supported modules are known, a Perl library for each Apache module is read in, each of which contains a function for editing and updating each module directive. Each directive in each module is assigned a category (such as Log Files or Access Control), so that when the user visits the Log Files submenu inputs for all the directives in all modules related to that category are displayed. This categorization system allows the large number of directives to be broken down logically instead of all being displayed on one huge page.

Because Apache supports subsections such as <VirtualHost> or <Directory>, the user interface is further categorized to allow the editing of directives in those sections, which are also broken down into categories. This way even a large Apache configuration with many virtual servers can be easy managed, and all supported directives can be editing in all sections.

Because there are some Apache directives (such as those in the mod_rewrite module) that are too complex for Webmin to manage, the module also provides support for manually editing parts of the config files. Comments and unsupported directives such as these are not effected by the other pages in the module.







4.2 Users and Groups

The Users and Groups module is designed to allowed the creation, modification and deletion of Unix users and groups by directly editing the /etc/passwd, /etc/group and /etc/shadow files. This is complicated slightly by the difference in format and existence of those files on different operating systems - for example, some Linux distributions do not have an /etc/shadow file at all, while some BSD-derived systems use the file /etc/master.passwd as their main source of user account information.

This functionality already exists in many other administration tools however. What makes Webmin unique in this area is the ability to update other parts of the system when a user is created or modified. For example, you can configure the Samba module to have a user added to Samba's encrypted password file whenever a Unix user is added, something that normally must be done manually. Similarly, the administrator can setup default quotas to be assigned when new users are created.



5 Problems

After several years of development and use, I have identified several design and implementation problems in Webmin :

  • Second and third level security
    This is still dependent on checking by individual CGI programs, and thus security breaching are more likely than they should be. While the second level is relatively secure and can be improved, there is no easy way to improve the fine-grained third level of access control. Only careful coding and close examination of the code by others can help solve this problem.

  • Coding style
    The development of Webmin began when I was unfamiliar with Perl 5 features such as packages and modules, and unfortunately the initial coding style has continued through to this day. A good implementation would have made each module a separate Perl module, allowing modules to call each other using standard Perl syntax instead of the ugly foreign_ functions. The best long-term solution is to recode all the Webmin modules as proper Perl modules, so that function calls between them can be made with Perl's module::function syntax.

  • Internationalization
    Because multi-language support was not part of the original design, several older modules still have strings hard-coded into their programs. Internationalization of these modules requires nothing more than time and tedious work, as there is no reliable way this process could be automated.

  • Keeping up with new releases
    Because new releases of servers such as Samba, Apache and Squid often have new configuration directives or change the meanings of existing ones, Webmin must keep up with the latest version of these programs. In addition, new releases of operating systems and Linux distributions which add new features and change the locations of config files much also be kept track of. This is an unavoidable task, but relatively easy if I download each new release of the supported servers and install each new version of operating systems and distributions to which Webmin has been ported. Fortunately, programs such as VMware make the testing of new PC-based operating systems relatively easy.

  • Documentation and help
    Most modules still lack online help, and there is no overall manual or instructions on how to use Webmin. While most screens are relatively self-explanatory to experienced system administrators, beginners would benefit from a simple set of instructions on what DNS domains are and how to set them up, how to create Unix accounts and so on.



6 Conclusion

From its initial releases that contained only a few modules, Webmin has met its design goals and developed to support many commonly used Unix services, becoming a useful and powerful administration tool. This paper has covered the design and implementation of Webmin, and should provide information for others planning to develop similar tools or contribute to Webmin.



7 Availability

Webmin is distributed under a BSD-like license, and thus is freely available. It can be downloaded from https://www.webmin.com/webmin/ in .tar.gz , RPM and Solaris package format. Several third-party modules contributed by others can also be downloaded from the same URL.









This paper was originally published in the Proceedings of the Freenix 2000 USENIX Annual Technical Conference, June 18-23, 2000, San Diego, California, USA
Last changed: 7 Feb 2002 ml
Technical Program
Conference Index Home
USENIX home