{"id":6912,"date":"2014-08-17T16:15:46","date_gmt":"2014-08-17T14:15:46","guid":{"rendered":"https:\/\/ingmarverheij.com\/?p=6912"},"modified":"2014-08-17T16:19:04","modified_gmt":"2014-08-17T14:19:04","slug":"one-content-switch-to-rule-them-all","status":"publish","type":"post","link":"https:\/\/ingmarverheij.com\/en\/one-content-switch-to-rule-them-all\/","title":{"rendered":"One Content Switch to rule them all!"},"content":{"rendered":"<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/Overview.png\"><img loading=\"lazy\" decoding=\"async\" title=\"\" style=\"border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 10px; display: inline; padding-right: 0px; border-top-width: 0px\" border=\"0\" alt=\"One content switch to rule them all\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/Overview_thumb.png\" width=\"220\" align=\"right\" height=\"314\" \/><\/a>The <a href=\"https:\/\/support.citrix.com\/proddocs\/topic\/netscaler-traffic-management-10-5-map\/ns-cs-wrapper-con-10.html\" target=\"_blank\">Content Switch<\/a> (CSW) is a beautiful feature that enables you to use a single point of entry \u2013 your <a href=\"https:\/\/support.citrix.com\/proddocs\/topic\/netscaler\/ns-gen-netscaler-wrapper-con.html\" target=\"_blank\">NetScaler<\/a> &#8211; to host multiple services (like XenDesktop, XenMobile and Sharefile). Based on the content (and context) requested the CSW will direct the traffic to the server offering the best service suitable for the task. <\/p>\n<p>Since I visit sites that restrict outgoing traffic to known ports (sometimes only port 80 and 443), and only have a single IP in my home lab, I needed a solution that allows me to demo several Citrix products using the same entry point. In this article I\u2019ll show you how you can use the CSW to host several Citrix products (XenDesktop, XenMobile and ShareFile) using a single IP and port. <\/p>\n<blockquote>\n<p><strong>Disclaimer<\/strong>: Parts in this setup are not supported and therefore shouldn\u2019t be used in production environments! <\/p>\n<\/blockquote>\n<p><!--more--><\/p>\n<h1>Services<\/h1>\n<p>Since I travel to customer sites to demo Citrix products I\u2019d like to access my lab environment in a secure manner. In my lab environment I host several Citrix products I\u2019d like to demo as part of the Mobile Workspace<\/p>\n<ul>\n<li>Citrix ShareFile <\/li>\n<li>Citrix XenDesktop \/ XenApp <\/li>\n<li>Citrix XenMobile <\/li>\n<\/ul>\n<p>Besides access to the services itself I\u2019d like to have secure access to a variety of web-based management consoles, for instance:<\/p>\n<ul>\n<li>AppController <\/li>\n<li>NetScaler Management console (NSIP) <\/li>\n<li>XenMobile Device Manager <\/li>\n<li>etc. <\/li>\n<\/ul>\n<p>&#160;<\/p>\n<h1>Content Switch<\/h1>\n<p>As a point of entry into the NetScaler I use a CSW for each type of traffic where I have multiple services. That means I have a CSW for https:80 (<strong>csw_http<\/strong>)&#160; and ssl:443 (<strong>csw_ssl)<\/strong> which will direct traffic to the corresponding service based on the <u>hostname<\/u> in the request.<\/p>\n<p>In order to access the various services a number of FQDN\u2019s are needed:<\/p>\n<p><u>Citrix solutions<\/u><\/p>\n<ul>\n<li>enroll.domain.com \u2013 Citrix XenMobile Device Management <\/li>\n<li>sharefile.domain.com \u2013 Citrix ShareFile StorageZone <\/li>\n<li>lab.domain.com \u2013 NetScaler Gateway (Citrix XenDesktop) <\/li>\n<\/ul>\n<p><u><\/u>&#160;<u>Servers (management consoles)<\/u><\/p>\n<ul>\n<li>netscaler.domain.com <\/li>\n<li>appcontroller.domain.com <\/li>\n<li>etc. <\/li>\n<\/ul>\n<p>&#160;<\/p>\n<p>A policy is created for each hostname + CSW combination (you can\u2019t bind the same policy to two CSW\u2019s). Each policy has an expression similar like this: <\/p>\n<pre>HTTP.REQ.HOSTNAME.CONTAINS(&quot;enroll.domain.com&quot;)<\/pre>\n<p>The only exception is ShareFile where we differentiate between data and connector (see the CSW policy<em><strong>&#160;<\/strong>cs_pol_ssl_sf_data<\/em> and<strong> <\/strong><em>cs_pol_ssl_sf_data<\/em> in the images below). traffic as explained in <a href=\"https:\/\/support.citrix.com\/article\/CTX139132\" target=\"_blank\">CTX139132<\/a>&#160;<\/p>\n<p>&#160;<\/p>\n<p>Since the CSW decrypts the SSL packet there are some takeaways you should consider:<\/p>\n<ol>\n<li>Content Switches don\u2019t understand ICA traffic. As a result you can\u2019t content switch \u201cICA proxy\u201d traffic, the CSW will simply choke when evaluating the policy. This can be mitigated by assigning the NSGW to the Default Load Balancing Virtual Server <\/li>\n<li>Citrix XenMobile Device Manager (XMDM) uses client certificates to authenticate mobile devices. As a result you need to enable client authentication (optional), apply an SSL policy (SSL-policy-XenMobile) and assign the CA certificates (basically the same as when you <a href=\"https:\/\/blogs.citrix.com\/2013\/12\/13\/xenmobile-configure-ns-ssl-offload-for-device-manager\/\" target=\"_blank\">SSL offload the XMDM<\/a>) <\/li>\n<li>When the next hop is a SSL virtual server the NetScaler needs to decrypt and encrypt again, increasing the required resources. If traffic is considered \u201csafe\u201d in your DMZ you might want to consider continuing in HTTP <\/li>\n<\/ol>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/csw_http.png\"><img loading=\"lazy\" decoding=\"async\" title=\"csw_http\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px\" border=\"0\" alt=\"csw_http\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/csw_http_thumb.png\" width=\"245\" height=\"322\" \/><\/a><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/csw_ssl.png\"><img loading=\"lazy\" decoding=\"async\" title=\"csw_ssl\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px\" border=\"0\" alt=\"csw_ssl\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/csw_ssl_thumb.png\" width=\"265\" height=\"322\" \/><\/a><\/p>\n<pre>#--- Content Switch: csw_http ---\n   #Create csw\n   add cs vserver csw_http HTTP 123.123.123.123 80 -cltTimeout 180\n\n   #Add and bind policies\n   add cs policy cs_pol_http_lab -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;lab.domain.com\\&quot;)&quot;\n   bind cs vserver csw_http -policyName cs_pol_http_lab -targetLBVserver lbsv-Redirect_to_https-lab.domain.com -priority 100\n   add cs policy cs_pol_http_xm_enroll -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;enroll.domain.com\\&quot;)&quot;\n   bind cs vserver csw_http -policyName cs_pol_http_xm_enroll -targetLBVserver lbvs-XenMobile-http -priority 110\n# -------------------------------\n\n# --- Content Switch: csw_ssl ---\n   #Create csw\n   add cs vserver csw_ssl SSL 123.123.123.123 443 -cltTimeout 180\n\n   #Add and bind policies\n   add cs policy cs_pol_ssl_lab -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;lab.domain.com\\&quot;)&quot;\n   bind cs vserver csw_ssl -policyName cs_pol_ssl_lab -targetLBVserver lbvs-SSLVPN-http -priority 130\n   add cs policy cs_pol_ssl_sf_data -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;sharefile.domain.com\\&quot;) &amp;&amp; HTTP.REQ.URL.CONTAINS(\\&quot;\/cifs\/\\&quot;).NOT &amp;&amp; HTTP.REQ.URL.CONTAINS(\\&quot;\/sp\/\\&quot;).NOT&quot;\n   bind cs vserver csw_ssl -policyName cs_pol_ssl_sf_data -targetLBVserver lbvs-ShareFile_szc-Data -priority 110\n   add cs policy cs_pol_ssl_sf_connectors -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;sharefile.domain.com\\&quot;) &amp;&amp; (HTTP.REQ.URL.CONTAINS(\\&quot;\/cifs\/\\&quot;) || HTTP.REQ.URL.CONTAINS(\\&quot;\/sp\/\\&quot;)) &quot;\n   bind cs vserver csw_ssl -policyName cs_pol_ssl_sf_connectors -targetLBVserver lbvs-ShareFile_szc-Connector -priority 100\n   add cs policy cs_pol_ssl_xm_enroll -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;enroll.domain.com\\&quot;)&quot;\n   bind cs vserver csw_ssl -policyName cs_pol_ssl_xm_enroll -targetLBVserver lbvs-XenMobile-http -priority 120\n   add cs policy cs_pol_ssl_netscaler -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;netscaler.domain.com\\&quot;)&quot;\n   bind cs vserver csw_ssl -policyName cs_pol_ssl_netscaler -targetLBVserver lbvs-localhost-HTTP -priority 140\n   add cs policy cs_pol_ssl_appcontroller -rule &quot;HTTP.REQ.HOSTNAME.CONTAINS(\\&quot;appcontroller.domain.com\\&quot;)&quot;\n   bind cs vserver csw_ssl -policyName cs_pol_ssl_appcontroller -targetLBVserver lbvs-appcontroller-4443 -priority 150\n\n   #Default Load Balancing Virtual Server \n   bind cs vserver csw_ssl -lbvserver lbvs-SSLVPN-http   \n\n   #Certificates\n   bind ssl vserver csw_ssl -certkeyName wilcard_domain_com\n   bind ssl vserver csw_ssl -certkeyName MDM001_Root-CA -CA -ocspCheck Optional\n   bind ssl vserver csw_ssl -certkeyName MDM001_Device-CA -CA -ocspCheck Optional\n\n   #SSL Parameters\n   set ssl vserver csw_ssl -eRSA DISABLED -clientAuth ENABLED -clientCert Optional -tls11 DISABLED -tls12 DISABLED\n\n   #SSL Policy\n   bind ssl vserver csw_ssl -policyName SSL-policy-XenMobile -priority 100\n# -------------------------------\n\n# --- SSL policy: SSL-policy-XenMobile ---\n   add ssl action SSL-Action-XenMobile -clientCert ENABLED -certHeader NSClientCert\n   add ssl policy SSL-policy-XenMobile -rule CLIENT.SSL.CLIENT_CERT.EXISTS -action SSL-Action-XenMobile\n# ----------------------------------------<\/pre>\n<p>&#160;<\/p>\n<h1>Load Balancing<\/h1>\n<p>A CSW always directs traffic to a Load Balancing (LB) Virtual Server. This means you should always create a LB Virtual Server for each service you\u2019d like to offer. For most services this is a normal procedure (for instance for ShareFile and XenMobile) but for other services this requires some tricks. <\/p>\n<h3>NetScaler Gateway<\/h3>\n<blockquote>\n<p><strong>Reminder<\/strong>: This is not supported. Don\u2019t try to get support as it\u2019s unsupported <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-winkingsmile\" style=\"border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none\" alt=\"Winking smile\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/wlEmoticon-winkingsmile.png\" \/><\/p>\n<\/blockquote>\n<p>A NetScaler Gateway (NSGW) is a Virtual Server which has a virtual IP (VIP) assigned. As a result you can\u2019t \u201cjust\u201d load balance NSGW virtual servers. If you\u2019ll try to create a LB Virtual Service for the NSGW the NetScaller will throw an \u201cAddress already in use\u201d error. <\/p>\n<p>No worries, there\u2019s a trick to achieve this. Basically we\u2019re gonna fool the NetScaler by making him think he\u2019s load balancing a generic TCP service.&#160; We can achieve this by sending the CSW to an SSL LB Virtual Server (lbvs-SSLVPN-http) which in its turn is sending all traffic to a TCP LB Virtual Server (lbvs-SSLVPN-tcp) which sends its traffic to the NSGW. Sounds complicated, but the picture below makes it easier to understand.<\/p>\n<p>As I said earlier this is not rather efficient, the NetScaler has to process SSL two times. First the content switch (csw_ssl) and then the NSGW (_XD_cag).<\/p>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/lbvs-SSLVPN-http.png\"><img loading=\"lazy\" decoding=\"async\" title=\"lbvs-SSLVPN-http\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto\" border=\"0\" alt=\"lbvs-SSLVPN-http\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/lbvs-SSLVPN-http_thumb.png\" width=\"470\" height=\"352\" \/><\/a><\/p>\n<pre>#--- Load Balancing vServer: lbvs-SSLVPN-http ---\n   #Create LBVS\n   add lb vserver lbvs-SSLVPN-http HTTP 0.0.0.0 0 -persistenceType SOURCEIP -cltTimeout 180\n\n   #Create Server\n   add server 172.16.0.252 172.16.0.252\n\n   #Create Service\n   add service 172.16.0.252-ssl 172.16.0.252 SSL 443 -gslb NONE -maxClient 0 -maxReq 0 -cip DISABLED -usip NO -useproxyport YES -sp ON -cltTimeout 180 -svrTimeout 360 -CKA NO -TCPB NO -CMP YES\n   set ssl service 172.16.0.252-ssl -tls11 DISABLED -tls12 DISABLED\n\n   #Bind service to LBVS\n   bind lb vserver lbvs-SSLVPN-http 172.16.0.252-ssl\n#------------------------------------------------\n\n#--- Load Balancing vServer: lbvs-SSLVPN-tcp ---\n   #Create LBVS\n   add lb vserver lbvs-SSLVPN-tcp TCP 172.16.0.252 * -persistenceType SOURCEIP -cltTimeout 9000\n\n   #Create Server\n   add server _XD_cag 10.0.1.252\n\n   #Create Service\n   add service &quot;_XD_cag- tcp&quot; _XD_cag TCP * -gslb NONE -maxClient 0 -maxReq 0 -cip DISABLED -usip NO -useproxyport YES -sp ON -cltTimeout 9000 -svrTimeout 9000 -CKA NO -TCPB NO -CMP NO\n\n   #Bind service to LBVS\n   bind lb vserver lbvs-SSLVPN-tcp &quot;_XD_cag- tcp&quot;\n#-----------------------------------------------<\/pre>\n<p>PS: The IP 10.0.1.252 is the virtual IP (VIP) of the NSGW and the IP 172.16.0.252 is simply a staging IP. <\/p>\n<p>PS: Technically you could create a NSGW via HTTP (see <a href=\"https:\/\/support.citrix.com\/article\/CTX120639\" target=\"_blank\">CTX120639<\/a>) \u2013 to avoid the second SSL \u2013 but then the load balancing \u201ctrick\u201d won\u2019t work. Let me know in the comments if you fixed that <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-winkingsmile\" style=\"border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none\" alt=\"Winking smile\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/wlEmoticon-winkingsmile.png\" \/><\/p>\n<p>&#160;<\/p>\n<h3>NetScaler Management Console<\/h3>\n<p>If you want to access the NetScaler Management Console via the same CSW VIP you need to access the NSIP (NetScaler IP) via a LB Virtual Server. Just like the NSGW this requires a trick. When you add the NSIP as a LB Server the NetScaler will throw an \u201cOperation not permitted\u201d error. This time the trick is easier, just add a LB Server with domain name <\/p>\n<pre>localhost<\/pre>\n<p>Now all you have to do is create LB service and a LB server (non addressable) and you can use the CSW to direct traffic to the NSIP.<\/p>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/lbvs-localhost-http.png\"><img loading=\"lazy\" decoding=\"async\" title=\"lbvs-localhost-http\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto\" border=\"0\" alt=\"lbvs-localhost-http\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/lbvs-localhost-http_thumb.png\" width=\"470\" height=\"138\" \/><\/a><\/p>\n<pre>#--- Load Balancing vServer: lbvs-localhost ---\n   #Create LBVS\n   add lb vserver lbvs-localhost-HTTP HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 180\n\n   #Create Server\n   add server localhost 127.0.0.1\n\n   #Create Service\n   add service &quot;localhost - http&quot; localhost HTTP 80 -gslb NONE -maxClient 0 -maxReq 0 -cip ENABLED cip-header -usip YES -useproxyport NO -sp OFF -cltTimeout 180 -svrTimeout 360 -CKA NO -TCPB NO -CMP NO\n\n   #Bind service to LBVS\n   bind lb vserver lbvs-localhost-HTTP &quot;localhost - http&quot;\n#------------------------------------------------<\/pre>\n<h1>&#160;<\/h1>\n<h1>Overview \/ diagram<\/h1>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/Diagram.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Diagram\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto\" border=\"0\" alt=\"Diagram\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/08\/Diagram_thumb.png\" width=\"620\" height=\"475\" \/><\/a><\/p>\n<p>&#160;<\/p>\n<h1>Remarks<\/h1>\n<ul>\n<li>You need a wildcard SSL certificate (*.domain.com) or a Subject Alternative Name (SAN) certificate linked to the SSL CSW virtual server <\/li>\n<li>You could use regular SSL certificates for the SSL LB Virtual Servers&#160; (lbvs-appcontroler-4443, lbvs-SSLVPN-ssl and lbvs-XenMobile-8443) and the NSGW (_XD_cag) but a wildcard SSL might be just as easy. <\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>The Content Switch (CSW) is a beautiful feature that enables you to use a single point of entry \u2013 your NetScaler &#8211; to host multiple services (like XenDesktop, XenMobile and Sharefile). Based on the content (and context) requested the CSW will direct the traffic to the server offering the best service suitable for the task. [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[502],"tags":[659,639,660,89],"class_list":["post-6912","post","type-post","status-publish","format-standard","hentry","category-netscaler","tag-content-switch","tag-load-balancing","tag-netscaler-gateway","tag-ssl"],"_links":{"self":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/6912","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/comments?post=6912"}],"version-history":[{"count":1,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/6912\/revisions"}],"predecessor-version":[{"id":6913,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/6912\/revisions\/6913"}],"wp:attachment":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/media?parent=6912"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/categories?post=6912"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/tags?post=6912"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}