Secara tradisional, aplikasi tipikal terdiri dari komponen berikut:
Dalam kasus sederhana ini, pengaturan dasar sudah cukup:
- aplikasi menggunakan mekanisme otentikasi lokal sederhana untuk penggunanya
- aplikasi menggunakan kumpulan koneksi sederhana
- ada satu pengguna yang ditentukan untuk akses database
Namun, seiring berkembangnya organisasi dan semakin besar, semakin banyak komponen yang ditambahkan:
- lebih banyak aplikasi penyewa atau contoh aplikasi yang mengakses database
- lebih banyak layanan dan sistem yang mengakses database
- otentikasi/otorisasi pusat (AA) untuk semua (atau sebagian besar) layanan
- pemisahan komponen untuk penskalaan yang lebih mudah di masa mendatang
Dalam skema di atas, semua masalah dipisahkan menjadi komponen individu, masing-masing komponen memiliki tujuan khusus. Namun, kumpulan koneksi tetap menggunakan satu pengguna database khusus seperti pada pengaturan sederhana sebelumnya yang kita lihat di atas.
Selain komponen baru, persyaratan baru juga datang:
- kontrol berbutir halus yang lebih baik atas apa yang dapat dilakukan pengguna di tingkat basis data
- mengaudit
- pencatatan log sistem yang lebih baik dan bermanfaat
Kami selalu dapat mengimplementasikan ketiganya dengan lebih banyak kode aplikasi atau lebih banyak lapisan dalam aplikasi, tetapi ini tidak praktis dan sulit untuk dipelihara.
Selain itu, PostgreSQL menawarkan serangkaian solusi yang kaya pada area yang disebutkan di atas (keamanan, Keamanan Tingkat Baris, audit, dll.) sehingga sangat masuk akal untuk memindahkan semua layanan tersebut ke lapisan basis data. Untuk mengambil layanan tersebut langsung dari database, kita harus melupakan pengguna tunggal dalam database dan menggunakan pengguna individu yang sebenarnya.
Ini membawa kita ke skema seperti di bawah ini:
Dalam kasus penggunaan kami, kami akan menjelaskan pengaturan perusahaan tipikal yang terdiri dari skema di atas di mana kami menggunakan:
- Server aplikasi Wildfly (contoh ditampilkan untuk versi 10)
- Layanan Otentikasi/Otorisasi LDAP
- pengumpul koneksi pgbouncer
- PostgreSQL 10
Sepertinya pengaturan biasa, karena jboss/wildfly telah mendukung otentikasi dan otorisasi LDAP selama bertahun-tahun, PostgreSQL telah mendukung LDAP selama bertahun-tahun.
Namun pgbouncer hanya memulai dukungan untuk LDAP (dan ini melalui PAM) sejak versi 1.8 pada akhir 2017, yang berarti bahwa seseorang hingga saat itu tidak dapat menggunakan kumpulan koneksi PostgreSQL terpanas dalam pengaturan perusahaan seperti itu (yang tidak terdengar menjanjikan oleh sudut mana pun yang kami pilih untuk melihatnya)!
Di blog ini, kami akan menjelaskan setup yang dibutuhkan di setiap layer.
Konfigurasi Wildfly 10
Konfigurasi sumber data akan terlihat seperti ini, saya menunjukkan hal yang paling penting:
<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>
Saya telah menebalkan parameter dan nilai penting. Ingatlah untuk menentukan alamat IP (atau nama host), nama database, dan port sesuai dengan pengaturan server pgbouncer Anda.
Selain itu, alih-alih nama pengguna/sandi biasa, Anda harus memiliki domain keamanan yang ditentukan, yang harus ditentukan di bagian sumber data seperti yang ditunjukkan di atas. Definisinya akan terlihat seperti:
<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>
Dengan cara ini wildfly akan mendelegasikan konteks keamanan ke pgbouncer.
CATATAN: di blog ini kami membahas dasar-dasarnya, yaitu kami tidak menggunakan atau menyebutkan TLS, namun Anda sangat dianjurkan untuk menggunakannya dalam instalasi Anda.
Pengguna wildfly harus mengautentikasi terhadap server LDAP Anda sebagai berikut:
<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>
File konfigurasi di atas berlaku untuk wildfly 10.0, Anda disarankan untuk berkonsultasi dengan dokumentasi resmi untuk lingkungan Anda.
Konfigurasi PostgreSQL
Untuk memberi tahu PostgreSQL untuk mengautentikasi (CATATAN: tidak mengizinkan!) terhadap server LDAP Anda, Anda harus membuat perubahan yang sesuai pada postgresql.conf dan pg_hba.conf. Entri yang menarik adalah sebagai berikut:
Di postgresql.conf:
listen_addresses = '*'
dan di 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"
Pastikan setelan LDAP yang ditentukan di sini sama persis dengan yang Anda tetapkan di konfigurasi server aplikasi Anda. Ada dua mode operasi yang PostgreSQL dapat diinstruksikan untuk menghubungi server LDAP:
- ikatan sederhana
- cari lalu ikat
Mode pengikatan sederhana hanya memerlukan satu koneksi ke server LDAP oleh karena itu lebih cepat tetapi memerlukan organisasi kamus LDAP yang lebih ketat daripada mode kedua. Mode pencarian dan ikat memungkinkan fleksibilitas yang lebih besar. Namun, untuk direktori LDAP rata-rata, mode pertama (ikatan sederhana) akan berfungsi dengan baik. Kami harus menggarisbawahi poin-poin tertentu tentang otentikasi LDAP PostgreSQL:
- Ini ada hubungannya dengan otentikasi saja (memeriksa kata sandi).
- Keanggotaan peran masih dilakukan di PostgreSQL, seperti biasa.
- Pengguna harus dibuat di PostgreSQL (melalui CREATE user/role) seperti biasa.
Ada beberapa solusi untuk membantu sinkronisasi antara pengguna LDAP dan PostgreSQL (mis. ldap2pg) atau Anda cukup menulis pembungkus Anda sendiri yang akan menangani LDAP dan PostgreSQL untuk menambah atau menghapus pengguna.
Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh WhitepaperKonfigurasi PgBouncer
Ini adalah bagian tersulit dari pengaturan kami, karena fakta bahwa dukungan LDAP asli masih hilang dari pgbouncer, dan satu-satunya pilihan adalah mengautentikasi melalui PAM, yang berarti bahwa ini tergantung pada pengaturan UNIX/Linux PAM lokal yang benar untuk LDAP.
Jadi prosedurnya dibagi menjadi dua langkah.
Langkah pertama adalah mengonfigurasi dan menguji apakah pgbouncer berfungsi dengan PAM, dan langkah kedua adalah mengonfigurasi PAM agar berfungsi dengan LDAP.
pgbouncer
pgbouncer harus dikompilasi dengan dukungan PAM. Untuk melakukannya, Anda harus:
- instal libpam0g-dev
- ./configure --with-pam
- kompilasi ulang dan instal pgbouncer
pgbouncer.ini Anda (atau nama file konfigurasi pgbouncer Anda) harus dikonfigurasi untuk pam. Juga, itu harus berisi parameter yang benar untuk database dan aplikasi Anda sesuai dengan parameter yang dijelaskan di bagian di atas. Hal-hal yang harus Anda definisikan atau ubah:
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
Tentu saja, Anda harus membaca dokumen pgbouncer dan menyetel pgbouncer Anda sesuai dengan kebutuhan Anda. Untuk menguji pengaturan di atas, yang harus Anda lakukan adalah membuat pengguna UNIX lokal baru dan mencoba mengautentikasi ke pgbouncer:
# adduser testuser
<answer to all question, including password>
Agar pgbouncer bekerja dengan PAM saat membaca dari file passwd lokal, pgbouncer yang dapat dieksekusi harus dimiliki oleh root dan dengan 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
Catatan:Perlunya kepemilikan root dan setuid (yang berlaku untuk setiap sistem debian/ubuntu yang telah saya uji) tidak didokumentasikan di mana pun, baik di dokumen pgbouncer resmi maupun di mana pun di internet.
Kemudian kita login (sebagai superuser pgsql) ke host postgresql (atau psql -h your.pgsql.server) dan membuat user baru:
CREATE USER testuser PASSWORD 'same as the UNIX passwd you gave above';
lalu dari host pgbouncer:
psql -h localhost -p 6432 yourdbname -U testuser
Anda seharusnya bisa mendapatkan prompt dan melihat tabel seolah-olah Anda terhubung langsung ke server database Anda. Ingatlah untuk menghapus pengguna ini dari sistem dan juga keluar dari database ketika Anda selesai dengan semua pengujian Anda.
PAM
Agar PAM dapat berinteraksi dengan server LDAP, diperlukan paket tambahan:libpam-ldap . Skrip pasca pemasangannya akan menjalankan dialog mode teks yang harus Anda jawab dengan parameter yang benar untuk server LDAP Anda. Paket ini akan membuat pembaruan yang diperlukan di file /etc/pam.d dan juga membuat file bernama:/etc/pam_ldap.conf. Jika ada perubahan di masa mendatang, Anda selalu dapat kembali dan mengedit file ini. Baris terpenting dalam file ini adalah:
base cn=users,cn=accounts,dc=yourorgname,dc=com
uri ldap://your.ldap.server/
ldap_version 3
pam_password crypt
Nama/alamat server LDAP Anda dan basis pencarian harus sama persis dengan yang ditentukan dalam pg_hba.conf PostgreSQL dan file conf Wildfly standalone.xml yang dijelaskan di atas. pam_login_attribute default ke uid. Anda dianjurkan untuk melihat file /etc/pam.d/common-* dan melihat apa yang berubah setelah instalasi libpam-ldap. Mengikuti dokumen, Anda dapat membuat file baru bernama /etc/pam.d/pgbouncer dan menentukan semua opsi PAM di sana, tetapi file common-* default sudah cukup. Mari kita lihat di /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
Unix passwd akan diperiksa terlebih dahulu, dan jika gagal maka LDAP akan diperiksa, jadi ingatlah bahwa Anda harus menghapus kata sandi lokal apa pun untuk pengguna yang ditetapkan ke linux/unix /etc/passwd lokal dan di LDAP . Sekarang saatnya untuk melakukan tes akhir. Pilih pengguna yang ditentukan di server LDAP Anda dan juga dibuat di PostgreSQL, dan coba autentikasi dari DB (via pgsql -h your.pgsql.server ), lalu dari pgbouncer (juga melalui psql -h your.pgbouncer.server) , dan terakhir melalui aplikasi Anda. Anda baru saja mewujudkan satu sistem keamanan tunggal untuk aplikasi, kumpulan koneksi, dan PostgreSQL!