Bezpieczeństwo w PASOE cz. III – LDAP

W tym artykule powracamy do tematu związanego z bezpieczeństwem w PASOE, które było omawiane ok. pół roku temu. Dla przypomnienia: część I oraz część II. Warto przypomnieć sobie te wiadomości bo będziemy z nich zaraz korzystać.

Spring Security to elastyczny framework, w którym administrator może wybrać poziom  zabezpieczeń w zależności od wymagań związanych z aplikacją. Pokażę jak przeprowadzić uwierzytelnienie użytkowników, którzy nie znajdują się w bazie, nie są zdefiniowani w plikach tekstowych, ale w zewnętrznym systemie LDAP, na przykładzie Apache Directory.

Instalujemy Apache Directory Studio, które zawiera serwer LDAP oraz środowisko oparte na Eclipse, do stworzenia hierarchicznej struktury, zawierającej m.in. konta użytkowników.

Na temat tworzenia takiej struktury w ADS czy innym systemie LDAP (Active Directory, OpenLDAP, itp) można znaleźć wiele informacji w sieci. Bardzo przydatne na początku są filmiki instruktażowe na youtube. Ja omówię ten proces bardzo ogólnie, na potrzebę niniejszego artykułu. Po pierwsze dodajemy nowy serwer, nazwę go localhost.


W widoku Connections definiuję połączenie dla tego serwera o nazwie local: Hostname: localhost (lub IP), domyślny port 10389.

Następnie w zakładce Authentication, wybieram Bind DN or user: uid=admin,ou=system. Domyślne hasło: secret.

Uruchamiamy zdefiniowany serwer oraz połączenie i możemy przystąpić do tworzenia schematu. Trzeba pamiętać, że będzie on dostępny tylko przy aktywnym połączeniu.
Ten schemat można utworzyć na różne sposoby. Ja zacznę od stworzenia obiektu organizacji.
Pod głównym węzłem dc=example,dc=com dodajemy obiekt typu organization o nazwie o=progress
Pod tym elementem tworzymy dwa obiekty typu organizationalUnit ou=groups oraz ou=users.

Pod users dodajemy przykładowych użytkowników typu inetOrgPerson. Dodałem dwóch użytkowników – nasuwa się pytanie jak ich identyfikować, mamy pola cn i sn… – otóż dla identyfikacji z zewnątrz ważny jest atrybut uid (admin1 i user1) oraz userPassword, taki sam jak nazwa użytkownika. Czyli logując się jako zwykły użytkownik (Marek Webowy) podamy dane: user1, user1.

Po uwierzytelnieniu przychodzi pora na autoryzację. Ta jest realizowana za pomocą ról. Zaglądając do poprzednich artykułów możemy zobaczyć, że w pliku pasoe oeablSecurity.csv są zdefiniowane role ROLE_PSCUser, ROLE_PSCAdmin, ROLE_PSCDebug. Dla demonstracji wykorzystamy tylko jedna rolę i stworzymy jedną grupę PSCUser typu groupOfUniqueNames.

W grupie tej umieszczamy użytkowników, tzn. ich atrybuty cn (Common Name). Pamiętajmy, że pełna nazwa zawiera elementy aż do węzła głównego, czyli np. dla użytkownika user1:
cn=Marek Webowy,ou=users,o=progress,dc=example,dc=com.

OK, zrestartujmy połączenie. Możemy teraz przystąpić do konfiguracji PASOE. Ja tworzę nową instancję o nazwie ldapas bez dostępu do bazy.
Konfigurację tę przeprowadzimy w, omawianym już w poprzednich częściach, pliku [working directory]\[instancja pasoe]\webapps\ROOT\WEB-INF\oeablSecurity.properties.
Wybieramy proces zarządzający uwierzytelnieniem ldap oraz model logowania form.

http.all.authmanager=ldap
client.login.model=form

Następnie dodajemy parametry logowania do serwera ldap oraz filtry wyszukiwania informacji o użytkowniku oraz grupie, do której należy.

ldap.root.dn to definicja węzła, od którego zaczyna się wyszukiwanie informacji w strukturze, ldap.usersearch.base to z kolei węzeł, pod którym znajdują się definicje użytkowników, ldap.usersearch.filter określa zakończenie wyszukiwania po znalezieniu elementu uid.

Podobne parametry definiujemy dla grup. Całość wygląda mniej więcej tak:

 ## Required LDAP Server Authentication Manager configuration properties 
 ldap.url=ldap://localhost:10389
 ldap.manager-dn=uid=admin,ou=system
 ldap.manager-password=secret
 
 ldap.root.dn=o=progress,dc=example,dc=com

 ldap.usersearch.base=ou=users  
 ldap.usersearch.searchSubtree=true
 ldap.usersearch.filter=(uid={0})
 
 ldap.grouprole.attribute=cn
 ldap.groupsearch.base=ou=groups
 ldap.groupsearch.searchSubtree=true
 ldap.groupsearch.filter=(uniqueMember={0})

 ldap.authpopulator.rolePrefix=ROLE_

Podawanie hasła w postaci jawnej (secret), to niezbyt dobry pomysł. Można to wyeliminować kodując hasło przy pomocy komendy: stspwdutil encrypt [hasło].

Ostatni parametr (wartość domyślna ROLE_) określa prefix dla roli jaki będzie dodany do nazwy grupy, czyli dla PSCUser pełna nazwa będzie ROLE_PSCUser.

Według konwencji nazewnictwa w LDAP, nazwy ról mają być pisane dużymi literami. W LDAP są one zamieniane z automatu, my musimy zmienić je w pliku oeablSecurity.csv, np. z ROLE_PSCUser na ROLE_PSCUSER itd.

Restartujemy PASOE. Wchodzimy do linku testującego:
http://localhost:[port]/rest/_oepingService/_oeping
Podajemy dane: user1, user1.

Mamy dostęp do serwisu.

OK, ale zazwyczaj nie ma tak dobrze. Często zanim wszystko skonfigurujemy pojawia się komunikat o braku dostępu. W logach nic nie ma, gdzie szukać informacji? Musimy odblokować ilość informacji zapisywanych do logów. W pliku [working directory]\[instancja pasoe]\conf\logging-pasoe.properties zmieniamy poziom zapisów z WARN na DEBUG, a ERROR na INFO, jak poniżej. Konfigurację zapisów do logów możemy zrobić także z poziomu danej aplikacji, ale tutaj poniższa zmiana wystarczy. Uwaga! ta zmiana powoduje znaczne zwiększenie tekstu w logach.

W pliku ldapas_authn.[data].log (przypominam, że moja instancja nazywa się ldapas) znajduje się informacja o udanym uwierzytelnieniu. Informacje o nieudanych logowaniach znajdują się w pliku ldapas_authz.[data].log

[data i czas] ldapas ROOT:f:0000000a success user1

W logu ldapas.[data].log znajduja się m.in. wpisy:

...LdapAuthenticationProvider - Processing authentication request for user: user1...
...FilterBasedLdapUserSearch - Searching for user 'user1', with user search [ searchFilter: '(uid={0})', searchBase: 'ou=users  '...
...Searching for entry under DN 'o=progress,dc=example,dc=com', base = 'ou=users', filter = '(uid={0})'... 
...Found DN: cn=Marek Webowy,ou=users...
......
...Searching for roles for user 'user1', DN = 'cn=Marek Webowy,ou=users,o=progress,dc=example,dc=com', with filter (uniqueMember={0}) in search base 'ou=groups'...
......
...Granted Authorities: ROLE_PSCUSER;...

Wpisów jest wiele, ale można prześledzić proces wyszukiwania oraz uwierzytelniania i autoryzacji.

Następnym razem chciałbym pokazać jak PASOE korzysta z obiektu CLIENT-PRINCIPAL przy autoryzacji LDAP.

MOVEit Automation – podstawy

Dzisiaj chciałbym przedstawić podstawy drugiego produktu Ipswitch – MOVEit® Automation.
MOVEit Automation (poprzednia nazwa MOVEit Central) pozwala w łatwy sposób zautomatyzować złożone przepływy danych (workflows) bez konieczności programowania.
Przepływy złożone są z zadań (tasków), a te z kolei mogą być uruchamiane wg harmonogramu, sterowane zdarzeniami lub na żądanie. Zadania mogą wymieniać pliki między systemami wewnętrznymi i zewnętrznymi, w tym serwerami MOVEit Transfer, przy użyciu wielu protokołów i przetwarzać pliki za pomocą wielu wbudowanych funkcji.

O ile miejsce MFT jest w strefie DMZ, to MA powinien znajdować się w bezpiecznej strefie sieci wewnętrznej (patrz rysunek poniżej).

Poniżej widzimy podobną architekturę, gdzie zamiast MFT jest inny produkt z grupy Ipswitch – WS_FTP Server. Możliwe są inne rozwiązania, serwery innych producentów, pominięcie strefy DMZ i połączenie np. z chmurą (MOVEit Cloud), ale o tym innym razem.

MOVEit Transfer (MFT) łatwo skonfigurować do współpracy z MOVEit Automation. W tym celu w MFT dodajemy użytkownika np. micentral z uprawnieniami admina.
Konto to będzie wykorzystywane do wysyłania dużej liczby pakietów dlatego wyłączamy dla niego notyfikacje. Można ustawić odpowiednie zabezpieczenia jak np. mocne hasło czy brak wygaśnięcia konta.
Logujemy się do MOVEit Automation, widzimy główne menu.

klikamy na HOSTS i Add Host. Z listy kilkunastów typów hostów wybieramy MOVEit Transfer.

Podajemy IP oraz dane logowania użytkownika micentral.

Można wprowadzić ograniczenia Limits i Timeouts itd. oraz przetestować połączenie.
Przejdźmy teraz do jednej z podstawowych czynności, tzn. do definiowania tasków.
W głównym menu wybieramy TASKS i Add Task.

Jak widać są trzy rodzaje tasków. Każdy rodzaj ma inne przeznaczenie. Najczęściej definiuje się taski typu Traditional, które zaspokajają większość potrzeb jakie występują w systemie.
Utwórzmy przykładowy tradycyjny task o nazwie myFirstTask. Pierwszym krokiem jest wybór kroku w definiowaniu (przycisk Step): Source, Process, Destination.

Zaczynam od źródła, czyli Source.

Wybieram dodany wcześniej serwer MFT oraz katalog i wzorzec plików, które będą przetwarzane. Możemy dodać czynności po udanym transferze jak np. skasować pliki, zmienić ich nazwę itp. Jeśli klikniemy w opcji Step na Process, dostaniemy listę skryptów do wyboru. Ja ten krok tutaj pominę.

Wybieram natomiast krok Destination, a w nim podaję adres email, na który pliki mają być wysłane.

OK, następny krok to zdefiniowanie harmonogramu (Schedule).

W kroku Next Action można wybrać Send Email, co jest rodzajem notyfikacji oraz ewentualnie Run Task, czyli uruchomienie innego wcześniej zdefiniowanego tasku. W ten sposób można zdefiniować cały cykl zadań.
OK, mój task ma być uruchamiany tylko we wtorki o określonej godzinie. Musimy go jeszcze włączyć i po pewnym czasie mamy raport z jego działania.

Zadania zaawansowane (Advanced Task) podobnie do zadań tradycyjnych mogą również korzystać z procesów. Mogą ponadto używać elementów warunkowych IF i FOR, aby określić, czy i kiedy inne elementy mają być uruchomione.
Elementy te zapewniają kontrolę przepływu pracy bez konieczności programowania.
Trzecim typem zadań sa zadania synchronizujące (Synchronization Task).

Ich zadaniem jest synchronizacja folderów, dlatego konfiguracja składa się z folderu A, folderu B i strzałki określającej kierunek synchronizacji.

MOVEit Automation, podobnie do MFT gwarantuje dostarczenie danych, szyfrowanie danych w spoczynku i szczegółową kontrolę dostępu. Na tym zakończę to wprowadzenie do systemu MA.
Jeśli ktoś ma pytania to proszę o kontakt na grupie PUG Poland.

OpenEdge 12.3

Powróćmy do tematu związanego z OpenEdge, ponieważ już od pewnego czasu mamy na rynku nową wersję OE 12.3.
Zacznijmy od nowinki dla programistów; dodano nową, bardziej zwięzłą instrukcję definicji zmiennych. Do tej pory ile zmiennych chcieliśmy zdefiniować, tyle musieliśmy wstawić definicji. Obecnie zapis jest krótszy, a w jednej instrukcji można zdefiniować wiele zmiennych. Zmienne zdefiniowane poprzez nową instrukcję są zawsze NO-UNDO.

Następna nowinka związana jest z definicją tablicy (extentu) o nieokreślonym rozmiarze. Rozmiar ten można teraz określić podczas fazy runtime, nawet jeśli tablica ma przypisane wartości początkowe.

W ABLu wprowadzono także operatory przypisania (+=, -=, *=, /=) do wykonywania operacji i przypisywania
wartość, używając skróconej notacji.

Od 12.3 jeśli zachodzi potrzeba aktualizacji aplikacji ABL, przy czym ta aktualizacja jest związana z nowymi elementami schematu, nie trzeba już
restartować maszyny wirtualnej ABL (AVM).

W OpenEdge 12.3 dodano ciekawą opcję komendy PROUTIL: PROUTIL TABLEREORG – umożliwia to reorganizację pofragmentowanych danych w tabeli, podczas gdy sama tabela pozostaje dostępna dla operacji OLTP (przetwarzanie transakcji online). Nowy proces zastępuje długotrwałe operacje zrzutu i ładowania danych oraz odbudowy powiązanych indeksów. Rekordy tabeli muszą znajdować się w tym samym obszarze przechowywania typu II. Operacja ta obsługuje także tabele multi-tenant oraz podzielone na partycje.

Kolejne parametry mogą być modyfikowane online, tym razem dla brokera secondary.
Maximum Clients per Server (-Ma)
Maximum Dynamic Server (-maxport)
Minimum Clients per Server (-Mi)
Minimum Dynamic Server (-minport)
Message Buffer Size (-Mm)
Maximum Servers per Broker (-Mpb)
Pending Connection Time (-PendConnTime)

Zmiany parametrów można dokonać w R&D -> opcja 4. Administrative Functions -> 16. Adjust Startup Parameters.

Jest jeszcze kilka ciekawych zmian związanych z tzw. Continuous Operations, bezpieczeństwem, programowaniem, ale to już musicie poszukać w sieci sami.

MOVEit Transfer – klient

W poprzednim artykule opowiedziałem o głównych cechach systemu MOVEit Transfer zainstalowanego na systemie serwerowym. Teraz napiszę o dostępie do niego z poziomu klienta. Potrzebna jest do tego osobna licencja Ad-Hoc Transfer, dzięki której użytkownik posiadający konto w systemie MFT może zainstalować dodatkowe komponenty i mieć dostęp poprzez przeglądarkę webową lub Microsoft Outlook. Użytkownicy mogą więc wymieniać się wiadomościami, przesyłać pliki, co wygląda podobnie do zwykłego systemu Outlook.

Są jednak istotne różnice.Załączniki są wysyłane jako część pakietu nie do odbiorcy, ale na serwer MFT.Do odbiorców wysłany jest e-mail z powiadomieniem o nowym pakiecie.Odbiorca może kliknąć link w tym powiadomieniu, zalogować się do MFT i odebrać pakiet.

Konfiguracja tzw. Moveit Connectora jest bardzo prosta. Potrzebujemy tylko dane logowania użytkownika systemu MFT i oczywiście adres hosta.

W programie Microsoft Outlook, jeśli chcemy skorzystać z nowej możliwości wysyłania pakietów wybieramy MOVEit Send i otrzymujemy poniższy ekran.

Wiadomość możemy wysłać tradycyjnie lub poprzez Send through MOVEit.
Na dole mamy ustawienia: Message body secured oznacza, że treść wiadomości, podobnie jak załączniki, będzie dostępna dopiero po zalogowaniu do MFT. Ustawienie czasu wygaśnięcia i max. ilość pobrań załączników określa administrator. Parametry te synchronizują się z serwerem.

Odbiorca może odpowiedzieć na wiadomość, ewentualnie dodać własne załączniki, ale tylko jeśli takie działanie jest dozwolone. Administrator systemu MFT ma szerokie pole do działania; może np. określać kto może wysyłać i odbierać pakiety, ustawiać limity na poziomie użytkownika lub pakietu oraz kontrolować terminy ważności i pobierania pakietów.

Bardzo duże pliki i dużą ilość załączników można wysyłać szybko i bezpiecznie, unikając ograniczeń serwera pocztowego.

Poniżej znajduje się przykładowy fragment wiadomości jaką odbiorca otrzymuje do skrzynki email. Jest tylko link do systemu. Może on otrzymać w oddzielnej wiadomości hasło do logowania, ale jest to tylko jedna z możliwości. Hasło może być przekazane także w sposób “manualny”.

Jeśli odbiorca nie jest zdefiniowany w systemie tworzony jest użytkownik tymczasowy TempUser a jego nazwa to adres email.

Jest jeszcze jeden produkt typu kienckiego MOVEit Client – bardzo prosty w obsłudze, dający dostęp do katalogu domyślnego oraz katalogów współdzielonych.
Zobaczmy, że w przykładowym systemie dwóch użytkowników (testuser, user1) ma dostęp do katalogu myshared. Ich uprawnienia różnią się nieco, ale obaj mogą wymieniać się danymi.

Użytkownik user1 umieścił w katalogu dwa pliki, które testuser może teraz pobrać i ew. umieścić swoje.

Ponieważ testuser ma uprawnienie List Users może klikając na ikonkę po prawej stronie podejrzeć kto współdzieli ten folder oraz jakie ma w nim uprawnienia.

MOVEit Transfer – podstawy systemu

Do tej pory wszystkie artykuły były związane z technologią OpenEdge. Najwięcej jest poświęconych oczywiście serwerowi aplikacji PASOE. Pora na małą zmianę.
W pierwszej połowie 2019 r. Progress zakupił firmę Ipswitch, Inc., specjalizującą się w rozwiązaniach związanych z bezpiecznym przesyłaniem danych oraz monitorowaniem i zarządzaniem zasobami sieciowymi.

MOVEit® Transfer (poprzednia nazwa MOVEit® DMZ) to cały system do bezpiecznego przetwarzania, przechowywania i przesyłania pakietów.

Produkty z serii MOVEit zapewniają kompleksowe rozwiązania, do bezpiecznej obsługi wrażliwych informacji takich jak dane finansowe, dokumentacja medyczna, dokumenty prawne czy dane osobowe.

No dobrze, powiecie, ale mamy serwery FTP, pocztę elektroniczną – czy to nie to samo i do tego za darmo?

Zabezpieczenia poczty elektronicznej nie zawsze są zgodne z wymaganiami korporacji, a załączane do emaili pliki mają spore ograniczenia dotyczące rozmiaru.

Serwery FTP to oczywiście popularny sposób bezpiecznego przesyłania dużych plików. Problem jest jednak gdy chcemy przekazywać dane wrażliwe (jak powyżej) przy zastosowaniu wymaganych, określonych zabezpieczeń, mieć gwarancję dostarczenia informacji, a do tego tworzyć raporty dotyczące wybranych transferów.

MOVEit® Transfer (MFT) dostarcza bezpieczne usługi przesyłania danych SFTP/S i HTTPS.
Ponadto, dane w systemie MFT są automatycznie szyfrowane nie tylko podczas transferu lecz także w spoczynku.

Zobaczmy dwie podstawowe konfiguracje MFT. Poprzednia nazwa produktu to, jak wspomniałem MOVEit® DMZ, przy czym DMZ oznacza strefę zdemilitaryzowaną, a więc strefę “ograniczonego zaufania” gdzie ryzyko włamania jest zwiększone. W strefie tej umieszcza są serwery, które świadczą usługi użytkownikom sieci wewnętrznej, którzy muszą kontaktować się z użytkownikami sieci zewnętrznej. Po prawej stronie schematu mamy wewnętrznych użytkowników korporacji, która musi mieć bezpieczny dostęp także do użytkowników zewnętrznych (lewa strona).


Zabezpieczenia te można jeszcze podnieść stosując produkt MOVEit Gateway (rysunek poniżej). Miedzy nim a serwerem MFT konfiguruje się tzw. tunelowanie.

Jeśli chodzi o architekturę to nie koniec możliwości, ale na początek poprzestaniemy na tych dwóch prostych przykładach.

MFT jest produktem serwerowym instalowanym na platformie Windows Server. Oznacza to, że próba zainstalowania na maszynie klienckiej zakończy się niepowodzeniem.
Produkt ma dość prosty interfejs webowy, ale bardzo dużo możliwości definiowania poszczególnych elementów w całym systemie przesyłania informacji.

Każdy kto ma dostęp do systemu ma określone uprawnienia oparte na rolach (role-based). Może to być np. administrator, administrator plików, administrator grupy, zwykły użytkownik, użytkownik tymczasowy.

Użytkowników możemy utworzyć od zera lub załadować z istniejącego systemu typu LDAP, SSO itp.

Użytkownicy mogą należeć do grup. Pliki mogą być współdzielone między poszczególnymi użytkownikami lub ich grupami.

Uprawnienia każdego użytkownika można dokładnie zdefiniować pod kątem zabezpieczeń, ograniczeń itd.
Na poniższym rysunku widać sekcję uprawnień związaną z uwierzytelnieniem. Może ono być realizowane przez MOVEit, system zewnętrzny lub oba. Można zdefiniować zasady związane z hasłem dostępu, uwierzytelnianiem przez HTTP, FTP, SSH itp.

W poniższej sekcji, można zdefiniować np. limity transferu i składowania danych, określić folder domowy i domyślny, i wiele innych.

Każdy użytkownik ma domyślnie włączone powiadomienia o przesłanych pakietach danych. Powiadomienia te wysyłane są drogą emailową. Ponieważ produkt nie posiada wbudowanego własnego serwera SMTP należy skonfigurować połączenie z istniejącym korporacyjnym serwerem pocztowym. Dla celów testowych wystarczy utworzyć na platformie Windows Server własną lokalną usługę.

Istotnym elementem wymiany danych są foldery. Z punktu widzenia organizacji, są one podobne do folderów w każdym systemie operacyjnym. W MFT w łatwy sposób można przyporządkowywać poszczególnych użytkowników lub ich grupy, mających do tych folderów dostęp oraz zdefiniować rodzaj dostępu.

Na poniższym rysunku widzimy listę uprawnień, które mogą być dziedziczone od folderu nadrzędnego lub nadane od zera. Oprócz tych najbardziej znanych mamy akcje związane z tworzeniem podkatalogów Sub czy najbardziej ciekawą Share, umożliwiającą udostępnianie tego folderu innym użytkownikom.

Jako administrator możemy określić, jakie uprawnienia dany użytkownik może przydzielić innym użytkownikom współdzieląc katalog. Nierzadko zostawia się tylko ustawienia List i Upload; użytkownik zewnętrzny może wtedy przesłać plik, wylistować zawartość katalogu, ale nie może nic pobrać ani skasować.

Jeśli zostawimy tylko te dwie akcje dla użytkownika testuser, a następnie zalogujemy się na jego konto, widzimy, że może on dodać innych użytkowników do współdzielenia katalogu, ale tylko dla tych wybranych akcji.

Ta użyteczność funkcjonalność nazywa się Secure Folder Sharing i powrócimy do niej w następnym artykule.

Jeśli ktoś nie chce czekać na następny odcinek może poczytać o MOVEit Transfer na stronach Ipswitch np. ipswitch.com, docs.ipswitch.com (cała dokumentacja) czy na stronach Progress Software.

Jeśli ktoś chciałby zobaczyć demo po polsku to proszę pisać na naszym PUG Poland.

Bezpieczeństwo w PASOE cz. II

Część druga bezpieczeństwa w PASOE to raczej tylko suplement, związany z uwierzytelnieniem i autoryzacją użytkowników opartym o dane w plikach tekstowych w podkatalogu serwera aplikacji.

Po pierwsze, autoryzacja użytkowników z pliku users.properites. Każdy z nich ma przypisana rolę np.: ROLE_PSCUser, ROLE_PSCAdmin, ROLE_PSCDebug czy ROLE_None.

Skąd wiadomo, co te role oznaczają i gdzie są zdefiniowane? Żeby się dowiedzieć trzeba otworzyć plik: [working directory]\[instancja pasoe]\webapps\ROOT\WEB-INFF\oeablSecurity.csv.

Pliku oeablSecurity.csv określa kontrolę dostępu do adresów URL dla aplikacji webowych. Każdy wiersz w pliku jest uporządkowanym zestawem trzech wartości.

Odpowiadają one trzem atrybutom elementu przechwytującego URL w Spring Security, a mianowicie:
– wzorzec – wzorzec adresu URL, który może zawierać symbole wieloznaczne i wyrażenia regularne
– metoda – metoda dostępu HTTP
– dostęp – dozwolone role dostępu do zasobu.

Na poniższym obrazku widzimy kontrole dostępu dla poszczególnych warst transportowych. Najpierw APSV (metody HAD, GET, POST) i role, potem SOAP, REST, WEB, a następnie bardziej szczegółowe definicje dla wybranych URI.

Dodajmy, że ustawienia w tym pliku oraz w oeablSecurity.properties znajdują się w kilku lokalizacjach i mają charakter hierarchiczny, np. plik oeablSecurity.csv znajdziemy także w: [working directory]\[instancja pasoe]\conf\oeablSecurity.properties.csv, a oeablSecurity.properties jeszcze w kilku miejscach.

Pliki te bardziej zagnieżdżone dziedziczą ustawienia od plików znajdujących się w podkatalogach powyżej. Dzięki temu można precyzyjnie określić zabezpieczenia dla całej instancji PASOE, aplikacji ABL (agenta wielosesyjnego) czy aplikacji WEB.

Do tej pory podawane przez nas hasła były w postaci jawnej. Co jednak zrobić żeby je zaszyfrować, tak aby haker, który skopiuje pliki z dysku nie miał z nich pożytku?

Sprawa jest bardzo prosta. Po pierwsze zmieniamy nazwę procesu managera uwierzytelniającego dane z local na extlocal.

 

[working directory]\[instancja pasoe]\webapps\ROOT\WEB-INFF\oeablSecurity.properties.

Wartość parametru client.login.model=form lub basic.

Szyfrujemy hasło poleceniem: genspringpwd [hasło], np. genspringpwd password

Otrzymujemy: $2a$09$EU0wp9hga2zmfKBUg21nAeVObPBQQ3erbW53XCcJiQYr8s4QwoCki i tę wartość wstawiamy do pliku users.properites w miejsce jawnego hasła np. dla użytkownika myrestuser.

Restartujemy PASOE i logujemy się wpisując hasło niezaszyfrowane.

Sprawdzamy, że logowanie się powiodło.

Bezpieczeństwo w PASOE cz. I

Większość nowoczesnych, rozproszonych aplikacji korzysta z serwera aplikacji
dla logiki biznesowej. Korzystanie z serwera PASOE jest bardzo dobrym rozwiązaniem
ponieważ może on bezpośrednio obsługiwać wszystkie typy klientów, jest łatwo skalowalny oraz
może zapewnić bezpieczeństwo aplikacji przy użyciu Spring Security.

Spring Security to framework, który koncentruje się na zapewnianiu uwierzytelniania i autoryzacji dla aplikacji.
Spring Security można rozszerzyć w celu spełnienia niestandardowych wymagań. Poziom bezpieczeństwa zależy od nas, ponieważ to my decydujemy, którą technologię zabezpieczeń wybieramy (lokalne pliki, LDAP, OEREALM, STS i inne).

PASOE zawsze uruchamia Spring Security w sposób domyślny. Nawet próba dostępu do serwisu REST przez użytkownika anonymous wywoła proces uwierzytelniania, autoryzacji i ew. utworzenia tokena Spring Security oraz obiektu ABL CLIENT-PRINCIPAL.

Żeby to zademonstrować, stwórzmy i wystartujmy przykładowy serwer PASOE (ja nazwę go mysec). Od wersji OE12.1 każdy serwer aplikacji startuje serwis ping – jest on dostępny pod adresem URL:
http://localhost:[port]/rest/_oepingService/_oeping


Oznacza to, że PASOE wystartował i mamy dostęp do serwisu ping.

Zobaczmy jakie są domyślne ustawienia dla tego serwisu, który procuje w web aplikacji ROOT. Otwieram plik oeablSecurity.properties w lokalizacji C:\WrkOpenEdge121\mysec\webapps\ROOT\WEB-INF.

Znajdujemy wpis: client.login.model=anonymous.

Oznacza on, że każdy użytkownik (anonymous) ma dostęp do wszystkich aplikacji w ROOT.

Powyżej, widzimy wpis: http.all.authmanager=local. Oznacza on, że uwierzytelnienie jest lokalne w oparciu o użytkowników zdefiniowanych w pliku:
C:\WrkOpenEdge121\mysec\webapps\ROOT\WEB-INFF\users.properites.
Zawartość tego pliku jest następująca:

restuser=password,ROLE_PSCUser,enabled
restdebug=password,ROLE_PSCUser,ROLE_PSCAdmin,ROLE_PSCDebug,enabled
restadmin=password,ROLE_PSCUser,ROLE_PSCAdmin,enabled
restnone=password,ROLE_None,enabled

Chcemy teraz wymusić logowanie ze strony użytkownika – ustawiamy wartość client.login.model=form.
Restartujemy PASOE i ponawiamy dostęp do URL oeping.
Bazując na danych w pliku users.properties wpisujemy: restuser i password. W efekcie dostajemy dostęp do serwisu (patrz. pierwszy rysunek).


Żeby pokazać, że dostaliśmy token od systemu, otwórzmy nową kartę w przeglądarce (ta sama sesja) i wpiszmy URL dla serwisu ping. Dostajemy od razu dostęp, bez logowania.

Jeśli podamy dane restnone i password lub jakiekolwiek inne, nie występujące w pliku, dostęp jest zabroniony.

Dodajmy teraz do pliku users.properties własnego użytkownika, o uprawnieniach takich jak restuser i zmieńmy nazwę na myrestuser.

restuser=password,ROLE_PSCUser,enabled
myrestuser=password,ROLE_PSCUser,enabled
restdebug=password,ROLE_PSCUser,ROLE_PSCAdmin,ROLE_PSCDebug,enabled
restadmin=password,ROLE_PSCUser,ROLE_PSCAdmin,enabled
restnone=password,ROLE_None,enabled

Aby zmiany zostały wczytane, restartujemy PASOE komendą:
pasman pasoestart -v -I mysec -restart

Logujemy się jako nowy użytkownik…

…który ma dostęp do serwisu rest.

O dalszych podstawach zabezpieczeń napiszę w drugiej części.

PASOE i Load Balancing

Użytkownicy klasycznego AppServera pamiętają zapewne możliwość dość łatwej implementacji load balancingu, wykorzystującego proces przekierowujący NameServer.
W nowym serwerze aplikacji PASOE nie ma NameServera, nawet proces AdminServera nie jest niezbędny, jak zatem można zrealizować usługę LB?

Aby to osiągnąć musimy wykorzystać istniejące rozwiązania innych firm. Dostępnych jest wiele produktów i ciężko jest wybrać jedną najlepszą opcję load balancingu do wszystkich zastosowań, dla każdego z klientów. Najbardziej znane to: Apache proxy LB, Tomcat LB i Amazon Elastic LB. Skupmy się na dwóch pierwszych rozwiązaniach. Oba wykorzystują popularny serwer Apache.

Apache proxy LB – popularny serwer Apache HTTP działa tutaj jako serwer proxy przekierowujący żądania HTTP do adresu URL, który jest unikalny dla każdej instancji PASOE. Ta metoda nie wymaga konfiguracji po stronie PASOE gdyż całe równoważenie obciążenia wykonywane jest przez serwer Apache.

Wadą tego typu rozwiązania jest to, że serwer Apache nie monitoruje statusu uruchomionych instancji i jeśli któraś z nich ulegnie awarii, serwer kontynuuje próbę wysyłania żądań do niedostępnej instancji i żądania zostają utracone.

Tomcat load balancing – równoważenie obciążenia realizuje tutaj wyznaczona instancja PASOE, która musi nazywać się lb (lub jklb). Jest to jej jedyne zadanie i jeśli instancja ma wdrożone jakiekolwiek aplikacje (np. ROOT) należy je usunąć (undeploy). Poniższy rysunek ilustruje przykładową konfigurację. Oprócz instancji lb można utworzyć opcjonalnie instancję do monitorowania procesu równoważenia. Musi się ona nazywać status (lub jkstatus) i także nie może mieć wdrożonych żadnych aplikacji.

Jednakże, wdrożenie load balancingu jest także możliwe gdy obie w/w instancje są skonfigurowane tylko wirtualnie, tzn. bez ich fizycznego utworzenia (bez komendy tcman create lub pasman create). Jaka jest różnica tego drugiego rozwiązania? Jest nieco łatwiejsze i bardziej nadaje się do demonstracji. Można je także wykorzystać w lokalnej instalacji. W produkcyjnym środowisku lepiej skorzystać z pierwszego sposobu i możliwości jakie dają nam fizyczne instancje PASOE, szczególnie jeśli idzie o bezpieczeństwo.

Tutaj omówię drugi, krótszy sposób. Na początek musimy mieć zainstalowany web serwer  Apache np. 2.4 (w sumie można użyć innego web serwera ale Apache jest najczęściej stosowany ze względu choćby na wspólna konfigurację Apache i Tomcata). Działanie serwera można rozszerzyć poprzez załadowanie odpowiednich modułów, i tak w pliku  conf\httpd.conf odkomentowujemy linie:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

To powinno wystarczyć, ale dla konkretnej wersji Apache może okazać się, że potrzebny jeszcze jakiś moduł; sprawdzajcie logi jeśli są kłopoty z uruchomieniem.

Teraz tworzymy przykładowe 2 instancje PASOE , między którymi będzie rozkładać się obciążenie. Nazwiemy je node1 i node2.

pasman create -p 8815 -P 8816 -s 8817 -j 8818 %WRKDIR%\node1
pasman create -p 8825 -P 8826 -s 8827 -j 8828 %WRKDIR%\node2

Teraz powiem kilka słów o powyższych instrukcjach. Pasman jest tą samą instrukcją co tcman, ale ma charakter jedynie globalny, tzn. nie ma tej instrukcji w podkatalogu bin dla instancji, przez co łatwiej z niej korzystać w przypadku zarządzania kilkoma instancjami. Stosuje się tutaj parametr -I, po którym podajemy nazwę instancji.

Zwróćcie uwagę, że oprócz 3 portów, podałem jeszcze czwarty oznaczony jako -j dla protokołu AJP13

Jest to binarny protokół, który umożliwia przesyłanie żądań z serwera WWW do serwera aplikacji. Jest on powszechnie stosowany w systemach ze równoważeniem obciążenia; obsługuje również monitorowanie stanu serwera.

Po utworzeniu instancji musimy aktywować protokół AJP13 w pliku conf/server.xml dla każdej instancji.

pasman feature -I node1 AJP13=on
pasman feature -I node2 AJP13=on

Krótka uwaga – zdecydowanie nie zalecam dokonywania zmian w pliku server.xml ręcznie, gdyż łatwo przy tym o błędny wpis i kłopot z prawidłowym uruchomieniem instancji PASOE.

Teraz trzeba skonfigurować obie instancje tak, aby obsługiwały naszą aplikację: ustawić połączenie z bazą, sprawdzić czy są włączone protokoły APSV / REST / WEB / SOAP,
warto wdrożyć (jeśli nie są) manager.war i oemanager.war oraz na koniec jakąś aplikację do testowania. Tych czynności nie będę tutaj opisywał bo była już wcześniej o nich mowa.

Uruchamiamy instancji node1 komendę tcman workers (lub pasman workers -I node1). W podkatalogu utworzy się plik w podkatalogu node1\temp\workers.properties z wygenerowanymi ustawieniami dla load balancingu. Ustawienia te należy traktować raczej jako wzorzec ponieważ wymagają pewnej edycji.

Do tego pliku za chwilę wrócimy; teraz w pliku Apache conf\httpd.conf na samym końcu dodajemy ustawienia:

#workers.properties load balancing config
LoadModule jk_module modules/mod_jk.so
JkWorkersFile C:/Apache24/lbfiles/conf/workers.properties
JkShmFile C:/Apache24/lbfiles/logs/mod_jk.shm
JkLogFile C:/Apache24/lbfiles/logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkMount /* jklb
JkMount /status jkstatus 

Jest tutaj ładowany jeszcze jeden moduł mod_jk.so, jeśli nie ma go w instalacji trzeba pobrać go z sieci i dodać katalogu modules. Wygodnie jest umieścić dane związane z LB w osobnym katalogu, tutaj jest to katalog lbfiles.

W tym katalogu musimy umieścić plik workers.properties odpowiednio skorygowany. Załączam plik z ustawieniami dla niniejszego przykładu.

# List of worker server instances
worker.list=jklb,jkstatus
#
# Global properties
#
# worker.maintain=60
# Common worker properties referenced by individual workers
worker.common.type=ajp13
worker.common.host=PCPTU3
worker.common.socket_timeout=10
worker.common.connect_timeout=10000
worker.common.socket_keepalive=true
worker.common.ping_mode=I
worker.common.ping_timeout=10000
worker.common.retry_interval=100
worker.common.recovery_options=7
# worker.common.connection_ping_interval=10000
# worker.common.fail_on_status=0
# worker.common.max_packet_size=8192
# worker.common.recover_time=60

 

# properties for alias node1 with jvmRoute node1
worker.node1.port=8818
worker.node1.reference=worker.common
worker.node1.lbfactor=1

# properties for alias node2 with jvmRoute node2
worker.node2.port=8828
worker.node2.reference=worker.common
worker.node2.lbfactor=1

# Load balancer directives
worker.jklb.type=lb
#worker.jklb.port=8012
worker.jklb.balance_workers=node1,node2
worker.jklb.method=Request

# Status worker directives
worker.jkstatus.type=status
worker.jkstatus.read_only=False

Omówię niektóre ustawienia: worker.list=jklb,jkstatus – to lista instancji wirtualnych do LB i do monitorowania. Sa również ustawienia dla maszyn z obiema instancjami node1 i node2 (tutaj wszystko znajduje się na jednej maszynie).

worker.jklb.balance_workers=node1,node2 – to lista instancji obsługujących żądania klienckie. Na uwagę zasługują ustawienia: worker.node1.lbfactor=1 oraz worker.node2.lbfactor=1. Określają one udział instancji w procesie obsługi żądań. W tym przypadku podział jest 50%/50%. Jeśli np. node1 ma obsługiwać 2 razy więcej żądań to współczynnik trzeba ustawić 2 razy większy niż node2.

Startujemy obie instancje. Jaki będzie port w adresie URL jeśli mamy kilka instancji PASOE, obsługujących tą samą aplikację? Port w adresie będzie wskazywać na Apache serwer (domyślnie 80), reszta pozostaje bez zmian. Odświeżamy kilka razu adres URL, generując żądania do obsługi.

Jeśli chcemy podejrzeć status LB to podajemy w adresie URL: nazwa_hosta_lb/status, czyli tutaj: localhost/status.

Widać m.in, że obie instancje są aktywne, node2 ma mniej obsłużonych żądań i 2 błędy, co jest związane z moim czasowym wyłączeniem tej instancji (dla testu). Większość oznaczeń jest opisana po najechaniu na nie kursorem. To na razie tyle, jeśli chodzi o Load Balancing.

OpenEdge Explorer

OpenEdge Explorer nie jest tematem nowym. To okrojona wersja systemu OpenEdge Management (dawniej Fathom Management) który pojawił się w wersji Progress V9.

Wszystkie wymienione powyżej produkty mają głównie za zadanie monitorowanie parametrów systemów operacyjnych i komponentów Openedge (bazy danych, serwery aplikacji itd). Dotyczy to zarówno lokalnego komputera jak i maszyn zdalnych, a wszystko to z jednej konsoli w przeglądarce internetowej. Oprócz monitorowania można także zarządzać komponentami OE: konfigurować, uruchamiać, zatrzymywać itp. W opcji Database Administration znajdują się ponadto dodatkowe możliwości związane z obsługą funkcji baz danych. Tyle w dużym skrócie.

OE Explorer (OEE) jest, jak wspomniałem, uboższą wersją OE Management (OEM). Nie ma np. możliwości zapisu parametrów do specjalnej bazy (trending data), definiowania alertów, wyświetlania graficznych widoków, ale ma te zaletę, że jest darmowy (instaluje się automatycznie z większością licencji od wersji OE 10.2B).

Jak uruchamiamy OEE: możemy kliknąć w ikonkę OE Explorer, ale najlepiej w przeglądarce wpisać URL: localhost:9090.

Aby system wystartował musi być uruchomiony AdminServer. Sprawdzamy jego status komendą w oknie Proenv: proadsv -query i jeśli proces nie pracuje uruchamiamy go komendą: proadsv -start.

Teraz sprawdzamy czy uruchomiony jest OEE: fathom -query i w razie konieczności uruchamiamy go: fathom -start.

Teraz już powinniśmy mieć system uruchomiony. Na starcie jesteśmy proszeni o zmianę hasła. Gdybyśmy mieli pełny produkt OEM to trzeba byłoby jeszcze zdefiniować mail server (powiadomienia o przekroczeniu zdefiniowaniu wartości), bazę do przechowywania trending data itd. W OEE po zmianie hasła mamy od razu widok podobny jak na poniższym rysunku.

Aby monitorować bazę danych definiujemy nowy element Resources -> OpenEdge -> Database. Database Migration Utility służy do skonfigurowania istniejącej już bazy przy czym serwer musi być uruchomiony z podaniem numeru lub nazwy portu.

Klikając na Database Administration możemy zarządzać funkcjami np. opisanymi wcześniej Table Partitioning czy Change Data Capture, Multi-tenancy itp. Funkcje te włączamy w bazie jak na rysunku poniżej. Tych funkcjonalności nie znajdziemy w graficznym narzędziu Data Administration.

Listę włączonych funkcji widać na rysunku po prawej stronie poniżej.

Można tutaj także edytować dane zabezpieczeń (Data Security), przeglądać schemat danych, …

… zrzucać i ładować dane tabel.

W zasobach bazy danych większość widoków jest nieaktywnych dla OEE, ale w widoku Performance Summary mamy ciekawe zestawienie aktualnych parametrów:

Od razu widać, że podobne informacje możemy uzyskać poprzez narzędzie PROMON, ale o ile promon zbiera dane tylko dla bazy lokalnej, to w OEE mamy dostęp dla baz zdalnych. W ten sposób z jednej konsoli można monitorować bazy danych i inne procesy np. serwery aplikacji, data serwery itd.

A propos serwerów aplikacji: poniżej zamieszczam widok dla PASOE, aplikacja ROOT. Dla zainteresowanych tym serwerem, w OEE i OEM 12 nie ma wsparcia dla web serwisów SOAP.

Podsumowując to krótkie zestawienie, OpenEdge Explorer jest użytecznym narzędziem dla administratorów baz, niezbędnym przy konfigurowaniu nowych funkcji jak partycjonowanie tabel czy multi-tenancy oraz do monitorowania zasobów zdalnych.

Partycje Tabel OpenEdge cz. III

Zanim przejdę do kolejnej części związanej z partycjami tabel, winien jestem odpowiedzi na pytanie związane z definiowaniem zasad partycjonowanie.
Otóż kilku z Was chciało wiedzieć czy jest planowana możliwość definiowania podziału danych w tabeli w oparciu nie o wartość pola, lecz o funkcję (np. YEAR(TODAY)-1).
Miałem okazję niedawno rozmawiać z Richem Banvill’em – odpowiedzialnym za rozwój bazy OpenEdge. Taka możliwość nie jest w planach, ani w wersji OE12 ani w dalszej przyszłości.
Rich wspomniał, że problem ten można rozwiązać np. poprzez zdefiniowanie zadań w cronie.

Wróćmy jednak do tematu. W poprzedniej części zakończyliśmy podział tabeli w oparciu o wartości pola Country (lokalny idex). Wspomniałem, że partycjonowanie jest transparentne dla aplikacji, jednakże mogą zdarzyć się sytuacje gdy zapytanie zwraca nie te same rekordy co przed partycjonowaniem. Jednym z przykładów jest stosowanie w kodzie wyszukiwania po adresach RECID/ROWID. Ponieważ partycjonowanie przenosi rekordy, ich fizyczne adresy ulegają zmianom. W przypadku stosowania tego rozwiązania trzeba wprowadzić odpowiednie poprawki w kodzie aplikacji.

Innym, częstszym przykładem jest stosowanie w zapytaniu filtra na dane pole (WHERE). Ponieważ w partycjonowanej tabeli dodany jest zazwyczaj nowy, lokalny index, wyszukiwanie może być realizowane w oparciu o niego. Aby mieć pewność, że index nie został zmieniony i aby zachować ten sam porządek rekordów trzeba ew. dopisać frazę USE-INDEX.

Teraz trzeba wspomnieć o ważnej funkcji technologi partycjonowania tzw. pruning (okrajanie partycji).

Proces pruningu analizuje automatycznie zapytanie i (o ile to możliwe) nie bierze pod uwagę rekordów w partycjach, które nie spełniają warunków zapytania. Na rysunku widać przykład podziału rekordów na kwartały wg pola OrderDate. Jeśli w zapytaniu warunki będą dotyczyły rekordów tylko z kwartału drugiego, to tylko ta jedna partycja będzie w użyciu. Technologia ta może znacząco wpłynąć na poprawę wydajności.

Następnym zagadnieniem jest stosowanie frazy TABLE-SCAN. Powoduje ona pobranie rekordów bez dostępu do indexów i wyświetlenie ich w porządku, w jakim znajdują się w blokach bazy. Porządek rekordów zmieni się więc po partycjonowaniu, ze względu na przeniesienie ich do innych bloków. Przed pobieraniem wykonywana jest operacja pruning. Zobaczmy poniższy przykład:

FOR EACH order WHERE country = “USA” AND
  OrderDate >= 10-01-2014 AND
  OrderDate <= 12-31-2014 TABLE-SCAN:
DISPLAY OrderNum...

Jak widać, partycjonowanie tabel może wpłynąć na porządek przetwarzanych rekordów. Zobaczmy teraz jak wygląda sytuacja z tworzenie nowych rekordów i ich edytowaniem.

Należy pamiętać, że rekordy muszą mieć określone wartości dla pól, wg których odbywa się partycjonowanie. Dlatego warto stosować instrukcję ASSIGN grupującą ustawienia wartości dla rekordu, zaraz po instrukcji CREATE. Instrukcja ASSIGN wymusza fizyczne utworzenie rekordu w bazie, a więc zadziałanie mechanizmu portycjonowania. Poniższy przykład wywoła błąd (partycjonowanie po polu Country).

CREATE order.
ASSIGN ordernum = NEXT-VALUE(next-ord-num). /* ERROR! */
ASSIGN country = “USA”. 

Przykład ten łatwo poprawić do postaci:

CREATE order.
ASSIGN ordernum = NEXT-VALUE(next-ord-num)
       country = “USA”.

Edycja pola rekordu, wg którego realizowany jest podział tabeli niesie ze sobą przeniesienie całego rekordu do innego obszaru, a więc skasowanie rekordu, utworzenie go w nowym obszarze, aktualizacja indexów. Zbyt częste takie operacje mogą nieść ze sobą obniżenie wydajności. Może to być wynikiem niewłaściwie wybranego klucza partycji, co warto przedyskutować i ew. wybrać inny klucz.

 

 

1 2