Tracking pixel with nginx
Find out, if and when someone reads your mail. The nasty way…
Track Example
/etc/nginx.conf
http {
[...]
log_format track '$remote_addr [$time_iso8601] [$http_user_agent] $args';
[...]
server {
location ^/track/logs\.php$ {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/track.socket;
}
location = /_.gif {
access_log /srv/www/track/trackingpixel.log track;
empty_gif;
}
[...]
}
}
/srv/www/track/logs.php
<?php
/** * Simple Tracking pixel log viewer */
/* access.log location */
$logfile = "/srv/www/track/trackingpixel.log";
function pc_validate($user,$pass) {
return true;
/* replace with appropriate username and password checking, such as checking a database */
$users = array('user' => 'pass');
if (isset($users[$user]) && ($users[$user] == $pass)) { return true; } else { return false; } }
/* if (! pc_validate($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'])) { $realm = 'Email Tracker'; header('WWW-Authenticate: Basic realm="'.$realm.'"'); header('HTTP/1.0 401 Unauthorized'); echo "Access Denied."; exit; } */
$regex = '/^(\S+) \[(\S+)\] \[(.*?)\] (.+)$/';
$log = file_get_contents($logfile);
$log2 = explode("\n",$log);
$html = "";
for($x=sizeof($log2)-1;$x>=0;$x--) { $matches = ""; preg_match($regex ,$log2[$x], $matches);
if(sizeof($matches) == 5) {
if(isset($_GET['t'])) { if($_GET['t'] == $matches[4]) $html .= sprintf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",$matches[1],str_replace("T",' ',$matches[2]),$matches[3],$matches[4]); } else $html .= sprintf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",$matches[1],str_replace("T",' ',$matches[2]),$matches[3],$matches[4]); } } ?>
<html lang="en" class="no-js">
<head>
<meta name="generator"
content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Email Tracker</title>
<!--[if IE]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
<style>
table a:link { color: #666; font-weight: bold; text-decoration:none; }
table a:visited { color: #999999; font-weight:bold;text-decoration:none; }
table a:active,
table a:hover { color: #bd5a35; text-decoration:underline; }
table { font-family:Arial,Helvetica, sans-serif; color:#666; font-size:12px; text-shadow: 1px 1px 0px #fff; background:#eaebec; margin:20px; border:#ccc 1px solid; -moz-border-radius:3px; -webkit-border-radius:3px; border-radius:3px; -moz-box-shadow: 0 1px 2px #d1d1d1; -webkit-box-shadow: 0 1px 2px #d1d1d1; box-shadow: 0 1px 2px #d1d1d1; }
table th { padding:21px 25px 22px 25px; border-top:1px solid #fafafa; border-bottom:1px solid #e0e0e0; background: #ededed; background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb)); background: -moz-linear-gradient(top, #ededed, #ebebeb); }
table th:first-child { text-align: left;padding-left:20px; }
table tr:first-child th:first-child { -moz-border-radius-topleft:3px; -webkit-border-top-left-radius:3px;border-top-left-radius:3px; }
table tr:first-child th:last-child { -moz-border-radius-topright:3px; -webkit-border-top-right-radius:3px; border-top-right-radius:3px; }
table tr { text-align: center; padding-left:20px; }
table td:first-child { text-align: left; padding-left:20px; border-left: 0; }
table td { padding:18px; border-top: 1px solid #ffffff; border-bottom:1px solid #e0e0e0; border-left: 1px solid #e0e0e0; background: #fafafa; background: -webkit- gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa)); background: -moz-linear-gradient(top, #fbfbfb, #fafafa); }
table tr.even td {background: #f6f6f6; background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6)); background: -moz-linear-gradient(top, #f8f8f8, #f6f6f6); }
table tr:last-child td { border-bottom:0; }
table tr:last-child td:first-child {
-moz-border-radius-bottomleft:3px; -webkit-border-bottom-left-radius:3px; border-bottom-left-radius:3px; }
table tr:last-child
td:last-child { -moz-border-radius-bottomright:3px; -webkit-border-bottom-right-radius:3px; border-bottom-right-radius:3px; }
table tr:hover
td { background: #f2f2f2; background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0)); background: -moz-linear-gradient(top, #f2f2f2, #f0f0f0); }
</style>
</head>
<body>
<div class="container">
<!-- Top Navigation -->
<div class="component">
<table>
<thead>
<tr>
<th>IP</th>
<th>Date</th>
<th>User-Agent</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
<?php print $html; ?>
</tbody>
</table>
</div>
</div>
<!-- /container -->
</body>
</html>
embed into email:
. .