Zen and the Art of Server Administration
Making things easier
Now that the server has been online for a while, it is time to begin the work of ensuring the safety of the server. Mine needed its own firewall. It also needed the ability to ward off those that seek ill of my little server in my little corner of the Interwebs. Time to get my hands dirty. This is the story of logs, awk, bash, and bad guy databases.
Little helpers
The first thing to do is to find out what kind of folks are coming by to visit. I do this with Google Analytics. By signing up with them, they give me a Google ID code for my server. I load this code in my HTML so that Google can come by and see how things are going. They also use it to provide statistics on my visitors; how many, when, how often, where are they from. It’s a useful tool and the only private data that gets collected, if indeed it does. Thus, I mention them in my privacy statement. You can find out a lot about them here.
Second, I need to check the logs of my server to see what some of the visitors are looking for. Most linux web servers will keep logs in some type of var/logs folder. Different packages keep them in different subfolders. The log is often called access.log and another is error.log. The access log is the one we are looking for. I can’t really print a fake log line well, but it will contain several very important items arranged in space separated columns. The very first column is the foreign visitor IP address ( usually IPV4 ). There are many other columns, but only a few are really relevant.
There will also be a column with a three digit number. These will be numbers like, 200, 301, 404, and a few others. They tell me what happened to the visitor’s request. Usually, a visitor requests a specific web page, or a default page like index.html. If the page is found, the server gives the visitor that page and records a 200. If a visitor clicks a link, the visitor is redirected to another site and the server records some type of 300. If the page isn’t found, the code is a 404.
Most visitors aren’t typing out specific pages in the address line to find them. They could. It’s not impossible and they might misspell the name and get a 404. More than likely, the visitor made a request like these.
20.104.78.132 - - [14/Aug/2026:00:25:39 +0000] "GET /img.php HTTP/1.1" 404 162 "-" "-"
20.104.78.132 - - [14/Aug/2026:00:25:39 +0000] "GET //aa.php HTTP/1.1" 404 162 "-" "-"
20.104.78.132 - - [14/Aug/2026:00:25:39 +0000] "GET //av.php HTTP/1.1" 404 162 "-" "-"
20.104.78.132 - - [14/Aug/2026:00:25:39 +0000] "GET /media.php HTTP/1.1" 404 162 "-" "-"
20.104.78.132 - - [14/Aug/2026:00:25:40 +0000] "GET /images.php HTTP/1.1" 404 162 "-" "-"
20.104.78.132 - - [14/Aug/2026:00:25:40 +0000] "GET /admin.php HTTP/1.1" 404 162 "-" "-"
None of these pages appear in my web server’s collection of files. These are all older PHP files that are identified with certain server vulnerabilities. The IP address, which is likely a known bad actor makes a check for many of these kinds of known vulnerable files in a row. It wastes my bandwidth and is just plain not nice. I need a way to keep them out.
However, manually looking through logs and finding these can be really inconvenient. I need a better way to configure my firewall to block these folks.
Awk is not the sound a bird makes
Enter Awk. Awk is built just for this kind of work. At its core, awk scans text files ( log files are plain text files ) and finds, skips, and organizes the results.
The simplest Awk command is awk { print } access.log This will print the entire contents of the text file, line by line. Not very useful, but use this command awk { print $1, $9 } access.log turns the log above into:
20.104.78.132 404
20.104.78.132 404
Use this awk '!seen[$1]++ { print $1, $9 } access.log and we get all the unique IP addresses with 404 results. Pretty helpful.
There are also bash scripts that I can write to do even more. In a bash script, I can programmatically run awk programs, check to make sure the 404’s aren’t related to my own IP address or to Google’s bot address ( that took help from Gemini ), counts to see if they have received five 404’s then blocks them in my firewall. In this case, it marks ufw with a DENY IN code for this address.
But, I can do even more than this.
Malevolent IP database
There are a few online databases of IP addresses known to cause problems. The one I signed up with is AbuseIPDB. I can now report bad IP’s and check to see if the IP’s hitting me are bad ones. I can also get a list of bad IP addresses to load into my firewall preemptively. I just started working with this database yesterday, so I have some work to do still. However, in the meantime, I only need check my logs every couple of days to see if I find any more.
This does pay off. I had sixteen access log files ( they rotate once per day ) built up in my server. Scanning them with bash and awk resulted in blocking 250 likely bad IP’s. Some of these I checked on and they are known bad guys.
Back to business
So, with those things handled, for now, I can return to programming the Java text adventure game. And, keep writing about programming. No, I didn’t give you the whole bash script. For one thing, most of it did come from Gemini. I’m not a deep bash expert and I didn’t want to spend all day on it, which I almost did anyway. Apologies. I may post it some time in the future, but it’s still early. I might find screw ups. So, until then, happy coding!