{"id":7283,"date":"2021-12-06T06:44:40","date_gmt":"2021-12-06T06:44:40","guid":{"rendered":"https:\/\/www.insentragroup.com\/au\/insights\/uncategorized\/conquering-per-user-firewall-rules-with-citrix-wem-privilege-elevation\/"},"modified":"2024-09-17T07:51:23","modified_gmt":"2024-09-17T07:51:23","slug":"conquering-per-user-firewall-rules-with-citrix-wem-privilege-elevation","status":"publish","type":"post","link":"https:\/\/www.insentragroup.com\/au\/insights\/geek-speak\/secure-workplace\/conquering-per-user-firewall-rules-with-citrix-wem-privilege-elevation\/","title":{"rendered":"Conquering Per User Firewall Rules with Citrix WEM Privilege Elevation"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1155\" height=\"208\" src=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/image-2.png\" alt=\"\" class=\"wp-image-7284\" title=\"\" srcset=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/image-2.png 1155w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/image-2-300x54.png 300w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/image-2-1024x184.png 1024w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/image-2-768x138.png 768w\" sizes=\"(max-width: 1155px) 100vw, 1155px\" \/><\/figure>\n\n\n\n<style>\n.elementor-widget-theme-post-featured-image {\n display: none !important;\n}\n<\/style>\n\n\n\n<p>I recently worked with a client who tested deployment of Microsoft Teams on Citrix without any form of optimisation. The optimisation packs were hindering user acceptance and not providing adequate stability. This blog is not about the why of Teams optimisation or not, rather the tactics used to tackle a side requirement \u2013 per user firewall rules on non-persistent desktops with no admin rights. A note of thanks to the team (you know who you are) &nbsp;who were patient enough to test these features and work through the challenges.<\/p>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>THE CHALLENGE<\/span><\/h3>\n\n\n\n<p class=\"has-link-color wp-elements-9f2d6b78689b64bac173f858acb8e63d\">The initial challenge presented itself after switching to the per user installation of Teams. When launching Teams, all appears fine, until you try to access devices, be it via making a call or by accessing settings -&gt; devices. This would prompt for the creation of a defender firewall rule as documented&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/microsoftteams\/get-clients#windows\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">here by Microsoft<\/a>. Telling the users to hit \u201ccancel\u201d and move on is not acceptable, particularly as this would happen repeatedly in a non-persistent environment.<\/p>\n\n\n\n<p class=\"has-link-color wp-elements-51880448fc4983da99dd5dd1807174eb\">Microsoft offer a fairly half-baked solution&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/microsoftteams\/get-clients#sample-powershell-script---inbound-firewall-rule\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">here<\/a>&nbsp;which is basically a PowerShell script to look at a list of user profiles in the system drive, and write the firewall rules based on its findings. Again, half-baked and not scalable in a non-persistent environment.<\/p>\n\n\n\n<p>Typically, with Firewall rules, we can centrally configure them with a GPO, however for some reason unbeknownst to me, Microsoft do not allow for wildcards or user-based variables in Firewall paths so \u201c<em><strong>C:usersJamesAppDataLocalMicrosoftTeamsCurrentTeams.exe<\/strong><\/em>\u201d suddenly becomes a bit of a challenge to manage.<\/p>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>THE REQUIREMENTS AND THE SOLUTION<\/span><\/h3>\n\n\n\n<p>What we needed, was a solution that could do several things:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create the firewall rule in the user context silently<\/li>\n\n\n\n<li>Not require users to have admin rights<\/li>\n\n\n\n<li>Handle a non-persistent environment<\/li>\n<\/ul>\n\n\n\n<p>What we used, was a combination of tools. Note, this is a Citrix Cloud environment referenced here, so the WEM Service was available for consumption.<\/p>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>CITRIX WEM SERVICE PRIVILEGE ELEVATION<\/span><\/h3>\n\n\n\n<p class=\"has-link-color wp-elements-9bf41db8afb49099f47bb012b2a874bf\">The Citrix Workspace Environment Management (WEM) Service offers part of the solution in the form of\u00a0<a href=\"https:\/\/docs.citrix.com\/en-us\/workspace-environment-management\/current-release\/user-interface-description\/security.html\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Privilege Elevation<\/a>. Privilege elevation allows us to elevate an executable in the user context without providing the user administrative privileges. Promising, however it has a few considerations:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>WEM can only elevate executables at the time of writing, not PowerShell<\/li>\n\n\n\n<li>WEM supports only elevating executables which are stored locally to the agent. Whilst I was successful in elevation from a NAS device in my own environment, I struggled with an Azure NetApp Files share, and the support stance from the WEM team is executable and must be local<\/li>\n\n\n\n<li>Elevation ONLY occurs in the context of Windows Explorer, trying to leverage a script, or external task to execute the exe for the user will not trigger elevation<\/li>\n<\/ul>\n\n\n\n<p>&nbsp;For more on Citrix WEM Cache, check out <a href=\"https:\/\/www.insentragroup.com\/au\/insights\/geek-speak\/modern-workplace\/the-why-does-it-of-citrix-wem-cache\/\" target=\"_blank\" rel=\"noreferrer noopener\">my previous blog<\/a>.<\/p>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>POWERSHELL SCRIPT<\/span><\/h3>\n\n\n\n<p>I&nbsp;tweaked the PowerShell example from Microsoft to make it per user based, with the logic that we would execute the code on logon and tackle the non-persistent requirements this way. Sounds good in theory, except WEM can\u2019t elevate PowerShell (yet) and as such, I needed to convert my script to an exe.<\/p>\n\n\n\n<p>I am no genius with this stuff, Ps2exe was an absolute breeze to use, and it was&nbsp;<a href=\"https:\/\/www.powershellgallery.com\/packages\/ps2exe\/1.0.10\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">native to the PowerShell Gallery<\/a>&nbsp;so job done. No doubt some environments will struggle with AV solutions which will get upset with this, however Defender was fine with it. The script is&nbsp;<a href=\"https:\/\/github.com\/JamesKindon\/Citrix\/blob\/master\/TeamsPerUserFirewall.ps1\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">located here<\/a>.<\/p>\n\n\n\ncode {\n  padding: 0.125rem 0.25rem;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 0.25rem;\n}\n\npre code {\n  padding: 0;\n  background-color: transparent;\n  border-radius: 0;\n}\n\npre {\n  font-size: 0.875rem;\n  line-height: 1.5em;\n  border-radius: 0.25rem;\n  padding: 0.59375rem;\n}\n.highlight pre {\n  border: none;\n  background: none;\n  margin: 0;\n}\n.highlight &gt; pre {\n  background-image: linear-gradient(\n    rgba(0,0,0,0.03), rgba(0,0,0,0.03) 1.5em, rgba(0,0,0,0.02) 1.5em, rgba(0,0,0,0.02) 3em);\n  background-size: auto 3em;\n  background-position-y: 0.625rem;\n  border: 1px solid rgba(0,0,0,0.1);\n  border-left: 0.4375rem solid #444;\n}\n.highlight &gt; pre:not([class~=&#8221;highlight&#8221;]) { \/* code block with line number *\/\n  padding: 0;\n}\n.highlight table,\n.highlight tr,\n.highlight td { \/* to be removed after fixing table styles *\/\n  border: none;\n  background: none;\n  padding: 0;\n  margin: 0;\n}\n.highlight pre.lineno {\n  color: rgba(0,0,0,0.3);\n  border-radius: 0;\n  border-right: 2px solid #444;\n}\n\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Install-Module ps2exe\nInvoke-PS2EXE .TeamsPerUserFirewall.ps1 .TeamsPerUserFirewall.exe -noConsole -noOutput\n<\/code><\/pre><\/div><\/div>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>LOCALISATION OF THE FILES<\/span><\/h3>\n\n\n\n<p>Given we couldn\u2019t elevate from a network location, we put together a small folder structure locally, we have different requirements for different users, so we wanted a fine-grained level of control with what we allowed WEM to elevate and for who. So, it was simple. Store the executables on a network share, and use Group Policy Preferences in the machine context to bring the files locally<\/p>\n\n\n\n<p><strong>Source<\/strong>: NetworkShareTeamsPerUserFirewall.exe<\/p>\n\n\n\n<p><strong>Destination<\/strong>: C:TempApplicationInstallsTeamsTeamsPerUserFirewall.exe<\/p>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>EXECUTION OF THE SOLUTION<\/span><\/h3>\n\n\n\n<p>This was a touch painful and still gives me a few heebie jeebie moments as it leads back to execution of tasks in a way I usually strip out, however it is what is it is. As mentioned, WEM can only elevate in the context Windows explorer, so we need the execution to occur as if the user was double clicking the exe. I found two ways of doing this:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Using the Windows Start Menu \u201cStartup\u201d folder<\/li>\n\n\n\n<li>Using the legacy run list in the registry HKLMSoftwareMicrosoftWindowsCurrent VersionRun (Thanks James Rankin for the nudge)<\/li>\n<\/ul>\n\n\n\n<p>Choose your poison, however, be warned some environments will disable the execution of applications from the legacy run list.<\/p>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>PUTTING IT ALL TOGETHER<\/span><\/h3>\n\n\n\n<p>This is how the final solution looks:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We have a PowerShell script compiled as an executable copied to the local device on start-up (GPO)<\/li>\n\n\n\n<li>We have a WEM elevation rule which elevates the executable based on the local path and user group membership<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"970\" height=\"250\" src=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Rule.png\" alt=\"\" class=\"wp-image-7286\" title=\"\" srcset=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Rule.png 970w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Rule-300x77.png 300w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Rule-768x198.png 768w\" sizes=\"(max-width: 970px) 100vw, 970px\" \/><\/figure>\n\n\n\n<p><li>We have used Group Policy to write the HKLMSoftwareMicrosoftWindowsCurrent VersionRun key to execute the executable on user logon which writes the firewall rule<\/li><\/p>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>TROUBLESHOOTING WEM PRIVILEGE EVALUATION<\/span><\/h3>\n\n\n\n<p>There was a bit of learning with WEM elevation here, a few notes from the field:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The solution is in its first iteration, so there is a lot of potential for improvement<\/li>\n\n\n\n<li>Logging is key. All elevation logging is logged to the user profile by WEM. The layout of the log files appears to need some work<\/li>\n\n\n\n<li>Logs are uploaded to the WEM central admin console, however this is not immediate, so you need to allow time for data upload to occur before you can review the results in the console. Local logs are of course real-time. I believe the logic is a 1-hour delay on the first log upload, and the incremental uploads every 1 minute after the first, however I didn\u2019t experience consistency in the 1-minute increments<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"906\" height=\"204\" src=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Logs.png\" alt=\"\" class=\"wp-image-7288\" title=\"\" srcset=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Logs.png 906w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Logs-300x68.png 300w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/Logs-768x173.png 768w\" sizes=\"(max-width: 906px) 100vw, 906px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>WEM elevation will fail if the \u201cdeny log on as a batch job\u201d security policy is altered. WEM elevates using batch logons. You should also be cautious of the \u201cAllow log on locally\u201d policy alterations which often occur<\/li>\n\n\n\n<li>Do not turn on the \u201cEnforce RunAsInvoker\u201d setting in Citrix WEM unless you want to kick your own backside. This is of course following the principle of \u201cleast privilege\u201d; however it is difficult when you are trying to work with basic Microsoft environments and consoles. You have been warned <\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"964\" height=\"167\" src=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/RunAsInvoker.png\" alt=\"\" class=\"wp-image-7290\" title=\"\" srcset=\"https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/RunAsInvoker.png 964w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/RunAsInvoker-300x52.png 300w, https:\/\/www.insentragroup.com\/au\/wp-content\/uploads\/sites\/22\/2021\/12\/RunAsInvoker-768x133.png 768w\" sizes=\"(max-width: 964px) 100vw, 964px\" \/><\/figure>\n\n\n\n<h3 style=\"padding-bottom: 15px;margin-bottom: 30px;margin-top: 40px;border-bottom: 1px solid #f16020;color: #f16020\"><span>SUMMARY AND THOUGHTS<\/span><\/h3>\n\n\n\n<p>Again, this post is not focused solely on Teams, we tackle the same requirement\/challenge with different applications using this approach successfully. I wanted to avoid disabling Windows Firewall and I wanted a graceful non-user impacting solution to address the challenge. We also had requirements for additional per-user installations of software which required administrative rights, so it was great timing for the release of the WEM privilege elevation feature.<br>There are no doubt additional ways of tackling the challenges, and no doubt it\u2019s not going to work in all environments, however it does the job so far. Privilege elevation will mature with Citrix, and heaven forbid, Microsoft might even one day allow the basic concept &#8211; a user variable in a firewall path- and then this entire process will be defunct, however for now, it does the job gracefully.<\/p>\n\n\n\n<p>I tested this with Windows 10 Multi-Session and Windows Server 2019.<\/p>\n\n\n\n<p>You can read more of <a href=\"https:\/\/www.insentragroup.com\/au\/insights\/insights-search-results\/?author=James%20Kindon\" target=\"_blank\" rel=\"noreferrer noopener\">my blogs here.<\/a><\/p>\n\n\n\n<p>This blog was originally published on <a href=\"https:\/\/jkindon.com\/conquering-per-user-firewall-rules-with-citrix-wem-privilege-elevation\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">jkindon.com<\/a> and reposted here with permission.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently worked with a client who tested deployment of Microsoft Teams on Citrix without any form of optimisation.<\/p>\n","protected":false},"author":86,"featured_media":7292,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"content-type":"","footnotes":""},"categories":[20],"tags":[46,79,155,156,157,58,59,158,85,86,159,147],"class_list":["post-7283","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-secure-workplace","tag-citrix","tag-cloud","tag-cvad","tag-firewall","tag-firewall-rules","tag-it-security","tag-microsoft","tag-privilege-elevation","tag-secure-workplace","tag-security","tag-teams","tag-wem","entry"],"_links":{"self":[{"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/posts\/7283","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/users\/86"}],"replies":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/comments?post=7283"}],"version-history":[{"count":6,"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/posts\/7283\/revisions"}],"predecessor-version":[{"id":18815,"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/posts\/7283\/revisions\/18815"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/media\/7292"}],"wp:attachment":[{"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/media?parent=7283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/categories?post=7283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.insentragroup.com\/au\/wp-json\/wp\/v2\/tags?post=7283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}