7

Environment:

  • IIS Web Farm
    • 5 servers
    • Windows Server 2008 R2
    • IIS 7.5
    • ASP.NET 3.5 and 4.0 web application

Our web app, like many, needs to send mail. Send only, no receiving.

In the past, we've enabled the IIS 6 SMTP service on each web server and used the .NET SMTP classes to drop mail files in the pickup folder. Works fine.

In order to simplify the environment and run fewer services on the web servers, I'm considering the viability of running the SMTP service on just one utility Windows service, and exposing the pickup directory to the rest of the web servers in the farm using a file share. The ASP.NET web applications will simply drop their mail files in the shared pickup folder, and the single SMTP service will handle the outgoing mail flow for all the web servers. I'm not worried about volume or the ability of the SMTP service to keep up, that won't be a problem.

The pros:

  • Simplified administration and configuration
  • Lower load and reduced attack vector on the web servers
  • Single point of troubleshooting if there are mail problems

The cons:

  • Single point of failure
  • If I need to reboot the utility box, I lose outbound mail capabilities. This could potentially be mitigated by using offline folder caching for the file share on the web servers. Haven't tested it, but possibly the web servers, sensing no connection to the file share, could drop their files locally, to be automatically synced to the SMTP server when it reboots.
  • Email file name clashing - need to make sure that ASP.NET, when it writes the .eml files, does so using a guaranteed unique name across the entire web farm. SmtpClient source code indicates a GUID is used to name the files, but MS could change that in a future implementation.

Will this work?

Edit: Thinking more about my idea for Offline Files, I'm not sure it's the greatest approach. Offline Files requires a scheduled task to schedule synchronization, and every time it runs, I'll be pulling all the other web servers' mail files every other server's local cache. Maybe a better idea is to just have the files pile up in a local folder, and some other job (scheduled robocopy) attempts to copy them to the remote file share whenever it's up. Had thought about DFSR, but again, I'll be shuffling all the mail files around to all the web servers, and that's wasteful.

Larry Silverman
  • 547
  • 6
  • 12
  • Using Resharper, I fetched the source for SmtpClient.cs and have confirmed that it uses a GUID to create the email file name. So my solution will be safe as long as that doesn't change. Of course, there's no guarantee that won't change. – Larry Silverman Sep 22 '11 at 22:20
  • 2
    Think Offline Files might do more file shuffling than you're expecting. SMTP on each sounds like a better bet; it's got queueing built in. Just use the other box as a smart host, and firewall them into the ground. – TristanK Sep 23 '11 at 04:22
  • Thanks. I added an edit after I did a little research into Offline Files and concluded the very same thing. It's a good point that local SMTPs mapped to a smart host will manage their own queuing, passing along mail when it's possible. At least that buys me relatively centralized troubleshooting and outbound email error logging. But it still requires installing SMTP everywhere, which is one of the main things I wanted to avoid. – Larry Silverman Sep 23 '11 at 13:53
  • wait a sec - what SMTP server are you using? Your web servers you say are running Win 2008 R2/IIS 7.5, but you mention IIS 6 SMTP below that and your post is tagged with IIS6, not IIS7.5 so maybe a little clarification is needed – August Sep 23 '11 at 18:35
  • 1
    All of the above is true. There is no SMTP service associated with IIS7 or 7.5. MS just reused the old engine from IIS6, and in order to use it, you have to install multiple components of IIS6 including the IIS 6 administration tools. – Larry Silverman Sep 23 '11 at 19:05

2 Answers2

4

I can't see your point here. You try to simplify your setup by introducing more complexity and security issues.

SMTP is the solution for your problem. Now you only have to look for a good implementation. SMTP comes with built-in queue handling (no file name collisions), failure resistant, redundancy aware due to multiple MX and is an ancient well-tested protocol. By the way it is Operating System independent.

You want to exchange this with single-point-of-failure, Scheduler dependent, Operating System bound, undocumented and new untested re-inventing-the-wheel procedure. Also you expose a drop-in-box for everybody not only for these 5 servers.

Use a simple store-and-forward server (like E-MailRelay) on the webservers and a central SMTP server where the mails are forwarded to. This SMTP server will then be used for final delivery. Then you can secure your central SMTP to only accept connections from these 5 servers and do sender-based-rejecting or whatever filter/block you want to reduce potential (Spam-)risk for the public.

This solution has all the benefits of transparency (logging+monitoring), simplicity (one process), conformity (standard Internet protocol) and integrity (delivery confirmation). No need to exchange it self-made workarounds.

mailq
  • 16,882
  • 2
  • 36
  • 66
  • Thanks. I agree with your point about the increased risk of exposing the drop-in box for everyone who might gain access to the file share. I'm not sold on adding another third-party component to every web server. I'd sooner use the built-in IIS SMTP service as a smart host relay as TristanK suggested in his comment on my original question. – Larry Silverman Sep 23 '11 at 17:07
2

Better bet would be to use SMTP via tcp/ip i.e. listening on port 25 (or any other port) and then using System.Net.Mail's MailMessage and SmtpClient.

You then could throw a load balancer in front of the SMTP server and have each server connect to that load balanced name/ip.

Christopher_G_Lewis
  • 3,647
  • 21
  • 27
  • Thanks, I like this suggestion. I could live with load balancing two SMTP instances. It's less management headache than having instances installed on every web server. And I can do it in an active/passive arrangement, so that I can mainly go to one server for troubleshooting normal email problems. – Larry Silverman Sep 23 '11 at 19:14
  • I'll also mention that we do use SmtpClient, and we've been using the PickupDirectoryFromIis DeliveryMethod, so that the SmtpClient writes an .eml email file directly into the pickup directory for delivery. If you're using the local SMTP service, this is really the fastest way to get the email "sent" so the web page can get on with whatever else it's doing. There's also a DeliveryMethod named SpecifiedPickupDirectory which allows you to decide where the mail file is dropped, which is how I was going to make my file share idea work. – Larry Silverman Sep 23 '11 at 19:28
  • @LarrySilverman I thought you wanted it fast?! Reducing the endpoints for SmtpClient from 5 to 2 is less than a half. This is why I (and you) wanted an endpoint per webserver. So SmtpClient can work via a local loopback device instead of the slow "Intranet". I can't see why you accepted this answer. – mailq Sep 23 '11 at 21:51
  • Speed is nice, but it wasn't a stated requirement. We don't send that much mail. More important to me is ease of management and fault tolerance. – Larry Silverman Sep 23 '11 at 22:03