Загрузка данных
-- ============================================================================
-- Аудит безопасности PostgreSQL
-- ============================================================================
\echo '================================================================================'
\echo ' АУДИТ БЕЗОПАСНОСТИ POSTGRESQL'
\echo '================================================================================'
\echo ''
\echo 'Дата проверки:' `SELECT TO_CHAR(NOW(), 'DD.MM.YYYY HH24:MI:SS');`
\echo 'Версия СУБД:' `SELECT version();`
\echo '================================================================================'
-- ============================================================================
-- СУБД.1.1 - Учетные записи по умолчанию и с простыми паролями
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.1 - Учетные записи по умолчанию и с простыми паролями'
\echo '--------------------------------------------------------------------------------'
SELECT
'INFO' as status,
'Всего пользователей с возможностью входа: ' || COUNT(*) as result
FROM pg_roles
WHERE rolcanlogin = true;
SELECT
CASE
WHEN rolname IN ('postgres', 'admin', 'test', 'user', 'guest', 'root', 'sa')
THEN 'WARNING'
ELSE 'OK'
END as status,
'Пользователь: ' || rolname ||
' | Суперпользователь: ' || rolsuper ||
' | Может войти: ' || rolcanlogin as result
FROM pg_roles
WHERE rolcanlogin = true
AND rolname IN ('postgres', 'admin', 'test', 'user', 'guest', 'root', 'sa')
ORDER BY rolname;
-- ============================================================================
-- СУБД.1.2 - Парольная политика
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.2 - Парольная политика'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN setting = 'scram-sha-256' THEN 'OK'
ELSE 'WARNING'
END as status,
'password_encryption = ' || setting as result
FROM pg_settings
WHERE name = 'password_encryption';
SELECT
CASE
WHEN setting = 'on' THEN 'OK'
ELSE 'WARNING'
END as status,
'log_connections = ' || setting as result
FROM pg_settings
WHERE name = 'log_connections';
SELECT
CASE
WHEN setting = 'on' THEN 'OK'
ELSE 'WARNING'
END as status,
'log_disconnections = ' || setting as result
FROM pg_settings
WHERE name = 'log_disconnections';
-- ============================================================================
-- СУБД.1.3 - Одинаковые пароли у администраторов
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.3 - Одинаковые пароли у суперпользователей'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN COUNT(*) > 0 THEN 'WARNING'
ELSE 'OK'
END as status,
'Найдено суперпользователей с одинаковыми паролями: ' || COUNT(*) as result
FROM (
SELECT passwd
FROM pg_shadow
WHERE usesuper = true AND passwd IS NOT NULL
GROUP BY passwd
HAVING COUNT(*) > 1
) as duplicates;
SELECT
'DETAIL: ' || passwd || ' -> ' || array_agg(usename)::text as result
FROM pg_shadow
WHERE usesuper = true AND passwd IS NOT NULL
GROUP BY passwd
HAVING COUNT(*) > 1;
-- ============================================================================
-- СУБД.1.4 - Неиспользуемые учетные записи
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.4 - Неиспользуемые учетные записи'
\echo '--------------------------------------------------------------------------------'
SELECT
'INFO' as status,
'Активных сессий сейчас: ' || COUNT(*) as result
FROM pg_stat_activity
WHERE usename IS NOT NULL;
SELECT
'WARNING' as status,
'Пользователи без активных сессий (возможно неиспользуемые): ' ||
array_agg(rolname)::text as result
FROM pg_roles r
LEFT JOIN pg_stat_activity a ON r.rolname = a.usename
WHERE a.usename IS NULL
AND r.rolcanlogin = true
AND r.rolname NOT IN ('postgres');
-- ============================================================================
-- СУБД.1.5 - Неограниченные подключения с любых IP
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.5 - Настройка listen_addresses'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN setting = '*' OR setting ~ '0\.0\.0\.0' THEN 'WARNING'
WHEN setting = 'localhost' OR setting = '' THEN 'OK'
ELSE 'INFO'
END as status,
'listen_addresses = ' || setting as result
FROM pg_settings
WHERE name = 'listen_addresses';
-- ============================================================================
-- СУБД.1.6 - Пользователи с полными правами (Full Access)
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.6 - Пользователи с расширенными правами'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN rolsuper THEN 'WARNING'
ELSE 'INFO'
END as status,
'User: ' || rolname ||
' | SUPER: ' || rolsuper ||
' | CREATEDB: ' || rolcreatedb ||
' | CREATEROLE: ' || rolcreaterole ||
' | REPLICATION: ' || rolreplication as result
FROM pg_roles
WHERE rolcanlogin = true
AND (rolsuper OR rolcreatedb OR rolcreaterole OR rolreplication)
ORDER BY rolsuper DESC, rolname;
-- ============================================================================
-- СУБД.1.7 - Одинаковые учетки для разных приложений
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.7 - Использование одних учеток разными приложениями'
\echo '--------------------------------------------------------------------------------'
SELECT
'INFO' as status,
'User: ' || usename ||
' | Apps: ' || array_agg(DISTINCT application_name)::text ||
' | Connections: ' || COUNT(*) as result
FROM pg_stat_activity
WHERE usename IS NOT NULL
GROUP BY usename
HAVING COUNT(DISTINCT application_name) > 1
ORDER BY COUNT(*) DESC;
-- ============================================================================
-- СУБД.1.8 - Права на системные таблицы
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.8 - Права на системные схемы'
\echo '--------------------------------------------------------------------------------'
SELECT
'WARNING' as status,
'Grantee: ' || grantee ||
' | Schema: ' || table_schema ||
' | Privilege: ' || privilege_type as result
FROM information_schema.role_table_grants
WHERE table_schema IN ('pg_catalog', 'information_schema')
AND grantee NOT IN ('postgres', 'pg_monitor', 'pg_read_all_settings')
LIMIT 10;
-- ============================================================================
-- СУБД.1.9 и СУБД.1.10 - Доступ со всех интерфейсов и ограничения по IP
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.9/1.10 - Настройки сетевого доступа'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN setting = '*' THEN 'WARNING'
ELSE 'OK'
END as status,
'listen_addresses = ' || setting as result
FROM pg_settings
WHERE name = 'listen_addresses';
SELECT
CASE
WHEN setting = 'on' THEN 'OK'
ELSE 'WARNING'
END as status,
'ssl = ' || setting as result
FROM pg_settings
WHERE name = 'ssl';
-- ============================================================================
-- СУБД.1.11 - Шифрование
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.11 - Настройки шифрования'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN setting = 'scram-sha-256' THEN 'OK'
ELSE 'WARNING'
END as status,
'password_encryption = ' || setting as result
FROM pg_settings
WHERE name = 'password_encryption';
SELECT
CASE
WHEN setting = 'on' THEN 'OK'
ELSE 'WARNING'
END as status,
'ssl = ' || setting as result
FROM pg_settings
WHERE name = 'ssl';
-- ============================================================================
-- СУБД.1.12 - SSL/TLS параметры
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.12 - Параметры SSL/TLS'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN setting IN ('TLSv1.2', 'TLSv1.3') THEN 'OK'
ELSE 'WARNING'
END as status,
'ssl_min_protocol_version = ' || setting as result
FROM pg_settings
WHERE name = 'ssl_min_protocol_version';
SELECT
'INFO' as status,
'ssl_ciphers = ' || setting as result
FROM pg_settings
WHERE name = 'ssl_ciphers';
-- ============================================================================
-- СУБД.1.13 - Доступность журналов аудита
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.13 - Настройки логирования'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN setting IN ('stderr', 'csvlog', 'syslog') THEN 'OK'
ELSE 'WARNING'
END as status,
'log_destination = ' || setting as result
FROM pg_settings
WHERE name = 'log_destination';
SELECT
CASE
WHEN setting = 'on' THEN 'OK'
ELSE 'WARNING'
END as status,
'logging_collector = ' || setting as result
FROM pg_settings
WHERE name = 'logging_collector';
SELECT
CASE
WHEN setting != 'none' THEN 'OK'
ELSE 'WARNING'
END as status,
'log_statement = ' || setting as result
FROM pg_settings
WHERE name = 'log_statement';
SELECT
CASE
WHEN setting = 'on' THEN 'OK'
ELSE 'WARNING'
END as status,
'log_connections = ' || setting as result
FROM pg_settings
WHERE name = 'log_connections';
-- ============================================================================
-- СУБД.1.14 - Ограничения на попытки ввода пароля
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.14 - Блокировка при неудачных попытках входа'
\echo '--------------------------------------------------------------------------------'
SELECT
'INFO' as status,
'PostgreSQL не имеет встроенной блокировки. Рекомендуется использовать PAM.' as result;
-- ============================================================================
-- СУБД.1.15 - Контроль доступа к файлам БД
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.15 - Опасные функции и права'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN rolsuper THEN 'WARNING'
ELSE 'OK'
END as status,
'Пользователи с правами суперпользователя (могут использовать COPY FROM PROGRAM): ' ||
array_agg(rolname)::text as result
FROM pg_roles
WHERE rolsuper = true;
-- ============================================================================
-- СУБД.1.16 - Другие уязвимости конфигурации
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.16 - Дополнительные проверки конфигурации'
\echo '--------------------------------------------------------------------------------'
SELECT
CASE
WHEN setting::integer > 0 THEN 'OK'
ELSE 'WARNING'
END as status,
'log_min_duration_statement = ' || setting || ' ms' as result
FROM pg_settings
WHERE name = 'log_min_duration_statement';
SELECT
CASE
WHEN setting = 'on' THEN 'OK'
ELSE 'WARNING'
END as status,
'row_security = ' || setting as result
FROM pg_settings
WHERE name = 'row_security';
-- ============================================================================
-- СУБД.1.17 - Уязвимости ПО (версия)
-- ============================================================================
\echo ''
\echo '>>> СУБД.1.17 - Версия PostgreSQL'
\echo '--------------------------------------------------------------------------------'
SELECT
'INFO' as status,
version() as result;
SELECT
CASE
WHEN (SELECT split_part(version(), ' ', 2)) < '14' THEN 'WARNING'
ELSE 'OK'
END as status,
'Рекомендуется использовать PostgreSQL 14 или выше' as result;
-- ============================================================================
-- Итоговая статистика
-- ============================================================================
\echo ''
\echo '================================================================================'
\echo ' ИТОГОВАЯ СТАТИСТИКА'
\echo '================================================================================'
SELECT
'Всего ролей: ' || COUNT(*) as total_roles
FROM pg_roles;
SELECT
'Суперпользователей: ' || COUNT(*) as superusers
FROM pg_roles
WHERE rolsuper = true;
SELECT
'Ролей с возможностью входа: ' || COUNT(*) as login_roles
FROM pg_roles
WHERE rolcanlogin = true;
SELECT
'Активных подключений: ' || COUNT(*) as active_connections
FROM pg_stat_activity
WHERE backend_type = 'client backend';
\echo '================================================================================'
\echo ' АУДИТ ЗАВЕРШЕН'
\echo '================================================================================'