SQL只读账号需从权限控制、连接约束、审计追踪三方面协同防护:严格授予SELECT权限并禁用其他操作,配置数据库只读参数与SQL拦截规则,规范连接字符串与工具使用,并启用审计日志与实时告警机制。
SQL只读账号的核心目标是:让指定用户只能执行 SELECT,不能改动任何数据或结构。配置本身不难,但要真正防住误操作,得从权限控制、连接约束、审计追踪三方面一起下手。
不同数据库的语法和粒度有差异,关键不是“加SELECT”,而是“不给其他权限”:
GRANT SELECT ON db_name.* TO 'user'@'host';,切忌用 GRANT SELECT ON *.*;执行后必须 FLUSH PRIVILEGES;
CREATE ROLE readonly WITH LOGIN PASSWORD 'xxx';,再对每张表运行 GRANT SELECT ON TABLE tbl_name TO readonly;;如需批量授权,可用 psql -c "SELECT 'GRANT SELECT ON ' ||
tablename || ' TO readonly;' FROM pg_tables WHERE schemaname = 'public';" 生成脚本db_datareader 角色;禁用 db_owner、db_ddladmin 等高危角色CREATE SESSION 和 SELECT_CATALOG_ROLE(如需查数据字典),避免授 CONNECT(含资源权限)或 SELECT ANY TABLE
光靠权限不够——比如用户连错库、用错账号、或应用代码里拼了 UPDATE 却没报错。得加一层保险:
INSERT/UPDATE/DELETE/DROP/ALTER 等关键词语句read_only=ON(对非 super 用户生效),配合 super_read_only=ON 防止管理员误开写权限default_transaction_read_only = on,并禁止用户在会话中执行 SET TRANSACTION READ WRITE;(通过 ALTER ROLE ... SET 固化)很多误操作来自连错环境或工具自动执行:
?readonly=true(如 JDBC)或 options='-c default_transaction_read_only=on'(psql),让客户端也感知只读意图db-prod-readonly),避免复制粘贴出错防不住100%,但要确保问题可追溯、可拦截:
general_log)或审计插件(如 MySQL Enterprise Audit、pgAudit),记录所有非 SELECT 语句的来源 IP、账号、时间、SQL 内容只读账号不是配完就完事,它是一套组合动作:权限最小化 + 连接强约束 + 使用有规范 + 行为可审计。少一个环节,就可能在某个深夜因为一条 DELETE FROM users; 被执行而惊醒。