Dopo un primo tentativo miseramente fallito Baring teeth e recuperato in corner grazie agli "Undo Disks" di Virtual Server, benedetti loro Open-mouthed, ho ripreso e portato felicemente a conclusione un task che mi ero pianificato tempo addietro. Lo scopo era:
  • rendere accessibile il mio TFS "Casalingo" al mondo esterno, praticamente a casa non ci sono mai...;
  • continuare ad usarlo anche dall'interno della LAN senza impazzire con le configurazioni sui client;
  • accedervi senza che sia necessario utilizzare una VPN come faccio adesso (ad esempio a FastWeb le VPN non piacciono per nulla...);
  • ovviamente rendere sicuro il canale con SSL;
  • limitare all'osso i problemi derivanti dai filtri che alcuni provider metteno sull'autenticazione NTLM;
la primissima cosa che ho fatto è stata scrivere una mail al "Team Foundation Server Man" per eccellenza e chiedergli lumi perchè avevo trovato un paio di risorse sul web che si sovrapponevano e non capivo bene quale fosse la strada giusta.
Alla fine la scelta è ricaduta (grazie a Lorenzo) su questo whitepaper ufficiale Microsoft: http://msdn2.microsoft.com/en-gb/library/aa833872(VS.80).aspx che spiega nel dettaglio tutti i passaggi per poter pubblicare TFS su SSL.
Non mi soffermo sugli step dell'articolo che sono parecchi ma ben documentati e precisi, fate, e ripeto fate, un backup di tutto il mondo prima di mettere mano al tutto... Developer e IT Pro avvisato... Open-mouthed 
La configurazione dell'ISAPI Filter per IIS non è uno step obbligatorio ma lo diventa se volete avevre l'opportunità di liberarvi di NTLM per la connessione a TFS dall'eterno (http://msdn2.microsoft.com/en-gb/library/aa833874(VS.80).aspx).
Se la procedura va a buon fine siete ora in grado di connettervi dalla vostra LAN al TFS su SSL e potete essere felici perchè già arrivare li non è proprio da tutti Tongue out... sappiate però che a questo punto siete in un vicolo cieco:
  • nessun supporto;
  • nessuna possibilità di installare service packs a causa dei cambiamenti nella configurazione;
I problemi nella mia configurazione sono sorti quando ho affrontato ISA Server... benedetto figgggghiu mio...
Un piccolo preambolo, la mia configurazione di rete:
  • Router HW
  • ISA Server (3 Schede di rete: LAN / FW<-->Router / DMZ)
  • LAN Interna
    • DC
    • TFS
    • Exchange
    • Etc...
  • I nomi interni non coincidono con i nomi pubblici (e questo è un problema per TFS...o meglio potrebbe esserlo)
Il problema della pubblicazione di TFS è legato in particolare ai FQDN che vengono usati per connettersi, essendo un'applicazione composta da n applicazioni distinte (TFS, SharePoint, ReportingServices) internamente i riferimenti agli url sono importanti e in alcuni casi (molti) includono anche il nome del server e la porta...
Il problema della nomenclatura si riflette di conseguenza anche su Visual Studio, dovendo lavorare sia in LAN che da fuori quando apro Visual Studio non voglio avere problemi di nomi non risolti etc... etc... Per fare ciò vi basta mettere mano al DNS e definire delle entry (Record A o Alias) anche per i nomi pubblici facendo si che vengao risolti con l'IP interno.
Fatto questo dall'interno della LAN il TFS è raggiungibile con il nome pubblico e su SSL, e abbiamo risolto almeno 2 degli obiettivi posti.
Vediamo adesso di capire come pubblicare all'esterno il tutto facendolo digerire al reverse proxy di ISA Server.
In un'installazione di default di TFS la configurazione è già abbastanza complessa, nella mia installazione personalizzata lo è un po' di più perchè ci sono due aggiunte:
  • Windows SharePoint Services 3.0 in sostituzione ai WSS2.0: TFS adesso usa la nuova versione, ma purtroppo non posso rimuovere i 2.0 (perchè necessari per la prima installazione e usati da TFS tutt'ora) quindi vivono Side By Side;
  • Team System Web Access: un portale web per accedere a tutte le funzionalità di TFS (SourceControl escluso) da internet senza aver bisogno di nessun client;
Questo comporta che la situazione IIS è più o meno questa sulla macchina di TFS (tfs.domain.local):
  • Team System Web Access
    • HTTP: 80 e 8090
    • HTTPS: 4343
  • Team Foundation Server
    • HTTP: 8080
    • HTTPS: 4433
  • ReportServer e WSS 2.0
    • HTTP: 80
    • HTTPS: 433
  • SharePoint Central Administration v3
    • HTTP: 32281
    • HTTPS: 44333
  • SharePoint Central Administration
    • HTTP: 17012
    • HTTPS: 43333
  • SharePoint Services 3.0:
    • HTTP: 81
    • HTTPS: 4443
perchè questo sfacelo di porte per HTTP e HTTPS? semplicemente perchè io sono un poveretto e ho un solo IP Pubblico (neanche statico per inciso) quindi per la gestione devo affidarmi ai WebListener di ISA e utilizzare le porte come discrimninante per fare il redirect sulle macchine interne... in ISA server "purtroppo" (non è che loconosca bene quindi magari sono io che non ho capito) non c'è mezzo di creare 2 WebListener in ascolto sulla stessa porta che usino come discriminate l'url richiesto, ad esempio sarebbe comodo poter dire a ISA:
Se la richiesta che ti arriva è per www.mydomain.tld allora fammi il redirect su myinternalwebserver.domain.local:80 mentre se la richiesta è per pippo.mydomain.tld allora vai da un'altra parte... putrooppo è necessario specificare anche una porta su cui è in ascolto il listerner quindi quello che potete fare è se la richiesta è per www.mydomain.tld (sottointeso :80) allora fai il redirect su una certa macchina, se invece è per pippo.mydomain.tld:8080 fai il redirect su un'altra macchina.
A questo punto armatevi di santa pazienza e create i vari listener e le regole di pubblicazione facendo attenzione a:
  • ogni Listener (uno per funzionalità che vogliamo pubblicare) ascolta solo sulla porta SSL;
  • Ogni listener non ha nessuna configurazione relativa all'utenticazione, tutto è delegato a IIS sulla macchina TFS;
  • nelle publishing rule di ogni sito, nella tab "Bridge", definite il redirect non verso la porta SSL ma bensì verso quella HTTP:

    bridging
  • nella tab "To" della publishing rule eseguite il redirect verso il nome interno del sito specificando l'indirizzo IP della macchina:

    to
  • abilitate la casella di spunta "Forward the original Host Header..." e fate in modo che la richiesta provenga dal client originale (Request apper to come from the original client) e non da ISA: pena un bel "TFXXXX...access denied user does not have access to tfs..." da parte di TFS quando vi connettete con Visual Studio
Le ultime 3 note sono fondamentali: la tecnica classica per pubblicare un Web Server attraverso ISA Server è quella di avere un nome esterno diverso dal nome interno del server da pubblicare, in questo modo è possibile, ad esempio, pubblicare il Web Server su SSL e fare anche la connessione da ISA verso il Web Server sempre su SSL, questo perchè se i nomi coincidono ISA si arrabbia ritornando un bel (e un po' misterioso...) HTTP500 Server Internal Error (Incorrect Server Principal Name), nel nostro caso non possiamo fare così perchè abbiamo bisogno che il nome esterno e il nome interno siano identici pena difficoltà/impossibilità di connettersi dall'interno. Facendo si invece che la richiesta da ISA vada verso la parte non SSL non abbiamo nessun problema di certificati digitali all'interno della LAN nella comunicazione tra ISA e TFS.
Fatti questi passaggi ricodatevi, dopo aver fatto qualche test di connettività con un browser, di installare il certificato della CA sul client se, come nel mio caso, la CA che emette il certificato non è trusted (nel mio caso la CA sono io stesso...quindi mi trasto da solo) questo è fondamentale perchè mentre il browser vi da un warning e vi consente di dedicedere se continuare o meno con la connessione, VS invece fallisce a priori e vi ritorna un bell'errore e basta.
Una nota importante:
non mi assumo nesuna responsabilità per i danni immani che potreste fare al vostro TFS seguendo la stessa procedura, se lo fate e vi si schianta tutto non venite a piangere da me... Wink

se avete domande invece fatevi sotto!
.m