October 29, 2019

Citrix ADC Virtual Server Hardening - The Right Way



Regardless of which role we serve in an organization, security should always be top of mind. This is especially critical today as we consistently hear how companies have been compromised leading to leaked data which cost them millions of dollars. Since the Citrix ADC presents traffic to the internet everyone should know how to secure what is presented. I am often working with folks that are accidentally presenting unsecured URLs to the internet. The common URLs are HTTP based sites and those sites are unsecured by design. The SSL based URLs are the one we care about more as the typical reason why we secure sites is that there is some sort of personal information is presented or passed on these sites. This blog post is not to discuss the Citrix Web App Firewall that exists on ADC appliances as that feature can fill multiple blog posts on how to configure and secure sites. In this blog post, we are more concerned with the easy wins that we can configure to provide more security on the ADC appliances.


To set the stage here, all of these items only work if the protocol on a virtual server on the ADC is set to SSL. This means that SSL traffic is terminated at the ADC virtual server and decrypted/re-encrypted before being sent to the backend. Therefore, other protocols such as SSL Bridge would not work as the Citrix ADC only passes the traffic through to the backend server which will handle the SSL requests. This type of hardening works for all editions of Citrix ADC. The next level of hardening such as Citrix Web App Firewall is better and if your appliance is licensed for it most definitely use it, but not everyone has a Premium Edition Citrix ADC appliance.

Out of the box any SSL virtual server created on the ADC will score an A- on SSLLabs.com. An A- is a heck of a lot better than what the ADC used to present in older versions of firmware which was capped based on if the appliance was virtual or physical.

Configuration:

To bump the A- to an A+ there are a few things to add. The easy way to add them come in a form of an SSL Profile.

To create one of these we simply navigate to System – Profiles – SSL Profile
It is easier to take one of the out of box SSL Profiles and Click Add and adjust the settings to what we need it to be

It is suggested to name the profile to something that makes sense such as ns_default_ssl_profile_hsts_tls_1.2_only

Set Deny SSL Renegotiation to NONSECURE
Enable HTTP Strict Transport Security (HSTS), set the age to 15768000 and enable the protocols (TLS1.2 only)

Some folks like to set HTTP Strict Transport Security via a Rewrite Policy and it comes down to preference. If set here, we do not need to bind an additional Rewrite policy and bind it to our SSL Virtual Servers.

For those that like to use the Citrix ADC CLI the command is:
add ssl profile ns_default_ssl_profile_hsts_tls_1.2_only -sessReuse ENABLED -sessTimeout 120 -tls1 DISABLED -tls11 DISABLED -denySSLReneg NONSECURE -HSTS ENABLED -maxage 157680000

Now we need to create a custom SSL Cipher Group that has the strong ciphers arranged at the top

To create one of these we simply navigate to Traffic Management – SSL – Cipher Groups
Select the Default Cipher Group and Click Add
Name the Cipher Group the company name or the company initials

Arrange the 24 Ciphers in this order
TLS1.2-ECDHE-RSA-AES-256-SHA384
TLS1.2-ECDHE-RSA-AES-128-SHA256
TLS1.2-ECDHE-RSA-AES256-GCM-SHA384
TLS1.2-ECDHE-RSA-AES128-GCM-SHA256
TLS1-ECDHE-RSA-AES256-SHA
TLS1-ECDHE-RSA-AES128-SHA
TLS1-ECDHE-RSA-DES-CBC3-SHA
TLS1-AES-256-CBC-SHA
TLS1-AES-128-CBC-SHA
TLS1.2-AES-256-SHA256
TLS1.2-AES-128-SHA256
TLS1.2-AES256-GCM-SHA384
TLS1.2-AES128-GCM-SHA256
TLS1.2-DHE-RSA-AES-256-SHA256
TLS1.2-DHE-RSA-AES-128-SHA256
TLS1.2-DHE-RSA-AES256-GCM-SHA384
TLS1.2-DHE-RSA-AES128-GCM-SHA256
TLS1-DHE-RSA-AES-256-CBC-SHA
TLS1-DHE-RSA-AES-128-CBC-SHA
TLS1-DHE-DSS-AES-256-CBC-SHA
TLS1-DHE-DSS-AES-128-CBC-SHA
SSL3-EDH-RSA-DES-CBC3-SHA
SSL3-EDH-DSS-DES-CBC3-SHA
SSL3-DES-CBC3-SHA

For those that like to use the Citrix ADC CLI the commands are:
add ssl cipher COMPANY
bind ssl cipher COMPANY -cipherName TLS1.2-ECDHE-RSA-AES-256-SHA384 -cipherPriority 1
bind ssl cipher COMPANY -cipherName TLS1.2-ECDHE-RSA-AES-128-SHA256 -cipherPriority 2
bind ssl cipher COMPANY -cipherName TLS1.2-ECDHE-RSA-AES256-GCM-SHA384 -cipherPriority 3
bind ssl cipher COMPANY -cipherName TLS1.2-ECDHE-RSA-AES128-GCM-SHA256 -cipherPriority 4
bind ssl cipher COMPANY -cipherName TLS1-ECDHE-RSA-AES256-SHA -cipherPriority 5
bind ssl cipher COMPANY -cipherName TLS1-ECDHE-RSA-AES128-SHA -cipherPriority 6
bind ssl cipher COMPANY -cipherName TLS1-ECDHE-RSA-DES-CBC3-SHA -cipherPriority 7
bind ssl cipher COMPANY -cipherName TLS1-AES-256-CBC-SHA -cipherPriority 8
bind ssl cipher COMPANY -cipherName TLS1-AES-128-CBC-SHA -cipherPriority 9
bind ssl cipher COMPANY -cipherName TLS1.2-AES-256-SHA256 -cipherPriority 10
bind ssl cipher COMPANY -cipherName TLS1.2-AES-128-SHA256 -cipherPriority 11
bind ssl cipher COMPANY -cipherName TLS1.2-AES256-GCM-SHA384 -cipherPriority 12
bind ssl cipher COMPANY -cipherName TLS1.2-AES128-GCM-SHA256 -cipherPriority 13
bind ssl cipher COMPANY -cipherName TLS1.2-DHE-RSA-AES-256-SHA256 -cipherPriority 14
bind ssl cipher COMPANY -cipherName TLS1.2-DHE-RSA-AES-128-SHA256 -cipherPriority 15
bind ssl cipher COMPANY -cipherName TLS1.2-DHE-RSA-AES256-GCM-SHA384 -cipherPriority 16
bind ssl cipher COMPANY -cipherName TLS1.2-DHE-RSA-AES128-GCM-SHA256 -cipherPriority 17
bind ssl cipher COMPANY -cipherName TLS1-DHE-RSA-AES-256-CBC-SHA -cipherPriority 18
bind ssl cipher COMPANY -cipherName TLS1-DHE-RSA-AES-128-CBC-SHA -cipherPriority 19
bind ssl cipher COMPANY -cipherName TLS1-DHE-DSS-AES-256-CBC-SHA -cipherPriority 20
bind ssl cipher COMPANY -cipherName TLS1-DHE-DSS-AES-128-CBC-SHA -cipherPriority 21
bind ssl cipher COMPANY -cipherName SSL3-EDH-RSA-DES-CBC3-SHA -cipherPriority 22
bind ssl cipher COMPANY -cipherName SSL3-EDH-DSS-DES-CBC3-SHA -cipherPriority 23
bind ssl cipher COMPANY -cipherName SSL3-DES-CBC3-SHA -cipherPriority 24


That solves SSLLabs.com, a lesser known site SecurityHeaders.com should be put into consideration. This site examines HTTP based header responses that an SSL site presents. Examining SSL based headers is important because HTTP headers are used by client devices and website to share information as part of the HTTP protocol. When we enter a URL in the browser or click on any link, the web browser sends a HTTP request containing client headers while the HTTP response contains server headers. Common HTTP headers can expose things that we don't necessarily want to expose such as the Powered By or Server header that shows what type of platform that the site is hosted on making it susceptible to targeted attacks. Just imaging if someone knows that a site is hosted on IIS, it makes it easier to only focus IIS based attacks on a site as opposed to presenting no information to them. This is commonly overlooked as most are only concerned with SSLLabs.com.

Out of the box any SSL virtual server created on the ADC will score a D on SecurityHeaders.com. We may ask why is this score so low? The answer is until people focus more on this side of site security there will be nothing out of the box to address it.

How do we add/change the headers? We use the Rewrite feature on the ADC to generate Rewrite policies and actions that we bind to SSL based virtual servers.

If not already enabled enable Rewrite from AppExpert – Rewrite – Right Click Rewrite – Select Enable Feature
Before we can create Rewrite Policies, we need to create the Rewrite Actions that bind to them
Give the Rewrite Action an appropriate name such as REW_ACT-CONTENT_SECURITY_POLICY

Under Type Select INSERT_HTTP_HEADER

Under the Header Name type Content-Security-Policy
Under the Expression type "frame-ancestors 'self'"
Rewrite Actions are needed for the following:
REW_ACT-REFERRER_POLICY with the header name Referrer-Policy and expression "STRICT-ORIGIN"
REW_ACT-X_XSS_PROTECTION with the header name X-Xss-Protection and expression "1; mode=block"
REW_ACT-X_CONTENT_TYPE_OPTIONS with the header name X-Content-Type-Options and expression "nosniff"
REW_ACT-EXPECT_CT with the header name Expect-CT and expression "\"enforce,max-age=30\""
REW_ACT-FEATURE_POLICY with the header name Feature-Policy and expression "vibrate 'self'"
REW_ACT-DELETE_SERVER with the type DELETE_HTTP_HEADER and the header name Server
REW_ACT-DELETE_X-POWERED-BY with the type DELETE_HTTP_HEADER and the header name X-Powered-By
REW_ACT-SERVER with the header name Server and expression "CheeseBurgers"
REW_ACT-X-POWERED-BY with the header name X-Powered-By and expression "CheeseBurgers"

Note that the term CheeseBurgers can be changed to anything else. I typically use CheeseBurgers as an Easter Egg to see if people actually notice it.

When finished there should be 10 Rewrite Actions

Now we create the Rewrite Policies that correspond to the actions

Give the Rewrite Policy an appropriate name such as REW_POL-CONTENT_SECURITY_POLICY
Select the Corresponding Action, in this case it is  REW_ACT-CONTENT_SECURITY_POLICY
Leave everything else default and in the Expression type True
Rewrite Policies are needed for the following:
REW_POL-REFERRER_POLICY with action REW_ACT-REFERRER_POLICY and the expression True
REW_POL-X_XSS_PROTECTION with action REW_ACT- X_XSS_PROTECTION and the expression True
REW_POL-X_CONTENT_TYPE_OPTIONS with action REW_ACT- X_XSS_PROTECTION and the expression True
REW_POL-EXPECT_CT with action REW_ACT-EXPECT_CT and the expression True
REW_POL-FEATURE_POLICY with action REW_ACT- FEATURE_POLICY and the expression True
REW_POL-DELETE_SERVER with action REW_ACT- DELETE_SERVER and the expression True
REW_POL-DELETE_X-POWERED-BY with action REW_ACT- DELETE_X-POWERED-BY and the expression True
REW_POL-SERVER with action REW_ACT- SERVER and the expression True
REW_POL-X-POWERED-BY with action REW_ACT- X-POWERED-BY and the expression True

When finished there should be 10 Rewrite Policies

For those that like to use the Citrix ADC CLI the commands are:
add rewrite action REW_ACT-REFERRER_POLICY insert_http_header Referrer-Policy "\"STRICT-ORIGIN\""
add rewrite action REW_ACT-X_XSS_PROTECTION insert_http_header X-Xss-Protection "\"1; mode=block\""
add rewrite action REW_ACT-X_CONTENT_TYPE_OPTIONS insert_http_header X-Content-Type-Options "\"nosniff\""
add rewrite action REW_ACT-CONTENT_SECURITY_POLICY insert_http_header Content-Security-Policy "\"frame-ancestors \'self\'\""
add rewrite action REW_ACT-EXPECT_CT insert_http_header Expect-CT q/"\"enforce,max-age=30\""/
add rewrite action REW_ACT-FEATURE_POLICY insert_http_header Feature-Policy "\"vibrate \'self\'\""
add rewrite action REW_ACT-DELETE_SERVER delete_http_header Server
add rewrite action REW_ACT-DELETE_X-POWERED-BY delete_http_header X-Powered-By
add rewrite action REW_ACT-X-POWERED-BY insert_http_header X-Powered-By "\"CheeseBurgers\""
add rewrite action REW_ACT-SERVER insert_http_header Server "\"CheeseBurgers\""
add rewrite policy REW_POL-CONTENT_SECURITY_POLICY TRUE REW_ACT-CONTENT_SECURITY_POLICY
add rewrite policy REW_POL-X_CONTENT_TYPE_OPTIONS TRUE REW_ACT-X_CONTENT_TYPE_OPTIONS
add rewrite policy REW_POL-X_XSS_PROTECTION TRUE REW_ACT-X_XSS_PROTECTION
add rewrite policy REW_POL-REFERRER_POLICY TRUE REW_ACT-REFERRER_POLICY
add rewrite policy REW_POL-EXPECT_CT TRUE REW_ACT-EXPECTED_CT
add rewrite policy REW_POL-FEATURE_POLICY TRUE REW_ACT-FEATURE_POLICY
add rewrite policy REW_POL-DELETE_X-POWERED-BY TRUE REW_ACT-DELETE_X-POWERED-BY
add rewrite policy REW_POL-DELETE_SERVER TRUE REW_ACT-DELETE_SERVER
add rewrite policy REW_POL-X-POWERED-BY TRUE REW_ACT-X-POWERED-BY
add rewrite policy REW_POL-SERVER TRUE REW_ACT-SERVER

Now we need to bind out configuration to an SSL Virtual Server

Open an SSL Virtual Server and Add in the SSL Policies Section on the Right
Click the Dropdown and select the SSL Policy that was created Earlier
Under SSL Ciphers Click the Pencil
Click the – sign next to the DEFAULT Cipher Group and Click OK
Note, this is important as if the DEFAULT GROUP is not unbound there sometimes is the issue where both Cipher Groups are bound which results in not having an A+.

Click the Pencil again, Click the radio button to Cipher Groups and from the dropdown select the Cipher Group and Click OK

Under the Policies Section click the + sign
On the Choose Policy dropdown select Rewrite, on the Choose Type select Response and Click Continue
Click the Arrow to the right of Click to Select
Select a Policy, it does not matter the order and Click Select
The Priority does not matter as long as policies are not bound at the same priority. Make sure the Goto Expression is set to next with the exception of the last policy needing to be End.
When finished there should be 10 Rewrite Policies bound to the VIP
The URL should be ready to scan the URLs from both SSLLabs and SecurityHeaders.

Feel free to drop us a note if you have any questions.

Troubleshooting:

Not scoring an A+? Common reasons why:
  • The SSL Ciphers have the default cipher bound in addition to the custom ciphers
  • One of the Rewrite policies with the exception of the last one was bound with the Goto Expression as End as opposed to Next which stop the processing of the Rewrite policies after that policy. 
  • The Rewrite policies are bound to the SSL Virtual Server as Requests and not as Responses.
  • A minor typo or flipped " (quotes) in the HTTP header can cause SecuriytHeaders.com to flag the header as incorrect. Make sure the " (quotes) are correct if copying and pasting from this blog.