Do Not Forward – czy to działa?

Problem

  • W Microsoft Purview, można zdefiniować Sensitivity Label 'Do Not Forward’. Potencjalnie bardzo fajna opcja do zabezpieczenia maila
  • Problem polega na tym, że jeśli w mailu jest plik, to zależnie od tego czy odbiorca ma konto pocztowe 3rd party czy M365 – osoba będzie w stanie plik otworzyć lub nie… i poszkodowana jest osoba posiadająca konto M365!

Wewnętrznie na EXO istnieją dwa workflowy:

  • OTP, dla kont, które nie są RMS-aware (3rd party), klient dostaje link 'pobierz kod’, kod przychodzi na zadeklarowany email i dzięki temu osoba ma dostęp do maila oraz pliku.
  • RMS-aware czyli M365. Microsoft chwali się, że usługa działa cross-tenant… ALE – musi być ALE.

Tutaj link opisujący cross-tenant: Microsoft Entra configuration for content encrypted by Microsoft Purview Information Protection | Microsoft Learn . W praktyce działa to tak (zakładając default configuration), że wiadomość 'Do Not Forward’ faktycznie można odczytać beż żadnych kodów przez posiadacza skrzynki EXO. Ale pliku nie da się otworzyć w żaden sposób… chyba, że zrobimy to tak, jak pisze MS:

”

  • For external users who have a Microsoft Entra account in their own tenant, we recommend you use External Identities cross-tenant access settings to configure trust settings for MFA claims from one, many, or all external Microsoft Entra organizations.
  • For external users not covered by the previous entry, for example, users who don’t have a Microsoft Entra account or you haven’t configured cross-tenant access settings for trust settings, these external users must have a guest account in your tenant.

”

…i cały wspaniały plan łatwego dostarczenia rozwiązania szyfrującego idzie w diabły. Bo kto będzie wszystkim ludziom zakładał konta gości? nie tak miała ta usługa ułatwiać życie – no i co za absurd, że użytkownicy nie-M365 mogą się dostać a M365 nie mogą.

Ale oczywiście nie pisałbym, gdyby nie dało się tego obejść…

Rozwiązanie

Okazuje się, że tym szablonem można zarządzać. Wybiera go Purview, które na ostatnim etapie mail flow, dodaje własne reguły transportowe (niewidoczne) – jeśli email ma jakieś Sensitivity Labels, to usługa dokona odpowiednich modyfikacji, sprawdza typ routingu i wybierze szablon – inny dla EXO, inny dla 3rd party. Tutaj nie da się nic zrobić, ponieważ całość jest black-box.

Ale da się:

  • Stworzyć label o jakiejś nazwie – np. 'Secure Email’, który nic nie robi poza oflagowaniem maila
  • ustawić dwie reguły transportowe na EXO – dla maila z i bez załącznika – dla tej etykiety

W efekcie mamy takie scenariusze dla maila z Do Not Forward (Secure Email):

  • do użytkownika non-M365 z lub bez załącznika: użyj szablonu OTP
  • do użytkownika M365 z załącznikiem: użyj szablonu OTP (inaczej nie ma szansy podejrzeć pliku)
  • do użytkownika M365 bez załącznika: użyj cross-tenant RMS, bo wiadomość się wyświetli

te reguły to:

New-TransportRule `
    -Name "Label secure external mail - Do Not Forward via OME portal" `
    -FromScope "InOrganization" `
    -SentToScope "NotInOrganization" `
    -HeaderContainsMessageHeader "msip_labels" `
    -HeaderContainsWords "MSIP_Label_<LABEL GUID>_Enabled=True" `
    -ApplyRightsProtectionTemplate "Do Not Forward" `
    -ApplyRightsProtectionCustomizationTemplate "OME Configuration"

New-TransportRule `
    -Name "Secure Email external WITHOUT business attachment - DNF native" `
    -FromScope "InOrganization" `
    -SentToScope "NotInOrganization" `
    -HeaderContainsMessageHeader "msip_labels" `
    -HeaderContainsWords "MSIP_Label_<LABEL GUID>_Enabled=True" `
    -ApplyRightsProtectionTemplate "Do Not Forward"

Żeby zdobyć GUID najlepiej użyć get-label, tylko najpierw trzeba się połczyć connect-iPPSSession.

> connect-iPPSSession -UserPrincipalName nexor@w-files.pl
> get-label|select name,guid
[...]

A jeśli ktoś byłby chętny modyfikować szablon [OTP/native, disclaimers, images…] to jest to szablon 'OME Configuration’:

> get-oMEConfiguration|fl

TemplateName : OME Configuration
Image :
ImageUrl :
EmailText :
PortalText :
DisclaimerText :
BackgroundColor :
IntroductionText :
ReadButtonText :
OTPEnabled : True
SocialIdSignIn : True
ExternalMailExpiryInterval : 00:00:00
PrivacyStatementUrl :
Identity : OME Configuration
IsValid : True
ObjectState : Unchanged

I ten właśnie default jest użyty w pierwszej regule, z parametrem 'OTPEnabled: True’.

Rebranding a nazwa usługi

To jedna z tych usług w stajni Microsoft, która po pierwsze od zawsze jest zaniedbana, i jak gorący kartofel – przechodzi rebranding co kilka lat. A podstawowe funkcjonalności – jak widać w tym scenariuszu – są często zaparkowane na zawsze. Po raz pierwszy wdrażałem RMS na Server 2oo8 – właśnie mniej-więcej w roku wydania serwera. Niemal dwie dekady, a usługa cały czas boryka się z tym samym problemem – fajnie działa w obiegu firmowym, zamkniętym, gorzej z zastosowaniem powszechnym, tzw. publicznym Internecie. A co najciekawsze to zasadniczo wszystko działa i wszystkie elementy układanki są dostępne… tylko MS z jakiegoś powodu wymyślił 'zakładajcie wszystkim konta gości’ zamiast pójść po rozum i zmienić workflow /:

Co do historii nazw:

Rok Nazwa
2003 Windows Rights Management Services (RMS)
2008 Active Directory Rights Management Services (AD RMS)
~2013 Azure Rights Management (Azure RMS)
~2015-2019 Azure Information Protection (AIP)
~2019-2021 Microsoft Information Protection (MIP)
obecnie Microsoft Purview Information Protection (MPIP)

I na wszystkie te nazwy można cały czas natrafić podczas korzystania z produktu – np. do otwarcia zaszyfrowanego pliku należy zainstalować RMS Client – pewnie ze względu na to, iż tak cały czas nazywa się w środowisku on-premises, na Server 2o25. W chmurze natomiast czas nie stoi – dla tego dziś mówimy o Purview i Sensitivity Labels…

A więc zasadniczo, na dzień dzisiejszy: MPIP – Microsoft Purview Information Protection, korzystający z RMS do szyfrowania plików.

AI nie pomogło

Takie problemy to dobry benchmark AI – tutaj nie pomogło. Nie znalazłem rozwiązania wyszukiwarką, a AI, jak się okazało, nie było w stanie samodzielnie 'rozumować’ – skoro nie znalazło tekstu, to 'nie wymyśliło’ rozwiązania. Udało mi się przygotować to rozwiązanie tylko dla tego, że pracując tyle z Ex/EXO po prostu wiedziałem czego szukać i po kilku próbach udało się wydziargać rozwiązanie…

eN.

 

passwordless EXO connection

przeglądając ostatnio changelog dla commandletów ExchangeOnlineManagement znalazłem bardzo miłą informację.

po pierwsze w końcu PS dla EXO zaczyna się normalizować. po dziwnych zawirowaniach i wydania ExchangeOnline 1.0.1 określonej jako… V2, w końcu ktoś poszedł po rozum do głowy i dał i wersję 2.x . niby drobna rzecz, ale istotna, ze względu na przejrzystość.

ponadto, pomimo że GraphAPI dla EXO jeszcze nie ma, dostarczony został [trochę wydrutowany, ale zawsze] sposób, na bezhasłowe połączenie do konsoli. nie wymaga to zbyt dużo gimnastyki, a pozwala na tworzenie skryptów w trybie nienadzrorowanym [unattended].

eN.

EXO V2

muszę (przynajmniej częściowo) odszczekać to, co pisałem w nie tak dawno temu – konkretnie część dotyczącą ClickOnce dla Exchange Online. w końcu, po wielu cierpieniach pojawił się moduł EXO V2 – i to na chwilę przed wpisem, czyli moje przeoczenie. w końcu można normalnie zainstalować z repozytorium! co prawda konsola wita jeszcze w klimacie helloween, z dreszczykiem, ale i to powinno wkrótce się zmienić:

----------------------------------------------------------------------------
Due to a security issue, this version of client module will be deprecated and stop working after 8 Jan,2020. Please update to latest version on or after 8 Jan, 2020.
----------------------------------------------------------------------------

nie tylko instalacja jest doprowadzona do normalności, ale pojawiło się wiele nowych commandletów. osoby pracujące z EXO na pewno odetchną z ulgą (:

eN.

 

Migracja w hybrydzie – zakończenie pojedynczej skrzynki w zadaniu synchronizacji

ciekawostka, bo wszyscy piszą, że się nie da… a się da.

jeśli założy się zadanie migracyjne Ex-EXO w którym jest wiele kont, to można potem usunąć pojedynczą skrzynkę użytkownika, ale nie bardzo jest sposób na to, żeby tylko jedną skończyć. jeśli jednak się przyjrzeć w jaki sposób działa parametr 'AutoComplete’ dla wsadu migracji, sprawa okazuje się oczywista.

korzystając z PowerShell, jeśli chcemy zsynchronizować skrzynki ale ręcznie ustalić kiedy mają się przełączyć wygląda to np tak:

$binBatch=[System.IO.File]::ReadAllBytes($bPath)
$mbParam=@{
    name="transza01";
    AutoComplete=$false;
    AutoStart=$true;
    badItemLimit='50';
    CSVData=$binBatch;
    SourceEndpoint='MigrationEndPoint';
    TargetDeliveryDomain='w-files.pl'
} 
New-MigrationBatch @mbParam

gdzie opisywanym parametrem jest oczywiście 'AutoComplete’. ale kiedy podejrzy się potem takie zadanie – gdzie to sobie siedzi? jeśli posłużymy się get-migrationUser żeby to znaleźć – nie bardzo się uda. parametr jest dziedziczony z całego wsadu, stąd może wydawać się niemożliwe ukończenie pojedynczej skrzynki. jeśli jednak wyświetli się i sprawdzi w jaki sposób jest to de facto zrealizowane, to rozwiązanie nasuwa się samo. tak na prawdę dla całego zadania ustawiany jest atrybut 'completeAfter’ na jakąś chorą datę – w tym przypadq wyjątkowo szybko:

PS C:\_scriptZ> Get-MigrationBatch -Identity transza01|select completeAfter*

CompleteAfter CompleteAfterUTC
------------- ----------------
01.01.4501 00:00:00 01.01.4501 00:00:00

wyjątkowo szybko, bo zazwyczaj widzę 31.12.9999 . z jakiegoś powodu tym razem czas został kapkę skrócony, ale i tak jestem zbyt niecierpliwy, żeby czekać tyle czasu (;

…a zatem aby skończyć pojedynczą synchronizację wystarczy ustawić jej czas 'completeAfter’ na obecny. korzystam z jednej z dwóch metod:

set-migrationUser <user-email> -CompleteAfter ((get-date).ToUniversalTime())

lub

set-migrationUser <user-email> -CompleteAfter ((get-date).AddDays(-1))

ustawiając datę z przeszłości – jeśli chcę mieć 1oo%, że to nie chodzi o UTC. nie porównywałem czy efekt jest identyczny. przez jakiś czas nic się nie dzieje (statystyki nie pokazują statusu jako 'completing’), ale po ok 1h skrzynka jest 'completed’.

eN.

Uruchamianie usług chmurowych w hybrydzie

Usługi czyli EXO (Exchange Online) i SOL (Skype for Business Online). Problem w hybrydzie polega na tym, że nie można skorzystać z interfejsu portal.office.com – należy konta założyć w środowisq onprem. i oczywiście prostą odpowiedzią byłoby skierowanie do commandletów Exchange i SfB w onprem… ale po co wtedy byłby wpis?

Scenariusz

zakładamy konto użytkownika i chcemy aby od razu miał skrzynkę w EXO i uruchomione usługi SOL. można założyć całość w onprem a potem migrować… ale to straszna strata czasu i wysiłq.

Standardowo

niemniej zacznę od standardowej metody, ponieważ tak to się robi oficjalnie.

po założeniu konta w AD, należy wykonać enable-RemoteMailbox – opis polecenia oraz doqmentacja do hybrydy. następnie trzeba włączyć konto SOL poleceniem enable-CSUser, a sztuczka polega na dodaniu parametru  „-HostingProviderProxyFqdn sipfed.online.lync.com”.

problem z tym rozwiązaniem jest taki, że żeby założyć konto potrzebne są aż trzy różne moduły: Active Directory, Exchange oraz Skype for Business. Prawidłowo administracja powinna być tak zorganizowana, że administratorzy logują się na stację zarządzającą, gdzie mają wszystkie narzędzia zainstalowane – w szczególności te wymienione. i oczywiście sugerowałbym aby tak to się odbywało. jednak… życie pisze własne scenariusze, np. taki, że jest sobie system HR, z którego wypływają dane o użytkownikach. i jak developer ma sobie z tym poradzić? do LDAP dość łatwo się dostać i są do tego standardowe biblioteki w samym frameworq, a do Ex czy SfB już tak różowo nie jest.

HACKED

….podam sposób, jak można założyć mailbox i włączyć SIP, wyłącznie przy pomocy modułu Active Directory/dostępu do LDAP. zaletą takiego rozwiązania jest brak konieczności instalacji pozostałych – i to właśnie był czynnik, który zmusił mnie do zrobienia takiego rozwiązania. zacznę od przestrogi:

zaprezentowane rozwiązanie nie jest wspierane, a konsekwencje użycia mogą być ciężkie do przewidzenia – dla tego przetestuj dokładnie, upewnij się, że rozumiesz co robisz i jak to działa tak, aby w razie co być w stanie naprawić. pełne commandlety wykorzystują mechanizmy sprawdzające poprawność ustawianych wartości, czy nie występują duplikaty w domenie, i wiele innych, których tutaj nie ma – a więc można namieszać. korzystasz na własną odpowiedzialność.

no to jak już się przestraszył[ae]ś, to teraz rozwiązanie.

w zasadzie najważniejszym trikiem jest zrozumienie jak działa hybryda – wszystkie zmiany wprowadzane są w onprem i synchronizowane do chmury. czyli wskazane polecenia – enable-RemoteMailbox czy enable-CSUser – wbrew temu co możesz sądzić, w żaden sposób nie łączą się z Office365. jedyne co robią, to modyfiqją wartości atrybutów w AD. w związq z tym można napisać skrypt, który dokładnie to zrobi.

nie będę zamieszczał całego skryptu – są w nim elementy specyficzne dla konkretnego klienta – ale wszystko co niezbędne znajdziesz poniżej.

Exchange

atrybuty, które należy zmodyfikować mogą się różnić, zależnie od klienta – wiadomo, różne firmy mają różne wymagania. poniżej zestaw atrybutów 'podstawowych’:

    $EXOattributes=@{
        'mail'=$oUser.UserPrincipalName
        'mailNickname'              =$oUser.SamAccountName
        'msExchPoliciesExcluded'    =@('26491cfc-9e50-4857-861b-0cb8df22b5d7') #disable automatic email address creation
        'msExchRecipientDisplayType'='-2147483642'
        'msExchRecipientTypeDetails'='2147483648'
        'msExchRemoteRecipientType' ='1'
        'msExchUMDtmfMap'           ="" 
        'msExchVersion'             ="44220983382016" #Ex2010 ; Ex13 = "88218628259840" ; Ex16 = "1125899906842624"
        'proxyAddresses'            ="" 
        'showInAddressBook'         ='CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,CN=LOGICUNION,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=LOGICUNION,DC=LAB'
        'targetAddress'             ="SMTP:$($oUser.SamAccountName)@LogicUnion.mail.onmicrosoft.com"
    }

to, co widać powyżej, to oczywiście zestaw atrybutów obiektu User w AD, niezbędnych do założenia skrzynki.

  • mail: $oUser to obiekt użytkownika, pobrany wcześniej jako „$oUser=get-aduser <name> -properties *”. tutaj założenie jest, że podstawowy email jest taki sam jak UPN
  • mailNickname: standardowo jest taki sam jak SAM
  • msExchPoliciesExcluded: jeśli chcę ustawiać adresy email ręcznie to wskazana polisa (GUID taki sam dla każdego Ex) jest odpowiednikiem odznaczenia 'Automatically update email addresses…’ . jeśli adresy będą się wypełniały standardowymi polisami, to można pominąć
  • msExchangeRecipient*: wskazują na typ skrzynki. szczegóły tutaj. ogólnie – wskazuje, że skrzynka typu RemoteUserMailbox ma być założona
  • msExchUMDtmfMap: będzie za chwilę wypełnione – funkcja poniżej. de facto chodzi o konwersję na cyferki z cyferblatu telefonu, fragment UC.
  • msExchVersion: jest zawsze taka sama, i pochodzi z onpremowego Exchange. można sobie zweryfikować z jakimś lokalnym kontem
  • proxyAddresses: to oczywiście aliasy. jeśli ustawiamy inne niż podstawowy, warto nie zapomnieć wyłączyć polisy msExchPoliciesExcluded…
  • showInAddressBook: to CN list adresowych, w których ma się pojawić. tutaj standardowa lista globalna. ten CN można odczytać z innego użytkownika.
  • targetAddress: bardzo ważne pole, wskazujące na przekierowanie do chmury. na jego podstawie robiony jest routing do chmury na connectorze.

zmienna jest typu hashtable, można więc sobie powyliczać np. proxyaddresses, poustawiać co potrzeba. np. DTMF. funkcja, która konwertuje ciągi do DTMF:

function convert-str2dtmf {
    param(
        [char[]]$str
    )
    $dtmfCodes=@{
        "a"=2;
        'b'=2;
        'c'=2;
        'd'=3;
        'e'=3;
        'f'=3;
        'g'=4;
        'h'=4;
        'i'=4;
        'j'=5;
        'k'=5;
        'l'=5;
        'm'=6;
        'n'=6;
        'o'=6;
        'p'=7;
        'q'=7;
        'r'=7;
        's'=7;
        't'=8;
        'u'=8;
        'v'=8;
        'w'=9;
        'x'=9;
        'y'=9;
        'z'=9;
    }

    $dtmfOut=""

    foreach($letter in $str) {
        $letter=([string]$letter).ToLower()
        if($dtmfCodes.ContainsKey($letter) ) { $dtmfOut+=$dtmfCodes[$letter] }
    }
    return $dtmfOut
}

i fragment kodu, który ustawia DTMF:

    $dtmfEmail=convert-str2dtmf -str $oUser.SamAccountName
    $dtmfLNFN=convert-str2dtmf -str "$($oUser.sn)$($oUser.givenName)"
    $dtmfFNLN=convert-str2dtmf -str "$($oUser.givenName)$($oUser.sn)"
    $EXOattributes.msExchUMDtmfMap=@("emailAddress:$dtmfEmail","lastNameFirstName:$dtmfLNFN","firstNameLastName:$dtmfFNLN")

zmienna jest tablicą zawierającą zazwyczaj trzy elementy w zapisie DTMF – adres email [a w zasadzie nazwa użytkownika – bez domeny], nazwa użytkownika 'lastNameFirstName’ oraz 'firstNameLastName’. a więc wyliczam przy pomocy funkcji konwertującej i paqję do zmiennej $EXOattributes.

kiedy $EXOAttributes zawiera wszystko to, co potrzebne, pozostaje pchnięcie tego do AD. i tutaj piękno i prostota PS:

 Set-ADUser -Identity $oUser.SamAccountName -replace $EXOattributes

i już. atrybuty są wypełniane, zsynchronizuje się do o365, a ten podejmie odpowiednie działania – czyli założy skrzynkę.

SOL

całość wykonuje się analogicznie – buduję hashtable, który potem pchnę do AD, a poniżej niezbędne atrybuty dla Skype for Business Online:

    $SOLAttributes=@{
        'msRTCSIP-DeploymentLocator'    ="sipfed.online.lync.com"
        'msRTCSIP-FederationEnabled'    =$True
        'msRTCSIP-InternetAccessEnabled'=$True
        'msRTCSIP-OptionFlags'          ='257'
        'msRTCSIP-PrimaryHomeServer'    ='CN=Lc Services,CN=Microsoft,CN=1:1,CN=Pools,CN=RTC Service,CN=Services,CN=Configuration,DC=LogicUnion,DC=Lab'
        'msRTCSIP-PrimaryUserAddress'   ="sip:$($oUser.UserPrincipalName)"
        'msRTCSIP-UserEnabled'          =$true
    }

te zbudowane są dla środowiska sfederowanego, gdzie po stronie OnPrem stoi Lync 2o13. to może mieć znaczenie dla atrybutu msRTCSIP-PrimaryHomeServer – ponieważ nie wiem czy tak samo wygląda CN usługi SfB.

dla 'OptionFlags’ link z wyjaśnieniem wartości można znaleźć tutaj.

Set-ADUser -Identity $oUser.SamAccountName -Replace $SOLAttributes

zakończenie

jak wspomniałem, nie publiqję całego skryptu, ponieważ logika wyliczania czy to proxyaddresses czy innych elementów jest dla konkretnego środowiska i każdy musi sam to oprogramować. celem wpisu jest tak na prawdę pokazanie na czym polega 'od spodu’ założenie konta w EXO czy SOL w środowisq hybrydowym. niby każdy wie, że zmiany synchronizują się w jedną stronę, a jednak podczas rozmów, okazuje się, że wszyscy spodziewają się jakiejś dodatkowej komunikacji pomiędzy systemami. a tu nic takiego nie ma – jest tylko synchronizacja i tyle.

nie jest to zalecany sposób tworzenia… ale na pewno fajna zabawa (;

eN.

konsola EXO z MFA

PowerShell dla EXO to porażka, zwłaszcza z włączonym MFA. już sam fakt, że należy jej szukać w części 'hybrid’ nie jest logicznie wyjaśnialny. podstawowym problemem jest jednak zaszyty hard-limit czasu sesji na 15 min. teoretycznie to czas bez aktywności (idle), ale zdarza mi się, że działający skrypt się sypie… najbardziej doqczliwe było jednak to, że za każdym razem trzeba się uwierzytelniać i przy każdym kolejnym połączeniu ponownie importowane są commandlety, a dodając do tego MFA… zaczyna się robić na prawdę nieprzyjemnie.

szukałem po forach i po doqmentach i miałem na prawdę dziwne pomysły jak to rozwiązać… aż w końcu znalazłem rozwiązanie. dodam, że trywialne.

jeśli uruchomi się po prostu 'Connect-EXOPSSession’ … nie da się żyć. a wystarczy uruchomić z parametrem:

Connect-EXOPSSession -UserPrincipalName admin@w-files.onmicrosoft.com

i owszem, sesja nadal jest zrywana po 15 min ale następuje automatyczne ponowne uwierzytelnienie, bez konieczności wpisywania hasła czy potwierdzania drugiego składnika. nie są również ponownie importowane commandlety. w skrócie – w końcu da się pracować.

być może to tak oczywiste, że nikt o tym nie pisze. być może to było wielką czcionką na 'pierwszej stronie’. ale być może uratuję kogoś tym wpisem przed całkowitą utratą nerwów, czego byłem już kilka razy bliski przygotowując raporty z EXO.

eN.

Ograniczenia Exchange Hybrid

[updated]

pomimo, że hybryda Exchange jest dość typowym scenariuszem i to raczej docelowym środowiskiem dla większości większych firm, to niestety niesie ze sobą sporo ograniczeń. zwłaszcza w okresie migracji może to stanowić spory problem.

poniżej zebrane – nie wiem, czy wszystkie. ograniczenia dotyczą dostępu do skrzynek pomiędzy środowiskami (cross-premise)

  • nie działa 'automapping’ dla kont cross-premise. czyli jeśli osoba w chmurze ma dostęp do skrzynki współdzielonej onprem to musi dodać ją ręcznie we właściwościach – sama się nie zmapuje.
  • największe hece są z kalendarzami dla skrzynek cross-premise. po migracji traci się udostępnienie, a przy ponownym udostępnieniu nie widać detali. jednym z obejść problemów jakie znalazłem jest ponowne udostępnienie skrzynki.. ale z OWA. to nie wszystko! akceptacja też musi być z OWA. ciekawy opis tu.
  • bardziej ogólnie problem polega na tym, że nie wszystkie uprawnienia są obsługiwane dla scenariuszy cross-premise. zwłaszcza uprawnienia item-level. i chociaż na stronie jest informacja że 'sand as’ nie działa, to da się to zrobić.
  • nie ma dostępu do skrzynek archiwalnych dla cross-premise
  • właściciele grup nie mogą zarządzać grupami dystrybucyjnymi z Outlook. jako obejście można stworzyć skrót do narzędzia systemowego.

znasz inne?

eN.

Exchange hybrid – niespójność informacji

ogólnie synchronizacja jest jednostronna – z onprem do online. obiektami środowiska hybrydowego najlepiej zarządza się z onprem, ponieważ w o365 są tylko do odczytu… ale są pewne wyjątki, powodujące niespójność. przykładem może być konwersja skrzynki User<>Shared.

od momentu, kiedy skrzynka jest już w ExOL, o statystyki czy operacje na skrzynce, trzeba sięgać bezpośrednio. o ile get-recipient można uruchomić również onprem, o tyle np. konwersję typu należy przeprowadzić w ExOL. dodajmy do tego fakt, że synchronizacja jest w jedną stronę i…

…po konwersji skrzynki, jeśli uruchomimy get-recipient lokalnie, to pokaże nam typ z przed konwersji. w efekcie, jeśli takie operacje są wykonywane często, statystyki będą przekłamywane. należy więc po dokonaniu konwersji ręcznie zmodyfikować atrybuty w AD tak, aby odpowiadały obecnemu stanowi. trzeba przy tym uważać, bo nazwy są bardzo podobne i łatwo je pomylić:

 SharedMailbox UserMailbox
msExchRemoteRecipientType 100 6
msExchRecipientTypeDetails 34359738368 2147483648
msExchRecipientDisplayType -2147483642 -2147483642

szczegółowy opis parametrów tutaj

przykładowy link do dalszej lektury: http://jetzemellema.blogspot.co.uk/2016/02/convert-user-mailbox-to-shared-in.html

eN.

user@tenant.onmicrosoft.com w hybrydzie

każdy obiekt użytkownika w o365 w hybrydzie ma standardowo zakładane dwa adresy email:

  • user@tenant.mail.onmicrosoft.com – który służy jako email routingowy. EXO jest de facto oddzielnym środowiskiem, oddzielną organizacją Exchange, a więc jeśli jest email user@w-files.pl, musi istnieć sposób na przesłanie maila do konkretnego serwera – wtedy wykorzystywany jest ten adres.
  • user@tenant.onmicrosoft.com – który jest tworzony na podstawie standardowej polityki adresowej EXO. czy użytkownik jest synchronizowany, czy założony bezpośrednio – jest nadal mailboxem i podlega polityce.

istnieją różne scenariusze, w których chcielibyśmy zmienić istniejący adres – np. chcemy go zwolnić tak, aby mógł być wykorzystany dla innego obiektu. ale….

w środowisq hybrydowym wszystkie zmiany muszą być zrobione w on-prem. próba dokonania adresu bezpośrednio w EXO skończy się Acc Denied. ale…

jeśli wykonamy polecenie

get-remoteMailbox username|select emailaddresses

to zobaczymy adres routingowy user@tenant.mail.onmicrosoft.com ale nie będzie na liście adresu EXO /:

jak zatem go zmienić?

da się, ale wymaga nieco gimnastyki. skoro nie da się zmienić dla konta synchronizowanego to trzeba je uczynić na chwilę kontem lokalnym o365. a więc kroki są następujące:

  • przesunąć obiekt w on-prem AD do OU, które nie jest synchronizowane
  • wymusić/poczekać na synchronizację
  • konto w AAD zostanie usunięte wraz z mailboxem
  • odzyskać konto w AAD [np. restore-msolUser]
  • zmienić adres w EXO
  • przywrócić pierwotną lokalizację obiektu w AD
  • poczekać na synchronizację

jeśli konto zniknie przy pierwszym cyklu, może to wynikać z niepełnym sync w domenie on-prem. najlepiej wykonywać operacje na AD, z którego jest robiony sync do AAD.

eN.

to się nie powinno zdarzyć… [combo]

takiego przypadq w-files nie miałem od dawna. od początq do końca – same zagwozdki. a zaczęło się tak…

objawy i pierwsza diagnoza

użytkownik zgłasza, że niektóre maile kierowane do niego, wysyłane są … na prywatną skrzynkę innej osoby. środowisko w hybrydzie exchange a cała sprawa zadziwia, bo zgłoszenie jest od użytkownika onprem.

po krótkim debugowaniu udaje się ustalić, że w AAD użytkownik ma wypełniony atrybut 'otherMails’. czemu innego użytkownika to da się wytłumaczyć ale czemu Exchange wysyła maile korzystając z tego atrybutu?? czy to oznacza kompromitacją routingu Exchange? mocno niepokojące zachowanie..

schodzimy głębiej

po dalszym dochodzeniu udaje się ustalić kilka innych faktów. większość pominę, bo pomimo, że dały dużo pikanterii do sprawy, i mocno utrudniły całe dochodzenie wprowadzając w ślepe zaułki, sqpię się na najważniejszym. udało się ustalić, że to konto jest widziane jako 'GuestMailUser’ przez Exchange lub 'Guest’ w AAD. to już lepiej, ponieważ parę rzeczy da się wyjaśnić: Exchange używa właśnie atrybutu otherMails [który wbrew nazwie jest typu 'string’ a nie tablicą] do wysyłki, a to oznacza, że pomimo iż sytuacja jest co najmniej dziwna, to nie jest kompromitacja całego tenanta. udało zawęzić się grupę zagrożonych użytkowników do kilqnastu osób.

no to impas: w onprem AD nie ma nigdzie informacji z adresem zewnętrznym, a w o365 nie da się go usunąć, ponieważ obiekt jest synchronizowany, więc zmiany autorytatywnie mogą pochodzić tylko z AD.

dla niektórych użytkowników udaje się skonwertować obiekt na 'member’ poprzez „set-msoluser -userprincipalname <UPN> -userType member”

ale po wyświetleniu pełnego obiektu AAD „get-AzureADUser -searchstring <UPN>|fl” okazuje się, że w atrybucie proxyaddresses cały czas siedzi adres #EXT#. czyli konwersja obiektu jest obejściem problemu, ale niedostatecznym rozwiązaniem.

jak do tego doszło?

no dobra. sytuacja opanowana, maile nie wyciekają. ale jak to się w ogóle mogło zdarzyć?

jak zwykle w takich przypadkach, nie da się tego na 1oo% potwierdzić, ale scenariusz był najprawdopodobniej taki:

  • był sobie tenant, który nie był w pełni zsynchronizowany
  • projekt rozpoczął się od testu SharePoint, gdzie jacyś użytkownicy bawili się, testowali, licho-wie-co jeszcze.
  • ponieważ tenant nie był w pełni zsynchronizowany, ba! zmieniane były UPNy użytkowników, ktoś wysłał zaproszenie do zasobu na SP. użytkownik przyjął to zaproszenie, ale zamiast się zalogować jako user tenanta, zalogował się jako zewnętrzny użytkownik, podając firmowy email. został więc utworzony obiekt Guest, z mailem odpowiadającym mailowi firmowemu
  • po uporządkowaniu UPNów i wymuszeniu synchronizacji część obiektów się nie zsynchronizowała. ktoś popoprawiał obiekty z błędem tak, żeby zadziałał soft-match. teoretycznie podczas takiej operacji, obiekt synchronizowany z onprem, powinien 'nadpisać’ obiekt Guest i stać się Member. ale tak się nie stało…

co na to Microsoft i czy to się powtórzy?

sprawę oczywiście potwierdzałem ze wsparciem MS żeby mieć jakieś autorytatywne odpowiedzi. potwierdzili scenariusz jak do tego doszło, z zastrzeżeniem, że nie mają pełnych danych z tamtego okresu. sprawdzili jednak, że ktoś manipulował przy obiekcie zmuszając do spasowania z onpremowym.

kolejne zapewnienie jakie otrzymałem, to iż już jakiś czas temu wdrożony został patch, który chroni przed takimi sytuacjami – czyli w trakcie synchronizacji nie może w efekcie dojść do pozostawienia obiektu jako Guest. sytuacja jest tak trudna i ulotna, że nie podejmuję się weryfikacji.

mówiąc w skrócie: to się nie ma prawa powtórzyć.

grande finale

jedynym sensownym rozwiązaniem problemu jest usunięcie użytkowników z synchronizacji, wywalenie ze śmietnika i powtórna synchronizacja. drugim rozwiązaniem byłaby dalsza eskalacja we wsparciu tak, aby użytkownicy nie potracili dostępów [bo przecież ich konta zostaną usunięte i utworzone totalnie nowe obiekty], ale od razu zastrzegli, że to może nawet nie zostać zaakceptowane a na pewno długo potrwa.

no więc usunąłem z synchronizacji… ale na koniec czekała mnie jeszcze jedna niespodzianka. otóż nie byłem w stanie usunąć niektórych kont ze śmietnika. co ciekawe get-msolUser -ReturnDeletedUsers pokazywał, że są tam te obiekty.. ale przy próbie usunięcia wywalało błąd, że obiekt nie istnieje.

a więc na koniec ostatni w-files: po wyświetleniu atrybutów obiektu poza UserPrincipalName znalazłem SignInName. dla użytkowników, których nie udało się usunąć, różnił się on tym, że był zawiera lokalny prefix domenowy – czyli np. zamiast username@logincunion.com było username@logicunion.com.pl . tak wyglądały te obiekty przed wspomnianą wcześniej zmianą UPN, i jak widać gdzieś ta informacja utknęła. i pomimo, że remove-msolUser -RemoveFromRecycleBin ma parametr ’-UserPrincipalName’ to de facto używa właśnie SignInName …

eN.