CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

June 2006 - Posts

  • ASP.NET 1.1 working with an ASP.NET 2.0 web.config file

    In a recent post I described the trouble an asp.net 1.1 application has with a web.config file targeted at asp.net 2.0. The main problem is that the asp.net 1.1. runtime does not understand parts of the 2.0 web.config and crashes. My first solution was to move settings to the global 2.0 config. In a brilliant comment Joshua Flanagan suggested to bring the problem to its owner. His idea was to teach asp.net 1.1 the 2.0 specific sections and tell it to ignore them. This sounds more complicated than it is and works well.

    For a good overview of the web.config in 1.x I again recommend James Avery little book,  I blogged before on that. The global configuration of asp.net 1.x is in the machine.config file in \WINDOWS\Microsoft.NET\Framework\v1.x\CONFIG. (Note that 1.x does not have a global web.config like 2.0). This file has a list of sections and the assemblies to handle the sections. The framework has a very handy handler, the IgnoreSectionHandler. Which does exactly what's desired: nothing. This snippet tells asp.net to ignore the connectionstrings section

    <?xml version="1.0" encoding="utf-8"?>

    <configuration>

     

      <configSections>

        <!-- tell .NET Framework to ignore 2.0 sections -->

        <section

            name="connectionStrings"

            type="System.Configuration.IgnoreSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

            allowLocation="false" />

     

        <!-- tell .NET Framework to ignore CLR sections -->

        <section

            name="runtime"

            type="System.Configuration.IgnoreSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

            allowLocation="false" />

        <section

            name="mscorlib"

    Entering it is easy, copy the runtime section, just below and change the name attribute. Asp.net has far more sections than 1.1, like the system.web.rolemanager and system.web.membership, which came by in the previous post. Add the sections as needed. Perhaps it would have been nice if there was an installation tool  which modifies the 1.x machine.config for all 2.0 specific sections. Hey MS, are you listening?

    There is one incompatibility which is not handled. In 2.0 the configuration node has a namespace attribute.

    <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

      <appSettings/>

      <connectionStrings>

    1.x trips over that. Delete the attribute:

    <configuration>

      <appSettings/>

      <connectionStrings>

    Asp.net 2.0 works without it. Assigning a namespace might be useful for future versioning, but it hinders backward compatibility.

  • Web.config combinations going bad Incompatible entries and incompatible framework versions

    When an asp.net application is started it processes the web.config file. Doing so it is combined with with all web.config files found up in the tree of virtual directories. Suppose you have a website located at www.YourSite.com/NiceWebApp/ and some supporting webservices like www.YourSite.com/NiceWebApp/Services/NiceService.asmx. When the webservice is loaded by the webserver the web.config of the NiceWebApp is read as well. Even when the physical path does not have a tree structure. This is nice, the site and service can share settings. Administering the settings can be done in one place: the site.

    But things can go wrong as well. Suppose the website uses a custom role and membership provider. The code is in the app_code dir of the site, the web.config of the site loads it. This is a part of the site's web.config

    <roleManager defaultProvider="DirActivityRoleProvider"

      enabled="true"

      cacheRolesInCookie="true"

      cookieName=".ASPROLES"

      cookieTimeout="10"

      cookiePath="/"

      cookieRequireSSL="false"

      cookieSlidingExpiration="true"

      cookieProtection="All" >

      <providers>

        <clear />

        <add

          name="DirActivityRoleProvider"

          type="DirActivity.WebSite.DaWsRoleProvider"

          applicationName="DirActivity" />

      </providers>

    </roleManager>

     

    <membership defaultProvider="DirActivityMemberProvider" userIsOnlineTimeWindow="15">

      <providers>

        <remove name="AspNetSqlProvider" />

        <add name="DirActivityMemberProvider"

            type="DirActivity.WebSite.DaWsMemberShipProvider"

            enablePasswordRetrieval="true"

            enablePasswordReset="false"

            requiresQuestionAndAnswer="false"

            passwordFormat="Hashed"

            applicationName="/" />

      </providers>

    </membership>

    <pages theme="DirActivityTheme">       

    </pages>

    It loads and configures a roleManger, a membership provider and sets a theme for the pages.

    Now when the service loads it will also read and try to process the web.config of the site. Doing so it will try to load the assemblies for the custom providers and the theme stylesheet. It can't find any of them and the service will crash on each of them. To prevent this you have to reset all of this in the web.config of the service and explicitly clear the provider lists.

    <roleManager enabled="false">

      <providers>

        <clear/>

      </providers>

    </roleManager>

     

    <membership>

      <providers>

        <clear/>

      </providers>

    </membership>

    <pages theme=""></pages>

    As you can see the different entries have different possibilities to knock them out .

    ASP.NET 1.1 and 2.0 running on the same web server

    The example above deals with two asp.net 2.0 applications. Things get worse when an asp.net 1.1 app enters the stage. This will also try to process all files named web.config up in the virtual directory tree, regardless of their intended framework version. That's not to good. The real bad thing is that asp.net does not understand an asp.net 2.0 config file. It will first crash on the xmlns attribute of the configuration node, after that on the connectionstrings node and so on. Now suppose the root of your web site is an asp.net 2.0 application and in one the sub directories lives an asp.net 1.1 application. This is what happened to me, my site is the 2.0 site and inside lives Outlook Mobile Access which is an asp.net 1.1 application. I know you shouldn't combine all of that in one server but resources are limited, I  have to get this rolling and am learning step by step. The site needs some configuration settings in a web.config in the root, oma will try to process that and will crash. Googling around I found this a problem many people wrestle with, but in a comment on a desperate post by Rick Strahl I found an easy solution which works perfect for me.

    After reading in all web.configs up the tree asp.net 2 finally combines the settings with the web.config found in the \WINDOWS\Microsoft.NET\Framework\version\CONFIG. For a 2.0 app it will read the one in \WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG, for a 1.1 app it will not see this file. I moved the settings from the web.config in the root to this file and deleted the file in the root. Now all apps are quite happy: the 2.0 root has its settings and the 1.1 one isn't blinded by them. Only the administration is a little harder as this web.config is somewhat larger. I can live with that.

  • A long running SQL batch in asp.net with feedback

    Another story from the app with the sprocs. That was a classical 2-tier CS application which we transformed into an asp.net 1.1 app. Once a year the application has to copy and transform huge amounts of data. This is done by running a batch of stored procedures which run in one huge transaction after which the database is ready for the next year. It takes quite a lot of time, up till now 8 hours was not unusual. The growing usage of the app will only increase the amount of time needed. Some feedback on the progress would be nice. For a windows client all of this is not that difficult to build, to get something likewise in asp.net is a different ballgame. We managed to get something working. It does have a drawback though; more on that in the end.

    The outline of our approach:

    • Create a table with a progress message and a timestamp
    • Start a transaction and enlist all sprocs
    • Start the sprocs one by one
    • In between add progress records to the temp tables
    • Wrap the process up in a method which is started in a new thread
    • Start the thread and navigate to another page which periodically queries the progress table

    Some essential parts of the code

    A helper function kopieSproc wraps up an individual stored procedure in a SqlCommand, sets the parameters and sets the timeout of the command. Setting up the transaction and enlisting the procs:

    SqlCommand cmdPRKOPIEJRBDGAFD = kopieSproc("dbo.PRKOPIEJRBDGAFD", idFaculteit, vanJaar, naarJaar);

    // More sprocs

    SqlCommand cmdPRKOPIEROOSTER = kopieSproc("dbo.PRKOPIEROOSTER", -1, vanJaar, -1);

     

    sqlConnection1.Open();

    SqlTransaction trans = sqlConnection1.BeginTransaction();

     

    // Alle sprocs in 1 transaction

    cmdPRKOPIEJRBDGAFD.Transaction = trans;

    // More sprocs

    cmdPRKOPIEROOSTER.Transaction = trans;

    A  helper function reportStatus fires a sqlcommand to write a status record to the table. This command should not enlist in the transaction. The transaction is meant to get an all or nothing result, changes are not visible until the transaction is committed. The status row has to be visible the moment it is added to the table.

    Running the transaction:

    try

    {

        reportStatus(cmdStatus, "Start kopiëren cursusjaar");   

     

        reportStatus(cmdStatus, "Start kopieren jaarbudget school");

        rc = cmdPRKOPIEJRBDGAFD.ExecuteNonQuery();

        reportStatus(cmdStatus, string.Format("{0} regels toegevoegd", rc));

     

        // More sprocs

       

        reportStatus(cmdStatus, "Start kopieren roostergegevens");

        rc = cmdPRKOPIEROOSTER.ExecuteNonQuery();

        reportStatus(cmdStatus, string.Format("{0} regels toegevoegd", rc));

     

        reportStatus(cmdStatus, "Commit naar database");

     

        trans.Commit();

     

        reportStatus(cmdStatus, "Kopieren voltooid");

    }

    catch(Exception ex)

    {

        trans.Rollback();

        reportStatus(cmdStatus, ex.Message);

        reportStatus(cmdStatus, string.Format(ApplicationMessages.CursusJaarKanFaculteitNietKopieren, idFaculteit));

    }

    finally

    {

        sqlConnection1.Close();

        reportStatus(cmdStatus, "Connectie met DB gesloten");

    }

    So these  lines of code can take hours and hours to complete. After each successful step, or after an exception a row is added to the table. Never mind the Dutch, the idea should be clear.

    The whole process is wrapped up in a method KopieerFaculteit, which is a member of a component in the data layer. A web page starts a new thread for the method and navigates away.

    private void maakKopie()

    {

        int idVanJaar = int.Parse(DropDownListVan.SelectedValue);

        int idNaarJaar = int.Parse(DropDownListNaar.SelectedValue);

        JaarData.KopieerFaculteit(int.Parse(DropDownListFaculteit.SelectedValue), idVanJaar, idNaarJaar);

    }

     

    private void Button1_Click(object sender, System.EventArgs e)

    {

        System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(maakKopie));

        t.Start();

        Response.Redirect("../SysteemBeheer/KopieerStatus.aspx");

     

    }

    The maakKopie method collects the parameters from the form and will keep running for quite some time on its own thread. The user is redirected to the status page.

    The follow the status, the status page has to requery the database periodically. Refreshing the page is automated by setting the (browser's) requery interval in the head of the page to 30 seconds.

    <HEAD>

        <title>KopieerStatus</title>

        <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">

        <meta name="CODE_LANGUAGE" Content="C#">

        <meta name="vs_defaultClientScript" content="JavaScript">

        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

        <meta HTTP-EQUIV="REFRESH" CONTENT="30">

    </HEAD>

    The result is that the application is responsive, none of the responses takes long to generate. The application is also informative, the user will be kept up to date about the status of the process. The application will stay alive, as it has to handle a request every 30 seconds.

    A small drawback is debugging. Any exception, however futile (like an error message which is to long to fit in the status field) trashes the thread with a quite non-informative "system error" message. So before running the code in a new thread you'll have to try it on the main thread. And now you have to set the page time-out to something large. Which does have it's drawbacks.

    But, as said in the beginning of this story, there is a larger drawback. The thread running the sql batch lives in the IIS application. As long as the application is alive the thread will keep running. But there are a lot of ways the application can be restarted. In .net terms the appdomain is recycled and your thread dies.

    • IIS is restarted
    • A content file of the application, like an aspx page or the web.config, is touched
    • Spontaneously, IIS restarts the application to free up resources.

    You can control the first two, but you cannot (afaik) control the latter one. Googling around on recycling an appdomain will give you a lot of information but no solution. The only one is to limit the amount of work you do in one go. Which does make a lot of sense but in our case that would be a major re-architecting of the application. All the BL is in the sprocs and their interaction. It works and it's result are exactly what's desired. So better stay away from changing that.

    Any suggestions are welcome. For the moment we're happy with this.

  • Bill gave me wings

    In a nice post on the announced retirement of Bill Gates John was asking how Bill Gates had impacted our lives.

    During my studies I had the opportunity to work with real computers and got totally addicted. When I finished in 1984 my access to these wonderful machines stopped. There were home computers but none of them were serious enough to do the things I wanted to keep doing. In the same year IBM introduced the Personal Computer, but took it for a souped-up type writer. To get the thing rolling they licensed something from a young nerd who did believe in the possibilities, had the vision where it could go and produced something which did work: Bill Gates. My first own machine was an Olivetti running MicroSoft Disk Operating System 2.11. The rest is history.

    But Bill Gates, as the face of Microsoft, has given me more than just tools to get myself a profession. As a kid I had always been crazy about airplanes and flying. Flying myself had always been far out of reach. With the first PC came also the first edition of Microsoft Flight simulator. It took some imagination to see an airplane in the rough 320*200 green wire frames and using the numeric keypad as a stick is far from the real world. But I finally got a chance to fly! And I still do it on a regular basis, now with an MS FF joystick. For entertainment most of you are probably shooting up aliens in (also Microsoft) Halo. I like to chase Zero's or Messerschmidt's in MS CSFx.

    A weird coincidence: the day Bill Gates announced his retirement I visited my first real big air show. For the other flying geeks over there a snapshot of another historical moment over there:

    The Blue Angels flying formation with the Red Arrows.

    Would I have been there without Bill? Probably not.

  • Timeout of an ASP.NET page

    In some cases it can take quite some time for the web server to complete your webpage. Setting a time out is not that difficult but Googling around you will either find over complicated scenarios or a very simple and clear story in Dutch. Before recapitulating that one in English I have to credit the author Michiel van Otegem. Besides writing some good content he's done a lot of work for the Dutch user group dotned. See him smiling here, he's the guy on the final picture.

    The timeout for a page request depends whether you are running debug or release code. The setting is in the web.config. In debug mode the timeout is 30000000 seconds which is about a year. In release mode the timeout is only 90 seconds. In some cases that may not be enough. You cannot set the timeout as a property of the page itself; it is a property of the global Server object. Set it in the page init event and reset it in the page unload event.

            private int timeOut;

            private void KopierenJaar_Init(object sender, System.EventArgs e)

            {

                timeOut = Server.ScriptTimeout;

                // Give it 1 hour = 3600 seconds

                Server.ScriptTimeout = 3600;

            }

     

            private void KopierenJaar_Unload(object sender, System.EventArgs e)

            {

                Server.ScriptTimeout = timeOut;

            }

    In case your page is doing heavy things in the database you have to set db timeouts as well. See here for a quick look at that.

  • .NET 3.0, formerly known as...

    Almost everybody wanted to say something on the .NET 3 moniker. From FUD like the return of DLL-hell. To the notion that whatever poetic or dull name a piece of software had to live under, it's all just another target for your C#/VB.NET/<your favorite language here> code.  The only one thing which really worries me is the documentation. Take this snippet which comes with the current WinFX sdk:

    What's Next
    You now have a number of techniques to handle input in Windows Presentation Foundation (formerly code-named "Avalon"). You should also have an improved understanding of the various types of input events and the routed event mechanisms used by Windows Presentation Foundation (formerly code-named "Avalon").

    Additional resources are available that explain Windows Presentation Foundation (formerly code-named "Avalon") framework elements and event routing in more detail. See the following overviews for more information, Base Elements Overviews, Element Tree overview, Events Overview, and the Routed Events Overview.

    Looks like a brain dead macro put it's mark on an original document. Making it almost unreadable. What will the .net 3 version of this doc look like? Wouldn't this be the moment to just drop all of this "formerly known as" name-fetishisms. It's up to Sam what to do with his blog title.

  • Passing the screwdriver to the next generation (Fiddling with a computer housing)

    Today was a special day. It would have been my dad's 77th birthday. He didn't even live to celebrate his 70th. As a technical engineer, specialized in thin layers, he worked for Philips. His first main project concerned the inner coating of CRT tubes, his second was taking part in the development of discs for optical storage. The first is almost fit for the museum; but every time I hold a CD or DVD he's still near. As a hobby (better said out of the hobby grew his profession) he constructed radio's and other electronic devices. Started with tubes, made the step to transistors and after that came IC's and microprocessors. Working completely bottom up, from diode to microprocessor he made his way up through teaching his TI-59 to play chess, Z80 assembly language to (finally) MS-DOS and Turbo Pascal. I did (initially) not follow his steps; but coming top down from biology, through computer based simulation we met in Turbo Pascal.

    The thing we always liked both was "knutselen": fidling with screwdrivers and small wrenches. He could spend an entire evening just fixing a a pot-meter right. And today I "wasted" a couple of hours assembling a PC. Not just a normal one, I want my machines to be quiet. Also in the spirit of my dad (he spent quite some time with clubs like the CSVN and HCC (ZX81/MSX)) I want to share some of the things I learned today on computer housings:

    • The are quite a lot of good looking and well isolated models around. But the fans of all of them sound like vacuum cleaners. In case you want a quiet PC you'll have to find some good replacement fans as well.
    • In the majority of these days models the drives are fixed using a clamping mechanism, looking something like this:

    This may look nice and quick but is a disaster to work with. The average "knutselaar" like you or me will not manage to get the drives firm and vibration free in place Nothing beats plain screws ! My dad was right.

    Finally I also want to thank the ikbenstil company again. They are quite geeky, specialized in (parts) for silencing PC's and operate (over the web) in most European countries. They make support, customer satisfaction and screwdriver-pleasure into a form of art. Absolutely recommended!

     

  • Visual accessibility of web pages: no real progress yet

    Working  a lot with a computer has a couple of health risks, which get bigger and bigger over the years. There are several ways to fight this:

    Big text has imho still a long way to go in Windows.

    The thing I always liked best about Firefox is not tabbed browsing but the impressive way you can simply set the font size by pressing ctrl-+/- or ctrl-scrollwheel. IE does this as well but the thing Firefox does far better is wrapping the text. And Firefox has a far greater range of text sizes. Many a site is easier to read with FF. Although it can be irritating that many a site has the width of a text block set absolutely, you end up with big text on a quarter of the screen width and 3 quarters of the screen width empty. Such a waste of resources

    Making a web page easy to read is not difficult at all. I wanted my new website visual accessible both in FF and IE. This is how I did that.

    The main markup of the masterpage

      <div>

        <table style="width:100%">

            <tr>

            <td><asp:Image ID="Mondriaan" runat="server" style="width:100%" ImageUrl="~/images/Mondbanner.gif"></asp:Image></td>

            <td class="big">Gekko Software</td>

            <td><asp:Image ID="Hemidactylus" runat="server" style="width:80%" ImageUrl="~/images/gekko.gif"></asp:Image></td>

            </tr>

        </table>

        <table style="width:100%">

            <tr>

            <td style="width: 120px; vertical-align:top">

            <asp:Menu ID="HoofdMenu" runat="server">

                <Items>

                    <asp:MenuItem Text="Services" Value="Services" NavigateUrl="~/Services.aspx"></asp:MenuItem>

                    <asp:MenuItem Text="Portfolio" Value="Portfolio" NavigateUrl="~/Portfolio.aspx"></asp:MenuItem>

                    <asp:MenuItem Text="Publications" Value="Publications" NavigateUrl="~/Publications.aspx"></asp:MenuItem>

                    <asp:MenuItem Text="Contact" Value="Contact" NavigateUrl="~/Contact.aspx"></asp:MenuItem>

                    <asp:MenuItem Text="Blog" Value="Blog" NavigateUrl="http://codebetter.com/blogs/peter.van.ooijen/default.aspx"></asp:MenuItem>

                    <asp:MenuItem Text="About" Value="About" NavigateUrl="~/about.aspx"></asp:MenuItem>

                </Items>

            </asp:Menu>

            </td>

            <td><asp:contentplaceholder id="ContentPlaceHolder1" runat="server">

                </asp:contentplaceholder>

            </td>

            </tr>

     

        </table>

        </div>

    Quite simple. The page heading is a three column table. Its width is set to 100% so it will use all real estate available. The images in the left and right column will also fill them according to space available. The middle column contains plain (CSS decorated) text. The middle part of the page is even simpler: a fixed size column for a menu and one column for the content.

    The content I want to demonstrate here is no big deal either. It reads an htm file, extracts the body and assigns that to a label (read here for the details)

    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

    <div>

        <asp:Label ID="LabelArticle" runat="server" Text="Label"></asp:Label>

    </div>

    </asp:Content>

    You can shrink or blow up the text size, in FF almost ad absurdum. From tiny

    to huge

    At a given moment a horizontal scroll bar will show up. The moment this happens in FF is (coincidental ?) when the text reaches the maximum size of IE.

    In comes IE7 which brings tabbed browsing and also a far greater range of text size. But just look what happens when you increase the size to more than 100%

    A horizontal scroll bar shows up which makes the text unreadable. Which makes it, when it comes to visual accessibility, a big step back.

    IE7 is in beta and beta does have bugs. What worries me is that such a (imho) blatant bug has not been spotted before the beta release. What worries me even more is that Charles Petzold had a quite similar story of a WPF bug when changing Window's DPI. Are computer screens becoming something just for the young?

  • Setting up a simple internet server (pt3) Accept incoming traffic (Sometimes default is not secure enough)

    In two previous post I described my first steps in setting up my own internet server.

    • Part 1 described choosing the hardware and orchestrating all network traffic bound for the internet.
    • Part 2 described setting up Active Directory as a central hub of configuration

    To conclude this story will focus on handling incoming traffic, which is after all the main reason to set up my own server. The main concern is safety. I want people to visit my website en to be able to sent me mail. But I don't want my server to be a prey of a hostile takeover or used as spamming machine for others. I don't believe I can secure my site against every imaginable form of attack. But I am sure I can make it as difficult as possible for any intruder by setting up several lines of defense at several places between the cable coming in and the server's hard drive.

    The first hurdle incoming traffic has to take is the router built into the DSL modem. The router does Network Address Translation (NAT); it translates the sender address in outgoing IP packets and will redirect any responses to the request to the original requester. As a result the router drops all packets which were not a response to a request originated in this router. So by default all incoming traffic is blocked. There are several ways to accept incoming traffic. The way to do this will depend on the brand, check your manual for the details. The easiest way is to redirect all incoming traffic to one of the connections on the router. The bad thing is that this will redirect traffic on all ports. In my case I only want to accept web surfing over HTTP and sending mail using SMTP. The good thing is that instead of redirecting all traffic you can select individual ports. In my case the router will only redirect traffic on port 80 (HTTP) and port 25 (SMTP). All other (potential malicious) traffic will not even reach my server. In case I need a web-enabled app which needs other ports it's a matter of opening just that specific port.

    The server itself has a second firewall. As my server is running server2003 I'm using ISA server 2004 (What's in a name..). Getting its base configuration setup is a matter of wizards and more wizards. ISA server has one for every kind of server you can imagine, and even more. Its user interface is very nice and gives a good overview how a firewall works.

    A firewall is a list of rules against which an incoming data packet is tested. Each rule states

    • The result when the rule is met. This set of rules gives a packet 4 chances to get allowance. When the first four fail the fifth will just discard the packet.
    • The protocol of the packet. This sets only tests for SMTP (mail) and HTTP (web browsing) packets.
    • The direction of the traffic. External packets only make a chance when they fall in the SMTP or HTTP protocol.
    • The destination. Mail packets are only allowed to the mail server
    • An extra condition. This allows for specific users to get more rights. In my case this is not interesting but this allows for endless configuration (and vulnerability) scenarios.

    These rules overlap with those on the router; the HTTP and SMTP check is made twice. To compromise my server an attacker has to get through both firewalls. As these are totally different in hard- and soft-ware it's quite unlikely that a technique to breach one will also breach the second. The attacker needs to breach both to get in; so using two firewalls does make that a lot harder.

    The wizards will set up the basic rule, after that you can fine tune every rule with very rich dialogs. As a developer I'm easily lost in the many configuration possibilities, some of them are completely new to me. The good UI of ISA server has not only helped me setting up my firewall but has also learned me more about internet traffic than most of the documentation.

    As a mail server I'm using Exchange 2003. Most of the configuration is done in Active Directory. Each domain user has its own mailbox. A mailbox can accept mail sent to a large number of email addresses. Take mine:

    These addresses fall in multiple domains. By default Exchange will only accept email for the domain which the mail server is part of. As seen in the ISA server firewall overview the server will listen for incoming mail on an IP address, which can stand for any domain (see later). In case someone tries to send me email on another domain I will receive relaying errors, much like the kind described here. If you want your server to accept email sent to the non default domain this has to be set this in the recipient policies of the Exchange System Manager

    As a last check make sure to run Microsoft Baseline Security Analyzer which does a good job in a load of checks. Having passed that the server should be ready to accept and handle incoming traffic.

    Throwing the switch was somewhat more complicated than I had anticipated. It all boils down to associating the IP address of my DSL modem with the domain names (Gekko-Software.nl, petersgekko.net, petersgekko.com) in the internet's name servers. This is a two stage thing. The first one is registering the name of the domain with an official registar. This can be your ISP but you can also do it yourself on a site like Stargate.com The second step is coupling your IP address to the domain(s). Again this can be done by your ISP or you can do it yourself at a place like zonedit.com. What happens after changing the address is a little time of utter chaos. In the forest of nameservers of the web it's impossible to see the individual trees and these trees don't update instantaneously. Give things 24 hours to settle and when it's really important to keep a domain in the air (I had some serious problems with my default Gekko-Software.nl domain) make sure you have professional help nearby. Again I have to praise xs4all for their professional and dedicated service. To direct the incoming mail to your own server is independent from the other traffic. It's a matter of entering the qualified name of the mail server in a so called DNS MX (Mail eXchange) record. The name of the mail server (sturisoma.petersgekko.net) contains the name of a registered domain (petersgekko.net). So the direction the mail will take is fully dependent on a domain name, not an IP address .

    When the server is up you should test it for security breaches A very nice site is DNSgoodies, here you can do all crucial tests on one web page. Server 2003 and Exchange 2003 are supposed to be secure by default. Nevertheless my tests for an open relay failed. Which would make my server a potential source of spam. This warning was pretty real, within a couple of hours some spam started to accumulate in the queues. I'm not sure whether it was actually delivered but the fact that a server will show up as an open relay is enough to get blacklisted and cleaning up the mess by hand is something you don't want to do. Setting this right took some effort. Google hits on the subject tell you how to disable relaying, but that will point to the default setting already present. What really helped was switching on recipient filtering, nicely described heree. This will discard any mail sent to someone who is not in my Active Directory and blocks the open relay. That's exactly what I want. Having applied the setting DNSgoodies congratulated me and my mail queues are clean again.

    That's about it. I'm not an ITpro guy but it looks like I managed to get everything up and running nevertheless. And it's humming along sweetly, over here everybody is content. But feel free to comment on anything which could be done better.

     

More Posts