You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
12 KiB

3 months ago
import { addBanner, addArticle, addTitle, addHeader, addParagraph, addClassParagraph, addSubHeader, addOrderedList, addUnorderedList, addBlockquote, addInset, addInsetList, addInsetCodeListing, addInsetBulletList, addImageWithCaption, addButtonGroup, addSidebar, addSyntax, menu, global_menu } from '/scripts/import.js';
import { local_menu } from '/scripts/webdev.js';
const heading = document.querySelector(".heading");
const global = document.querySelector(".global_menu");
const local = document.querySelector(".local_menu");
const sidebar = document.querySelector(".sidebar");
const main = document.querySelector(".main_content");
heading.append(addTitle("Apache Web Server: Administration"));
heading.append(addParagraph("Jon Peck - LinkedIn Learning - August 2014"));
heading.append(addParagraph("Chapter 3 : Troubleshooting with Log Files"));
main.append(addHeader("What are the Common Log Files?"))
main.append(addParagraph("Apache proivdes a comprehensive logging system that servers three main purposes."))
main.append(addSyntax("• Finding problems with a site including things like server or config errors."))
main.append(addSyntax("• Analyzing traffic patterns - eg, who has accessed what."))
main.append(addSyntax("• Detecting malicious activity including brute force attacks and vulnerability scans."))
main.append(addParagraph("The online documentation for the Apache logging system can be found at <a href=\"https://httpd.apache.org/docs/current/logs.html\">httpd.apache.org</a>."))
main.append(addParagraph("If you make any changes to your site, it can be useful to have these logs available if something goes wrong."))
main.append(addParagraph("Logs can appear in different formats and this can be configured, so it may not always be the same even for different machines running the same OS. However, there are a few standards which you can usually rely on."))
main.append(addParagraph("The most important log file is probably the error log which is the first place you should look when diagnosing a problem. Another important log is the access log which logs all server access requests. It is important to remember that Apache only writes these logs, it doesn't provide any tools for analysing them."))
main.append(addParagraph("Apache modules such as PHP should have their own logs. It may be possible to conifgure logs to put, for example, PHP errors and Apache errors in the same file, but that would probably just make it harded to get any useful information from the logs so this is something you want to avoid."))
main.append(addHeader("Enabling and Reading Apache Log Files"))
main.append(addParagraph("There are a couple of important directives for configuring Apache error logs. Error log, which defines the name and location of the error log and LogLevel which determines the degree of verbosity. These levels are:"))
main.append(addParagraph("&emsp;&bull;&emsp;trace - this provides the most detail possible including stack dumps but it is really only of interest to someone who is actually developing Apache functionality."))
main.append(addParagraph("&emsp;&bull;&emsp;info - provides logging for a variety of things, not just errors."))
main.append(addParagraph("&emsp;&bull;&emsp;warn - provides logging for anything that looks like an error."))
main.append(addParagraph("&emsp;&bull;&emsp;emerg - the least verbose level, it only logs anything when the system is unusable."))
main.append(addParagraph("In most cases, your Apache server will already be configured to log errors, so you need to be able to find where the logs are being written to. A good place to start would be to search using grep as follows."))
main.append(addSyntax("grep -Ri ErrorLog /etc/apache2"))
main.append(addParagraph("The options for grep here are R for a recursive search and i for case insensitivity. We are searching for ErrorLog and the starting point for the search is /etc/apache2. When I run this on my web server, the results are as follows."))
main.append(addImageWithCaption("./images/screen14.png", "Caption"))
main.append(addParagraph("Of course, the results are not identical to those shown in the course video which come from an Ubuntu machine, but the highlighted line is the same in both and this shows that the main ErrorLog is named error.log and its location is given as APACHE_LOG_DIR, so this is a directory defined elsewhere in the config files."))
main.append(addParagraph("Since this is an environment variable, it must have been created with an export, so we can search for a file that exports this particular variable."))
main.append(addSyntax("grep -Ri \"export APACHE_LOG_DIR\" /etc/apache2"))
main.append(addParagraph("This returns the following results, which again is the same on my web server as it is on the Ubuntu machine (both systems are Debian based but as far as I'm aware, Raspbian is a relatively limited OS compared to Ubuntu and so things are not always exactly the same so I think it is worth mentioning when they are)."))
main.append(addSyntax("/etc/apache2/envvars:export APACHE_LOG_DIR=/var/log/apache2$SUFFIX"))
main.append(addParagraph("It may be worth mentioning that this can be defined using an absolute path rather than an environment variable which would make the log easier to find, but in any case, we can see that it is on the directory"))
main.append(addSyntax("/var/log/apache2$SUFFIX"))
main.append(addParagraph("The $SUFFIX is a mechanusm that allows us to log form several servers running simultaneously, but this is an advanced configuration not covered in this course. We can ignore it so our directory is <high>/var/log/apache2</high>."))
main.append(addParagraph("We can cd over to that directory and there is the error.log file and there we can see error.log, access.log and another log file called other_vhosts_access.log (since I haven't set up any virtual hosts on my web server yet, I'm not surprised at the fact that this is an empty file. This is a file that Debian creates by default and it logs traffic to any virtual hosts that don't have their own config file."))
main.append(addParagraph("There are a lot of GET requests in the access.log file and I have opened up my website and navigated around it a little in order to generate some more. A sample of the most recent request from the log file are shown below."))
main.append(addImageWithCaption("./images/screen15.png", "Caption"))
main.append(addParagraph("As a matter of interest, the last entry shows a GET request for this page. If I change the spelling of the page name and try to load that (by pressing enter), I get a page not found error. This is shown in the access log as"))
main.append(addSyntax("2.2.236.221 - - [23/Jan/2022:22:37:24 +0000] \"GET /webdevelopment/apachewebserveradmin/troubeshooting.html HTTP/1.1\" 404 496 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0\""))
main.append(addParagraph("For comparison, the last few lines in the error.log file are"))
main.append(addImageWithCaption("./images/screen16.png", "Excerpt from the error.log file."))
main.append(addParagraph("You may notice that the failure to access a page is not shown here and that is because it is not an error. The user (me) requested a page that doesn't exist and received a not found error, but this is not an error in Apache2, it is an error made by the user. It is still an access request so this is logged in access.log and that logging includes the fact that a 404 response was sent. In this respect, the server is working correctly and has provided the correct response to a request for a non-existent resource."))
main.append(addParagraph("Let's say that we want to set up custom logging for the Alice website on our Ubuntu machine. To do that, we want to edit the alice.conf file in /etc/apache2/sites-available. Just a side note here, in the course video, Jon used the command sudoedit to edit the file which invokes the nano text editer with root access. I'm not sure how this is different, or even if it's different from just typing sudo nano but I don't like nano so I will use sudo vi instead."))
main.append(addParagraph("At the end of the file (so after the line with the DocumentRoot, we want to add the following:"))
main.append(addSyntax("ErrorLog ${APACHE_LOG_DIR}/alice.log"))
main.append(addSyntax("LogLevel info"))
main.append(addSyntax("CustomLog ${APACHE_LOG_DIR}/alice-access.log combined"))
main.append(addParagraph("The first two lines are fairly straightforward and these are the ErrorLog and LogLevel directives we saw earlier so respectively, they are setting the name and location (ErrorLog) and verbosity (LogLevel) for our error logs. It may not have been clear earlier, but these directives apply specifically to the error log, we can't use them with the access log."))
main.append(addParagraph("So, we should have a directive called AccessLog which would make sense, but Debian uses CustomLog instead. There isn't any obvious link between access log and CustomLog so I don't know what the reason for this is. In any case, the third line is defining the name and location of the access log for the Alice website. It doesn't have a corresponding LogLevel, but combined defines the format for the logging. This is the default value and you can also use the common format so the directive would be"))
main.append(addSyntax("CustomLog ${APACHE_LOG_DIR}/alice-access.log comm,on"))
main.append(addParagraph("We need to restart Apache for these changes to take effect and we will do that with a graceful restart."))
main.append(addSyntax("sudo service apache2 graceful"))
main.append(addParagraph("If we now try to access a non-existent page on the Alice website, an error is logged in the alice-error.log as shown in the image below."))
main.append(addImageWithCaption("./images/image9.png", "Error shown in the alice-error.log file"))
main.append(addParagraph("Note that I don't currently have the web server set up correctly on the Ubuntu machine in order to display, or even attempt to access the Alice website so I am using a screenshot from the course video for this purpose. There is more information on these directives on the httpd.apache.org website under <a href=\"https://httpd.apache.org/docs/2.4/logs.html\">Log Files</a>."))
main.append(addHeader("Tools for Analysing Apache Log Files"))
main.append(addParagraph("There are actually quite a lot of tools to analyse the Apache log files, but we will just look at a couple of them here."))
main.append(addSubHeader("AWStats"))
main.append(addParagraph("This is a real-time access log analyzer and it provides a web interface allowing you to generate graphs and summaries, but it can be a security risk if it is publicly accessible. If it is installed, you will want to ensure that access to it is limited to those who need to use it."))
main.append(addParagraph("More information can be found on <a href=\"https://www.awstats.org/\">awstats.org</a>. It is open source and avaialble on most Linux platforms including the Raspberry Pi."))
main.append(addSubHeader("GoAccess"))
main.append(addParagraph("This is also a real-time access log analyser, but it is a terminal application rather than a web application, so it is easier to secure. It is also lightweight and fast and it provides a lot of features including"))
main.append(addSyntax("&bull; general statistics"))
main.append(addSyntax("&bull; time taken to serve requests"))
main.append(addSyntax("&bull; requested and missing pages"))
main.append(addSyntax("&bull; referrers analysis"))
main.append(addParagraph("You can get more information, including detailed instructions for installation, on the <a href=\"https://goaccess.io/\">goaccess.io</a> website."))
main.append(addParagraph("There are also log aggregators, for example <a href=\"https://www.graylog.org/\">graylog</a> or <a href=\"https://www.elastic.co/logstash/\">logstash</a> that allow you to combine log files from a variety of sources, including different servers and generate detailed reports. These can take a lot of work to setup and they are more suited to multi-server environments than, say, a single website being served up from a Raspberry Pi!"))
main.append(addParagraph("The main thing to understand from this is that there are a lot of tools for analysing Apache logs and which, if any, you would choose to install and use really depends on a number of factors including your environment (number of servers etc), your needs (monitor a site for missing pages or investigate a security issue)."))
main.append(addParagraph("Knowing how to find the log files and configure them can be very important because in some cases, you may not need any additional tools, you may be able to solve a problem with just the information found in these logs."))
addSidebar("webdev");