从V$SESSION中只能得到机器名, 而通过机器名不能确定到具体的机器. 所以必须得到IP 在oracle中的v$session视图中可以保存有会话的想关信息,包括了客户端的大部分连接信息。其中我们可以将会话的发起ip地址写入到client_identifier和client_info 上文中我们提到了使用userenv函数或者sys_context函数可以获得当前会话的相关信息,其中就包含的有ip_address这一项 当我们使用client_identifier字段来保存登录会话的ip地址的时候,我们需要用到dbms_session.set_identifier过程/函数 当我们使用client_info字段来保存登陆会话的ip地址的时候,我们需要用到dbms_application_info.set_client_info过程/函数 例:查看当前用户的ip地址: MAI@test > select sys_context('userenv','ip_address') from dual; SYS_CONTEXT('USERENV','IP_ADDRESS') ------------------------------------- 192.168.77.1 MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual); USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER --------------- ------- ---------- -------------------- -------------------- MAI                 138      38266 使用client_identifier字段 MAI@test > exec dbms_session.set_identifier(sys_context('userenv','ip_address')); MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual); USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER --------------- ------- ---------- -------------------- -------------------- MAI                 138      38270                      192.168.77.1 使用client_info字段 MAI@test > exec dbms_application_info.set_client_info(sys_context('userenv','ip_address')); MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual); USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER --------------- ------- ---------- -------------------- -------------------- MAI                 138      38270 192.168.77.1         192.168.77.1 当然,这个过程过程可以通过一个触发器来调用,当每一个新的用户连接开启的时候自动触发该触发器,将相应的ip信息写入v$session的相应字段。 触发器的例子: create or replace trigger on_login_trigger after logon on database begin dbms_application_info.set_client_info(sys_context('USERENV','IP_ADDRESS')); 建立这个trigger需要有dba权限,这样的话,当每个用户新登录的时候,这个触发器就会起作用,然后就能够将客户端的ip地址填充到v$session视图中的client_info字段中: MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual); USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER --------------- ------- ---------- -------------------- -------------------- MAI                 149        425 192.168.77.1 利用sys_context函数我们可以获得当前session的hostname和ip address SQL> selectsys_context('userenv','host') from dual; SYS_CONTEXT('USERENV','HOST') -------------------------------------------------------------- WORKGROUP\IBM-L3YMBNP SQL> select sys_context('userenv','ip_address') from dual; SYS_CONTEXT('USERENV','IP_ADDRESS') ----------------------------------------------------------- 127.0.0.1 通过sys_context我们只能获得当前session的信息,如果要获得其他session呢? 这个时候我们就用utl_inaddr包来获取 SQL> selectutl_inaddr.get_host_address('IBM-L3YMBNP') from dual; UTL_INADDR.GET_HOST_ADDRESS('IBM-L3YMBNP') ------------------------------------------------------------------- 9.181.142.152 而且我们还可以获得sina以及其他web site的ip SQL> select utl_inaddr.get_host_address('www.sina.com.cn') from dual; UTL_INADDR.GET_HOST_ADDRESS('WWW.SINA.COM.CN') --------------------------------------------------------------------- 218.30.108.55 其原理是:首先获取域名解析服务器(resolv.conf),在根据host.conf文件确定解析顺序,因为缺省的是hosts文件优先解析,这个时候会又继续读取/etc/hosts文件。 如果hosts文件存在解析关系,则返回信息;如果不存在,则继续问询DNS服务器,获得解析地址,如果不能解析,则会出错 SQL> select utl_inaddr.get_host_address('www.a.com') from dual; select utl_inaddr.get_host_address('www.a.com') from dual ERROR 位于第 1 行: ORA-29257: 未知的主机www.a.com ORA-06512: 在"SYS.UTL_INADDR", line 35 ORA-06512: 在"SYS.UTL_INADDR", line 40 ORA-06512: 在line 1 基本上就是这样了。 方法1创建触发器: create orreplace trigger login_on alfterlogon on database begin dbms_application_info.set_client_info(sys_context('userenv','ip_address')); end; / 这样以后在
最近群里好多人讨论 oracle 安全问题,今天找了些资料学习了下 获取 Oracle 当前会话的一些属性 (对于sql注射的环境判断很有用哦) SYS_CONTEXT 函数返回是与上下文名称空间相关的属性值。这个函数可以用在SQL和PL/SQL语句中。 注意: SYS_CONTEXT 返回的是用户会话期间的属性,所以,你无法使用它在并行的查询或实时应用集群环境。 对于名称空间和变量, 你可以定义它(们)为常量字符串,也可以定义一个变量,来代替名称空间或属性的字符串。名称空间必须是已经在数据库中定义好的, 并且相关的参数和值已经被指定到DBMS_ SESSION 中。名称空间必须是一个合法的SQL标识符。
Oracle 中如何确定远程 session 客户端的 IP 地址 前几天,Daniel 所在的环境多个数据库发生了一件惨案:我们把所有数据库主机、数据库的密码更改后, 硬件总集成的一台 windows 主机安装了一个 Oracle 数据库监控工具,不断尝试利用错误的密码(有错有对) 连接到我们的数据库中,导致生产环境多个数据库发生大量的 library cache lock 等待事件,虽...
[ oracle @vzwc1 ~]$ sqlplus  / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Sat Mar 28 17:53:35 2015