从mysql命令中提取相关信息


=Start=

缘由:

简单整理一下最近在做的mysql命令信息提取的内容,方便后面有需要的时候参考(简单能想到的就是其他客户端连接命令的解析和提取)。

正文:

参考解答:

通用性的大体流程:

  1. 先读官方的manual文档,看有哪些典型选项和写法;
  2. 再对真实数据进行抽样,看看能正确提取到哪些信息;
  3. 对无法提取/提取错误的日志进行针对性分析,优化改进提取逻辑;
  4. 做一个结果统计分析的功能,评估一下提取逻辑的有效性和局限性,用数据指导后面的操作决策。
阅读mysql manual文档
从 mysql 的命令中提取 user/password/host/port/database 等信息。
$ man mysql
...
•   --user=user_name, -u user_name
•   --password[=password], -p[password]
•   --host=host_name, -h host_name
•   --port=port_num, -P port_num
•   --database=db_name, -D db_name The database to use. This is useful primarily in an option file.

$ man mysqldump
...
NAME
   mysqldump - a database backup program

SYNOPSIS
   mysqldump [options] [db_name [tbl_name ...]]

   •   --user=user_name, -u user_name The user name of the MySQL account to use for connecting to the server.
   •   --host=host_name, -h host_name Dump data from the MySQL server on the given host. The default host is localhost.
   •   --port=port_num, -P port_num For TCP/IP connections, the port number to use.
...
简单试试看效果
$ mysql
ERROR 1045 (28000): Access denied for user '$(id -un)'@'localhost' (using password: NO)
$
$ mysql -uroot
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
$
$ mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
$
$ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.28 Homebrew
...
$ mysql -uroot -p -P3306
$ mysql -uroot -p -P 3306
$ mysql -uroot -p --port 3306
$ mysql -uroot -p --port    3306
$ mysql -uroot -p --port=3306
$ mysql -uroot -p --port=  3306
mysql: [ERROR] mysql: Empty value for 'port' specified.
$
$ mysql -uroot -p --port3306
mysql: [ERROR] unknown option '--port3306'.
$
用SQL进行字符串处理以提取相关信息
# 因为bash日志只是记录了命令,但并未记录命令的执行状态(成功/失败),所以下面的单纯基于执行命令字符串做子串提取可能会拿到错误/实际不可用的结果。
# 比如 m_port 取到的结果不是数字格式的字符串。
,case
when cmd like '%--host%' then split(split(cmd, '--host=')[1], ' ')[0]
when cmd like '% -h%' then split(trim(split(cmd, ' -h')[1]), ' ')[0]
else 'default'
end as m_host

,case
when cmd like '%--port%' then split(split(cmd, '--port=')[1], ' ')[0]
when cmd like '% -P%' then split(trim(split(cmd, ' -P')[1]), ' ')[0]
else 'default'
end as m_port

,case
when cmd like '%--user%' then split(split(cmd, '--user=')[1], ' ')[0]
when cmd like '% -u%' then split(trim(split(cmd, ' -u')[1]), ' ')[0]
else 'default'
end as m_user

,case
when cmd like '%--password%' then split(split(cmd, '--password=')[1], ' ')[0]
when cmd like '% -p%' then split(trim(split(cmd, ' -p')[1]), ' ')[0]
else 'default'
end as m_pass

-- 从mysql命令中提取出的信息可能有些脏数据需要过滤,这里以提取的明文密码为例进行说明:
-- (m_pass not in ('','default') and m_pass not like '-%')

,case
when cmd like '%--database%' then split(split(cmd, '--database=')[1], ' ')[0]
when cmd like '% -D%' then split(trim(split(cmd, ' -D')[1]), ' ')[0]
else 'xdefaultx'
end as m_db
对提取结果进行评估分析
# 先对提取字段进行标签化处理,后面再基于不同维度进行 group by 以统计不同标签在整体数据中的占比情况

,if(m_host in ('127.0.0.1','localhost'),1,0) as m_host_local

,if(m_port rlike '^(\\d+){1,}$',1,0) as m_port_numeric

,if(m_pass not in ('','default') and m_pass not like '-%',1,0) as m_pass_exists
参考链接:

Connecting to the MySQL Server Using Command Options
https://dev.mysql.com/doc/refman/5.7/en/connecting.html

Command Options for Connecting to the Server
https://dev.mysql.com/doc/refman/8.0/en/connection-options.html

Tired of manually extracting login credentials from mysql connection strings? Look no further!
https://www.npmjs.com/package/mysql-parse

=END=


《“从mysql命令中提取相关信息”》 有 1 条评论

  1. 直接在mysql命令行中通过“-e”选项指定要执行的SQL语句,这样的话这条mysql命令在连接并执行了SQL语句之后就直接退出,不会像常规的mysql命令那样还保持一个交互的终端
    `
    ,case
    when cmd like ‘%–execute=%’ then split(cmd, ‘–execute=’)[1]
    when cmd like ‘% -e %’ then split(cmd, ‘ -e ‘)[1]
    when cmd like ‘% -Ne %’ then split(cmd, ‘ -Ne ‘)[1]
    when cmd like ‘% -Bse %’ then split(cmd, ‘ -Bse ‘)[1]
    when cmd like ‘% -se %’ then split(cmd, ‘ -se ‘)[1]
    else ”
    end as cmd_sql

    • –execute=statement, -e statement Execute the statement and quit. The default output format is like that produced with –batch. See Section 4.2.2.1, “Using Options on the Command Line”, for some examples. With this option, mysql does not use the history file.

    • –silent, -s Silent mode. Produce less output. This option can be given multiple times to produce less and less output.

    • –skip-column-names, -N Do not write column names in results.

    • –batch, -B Print results using tab as the column separator, with each row on a new line. With this option, mysql does not use the history file.
    Batch mode results in nontabular output format and escaping of special characters. Escaping may be disabled by using raw mode; see the description for the –raw option.
    `

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注