While cleaning up my server recently I found that stringing together several commands with pipes made it easier to check logs, find defaults, and remember Linux commands.
I don’t do a whole lot of things from the command line, so when I want to do something that I’ve done recently, I just use the up arrow key to find the command from the last time I used it. If I’ve done a lot of work on the command line, the history command will save some scrolling. Here’s the tail end of a recent history command.
501 sudo grep sshd:session /var/log/messages
502 sudo tail -n 1000 /var/log/php/error.log
503 sudo grep Authentication /var/log/messages | wc -l
If I want to check the error log I can just up arrow a couple of times and then hit return. Or I could type !502 and hit return.
grep and pipes
I can never remember all the options for tarring up a file, so I almost always find the last time I used it and use the same command again. But it was a while ago and searching through 500 lines of history isn’t particularly efficient. That’s where grep and pipes come in.
history | grep tar
history normally displays on the default output, in this case the terminal. But you can redirect the output to another command or a file. I used the pipe | to redirect the 500 lines of history into the grep command and looked for the characters tar. Rather than displaying 500 lines, I got a few with restart and a coupe of with tar. The target characters are highlighted in red on the terminal.
279 sudo /etc/init.d/apache2 restart
280 sudo /etc/init.d/mysql restart
428 sudo tar -czvf ./mysql-backup.sql.tgz mysql-backup.sql
While checking the messages log, I noticed that someone was trying to break into the server by sending login requests every second or so. I was curious about how many attempts there were, so I looked for the words ‘Authentication failure’ in the logs. Note that there is a space in the text I’m looking for so I need to put the search text in quotes. I then piped the result to the wc -l command to count the number of lines. There were almost 10,000 all from the same IP address. We changed our iptables config to only allow 3 attempts from the same IP address and then disable logins for a while.
493 sudo grep 'Authentication failure' /var/log/messages
503 sudo grep 'Authentication failure' /var/log/messages | wc -l
The output of 493 was thousands of lines like this—all with different users.
Jan 1 11:04:56 server sshd: error: PAM: Authentication failure for illegal user testtest from 220.127.116.11
Jan 1 11:05:05 server sshd: error: PAM: Authentication failure for root from 18.104.22.168
You can have multiple pipes as well. Here I want to check just the Authentication’s for Jan 3 so I cat the messages file to a grep that looks for Jan 3 (note the quotes) and then pipe that to a grep that looks for Authentication.
sudo cat /var/log/messages | grep 'Jan 3'| grep Authentication
Now that the logs are cleaned up, I check for successful logins with this command>
sudo grep Accepted /var/log/auth.log | tail -20
If there have been more than 20 logins since I last checked, I can make the number larger.
php error log
We have our server set up to put error messages into an error log rather than displaying them on the screen. Visitors to the site don’t care about the error messages and crackers can take advantage of the messages to exploit vulnerabilities so there is no reason to display them. However, if you are writing a new page or changing an existing one, you as a programmer can benefit from knowing where your code failed. When I’m coding I always have a terminal window open with this command running.
tail -f /var/log/php/error.log
One more grep command
When we updated to the latest version of PHP we started getting messages in the logs for deprecated commands. We fixed most of them, but the locations of others weren’t obvious from the error messages. Specifically, we needed to replace all of the places we used PEAR to access the MySQL database. So starting at the root of our website code I look for every file where we use the PEAR initialization code for MySQL. The -R in the grep command means to recursively search through all folders. You start with the current location and traverse the entire directory tree. Notice the * at the end of the command. I don’t want to look at a specific file, like I did in other examples, but want to look at all files.
grep -R initialize_db.inc *