I varje IT-system där viktiga affärsuppgifter äger rum är det viktigt att ha en tydlig uppsättning policyer och rutiner och att se till att de respekteras och följs.
Introduktion till revision
En IT-systemrevision är en granskning av en organisations policyer, processer, procedurer och praxis avseende IT-infrastruktur mot en viss uppsättning mål. En IT-revision kan vara av två generiska typer:
- Kontrollerar mot en uppsättning standarder på en begränsad delmängd av data
- Kontrollerar hela systemet
En IT-revision kan omfatta vissa kritiska systemdelar, till exempel de som är relaterade till finansiell data för att stödja en specifik uppsättning regelverk (t.ex. SOX), eller hela säkerhetsinfrastrukturen mot regelverk som den nya EU GDPR-förordningen som adresserar behovet för att skydda integriteten och sätter riktlinjerna för personuppgiftshantering. SOX-exemplet är av den förra typen som beskrivs ovan medan GDPR är av den senare.
Revisionens livscykel
Planering
omfattningen av en revision är beroende av revisionsmålet. Omfattningen kan omfatta en speciell applikation identifierad av en specifik affärsverksamhet, såsom en finansiell verksamhet, eller hela IT-infrastrukturen som omfattar systemsäkerhet, datasäkerhet och så vidare. Omfattningen måste vara korrekt identifierad i förväg som ett tidigt steg i den inledande planeringsfasen. Organisationen är tänkt att ge revisorn all nödvändig bakgrundsinformation för att hjälpa till med planering av revisionen. Detta kan vara funktionella/tekniska specifikationer, systemarkitekturdiagram eller annan information som efterfrågas.
Kontrollmål
Utifrån omfattningen bildar revisorn en uppsättning kontrollmål som ska prövas av revisionen. Dessa kontrollmål implementeras via förvaltningspraxis som är tänkt att finnas för att uppnå kontroll i den utsträckning som beskrivs av omfattningen. Kontrollmålen är knutna till testplaner och de utgör tillsammans revisionsprogrammet. Baserat på revisionsprogrammet organisationen under revision avsätter resurser för att underlätta revisorn.
Resultat
Revisorn försöker få bevis för att alla kontrollmål är uppfyllda. Om det för något kontrollmål inte finns några sådana bevis, försöker revisorn först se om det finns något alternativt sätt som företaget hanterar det specifika kontrollmålet på, och om det finns ett sådant sätt markeras detta kontrollmål som kompenserande och revisorn anser att målet är uppfyllt. Om det däremot inte finns några bevis alls för att ett mål uppnås, markeras detta som ett fynd . Varje fynd består av tillstånd, kriterier, orsak, verkan och rekommendation. IT-chefen måste ha nära kontakt med revisorn för att få information om alla potentiella fynd och se till att all efterfrågad information delas mellan ledningen och revisorn för att säkerställa att kontrollmålet uppfylls (och därmed undvika hitta).
Utvärderingsrapporten
I slutet av revisionsprocessen kommer revisorn att skriva en utvärderingsrapport som en sammanfattning som täcker alla viktiga delar av revisionen, inklusive eventuella iakttagelser följt av ett uttalande om huruvida målet är tillfredsställande och rekommendationer för att eliminera effekterna av resultaten.
Vad är revisionsloggning och varför bör du göra det?
Revisorn vill ha full tillgång till ändringarna på programvara, data och säkerhetssystemet. Han/hon vill inte bara kunna spåra eventuella förändringar av affärsdata, utan också spåra förändringar i organisationsschemat, säkerhetspolicyn, definitionen av roller/grupper och förändringar av roll/gruppmedlemskap. Det vanligaste sättet att utföra en revision är via loggning. Även om det tidigare var möjligt att klara en IT-revision utan loggfiler, är det idag det föredragna (om inte det enda) sättet.
Vanligtvis består det genomsnittliga IT-systemet av minst två lager:
- Databas
- Applikation (möjligen ovanpå en applikationsserver)
Applikationen upprätthåller sina egna loggar som täcker användaråtkomst och åtgärder, och databasen och eventuellt applikationsserversystemen upprätthåller sina egna loggar. Ren, lättanvänd information i loggfiler som har verkligt affärsvärde ur revisorns perspektiv kallas revisionsspår . Granskningsspår skiljer sig från vanliga loggfiler (ibland kallade inbyggda loggar) genom att:
- Loggfiler är oundgängliga
- Revisionsspår bör behållas under längre perioder
- Loggfiler lägger till overhead till systemets resurser
- Syftet med loggfiler är att hjälpa systemadministratören
- Revisionsspårens syfte är att hjälpa revisorn
Vi sammanfattar ovanstående i följande tabell:
Loggtyp | App/System | Revisionsvägvänlig |
---|---|---|
Apploggar | App | Ja |
Appserverloggar | System | Nej |
Databasloggar | System | Nej |
Apploggar kan enkelt skräddarsys för att användas som revisionsspår. Systemloggar inte så lätt eftersom:
- De begränsas i sitt format av systemprogramvaran
- De agerar globalt på hela systemet
- De har inte direkt kunskap om specifika affärssammanhang
- De kräver vanligtvis ytterligare programvara för senare offlineanalys/bearbetning för att skapa användbara revisionsvänliga granskningsspår.
Å andra sidan placerar apploggar ett extra mjukvarulager ovanpå de faktiska uppgifterna, alltså:
- Göra revisionssystemet mer sårbart för programbuggar/felkonfiguration
- Skapa ett potentiellt hål i loggningsprocessen om någon försöker komma åt data direkt i databasen förbi apploggningssystemet, till exempel en privilegierad användare eller en DBA
- Göra revisionssystemet mer komplext och svårare att hantera och underhålla om vi har många applikationer eller många programvaruteam.
Så, helst skulle vi leta efter det bästa av de två:Att ha användbara granskningsspår med den största täckningen i hela systemet inklusive databaslager, och konfigurerbara på ett ställe, så att själva loggningen enkelt kan granskas med hjälp av andra ( system) loggar.
Revisionsloggning med PostgreSQL
Alternativen vi har i PostgreSQL angående revisionsloggning är följande:
- Genom att använda uttömmande loggning ( log_statement =alla )
- Genom att skriva en anpassad triggerlösning
- Genom att använda vanliga PostgreSQL-verktyg som tillhandahålls av communityn, såsom
- audit-trigger 91plus (https://github.com/2ndQuadrant/audit-trigger)
- pgaudit-tillägg (https://github.com/pgaudit/pgaudit)
Uttömmande loggning åtminstone för standardanvändning i OLTP- eller OLAP-arbetsbelastningar bör undvikas eftersom:
- Producerar enorma filer, ökar belastningen
- Har ingen inre kunskap om tabeller som nås eller ändras, skriver bara ut påståendet som kan vara ett DO-block med en kryptisk sammanlänkning
- Behöver ytterligare programvara/resurser för offlineanalys och bearbetning (för att producera revisionsspåren) som i sin tur måste inkluderas i granskningens omfattning för att anses trovärdig
I resten av den här artikeln kommer vi att prova verktygen som tillhandahålls av communityn. Låt oss anta att vi har den här enkla tabellen som vi vill granska:
myshop=# \d orders
Table "public.orders"
Column | Type | Collation | Nullable | Default
------------+--------------------------+-----------+----------+------------------------------------
id | integer | | not null | nextval('orders_id_seq'::regclass)
customerid | integer | | not null |
customer | text | | not null |
xtime | timestamp with time zone | | not null | now()
productid | integer | | not null |
product | text | | not null |
quantity | integer | | not null |
unit_price | double precision | | not null |
cur | character varying(20) | | not null | 'EUR'::character varying
Indexes:
"orders_pkey" PRIMARY KEY, btree (id)
revisionstrigger 91plus
Dokumenten om att använda triggern finns här:https://wiki.postgresql.org/wiki/Audit_trigger_91plus. Först laddar vi ner och installerar den medföljande DDL (funktioner, schema):
$ wget https://raw.githubusercontent.com/2ndQuadrant/audit-trigger/master/audit.sql
$ psql myshop
psql (10.3 (Debian 10.3-1.pgdg80+1))
Type "help" for help.
myshop=# \i audit.sql
Sedan definierar vi utlösare för våra bordsbeställningar med den grundläggande användningen:
myshop=# SELECT audit.audit_table('orders');
Detta kommer att skapa två utlösare för bordsorder:en radutlösare insert_update_delere och en utlösare för trunkering. Låt oss nu se vad utlösaren gör:
myshop=# insert into orders (customer,customerid,product,productid,unit_price,quantity) VALUES('magicbattler',1,'some fn skin 2',2,5,2);
INSERT 0 1
myshop=# update orders set quantity=3 where id=2;
UPDATE 1
myshop=# delete from orders where id=2;
DELETE 1
myshop=# select table_name, action, session_user_name, action_tstamp_clk, row_data, changed_fields from audit.logged_actions;
-[ RECORD 1 ]-----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
table_name | orders
action | I
session_user_name | postgres
action_tstamp_clk | 2018-05-20 00:15:10.887268+03
row_data | "id"=>"2", "cur"=>"EUR", "xtime"=>"2018-05-20 00:15:10.883801+03", "product"=>"some fn skin 2", "customer"=>"magicbattler", "quantity"=>"2", "productid"=>"2", "customerid"=>"1", "unit_price"=>"5"
changed_fields |
-[ RECORD 2 ]-----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
table_name | orders
action | U
session_user_name | postgres
action_tstamp_clk | 2018-05-20 00:16:12.829065+03
row_data | "id"=>"2", "cur"=>"EUR", "xtime"=>"2018-05-20 00:15:10.883801+03", "product"=>"some fn skin 2", "customer"=>"magicbattler", "quantity"=>"2", "productid"=>"2", "customerid"=>"1", "unit_price"=>"5"
changed_fields | "quantity"=>"3"
-[ RECORD 3 ]-----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
table_name | orders
action | D
session_user_name | postgres
action_tstamp_clk | 2018-05-20 00:16:24.944117+03
row_data | "id"=>"2", "cur"=>"EUR", "xtime"=>"2018-05-20 00:15:10.883801+03", "product"=>"some fn skin 2", "customer"=>"magicbattler", "quantity"=>"3", "productid"=>"2", "customerid"=>"1", "unit_price"=>"5"
changed_fields |
Notera värdet change_fields på uppdateringen (RECORD 2). Det finns mer avancerad användning av granskningsutlösaren, som att exkludera kolumner eller använda WHEN-satsen som visas i dokumentet. Granskningsutlösaren verkar verkligen göra jobbet med att skapa användbara granskningsspår i tabellen audit.logged_actions. Det finns dock några varningar:
- Inga SELECTs (triggers aktiveras inte på SELECTs) eller DDL spåras
- Ändringar av bordsägare och superanvändare kan enkelt manipuleras
- Bästa tillvägagångssätt måste följas när det gäller appanvändare(r) och appschema och tabellägare
Pgaudit
Pgaudit är det senaste tillskottet till PostgreSQL när det gäller revision. Pgaudit måste installeras som ett tillägg, som visas på projektets github-sida:https://github.com/pgaudit/pgaudit. Pgaudit loggar i den vanliga PostgreSQL-loggen. Pgaudit fungerar genom att registrera sig själv vid modulladdning och tillhandahålla krokar för executorStart, executorCheckPerms, processUtility och object_access. Därför stöder pgaudit (i motsats till triggerbaserade lösningar som revisionsutlösare som diskuterades i föregående stycken) READs (SELECT, COPY). Generellt kan vi med pgaudit ha två funktionssätt eller använda dem i kombination:
- SESSION revisionsloggning
- OBJECT granskningsloggning
Sessionsgranskningsloggning stöder de flesta DML-, DDL-, privilegie- och misc-kommandon via klasser:
- LÄS (välj, kopiera från)
- SKRIV (infoga, uppdatera, ta bort, trunkera, kopiera till)
- FUNCTION (funktionsanrop och DO-block)
- ROLE (bevilja, återkalla, skapa/ändra/släpp roll)
- DDL (alla DDL utom de i ROLE)
- MISC (kassera, hämta, checkpoint, vakuum)
Metaklass "alla" inkluderar alla klasser. - exkluderar en klass. Låt oss till exempel konfigurera sessionsgranskningsloggning för alla utom MISC, med följande GUC-parametrar i postgresql.conf:
pgaudit.log_catalog = off
pgaudit.log = 'all, -misc'
pgaudit.log_relation = 'on'
pgaudit.log_parameter = 'on'
Genom att ge följande kommandon (samma som i triggerexemplet)
myshop=# insert into orders (customer,customerid,product,productid,unit_price,quantity) VALUES('magicbattler',1,'some fn skin 2',2,5,2);
INSERT 0 1
myshop=# update orders set quantity=3 where id=2;
UPDATE 1
myshop=# delete from orders where id=2;
DELETE 1
myshop=#
Vi får följande poster i PostgreSQL-loggen:
% tail -f data/log/postgresql-22.log | grep AUDIT:
[local] [55035] 5b03e693.d6fb 2018-05-22 12:46:37.352 EEST psql [email protected] line:7 LOG: AUDIT: SESSION,5,1,WRITE,INSERT,TABLE,public.orders,"insert into orders (customer,customerid,product,productid,unit_price,quantity) VALUES('magicbattler',1,'some fn skin 2',2,5,2);",<none>
[local] [55035] 5b03e693.d6fb 2018-05-22 12:46:50.120 EEST psql [email protected] line:8 LOG: AUDIT: SESSION,6,1,WRITE,UPDATE,TABLE,public.orders,update orders set quantity=3 where id=2;,<none>
[local] [55035] 5b03e693.d6fb 2018-05-22 12:46:59.888 EEST psql [email protected] line:9 LOG: AUDIT: SESSION,7,1,WRITE,DELETE,TABLE,public.orders,delete from orders where id=2;,<none>
Observera att texten efter AUDIT:utgör ett perfekt revisionsspår, nästan redo att skickas till revisorn i kalkylarksfärdigt csv-format. Att använda sessionsrevisionsloggning ger oss revisionsloggposter för alla operationer som tillhör klasserna som definieras av parametern pgaudit.log på all tabeller. Det finns dock fall där vi önskar att endast en liten delmängd av data, dvs. endast ett fåtal tabeller ska granskas. I sådana fall kan vi föredra objektgranskningsloggning som ger oss finkorniga kriterier till utvalda tabeller/kolumner via PostgreSQL:s privilegiesystem. För att börja använda objektgranskningsloggning måste vi först konfigurera parametern pgaudit.role som definierar huvudrollen som pgaudit kommer att använda. Det är vettigt att inte ge denna användare några inloggningsrättigheter.
CREATE ROLE auditor;
ALTER ROLE auditor WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT 0;
Vi anger detta värde för pgaudit.role i postgresql.conf:
pgaudit.log = none # no need for extensive SESSION logging
pgaudit.role = auditor
Pgaudit OBJECT-loggning fungerar genom att hitta om användaren revisor ges (direkt eller ärvt) rätten att utföra den angivna åtgärden som utförs på de relationer/kolumner som används i ett uttalande. Så om vi behöver ignorera alla tabeller, men har detaljerad loggning till bordsorder, är det här sättet att göra det:
grant ALL on orders to auditor ;
Genom ovanstående anslag möjliggör vi fullständig SELECT, INSERT, UPDATE och DELETE inloggning på bordsorder. Låt oss återigen ge INSERT, UPPDATERA, DELETE av de tidigare exemplen och titta på postgresql-loggen:
% tail -f data/log/postgresql-22.log | grep AUDIT:
[local] [60683] 5b040125.ed0b 2018-05-22 14:41:41.989 EEST psql [email protected] line:7 LOG: AUDIT: OBJECT,2,1,WRITE,INSERT,TABLE,public.orders,"insert into orders (customer,customerid,product,productid,unit_price,quantity) VALUES('magicbattler',1,'some fn skin 2',2,5,2);",<none>
[local] [60683] 5b040125.ed0b 2018-05-22 14:41:52.269 EEST psql [email protected] line:8 LOG: AUDIT: OBJECT,3,1,WRITE,UPDATE,TABLE,public.orders,update orders set quantity=3 where id=2;,<none>
[local] [60683] 5b040125.ed0b 2018-05-22 14:42:03.148 EEST psql [email protected] line:9 LOG: AUDIT: OBJECT,4,1,WRITE,DELETE,TABLE,public.orders,delete from orders where id=2;,<none>
Vi observerar att utdata är identisk med SESSION-loggningen som diskuterats ovan med skillnaden att istället för SESSION som revisionstyp (strängen bredvid AUDIT:) får vi nu OBJECT.
En varning med OBJECT-loggning är att TRUNCATEs inte loggas. Vi måste tillgripa SESSION-loggning för detta. Men i det här fallet får vi all WRITE-aktivitet för alla bord. Det pågår samtal mellan de inblandade hackarna för att göra varje kommando till en separat klass.
En annan sak att tänka på är att i fallet med arv om vi GER tillgång till revisorn på någon underordnad tabell, och inte föräldern, kommer åtgärder på den överordnade tabellen som översätts till åtgärder på rader i den underordnade tabellen inte att loggas.
Utöver ovanstående måste de IT-personal som ansvarar för loggarnas integritet dokumentera en strikt och väldefinierad procedur som täcker utvinningen av revisionsspåret från PostgreSQL-loggfilerna. Dessa loggar kan strömmas till en extern säker syslog-server för att minimera risken för störningar eller manipulering.
Sammanfattning
Vi hoppas att den här bloggen har hjälpt dig att bättre förstå bästa praxis för revisionsloggning i PostgreSQL och varför det är så viktigt att skapa ett revisionsspår för att förbereda en IT-revision. En revisionsspår kommer att tillhandahålla en uppsättning ren, användbar information som hjälper din revision att gå smidigt.
ClusterControl kan hjälpa till att automatisera och hantera de flesta databasrelaterade uppgifter samtidigt som databassäkerhet, tillgänglighet och prestanda säkerställs – oavsett vilket system du valt. Ladda ner en gratis testversion av ClusterControl idag för att se hur ditt företag kan dra nytta av verktyget och de operationer det utför. Om du inte redan har gjort det, se till att följa oss på Twitter och LinkedIn och prenumerera på vårt flöde, så ses vi i nästa blogg.