{"id":243,"date":"2020-11-29T16:07:00","date_gmt":"2020-11-29T21:07:00","guid":{"rendered":"https:\/\/stump.io\/blog\/?p=243"},"modified":"2020-11-29T16:07:00","modified_gmt":"2020-11-29T21:07:00","slug":"a-little-gotcha-with-postfixs-header_checks","status":"publish","type":"post","link":"https:\/\/stump.io\/blog\/2020\/11\/29\/a-little-gotcha-with-postfixs-header_checks\/","title":{"rendered":"A little gotcha with Postfix&#8217;s header_checks"},"content":{"rendered":"\n<p>I run my own mail on all of my personal domains using Postfix and Dovecot, doing almost all of my day-to-day interaction with it using Thunderbird. Many years ago, I realized I would rather not be leaking my home IP address in the initial <code>Received:<\/code> header in the mail I send, so, guided by various online postings that I can no longer identify with certainty, I initially did the following.<\/p>\n\n\n\n<p>First, I set up a custom cleanup service to be used by the message submission service by adding this entry to <code>master.cf<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Scrubs client IP address from things arriving over the submission port.\n# DON'T FORGET \"-o cleanup_service_name=subcleanup\" IN THE SERVICE'S ENTRY!\nsubcleanup unix n       -       -       -       0       cleanup\n  -o syslog_name=postfix\/submission\n  -o header_checks=pcre:\/etc\/postfix\/submission-header-checks\n# (Don't actually deploy the snippet above - keep reading.)<\/code><\/pre>\n\n\n\n<p>And I put the following in <code>\/etc\/postfix\/submission-header-checks<\/code> to define the actual substitution to be performed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/^(Received:\\s+)from\\s.*?\\b(by\\s.*)$\/mi REPLACE $1$2<\/code><\/pre>\n\n\n\n<p>And finally, I tacked this line onto the <code>submission<\/code> entry in <code>master.cf<\/code> to choose the new custom cleanup service:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  -o cleanup_service_name=subcleanup<\/code><\/pre>\n\n\n\n<p>(Don&#8217;t forget the indentation.)<\/p>\n\n\n\n<p>This worked well for quite a while, but has a subtle shortcoming that I didn&#8217;t hit until a few days ago when I found myself needing to provide someone with a copy of some pieces of spam I had received, which I decided to forward as attachments &#8211; something I had never done before &#8211; to ensure the headers would be preserved.<\/p>\n\n\n\n<p>That&#8217;s when I found out that <code>header_checks<\/code>, by default, apply to MIME headers and MIME subparts too &#8211; including the <code>Received:<\/code> headers in the attached spam, stripping away the very information I was trying to preserve by forwarding the messages as attachments.<\/p>\n\n\n\n<p>(I noticed immediately because I was watching Postfix&#8217;s logs as I sent the message, having temporarily reconfigured Postfix not to use my usual outbound relay service since&#8230; well&#8230; it <em>kind of<\/em> might look like I was trying to send spam through them&#8230; and I wanted to see that Postfix really was delivering the message directly. It&#8217;s nice that <code>header_checks<\/code> rules log every change they make.)<\/p>\n\n\n\n<p>A quick look at <a href=\"http:\/\/www.postfix.org\/cleanup.8.html\">cleanup(8)<\/a> revealed that <code>mime_header_checks<\/code> and <code>nested_header_checks<\/code> default to the value of <code>header_checks<\/code>, so I updated the <code>master.cf<\/code> entry to set those to nothing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Scrubs client IP address from things arriving over submissions port.\n# DON'T FORGET \"-o cleanup_service_name=subcleanup\" IN THE SERVICE'S ENTRY!\nsubcleanup unix n       -       -       -       0       cleanup\n  -o syslog_name=postfix\/submissions\n  -o header_checks=pcre:\/etc\/postfix\/submission-header-checks\n  -o mime_header_checks=\n  -o nested_header_checks=<\/code><\/pre>\n\n\n\n<p>&#8230;and resent the message (after testing with a resend to myself, of course), saw that only the one actual intended hit of the <code>Received:<\/code>-modifying rule occurred this time, re-enabled use of the outbound relay service, and went about my day.<\/p>\n\n\n\n<p>(That block now refers to <code>submissions<\/code> &#8211; note the extra &#8220;s&#8221; &#8211; because between the time I first added <code>Received:<\/code> header filtering to my configuration and the time of this incident, I moved the submission service from port 587 with STARTTLS to port 465 with TLS from the start, in accordance with <a href=\"https:\/\/tools.ietf.org\/html\/rfc8314\">RFC 8314<\/a> not just undeprecating that port but calling for it to become new best practice.)<\/p>\n\n\n\n<p>Looking back at the documentation, I now feel that setting <code>disable_mime_input_processing = yes<\/code> (disclaimer: haven&#8217;t actually tried it) might have been a better thing to do to fix this, but I don&#8217;t quite feel up to messing more with something that works for the moment.<\/p>\n\n\n\n<p>If this article happens to directly help you get endpoint IP scrubbing working properly (i.e. without also removing information from messages forwarded as attachments) in your Postfix installation, I&#8217;d love to know in the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I run my own mail on all of my personal domains using Postfix and Dovecot, doing almost all of my day-to-day interaction with it using Thunderbird. Many years ago, I realized I would rather not be leaking my home IP address in the initial Received: header in the mail I send, so, guided by various [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[],"_links":{"self":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts\/243"}],"collection":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/comments?post=243"}],"version-history":[{"count":10,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts\/243\/revisions"}],"predecessor-version":[{"id":253,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts\/243\/revisions\/253"}],"wp:attachment":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/media?parent=243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/categories?post=243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/tags?post=243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}