墨天轮:
CSDN :
ITPUB:
腾讯云:
————————————————————————————
那么我们可以通过编写 shell 脚本通过正则表达式将监听日志中的 IPv4 都全部取出来。因为监听日志中有两种连接类型如下,第一类是通过 JDBC 访问,另一类是 自身通过 = 访问的。
22-MAR-2024 09:50:47 * (CONNECT_DATA=(CID=(PROGRAM=newdt)(HOST=__jdbc__)(USER=root))(SERVICE_NAME=jiekexustb)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.75.22)(PORT=49126)) * establish * jiekexustb * 0
2024-03-22T09:51:10.343176+08:00
22-MAR-2024 09:51:10 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=jiekexustb)(CID=(PROGRAM=oracle)(HOST=t4-rac19c-72)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.75.23)(PORT=44953)) * establish * jiekexustb * 0
2024-03-22T09:51:11.414854+08:00
单机环境
--查看监听日志位置
su - oracle
lsnrctl status
cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener/trace/listener.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $10}'|awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u > iptables_rule_ip.txt
cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener/trace/listener.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $6}' |awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u >> iptables_rule_ip.txt
if [ $? = 0 ];then
awk '{count[$1]++;} END {for (i in count) {print i}}' iptables_rule_ip.txt|sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|while read line
do
echo "firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="$line" port protocol="tcp" port="11521" accept'"
done
fi
cat iptables_rule_ip.txt
cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener/trace/listener.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $10}'|awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u
这段 Shell 命令链主要用于从 监听器的日志文件中提取并过滤出唯一的 IPv4 地址。命令逐级解析和操作流程如下:
| cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener/trace/listener.log:
使用 cat 命令读取 Oracle 监听器日志文件内容。
| sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p':
通过管道 (|) 将日志内容传递给sed命令,并启用静默模式 -n,只打印匹配IPv4地址格式的行。
| awk '{print $10}':
对匹配到的行进一步处理,仅打印每行的第 10 个字段(按照空格或制表符分隔)。
| awk -F "=" '{print $4}':
再次使用 awk,但这次以等号(=)作为字段分隔符,打印出第 4 个字段的内容。
| awk -F ")" '{print $1}':
继续使用 awk,这次以右括号)作为分隔符,打印出第一个字段。
| grep -v ^$:
使用 grep 命令排除所有空行(即不包含任何字符的行)。
| sort -u:
最后,通过 sort 命令对输出进行排序,并使用 -u 选项去除重复项,从而得到唯一列表的IPv4地址。
sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'
这是一个在 Unix 或 Linux 环境下使用的命令,使用了 sed(流编辑器)对输入的文本进行处理。具体解释如下:
sed -n:sed 命令默认会打印每一行处理后的结果,这里的 -n 参数表示静默模式,即只打印经过命令匹配且要求打印的行。
//p:这是 sed 的命令格式,其中 是正则表达式,p 表示打印。当某一行与给定的正则表达式 匹配时,这一行会被打印出来。
/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/ 是一个正则表达式,它用于匹配符合 IPv4 地址格式的字符串,也就是类似于 “xxx.xxx.xxx.xxx” 的形式,其中每个 “xxx” 都代表 0 到 255 之间的数字。
因此,整个命令的作用是:对于输入的文本,只打印出其中的IPv4地址。
如下是一个例子:
jiekexuadg:/u01/app/oracle/diag/tnslsnr/jiekexuadg/listener/trace(jiekeadg)$ cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener/trace/listener.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $10}'|awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u > iptables_rule_ip.txt
jiekexuadg:/u01/app/oracle/diag/tnslsnr/jiekexuadg/listener/trace(jiekeadg)$ cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener/trace/listener.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $6}' |awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u >> iptables_rule_ip.txt
jiekexuadg:/u01/app/oracle/diag/tnslsnr/jiekexuadg/listener/trace(jiekeadg)$ cat iptables_rule_ip.txt | sort -u > iptables_rule_ip2.txt
jiekexuadg:/u01/app/oracle/diag/tnslsnr/jiekexuadg/listener/trace(jiekeadg)$ if [ $? = 0 ];then
> awk '{count[$1]++;} END {for (i in count) {print i}}' iptables_rule_ip2.txt|sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|while read line
> do
> echo "firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="$line" port protocol="tcp" port="11523" accept'"
> done
> fi
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.75.35" port protocol=tcp port=11523 accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.75.36" port protocol=tcp port=11523 accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.75.25" port protocol=tcp port=11523 accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.75.24" port protocol=tcp port=11523 accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.75.41" port protocol=tcp port=11523 accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.75.18" port protocol=tcp port=11523 accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.75.43" port protocol=tcp port=11523 accept'
jiekexuadg:/u01/app/oracle/diag/tnslsnr/jiekexuadg/listener/trace(jiekeadg)$ cat all_ip2.txt
192.168.75.24
192.168.75.35
192.168.75.36
192.168.75.25
192.168.75.18
192.168.75.41
192.168.75.43
RAC 环境
从 RAC 主库 监听查看连接 IP
查看 scan 监听位置
su - grid
$lsnrctl status LISTENER_SCAN1
$cd $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener_scan1/trace
因为 19c 对于监听日志过大的问题进行了优化,当监听日志达到一定大小后就会被切割,生成最新的 .log,历史的日志则会被切分到.log,.log,依次类推则日志中会出现 .log,所以查找 IP 时还需要遍历这些日志。
cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener_scan1/trace/listener_scan1.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $10}'|awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u > iptables_rule_ip2.txt
cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener_scan1/trace/listener_scan1.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $6}' |awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u >> iptables_rule_ip2.txt
cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener_scan1/trace/listener_scan1_[1-22].log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $10}'|awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u >> iptables_rule_ip2.txt
cat $ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener_scan1/trace/listener_scan1_[1-22].log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $6 }'|awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u >> iptables_rule_ip2.txt
--生成添加防火墙白名单命令
if [ $? = 0 ];then
awk '{count[$1]++;} END {for (i in count) {print i}}' iptables_rule_ip2.txt|sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|while read line
do
echo "firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="$line" port protocol="tcp" port="11521" accept'"
done
fi
cat iptables_rule_ip2.txt
另外, 有时可能运行在另一个节点,所以以上 shell 需要在节点 2 的 grid 用户下也要运行一次,将生成的 .txt 和节点 1 的合并后去重,生成最终需要的 IP 地址信息。如果 RAC 有三、五个 则需要去各个目录下查找,相对而言还是比较麻烦的。
cat iptables_rule_ip2.txt >> iptables_rule_ip1.txt
cat iptables_rule_ip1.txt | sort -u > iptables_rule_ip.txt
如果还有部分应用或者客户端直接连接 vip 而不是 scan ip 则还需要当成单机环境去本地监听日志里查找lsnrctl,最终合并到 .txt 文件。
$ lsnrctl status | grep "Listener Log File"
Listener Log File /u01/app/19.0.0/grid/network/log/listener.log
cat /u01/app/19.0.0/grid/network/log/listener.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $10}'|awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u > iptables_rule_ip0.txt
cat /u01/app/19.0.0/grid/network/log/listener.log |sed -n '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/p'|awk '{print $6}' |awk -F "=" '{print $4}'|awk -F")" '{print $1}'|grep -v ^$ |sort -u >> iptables_rule_ip0.txt
将上面 echo 出来的信息添加到防火墙白名单中即可,也可查看 .txt 文件中的 IPv4 地址系统工程师自行编辑防火墙白名单。
这个方法的弊端就是如果已经有正常客户端配置了连接信息但是一次都没有登录,那么添加白名单后也会被阻挡,不可访问。另外,也需要保证所有的监听日志均存在没有被删除的情况下才可以实施。当然,最保险的方式还是去找网络工程师,通过他们查看访问此数据库的 IP 地址有哪些才是上策。
以上记录于 2024 年 4 月 3 日。
全文完lsnrctl,希望可以帮到正在阅读的你,如果觉得有帮助,可以分享给你身边的朋友,同事,你关心谁就分享给谁,一起学习共同进步~~~
欢迎关注我公众号【 DBA之路】,第一时间一起学习新知识!以下四个地址可以找到我,其他地址均属于盗版侵权爬取我的文章,而且代码格式、图片等均有错乱,不方便阅读,欢迎来我公众号或者墨天轮地址关注我,第一时间收获最新消息。
欢迎关注我的公众号【 DBA之路】,第一时间一起学习新知识!————————————————————————————
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。