真正有效的限制手段只有两种:停用远程口令验证(remote_login_passwordfile=none并重启)和用after logon on system.schema触发器控制ip;alter user lock或改密对sys/system的sysdba登录无效。

不能靠“改密码”或“锁账户”来真正限制 SYS 和 SYSTEM,这两个用户在 Oracle 中本质是系统级身份,账户本身无法被禁用或彻底隔离。真正有效的限制手段只有两种:停用远程口令验证、配合登录触发器控制访问来源。
停用 remote_login_passwordfile=none 是最直接的硬性拦截
Oracle 默认允许远程以 sysdba 身份登录,靠的就是口令文件(orapw$ORACLE_SID)。只要这个文件生效(remote_login_passwordfile=exclusive),任何知道 SYS 密码的人,从任意 IP 都能连上并执行 shutdown、create database 等高危操作。
停用它的命令只有一条,且必须重启生效:
ALTER SYSTEM SET remote_login_passwordfile=none SCOPE=SPFILE;
重启后,所有远程 as sysdba 或 as sysoper 连接都会失败,错误信息是:ORA-01031: insufficient privileges。本地 IPC 连接(如 sqlplus / as sysdba)仍可正常工作,不影响运维。
- 该设置对
SYSTEM用户无直接影响,但它间接封死了SYSTEM通过as sysdba提权的路径 - 不要设为
shared——它只支持一个用户(SYS),且仍允许远程登录,不解决根本问题 - 修改后务必确认
SHOW PARAMETER remote_login_passwordfile返回值确实是none
用 LOGON 触发器禁止非本地 IP 登录 SYSTEM
SYS 的登录行为受口令文件和实例状态双重约束,而 SYSTEM 是普通数据库用户,完全走 SQL 层认证,所以可以用触发器精准控制。
以下触发器会拒绝所有非 127.0.0.1 或本机 hostname 的 SYSTEM 登录请求:
CREATE OR REPLACE TRIGGER deny_remote_system_login
AFTER LOGON ON SYSTEM.SCHEMA
BEGIN
IF SYS_CONTEXT('USERENV', 'IP_ADDRESS') NOT IN ('127.0.0.1', 'localhost') THEN
RAISE_APPLICATION_ERROR(-20001, 'SYSTEM login only allowed from localhost');
END IF;
END;
- 触发器必须由
SYS创建,且作用域是SYSTEM.SCHEMA(不是DATABASE) -
SYS_CONTEXT('USERENV', 'IP_ADDRESS')在本地 IPC 连接时返回空字符串,所以要同时检查localhost - 该触发器对
SYS无效——SYS登录不经过普通用户 schema 触发器链 - 测试时用
sqlplus system/xxx@//host:1521/orcl模拟远程连接,确认报错ORA-20001
为什么 ALTER USER ... ACCOUNT LOCK 对 SYSTEM/SYS 几乎无效
很多人第一反应是执行:
ALTER USER system ACCOUNT LOCK;
但这只对普通登录(conn system/password)起作用;一旦攻击者知道密码,仍可绕过账户状态,用 conn system/password as sysdba 登录——因为此时认证走的是口令文件,不是数据字典中的 USER$ 表。
-
ACCOUNT LOCK只影响normal方式登录,对sysdba/sysoper完全无效 -
SYS账户甚至不能被锁:ALTER USER sys ACCOUNT LOCK会直接报错ORA-28008: the SYS user cannot be locked - 改密文(如
ALTER USER system IDENTIFIED BY VALUES 'xxx')也拦不住as sysdba登录
真正关键的防线就两条:关掉口令文件远程入口,再用触发器卡住 SYSTEM 的常规登录路径。其他操作都是障眼法——Oracle 的设计决定了 SYS 必须存在且本地可用,安全边界只能划在“谁能连进来”这一层,而不是“能不能登上去”。











