wiki:AdvancedDatabaseDevelopment

Version 3 (modified by 231118, 4 days ago) ( diff )

--

Advanced Database Development

Забелешка: наменето за PostgreSQL project шемата (v04). Во v04: security_alerts.id е INTEGER IDENTITY (не се внесува рачно), computer_id е INTEGER, timestamp е TIMESTAMP, resolved е BOOLEAN. Затоа INSERT-ите не внесуваат id, користат NOW() (не текст) и false (не 'false').

Автоматска детекција и пријавување на безбедносни аномалии

Системот треба автоматски да детектира невообичаено однесување на компјутерите и да генерира безбедносни предупредувања без рачна интервенција. Ова вклучува ситуации кога одреден компјутер генерира голем број Sysmon настани во краток период, или кога ресурсната потрошувачка (CPU, RAM) ги надминува критичните прагови.

Implementation

Triggers

Тригер за автоматско предупредување при висока искористеност на процесорот. Кога во computer_history се вметнува нов запис со CPU > 90%, автоматски се креира запис во security_alerts:

CREATE OR REPLACE FUNCTION create_cpu_alert()
RETURNS TRIGGER AS
$$
BEGIN
  IF NEW.cpu_usage > 90 THEN
    INSERT INTO security_alerts(
      computer_id, alert_type, severity,
      description, timestamp, resolved
    )
    VALUES (
      NEW.computer_id,
      'High CPU Usage',
      'HIGH',
      'CPU usage exceeded 90%',
      NOW(),
      false
    );
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS cpu_alert_trigger ON computer_history;
CREATE TRIGGER cpu_alert_trigger
AFTER INSERT ON computer_history
FOR EACH ROW
EXECUTE FUNCTION create_cpu_alert();

Тригер за автоматско предупредување при висока искористеност на RAM меморијата. Кога во computer_history се вметнува нов запис со RAM > 90%, автоматски се креира запис во security_alerts:

CREATE OR REPLACE FUNCTION create_ram_alert()
RETURNS TRIGGER AS
$$
BEGIN
  IF NEW.ram_usage > 90 THEN
    INSERT INTO security_alerts(
      computer_id, alert_type, severity,
      description, timestamp, resolved
    )
    VALUES (
      NEW.computer_id,
      'High RAM Usage',
      'HIGH',
      'RAM usage exceeded 90%',
      NOW(),
      false
    );
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS ram_alert_trigger ON computer_history;
CREATE TRIGGER ram_alert_trigger
AFTER INSERT ON computer_history
FOR EACH ROW
EXECUTE FUNCTION create_ram_alert();

Тригер за автоматско предупредување при висока искористеност на дискот (> 90%):

CREATE OR REPLACE FUNCTION create_disk_alert()
RETURNS TRIGGER AS
$$
BEGIN
  IF NEW.disk_usage > 90 THEN
    INSERT INTO security_alerts(
      computer_id, alert_type, severity, description, timestamp, resolved
    )
    VALUES (
      NEW.computer_id, 'High Disk Usage', 'MEDIUM',
      'Disk usage exceeded 90%', NOW(), false
    );
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS disk_alert_trigger ON computer_history;
CREATE TRIGGER disk_alert_trigger
AFTER INSERT ON computer_history
FOR EACH ROW
EXECUTE FUNCTION create_disk_alert();

Тригер (BEFORE UPDATE) кој автоматски го ажурира updated_at во env_settings при секоја промена на поставките:

CREATE OR REPLACE FUNCTION set_env_settings_updated_at()
RETURNS TRIGGER AS
$$
BEGIN
  NEW.updated_at := NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS env_settings_updated_trigger ON env_settings;
CREATE TRIGGER env_settings_updated_trigger
BEFORE UPDATE ON env_settings
FOR EACH ROW
EXECUTE FUNCTION set_env_settings_updated_at();

Тригер (напреден) кој при нова проверка на достапност со недостапен сервис (service_availability.is_available = false) автоматски генерира безбедносен аларм, поврзувајќи го сервисот со неговиот компјутер:

CREATE OR REPLACE FUNCTION create_service_down_alert()
RETURNS TRIGGER AS
$$
DECLARE
  v_computer_id INTEGER;
  v_service     TEXT;
BEGIN
  IF NEW.is_available = false THEN
    SELECT computer_id, service_name
      INTO v_computer_id, v_service
      FROM network_services
     WHERE id = NEW.service_id;

    INSERT INTO security_alerts(
      computer_id, alert_type, severity, description, timestamp, resolved
    )
    VALUES (
      v_computer_id, 'Service Unavailable', 'MEDIUM',
      'Network service ' || COALESCE(v_service, '?') || ' is unavailable',
      NOW(), false
    );
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS service_down_trigger ON service_availability;
CREATE TRIGGER service_down_trigger
AFTER INSERT ON service_availability
FOR EACH ROW
EXECUTE FUNCTION create_service_down_alert();

Тригер кој при нов перформансен запис го освежува last_seen на компјутерот (машината се смета за активна штом испраќа податоци):

CREATE OR REPLACE FUNCTION touch_computer_last_seen()
RETURNS TRIGGER AS
$$
BEGIN
  UPDATE computers
     SET last_seen = COALESCE(NEW.timestamp, NOW())
   WHERE id = NEW.computer_id;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS touch_last_seen_trigger ON computer_history;
CREATE TRIGGER touch_last_seen_trigger
AFTER INSERT ON computer_history
FOR EACH ROW
EXECUTE FUNCTION touch_computer_last_seen();

Stored Procedures/Functions

Процедура за детекција на сомнителна активност врз основа на Sysmon настани. Ако еден компјутер генерирал повеќе од 50 Sysmon настани во последниот час, автоматски се внесува безбедносно предупредување. Може да се извршува периодично (на пр. преку pg_cron):

CREATE OR REPLACE PROCEDURE detect_security_anomalies()
LANGUAGE plpgsql AS
$$
BEGIN
  INSERT INTO security_alerts(
    computer_id, alert_type, severity,
    description, timestamp, resolved
  )
  SELECT
    computer_id,
    'Suspicious Activity',
    'HIGH',
    'More than 50 Sysmon events in the last hour',
    NOW(),
    false
  FROM sysmon_events
  WHERE timestamp > NOW() - INTERVAL '1 hour'
  GROUP BY computer_id
  HAVING COUNT(*) > 50;
END;
$$;

Views

Поглед за безбедносен преглед на системот. Обезбедува брз преглед на вкупниот број Sysmon настани по компјутер:

CREATE OR REPLACE VIEW security_summary_view AS
SELECT
  c.name,
  COUNT(s.id) AS total_events
FROM computers c
LEFT JOIN sysmon_events s ON c.id = s.computer_id
GROUP BY c.name;

Автоматско одржување и чистење на историски податоци

Со текот на времето, историските табели (sysmon_events, computer_history, computer_processes_history, network_connections_history) акумулираат голем број записи кои ги успоруваат пребарувањата и го зголемуваат дисковниот простор. Потребен е механизам за автоматско бришење застарени записи.

Implementation

Stored Procedures/Functions

Процедура за отстранување стари Sysmon логови (постари од 90 дена):

CREATE OR REPLACE PROCEDURE cleanup_old_sysmon_events()
LANGUAGE plpgsql AS
$$
BEGIN
  DELETE FROM sysmon_events
  WHERE timestamp < NOW() - INTERVAL '90 days';
END;
$$;

Процедура за отстранување стари записи од computer_history (постари од 180 дена):

CREATE OR REPLACE PROCEDURE cleanup_old_computer_history()
LANGUAGE plpgsql AS
$$
BEGIN
  DELETE FROM computer_history
  WHERE timestamp < NOW() - INTERVAL '180 days';
END;
$$;

Процедура за чистење на историските табели за процеси и мрежни конекции (v04), постари од 90 дена:

CREATE OR REPLACE PROCEDURE cleanup_old_history()
LANGUAGE plpgsql AS
$$
BEGIN
  DELETE FROM computer_processes_history
  WHERE timestamp < NOW() - INTERVAL '90 days';

  DELETE FROM network_connections_history
  WHERE timestamp < NOW() - INTERVAL '90 days';
END;
$$;

Процедурите може да се закажат за периодично извршување преку pg_cron:

-- Извршување секој ден во раните утрински часови
SELECT cron.schedule('0 0 * * *', $$CALL cleanup_old_sysmon_events()$$);
SELECT cron.schedule('0 1 * * *', $$CALL cleanup_old_computer_history()$$);
SELECT cron.schedule('0 2 * * *', $$CALL cleanup_old_history()$$);

Аналитички погледи за брз пристап до системски информации

Администраторите и апликацијата честопати бараат консолидирани информации за состојбата на компјутерите. Директното пресметување при секое барање е бавно кога базата содржи голем број записи. Погледите и материјализираните погледи овозможуваат побрз пристап.

Implementation

Views

Детален поглед на компјутерите. Консолидиран приказ на основните информации за сите компјутери:

CREATE OR REPLACE VIEW computer_details_view AS
SELECT
  name,
  "user",
  ip,
  os,
  env_name,
  last_seen
FROM computers;

Поглед за активни (online) компјутери. Прикажува само компјутери активни во последните 5 минути, корисен за real-time dashboard:

CREATE OR REPLACE VIEW active_computers_view AS
SELECT
  c.id,
  c.name,
  c.ip,
  c.env_name,
  c.last_seen
FROM computers c
WHERE c.last_seen >= NOW() - INTERVAL '5 minutes';

Materialized Views

Материјализиран поглед за најактивни компјутери. Резултатите се физички зачувани, што овозможува побрзо извршување на аналитички пребарувања врз голем број историски записи:

CREATE MATERIALIZED VIEW IF NOT EXISTS most_active_computers AS
SELECT
  c.id,
  c.name,
  COUNT(h.id) AS total_logs
FROM computers c
JOIN computer_history h ON c.id = h.computer_id
GROUP BY c.id, c.name;

Рачно (или закажано) освежување на материјализираниот поглед:

REFRESH MATERIALIZED VIEW most_active_computers;

Статистички извештаи по околини (environments)

Администраторите треба увид во тоа колку компјутери се регистрирани во секоја околина, за следење на растот и планирање капацитети.

Implementation

Stored Procedures/Functions

Процедура за генерирање статистика по околини (RAISE NOTICE):

CREATE OR REPLACE PROCEDURE environment_statistics()
LANGUAGE plpgsql AS
$$
DECLARE
  r RECORD;
BEGIN
  FOR r IN (
    SELECT env_name, COUNT(*) AS total
    FROM computers
    GROUP BY env_name
  )
  LOOP
    RAISE NOTICE 'Environment: %, Computers: %', r.env_name, r.total;
  END LOOP;
END;
$$;

Функција која враќа статистика по околини во форма на табела (погодна за апликацијата):

CREATE OR REPLACE FUNCTION get_environment_statistics()
RETURNS TABLE(env_name TEXT, total_computers BIGINT)
LANGUAGE plpgsql AS
$$
BEGIN
  RETURN QUERY
  SELECT
    c.env_name,
    COUNT(*)::BIGINT AS total_computers
  FROM computers c
  GROUP BY c.env_name
  ORDER BY total_computers DESC;
END;
$$;

Повикување на функцијата:

SELECT * FROM get_environment_statistics();
Note: See TracWiki for help on using the wiki.