Typická aplikace se tradičně skládá z následujících komponent:
V tomto jednoduchém případě by stačilo základní nastavení:
- aplikace používá pro své uživatele jednoduchý mechanismus místního ověřování
- aplikace používá jednoduchý fond připojení
- pro přístup k databázi je definován jeden uživatel
Jak se však organizace vyvíjí a zvětšuje, přibývají další součásti:
- více aplikací tenanta nebo instancí aplikace přistupujících k databázi
- více služeb a systémů přistupujících k databázi
- centrální ověřování/autorizace (AA) pro všechny (nebo většinu) služeb
- oddělení komponent pro snadnější budoucí škálování
Ve výše uvedeném schématu jsou všechny obavy rozděleny do jednotlivých složek, každá složka slouží ke specializovanému účelu. Fond připojení však stále používá jednoho vyhrazeného uživatele databáze jako v předchozím jednodušším nastavení, které jsme viděli výše.
Kromě nových komponent přicházejí také nové požadavky:
- lepší jemné ovládání toho, co mohou uživatelé dělat na úrovni databáze
- audit
- lepší a užitečnější systémové protokolování
Vždy můžeme implementovat všechny tři s více aplikačním kódem nebo více vrstvami v aplikaci, ale to je jen těžkopádné a náročné na údržbu.
PostgreSQL navíc nabízí tak bohatou sadu řešení ve výše uvedených oblastech (zabezpečení, zabezpečení na úrovni řádků, audit atd.), že přesunout všechny tyto služby do databázové vrstvy dává naprosto smysl. Abychom mohli tyto služby převzít přímo z databáze, musíme zapomenout na jednoho uživatele v databázi a místo toho použít skutečné jednotlivé uživatele.
Tím se dostáváme ke schématu jako je níže:
V našem případě použití popíšeme typické podnikové nastavení sestávající z výše uvedeného schématu, kde používáme:
- Aplikační server Wildfly (příklady zobrazené pro verzi 10)
- Služba ověřování/autorizace LDAP
- soubor připojení pgbouncer
- PostgreSQL 10
Vypadá to jako typické nastavení, protože jboss/wildfly podporuje autentizaci a autorizaci LDAP mnoho let, PostgreSQL podporuje LDAP mnoho let.
Nicméně pgbouncer spustil podporu pro LDAP (a to prostřednictvím PAM) teprve od verze 1.8 na konci roku 2017, což znamená, že někdo do té doby nemohl používat nejžhavější PostgreSQL pooler připojení v takovém podnikovém nastavení (což neznělo slibně z žádného úhlu, který jsme zvolili podívat se na to)!
V tomto blogu popíšeme nastavení potřebné v každé vrstvě.
Konfigurace Wildfly 10
Konfigurace zdroje dat bude muset vypadat takto, ukazuji to nejdůležitější:
<xa-datasource jndi-name="java:/pgsql" pool-name="pgsqlDS" enabled="true" mcp="org.jboss.jca.core.connectionmanager.pool.mcp.LeakDumperManagedConnectionPool">
<xa-datasource-property name="DatabaseName">
yourdbname
</xa-datasource-property>
<xa-datasource-property name="PortNumber">
6432
</xa-datasource-property>
<xa-datasource-property name="ServerName">
your.pgbouncer.server
</xa-datasource-property>
<xa-datasource-property name="PrepareThreshold">
0
</xa-datasource-property>
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
<driver>postgresql-9.4.1212.jar</driver>
<new-connection-sql>
SET application_name to 'myapp';
</new-connection-sql>
<xa-pool>
<max-pool-size>400</max-pool-size>
<allow-multiple-users>true</allow-multiple-users>
</xa-pool>
<security>
<security-domain>postgresqluser</security-domain>
</security>
</xa-datasource>
Důležité parametry a hodnoty jsem uvedl tučně. Nezapomeňte definovat IP adresu (nebo název hostitele), název databáze a port podle nastavení vašeho serveru pgbouncer.
Také místo typického uživatelského jména/hesla budete muset mít definovanou doménu zabezpečení, která musí být uvedena v části zdroje dat, jak je uvedeno výše. Jeho definice bude vypadat takto:
<security-domain name="postgresqluser">
<authentication>
<login-module code="org.picketbox.datasource.security.CallerIdentityLoginModule" flag="required">
<module-option name="managedConnectionFactoryName" value="name=pgsql,jboss.jca:service=XATxCM"/>
</login-module>
</authentication>
</security-domain>
Tímto způsobem wildfly deleguje bezpečnostní kontext na pgbouncer.
POZNÁMKA: v tomto blogu se zabýváme základy, tj. nepoužíváme ani nezmiňujeme TLS, ale důrazně vám doporučujeme, abyste jej ve své instalaci používali.
Uživatelé wildfly se musí ověřit vůči vašemu serveru LDAP následovně:
<login-module code="<your login module class>" flag="sufficient">
<module-option name="java.naming.provider.url" value="ldap://your.ldap.server/"/>
<module-option name="java.naming.security.authentication" value="simple"/>
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<module-option name="principalDNPrefix" value="uid="/>
<module-option name="uidAttributeID" value="memberOf"/>
<module-option name="roleNameAttributeID" value="cn"/>
<module-option name="roleAttributeID" value="memberOf"/>
<module-option name="principalDNSuffix"
value=",cn=users,cn=accounts,dc=yourorgname,dc=com"/>
<module-option name="userSrchBase" value="dc=yourorgname,dc=com"/>
<module-option name="rolesCtxDN"
value="cn=groups,cn=accounts,dc=yourorgname,dc=com"/>
<module-option name="matchOnUserDN" value="true"/>
<module-option name="unauthendicatedIdentity" value="foousr"/>
<module-option name="com.sun.jndi.ldap.connect.timeout" value="5000"/>
</login-module>
Výše uvedené konfigurační soubory platí pro wildfly 10.0, v každém případě vám doporučujeme nahlédnout do oficiální dokumentace pro vaše prostředí.
Konfigurace PostgreSQL
Aby bylo možné PostgreSQL sdělit, aby se ověřil (POZNÁMKA: neautorizovat!) proti vašemu LDAP serveru musíte provést příslušné změny v postgresql.conf a pg_hba.conf. Položky, které vás zajímají, jsou následující:
V postgresql.conf:
listen_addresses = '*'
a v pg_hba.conf:
#TYPE DATABASE USER CIDR-ADDRESS METHOD
host all all ip.ofYourPgbouncer.server/32 ldap ldapserver=your.ldap.server ldapprefix="uid=" ldapsuffix=",cn=users,cn=accounts,dc=yourorgname,dc=com"
Ujistěte se, že zde definovaná nastavení LDAP přesně odpovídají těm, která jste definovali v konfiguraci vašeho aplikačního serveru. Existují dva provozní režimy, kterým lze PostgreSQL nařídit, aby kontaktoval server LDAP:
- jednoduchá vazba
- vyhledejte a poté svažte
Jednoduchý režim vazby vyžaduje pouze jedno připojení k serveru LDAP, je tedy rychlejší, ale vyžaduje poněkud přísnější organizaci slovníku LDAP než druhý režim. Režim vyhledávání a vazby umožňuje větší flexibilitu. Nicméně pro průměrný adresář LDAP bude první režim (jednoduchá vazba) fungovat dobře. Musíme zdůraznit určité body o autentizaci PostgreSQL LDAP:
- To souvisí s pouze autentizací (kontrola hesel).
- Členství v rolích se stále provádí v PostgreSQL, jako obvykle.
- Uživatelé musí být vytvořeni v PostgreSQL (prostřednictvím CREATE uživatele/role) jako obvykle.
Existuje několik řešení, která vám pomohou se synchronizací mezi uživateli LDAP a PostgreSQL (např. ldap2pg), nebo si můžete jednoduše napsat svůj vlastní obal, který bude zpracovávat LDAP i PostgreSQL pro přidávání nebo mazání uživatelů.
Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si WhitepaperKonfigurace PgBouncer
Toto je nejtěžší část našeho nastavení, protože v pgbouncer stále chybí nativní podpora LDAP a jedinou možností je autentizace přes PAM, což znamená, že to závisí na správném místním nastavení PAM pro LDAP v systému UNIX/Linux.
Postup je tedy rozdělen do dvou kroků.
Prvním krokem je konfigurace a testování, zda pgbouncer funguje s PAM, a druhým krokem je konfigurace PAM pro práci s LDAP.
pgbouncer
pgbouncer musí být zkompilován s podporou PAM. Chcete-li tak učinit, budete muset:
- nainstalujte libpam0g-dev
- ./configure --with-pam
- znovu zkompilujte a nainstalujte pgbouncer
Váš pgbouncer.ini (nebo název vašeho konfiguračního souboru pgbouncer) musí být nakonfigurován pro pam. Musí také obsahovat správné parametry pro vaši databázi a vaši aplikaci v souladu s parametry popsanými ve výše uvedených částech. Věci, které budete muset definovat nebo změnit:
yourdbname = host=your.pgsql.server dbname=yourdbname pool_size=5
listen_addr = *
auth_type = pam
# set pool_mode for max performance
pool_mode = transaction
# required for JDBC
ignore_startup_parameters = extra_float_digits
Samozřejmě si budete muset přečíst dokumentaci pgbouncer a vyladit si pgbouncer podle svých potřeb. Chcete-li otestovat výše uvedené nastavení, vše, co musíte udělat, je vytvořit nového místního uživatele UNIX a pokusit se ověřit na pgbouncer:
# adduser testuser
<answer to all question, including password>
Aby pgbouncer pracoval s PAM při čtení z místních souborů passwd, musí být spustitelný soubor pgbouncer vlastněn rootem a s setuid:
# chown root:staff ~pgbouncer/pgbouncer-1.9.0/pgbouncer
# chmod +s ~pgbouncer/pgbouncer-1.9.0/pgbouncer
# ls -l ~pgbouncer/pgbouncer-1.9.0/pgbouncer
-rwsrwsr-x 1 root staff 1672184 Dec 21 16:28 /home/pgbouncer/pgbouncer-1.9.0/pgbouncer
Poznámka:Potřeba vlastnictví roota a setuid (což platí pro každý systém debian/ubuntu, který jsem testoval) není nikde zdokumentována, ani v oficiální dokumentaci pgbouncer ani nikde na internetu.
Poté se přihlásíme (jako pgsql superuser) k hostiteli postgresql (nebo psql -h your.pgsql.server) a vytvoříme nového uživatele:
CREATE USER testuser PASSWORD 'same as the UNIX passwd you gave above';
pak z hostitele pgbouncer:
psql -h localhost -p 6432 yourdbname -U testuser
Měli byste být schopni získat výzvu a zobrazit tabulky, jako byste byli připojeni přímo k databázovému serveru. Nezapomeňte tohoto uživatele vymazat ze systému a také jej vypustit z databáze, až skončíte se všemi svými testy.
PAM
Aby se PAM propojil se serverem LDAP, je zapotřebí další balíček:libpam-ldap . Jeho skript po instalaci spustí dialogové okno v textovém režimu, na které budete muset odpovědět správnými parametry pro váš server LDAP. Tento balíček provede potřebné aktualizace v souborech /etc/pam.d a také vytvoří soubor s názvem:/etc/pam_ldap.conf. V případě, že se v budoucnu něco změní, můžete se vždy vrátit a tento soubor upravit. Nejdůležitější řádky v tomto souboru jsou:
base cn=users,cn=accounts,dc=yourorgname,dc=com
uri ldap://your.ldap.server/
ldap_version 3
pam_password crypt
Název/adresa vašeho LDAP serveru a vyhledávací báze musí být přesně stejné jako ty, které jsou uvedeny v souborech PostgreSQL pg_hba.conf a Wildfly standalone.xml conf vysvětlených výše. pam_login_attribute výchozí uid. Doporučujeme vám podívat se na soubory /etc/pam.d/common-* a zjistit, co se změnilo po instalaci libpam-ldap. Podle dokumentů můžete vytvořit nový soubor s názvem /etc/pam.d/pgbouncer a definovat v něm všechny možnosti PAM, ale postačí výchozí soubory common-*. Podívejme se do /etc/pam.d/common-auth:
auth [success=2 default=ignore] pam_unix.so nullok_secure
auth [success=1 default=ignore] pam_ldap.so use_first_pass
auth requisite pam_deny.so
auth required pam_permit.so
Nejprve bude zkontrolováno unixové heslo, a pokud to selže, zkontroluje se LDAP, takže mějte na paměti, že budete muset vymazat všechna lokální hesla pro uživatele, kteří jsou definováni jak v místním linux/unix /etc/passwd, tak v LDAP. . Nyní je čas udělat poslední test. Vyberte uživatele, který je definován na vašem LDAP serveru a také vytvořen v PostgreSQL, a zkuste se autentizovat z DB (přes pgsql -h your.pgsql.server ), poté z pgbouncer (také přes psql -h your.pgbouncer.server) a nakonec prostřednictvím vaší aplikace. Právě jste udělali z jediného bezpečnostního systému pro aplikaci, pooler připojení a PostgreSQL realitu!