sql >> データベース >  >> RDS >> PostgreSQL

AFTER LOGON(Oracle)は、拡張子が付けられたPostgreSQLでトリガーされます– login_hook

    詳細に入る前に、それを開発および保守するための「ログインフック」拡張機能の作成者に感謝します。

    OracleからPostgresへの移行の演習では、Oracle Databaseイベントトリガー(AFTER LOGON ON)の使用を何度も見ました。ユーザーがデータベースに接続したときに起動するOracleデータベース/ユーザーイベントトリガー(LOGON)の一種で、通常はユーザー環境を設定し、安全なアプリケーションロールに関連付けられた機能を実行するために使用されます。

    たとえば、アプリケーションユーザーがアプリケーションからのみ接続するようにしたいとします。 他のプログラムやクライアント(Oracle / SQL * Plus)からではありません。これは、Oracleでログオン後にデータベースイベントトリガーを作成することで実現できます。

    Postgresはほとんどの標準トリガーをサポートしていますが、AFTERLOGONトリガーはありません。回避策として、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をコンパイルする必要があります。 Postgresで。手順は他の拡張機能のコンパイルと同様に非常に簡単です

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

    これで、この拡張機能を使用する準備が整いました。この例では、アプリケーションユーザーがPostgresクライアント 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の他のプログラム/クライアントからのアプリケーションユーザーの接続を防ぐことができます。

    ありがとうございます。

    –raghav


    1. jdbc:postgresql://192.168.1.8:5432/NexentaSearchに適したドライバーが見つかりません

    2. テーブルの行を更新する方法、または行が存在しない場合は挿入する方法を教えてください。

    3. 外部からDockerコンテナでPostgresqlに接続する

    4. データベースの破損はどのように発生しますか?