Saving autocomplete history in Outlook 2010 (and later)

Anyone who has had to transfer a user’s MS Outlook data from one computer or another has probably heard this question before:

“Where are all my addresses?”

Of course, you transferred the contacts so, confused, you ask the user what they’re talking about. The user then shows you that whenever they try to compose an e-mail, addresses do not “auto-fill” — hence “Where are all my addresses?”

Worse: in older versions of Outlook, there was no “Suggested Contacts” functionality so this sometimes lead to users completely disregarding the use of their address book, instead opting to depend solely upon autocomplete history.

Explaining to a user why this is bad practice will often get you nowhere. Luckily, most of the time you could just locate the *.nk2 file in their old profile and copy it to their new profile to restore their autocomplete history. This process has become slightly more complicated in Outlook 2010, but it’s still a simple thing to recover, provided you still have access to the original user profile.

  1. Locate the data file that contains the old autocomplete history. It will be in %userprofile%\AppData\Local\Microsoft\Outlook\RoamCache
  2. It will be named something like: Stream_Autocomplete_0_2CB1C400532AC94FAA6D3387E44FAE5B.dat … make a backup copy of this file and keep it in a safe place. If there are multiple similarly named files, backup all of them. Note that the largest file is likely the most important one.
  3. Locate the autocomplete file in the new userprofile; it will be in the same location but it will have a different name.
  4. Make a backup copy of the new one just in case it also contains autocomplete data that the user doesn’t want to lose and/or does not already have.
  5. Replace the new file with the old one from the old profile. Usually this just means that you overwrite the new file with the old one, ensuring that you change the name of the old file (the one containing all the data) to the filename of the new one. Make sure Outlook is not open when you do this. Alternatively, you can use NK2Edit to merge these files.
  6. Open Outlook and try to compose a new e-mail; your autocomplete history should be restored.

Sonicwall logs flooded with: destination for 255.255.255. 255 is not allowed by access control

I recently deployed a Sonicwall TZ200 (fw version: SonicOS Enhanced 5.6.0.11-61o) and after setting up SSLVPN access, the logs were being flooded with the following message:

1		03/20/2013 13:13:55.416	Info	SSLVPN	destination for 255.255.255.255 is not allowed by access control				
2		03/20/2013 13:13:51.672	Info	SSLVPN	destination for 255.255.255.255 is not allowed by access control				
3		03/20/2013 13:13:50.896	Info	SSLVPN	destination for 255.255.255.255 is not allowed by access control				
4		03/20/2013 13:13:50.176	Info	SSLVPN	destination for 255.255.255.255 is not allowed by access control				
5		03/20/2013 13:13:46.752	Info	SSLVPN	destination for 255.255.255.255 is not allowed by access control				
6		03/20/2013 13:13:46.016	Info	SSLVPN	destination for 255.255.255.255 is not allowed by access control				
7		03/20/2013 13:13:45.464	Info	SSLVPN	destination for 255.255.255.255 is not allowed by access control

I found a few discussion threads pertaining to this issue on the Sonicwall forums and I tried some of the solutions offered but none of them worked. If you have an account on the forums, you can see these discussions here:

https://forum.sonicwall.com/showthread.php?t=25636&highlight=destination+255.255.255.255

https://forum.sonicwall.com/showthread.php?t=24107&highlight=destination+255.255.255.255

https://forum.sonicwall.com/showthread.php?t=27473&highlight=destination+255.255.255.255

Through trial and error, I noticed that the messages stopped appearing in the logs (not immediately after, I might add) after disabling “Communication Between Clients” under SSL VPN -> Client Settings, and adding “WAN RemoteAccess Networks” to the Access List for the SSLVPN Services group (on the VPN Access tab) under Users -> Local Groups. The messages returned upon reversing these changes. I also noticed that whenever I enabled/disabled “Communication Between Clients”, the following error message was logged:

Adding L2TP IP pool Address object Failed.

I’m not sure if they’re related but they appeared to coincide. This doesn’t seem like the best remedy but at the time I wasn’t able to update the firmware on this device, so this was the next best thing. I’ll update this post once when I get a chance to update the firmware.

Zimbra Notes

This is going to be an ongoing post where I list useful commands that I happen across while managing various Zimbra installations. This is mainly for my own sanity but it has the added benefit of possibly being able to help out someone else. Enjoy!

Increasing the Maximum Allowable Attachment Size

By default, this setting is low. Nowadays it’s acceptable to send attachments larger than 10MB (but not obscenely larger). I don’t like it and I discourage my users from sending large attachments via e-mail but if you feel the need to loosen up this restriction, here are the commands to do that:

su -l zimbra
zmprov ms `zmhostname` zimbraFileUploadMaxSize 20971520
zmprov mcf zimbraFileUploadMaxSize 20971520
zmprov ms `zmhostname` zimbraMailContentMaxSize 20971520
zmprov mcf zimbraMailContentMaxSize 20971520
zmprov mcf zimbraMtaMaxMessageSize 20971520
zmmtactl restart

20971520 = 20MB in bytes.

Disabling the Spam Filter

Sometimes it might be desirable to disable spam filtering across an entire domain or COS. For example, if you pay a 3rd party service to do your spam filtering for you.

zmprov md domain.tld +amavisBannedFilesLover TRUE
zmprov md domain.tld +amavisSpamLover TRUE

The first command turns off all filetype filtering for the domain “domain.tld” while the second turns off all spam filtering. If you wanted to do this on a per-account basis, you’d do this:

zmprov ma user@domain.tld +amavisBannedFilesLover TRUE
zmprov ma user@domain.tld +amavisSpamLover TRUE

“ma” stands for “manage account” and “md” stands for “manage domain”. This is used to specify which type of object you are editing/managing. To reverse these changes you would just change the “+” to a “-” in the previous commands or change the “TRUE” to “FALSE”. My understanding is that this:

zmprov ma user@domain.tld -amavisBannedFilesLover TRUE
zmprov ma user@domain.tld -amavisSpamLover TRUE

Accomplishes the same exact thing that this does:

zmprov ma user@domain.tld +amavisBannedFilesLover FALSE
zmprov ma user@domain.tld +amavisSpamLover FALSE

(This is an assumption, someone please correct me if I’m wrong.)

Now, it’s also possible to completely disable spam and virus filtering, here’s how to do it:

zmprov -l ms `zmhostname` -zimbraServiceEnabled antivirus
zmprov -l ms `zmhostname` -zimbraServiceEnabled antispam

However, if you do this, you will end up with an ugly “***UNCHECKED***” tag inserted into the subject line of every e-mail. To get rid of that you’ll need to edit /opt/zimbra/amavisd/sbin/amavisd and change the following value:

$undecipherable_subject_tag = '***UNCHECKED*** ';

to:

$undecipherable_subject_tag = '';

And then restart Zimbra:

/etc/init.d/zimbra restart

Archiving/exporting/importing a user’s inbox

This is handy if you want to move a user from one server to another, or if you need to export and archive the mailbox of a user who no longer exists.

zmmailbox -z -m user@domain.tld getRestURL "//?fmt=tgz" > /tmp/user_inbox.tar.gz

Then, to import to another server:

zmmailbox -s -m user@domain.tld postRestURL "//?fmt=tgz&resolve=reset" /tmp/user_inbox.tar.gz

Further Reading:

What a n00b! | Zimbra junk mail options you didn’t know existed

Zimbra Forums » [SOLVED] ***unchecked***

Zimbra Wiki » Improving Anti-Spam System

Zimbra Account Export / Import from Command Line

DDoS via DNS Amplification and Windows Server 2003

A quick show of hands; who else is still running Windows Server 2003 somewhere on their network? Ok, how many of you depend on those servers for DNS? It’s 2012 for fuck’s sake… what the hell is wrong with you people?

… I kid, I kid.

Unfortunately for the time being, I’m included in that group. I’ve got more than a few clients who still rely on the Windows Server 2003 DNS — which is the reason I’m writing this post.

This morning I had a client complaining about their Internet connectivity being quite unreliable. It was easy to determine that this was a DNS-related problem: pinging 8.8.8.8 (Google’s public DNS) was successful while resolving google.com was not. This particular network only has a single DNS so naturally that is where I looked next. Running netstat -a revealed a ton of outbound traffic — all DNS queries — directed towards their upstream DNSs and the root servers. Their DNS was making these queries, but why? I’d disabled recursion on that server literally years ago, but for some reason it was still responding to recursive queries — look at the “Flags” section of the log snippet below (this particular snippet was generated by windows’ DNS debug log). Notice where it says RD 1. This means the query was recursive:


20121105 08:40:29 F94 PACKET  02612A00 UDP Rcv 72.8.132.25     ebe4   Q [0001   D   NOERROR] ALL   (4)ripe(3)net(0)
UDP question info
  Socket = 512, recvd on port (65535)
  Remote addr 72.8.132.25, port 53
  Time Query=12890, Queued=0, Expire=0
  Buf length = 0x0500 (1280)
  Msg length = 0x0025 (37)
  Message:
    XID       0xebe4
    Flags     0x0100
      QR        0 (QUESTION)
      OPCODE    0 (QUERY)
      AA        0
      TC        0
      RD        1
      RA        0
      Z         0
      RCODE     0 (NOERROR)
    QCOUNT    1
    ACOUNT    0
    NSCOUNT   0
    ARCOUNT   1
    QUESTION SECTION:
    Offset = 0x000c, RR count = 0
    Name      "(4)ripe(3)net(0)"
      QTYPE   ALL (255)
      QCLASS  1
    ANSWER SECTION:
      empty
    AUTHORITY SECTION:
      empty
    ADDITIONAL SECTION:
    Offset = 0x001a, RR count = 0
    Name      "(0)"
      TYPE   OPT  (41)
      CLASS  4096
      TTL    0
      DLEN   0
      DATA   (none)

Next I had a look at the firewall’s logs. The firewall has logging configured on all policies that allow requests from the public Internet, so when I saw this:

(For security purposes, we’ll pretend that the public IP address of the DNS targeted by the attack is 66.66.66.66)


Traffic Log for Policy:

(Src = "Untrust/Any", Dst = "Global/MIP(66.66.66.66)", Service = "DNS")

Current system time is Mon, 5 Nov 2012 08:43:21


Time Stamp Action Source Destination Translated Source Translated Dest Duration Bytes Sent Bytes Received Application

2012-11-05 08:43:11 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:42:55 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:42:39 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:42:23 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13695 72 DNS 
2012-11-05 08:42:07 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13197 72 DNS 
2012-11-05 08:41:51 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13529 72 DNS 
2012-11-05 08:41:35 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:41:19 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13363 72 DNS 
2012-11-05 08:41:11 Permit 200.35.37.219:1620 66.66.66.66:53 192.168.0.252:53 1 sec 75 208 DNS 
2012-11-05 08:41:09 Permit 199.224.64.72:27181 66.66.66.66:53 192.168.0.252:53 2 sec 90 120 DNS 
2012-11-05 08:41:05 Permit 67.94.175.199:53253 66.66.66.66:53 192.168.0.252:53 2 sec 86 219 DNS 
2012-11-05 08:41:03 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:40:47 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:40:31 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:40:15 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:39:59 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:39:55 Permit 64.233.168.83:36593 66.66.66.66:53 192.168.0.252:53 3 sec 75 91 DNS 
2012-11-05 08:39:43 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:39:27 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13446 72 DNS 
2012-11-05 08:39:11 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13363 72 DNS 
2012-11-05 08:38:55 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 13612 72 DNS 
2012-11-05 08:38:39 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 7 sec 9462 1112 DNS 
2012-11-05 08:38:33 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 25730 72 DNS 
2012-11-05 08:38:33 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 1 sec 83 1251 DNS 
2012-11-05 08:38:27 Permit 168.95.43.42:52906 66.66.66.66:53 192.168.0.252:53 4 sec 90 106 DNS 
2012-11-05 08:38:19 Permit 64.80.255.118:35570 66.66.66.66:53 192.168.0.252:53 3 sec 90 130 DNS 
2012-11-05 08:38:17 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 17 sec 24817 72 DNS 
2012-11-05 08:38:01 Permit 72.8.132.25:53 66.66.66.66:53 192.168.0.252:53 1 sec 166 1271 DNS 
2012-11-05 08:37:19 Permit 208.69.34.19:43768 66.66.66.66:53 192.168.0.252:53 4 sec 79 95 DNS 
2012-11-05 08:37:17 Permit 208.69.34.19:21491 66.66.66.66:53 192.168.0.252:53 2 sec 79 95 DNS 
2012-11-05 08:37:15 Permit 208.69.34.19:28679 66.66.66.66:53 192.168.0.252:53 1 sec 79 95 DNS 
2012-11-05 08:35:21 Permit 207.46.200.45:9397 66.66.66.66:53 192.168.0.252:53 3 sec 84 100 DNS

…It was pretty obvious what was going on. There were a few other suspicious IP addresses in the logs other than 72.8.132.25 including, but not limited to:


217.72.241.20
220.226.6.118
203.113.188.6
203.113.131.9
203.113.188.3

  1. Loads of traffic originating (i.e., “distributed”) from multiple source IPs? Check.
  2. Internet connectivity (i.e., “service”) pretty much dead (i.e., “denied”)? Check.

This has all the makings of a Distributed Denial of Service attack (DDoS). This particular type of DDoS is known as a DNS Amplification Attack, technically it’s a distributed reflected denial of service attack (DRDoS). It can occur when you are running an open DNS and somebody with malicious intent notices.

After blocking inbound requests from all of the suspicious IPs and verifying that service had been restored, I shifted my focus back to the DNS. There are two places in the DNS Management Console where you can disable recursive queries:

…But as far as I can tell, the DNS built into Windows Server 2003 will allow you to change these settings and then it disregards your configuration and does whatever it damn well pleases. You’d think that between the two of these configuration options, the server wouldn’t respond to any recursive queries. Sadly this is not the case as you can see in the test results from DNSStuff:

DNSStuff also provides a link in the test output that describes which steps you should take in order to close an open DNS. Unfortunately…

NOTE: These instructions show you how to completely disable recursion. This is the best practice. However, if you need to run a DNS server that is both authoritative and recursive/caching, you will need to check the DNS server documentation to find out how to enable recursive lookups only for your local network. It seems that there is no way to do this with Microsoft DNS; if so, you will need to use other DNS server software or use a hosted DNS service. If anyone is aware of a way to get Microsoft DNS to allow recursion only to specific IP ranges, please let us know -- lots of people would like to do that.

This is the default behavior of the Windows Server 2003 (and 2008, 2012 from what I’ve read) DNS. In other words, it is insecure out of the box — this is analogous to allowing unauthenticated, unrestricted relaying on a mail server by default. Thanks Microsoft!

Anyway… since the company-in-question has it’s website hosted on the local network and their only DNS also serves as the authoritative DNS for their domain name, my next course of action will be to configure a separate non-windows DNS and use that to host their zones. Let this serve as a cautionary tale to any of you out there who might be using a Windows server as an authoritative NS for domains and a resolver for queries originating on the local network.

Simple configuration file parser (python)

Python’s ConfigParser works well for INI files but what about config files that are simple key/value options? For example, ConfigParser will not work with files like this:


#Example configuration file
#Foo Bar-er v1.0
foo_dir="/var/lib/foo"
bar_dir="/var/lib/bar"
foo_all_the_bars="1"
bar_all_the_foos = "yes, do it"

Granted, the example above is a poorly written config file however I’m using it as an example to demonstrate the flexibility of configuration parser. So here’s the code:


# SimpleConfigParser
# Inspired by:
# http://www.decalage.info/fr/python/configparser
class SimpleConfigParser():

    def __init__(self, comment_char = '#', option_char = '=', allow_duplicates = False, strip_quotes = True):
        self.comment_char = comment_char
        self.option_char = option_char
        self.allow_duplicates = allow_duplicates
        self.strip_quotes = True

    def parse_config(self, filename):
        self.options = {}
        config_file = open(filename)
        for line in config_file:
            if self.comment_char in line:
                line, comment = line.split(self.comment_char, 1)
            if self.option_char in line:
                option, value = line.split(self.option_char, 1)
                option = option.strip()
                value = value.strip()
                value = value.strip('"\'')
                if self.allow_duplicates:
                    if option in self.options:
                        if not type(self.options[option]) == list:
                            old_value = self.options[option]
                            self.options[option] = [value] + [old_value]
                        else:
                            self.options[option] += [value]
                    else:
                        self.options[option] = value
                else:
                    self.options[option] = value
        config_file.close()
        return self.options

And here’s an example of how you’d use this (assuming you saved the code in a file named ‘simpleconfig.py’ and you saved the example config as ‘example.cfg’):


Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from simpleconfig import SimpleConfigParser
>>> scp = SimpleConfigParser()
>>> scp.parse_config('example.cfg')
{'bar_dir': '/var/lib/bar', 'foo_all_the_bars': '1', 'foo_dir': '/var/lib/foo', 'bar_all_the_foos': 'yes, do it'}
>>>

Also, if you have a config file that has duplicate “options” (nagios.cfg comes to mind), you can do the following:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from simpleconfig import SimpleConfigParser
>>> scp = SimpleConfigParser(allow_duplicates = True)
>>> nagios_config = scp.parse_config('/etc/nagios3/nagios.cfg')
>>> nagios_config['cfg_dir']
['/etc/nagios3/conf.d', '/etc/nagios-plugins/config']
>>> 

Instead of a key/value pair, you’ll get a key with a list as it’s value for each identically named configuration option.