Jak szybko wygenerować certyfikaty dla Always On

Zadanie niby trywialne – skonfigurować TLS na SQL Server z grupami Always On. Chwila szukania i wiem co musi mieć template certyfikatu. https://technet.microsoft.com//en-us/library/ms189067(v=sql.105).aspx#Anchor_2 mówi, że jest potrzebne m.in.

The certificate must be meant for server authentication. This requires the Enhanced Key Usage property of the certificate to specify Server Authentication (1.3.6.1.5.5.7.3.1).

Pech chciał, że akurat miałem pasujący template, który poza tym pozwalał na client authentication i postanowiłem go użyć. Niestety takie podejście okazało się skuchą bo certyfikat musi mieć wyłącznie OID 1.3.6.1.5.5.7.3.1 . Jeśli pojawi się cokolwiek innego to koniec, kaplica, bez szans. SQL go nie uzna i nie pozwoli na użycie do szyfrowania połączeń. Z punktu widzenie bezpieczeństwa ma to sens ale mogło by się gdzieś w dokumentacji pojawić, że leniuchy będę musiały stracić czas na zastanawianie się czemu nie działa. Koniec końców, całkiem nieźle sprawdziłPKI się standardowy template Web Server :-)

Drugim problemem dla leniwego admina pojawia się wygenerowanie requestów z wszystkim nazwami listenerów (purystów przepraszam za moją hiperniepoprawną polszczyznę) na wszystkich serwerach. https://msdn.microsoft.com/en-us/library/hh213417.aspx#SSLcertificates bardzo ładnie podaje, że temat certyfikatu to hostname bądź fqdn serwera a SAN musi zawierać wszystkie nazwy DNSowe listenerów (zarówno skrócone jak i fqdn). I tu pojawiają się dwa problemy (korporacyjnie: wyzwania) bo po pierwsze serwerów jest dużo a po drugie każdy z nich ma po kilkanaście listenerów. Jako, że nie chce mi się tyle klikać w GUI a tym bardziej nie chcę zrobić nigdzie literówki, piszę coś takiego i paroma linijkami kodu ratuję sobie resztę dnia ;)

#import SQL PS module
ipmo sqlps

#get all availability groups
#
#  Replace HOSTNAME and INSTANCE with correct names
#

$allag = Get-ChildItem SQLSERVER:\SQL\HOSTNAME\INSTANCE\AvailabilityGroups

#Get list of all Subject Alternative Names
# (FQDNs and short names of all listeners)

[String[]] $listeners = @()
$allag | Select-Object Name | %{$listeners += ($_.Name + "." + $env:userdnsdomain); $listeners += $_.Name }
$fqdn = ([System.Net.Dns]::GetHostByName(($env:computerName)).HostName) 


#Add server's hostname and FQDN to SANs
$listeners += $env:computerName
$listeners += $fqdn.ToString()

#Set subject as server's FQDN 
[String]$subject = ("CN=" + $fqdn)

#Request certificate
Get-Certificate -Template WebServer -SubjectName $subject -DnsName $listeners -CertStoreLocation cert:\LocalMachine\My

 

Obronić się przed MiTM

Minęło wiele lat od kiedy napisałem tu ostatni post a do tego temat na (re)debiut już nie jest gorący. Chociaż z drugiej strony nie zdążył jeszcze wystygnąć i w każdej chwili może ponownie wybuchnąć. Ale do rzeczy. Dziesięć miesięcy temu okazało się, że przez pół roku Lenovo raczyło swoich użytkowników certyfikatami umożliwiającymi ataki MiTM (https://www.us-cert.gov/ncas/alerts/TA15-051A). Wiadomo, generalne oburzenie, Chińczycy nas śledzą, na pewno to sprawa służb, teorie spiskowe  i w ogóle koniec świata. Szczerze mówiąc temat spłynął po mnie jak po kaczce, sprawdziłem swój tablet (kupiony w przypływie weny wracając z baru po spotkaniu świąteczno noworoczny) i zapomniałem o temacie. Potem gdzieś pojawił się problem z Dell System Detect i zdalnym wywołaniem kodu, który został załatany przed opublikowaniem dziury (http://tomforb.es/dell-system-detect-rce-vulnerability). To ruszyło mnie trochę bardziej, sprawdzanie kto ma zainstalowane oprogramowanie i usunięcie starych wersji okazało się nie być trzema kliknięciami ale koniec końców temat załatwiony i systemy załatane w kilka godzin.

Niby dwie z pozoru niepowiązane rzeczy a jednak ostatnio okazało się, że niektórzy wolą się uczyć na własnych błędach zamiast na cudzych i Dell obdarzył nas kolejną serią serią wpadek (http://joenord.blogspot.in/2015/11/new-dell-computer-comes-with-edellroot.html,http://www.kb.cert.org/vuls/id/925497) instalując razem ze swoim oprogramowaniem certyfikaty w Trusted Root razem z ich kluczami prywatnymi. Do tej pory jest jeszcze prawie ok. Oprogramowanie potrzebuje coś samo podpisać żeby system się nie burzył przy instalacji, certyfikat jest oznaczony jako nieeskportowalny. Nie jest najgorzej, w końcu to narzędzie systemowe a nie aplikacja pokazujące  reklamy jak w przypadku Lenovo i jesteśmy zadowoleni dopóki nie zauważymy, że nasz kolega ma ten sam certyfikat a ktoś nam powie, że klucz prywatny można wyeksportować na przykład za pomocą mimikatz.

W głowie zaczynają układać się klocki pokazujące bardzo prosty scenariusz ataku:

  1. Eksportujemy certyfikat (patrz link powyżej)
  2. Stawiamy darmowe WiFi z SSID Starbunio i idziemy w pobliże kawiarni
  3. Czekamy na kogoś z laptopem Della kto podłączy się do naszego WiFi i otworzy stronę, którą warto przechwycić
  4. Zmieniamy SSID i miejsce bo w naszym pierwotnym celu są same błyszczące Maci
  5. Bingo, złapaliśmy klienta otwierającego stronę banku. Dla niego wszystko wygląda w porządku, jest https, jest zielona kłódeczka a przeglądarka nie ma żadnych podejrzeń. Dopiero jak gość będzie bardzo dociekliwy to okaże się, że certyfikat uwierzytelniający bank wystawił Dell a nie Verisign. My sobie po drodze cały ruch odszyfrowujemy, podmieniamy numery kont (bo kto to sprawdza w smssach) i jesteśmy szczęśliwi.

Problem pojawia się kiedy zdamy sobie sprawę, że nie tylko my możemy tak zrobić a nasi użytkownicy na pewno nie sprawdzają za każdym razem kto wystawił certyfikat stronie i możemy się założyć, że kwestią czasu jest kiedy wypłyną dane z naszej firmy albo ktoś dostanie karnego na Facebook’u. A co jeśli nie tylko Dell i Lenovo mają problem z certyfikatami? Będziemy czekać na białe kapelusze aż opublikują artykuły i łatać za każdym razem licząc na to, że czarne kapelusze nie wkroczyły jeszcze do akcji? A może pójdziemy o krok dalej i będziemy bardziej proaktywni sprawdzając czy mamy jakiekolwiek podejrzane certyfikaty na naszych komputerach?

Teoria mówi, że żaden certyfikat znajdujący się w Trusted Root Certification Authorities nie powinien mieć klucza prywatnego. Gdzieś daleko od nas jest CA a my jemu ufamy ponieważ znamy klucz publiczny CA pasujący do klucza prywatnego używanego do podpisywania certyfikatów. Tyle teorii, praktyka okazuje się być trochę bardziej brutalna ale o tym później.

Kiedy mamy problem z pomocą przychodzi korporacyjna nowomowa i nagle problem staje się on wyzwaniem, a kto nie lubi wyzwań? Do tego jeszcze można zaprzęgnąć lubianego PowerShell i System Center lubiane … inaczej ;)

Zaczynamy od kawałka banalnego kodu:

foreach($BaseStore in Get-ChildItem cert:\)
{
   Get-ChildItem $BaseStore.PSPath -Exclude "My","Remote Desktop","SMS" |ForEach-Object{
      [array]$comptmp = Get-ChildItem $_.PSPath |Where-Object {
         $_.HasPrivateKey `
         -and $_.Subject -notmatch 'DO_NOT_TRUST_FiddlerRoot' `
         -and $_.Subject -notmatch $env:COMPUTERNAME
      }
   [array]$Compromised += $comptmp
   }
}
if($Compromised.Count -eq 0){
   return "Compliant"
}
else
{
   $output = ($Compromised | Out-String)
   return $output
}

Który przeleci nam po wszystkich dostępnych certificates stores wyłączając z tego:

  • My – certyfikaty użytkownika/komputera
  • Remote Desktop – to chyba nie wymaga tłumaczenia
  • SMS – certyfikaty używane przez klienta SCCM

w tym kroku można się pokusić jeszcze o wyłączenie innych rzeczy (np. certyfikatów klienta SCOM) albo zamianę

Get-ChildItem $BaseStore.PSPath -Exclude "My","Remote Desktop","SMS"

na

Get-ChildItem $BaseStore.PSPath -Include "Root"

żeby zaglądać tylko do Trusted Roots. Na razie trzymajmy się pierwszej wersji żeby zobaczyć co się w ogóle dzieje.

 

Jak już wiemy jakie mamy Certificates Stores to warto do nich zajrzeć i zobaczyć jakie mamy certyfikaty z kluczami prywatnymi

[array]$comptmp = Get-ChildItem $_.PSPath |Where-Object {
     $_.HasPrivateKey `
     -and $_.Subject -notmatch 'DO_NOT_TRUST_FiddlerRoot' `
     -and $_.Subject -notmatch $env:COMPUTERNAME
}

żeby uniknąć szumu wywalamy:

  • certyfikat Fiddlera – jego celem jest robienie MiTM i osoby mające go na komputerach wiedzą co robią
  • certyfikat zawierający z temacie nazwę hosta – tak to ciągle jest niebezpieczne ale wiemy, że ten certyfikat mamy tylko my i ewentualnie ktoś kto go nam wygenerował a nie cały internet. Takie świństwa podrzuca na przykład Skype ze skonfigurowanym Click to call

Reszta to proste działania mające na celu sprawdzenia czy mamy jakiekolwiek podejrzane certyfikaty i podanie ich listę lub potwierdzenie, że komputer jest ok.

 

Kiedy mamy już PowerShell to warto byłoby uruchomić go na wszystkich komputerach i sprawdzić kto ma coś podejrzanego na swojej maszynie. Fajnie byłoby też aby sprawdzanie odbywało się cyklicznie i informowało nas kiedy jest coś nie tak. Tutaj przydaje się SCCM i Compliance Settings.

Tworzymy Configuration Item uruchamiające skrypt i sprawdzające co jest na wyjściu

Configuration item

2015-12-08_21-47-13

Compliance Rules

2015-12-08_21-47-35

Compliance Rule

Potem robimy Configuration Baseline, dodajemy do niego nasz Configuration Item i robimy Deploy na kolekcje użytkowników oraz na kolekcje komputerów (odpowiednio All Users i All Systems). Ostatnie może się wydać trochę dziwne ale jest potrzebne żeby sprawdzić zarówno co mają użytkownicy jak i konto local system. Configuration baseline uruchomiony w kontekście systemu (Deploy na kolekcję komputerów) nie może zajrzeć do certyfikatów użytkowników bo te są trzymane w profilach*, a użytkownicy nie mogą zobaczyć jakie certyfikaty ma konto local system, za to zarówno użytkownik jak i local system mogą sprawdzić zawartość Certificate Store: Local Machine.

*-to nie jest do końca prawda bo można podmontować Hive i dekodować certyfikaty ale są na to prostsze sposoby

Jakby ktoś się pokusił dodatkowo o Remediation script żeby usuwać podejrzane certyfikaty to warto pamiętać, że Local System będzie mógł usuwać certyfikaty zarówno swoje jak o Local Machine a użytkownik będzie mógł usuwać wyłącznie swoje.

Na koniec pozostaje skonfigurowanie alertów, wysyłanie ich do SCOM i workflow do obsługi zdarzeń ale to już temat na osobny wpis.

 

migracyjna zagadka z certyfikatami

staram się nie wpisywać tego, co się nie da, a raczej rozwiązania, ale tym razem się poddałem – częściowo z braq czasu, ale generalnie nie zmęczyłem tematu. a ciekawostka jest taka:

po migracji użytkowników i kompów między domenami, zaczęły się pojawiać problemy z dostępem do niektórych stron. IE [mówiłem, że nie lubię tego produktu?] pokazuje standardowy błąd, dokładnie taki, jak przy braq komunikacji sieciowej. otwarcie w niekoszernej przeglądarce pokazało od razu problem z certyfikatem użytkownika.

ciekawostka na boq: otwarcie certmgr.msc wymaga uprawnień admina /: bardziej ogólnie – uruchomienie mmc wymaga uprawnień admina…

kiedy otworzy się widok certyfikatów [Internet Options -> Content -> certificates]… wszystkie certyfikaty są i pokazują, że posiadają prawidłowe klucze prywatne O_o

rozwiązanie jest trywialne – wystarczy wyexportować cert i zaimportować z powrotem. oznacza to, że cert jest ok, klucz prywatny ok… tylko gdzieś gubiony jest jakiś kawałek informacji – ale nie udało mi się odnaleźć o co c’mon…

eN.

PKI – a nie mówiłem…?

ROTFLMAO – tak można podsumować wtopę, jaką zaliczył eMeS w ten weekend. a w zasadzie od piątq. cała chmura Azure wyparowała. dosłownie *cała*. od usług komercyjnych, darmowych, xbox… a wszystko przez… nieodświeżony certyfikat!

o tym, że PKI jest sztuką zanikającą i dla większości wdrożeń nazwa “PKI” jest mocno na wyrost, pisałem całkiem niedawno. ale to co się wydarzyło ciężko nawet komentować, więc zamiast się nabijać kilka wniosqw dla nas wszystkich:

  • CERTYFIKATY SĄ WAŻNE. jak widać – jeden zły cert i cała wielka machina może zdechnąć.
  • to, że nie dzieje się tak w innych firmach wynika z faktu, że każdy zna trywialim “bezpieczeństwo jest bardzo ważne/najważniejsze” ale środowisko konfiguruje się przeciwnie. ponieważ niewiele osób certyfikaty rozumie, aby sobie nie utrudniać życia, wszystko konfiguruje się tak, żeby “niewadziły”. czyli używa się self-signów, wyłącza się weryfikację CRL, pozwala się na połączenia pomimo braku poprawnej walidacji itd. czyli jakiś cert jest, jakieś szyfrowanie jest i wszyscy skaczą szczęśliwi że mają PKI i super bezpieczeństwo.
  • w Windows od zawsze brakowało automatu, przypominającego o wygasającym certyfikacie. taka funkcjonalność została dodana – AFAIR w Vista, jednak trzeba się lokalnie zalogować na serwer/stację, aby komunikat zobaczyć. tam, gdzie PKI jest istotne – jak np. główny cert firmy czy jakiejś aplikacji Web – admin powinien od razu wrzucić jakieś przypomnienie do kalendarza…

zamiast ustawiać przypomnienia na konkretne daty, co jest mało elastyczne z 1ooo powodów, warto byłoby zrobić coś bardziej uniwersalnego. na szybko – skrypt, który sprawdza wszystkie certy w computerMY i jeśli data jest powżej 6o% czasu życia, wysyła maila z informacją. skrypt można by wrzucić do do schedulera na serwerach. trzeba będzie nad tym pomyśleć…

eN.

Hyper-v replication–konfiguracja

podczas konfiguracji Hyper-V replication można natrafić na wiele niespodzianek. teoretycznie jest to trywialne w konfiguracji – w praktyce artykuły są niepełne i wprowadzają w błąd. podstawowy jaki można znaleźć już zamieszczałem:

teraz testowałem konfigurację cluster-to-cluster i dwie ciekawostki:

  • teoretycznie usługa broker potrzebna jest na docelowym klastrze. niemniej trzeba ja zainstalować również na źródłowym – ponieważ jest tak dziwnie zaprojektowane, że będzie przedstawiać się FQDN’em CAP zasobu brokera [jego nazwą i IP]. żeby było ciekawiej – sam zasób brokera oraz obiekt CAP w AD można wyłączyć a nadal będzie działać /:
  • podczas generowania certyfikatu na replika-serwerze trzeba dodać SAN dla nazw obu węzłów klastra. czyli certyfikat musi mieć:
  • nazwę z CN dla brokera
  • nazwy wszystkich węzłów jako alternate name
  • takiego certyfikatu nie da się wygenerować makecertem – nie obsługuje alternate names. jedymym obejściem przy self-signed jest wygenerowanie certyfikatu wildcardowego.
  • jeśli na klastrze repliki będzie cert tylko z nazwą brokera, podczas konfiguracji Hyper-V replica pojawi się błąd:

    connection with the server could not be wstablished (0x00002EFD)

    HV connot connect to specified Replica server '<NODE-A>’. Error: A connection with the server could not be established (0x00002EFD). Verifiy that the specified server is enabled as a Replica server, allows inbound connection on port 443 and supports the same authentication scheme

    ten błąd jest dość mylący i dopiero rzut okiem do eventlogu wskazuje prawdziwy problem – brak obsługi na drugim węźle ze względu na certyfikat.

    eN.

    certyfikaty – takie tam ciekawostki

    kilka drobiazgów na które ostatnio natrafiłem…

    • self-signed certificate wcale nie musi być taki bardzo 'self’. w niektórych scenariuszach [np. hyper-v replication] najpierw tworzy się self-signed rootCA a potem za pomocą tego certu tworzy się kolejne. takie odzwierciedlenie prawdziwej struktury serwerów. wady pozostają – oczywiście nie ma w nich CDP i AIA więc są nieweryfikowalne
    • można ominąć takie wydumane struktury zaufania. można wygenerować pojedynczy self-signed i dodać go zarówno do computerMy oraz do Trusted Root CAs – dzięki temu będzie samo-weryfikowalny (;
    • z jakiegoś powodu nie dodano do systemu makecert’a – dziwne. od w2k8 [w końcu!] nie trzeba instalować reskitów i support toolsów bo niemal wszystko co potrzebne jest w systemie. brak makecerta jest imho niedopatrzeniem
    • w w8/2o12 jest cmdlet new-selfsignedcertificate. niestety bardzo prymitywny – można za jego pomocą wygenerować najprostsze certy SAN [subject alternative name]
    • w w8/2o12 pojawił się [w końcu!] dodatkowy snap-in dla cert store komputera: certlm.msc

    jakie widziałem certy z najdalszą datą ważności? standardowo AD wystawia cert dla admina do szyfrowania EFS na 1oo lat. sporo. niemniej przy okazji ostatniego grzebactwa trafiłem na cert wygenerowany przez Windows Server 2o12… nie udało mi się ustalić przy jakiej okazji. to selfsigned zrobiony na potrzeby jakiejś usługi [jakiej?]:
    cert 3o12
    trzeba ustawić sobie w kalendarzu na kwiecień 25o6, żeby go odnowić…

    ale trafiłem na rekordzistę chyba nie do pobicia. certy generowane przez SharePoint:
    SP certificate

    eN.

    Replikacja Hyper-V – url revocation list check failed

    wraz z ws2o12 i nowym Hv v3 jest możliwość replikowania maszyny na zdalnego hosta. najbardziej interesujący scenariusz to replikacja hostingowa – jest sobie firma, która outsource’uje usługi IT i chce, aby ich maszyny były dodatkowo zabezpieczone. do tej pory wymagało to tworzenia całkiem wymyślnych struktur – VPNy, trusty, skomplikowane procedury recovery czy inne wynalazki. teraz scenariusz jest trywialny:

    • no owszem.. jakiś VPN czy inna komunikacja jest niezbędna
    • Hyper-v v3 u klienta i Hyper-v v3 w ośrodku hostującym
    • brak trustów, jakichkolwiek innych związqw między domenami. jedyny mechanizm uwierzytelniający to certyfikaty zdefiniowane po obu stronach. de facto cross-trust między rootCA choć wystarczy na wybranych serwerach

    jakie jest PKI każdy widzi (; CRLe często-gęsto są niedostępne. w labie z kolei łatwiej byłoby zrobić na selfsign’ach a nie bawić się w stawiania CA. a więc kilka tricków z pola walki:

    • do generowania certów można użyć makecert. niestety, pomimo że ma tylko 37kb nie ma go w systemie /: trzeba ściągnąć i zainstalować kilqGB SDK do Windows. LoL. albo sięgnąć po tego linka.
    • łatwo znaleźć art, w którym krok po korq opisana jest cała konfiguracja łącznie z poleceniami dla makecert – które są trudne i łatwo się pomylić. więc to bardzo ładnie, że ktoś to tak zacnie opisał
    • jest nawet polecenie w rejestrze wyłączające weryfikację CRLi. i tu się zaczyna problem, ponieważ on nie działa. ktoś zapomniał dopisać jeszcze jednego wpisu w rejestrze:
      reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\FailoverReplication" /v DisableCertRevocationCheck /d 1 /t REG_DWORD /f
      reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Replication" /v DisableCertRevocationCheck /d 1 /t REG_DWORD /f

      ten wpis jest potrzebny zarówno przy clustrze jak i bez niego. kluczowa informacja

    • zmiany działają natychmiast i nie wymagają restartów – a więc jeśli nadal pojawia się błąd, to należy sprawdzić czy wartości są poprawnie wprowadzone do obu kluczy

    eN.

    brak szablonów certyfikatów v2

    ha! tydzień rozwiązywania problemów (: wakacje to jednak piękna rzecz – to kolejna wyjaśniona tajemnica w krótkim czasie. tym razem trafił się serwer Enterprise RootCA. PKI to od jakiegoś czasu moje hobby [dzięki Pauli *] więc nie odpuściłem:

    • pojedyncze Ent root CA jako issuing. standardowa 'zwalona’ instalacja u klienta czyli 'wsadził-wyjął-PKI’. no co zrobić – tak jest i trzeba z tym póki co żyć
    • serwer w wersji w2k8 R2 standard
    • po utworzeniu nowych szablonów, których jakoś nikt do tej pory nie zrobił, nie można ich dodać do publikacji na CA

    podczas próby wyszukania jakiejś pomocy wszystkie linki dotyczyły podstawowego błędu – szablony w wersji v2 i v3 nie są obsługiwane przez wersję standard, wymagany jest enterprise. tyle, że od wersji w2k8 R2 ten limit zniesiono. żeby się upewnić postawiłem sobie wirtualkę w2k8r2std, na niej CA i na szybciorka upewniłem się, że spokojnie obsługuje v2 i v3. po długim debugowaniu w końcu znalazłem:

    • atrybut 'flags’ dla obiektu 'CN=MYCANAME,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=DOMAIN,DC=AD’ na partycji konfiguracji zawierał wartość '2′

    znaczenie tego atrybutu to:

    • 2„: Enterprise CA running on Standard Edition
    • 10„: Enterprise CA running on Enterprise Edition
    • 5„: Standalone CA running on Standard Edition
    • 9„: Standalone CA running on Enterprise Edition

    prawdopodobnie maszyna była upgradowana z wersji Windows 2oo8 std a instalator nie modyfiqje takich rzeczy. pomyślałem, że to on dyktuje dostępność szablonów i trafiłem – na wirtualce, pomimo wersji std, atrybut ustawiony był na '1o’. zmiana na produkcji, replikacja, restart usługi – voila! ^^

    refs:

    eN.