Results for tag "security"

4 Articles

TeamCity: Make the NuGet repository available without authentication

Task for today was making the NuGet repository of TeamCity available in our local network. Sounds easier as it was as our TeamCity instance is available from the Internet but you can only access the rontend with valid domain credentials (LDAP/Active Directory authentication). Enabling the guest account feature in TeamCity would have mean a small security break in our concept.

Here is the success-story how to enable the NuGet repository for local accesss without authentication and without enabling the TeamCity guest account:

Creating a new proxy instance

One of our Apache servers got the order to act as reverse proxy for the NuGet repository. The reverse proxy was running inside an own virtual host (nuget.mydomain.local) and was registered in our local DNS.
The configuration looked like this:


<VirtualHost *:443>
 SSLEngine on
 SSLProxyEngine on

ServerAdmin admin@mydomain.local
 ServerName nuget.mydomain.local
 ServerAlias nuget.mydomain.de

LogLevel warn
 ErrorLog logs/nuget.mydomain.local-error_log
 CustomLog logs/nuget.mydomain.local-access_log combined

# Map other source to FeedService URL
ProxyPass / https://teamcity.mydomain.local:443/guestAuth/app/nuget/v1/FeedService.svc/
ProxyPassReverse / https://teamcity.mydomain.local:443/guestAuth/app/nuget/v1/FeedService.svc/

</VirtualHost>

Adding a domain proxy user

With the configuration above we still have the problem that there is no user who can access the repository without credentials. So we need to add a domain user, let me call it teamcity-nugetfeed-proxy-user. For security reasons this account has a very long random generated password and is only used for providing the NuGet feed.

Using the domain proxy user in our Apache configuration

We have to add a Basic Authorization header in our Apache configuration so that every access between the proxy and TeamCity is authenticated.


RequestHeader set Authorization "Basic <Base64(teamcity-nugetfeed-proxy-user:$password)>"

The phrase <Base64(teamcity-nugetfeed-proxy-user:$password)> must be replaced by an base64-encoded string with format $username:$password.

After restarting the Apache you should be able to use the NuGet stream in Visual Studio. Look at the Apache logs for occuring errors.

TeamCity is failing – NuGet return “File contains corrupted data”

Till yet you are able read the stream but TeamCity will fail downloading your repository files. The reason is easy: The FeedService.svc returns an XML file which contains absolute pathes mapping to teamcity.mydomain.local and not nuget.mydomain.local. So again we have no authorization and the error File contains corrupted data occurs because of the TeamCity login dialogue.

We have to rewrite the content of the FeedService.svc replacing every occurence of teamcity.mydomain… with nuget.mydomain…
At first I tried mod_proxy_html but in the end using mod_substitute was the only solution that worked.


# Rewrite FeedService URL
 Substitute "s|https://teamcity.mydomain.local/guestAuth/app/nuget/v1/FeedService.svc|https://nuget.mydomain.local|i"
# Rewrite repository access
Substitute "s|https://teamcity.mydomain.local/guestAuth/repository|https://nuget.mydomain.local/repository|i"

# Execute every substitution only for XML/HTML
 AddOutputFilterByType SUBSTITUTE text/html
 AddOutputFilterByType SUBSTITUTE text/xml
 AddOutputFilterByType SUBSTITUTE application/atom+xml

# Map local repository path to remote repository
 ProxyPass /repository https://teamcity.mydomain.local:443/guestAuth/repository
 ProxyPassReverse /repository https://teamcity.mydomain.local:443/guestAuth/repository

# Unset gziped accepted encoding
RequestHeader unset Accept-Encoding

After restarting everything should work fine.

The complete configuration is now


<VirtualHost *:443>
 SSLEngine on
 SSLProxyEngine on

ServerAdmin admin@mydomain.local
 ServerName nuget.mydomain.local
 ServerAlias nuget.mydomain.de

LogLevel warn
 ErrorLog logs/nuget.mydomain.local-error_log
 CustomLog logs/nuget.mydomain.local-access_log combined

# Rewrite FeedService URL
 Substitute "s|https://teamcity.mydomain.local/guestAuth/app/nuget/v1/FeedService.svc|https://nuget.mydomain.local|i"
 # Rewrite repository access
 Substitute "s|https://teamcity.mydomain.local/guestAuth/repository|https://nuget.mydomain.local/repository|i"

# Map local repository path to remote repository
 ProxyPass /repository https://teamcity.mydomain.local:443/guestAuth/repository
 ProxyPassReverse /repository https://teamcity.mydomain.local:443/guestAuth/repository
 # Map other source to FeedService URL
 ProxyPass / https://teamcity.mydomain.local:443/guestAuth/app/nuget/v1/FeedService.svc/
 ProxyPassReverse / https://teamcity.mydomain.local:443/guestAuth/app/nuget/v1/FeedService.svc/

# Execute every substitution only for XML/HTML
 AddOutputFilterByType SUBSTITUTE text/html
 AddOutputFilterByType SUBSTITUTE text/xml
 AddOutputFilterByType SUBSTITUTE application/atom+xml

RequestHeader set Authorization "Basic <Base64(teamcity-nugetfeed-proxy-user:$password)>"

 # Unset gziped accepted encoding
 RequestHeader unset Accept-Encoding
</VirtualHost>

WSUS: Moving from Windows Internal Database to external SQL Server 2008 and receiving “Token-based server access validation failed with an infrastructure error”

Today I had to move the WSUS internal database to one of our backend database servers. Microsoft has a good instruction how to do this, nevertheless I ran into a problem.

Microsoft SQL Server 2008 did not allow me to add the machine account of our WSUS frontend server (let me call it WSUS-SRV), so I created a new Active Directory security group called WSUS Administrators containing the WSUS-SRV machine account. This security group I gave the permission to access the database.

After starting the IIS Admin Service and Update Services the database backend server showed the error Token-based server access validation failed with an infrastructure error (event-id 18456). Oops.
One workaround  would have been to disable the UAC (http://blogs.msdn.com/b/sqlserverfaq/archive/2010/10/27/troubleshooting-specific-login-failed-error-messages.aspx). Not a solution I was very keen about.

I fixed the problem by creating a local security group on the database server and adding the maching account of WSUS-SRV into it.

Remove version signature from TeamCity, Confluence and JIRA

If you want to make your TeamCity, Confuence or JIRA instance accessible from outside of your LAN, you should remove all version signatures so that no attacker can easily lookup for existing exploits.

  • TeamCity: Open <TeamCity installation dir>/webapps/ROOT/WEB-INF/tags/version.tag and remove the full content from this file. You must restart the TeamCity service afterwards.
  • Confluence: Open <Confluence installation dir>/confluence/decorators/includes/footer-content.vm and remove the line
    <li class=”print-only”>$action.getText(‘printed.by.atlassian.confluence’,[“$generalUtil.versionNumber”])</li>Restart of Confluence service/instance is required.
  • JIRA: Open <JIRA installation dir>/atlassian-jira/WEB-INF/classes/templates/plugins/footer/footer.vm and remove the line
    <span id=”footer-build-information”>(v${build.version}#${build.currentBuildNumber}${commitId}${partnerName})</span>

    Restart of JIRA service/instance is required.

Windows 2003 als zentraler Event Log-Server / Freigeben von Event Logs an bestimmte Benutzer

Florian hatte vor einigen Wochen das Tool eventcreatef vorgestellt.  Es dient dazu, dass komplette Log-Dateien und nicht nur einzelne Log-Nachrichten in die Ereignisanzeige von Windows geschrieben werden können. eventcreatef delegiert die Aufrufe an das Microsoft-Tool eventcreate, dass die übergebenen Daten in kleinere Teile an den jeweiligen Server sendet.

Somit kann man mit Hilfe von eventcreatef einen zentralen Log-Server auf Basis von Windows Server 2003 o.ä. aufsetzen, der alle Log-Dateien sammelt, z.B. die, die während eines nächtlichen Backups auftreten.

Leider gibt es für Linux kein Tool, dass direkt in die Ereignisanzeige von Windows Server 2003 schreiben kann. Für unsere heterogene Umgebung war dies ein ungünstiger Sachverhalt. Ich musste also einen generischen Service schreiben, der per SOAP die Log-Daten entgegen nehmen konnte und dann dementsprechend an eventcreatef weiterdelegiert.

Dabei ist das unten angehängte Script namens eventcreateservice.php (ECS)heraus gekommen: Es stellt über das Zend Framework eine SOAP-Schnittstelle bereit, die die einfache Methode create besitzt. Wird das Script über eventcreateservice.php?wsdl aufgerufen, wird die WSDL-Datei ausgegeben, über eventcreateservice.php?bash lässt sich ein Bash-Script downloaden, dass mit Hilfe von curl eine Verbindung mit dem SOAP-Service herstellt. An dem Bash-Script muss nichts weiter angepasst werden, da die URLs automatisch generiert werden. Somit lassen sich nativ auf Linux-Maschinen Einträge in die (native) Ereignisanzeige von Windows-basierten Maschinen schreiben.
Ein Syslog-Server ist also nicht mehr nötig. Das Konzept ist besonders für kleinere Unternehmen interessant, die mehr Windows-Maschinen als Linux-Maschinen besitzen und für die ein zentraler Syslog-Server oversized ist.

Nachdem ich ECS fertig entwickelt hatte, ging es nun darum, dass ich die von mir erstellten Log-Einträge nicht in den Standard-Log-Dateien Applikation, System und Sicherheit schreiben wollte, sondern in eine Extra-Logdatei namens Backups.
Florian stellt in der oben bereits genannten URL ein kleines Tool namens CreateEventLog2 bereit. Über die Aufmachung und Fehlerbehandlung der GUI lässt sich streiten, mir ging es um den Funktionsumfang: CreateEventLog2 erzeugt eine neue Log-Datei, die dann in der Ereignsanzeige der MMC angezeigt werden kann.
Damit hatte ich schon ein Großteil erreicht: Ich konnte nun von Windows-Systemen aus Log-Nachrichten auf unserem Log-Server speichern, die Linux-Systeme konnten über das Bash-Script und den SOAP-Service ebenfalls in die Windows-Ereignisanzeige schreiben und schließlich hatte ich ein weiteres Log neben den Standard-Windows-Logs.

Im letzten Schritt ging es nun darum, das von mir definierte Log einem dedizierten Benutzer zugänglich zu machen. Ich wollte in der Konfigurationsdatei von ECS (logischerschweise) keinen Domänen-Administratoraccount eintragen, sondern einen Benutzer mit beschränkten Rechten. Für dieses Vorhaben muss man zuerst einmal ein paar Sachen wissen: Der Zugriff auf die Log-Dateien eines Systems werden über Registry-Einträge geregelt. Es gibt unter HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventLog zu jeder Log-Datei einen Schlüssel, der wiederum diverse Attribute enthält. Wichtig ist das Attribut CustomSD: dieses beschreibt anhand eines SDDLs, ob und wer auf dieses Objekt zugreifen darf. Standardmäßig steht in der CustomSD (in meinem Fall zu finden unter HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventLogBackupsCustomSD) ein String der folgenden Art: O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3). Sieht kryptisch aus, ist es aber eigentlich nicht – wenn man weiß, wie die SDDLs aufgebaut sind.
Kurz dazu: Jeder eingeklammerte Eintrag, z.B. (D;;0xf0007;;;AN) definiert eine Zugriffsregel (ACE). Die erste Regel, die vom System gefunden wird und zutrifft, wird benutzt.

Wie dem auch sei: Es gibt glücklicherweise ein Tool namens sddlparse, das die zugegebenermaßen etwas kryptisch anmutende Zeichenkette analysiert und dann wieder in lesbarer Form ausspuckt.
Nachdem ich damit die benötigten Rechte für einen schreibenden Zugriff auf die Ereignisanzeige auslesen konnte (ADS_RIGHT_DELETE, ADS_RIGHT_READ_CONTROL, ADS_RIGHT_WRITE_DAC, ADS_RIGHT_WRITE_OWNER, ADS_RIGHT_DS_CREATE_CHILD, ADS_RIGHT_DS_DELETE_CHILD und ADS_RIGHT_ACTRL_DS_LIST), erstellte ich einen neuen ACE mit eben diesen Rechten. Die ACE muss an erster Stelle eingefügt werden, so dass der Registry Key wie folgt aussieht: O:BAG:SYD:(A;;LCDCCCWOWDSDRC;;;S-1-5-21-xxx-xxx-xxx-xxx)(nächste ACE…). Der Registry Key wird übrigens bei jedem Aufruf der Ereignisanzeige ausgelesen, somit tritt die Änderung sofort in Kraft.
Ich fügte die SID unseres dedizierten Ereignisanzeigen-Benutzer mit Hilfe der obigen ACE hinzu und war in der Lage mit diesem in die Ereignisanzeige zu schreiben.

Während ich mich in SDDLs und ACEs einarbeitete, fiel auch ein kleineres Tool namens ACECreator ab. Es verbindet sich mit dem Active Directory und sucht mit Hilfe von Ambigious Name Resolution (ANR) Objekte heraus. Diesen Objekten lassen sich dann die Einstellungen verpassen, die man braucht, das passende ACE wird automatisch erzeugt.

Alles in allem war dieses Projekt äußerst spannend. Zwar klingt die Durchführung relativ einfach, allerdings gab einige Probleme mit den Rechten bzw. Benutzeraccount, unter dem eventcreatef lief u.s.w.
Lesenswert sind folgende Links, die ich u.a. für den ACECreator als Referenz herangezogen habe:

Angehängte Downloads
[download id=5]
[download id=6]