Hello all, Nathan Penn here to shed some light on how I identify the most restrictive settings for applications and their associated service accounts, while keeping things functioning. When security is paramount (which is always) and we are deploying enterprise applications to Windows systems, we must ensure that the level of access provided to any given application is just what it requires to function. For example, if installing an application like SQL, you may hear that the service account "requires" local or even domain administrator rights to operate. While this is the EASY way and will ensure functionality, it is NOT true and can be done in a much more secure manner with a little effort... and maybe a little magic! The software installation process itself will require local administrator rights to the system by the individual performing the install, however, the service account does not need this level of persistent permission. So what permission does a given service account need and how do you identify it? The method I highlight below will demonstrate how to accomplish just that.
To walk through this process, I will install SQL Server 2016 Express on a domain-joined Windows 2016 Member Server, and then apply the Microsoft Security Baseline for Server 2016 (optimally, do this in a lab first and then move to production). The server will be placed in a Staging/Test OU that has block inheritance enabled to ensure that we don't have to fight security lockdowns during the initial installation and configuration. There is an assumption here that you are not enforcing GPOs at a higher OU or domain level that configure user rights assignment. In my environment this is the "T1-Staging" OU and as you can see from the Group Policy Inheritance tab, no GPOs are being applied at this time.
If working in production, we should ensure that no end users or production data are added to this system while in the Staging OU. This process enables us to confirm a known-good functionally configured state for any of our applications and identify any settings that might conflict with our environment baseline security policies. The account performing the install is only a Member Server Administrator to the local system, so there is no need for Domain Admin rights. The service account (CONTOSO\s-sql) is a basic user account with no additional privileges or group memberships, as shown below.
As a first step, let's look at the user rights assignments for our Windows 2016 Server that has no domain policies affecting it before the application install. On the server we launch the Local Policy Editor by running gpedit.msc and browsing to Local Computer Policy -> Computer Configuration -> Windows Settings -> Security Settings –> Local Policies -> User Rights Assignment to review the settings.
Now let's start our software installation on the system. During the software installation, whenever prompted for service account, supply the associated service account and password.
After running the install, verifying that our installation was successful and checking that the application is functioning, we are now ready to revisit the User Rights Assignment as before and look for changes.
A quick review shows that there are updates adding accounts like NT SERVICE\MSSQL$… and CONTOSO\s-sql to several user right assignment policies as detailed here:
Adjust memory quotas for a process
Bypass traverse checking
Log on as a service
Replace a process level token
With this information, we can have our Group Policy admins create a GPO specific to our application that gives the service account (and any application local accounts as needed - i.e. NT SERVICE\MSSQL...) just the level of permission required to the associated server.
Using an account and a system with access to create Active Directory Group Policies, launch the Group Policy Management Console, gpmc.msc, and create a customization GPO for the application. In this instance I created a policy named "SQL Server Customizations," and I like to edit the properties of the policy to add comments on exactly what this policy is for.
Browse to Computer Configuration -> Windows Settings -> Security Settings –> Local Policies -> User Rights Assignment of the policy and define the settings we identified earlier.
IMPORTANT: A common mistake that is made is defining a user right assignment with only the new additions, i.e only adding the new SQL accounts to the "Replace a process level token" while leaving off Local Service and Network Service. When identifying and updating user rights assignments, you need to include ALL accounts that should have permissions, as this does not perform a merge with current settings, but instead performs a REPLACE of the user assignments.
Once we have finished defining the updated User Rights Assignment with our updates, we should have a domain GPO that looks similar to this:
After applying our GPO to our test OU, we can refresh group policy processing on our system and confirm that our settings are applying by executing a gpresult. As we can see, the User Rights Assignments are applied from our GPO.
At this point, I would recommend a reboot of the system so that we can confirm all settings are in affect at application start. Now we proceed with reaffirming that the applications services are starting with our policy applied.
Once satisfied that the application is still functional, we are ready to apply the security lockdowns by moving the Active Directory Server object from the block OU into a production OU that receives security lockdowns. In my environment, that means moving this server into my "T1-Database" OU where I have linked our SQL Server Customization policy. In addition to our policy the server will now also receive the Microsoft Security Baseline policy for Windows 2016 Servers (Available here - https://www.microsoft.com/en-us/download/details.aspx?id=55319 ).
We then refresh the group policies on our system and perform one more reboot to again ensure that all settings are in affect at application start and that our settings are applying by executing a gpresult. As we can see, the User Rights Assignments are being applied from our GPO as well as the Security Baseline.
Now we once again confirm that application services are still starting as expected.
There you have it - A service account that has no administrative privileges to the domain or even to the server itself, but still permits the application to function.
NOTE: If the application services are starting and running in the production OU, but no longer functioning as it was while in the Staging OU, this is not a service account issue but rather a lockdown configuration item such as FIPS, NTLM version, etc. More on how to identify and troubleshoot these in a future post.
Now get out there and start removing all those extra permissions from your service accounts. Hope this helps!