विवरण में जाने से पहले, इसे विकसित करने और बनाए रखने के लिए 'लॉगिन हुक' एक्सटेंशन के लेखक को धन्यवाद।
कई बार, Oracle से Postgres प्रवासन अभ्यास में, मैंने Oracle डेटाबेस इवेंट ट्रिगर - आफ्टर लॉगऑन ऑन का उपयोग देखा है। इसका एक प्रकार का Oracle डेटाबेस/उपयोगकर्ता ईवेंट ट्रिगर (LOGON) है जो उपयोगकर्ता द्वारा डेटाबेस से कनेक्ट होने पर सक्रिय होता है, आमतौर पर इसका उपयोग उपयोगकर्ता वातावरण को सेट करने और सुरक्षित एप्लिकेशन भूमिकाओं से जुड़े कार्यों को करने के लिए किया जाता है।
उदाहरण के लिए, मान लें कि हमारे पास एक एप्लिकेशन उपयोगकर्ता है जहां हम चाहते थे कि वह एप्लिकेशन से कनेक्ट हो केवल और किसी अन्य प्रोग्राम या क्लाइंट (ओरेकल/एसक्यूएल * प्लस) से नहीं। इसे Oracle में लॉगऑन ऑन करने के बाद डेटाबेस इवेंट ट्रिगर बनाकर प्राप्त किया जा सकता है।
पोस्टग्रेज अधिकांश मानक ट्रिगर का समर्थन करता है, लेकिन लॉगऑन ट्रिगर के बाद कोई नहीं है। समाधान के लिए, मैंने login_hook
. चुना है एक्सटेंशन जिसने काम बहुत अच्छा किया।
आइए देखें कि एक्सटेंशन की मदद से हम Oracle से Postgres में क्या बदलने जा रहे हैं। Oracle में एक ट्रिगर है जो एप्लिकेशन उपयोगकर्ताओं को अन्य प्रोग्राम/क्लाइंट (sqlplus) से डेटाबेस से कनेक्ट होने से रोकता है।
CREATE OR REPLACE TRIGGER program_restrict
AFTER LOGON ON DATABASE
BEGIN
FOR x IN (SELECT username, program FROM SYS.v_$session WHERE audsid = USERENV ('sessionid'))
LOOP
IF LTRIM (RTRIM (x.username)) = 'MIGUSER' AND UPPER(substr(x.program,1,7)) = 'SQLPLUS'
THEN
raise_application_error(-20999,'Not authorized to use in the Production environment!');
END IF;
END LOOP;
END program_restrict;
उपरोक्त कोड से यह स्पष्ट है कि MIGUSER
(एप्लिकेशन उपयोगकर्ता) SQL*PLUS
. के माध्यम से कनेक्ट करने के लिए प्रतिबंधित है क्लाइंट और उपयोगकर्ता द्वारा किए गए किसी भी प्रयास के परिणामस्वरूप निम्न त्रुटि होगी:
[oracle@rrr ~]$ rlsqlplus miguser/miguser
... <trimmed banner>
ERROR:
ORA-04088: error during execution of trigger 'SYS.PROGRAM_RESTRICT'
ORA-00604: error occurred at recursive SQL level 1
ORA-20999: Not authorized to use in the Production environment!
ORA-06512: at line 6
ORA-06512: at line 6
उपरोक्त आवश्यकता को हल करने के लिए, हमें सबसे पहले एक्सटेंशन को संकलित करना होगा login_hook
पोस्टग्रेज में। किसी भी अन्य एक्सटेंशन संकलन की तरह चरण बहुत सरल हैं
--Download zip/Git clone the extension
https://github.com/splendiddata/login_hook
-- Set the pg_config in your path
[root@node1-centos8 ~]# export PATH=/usr/pgsql-13/bin:$PATH
-- change to login_hook directory and run make/make install
[root@node1-centos8 ~]# cd login_hook
[root@node1-centos8 login_hook]# make
[root@node1-centos8 login_hook]# make install
-- add the login_hook.so to session_preload_libraries and restart the database
[root@node1-centos8 ~]# grep -i session_preload /var/lib/pgsql/13/data/postgresql.conf
session_preload_libraries = 'login_hook'
[root@node1-centos8 ~]# systemctl restart postgresql-13.service
-- connect to the database and create the extension
[postgres@node1-centos8 ~]$ psql
psql (13.1)
Type "help" for help.
postgres=# create extension login_hook;
CREATE EXTENSION
अब, हम इस एक्सटेंशन का उपयोग करने के लिए पूरी तरह तैयार हैं। हमारे मामले में, हम एप्लिकेशन उपयोगकर्ता को पोस्टग्रेज क्लाइंट psql . का उपयोग करने से रोकेंगे . ऐसा करने के लिए, login_hook
. पर दिए गए टेम्पलेट फ़ंक्शन का उपयोग करें विस्तार पृष्ठ और क्लाइंट के एप्लिकेशन नाम को pg_stat_activity . से कैप्चर करने के लिए इसे संशोधित करें pg_terminate_backend() . का उपयोग करके इसे देखें और समाप्त करें सिस्टम फ़ंक्शन। नोट:आप एप्लिकेशन उपयोगकर्ता को प्रबंधित करने के लिए कई उद्देश्यों के लिए एक ही टेम्पलेट फ़ंक्शन का उपयोग कर सकते हैं।
CREATE OR REPLACE FUNCTION login_hook.login() RETURNS VOID LANGUAGE PLPGSQL AS $$
DECLARE
ex_state TEXT;
ex_message TEXT;
ex_detail TEXT;
ex_hint TEXT;
ex_context TEXT;
rec record;
BEGIN
IF NOT login_hook.is_executing_login_hook()
THEN
RAISE EXCEPTION 'The login_hook.login() function should only be invoked by the login_hook code';
END IF;
BEGIN
for rec in select pid,usename,application_name from pg_stat_activity where application_name ilike 'psql%'
loop
if rtrim(rec.usename) = 'miguser' and rtrim(rec.application_name) = 'psql' then
raise notice 'Application users(%) restricted to connect with any clients(%)',rec.usename,rec.application_name;
perform pg_terminate_backend(rec.pid);
end if;
end loop;
EXCEPTION
WHEN OTHERS THEN
GET STACKED DIAGNOSTICS ex_state = RETURNED_SQLSTATE
, ex_message = MESSAGE_TEXT
, ex_detail = PG_EXCEPTION_DETAIL
, ex_hint = PG_EXCEPTION_HINT
, ex_context = PG_EXCEPTION_CONTEXT;
RAISE LOG e'Error in login_hook.login()\nsqlstate: %\nmessage : %\ndetail : %\nhint : %\ncontext : %'
, ex_state
, ex_message
, ex_detail
, ex_hint
, ex_context;
END ;
END$$;
-- Give exeuction grant on the function.
GRANT EXECUTE ON FUNCTION login_hook.login() TO PUBLIC;
अब, देखते हैं कि एप्लिकेशन उपयोगकर्ता Postgres psql
. का उपयोग कर सकता है या नहीं डेटाबेस से कनेक्ट करने के लिए।
[postgres@node1-centos8 ~]$ psql -U miguser -d postgres -p 5432
NOTICE: Application users(miguser) restricted to connect with any clients(psql)
psql: error: FATAL: terminating connection due to administrator command
CONTEXT: SQL statement "SELECT pg_terminate_backend(rec.pid)"
PL/pgSQL function login_hook.login() line 20 at PERFORM
SQL statement "select login_hook.login()
ठंडा। हम Postgres में किसी अन्य प्रोग्राम/क्लाइंट से एप्लिकेशन उपयोगकर्ता कनेक्शन को रोकने में सक्षम हैं।
धन्यवाद।
-राघव