Security is such a big topic that it's hard to know where to start. To begin with, we should probably have the document root and the script directory moved to less predictable places. But how to redirect those client requests is a goal for the future. We should also review carefully the configuration details for Apache, including which Apache modules are enabled.
There are a number of modules that are not recommended for one reason or another, as described here:
userdir – Mapping of requests to user-specific directories. i.e ~username in URL will get translated to a directory in the server autoindex – Displays directory listing when no index.html file is present status – Displays server stats env – Clearing/setting of ENV vars setenvif – Placing ENV vars on headers cgi – CGI scripts actions – Action triggering on requests negotiation – Content negotiation alias – Mapping of requests to different filesystem parts include – Server Side Includes filter – Smart filtering of request version – Handling version information in config files using IfVersion as-is – as-is filetypes
I can check whether any are in the compiled modules for Apache I'm running by doing apache2. Investigating its use with man I see:
.In general, apache2 should not be invoked directly, but rather should be invoked via /etc/init.d/apache2 or apache2ctl.Nevertheless:
telliott@U32:/var/log$ /usr/sbin/apache2 -l Compiled in modules: core.c mod_log_config.c mod_logio.c worker.c http_core.c mod_so.c
It seems OK.
telliott@U32:~$ sudo find / -name "apachectl" [sudo] password for telliott: /usr/sbin/apachectl telliott@U32:~$ /usr/sbin/apachectl ulimit: 88: error setting limit (Operation not permitted) Usage: /usr/sbin/apachectl start|stop|restart|graceful|graceful-stop|configtest|status|fullstatus|help /usr/sbin/apachectl
The log files for Apache are in /var/log/apache2. There are three:
telliott@U32:~$ ls /var/log/apache2/
access.log error.log other_vhosts_access.log
For example, we can see who has made requests to the server recently:
telliott@U32:/var/log/apache2$ cd telliott@U32:~$ cd /var/log/apache2 telliott@U32:/var/log/apache2$ tail -1 access.log 10.0.1.3 - - [30/Mar/2012:11:36:10 -0400] "GET /cgi-bin/test.py HTTP/1.1" 200 801 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.54.16 (KHTML, like Gecko) Version/5.1.4 Safari/534.54.16"
The first field is the IP address of the request. We can use grep with the -v flag to exclude patterns (e.g. the known hosts 10.0.1.* and 127.0.0.1):
telliott@U32:/var/log/apache2$ cat access.log | grep -v "10.0.1" | grep -v "127.0.0" telliott@U32:/var/log/apache2$
There is undoubtedly a more elegant way to do what's above, but that works. No one but 10.0.1.* and 127.0.0.1 has asked for anything (yet).
I'd like to write these files to the OS X host. Since I set up ssh, I can use that to do it from a Terminal in OS X:
> scp email@example.com:/var/log/apache2/error.log error.log > scp firstname.lastname@example.org:/var/log/apache2/access.log access.logf
The error log shows a number of entries like this:
[Fri Mar 30 07:14:37 2012] [error] [client 127.0.0.1] File does not exist: /var/www/favicon.ico
Apparently we're supposed to have a favicon. This is annoying, but I can fix it as described here.
However, it's not just Apache we need to worry about. There are system logs like /var/log/syslog.
For the future, we should set up a way to systematically monitor the logfiles for unusual activity. I'd rather not write such tools from scratch, though it's a possibility. I'll have to look into it.
There is also the firewall (ufw), which I haven't actually set up yet. (The default state is off). It really is time to think about that. The docs for ufw are here.
telliott@U32:~$ sudo ufw default deny [sudo] password for telliott: Default incoming policy changed to 'deny' (be sure to update your rules accordingly) telliott@U32:~$ sudo ufw allow from 10.0.1.3 to any port 8080 Rule added telliott@U32:~$ sudo ufw allow from 10.0.1.3 to any port 22 Rule added telliott@U32:~$ sudo ufw status Status: active To Action From -- ------ ---- 22 ALLOW 10.0.1.3 8080 ALLOW 10.0.1.3 telliott@U32:~$ sudo ufw enable Firewall is active and enabled on system startup telliott@U32:~$ sudo ufw logging on Logging enabled
Restart Ubuntu. Check the server still works. From OS X Terminal:
> curl http://10.0.1.2:8080 <html><body><h1>It works!</h1> .. > curl http://10.0.1.2:8080/cgi-bin/test.py <head> <p> HTTP_ACCEPT */* </p> ..
Now, if an attempt is made on a different port, ufw should log it.. For example, OS X has a utility called stroke, which can carry out a port scan:
> cd "/Applications/Utilities/Network Utility.app/Contents/Resources" > ./stroke 10.0.1.2 22 22 Port Scanning host: 10.0.1.2 Open TCP Port: 22 ssh > ./stroke 10.0.1.2 8080 8080 Port Scanning host: 10.0.1.2 Open TCP Port: 8080 http-alt > ./stroke 10.0.1.2 8081 8081
The scan command hangs.. so do CTL-Z to kill it. That last scan should trigger a logfile entry on Ubuntu.
telliott@U32:~$ tail -1 /var/log/ufw.log Mar 30 14:53:20 U32 kernel: [ 528.390507] [UFW BLOCK] IN=eth1 OUT= MAC=08:00:27:d7:ba:0e:XX:XX:XX:XX:XX:XX:08:00 SRC=10.0.1.3 DST=10.0.1.2 LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=40207 DF PROTO=TCP SPT=54520 DPT=8081 WINDOW=65535 RES=0x00 SYN URGP=0
The first part of that MAC address is for Ubuntu on the VM, and the second part is for my OS X airport card. I don't know about the last part (08:00). But the SRC and DST IP addresses are clear, as is the DPT=8081. Just to check, try it again with 8082..
telliott@U32:~$ tail -1 /var/log/ufw.log Mar 30 15:05:49 U32 kernel: [ 1277.422229] [UFW BLOCK] IN=eth1 OUT= MAC=08:00:27:d7:ba:0e:XX:XX:XX:XX:XX:XX:08:00 SRC=10.0.1.3 DST=10.0.1.2 LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=21050 DF PROTO=TCP SPT=54579 DPT=8082 WINDOW=65535 RES=0x00 SYN URGP=0
I have misplaced the logfile, but earlier I had an access attempt from somone unknown: 18.104.22.168. Just ask google: "who is" 22.214.171.124. It's Dropbox. Huh. Didn't know they were in Wichita.
I had installed Dropbox on Ubuntu for file transfer, then deleted it. It seems that they were still trying to contact me for some time after that.
Finally, there are other tools out there. For example: nmap. This is another sophisticated tool that will require a more serious investigation. I can run nmap from Ubuntu on itself:
telliott@U32:~$ nmap -sT 10.0.1.2 Starting Nmap 5.21 ( http://nmap.org ) at 2012-03-30 15:11 EDT Nmap scan report for 10.0.1.2 Host is up (0.00076s latency). Not shown: 997 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 8080/tcp open http-proxy Nmap done: 1 IP address (1 host up) scanned in 0.21 seconds
This does not trigger a logfile entry by ufw. It is curious that although I only set up rules for ports 22 and 8080, port 80 still is open (as I'd like for Firefox to work properly). Note that these port scanning tools shouldn't be used against other people's servers. That will be interpreted as aggressive behavior (probing for weaknesses), and will surely make folks upset. It's the sort of thing we want to be on the lookout for on our server.
Immediate goals for the future: understand the detailed setup of ufw and get a good book about Apache.