PostgreSQL ने लंबे समय से SSL कनेक्शन और प्रमाणपत्र-आधारित प्रमाणीकरण तंत्र का समर्थन किया है। हालांकि इस संबंध में PostgreSQL दुनिया के लिए कुछ भी नया नहीं लगता है। हालांकि, क्लाइंट कनेक्शन (क्लाइंट-प्रमाणपत्र आधारित प्रमाणीकरण) के लिए एक छोटी सी परेशानी वाली समस्या एन्क्रिप्टेड क्लाइंट कुंजी के लिए "पीईएम पास वाक्यांश दर्ज करें:" एक संकेत था।
PostgreSQL 13 में एक नई सुविधा 'ssl_passphrase_command' सर्वर पैरामीटर की तारीफ करती है। जबकि ssl_passphrase_command पैरामीटर सर्वर व्यवस्थापकों को सर्वर प्रमाणपत्रों के लिए उपयोग की जाने वाली एन्क्रिप्टेड सर्वर कुंजियों के लिए पासफ़्रेज़ निर्दिष्ट करने की अनुमति देता है; नया शुरू किया गया कनेक्शन पैरामीटर 'sslpassword' क्लाइंट कनेक्शन के लिए कुछ हद तक समान नियंत्रण देता है।
इन्फ्रास्ट्रक्चर पर एक नजर
इस सुविधा विश्लेषण के लिए व्यावहारिक अभ्यास करने के लिए, मैंने एक बहुत ही बुनियादी प्रणाली स्थापित की है:
- दो वर्चुअल मशीन
- pgServer ( 172.25.130.189 )
- pgClient ( 172.25.130.178 )
- pgServer पर स्व-हस्ताक्षरित प्रमाणपत्र
- PostgreSQL 13 दोनों मशीनों पर स्थापित है
- एक नमूना libpq प्रोग्राम को संकलित करने के लिए gcc
सर्वर सेट करना
सुविधा का विश्लेषण करने के लिए, आइए पहले प्रासंगिक प्रमाणपत्रों और pgServer वर्चुअल मशीन पर संबंधित कॉन्फ़िगरेशन के साथ PostgreSQL 13 सर्वर इंस्टेंस सेट करें।
[[email protected]]$ echo ${HOME}
/var/lib/pgsql/
[[email protected]]$ mkdir ~/server_certs/
[[email protected]]$ openssl genrsa -des3 -passout pass:secretserverpass -out ~/server_certs/server.key
[[email protected]]$ openssl req -new -key ~/server_certs/server.key -days 365 -out ~/server_certs/server.crt -x509 -subj "/C=AU/ST=NSW/L=DY/O=MyOrg/OU=Dev/CN=pgServer"
Enter pass phrase for /var/lib/pgsql/server_certs/server.key:
[[email protected]]$ chmod 0600 /var/lib/pgsql/server_certs/server.key
[[email protected]]$ cp ~/server_certs/server.crt ~/server_certs/root.crt
उपरोक्त आदेश एक कुंजी का उपयोग करके एक स्व-हस्ताक्षरित प्रमाणपत्र उत्पन्न कर रहे हैं जो एक पासफ़्रेज़ द्वारा सुरक्षित है। PostgreSQL द्वारा आवश्यकतानुसार server.key की अनुमतियाँ प्रतिबंधित हैं। इन प्रमाणपत्रों का उपयोग करने के लिए PostgreSQL इंस्टेंस को कॉन्फ़िगर करना अब कोई जादू नहीं है। पहले निम्न का उपयोग करके आधार डेटा फ़ोल्डर बनाएं:
[[email protected]]$ initdb
और जेनरेट किए गए postgresql.conf में निम्नलिखित कॉन्फ़िगरेशन पैरामीटर पेस्ट करें:
ssl=on
ssl_cert_file='/var/lib/pgsql/server_certs/server.crt'
ssl_key_file='/var/lib/pgsql/server_certs/server.key'
ssl_ca_file='/var/lib/pgsql/server_certs/root.crt'
ssl_passphrase_command = 'echo secretserverpass'
listen_addresses = '172.25.130.189'
और यह भी सुनिश्चित करें कि pgClient नोड से एक SSL कनेक्शन स्वीकार किया गया है और जेनरेट किए गए pg_hba.conf में निम्न पंक्ति चिपकाकर प्रमाणपत्र प्रमाणीकरण तंत्र का उपयोग कर सकता है:
hostssl all all 172.25.130.178/32 cert clientcert=1
अब केवल pg_ctl कमांड का उपयोग करके सर्वर को उपरोक्त कॉन्फ़िगरेशन के साथ प्रारंभ करने की आवश्यकता है:
[[email protected]]$ pg_ctl start
क्लाइंट सेट करना
अगला चरण क्लाइंट प्रमाणपत्र जेनरेट करना होगा जो उपरोक्त सर्वर प्रमाणपत्रों द्वारा हस्ताक्षरित हैं:
[[email protected]]$ mkdir ~/client_certs/
[[email protected]]$ openssl genrsa -des3 -passout pass:secretclientpass -out ~/client_certs/postgresql.key
[[email protected]]$ openssl req -new -key ~/client_certs/postgresql.key -out ~/client_certs/postgresql.csr -subj "/C=AU/ST=NSW/L=DY/O=MyOrg/OU=Dev/CN=postgres"
Enter pass phrase for ~/client_certs/postgresql.key:
उपरोक्त चरण में, एक एन्क्रिप्टेड क्लाइंट कुंजी और क्लाइंट प्रमाणपत्र के लिए एक सीएसआर उत्पन्न होता है। निम्न चरण क्लाइंट प्रमाणपत्र को सर्वर रूट प्रमाणपत्र और सर्वर कुंजी का उपयोग करके हस्ताक्षर करके पूरा करते हैं।
[[email protected]]$ openssl x509 -req -in ~/client_certs/postgresql.csr -CA ~/server_certs/root.crt -CAkey ~/server_certs/server.key -out ~/client_certs/postgresql.crt -CAcreateserial
Signature ok
subject=/C=AU/ST=NSW/L=DY/O=MyOrg/OU=Dev/CN=postgres
Getting CA Private Key
Enter pass phrase for /var/lib/pgsql/server_certs/server.key:
सर्टिफिकेट में CN नाम याद रखने वाला एक महत्वपूर्ण पहलू है। इसे इकाई की पहचान या नाम के रूप में अधिक मानें। उपरोक्त क्लाइंट प्रमाणपत्र में, यदि CN को 'पोस्टग्रेज़' पर सेट किया गया है, तो यह पोस्टग्रेज़ नामक भूमिका के लिए अभिप्रेत है। साथ ही सर्वर प्रमाणपत्र सेट करते समय, हमने CN=pgServer; यह महत्वपूर्ण हो सकता है जब हम एसएसएल कनेक्शन के एक सत्यापन-पूर्ण मोड का उपयोग करते हैं।
SSL कनेक्शन को आज़माने के लिए क्लाइंट मशीन पर प्रमाणपत्र कॉपी करने का समय:
[[email protected]]$ scp -r client_certs/* [email protected]:~/.postgresql
लिनक्स/यूनिक्स परिवेशों पर डिफ़ॉल्ट रूप से, जब एसएसएल कनेक्शन बनाने के लिए psql का उपयोग किया जाता है, तो यह वर्तमान उपयोगकर्ता के '${HOME}/.postgresql' में प्रमाणपत्र/कुंजी खोजता है। इन सभी फाइलों को कनेक्शन पैरामीटर में भी निर्दिष्ट किया जा सकता है - हालांकि, इससे वह चीज खराब हो जाती जिसे हम परीक्षण करना चाहते हैं।
pgClient मशीन पर, यह सुनिश्चित करने के लिए कि PostgreSQL इसे स्वीकार करता है, postgresql.key की अनुमति को बदलें।
[[email protected]]$ chmod 0600 ~/.postgresql/postgresql.key
सुविधा का परीक्षण
PSQL कनेक्शन पैरामीटर
पर्यावरण की स्थापना के साथ हम काफी कुछ कर चुके हैं। आइए SSL कनेक्शन बनाने का प्रयास करें:
[[email protected]]$ psql "host=172.25.130.189 port=5432 user=postgres dbname=postgres sslmode=prefer"
Enter PEM pass phrase:
अच्छा! यह सब उपरोक्त संकेत के साथ ही शुरू हुआ। अगर हमारे पास बैच प्रोग्राम या ऑटोमेशन स्क्रिप्ट है, तो प्रॉम्प्ट को हैंडल करना थोड़ा मुश्किल है। कनेक्शन स्ट्रिंग में पैरामीटर 'sslpassword' के नए जोड़े के साथ, अब इसे नीचे निर्दिष्ट करना आसान है:
[[email protected]]$ psql "host=172.25.130.189 port=5432 user=postgres dbname=postgres sslmode=prefer sslpassword=secretclientpass"
इसके बाद, बिना किसी संकेत के कनेक्शन सफल होना चाहिए।
SSL पासवर्ड के लिए Libpq Hook
कहानी जारी है - Libpq इंटरफ़ेस में एक हुक फ़ंक्शन 'PQsetSSLKeyPassHook_OpenSSL' जोड़ा गया है। इसका उपयोग क्लाइंट अनुप्रयोगों द्वारा किया जा सकता है जिनके पास कुंजी पासफ़्रेज़ तक पहुंच नहीं हो सकती है और कुछ जटिल तर्क का उपयोग करके बाहरी इंटरफ़ेस से उत्पन्न/प्राप्त करने की आवश्यकता होती है।
void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook);
इस हुक का उपयोग करके PQsslKeyPassHook_OpenSSL_type प्रकार का कॉल-बैक फ़ंक्शन पंजीकृत किया जा सकता है। पासफ़्रेज़ प्राप्त करने की आवश्यकता होने पर Libpq द्वारा कॉल-बैक का आह्वान किया जाएगा। ऐसे कॉल बैक फ़ंक्शन के हस्ताक्षर होने चाहिए:
int my_callback_function(char *buf, int size, PGconn *conn);
नीचे एक नमूना कार्यक्रम 'client_conn.c' है - जो ऐसे हुक के एकीकरण को प्रदर्शित करता है:
#include <stdlib.h>
#include <string.h>
#include "libpq-fe.h"
void do_exit(PGconn *conn) {
PQfinish(conn);
exit(1);
}
/**
* For PQsetSSLKeyPassHook_OpenSSL to provide password for SSL Key
**/
int ssl_password_provider(char *buf, int size, PGconn *conn)
{
const char * default_key_password = "secretclientpass";
strcpy(buf, default_key_password);
return strlen(default_key_password);
}
/**
* Sample program to make a connection and check server version
*/
int main()
{
PQsetSSLKeyPassHook_OpenSSL( ssl_password_provider );
PGconn *conn = PQconnectdb("host=172.25.130.189 port=5413 user=postgres dbname=postgres sslmode=prefer");
if (PQstatus(conn) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to DB failed: %s\n", PQerrorMessage(conn));
do_exit(conn);
}
printf("Server version: %d\n", PQserverVersion(conn));
PQfinish(conn);
return 0;
}
संकलित करें और इसे चलाकर देखें कि क्या यह वास्तव में काम करता है:
[[email protected]]$ gcc -DUSE_OPENSSL -I/usr/pgsql-13/include/ -lpq -L/usr/pgsql-13/lib/ client_conn.c -o client_conn
[[email protected]]$ client_conn
[[email protected]]$ ./client_conn
Server version: 130000
सावधानी का एक अंतिम शब्द
उपरोक्त ब्लॉग PostgreSQL में प्रमाणपत्र आधारित प्रमाणीकरण के लिए Libpq/psql कनेक्शन पैरामीटर में एक छोटा लेकिन उपयोगी परिवर्तन दिखाता है। लेकिन, सावधानी की बात - उपरोक्त व्यावहारिक अभ्यास में हम स्व-हस्ताक्षरित प्रमाणपत्रों का उपयोग कर रहे हैं; हो सकता है कि यह आपके संगठन/उत्पादन परिवेश में बहुत अच्छी तरह से फिट न हो। आप ऐसे SSL सेटअप का उपयोग करने के लिए कुछ तृतीय पक्ष प्रमाणपत्र प्राप्त करना चाह सकते हैं।