sql >> Databáze >  >> RDS >> PostgreSQL

Jeden bezpečnostní systém pro aplikaci, sdružování připojení a PostgreSQL – případ LDAP

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 Whitepaper

Konfigurace 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!


  1. Existuje nějaká hashovací funkce v PL/SQL?

  2. Naformátujte číslo jako měnu v SQLite

  3. SELECT v zobrazení obsahuje poddotaz v klauzuli FROM

  4. Nejrychlejší metoda pro SQL Server vkládá, aktualizuje, vybírá