Teamcity HTTPS running under a service account

Well, now that I'm in my devops role, it's time for me to start working on our Team City build environment. One of the things we wanted to do, now that we have the time, was run our Team City environment under a service account and force https. It's part of company wide thing to enable and force https on everything, and I prefer service accounts and windows authentication for service accounts. It makes communicating with network resources really easy.....web deploy (another post) for example.

Basic overview of the the setup and needs, Team City is installed on windows servers. Create a domain trusted certificate for the server (which was fine for our environment). Import the certificate into a keystore file for java. Reconfigure the java webserver to use https and port 443. Now for the detailed step-by-step instructions. There's a lot, but it's pretty easy once you've gone through it.

To run as https, you do not have to run with a service account. It's just something else I wanted in my environment.

In my instructions below, I have some examples of names and passwords. These are examples and need to be changed to your values.

Install Team City with a service account

Install Team City with a service account

  1. Create the service account in active directory: Example: litterbox\!teamcity
  2. Install team city, I used default options, installing team city to c:\teamcity, there is a step where you can specify the user account. You will want to do this.
  3. Set the file permissions on installed files.
    C:\teamcity is the default install locations
  4. Allow special system rights for your service account
    • Using gpedit, Expand out to Windows Settings\Security Settings\Local Policies\User Rights Assignment
    • Add your service account to "Debug Programs"
    • Add your service acocunt to "Shut down the system"
    • If it's not already, add your service account to "Logon as a service"
  5. Allow the service account full control to the TCBuildAgent service
    • Download and install subinacl.
    • Using an elevated command prompt or powershell run subinacl /service TCBuildAgent /grant=litterbox!teamcity=F

Enable and force SSL:

  1. Using IIS Manager from a server that has IIS installed
    • Open IIS Manager
      • Server Name->Server Certificates->Create Domain Certificate>
      • Common Name=fqdn of the url for the server. Example: teamcity.litter.box
      • Organization=name of your company
      • Organizational Unit=department of your company
      • City/Locality=city your company is based out of
      • State/province=state your company is based out of
      • Country/Region=country your company is based out of
    • Next
    • Specify Online Certificate Authority-Select->Choose your pki server. (Example: Litterbox Certificate Root)
      • Friendly Name=fqdn of the url for the server. Example: teamcity.litter.box
    • Finish
  2. Using the certificate snapin in mmc, export the created certificate and a root certificate
    • (Start->run) or (windows key+r) -> mmc
    • File->Add/Remove Snap-ins->Certificates in the left->Add in the middle->Computer Account->Next->Finish->OK
    • Expand the path Certificates (Local Computer)\Personal\Certificates in the left
    • Right click the certificate that you just created. Example: (Issued To=teamcity.litter.box and Issue By=Litterbox Certificate Root)
    • Click All Tasks->Export->Next->Yes, export the private key->(Make sure pfx is chosen, and Include All certificates is selected)->Next
      Important: When setting the password, make sure it is the password you want to use in your final java chain. I will have steps at the end to show how to change it later if want to use seperate passwords.
      • Password=YourPassword. Example: P@ssword1
    • Next
      • Filename=where ever you want it saved. Example: c:\teamcity.litter.box.pfx
    • Next
    • Finish
    • Expand the path Certificates (Local Computer)\Trusted Root Certificates\Certificates
    • Right click the correct root certificate. Example: Litterbox Certificate Root
    • Click All Tasks->Export->Next->Selecte Base-64 encoded X.509 (.CER)->Next
      • Filename=where ever you want it saved. Example: c:\rootcertificate.cer
    • Next
    • Finish
  3. Copy the exported certificates to your teamcity server.
    • Example: \teamcity.litter.box\c$\teamcity.litter.box.pfx
    • Example: \teamcity.litter.box\c$\rootcertificate.cer
    • Delete the exported certificates (optional)
  4. Using keytool.exe import the certificate to a keystore file on the team city server.
    • Open an elevated command prompt or powershell (how you do this is up to you)
    • Example: c:\TeamCity\jre\bin\keytool.exe -importkeystore -srckeystore c:\teamcity.litter.box.pfx -srcstoretype pkcs12 -destkeystore c:\teamcity\conf\.keystore2
    • It will ask for a password for the new keystore. This should match what you put in for the pfx file when you exported it. Instructions below if you want this password different from the exported file. (In the end they need to be the same). Example: Password1
    • Confirm the password. Example: Password1
    • Enter the password for the pfx you exported. Example: Password1
  5. Configure the teamcity server to use the https protocol
    Inside of c:\teamcity\conf\server.xml, look for the elements. You will need to add one for port 443, and replace the port 80.

  6. Force https
    • Inside of c:\teamcity\conf\web.xml, at the end, just before the closing add the following
      <security-constraint>
          <web-resource-collection>
              <web-resource-name>HTTPSOnly</web-resource-name>
              <url-pattern>/*</url-pattern>
          </web-resource-collection>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
      </security-constraint>
      
      1. Update the build agents to use HTTPS
        • Import the root certificate into the java root chain
          c:\teamcity\jre\bin\keytool -importcert -file c:\rootcertificate.cer -keystore c:\teamcity\jre\lib\security\cacerts
        • The password for the cacert file, by default, is changeit
      2. Restart the TeamCity and TeamCity Agent services

Helpers/Troubleshooting:

  • If you wanted to specify a different password for the exported certificate than the one for the keystore, once it is imported, there are a few command that need to be run.
    1. We need to get the alias of your certificate
      1. List certificates from your .keystore2 file:
        c:\teamcity\jre\bin\keytool.exe -list -keystore c:\TeamCity\conf\.keystore2 -v
        • It should dump out something like this:
           Enter keystore password:
           Keystore type: JKS
           Keystore provider: SUN
           Your keystore contains 1 entry
           Alias name: le-e525723e-3ae6-48bc-9dd4-4eccd0379554
           Creation date: Jun 19, 2014
           Entry type: PrivateKeyEntry
           Certificate chain length: 2
           Certificate[1]:
           Owner: CN=teamcity.litter.box, OU=Litterbox, O=VECC, L=West Jordan, ST=UT, C=US
           Issuer: CN=Litterbox Certificate Root, DC=litter, DC=box
           .
           .
           .
           
          
        • In bold, up near the top, is what we are looking for. The Alias. You want to find the correct alias, by looking at owner following it a few lines down that should get you the right one.
          You now need to change the password to the correct one.
        • You now need to change the password to the correct one.
          C:\TeamCity\jre\bin\keytool.exe -keypasswd -keystore C:\teamcity\conf\.keystore2 -alias le-e525723e-3ae6-48bc-9dd4-4eccd0379554
          It will ask for the password for the keystore file, the password for the certificate (which is what you put in when you exported it), and the new password, this should be the same as the one of the keystore file, otherwise HTTPS will not work.
        • That's it.