Monday, February 20, 2017

ADFS and SNI

SNI, or Server Name Indicator, is an extension to TLS (Transport Layer Security, the evolutionary child of SSL/Secure Socket Layer) that permits multiple certificates (and therefore encrypted sessions) to be bound to the same TCP port.

Starting with ADFS v3.0 (aka ADFS for Windows Server 2012R2), Microsoft uses SNI by default. On the whole, this has little impact on most users of ADFS, but for one small, important subset: users that sit behind reverse proxy or hardware SSL-offload devices.

Readers of this blog know that I use the Citrix NetScaler VPX Express as a reverse proxy for my home lab; until I tried to stand up an ADFS server (running Server 2016) behind it—I'm going to start digging into Office 365 in a serious way and want the most seamless user experience—I'd never had a problem with it.

I just could NOT figure out why the ADFS system was immediately rejecting connections via NetScaler, while it was perfectly happy with local connections.

I knew things were problematic as soon as I did packet captures on the NetScaler: the [SYN]-[SYN, ACK]-[Client Hello] were immediately followed by [RST, ACK] and a dropped connection.


Once I "fired up" a copy of Wireshark and pulled some captures at the ADFS host, however, I was able to compare the difference between the NetScaler-proxied connections that were failing, and on-prem connections that were successful.



At that point, I could explicitly compare the two different [Client Hello] packets and see if I could tell the difference between the two...

Unfortunately, I started with comparing the protocols, ciphers and hash algorithms. It took a while to get the TLS1.2 setup just right to mimic the local connection, but no joy. But then I went after the extensions: only one extension was in the "misbehaving" [Client Hello]
There are a bunch of extensions in the "working" [Client Hello]:
holy crap

To make my task easier, I switched back to google-fu to see if I could narrow down the search; voila!

I found an article that talked about handling ADFS clients that don't support the SNI extension, and the lightbulb went on: my browsers do SNI, but with the NetScaler acting as a proxy SNI support is disabled by default.

Luckily there are two fixes:
  1. Update the ADFS server with a "blanket" or "fallback" binding for the ADFS service (see https://blogs.technet.microsoft.com/applicationproxyblog/2014/06/19/how-to-support-non-sni-capable-clients-with-web-application-proxy-and-ad-fs-2012-r2/)
  2. Update the NetScaler service entry (in the SSL Parameters section) to support SNI for the expected client hostname.
I went with the latter; that way I don't modify any more of the ADFS host than necessary, and because the NetScaler is essentially acting as a client while it's doing its proxy duties, that seemed to make the most sense.

Within a minute of adding the SNI extension, the ADFS system worked as expected.

Wednesday, February 15, 2017

SSL Reverse Proxy using Citrix NetScaler VPX Express

Part 6 in a series

In previous posts I covered the configuration of the NetScaler VPX Express for use as an intelligent reverse proxy, allowing the use of a single public IP address with multiple interior hosts.

In recent days, I've been working on adding Horizon View to my home lab; in addition to requisite Connection Servers, I'm using the EUC Access Point virtual appliance as a security gateway instead of Security Servers paired with dedicated Connection Servers.

The procedure I outline for the creation of a content-switching configuration works as you'd expect...to a point.

I found that I kept getting "Tunnel reconnection is not permitted" errors when trying to login using the dedicated Horizon Client; this was extremely frustrating because HTML access (using nothing but an HTML5-compatible browser) was working flawlessly.

Upon reviewing the client logs, I noticed that the response from the tunnel connection (HTTP/1.1 404 Not Found) was from IIS, not a Linux or other non-Windows webserver. In my configuration, my content-switching plan uses a Windows IIS server as the fall-through (default/no-match).

Theory: for whatever reason, while the registration process for the Horizon Client was being properly switched to the Access Point, login via tunnel was not.

By capturing a trace (including SSL decoding) at the NetScaler and reviewing it in Wireshark, I was able to see that the client is using two different host strings, one during the initial login followed by a second one during tunnel creation.

What's the difference? The initial login doesn't include the port number in the host string; the tunnel request includes it...
Login: vdi.corp.com
Tunnel: vdi.corp.com:433
The fix is to add an additional match criteria for your content switching policy:
Before: HTTP.REQ.HOSTNAME.EQ("vdi.corp.com")
After: HTTP.REQ.HOSTNAME.EQ("vdi.corp.com")||HTTP.REQ.HOSTNAME.EQ("vdi.corp.com:443")
You can also create an additional policy with the "fqdn:443" match, but editing the policy was faster to implement.

UPDATE: I've done some more digging, and there are additional arguments/functions that would also work—and would've worked transparently had I used them in the first place—instead of the EQ("") expression:
HTTP.REQ.HOSTNAME.CONTAINS("vdi.corp.com")
HTTP.REQ.HOSTNAME.SERVER=="vdi.corp.com"
HTTP.REQ.HOSTNAME.STARTSWITH("vdi.corp.com")
HTTP.REQ.HOSTNAME.PREFIX('.',0).EQ("vdi")

Friday, December 23, 2016

Apple Watch First Impressions

 ...from a former Pebble user


When Pebble announced their acquisition by FitBit, I was cautious about the future of the product: I backed the original Pebble on Kickstarter, as well as the Pebble Steel, Time Steel and finally, Time 2 when the opportunities presented themselves. But then recent things like having a total reset screwing up all my settings (and needing to do a factory reset to get things back) and a limited lifetime (and no more warranty support) for the existing units, I decided to look elsewhere for a good smartwatch.

As a longtime iPhone/iPad user I'd looked at the specs for Apple Watch when it was first released, and between the significant cost difference from the Pebble (like 4x more expensive, depending on the edition and band choices) and significant hardware limitations (Single-day battery life? Really? Not water resistant?), the sale of Pebble was making my smartwatch options pretty bleak.

However, the recently released Series 2 from Apple addressed 2 of the 3 biggest faults I had with the platform (nothing is going to address the cost problem: this is Apple we're talking about, and all of its options are boutique-priced) by adding significant strides to battery life along with 50M water resistance.

So I pulled the trigger and yesterday was able to take delivery of a 42mm Stainless Steel with Milanese Loop band in Space Black.
42mm Apple Watch Series 2 in Space Black
with Milanese Loop band
If you're interested in an un-boxing, you can search elsewhere. Suffice it to say that, in typical Apple fashion, the watch was simultaneously beautifully and over-packaged; a fair expectation for an $800 timepiece, whether it comes from Apple or not, but the amount of material waste from the packaging hails back to when Apple thought they were competing in the luxury timepiece market rather than the fitness wearables market. They really, really could've gone with less.

I started by placing the watch on the charging disc for a few hours to make sure it was well charged, then I went through the pairing process. Unlike Pebble, the Watch doesn't use two different Bluetooth profiles (one standard and one low-energy), and pairing with my iPhone 6s running iOS 10.2 was smooth and less error-prone compared to my usual experience with Pebble pairing. If there's one thing to be said for getting the two devices from the same manufacturer, it's the effortless user experience with pairing.

Before purchasing, I visited a local Apple store to get a feel for my choices in cases and bands. I selected the 42mm over the 38mm because of the larger display and my old eyes. The stainless steel case is a heftier feel over aluminium (or ceramic), which I definitely prefer, and there was a noticeable difference between the 38mm and 42mm as well, solidifying my choice of that size. Lighter watches tend to slide around to the underside of my wrist, while heavier ones seem to stay in place on the top. And if I have to deal at all with the watch on the underside of my wrist, the sapphire crystal of the stainless steel & ceramic cases was a must. I also prefer the heavier link band, but between the $500 premium and its "butterfly clasp" (which I hate), there was no way I was going with the Apple link band. The Milanese felt "weighty" enough in comparison to the link band, and its "infinite adjustability" had some appeal as well.

Once I had the watch paired and on my wrist, I started digging into the features I'd come accustomed to on the Pebble. Probably the biggest surprise was the dearth of watch face choices: unlike the Pebble ecosystem, with thousands of watch faces to choose from—everything from utilitarian designs to homages to Star Trek to the silly "Drunk O'Clock" face—the handful of faces available in the Watch ecosystem was a big surprise.

Worse, while all the Watch faces are customizable to some degree, all of them have the limitation of disallowing the customization of "time" itself. The face I'm most accustomed to on the Pebble—YWeather by David Rincon—is nearly reproducible on the Watch using the "Modular" face, but the options—or "Complications" as Apple terms them—aren't very flexible and make "time" a less-prominent feature in the face. Which, in my opinion, sort of defeats the purpose in a watch face.
Apple Watch
"Modular"
Pebble
"YWeather"

If I could just move the Time to the center section and make it more prominent, while moving the date to the upper-right, it'd be good enough...

Notifications are also very different on the Apple Watch; the most significant seems to be the suppression of all notifications when the phone is actively being used, which I'm extremely unhappy with. Among other things, it means that I'm not getting notifications when I've got the phone plugged into power and showing a route in Waze. Even when the phone is locked & screen is off, I'm finding that notifications I usually received on the Pebble are missing/silent on the watch: I've yet to get a notification from Slack, which is one of the busiest apps on my phone after Mail itself.
Yes, I've made sure that things like "cover to mute" is disabled and "mirror phone" is set for pretty much all of the integrations on the watch, but the only type of notification that I get seems to be Messages and Calendar.

Application integration is nice for many apps I have on the phone; being able to quickly raise/lower the garage door using GarageIO on the watch instead of the phone is nice, as is checking the home alarm. However, it does seem that some watch app integrations require the phone-based app to be running (or at least "backgrounded") in order for the watch component to function. It's not consistent, so I'm still trying to figure out which ones need to be running in order to work.

The blob of apps in the App Layout sucks, however. While I have the ability to move apps around to change their proximity to the "central" Clock app, the fact that there are so many that I'd just as soon never see—even after telling Watch to uninstall the integration—is mind-boggling when you consider the minimalist design elements used everywhere else in all Apple products.

At any rate, I'm still getting used to this thing, but from my perspective, I like parts of it, but other parts are still inferior to Pebble