sql >> Database >  >> RDS >> PostgreSQL

NA LOGON (Oracle) trigger in PostgreSQL met extensie – login_hook

Alvorens in te gaan op de details, dank aan de auteur van de 'login hook'-extensie voor het ontwikkelen en onderhouden ervan.

In de migratie-oefening van Oracle naar Postgres heb ik vaak het gebruik van Oracle Database Event-trigger gezien - NA AANMELDEN. Het is een type Oracle database/user event trigger (LOGON) dat wordt geactiveerd wanneer een gebruiker verbinding maakt met een database, meestal gebruikt om de gebruikersomgeving in te stellen en functies uit te voeren die zijn gekoppeld aan veilige applicatierollen.

Laten we bijvoorbeeld zeggen dat we een applicatiegebruiker hebben waarvan we wilden dat hij verbinding zou maken vanuit de applicatie ALLEEN en niet van andere programma's of clients (Oracle/SQL*Plus). Dit kan worden bereikt door een databasegebeurtenis-trigger te maken NA AANMELDING in Oracle.

Postgres ondersteunt de meeste standaardtriggers, maar er is geen NA AANMELDEN-trigger. Als tijdelijke oplossing selecteerde ik login_hook extensie die het werk redelijk goed deed.

Laten we eens kijken wat we gaan converteren van Oracle naar Postgres met behulp van extensie. Er is een trigger in Oracle die voorkomt dat de applicatiegebruikers verbinding maken met de database vanuit andere programma's/clients (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;

Uit de bovenstaande code is het duidelijk dat MIGUSER (toepassingsgebruiker) is beperkt om verbinding te maken via SQL*PLUS client en elke poging van de gebruiker zal resulteren in de volgende fout:

[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

Om bovenstaande vereiste te omzeilen, moeten we eerst de extensie login_hook compile compileren in Postgres. Stappen zijn heel eenvoudig zoals elke andere extensiecompilatie

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

Nu zijn we helemaal klaar om deze extensie te gebruiken. In ons geval zullen we voorkomen dat de applicatiegebruiker Postgres-client psql gebruikt . Gebruik hiervoor de sjabloonfunctie op de login_hook extensiepagina en wijzig deze om de applicatienaam van de klant vast te leggen van pg_stat_activity bekijk en beëindig het met pg_terminate_backend() systeem functie. Opmerking:u kunt dezelfde sjabloonfunctie voor verschillende doeleinden gebruiken om de toepassingsgebruiker te beheren.

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;

Laten we nu eens kijken of de applicatiegebruiker Postgres psql . kan gebruiken om verbinding te maken met de database.

[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()

Stoer. We kunnen voorkomen dat de gebruikers van de applicatie verbinding maken met een ander programma/client in Postgres.

Dank je.

–Raghav


  1. Beveiligingsoverwegingen voor MariaDB-implementaties in een hybride cloudomgeving

  2. Caculate punt 50 mijl afstand (Noord, 45% NE, 45% ZW)

  3. Migreren van MySQL Enterprise naar MariaDB 10.3

  4. Hoe kan ik de querycache van SQL Server wissen?