Cluster terminology – What “Active/Active” actually means

As a follow-up to my last entry (attempting to clear up some Windows Clustering terminology), I’ve found an article that makes another distinction that I forgot to include – the difference between an active/passive and an active/active cluster:

The misconception of active/active clustering (a la AirborneGeek.com)

The understanding among those new to cluster seems to be that a/a vs. a/p is a licensing question, and then if you’re licensed for it, you just turn it on. In reality, it really just describes whether you have clustered services living on only one node or split between both nodes (during normal operation – during a cluster failover, any cluster might be active/active for a short period of time. Or, I suppose, your cluster is active/active if your quorum drive lives on the opposite node from your clustered service). There’s no load-balancing involved in clustering at all – at any time, only one node owns a particular resource, and only that node is responding to client requests for that resource.

In SQL Server 2012 AlwaysOn, the new high-availability feature, the SQL Server service is running on both cluster nodes, but client access (through the “Availability Group”) is controlled by the cluster service. That means that all clients making a connection go first to the active server, and then the SQL Service there might send them to get their data from one of the other nodes (it’s worth reiterating here that, in AlwaysOn, SQL Server isn’t clustered, but the SQL services operate independently on each node).

Clearing up Windows Cluster terminology

I wanted to clear up some terminology around Windows Clusters that seems to cause a bit of confusion. I’ve stumbled across a few questions on StackOverflow and Experts-Exchange that seem to have some basic confusion around “clustering servers” and “how to install an application to a cluster”, and I’m hoping to set a few things straight.

  1. There’s really no such thing as a clustered server. Servers can have clustering enabled and configured, but the servers themselves aren’t really clustered – they’re just set up to enable clustered applications. When servers are part of a cluster, they still do all their thinking on their own, including running their own applications, services, and tasks, without the other servers in the cluster even being aware.
  2. You don’t cluster servers, you cluster applications and resources. Once servers have had clustering installed and are configured, you can cluster an application or a resource. This clustering is really just telling the cluster manager that you want it to control which server clients talk to when they want to access the resource. The cluster manager ensures that the application (or service or resource) is running on only one node at any given time, and to the extent it’s able, it ensures that it’s always running (watching for a failure and bringing the resource online on another node and then directing clients to that node instead).
  3. Applications don’t have to be “cluster-aware” to be clustered. I work mostly with SQL Server, which is cluster-aware, but applications you cluster don’t need to be. You can cluster any service, or resource on a server by just adding it to the cluster manager – the cluster manager will ensure it only runs on one server at a time, not allowing it to start on other nodes. For example, we use a monitoring tool that runs as a service – we installed the service on each cluster node and then added to the cluster manager – it now can be failed back and forth between nodes as a clustered resource, so it’s always online, is failure-resistant, and shares a segment of the HKLM in the registry between nodes – all without being explicitly cluster-aware.
  4. SQL Server doesn’t need to be clustered when it’s installed on a cluster. While you can install a clustered instance of SQL Server (which automatically registers everything with the cluster manager), you can also install stand-alone instances of SQL Server (or any other application) on a cluster. That’s actually how a new feature in SQL 2012 – AlwaysOn – works: You install a non-clustered instance of SQL Server on different cluster nodes, and then you let the cluster manager coordinate client connections to the SQL Servers, but they still operate independantly and replicate their data between each other.

Hopefully this clears things up and doesn’t lead to more confusion. When I first started working with clustering, I had the impression that setting up a cluster caused the servers to act as one and share all their resources, but that understanding led to a lot of confusion when it came time to set something up or troubleshoot an issue. With the understanding that “clustered servers” are really just servers with clustered resources, and not actually clustered themselves, hopefully it will simply things!

Clean up vendor names and other data with unwanted numbers/characters

In creating an accounting report, the vendor names we get back from our credit card processor needed some major clean-up: “52334SOUTHWESTAIR1234”, “ABD2343-BLUE DINER 843”, and so on. I initially found a great function for this from Pinal Dave:

http://blog.sqlauthority.com/2007/05/13/sql-server-udf-function-to-parse-alphanumeric-characters-from-string/

But I wanted to make a few enhancements to it:

  1. He leaves numbers in the string and I’d like to remove them
  2. I’d like to combine multiple spaces in a row into a single space, but leave spaces intact

The first is pretty easy to do – just remove the [0-9] and add a space to the PATINDEX. The second one uses a trick from another post I did a few years ago.

Here’s the modified version:

CREATE FUNCTION dbo.UDF_ParseAlphaChars2
(
   @string VARCHAR(8000)
)
RETURNS VARCHAR(8000) WITH SCHEMABINDING
AS
BEGIN
   DECLARE @IncorrectCharLoc SMALLINT
   SET @IncorrectCharLoc = PATINDEX('%[^ A-Za-z]%', @string)

   WHILE @IncorrectCharLoc > 0
   BEGIN
      SET @string = STUFF(@string, @IncorrectCharLoc, 1, '')
      SET @IncorrectCharLoc = PATINDEX('%[^ A-Za-z]%', @string)
   END

   -- Trim groups of spaces into single space
   SET @string = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(@string,' ','<>'),'><',''),'<>',' ')))

   RETURN @string
END
GO

--Test
SELECT dbo.UDF_ParseAlphaChars2('ABC”_I+{D[]}4|:e;””5,<.F>/?6')
SELECT dbo.UDF_ParseAlphaChars2('52334SOUTHWESTAIR1234')
SELECT dbo.UDF_ParseAlphaChars2('ABD2343-BLUE DINER 843')
GO

Network not working after removing Symantec Endpoint Protection

About a year ago, I made the switch from Symantec Endpoint Protection 12 to Microsoft Forefront on a small network I manage, and the transition was mostly smooth. I noticed a few weeks ago, though, that one of my servers still had SEP installed, though it wasn’t running. I uninstalled SEP, thinking it would go smoothly, and on reboot, I lost connectivity to the server. No ping, no remote desktop – nothing.

On rolling over to the server and checking the desktop, the network connectivity was completely dead – I couldn’t ping the gateway or browse the internet at all. Using Device Manager to uninstall the network card and rebooting didn’t do any good, not did attempting to update drivers. However, in device manager, I could see a “Teefer2” entry for every one of my network connections, and it was set to disabled – this is the Symantec Network Threat Protection driver, and it monitors your network activity. Thinking this could be the problem, I attempted to right-click -> Uninstall each of these, but nothing happened – they didn’t uninstall.

Trying to update the drivers on the network card (which said a file was missing) always give me the same error message: “The system cannot find the file specified.” It would almost work, up until the very end of the driver wizard, and then that error.

I found an article about running a Symantec tool called “Cleanwipe” that’s supposed to remove traces of failed Symantec Endpoint installations. You need an open support ticket to get it from Symantec directly, but if you know the filename, you can Google it and get it from others (note: I don’t vouch for the results – you’re on your own).

Running that tool didn’t solve my problem, though it did delete a number of components that were left. Next, I went through and manually deleted the remnants, following these instructions:

http://www.symantec.com/business/support/index?page=content&id=TECH91038&locale=en_US

That removed everything except the Teefer2 entries in my networking list. After about a dozen random fix attempts from all over the internet and reboots in between, I stumbled on an Experts Exchange question where somebody had posted a solution:

http://www.experts-exchange.com/Hardware/Networking_Hardware/Q_23508822.html

For those without access, the fix is simple – delete a single registry value. It’s located under HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNetwork and is called “Config”. Don’t delete the Network key, and don’t just clear this value, delete the value entirely. Once you do, you’ll be allowed to delete your network cards and the Teefer2 entries from device manager – remove all the Teerfer2 entries and any network connections that were associated with them, and then reboot. Windows will detect your network cards and let you install drivers, except this time it will work.

About 7 hours of troubleshooting and a dozen reboots, and the fix was to delete a single registry value. The Cleanwipe and the manual removal of SEP might have been required as well, but hopefully this saves you some time.

Decrypting RSA with Java

In a recent Java project (a *small* departure from my normal VB.NET development), I was attempting to use RSA to decrypt a value stored in one of our databases, but was running into some trouble. When I used Java’s native RSA Cipher (available in Java 1.5+), I could decrypt the value without any issues, but when I switched to Bouncycastle, I would get gibberish. Since I was doing the decryption from inside an Oracle database, the only version of Java available was 1.4.2, which doesn’t have a default RSA provider, leaving Bouncycastle as the only option.

The decryption didn’t fail or throw an exception – it always succeeded – but the resulting decrypted byte array was completely different between the two providers. In Java’s native RSA, it was 32 bytes (as it should be), but in Bouncycastle, it was 128 bytes (the same length as the input, interestingly).

In the end, it turned out that Java’s default RSA implementation is “RSA/None/PKCS1Padding”, whereas BC’s is “RSA/None/NoPadding”. Changing BC’s version of the Cipher.getInstance line in my code to explicitly specify the new padding resolved my issue:

    RSADecrypter = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");

Here’s the original code (Line 10 is the one to switch out):

Cipher RSADecrypter;

// Here's the flag for choosing which provider to use
Boolean UseBouncyCastle = Boolean.TRUE;

// Choose between Java and BouncyCastle
if (UseBouncyCastle == Boolean.TRUE)
{
    Security.addProvider(new BouncyCastleProvider());
    RSADecrypter = Cipher.getInstance("RSA", "BC");
} else
{
    RSADecrypter = Cipher.getInstance("RSA");
}

// Initialize the Cipher using our the first key in the keystore
// This step works fine for both providers
RSADecrypter.init(Cipher.DECRYPT_MODE, keystore.getKey("1", PrivateKeyPassword.toCharArray()));

// Decrypt first 128 bytes of the array - here's the problem
// Java RSA gives 32 byte result, BouncyCastle gives 128 bytes of randomness
aegEncryptionKey = RSADecrypter.doFinal(binaryDataEncrypted,0,128);

More related reading:

How to check the java version
Bouncycastle’s default crypto
Java’s default crypto