Because Webmin runs with the privileges of the root user, it is vitally important that Webmin be locked down tightly before allowing remote internet access. Historically, Webmin is pretty secure, but there have been exploits discovered in the past, and there will probably be exploits discovered in the future. Any tool which runs as root has the potential to be an entry point for a malicious cracker to unlimited access to the machine.
So in order to prevent all of the woes that can result from an exploited machine, we’re going to take a few steps to limit our risk, and minimize the damage that can be done without us noticing. We will briefly discuss password policy, application level network access control, SSL, and firewall configuration.
Countless studies and anecdotes from both sides of the security issue (crackers on one side, and those who implement systems to protect against crackers on the other) have told us that cracking weak passwords is nearly always a reliable, if time consuming way to obtain illicit entry into a system. Because many users, and even system administrators use weak, easily guessed passwords, it is quite common for a determined hacker to run an automated password hunt on a target system. Another, perhaps even more frightening, technique crackers use is what is known as Social Engineering.
Social Engineering is a technique as old as malicious cracking itself, which plays on human nature to overcome technical barriers to entry by going the easier path of getting through a human’s line of defense. One common technique is for a cracker to pose as tech support staff, and simply ask for the users password so they can “test” something or other on the network. This works disturbingly often, even among technically savvy users. This type of attack can happen via any communications medium, including telephone, IRC, email, etc. and its continued success relies on the human desire to be helpful. This technique is often enhanced through the use of other subtle additions to further lower the guard of the person answering the phone or email. The cracker may mention that there is a problem on the network, of some sort, which taps into another fundamental aspect of human nature: complaining about the state of the network. Everyone complains about the state of the network in an office at one point or another, and when a “tech” calls to say he is going to fix it it further establishes his credibility with the victim. In the users mind, it seems obvious that no outsider would know about the “network problems” he has been experiencing lately, so this caller must be legitimate.
In my time of supporting Unix servers I’ve noticed another aspect of human nature that is sometimes exploited by crackers. When asked to type in their password, some users spell it out quietly under their breath while entering the letters. Experienced typists are far less likely to speak the text they are entering in this way, but it may be a last resort trick used by a Social Engineering cracker to simply ask the user to type in their password a few times (because by the second or third time, the user is either excited enough to be taking part in “solving a network problem” to begin talking or singing along with their text input or be frustrated enough at being kept away from his real work to start muttering along with what he is typing). Users should be cautioned against this habit. This may all sound like a rather silly way to break into a network, when Hollywood movies always show us a lone cracker in a basement filled with computer junk, but it is likely that the most determined, and thus the most dangerous, crackers will use these techniques before attempting more time consuming technical attacks like brute force password searches. These techniques work, if users are not aware of the danger.
This only scratches the surface of how crackers operate. But it does begin to make it clear that good passwords and educated users are core to any successful security policy. Insist upon quality passwords, and notify your users of the policy. A good password policy might include the following requirements:
A good password should be a minimum of 6 or 8 characters. All other things being equal, longer passwords are more secure than shorter passwords, simply because a brute force attack has more possibilities to go through to find a password that works.
It is generally recommended to avoid plain dictionary words, or even dictionary words at all. The reason for this is that brute force attacks usually involve attempting all of the words in a word list, or in a dictionary file. Real words are simply easier to guess and easier to obtain through brute force attacks. Weird spellings, odd capitalizations, and combinations of word fragments can all be used to create less easily guessed passwords without making them much less memorable for the user. After all, if the user has a drawer full of their passwords on sticky notes because they can’t remember them, the cure is worse than the disease.
Another good possibility is to enforce the inclusion of at least one number in all passwords. This automatically increases the pool of possible passwords by an order of magnitude, even if dictionary words are allowed. Again, this doesn’t make passwords significantly less memorable for the user, but does increase the security of the password. However, use of birthdays, anniversaries, etc. should be discouraged as these are easily guessable, and more prone to Social Engineering attacks.
In environments where security is important, it is wise to implement a mandatory password change after some specified period of time. The inconvenience to users of this choice should be carefully balanced against the security needs of the environment. It is less useful if frustrated users alternate between two passwords because they are being forced to change them every two weeks, or even worse if they write them down somewhere in their desk because they don’t want to take the effort to remember a new password every week. Once every 6 months is probably frequent enough for all but the most extreme circumstances.
In the event that a cracker attempts a brute force attack on your server, password timeouts can be very effective at making the process extremely time consuming, or even impossible. Going on the assumption that a user usually will not mistype their password more than a few times, many authenticators can timeout and refuse to allow any login for that user for a specified period of time after that number of failed logins is reached. With this feature enabled, it becomes a daunting task to use brute force password searches to break into a system that has password timeouts of this sort. It can potentially increase the time it takes by months or years, and the likelihood of detection of the scans considerably since one or more users will begin to complain of being unable to login (since their password is in a state of timeout most of the time).
This is perhaps the most important in light of the prevalence of Social Engineering. Users of the network, both new and old, should receive training about the password policy, why the policy has been implemented, and how to use the tools required to take part in the new policy. This training doesn’t have to be a large investment in time, effort, or money. In high tech environments, a simple email reminder with the policy and instructions sent out every month to old users and immediately to new users could be enough. In traditional business, education, or government, environments it may be better to schedule a one hour group lecture the first time in order to explain both the whys and the hows, followed by a question and answer period. It is also vitally important that users understand that no one should ever ask for their password, and they should never give out their password to anyone, no matter who they claim to be. It might also be appropriate to make clear that the real system administrator doesn’t need a password to login as any user, and thus would never need a users password to test or fix anything.
Some of these policy choices cannot currently be enforced with Webmin. As of version 0.970, only password timeouts are available. Even so, encouraging users to use secure passwords, and more importantly for you as an administrator, using good password policy yourself, can achieve the same goals without enforcing them. It is likely that Webmin will have all of these features in some form or another in future revisions. Your underlying OS variant probably supports some or all of them, as well, for system passwords. Educating users about these issues becomes more important when policy cannot be enforced via technical measures.
As discussed above, a carefully considered password policy can be very helpful in defending against crackers. Webmin provides a simple means to enforce some aspects of password policy for Webmin users in the Webmin:Webmin Configuration:Authentication module. Here you may choose to enable password timeouts, and automatically block hosts that appear to be running brute force attacks on the Webmin server.
Also, enabling logging of failed login attempts is an excellent idea, assuming someone will read those logs on occasion. It is possible using tools like logwatch to automatically be notified via email of some types of logged data. While logwatch is not currently configurable within Webmin, it is well worth your time to read up on this utility, or any similar tool provided by your OS vendor and to make use of it to help ease the burden of administering a system. To enable logging of authentication failures, browse to the Webmin:Webmin Configuration:Authentication module, and select Log blocked hosts, logins and authentication failures to syslog Disable session authentication. Then you may configure any log analysis tools you use to flag these authentication failures so that a human administrator can watch for signs of cracker activity.
The logwatch utility is Open Source software, available from www.logwatch.org. The program is maintained by Kirk Bauer and is included with many Linux distributions. Other OS variants often provide similar functionality
As discussed earlier in this chapter, Webmin provides a few mechanisms to provide network level security to your Webmin installation. Utilizing some or all of them can increase security immensely, without adding complexity to the deployment. The primary purpose of these features is to allow Webmin to refuse to even talk to someone on an address that is not allowed to login.
To begin, take a look at your network topology diagram, or write down your local network information, if your network isn’t large enough to justify a full diagram. Then write down the network information for every user that must be able to access your Webmin server. This may get complicated rather quickly, if you have dial up or other remote users who need to log in from dynamically assigned IP addresses, but even in such cases it may be possible to reach a viable compromise.
The first step, is to decide if you can restrict access to one particular network interface on your server. If your Webmin server has a non-routable local address and a routable internet address, you should decide whether anyone will ever need to be able to access the Webmin server from outside of your local network. If not, simply configure Webmin to listen on the local interface. This can be configured using the Webmin:Webmin Configuration:Port and Address module by selecting the radio button beside the Listen on IP Address option, and entering your internal IP in the entry field.
Before moving on to other items, it may be worthwhile to consider moving Webmin to another port. Webmin being on port 10000 leads to one additional type of possible exploit, that would be difficult for a cracker to take advantage of, but is probably not impossible for a local user. Because port 10000 is a non-privileged port, any user with login permission on the server could start an arbitrary server that listened on that port, if Webmin were not currently running on the port. Once a local user is able to start a server on port 10000, it is trivial to setup a webserver that looks like the Webmin login page, but in fact is just a simple CGI script in the user’s home directory. If the system administrator then attempts to login, his password can be grabbed and stored for the user to pick up later (or worse, mailed out automatically as soon as it has been grabbed). A particularly clever script of this sort could delete itself after its job is done, and even restart Webmin so the administrator will believe they simply entered the wrong password when they attempted to login the first time. One solution to this problem is to simply run Webmin on a port below 1024, as these ports require root permission to bind to, so a malicious user would not be able to run a password grabbing trojan on the same port, and thus would not be able to fool anyone into entering their authentication information.
In some OS variants and versions, it is possible to control which users can bind to any port, whether above or below 1024. This feature is sometimes known as capabilities or ACLs. A proposed, but then withdrawn, specification labelled POSIX.1e provided some of the capabilities that are supported by some Linux versions. With features of this sort it may be possible to make port 10000 behave just like a sub-1024 port, but availability of this kind of feature varies wildly, so it will not be covered here. In the vast majority of environments, it makes sense to run Webmin on port 1000, or if connectivity through very restrictive proxy firewalls is required, port 553.
The next step is to setup application level IP access control to your Webmin installation. If you have only static, or local addresses that should have access to Webmin, then your job is simple. Just open the Webmin:Webmin Configuration:IP Access Control module, and select the Only allow from listed addresses radio button, and then enter all of the addresses or hostnames that must have Webmin access.
If, however, you have users who will be accessing Webmin from dialup connections, or some other form of dynamic link, you cannot know in advance what IP address they will need to log in from. In some cases this can be mostly worked around, if you have a friendly ISP who will provide a list of their IP blocks. With the list of all possible addresses on which your dial up users may come in on, you can severely limit the percentage of internet users who can access your Webmin installation, simply because a single ISP only represents a tiny number of the total addresses on the internet. This is, for lack of a better term, Good Enough. Obviously, large nationwide ISPs are not generally helpful enough to provide this information for you, but if you are lucky enough to have a service-oriented local or regional ISP, you will likely find the technicians to be quite helpful.
If address based access control is not feasible due to needing nationwide dialup access or similar, it isn’t the end of the world. Assuming systems are kept up to date, and other security policies followed, it is highly unlikely that your Webmin server will ever expose an exploitable condition to crackers.
Webmin version 0.980 and above provides the option to do a hostname lookup for every user access. The result of this will be that a dynamically assigned IP with a DNS entry with DynDns, or a similar service, will be able to be checked against the IP Access Control list, just like a fixed address. This is not efficient if you have more than a few domain names entered in the IP Access Control list, due to the high overhead of performing a name lookup for every hostname in the list on every request. But it can be very useful if you have one or two administrators or users who travel or simply don’t have a fixed address at their normal location, because they can have a domain name that follows them wherever they go, and this name can be used to allow them access. I use this feature for the swelltech.com webserver, since it is remotely located and I often access it from my dynamically-assigned home ADSL link.
Webmin is a web-based application, thus it operates using the standard protocols of the internet and specifically the HTTP or HTTPS protocol. In a default installation from tarball or package, Webmin operates via the standard unencrypted HTTP protocol. In some environments this presents no major security threat, but in most situations this is a quite large hole in the security of a Webmin installation. If you only access Webmin across a local network of only trusted clients, and have a firewall closing your local network to outsiders, then you may feel safe in using Webmin over an unencrypted link. Otherwise, if you ever access your Webmin across the internet or an intranet that may have untrusted clients (for example, a laptop owned by an outside consultant, temporary employees, etc.) encryption should be considered mandatory.
Luckily, setting up Webmin for use with SSL connections is pretty simple, and requires only installation of two other packages: OpenSSL and the Perl Net::SSLeay module. Here we’ll briefly discuss installing these tools from source, though it is even easier if your OS vendor provides binary packages. Documenting the actual installation process will be left for the included documentation of these packages.
OpenSSL is an Open Source implementation of the Secure Sockets Layer protocols (SSL), as well as the Transport Layer Security protocol (TLS). It provides strong encryption library routines that are easy to integrate into other software, and is thus used quite frequently in Open Source projects requiring encryption. Because of this, if you are using any modern Open Source operating system, like Linux or FreeBSD, you probably already have OpenSSL installed on your system or can get a package for your OS that is simpler to install.
OpenSSL is free software, and can be downloaded from the www.openssl.org homepage, or one of its many mirrors. Download it to the server running Webmin. If you don’t have a graphical browser installed, or are accessing your server remotely you can use lynx or wget to fetch it from the website. If no text mode HTTP client is available, you can get the file from the ftp.openssl.org FTP site instead. I’ve never seen any internet capable operating system that does not have at least one text-mode FTP client available. Even Windows includes a simple FTP client for use in the MS-DOS shell! To install simply follow the instructions found in the INSTALL document included in the source distribution.
Getting the Net::SSLeay Perl Module
Because Webmin is written in Perl, it needs a Perl interface to the OpenSSL libraries. The standard choice for this is the Net::SSLeay module, which can be downloaded for free from CPAN or one of its mirrors. You may also be able to download a packaged binary version from your OS vendor.
Webmin itself offers a module for managing and installing Perl modules on your system. Using this module, documented later in this book, you may be able to install the Net::SSLeay module using this module. On my test systems (mostly Red Hat Linux of varying versions) I could only successfully install using the Webmin module if I left out the make test option, selecting only make and install. No additional arguments were required, however.
If a package is not provided by your vendor and installation via Webmin fails for some reason (and there are several reasons why it might), simply visit the Comprehensive Perl Archive Network (CPAN), and search for “SSLeay” to get the latest version. After downloading the tarball, unzip and untar it:
[joe@grover /joe]$ tar zxvf Net_SSLeay.pm-1.15.tar.gz
Or, if your OS doesn’t use GNU tar you may have to unzip and untar in two steps:
[joe@grover /joe]$ gunzip Net_SSLeay.pm-1.15.tar.gz [joe@grover /joe]$ tar xvf Net_SSLeay.pm-1.15.tar
Change directory to the newly created Net_SSLeay directory. Run the Makefile.PL using Perl, like so:
[joe@grover Net_SSLeay.pm-1.15]# perl Makefile.PL
Assuming no problems arise, this will generate a standard makefile suitable for your system. If OpenSSL was installed from an RPM, you may need to explicitly specify the /usr directory on the command line, though it appears to be unnecessary in new versions the module. But if it complains about being unable to find an OpenSSL installation you can try the following:
[joe@grover Net_SSLeay.pm-1.15]# perl Makefile.PL /usr
Next, use make to build, test and install the module into the correct location. The command sequence is as follows (don’t forget to switch user to root before the install phase):
[joe@grover Net_SSLeay.pm-1.15]# make [joe@grover Net_SSLeay.pm-1.15]# make test [joe@grover Net_SSLeay.pm-1.15]# su Password: [root@grover Net_SSLeay.pm-1.15]# make install
Finally, test to be sure the module is installed, using the following command line:
[root@grover Net_SSLeay.pm-1.15]# perl -e 'use Net::SSLeay; print "Success!\n"' Success!
If the result is the word Success!, then the module has been successfully installed. Otherwise, if you see an error regarding Perls inability to find the module, it is not installed correctly.
Now that the correct additional tools are installed, all that is left is to turn on SSL connections in the Webmin configuration. This can be done from within Webmin itself, or if you’re particularly paranoid and don’t want even want to login once over an unencrypted connection you can edit the configuration file manually.
To enable SSL connections using Webmin, browse to the Webmin:Webmin Configuration:SSL Encryption page, and click the radio button labelled Enable SSL support, if available. Click save, and you will automatically be redirected to the https port and connected via an SSL link.
To enable from the command line, for example from a SSH login or a direct console login, edit the miniserv.conf file, usually located in /etc/webmin or possibly /usr/local/webmin-0.980/etc, where 0.980 is replaced by the version of Webmin you have installed. The option to modify is ssl=, which defaults to 0 (off). Changing it to a 1 and restarting the Webmin server will enable SSL connections. You can then login on the HTTPS port as documented earlier.
As in the earlier discussion of IP Access Controls, the goal when constructing a set of firewall rules is to prevent access to sensitive ports by unknown persons. If, for example, you can restrict the external network addresses that can talk to your server on port 10000 (or 1000, depending on the port you choose to run Webmin on) you can very easily make it impossible to exploit your Webmin installation via most types of attack. This is, perhaps, a bold claim, but it is easily proveable assuming one can trust the firewall to do its job.
Unfortunately, the internet is a world of tradeoffs, and constantly changing conditions. Sometimes, you simply can’t lock down your machine using a firewall without locking out all of the people who need to use it. If you remotely manage your server via a dialup connection, the firewall clearly cannot be restricted to allowing only one IP. So compromises are required. As in the IP Access Controls, an ideal world would allow you to restrict access to only one or two external IPs (and most likely all of the IPs within your own local network), but most likely you’ll have to allow large blocks of IPs to account for dynamically assigned addresses on dialup, DSL and Cable internet connections. As before, if you have a helpful ISP, you’ll be able to obtain a list of the blocks that may be assigned to you.
As an example, we’ll create a simple firewall rule using both iptables for Linux and ipfw for BSD operating systems that will block access to the Webmin port to all but one address. Such a rule should be added to an existing firewall when possible.
The rules below should not be considered comprehensive firewalls. In fact, they are nowhere near it. We are simply blocking one port (the Webmin port) for all but one address. This should not be your whole firewall! However, building a complete firewall is well outside the scope of this book, and the goal of this tutorial is to secure your Webmin installation first, while briefly addressing a few peripheral issues surrounding general system security.
The standard packet filtering tool on Linux operating systems today is iptables, which is an advanced stateful packet filtering tool. It allows extensive logging, as well as a mostly cohesive front-end to some of the more advanced routing and network address translation features of the Linux kernel networking subsystem.
The routing path in Linux proceeds through three primary chains named INPUT, OUTPUT and FORWARD. In addition to these chains, there may be a set of chains related to Network Address Translation (NAT) rules. These are called PREROUTING and POSTROUTING. For our purposes we’ll ignore the NAT chains, since they aren’t relevant for blocking access to a local port.
[root@zope webmin]# /sbin/iptables -I INPUT 1 -s ! 192.168.1.1 -p tcp --dport 10000 -j REJECT
In the above example, we have used the -I INPUT 1 to insert a rule in the first position (the numeral one signifies where to insert the rule, in this case before all other INPUT rules). The rule will apply to all packets originating from any source except 192.168.1.1, because the preceding exclamation point negates the following argument. Next we have signified this rule will apply to the TCP low-level protocol. And the destination port is specified with the --dport flag. Finally, the -j (j is for jump) flag specifies what should be done with the packet. We could direct it to another chain for further processing, accept is, or deny it in a number of ways. In this case, we have chosen to simply REJECT it, which causes the network layer to return an ICMP port-unreachable error.