Information about starting and operating an ISP or corporate Intranet using Linux servers.

Security

Topics related to server security.

This will get divided into sections as it grows.

Command Line (BASH)

Idle Log-out

If you want idle sessions to be logged out automatically, put something like the following into /etc/profile.d/timeout.sh (or another similar name). In modern distributions (Gentoo and RHEL5) placing the file in /etc/profile.d/ should cause it to be automatically executed at each log-in.

[ -n "${TMOUT}" ] && readonly TMOUT
[ -z "${TMOUT}" ] && declare -irx TMOUT=7200

This sets a 7200-second (2-hour) time-out and makes the variable read-only so that it cannot be changed by the user.

Apache

Using .htaccess to restrict access

There is a great deal that can be done with .htaccess. Most Apache configuration parameters can be modified by placing an .htaccess file in a directory, authentication can be specified on a per-directory basis, and more. There is a performance penalty for using .htaccess, however, as described on the Apache Foundation's htaccess tutorial page.

Here are some good sites explaining the use of .htaccess:

Restricting access by IP address

One of the things you will constantly see in your server logs are attempts to find weaknesses in your server's configuration. I have observed that most often these attempts come from Asia followed by the Middle East (Turkey etc.). Only rarely do I see attempts from North America, and when I do a single report almost always makes them stop, whereas reports to Asian or Middle East ISPs often get returned because their “abuse” mailbox is invalid or inactive (e.g., full because probably nobody ever checks it).

In order to relieve myself of this time-wasting annoyance, for web sites which have no application in certain regions (do I really want anyone in China looking at my family photo album site since I don't have any relatives there?) I simply block the IP address ranges and large ISP domain names for those countries by placing them in the configuration file or the “.htaccess” file for the web site.

For example, on my family photo albums site I want to exclude people from Asia who constantly create accounts in order to place ads on it, and I don't want search engines to index it either. To cover most of my problem areas without going overboard, I can use these lines:

order deny,allow
deny from .com.cn
deny from 59.0.0.0/255.128.0.0
deny from 120.28.64.0/255.255.192.0
deny from 120.40.0.0/255.252.0.0
deny from 125.78.

deny from .googlebot.com
deny from 66.249.64.0/19

deny from .microsoft.com
deny from .msnbot.com
deny from 65.52.0.0/14

Country IP block lists

A good source for country IP blocks is this web site, although the lists are specific to each country so you may end up with more lines than if you wanted to cover a region with several countries. For example, you see that I use 59.0.0.0/9 in my example above, which is easy to write and covers a large portion of Korea, China, India, etc., however, it includes some Australian ISPs whom I really don't mind, but for my photo albums site it's fine since I don't have family there either.

Blocking entire countries means should probably be done in your main Apache configuration files, within <Directory> or <Files> blocks, to avoid the performance penalty mentioned above. I made this easy for myself by creating a directory called “country-block-lists” and then placing Include directives as desired in various web site definitions. For example:

Order deny,allow
Include /etc/apache2/vhosts.d/country-block-lists/China
Allow from all

You could also use the country lists on the “countryipblocks” web site with Sendmail on a server to block mail from places you don't have any reason to talk to. Just use sed to convert “deny from ” into “Connect:” and then again to tack-on the REJECT message, like so:

sed -e s/"deny from "/"Connect:"/ -i korea.list
sed -e s/$/"\tREJECT"/ -i korea.list

PHP Coding

Storing passwords in code

Passwords, such as for PostgreSQL or MySQL, must be accessible from PHP (therefore readable by the Apache web server and possibly from command-line scripts run by ordinary/unprivileged users) yet protected from being seen in plain text in order to prevent undesired access to the database from outside the application. In rare situations1) it is possible for Apache to deliver unprocessed PHP code to a user's browser, which could reveal passwords if proper care is not taken.

Here are ideas to keep tight security for passwords stored in PHP code.

  1. Store passwords outside the Apache DocumentRoot so they cannot be directly delivered to a user's browser
  2. Set permissions to not permit world read-ability. For example, set the ownership to root:apache and set the permissions to 0640 if the scripts will only be run by Apache or root. This will prevent other users from running PHP scripts from the command-line that require reading such a file.
  3. Encrypt passwords using a method that can be reversed.
  4. Store the encryption key in a separate file on the server, also outside Apache's DocumentRoot, so that if anyone sees the code they cannot decrypt the password without already having access to the server. This becomes a bit complicated if multiple web servers are involved, but can be handled by placing the encryption keys in a separate source code repository or Cfengine rule that the sysadmins control rather than the developers, so the same key can be deployed and updated to multiple web servers.
1) Raw PHP code could be delivered by Apache, for example, if Apache's configuration did not process your files through the PHP engine. Imagine you made some files that ended in “.inc” (for “include”) and you added that extension to Apache's AddHandler directive. A year later an upgrade to Apache is installed and the admin is not aware of this non-standard extension and ends up removing it.
You could leave a comment if you were logged in.
Print/export