Howto log extra Kickstart headers in nginx

When a server is kickstarted via PXE to deploy RHEL or CentOS it can send a few useful headers when requesting the Kickstart file. The following headers are sent if enabled in the PXE config:

X-Anaconda-Architecture: x86_64
X-Anaconda-System-Release: CentOS
X-RHN-Provisioning-MAC-0: eth0 11:22:33:44:55:66
X-System-Serial-Number: A1B2C3D4G5

Since these headers uniquely identify the requesting host, they can be used by a web app to modify the Kickstart file before it is sent back. You could for example define a specific network setup or partitioning layout.

In RHEL7 or CentOS7 you can enable these headers by adding inst.ks.sendmac and inst.ks.sendsn to the PXE config. Here’s an example:

By default nginx does not log these headers. Here’s how to make nginx log them.

1) add the headers to the log_format of your choice

In this example I just use the default ‘main’ log_format and have appended the headers to log. Open the file /etc/nginx/nginx.conf with your favorite text editor and add the lines beginning with $http_x_ (so the last 4 lines):

You can add additional X-… headers off course. Just make sure that you prepend them with $http_ and that all characters are converted to lowercase and that any dashes ‘-‘ are converted to underscores ‘_’.

2) enable the log_format in your nginx server config

You now need to enable the log_format above (‘main’) to the ‘server’ section in your nginx config. Open the config file for your virtual server and modify the access_log line so that it uses the ‘main’ format:

Restart nginx, PXE boot a VM for deployment and see the headers show up in the nginx log:

Notice the ‘?’ in the GET /ks/?CentOS-7_x86_64.ks? That means that it asks for the default index with argument CentOS-7_x86_64.ks. Fully written it looks like this:

GET /ks/index.php?CentOS-7_x86_64.ks

By just using the ‘?’ you are more flexible as you can change the ‘index’ config option in the nginx configuration without having to change the PXE boot config.

How to remove nginx & PHP versions from HTTP Header

Unless disabled both nginx and PHP give away their version in the HTTP Header. Here is what that looks like:

For security purposes it’s not a bad idea to prevent those versions from being shown. Mind you, security through obscurity is no real security. Having said that, here’s how to do it.

To disable the nginx version, in /etc/nginx/nginx.conf add server_tokens off; in the http section:

More information about server_tokens can be found in the nginx docs.

It’s not possible to disable just the PHP version in the X-Powered-By: PHP/5.3.3 header. However, it is possible to disable the header all together. There are two ways to do that:

1) in /etc/php.ini add expose_php = Off. This will disable the PHP header everywhere.

2) if you only want the X-Powered-By: PHP/5.3.3 header disabled for a certain host, add php_flag[expose_php] = off to the appropriate conf file in /etc/php-fpm.d/.

More information about expose_php can be found in the PHP manual.

With both headers sanitized, the HTTP Response Headers now look like this:

No more headers giving away the versions of both nginx and PHP.

Piwik, nginx and self-signed certificates

To keep track of some website statistics I use Piwik, an excellent free web analytics tool that provides you with detailed reports on your website’s visitors, your marketing campaigns and much more.

Obviously I want to make sure that information is secure and shielded from unauthorized access. After too many Certificate Authorities recently dropped the ball (TurkTrust and Diginotar but Google for more) it makes more sense to use self-signed certificates and client certificate authentication.

Unfortunately Piwik does not support client certificate authentication in its tracker code so how can self-signed certificates and client certificate authentication still be used?

They can not… sorta.

Nginx to the rescue. The fast growing webserver ( actually an HTTP and reverse proxy server, as well as a mail proxy server) is tremendously flexible and granular and allows you to provide limited non-SSL access to piwik.js and piwik.php while the actual webinterface behind index.php is only available on an SSL link with client certificate authentication. While I would prefer to see support for SSL with self-signed certificates & client certificate authentication in Piwik’s tracker code, this should do for now.

Example configuration:

I’ll leave the SSL enabled full Piwik configuration as an exercise to the reader. Piwik on nginx is well documented as is the SSL part.

If you know a way to make Piwik’s tracker code work with SSL with self-signed certificates & client certificate authentication then please leave a comment.