线上的数据库,开发可以直接navicat软件直接操作。一旦发生数据泄露,后果严重。需要禁止使用navicat,使用命令行操作,并且能记录每个开发执行的SQL语句。
在跳板机上面写了一个shell脚本,开发只能通过执行shell脚本,来连接数据库
环境如下:
跳板机-->centos7-->192.168.78.133
MySQL-->centos6.5-->192.168.78.128
1.在跳板机安装php,mysql
yum -y install php mariadb-server mariadb mariadb-devel
启动数据库
systemctl start mariadb
2.创建数据库和表
进入数据库
mysql -u root
创建数据库
CREATE DATABASE audit DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
use audit;
创建表
CREATE TABLE `tbl_sql_record` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`rds` varchar(30) NOT NULL DEFAULT '' COMMENT '实例名',
`username` varchar(30) NOT NULL DEFAULT '' COMMENT '用户名',
`content` text NOT NULL COMMENT 'sql命令',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `title` (`create_time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='sql记录表';
3.MySQL服务器创建只读账号
GRANT Select ON *.* TO zhangsan@'%' IDENTIFIED BY "123456";
flush privileges;
4.接下来的操作,都在跳板机上面
编辑php文件,用来将sql语句转换为json
vim /opt/1.php
内容如下:
<?php
array_shift($argv);
$str=implode(' ',$argv);
$sql=json_encode($str);
echo $sql;
编辑shell脚本
vim /opt/sql_con.sh
内容如下:
#!/bin/bash
#MySQL主机列表
db_base='192.168.78.128'
#默认端口号
PORT='3306'
#输出页面
OPTION=`whiptail --title "连接MySQL" --menu "请选择MySQL" 20 40 10 \
"1" "db_base" \
"2" "退出程序" \
3>&1 1>&2 2>&3`
#数字匹配
if [ $? = 0 ]; then
case $OPTION in
1)
HOST=$db_base
RDS="db_base"
;;
*)
echo "程序退出"
exit
;;
esac
#用户名和密码输入框
USERNAME=$(whiptail --title "RDS 用户认证" --inputbox "请输入用户名?" 10 60 3>&1 1>&2 2>&3)
PASSWORD=$(whiptail --title "RDS 密码认证" --passwordbox "请输入密码" 10 60 3>&1 1>&2 2>&3)
#显示RDS所有数据库,-N不显示标题
data=$(/usr/bin/mysql -h $HOST -u $USERNAME -p$PASSWORD -P$PORT -N -e 'show databases' > /tmp/"$USERNAME"_data.txt)
if [ $? != 0 ];then
echo -e "\033[31m 用户验证失败,程序退出 \033[0m"
exit
fi
echo -e "\033[32m 数据库列表: \033[0m"
echo "===================="
#过滤掉默认的数据库
cat /tmp/"$USERNAME"_data.txt | grep -E -v 'information_schema|mysql|performance_schema'
#grep -E -v 'information_schema' $data
echo "===================="
echo -e "\033[32m 请输入sql语句或者exit退出 \033[0m"
#执行sql语句方法
query(){
#mysql>提示符
read -p "mysql> " SQL
#判断输入不为空或者exit
if [ "$SQL" != "" ] && [ "$SQL" != "exit" ];then
#当输入\G时,替换为\\g
sql_ex=$(echo "$SQL" | sed 's@\G;$@\\G;@g')
#判断sql是否包含select
result=$(echo $sql_ex | grep -i "select")
#判断结果,不为空,表示匹配
if [[ "$result" != "" ]];then
#增加显示返回的行数和执行时间,select语句使用FOUND_ROWS()方法显示返回的行数,timestampdiff返回2个时间的差值
sql_query="set @d=now();""$sql_ex"";SELECT FOUND_ROWS() as affected_lines;select timestampdiff(second,@d,now()) as execution_time;"
else
#delete,insert,update...其他语句使用ROW_COUNT()方法显示影响的行数
sql_query="set @d=now();""$sql_ex"";SELECT ROW_COUNT() as affected_lines;select timestampdiff(second,@d,now()) as execution_time;"
fi
#执行insert sql语句
/usr/bin/mysql -h $HOST -u $USERNAME -p$PASSWORD -P$PORT -e "$sql_query"
#当执行不成功时,提示错误
if [ $? != 0 ];then
echo -e "\033[31m sql执行错误 \033[0m"
else
#插入数据库
#sql语句转换为json
content=$(/usr/bin/php /opt/1.php "$sql_ex")
#当前时间
statime=`date +%Y-%m-%d" "%H:%M:%S`
#insert语句,双引号需要转义,content已经转义为json了
insert="insert into audit.tbl_sql_record set rds=\"$RDS\",username=\"$USERNAME\",content=$content,create_time=\"$statime\"";
#执行insert语句
/usr/bin/mysql -u root -e "$insert"
fi
fi
}
#当sql不等于exit时,循环执行方法
while [[ $SQL != "exit" ]]
do
query
done
fi
执行shell脚本,执行sql语句
登录跳板机
进入本机的mysql,创建远程授权账号,方便navicat查看sql执行记录
mysql -u root
grant all PRIVILEGES on *.* to owner@'%' identified by 'owner@123';
flush privileges;
使用navicat新建连接
查看数据表