Nginx Logging Privacy and Security
Below you will learn how to configure Nginx to stop logging sensitive information and help protect the privacy of your users along with protect authorization keys and query strings from being logged. Each section below outlines how to stop logging a specific page or piece of information. Multiple sections below can be combined to fully customize how you log visitors to your website.
Basics to Nginx Log Options
Before actually modifying any configuration files, here is an overview of the Nginx log options we will be using. Quickly, Nginx configuration files are generally stored in the directory /etc/nginx/
, with site specific configuration options beings stored in separate files inside the directory /etc/nginx/sites-available/
. The main Nginx configuration file is /etc/nginx/nginx.conf
.
There are three main directives that affect logging, access_log
, log_format
, and error_log
. Another directive that will be used frequently is the location
directive; It allows directives to be set for a particular page instead of having it set site or server wide. Nginx directives have to be set in their correct context for them to work. The access_log
and error_log
directives can be set in the http
, server
, and location
context. But the log_format
directive has to be set in the http
context, which is generally defined in the nginx.conf
file. All of this information is available in the Nginx documentation.
When changing or creating the log format, you will set a name for the log format that will later be used by the access_log
directive. The default log_format
name used is “combined” and it cannot be overwritten. The access_log
directive then sets the file location of the log and what log format to use. It’s also possible to specify additional options for the access log, such as buffer size, flush duration, and if logs should be compressed using gzip while writing the log file.
Using the Settings Below
To keep this tutorial condensed and not to repeat the same information in every section, each section will outline the settings and directives you need to add to your Nginx configuration files. You will generally have to modify multiple files unless you want to apply settings to all Nginx web sites you are serving. The code blocks below outline the context (e.g. http, server, location) the directives must be applied to for them to work. You will want to copy the directives from inside of each context and not the context itself, except for the location
context in some cases where you are only applying a directive to a specific location.
The log_format
directive will always be applied in the nginx.conf
file inside of the http
context. As for the access_log
directive, this tutorial assumes each site has unique logging and the access_log
will be applied to an individual website configuration file /etc/nginx/sites-available/example.com.conf
. The access_log
directive will be placed inside of the server
or location
context. If you want all websites to use the new log format, you will set the access_log
directive inside of the http
context, but it’s still possible for it to be overwritten by individual websites.
Stop Logging IP Addresses
Using the below log format, you can continue logging requests on your website but not log the visitors remote IP address. Many websites that care about your privacy will not log your IP address. There are some cases where this can backfire. If your site has a security flaw and has been compromised, you will not have the IP address of the attacker. An alternative route you can take (not outlined in this tutorial) is to either delete logs after a week or remove IP address from logs after a certain amount of time.
The log format replaces the users IP address with the IP address “0.0.0.0”. This is done to allow log parsers to continue working and not to disrupt the log format.
# /etc/nginx/nginx.conf
http {
log_format hide_ip '0.0.0.0 - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
}
# /etc/nginx/sites-available/example.com.conf
server {
access_log /var/log/nginx/example.com.log hide_ip;
}
Stop Logging Sensitive URLs
When your website allows users to sign in through other services using OAuth (e.g. Google, Facebook, Twitter), the callback URL could possibly contain authorization tokens that you don’t want to end up in logs. You can stop logging specific URLs all together by using the settings below. If you would still like to log these URLs but without the query string, look at the next section.
# /etc/nginx/sites-available/example.com.conf
server {
location /authorization {
access_log off;
}
}
Stop Logging Query Strings
Query strings inside of URLs can contain sensitive information, such as authorization tokens from Oauth, or some forms may submit GET requests instead of POST and show personal information in your server logs. It’s possible to stop this on your whole site or for individual pages. If your site uses SEO friendly URLs, applying this setting site wide should work fine, but in cases where pages change based on query parameters, you will want to limit what locations will use this new log format. A good example of pages would be authorization callback URLs, form processing pages, search results, etc.
# /etc/nginx/nginx.conf
http {
log_format hide_query '$remote_addr - $remote_user [$time_local] '
'"$request_method $uri $server_protocol" $status '
'$body_bytes_sent "$http_referer" "$http_user_agent"';
}
# /etc/nginx/sites-available/example.com.conf
server {
access_log /var/log/nginx/example.com.log hide_query;
}
Testing and Restarting Nginx
Once your configuration files have been modified, you will first want to test the configuration changes before applying them. Improperly configuring your files can prevent Nginx from starting, or the worse case is that the web server acts in a way it’s not supposed to. If possible, test the changes on a staging server before moving them onto your production server.
To test if the configuration files do not contain any syntax errors, you will run the command below as root or an administrative account. If there is an error, the command below will warn you and you can check the error log at /var/log/nginx/error.log
for more information.
$ service nginx configtest
[ ok ] Testing nginx configuration:.
If there are no errors, you can now start Nginx with the new changes. Once you restart Nginx, check your website and verify that files are still being served correctly; also take a look at the logs and see if your changes have been applied.
$ service nginx reload
With the information above you can make other changes to the log format and set different log formats for different pages. Keeping all of your log formats similar is a good idea if you use parsers or any scripts that read your log files. It’s also important to remember that error logs may contain some of the private information you are trying to hide. It’s not possible to change the format of error logs but you can disable them, which is probably a bad idea.