Oracle的监听和白名单

发布时间 2023-06-21 15:56:04作者: 数据库小白(专注)

Oracle的监听和白名单

监听的基本概念和配置:

**经验告诉我:最好把数据库的SID和数据库全局名称分开,免得配置时混了,如果要配置服务器端和客户端时,服务器端和客户端都需要配置,并且配置方法一样。

Oracle监听器是做什么的呢?它设置在服务端,是基于服务端的一种网络服务,用于监听客户端向数据库端发出的连接请求。判断一下连接请求是否正确,请求有效就连接,失败就拒绝。所以你要连接远程数据库,那么远程数据库就要配置监听器,客户端则不需要配置。

image-20210628164157986

一、监听器(LISTENER)** **

**  监听器是Oracle基于服务器端的一种网络服务,主要用于监听客户端向数据库服务器端提出的连接请求。既然是基于服务器端的服务,那么它也只存在于数据库服务器端,进行监听器的设置也是在数据库服务器端完成的。

oracle的常见的几种连接方式

  1. ServiceName方式:
jdbc:oracle:thin:@//<host>:<port>/ServiceName
sqlplus scott/scott@//192.168.21.142:1521/adg
  1. SID方式:(这种方式只要监听启动了就能创建连接)
jdbc:oracle:thin:@<host>:<port>:<SID>
sqlplus scott/scott@192.168.21.142:1521/adg  (sid方式)

3.RAC方式(老的写法,现在一般用ServiceName方式)

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=x.x.x.1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=x.x.x.2)(PORT=1521)))(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=xxrac)))

(这种方式一定要在创建连接的客户端创建tnsname.ora的配置,否者无法连接)
4. jdbc:oracle:oci:@service (这种一般没有人写吧)

sqlplus scott/scott@adg
eg:
ADG =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.21.142)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = adg)
    )
  )

**二、****本地服务名(Tnsname)

**  Oracle客户端与服务器端的连接是通过客户端发出连接请求,由服务器端监听器对客户端连接请求进行合法检查,如果连接请求有效,则进行连接,否则拒绝该连接。
  本地服务名是Oracle客户端网络配置的一种,另外还有Oracle名字服务器(Oracle Names Server)等。Oracle常用的客户端配置就是采用的本地服务名,本文中介绍的也主要是基于本地服务名的配置。 

客户端连接服务器端常见问题排除方法

要排除客户端与服务器端的连接问题,首先检查客户端配置是否正确(客户端配置必须与数据库服务器端监听配置一致),再根据错误提示解决。下面列出几种常见的连接问题:

1、 ORA-12541: TNS: 没有监听器

显而易见,服务器端的监听器没有启动,另外检查客户端IP地址或端口填写是否正确。启动监听器:
$ lsnrctl start
或
C:/lsnrctl start

2、 ORA-12500:

ORA-12500: TNS: 监听程序无法启动专用服务器进程(用pl/sql登录时需要必须和客户端的一致,如果有客户端的话,数据库显示的是客户端的服务名,如果服务器连接的话显示的是服务器配置的服务名)
对于Windows而言,没有启动Oracle实例服务。启动实例服务:
C:/oradim –startup -sid myoracle

3、 ORA-12535: TNS: 操作超时

出现这个问题的原因很多,但主要跟网络有关。解决这个问题,首先检查客户端与服务端的网络是否畅通,如果网络连通,则检查两端的防火墙是否阻挡了连接。

4、 ORA-12154: TNS: 无法处理服务名

检查输入的服务名与配置的服务名是否一致。另外注意生成的本地服务名文件(Windows下如D:/oracle/ora92/network/admin/tnsnames.ora,Linux/Unix下$ORACLE_HOME/network/admin/tnsnames.ora)里每项服务的首行服务名称前不能有空格。

5、 ORA-12514: TNS: 监听进程不能解析在连接描述符中给出的 SERVICE_NAME

打开Net Manager,选中服务名称,检查服务标识栏里的服务名输入是否正确。该服务名必须与服务器端监听器配置的全局数据库名一致。

6、 Windows下启动监听服务提示找不到路径

错误信息:ORA-28009 Connection to SYS should be as sysdba or sysoper;
原因:用SYS用户登录数据库时,语法与其它操作用户写法不同,必须写明登录权限。(安装时没有解锁)
解决方法:使用正确的书写方式。
例如:SYS/口令@服务名 AS SYSDBA;
cmd下执行
sqlplus / as sysdba
alter user sys identified by password;然后都可以了

监听的配置和说明:
通常,对于服务端,我们是需要配置监听程序文件listener.ora,

对于客户端连接,我们需要配置tnsnames.ora

常用监听配置:

listener.ora 文件:

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

SID_LIST_LISTENER=
   (SID_LIST=
       (SID_DESC=
          (SID_NAME = ORCL)
          (ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1)
          (GLOBAL_DBNAME=ORCL)
       )
  )

ADR_BASE_LISTENER = /u01/app/oracle

tnsnames.ora 文件配置:

std =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dg)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = std)
    )
  )

01 静态监听和动态监听的区别:

静态注册,listener不知道实例的状态,只有在进程通过其连接数据库时才能知道,如果你想使用远程管理数据库就使用静态监听
动态注册:listener实时的都知道实例的状态,数据库在关闭的时候会动态的从listener中注销,所以远程管理数据库的启动和停止就不行了。

sqlnet.ora文件的作用:

文件内容

cat sqlnet.ora 
This file is actually generated by netca. But if customers choose to
install "Software Only", this file wont exist and without the native
authentication, they will not be able to connect to the database on NT.

SQLNET.AUTHENTICATION_SERVICES = (NTS)
把NTS该为NONE时,那么使用sqlplus / as sysdba 这个不用输入密码的命令就没法再直接登录到oracle系统了

通过以下的方式开放IP 地址白名单:

ADR_BASE = /oracle/app/grid
tcp.validnode_checking=yes
tcp.invited_nodes=(10.25.71.47,10.25.71.88)

sqlnet.ora文件控制密码登录方式:SQLNET.AUTHENTICATION_SERVICES

SQLNET.AUTHENTICATION_SERVICES的参数有以下三种:

1.注释或者SQLNET.AUTHENTICATION_SERVICES =(none)
2.SQLNET.AUTHENTICATION_SERVICES =(nts)
3.SQLNET.AUTHENTICATION_SERVICES =(all)

场景1 : 没有配置 AUTHENTICATION_SERVICES 或 注释掉 AUTHENTICATION_SERVICES

此场景下 -> 无密、错密、正确密码都可以登录sysdba
cat sqlnet.ora 
#SQLNET.AUTHENTICATION_SERVICES =(none)
表示不用输如密码就可以登录数据库(以下三种方式都可以登录数据库):

sqlplus / as sysdba
sqlplus sys/error_pass as sysdba
sqlplus sys/123456 as sysdba        --正确密码

场景2:(none) or (nts) 此场景下 -> 需要验证oracle的用户密码

------------------------------------------------------------------------------------
sqlplus / as sysdba
ERROR:
ORA-01017: invalid username/password; logon denied

sqlplus sys/error_pass as sysdba
ERROR:
ORA-01017: invalid username/password; logon denied

sqlplus sys/123456 as sysdba
------------------------------------------------------------------------------------

场景3:(all) -- 同场景1 ,不需要密码就可以登录

控制客户端连接数据库时使用别名还是直接使用实例名:NAMES.DIRECTORY_PATH

假如现在tnsname.ora有如下配置

cat tnsnames.ora 
------------------------------------------------------------------------------------
MYCDB2 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = XAG193)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = MYCDB)
    )
  )

LISTENER_MYCDB =
  (ADDRESS = (PROTOCOL = TCP)(HOST = XAG193)(PORT = 1521))

------------------------------------------------------------------------------------

那么客户端的连接方式有如下几种:

场景1 : (TNSNAMES)

那么客户端就只会从tnsnames.ora查找你要连接的字符串(db_alias)记录,
如果tnsname.ora文件中没有此记录,则连接不上数据库。
cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES = (none)
NAMES.DIRECTORY_PATH = (TNSNAMES)

只能通过如下的方式连接数据库:
 sqlplus C##XAG/xag123@MYCDB2

场景2:(EZCONNECT)

就是说可以不用在tnsnames.ora文件去查询db_alias就可以通过Service Name进行数据库的连接

sqlplus C##XAG/xag123@XAG193:1521/MYCDB
sqlplus C##XAG/xag123@XAG193:1521/MYPDB

无法通过实例名称连接:
sqlplus C##XAG/xag123@MYCDB2
ERROR:
ORA-12154: TNS:could not resolve the connect identifier specified

场景3:(TNSNAMES,EZCONNECT)

cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES = (none)
NAMES.DIRECTORY_PATH = (TNSNAMES,EZCONNECT)

如下的方式都可以连接数据库:
sqlplus C##XAG/xag123@MYCDB2
sqlplus C##XAG/xag123@XAG193:1521/MYCDB
sqlplus C##XAG/xag123@XAG193:1521/MYPDB

检测僵死进程连接时间:SQLNET.EXPIRE_TIME (单位分钟)

DCD: Dead Connection Detection ,可以用于检测、标记僵死而没有断开会session,
再由PMON进行清理,释放资源。开启DCD,只需要在服务端的sqlnet.ora文件中
添加SQLNET.EXPIRE_TIME参数,单位为分钟。如果时间达到这个值,server端就
是发出一个”probe” packet 给客户端,如要客户断是正常的,这个packet就被忽略,
timer重新计时;如果客户端异常中断,则server端就会收到一个消息,用以释放连接。

DCD还可以用于防止防火墙的timeout,由于防火墙设置timeout原因,当client和server在timeout时间内
没有数据传输的时候,会话就会被防火墙断开。而设置SQLNET.EXPIRE_TIME参数,使其小于防火墙
的timeout时间,就可以避免这一情况的发生
——————————————————————————————
ORA-03135: connection lost contact.
——————————————————————————————
某B/S架构的应用程序在测试过程中每隔1到2小时出现“错误信息:ORA-03135: 连接失去联系的报错”,
详细报错信息如下:
ORA-03135出现的原因较多,问题有可能出在网络设备、操作系统、数据库上,
问题最有可能是由于网络闪段和防火墙配置所导致。

测试案例: SQLNET.EXPIRE_TIME=1   (本次是为测试方便,正常应该配置10分钟左右)
[oracle@XAG193 admin]$ cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES = (none)
NAMES.DIRECTORY_PATH = (TNSNAMES,EZCONNECT)
SQLNET.EXPIRE_TIME=1

#客户端
D:\Tools\sqlcl\bin>sql C##XAG/xag123@MYCDB2       ---MYCDB2 为客户端tnsnames.ora 中配置的别名       
or 
D:\Tools\sqlcl\bin>sql C##XAG/xag123@192.168.40.193:1521/MYPDB
or
D:\Tools\sqlcl\bin>sql /nolog
SQL> CONN C##XAG/xag123@192.168.40.193:1521/MYPDB
OR
SQL> CONN C##XAG/xag123@//192.168.40.193:1521/MYPDB

#服务端(查到 192.168.40.1 客户端有连接到服务器端)
[root@XAG193 ~]# netstat -pan | grep 192.168.40.193:1521 
tcp        0      0 192.168.40.193:33741    192.168.40.193:1521     ESTABLISHED 1651/ora_lreg_MYCDB 
tcp6       0      0 192.168.40.193:1521     192.168.40.193:33741    ESTABLISHED 1565/tnslsnr        
tcp6       0      0 192.168.40.193:1521     192.168.40.1:62171      ESTABLISHED 3631/oracleMYCDB 

[root@XAG193 ~]# tcpdump -i ens33 -nnn host 192.168.40.1 and port 1521
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
-------------------------------------------------------------------------------------------------------------------------
01:44:11.882228 IP 192.168.40.193.1521 > 192.168.40.1.62171: Flags [.], ack 1131350432, win 353, length 0
01:44:11.882496 IP 192.168.40.1.62171 > 192.168.40.193.1521: Flags [.], ack 1, win 4105, length 0
01:45:12.042737 IP 192.168.40.193.1521 > 192.168.40.1.62171: Flags [.], ack 1, win 353, length 0
01:45:12.043181 IP 192.168.40.1.62171 > 192.168.40.193.1521: Flags [.], ack 1, win 4105, length 0
01:46:12.203380 IP 192.168.40.193.1521 > 192.168.40.1.62171: Flags [.], ack 1, win 353, length 0
01:46:12.204089 IP 192.168.40.1.62171 > 192.168.40.193.1521: Flags [.], ack 1, win 4105, length 0
可以看到每隔1分钟,服务端向客户端发起连接,检测客户端是否存在(客户端一直有ack应答,则表示客户端正常)

配置用户连接超时时间:SQLNET.INBOUND_CONNECT_TIMEOUT (单位秒)

它表示等待用户认证超时的时间,单位是秒,缺省值是60秒,如果用户认证超时了,
alert.log显示出错信息"WARNING: inbound connection timed out (ORA-3136)",
sqlnet.log里面出现TNS-12535: TNS:operation timed out错误信息。

[oracle@XAG193 admin]$ cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES = (none)
NAMES.DIRECTORY_PATH = (TNSNAMES,EZCONNECT)
SQLNET.EXPIRE_TIME=1
SQLNET.INBOUND_CONNECT_TIMEOUT=10

#客户端用错误密码登录,如下监控日志

[oracle@XAG193 trace]$ tail -20f /u01/app/oracle/diag/rdbms/mycdb/MYCDB/trace/alert_MYCDB.log 
***********************************************************************
Fatal NI connect error 12170.

  VERSION INFORMATION:
    TNS for Linux: Version 19.0.0.0.0 - Production
    Oracle Bequeath NT Protocol Adapter for Linux: Version 19.0.0.0.0 - Production
    TCP/IP NT Protocol Adapter for Linux: Version 19.0.0.0.0 - Production
  Version 19.3.0.0.0
  Time: 10-JAN-2021 23:13:38
  Tracing not turned on.
  Tns error struct:
    ns main err code: 12535
    
TNS-12535: TNS:operation timed out
    ns secondary err code: 12606
    nt main err code: 0
    nt secondary err code: 0
    nt OS err code: 0
  Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.40.1)(PORT=50359))
2021-01-10T23:13:38.159872+08:00
WARNING: inbound connection timed out (ORA-3136)

sqlnet.ora常见配置:

LOG_FILE_SERVER

[oracle@XAG193 admin]$ cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES = (none)
NAMES.DIRECTORY_PATH = (TNSNAMES,EZCONNECT)
SQLNET.EXPIRE_TIME=1
SQLNET.INBOUND_CONNECT_TIMEOUT=10

DIAG_ADR_ENABLED=off
LOG_DIRECTORY_SERVER=$ORACLE_HOME/network/log
LOG_FILE_SERVER=sqlnet_server.log
LOG_DIRECTORY_CLIENT=$ORACLE_HOME/network/log
LOG_FILE_CLIENT=sqlnet_client.log