Hello,
Today I'm going to share some experience about SSL rating, time, security, performance and why it is better to turn off the RC4 protocol.
Also I did find and would like to share two useful resources that you can use to check your SSL and Website overall performance:
- https://www.dotcom-tools.com/website-speed-test.aspx to analyze your website from different world locations
- https://www.ssllabs.com/ssltest/analyze.html to analyze your SSL certificate
Using that two tools I did find a few main issues: my IIS server were still using RC4 that is considered non-secure, my DNS resolving time was too long from some points of world and my SSL handshake time was not very fast.
DNS resolving time - is still an issue as it require non-server and non-application actions to be taken to resolve it :(
SSL handshake is not so easy to resolve as well but what I have noticed is that resolving RC4 did speedup overall website loading performance and increase overall security rating.
So first step I would suggest is disabling the RC4 protocol. Lets take a look how to disable it on Windows Server with IIS:
- Open the RegEdit (Win + R >> regedit) and find the following key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Ciphers
- Right-click on Ciphers >> New >> Key and name it RC4 40/128

- Right-click on RC4 40/128 >> New >> DWORD (32-bit) Value and name the value Enabled

- Double-click the created Enabled value and make sure that there is zero (0) in Value Data field then click OK

- Repeat those steps and create two more keys with the names RC4 56/128 and RC4 128/128 in the Ciphers directory

- Close the RegEdit
In my case it was not required to reboot my server so I hope you will see the result immediately as well using the ssllabs web-tool I mentioned before.
This will give your A Rating for your SSL website security and as I noticed it speed up your website overall loading time (including SSL time) by 1.2-1.5 times.

Hope that will help you as well and let me know if you can add some useful info in comments.
Thank you and see you :)

1vqHSTrq1GEoEF7QsL8dhmJfRMDVxhv2y
There are so many times you need to get a place where your frozen process stuck aren't?
Especially if this is a production server or remote environment. So what to do?
I have faced this problem myself and created a small tool that gets stack trace from process by its name.
We will need the following instruments:
- Microsoft.Diagnostics.Runtime.dll
- System.Management.dll
And some code to find a process and get its stack trace.
private string CatchStacktrace(string domainName)
{
int pid = -1;
var procs = System.Diagnostics.Process.GetProcessesByName("w3wp");
var proc = procs.FirstOrDefault(p => GetProcessOwner(p.Id).StartsWith(domainName));
if (proc == null)
return string.Format("User Name not found: {0}", domainName);
pid = proc.Id;
if (pid < 1)
return string.Format("Process w3wp.exe not found: {0}", domainName);
StringBuilder sb = new StringBuilder();
sb.AppendLine(domainName);
sb.AppendLine(string.Empty);
using (var tdata = DataTarget.AttachToProcess(pid, 3000))
{
// Dump CLR info
var clrVersion = tdata.ClrVersions.First();
var dacInfo = clrVersion.DacInfo;
sb.AppendLine("# CLR Info");
sb.AppendLine(string.Format("Version: {0}", clrVersion.Version));
sb.AppendLine(string.Format("Filesize: {0:X}", dacInfo.FileSize));
sb.AppendLine(string.Format("Timestamp: {0:X}", dacInfo.TimeStamp));
sb.AppendLine(string.Format("Dac file: {0}", dacInfo.FileName));
sb.AppendLine(string.Empty);
var runtime = clrVersion.CreateRuntime();
var appDomain = runtime.AppDomains.First();
sb.AppendLine(string.Format("# Runtime Info"));
sb.AppendLine(string.Format("AppDomain: {0}", appDomain.Name));
sb.AppendLine(string.Format("Address: {0}", appDomain.Address));
sb.AppendLine(string.Format("Configuration: {0}", appDomain.ConfigurationFile));
sb.AppendLine(string.Format("Directory: {0}", appDomain.ApplicationBase));
sb.AppendLine(string.Empty);
// Dump thread info
sb.AppendLine("## Threads");
sb.AppendLine(string.Format("Thread count: {0}", runtime.Threads.Count));
sb.AppendLine(string.Empty);
foreach (var thread in runtime.Threads)
{
sb.AppendLine(string.Format("### Thread {0}", thread.OSThreadId));
sb.AppendLine(string.Format("Thread type: {0}",
thread.IsBackground ? "Background"
: thread.IsGC ? "GC"
: "Foreground"));
var blocks = thread.BlockingObjects;
if (blocks != null)
{
foreach(var block in blocks)
{
sb.AppendLine(string.Format("Blocked by: {0} reason: {1}", block.ToString(), block.Reason.ToString()));
}
}
sb.AppendLine(string.Empty);
sb.AppendLine("Stack trace:");
foreach (var stackFrame in thread.EnumerateStackTrace())
{
sb.AppendLine(string.Format("* {0}", stackFrame.DisplayString));
}
sb.AppendLine(string.Empty);
sb.AppendLine(string.Empty);
}
}
return sb.ToString();
}
string[] argList = new string[] { string.Empty, string.Empty };
ManagementObjectCollection processList = null;
ManagementObjectSearcher searcher = null;
string query = "Select * From Win32_Process Where ProcessID = ";
public string GetProcessOwner(int processId)
{
searcher = new ManagementObjectSearcher(query + processId);
processList = searcher.Get();
foreach (ManagementObject obj in processList)
{
argList[0] = string.Empty;
argList[1] = string.Empty;
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
if (returnVal == 0)
{
return argList[0];
}
}
return "NO OWNER";
}
As you know asp.net applications all have w3wp process name and run under its own user name usually with the same name as website name. So to find w3wp process we will pass its username like "ok.unsode.com" to the CatchStacktrace method.
If appropriate w3wp process has been found then you will get something like that: