謹(jǐn)防持久化+未授權(quán)訪問(wèn)漏洞入侵服務(wù)器
CVE編號(hào)找不到囤热,CNVD有一個(gè):CNVD-2015-07557(國(guó)家信息安全漏洞共享平臺(tái)漏洞編號(hào))猎提。
這是我之前寫過(guò)的文章,漏洞成因旁蔼、影響范圍锨苏、POC與對(duì)抗方案有詳解:
謹(jǐn)防利用Redis未授權(quán)訪問(wèn)漏洞入侵服務(wù)器
RDB(Redis Database疙教、全量保存,默認(rèn)方式)
- 極簡(jiǎn)概括:通過(guò)符合單位時(shí)間數(shù)據(jù)被修改的量作為觸發(fā)蚓炬,或手動(dòng)觸發(fā)松逊,把某一時(shí)刻的全部數(shù)據(jù)寫到磁盤。
- 現(xiàn)象:編譯安裝完Redis后啟動(dòng)肯夏,默認(rèn)會(huì)在根目錄(這默認(rèn)配置地址得吐槽)下生成一個(gè)dump.rdb文件经宏。
- 會(huì)被自動(dòng)觸發(fā)的情形:
- 配置設(shè)置。
- 關(guān)閉Redis服務(wù)驯击。
- Flashall命令烁兰。
- 相關(guān)配置:從6.2.0開始有差異:
6.2.0之前
save 900 1 15分鐘至少有1個(gè)值被改動(dòng),這是避免備份數(shù)據(jù)與內(nèi)存數(shù)據(jù)長(zhǎng)期不一致的兜底策略徊都。
save 300 10 5分鐘至少有10個(gè)值被改動(dòng)沪斟,中庸策略。
save 60 10000 1分鐘至少有1萬(wàn)個(gè)值被改動(dòng)暇矫,避免備份數(shù)據(jù)與內(nèi)存數(shù)據(jù)短時(shí)間大量不一致的策略主之。
6.2.0之后,這意味著某些場(chǎng)景李根,需要改變配置槽奕。
save 3600 1
save 300 100
save 60 10000
這種東西怎么配,若數(shù)據(jù)要緊房轿,時(shí)間就配置的少一點(diǎn)粤攒,若要求性能,對(duì)數(shù)據(jù)丟失有容忍度囱持,那就按照默認(rèn)配置夯接,或加大時(shí)間配置。
若要修改rdb文件存放位置和名稱
dir 自定義路徑
dbfilename 自定義文件名.rdb
其它配置:
stop-writes-on-bgsave-error yes
用于在BGSAVE操作出現(xiàn)錯(cuò)誤時(shí)Redis的行為纷妆。當(dāng)這個(gè)配置選項(xiàng)被設(shè)置為yes時(shí)盔几,如果后臺(tái)保存操作BGSAVE失敗,Redis將停止接受寫操作掩幢,以防止數(shù)據(jù)丟失逊拍。這樣做可以確保數(shù)據(jù)的完整性,因?yàn)樵跓o(wú)法完成后臺(tái)保存操作時(shí)粒蜈,寫入新數(shù)據(jù)可能會(huì)導(dǎo)致數(shù)據(jù)不一致或丟失顺献。
當(dāng)stop-writes-on-bgsave-error被設(shè)置為no時(shí)旗国,Redis在后臺(tái)保存操作失敗時(shí)仍然會(huì)繼續(xù)接受寫操作枯怖。這可能會(huì)導(dǎo)致數(shù)據(jù)不一致或丟失,但也可以確保寫操作的連續(xù)性能曾。
rdbcompression yes
指定Redis在執(zhí)行RDB時(shí)是否啟用LZF算法壓縮度硝。
rdbchecksum yes
用于指定在執(zhí)行RDB(Redis Database)持久化時(shí)是否對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)和檢查肿轨,會(huì)有10%的性能消耗。
rdb-del-sync-files no
在沒(méi)有持久性的實(shí)例中刪除復(fù)制使用的RDB文件蕊程。
- redis/bin/redis-check-rdb椒袍,可檢測(cè)rdb文件是否存壞,并修復(fù)藻茂。
RDB同步持久化與異步非阻塞持久化
- save(不推薦用):執(zhí)行期間會(huì)阻塞其它命令(意味著臨時(shí)停止服務(wù))直到執(zhí)行完畢驹暑,不適合大量請(qǐng)求場(chǎng)景,由于是直接執(zhí)行辨赐,性能比bgsave略高优俘。
- bgsave:會(huì)fork一個(gè)子進(jìn)程去處理備份,異步執(zhí)行期間不會(huì)阻塞其它命令掀序,但是若數(shù)據(jù)資源相當(dāng)龐大帆焕,仍舊會(huì)拉低Redis的性能。
- lastsave:使用lastsave命令不恭,可以查看最后一次執(zhí)行RDB的時(shí)間叶雹,對(duì)于Redis運(yùn)維還是有幫助的。
- 注意:在持久化時(shí)换吧,需要考慮數(shù)據(jù)量的大小折晦,與磁盤大小,避免內(nèi)存或者磁盤不足讓服務(wù)夯住的情況發(fā)生式散。
- fork: 在Unix/Linux系統(tǒng)中用來(lái)創(chuàng)建一個(gè)新的子進(jìn)程的操作筋遭。在調(diào)用fork() 后,操作系統(tǒng)會(huì)復(fù)制當(dāng)前進(jìn)程的所有內(nèi)容(包括內(nèi)存數(shù)據(jù)暴拄、堆棧等)到新的子進(jìn)程中漓滔,從而創(chuàng)建一個(gè)完全獨(dú)立的子進(jìn)程,而子進(jìn)程擁有獨(dú)立的內(nèi)存空間和進(jìn)程 ID乖篷。
RDB恢復(fù)數(shù)據(jù)
- 注意:由于Redis RDB是全量備份响驴,所以不會(huì)像MySQL binlog那種,可以恢復(fù)部分?jǐn)?shù)據(jù)撕蔼。也不是像MySQL redo log那種接近實(shí)時(shí)的備份豁鲤,RDB備份有間隙,所以就算通過(guò)文件恢復(fù)鲸沮,也可能丟失部分?jǐn)?shù)據(jù)琳骡。
- 如果誤刪了數(shù)據(jù):其它節(jié)點(diǎn)(如MySQL)又沒(méi)有備份,可以利用這個(gè)間隙讼溺,立即把rdb文件備份楣号,防止觸發(fā)redis同步功能覆蓋原數(shù)據(jù),把之前持久化的數(shù)據(jù)整沒(méi)了,然后停止Redis(一定要在Redis停止之前備份炫狱,利用Redis命令停止Redis也會(huì)觸發(fā)一次RDB持久化藻懒,利用操作系統(tǒng)命令干掉進(jìn)程則不會(huì)),接著把持久化名字改過(guò)來(lái)视译,隨后啟動(dòng)Redis嬉荆。
- 默認(rèn)處理方式:Redis在啟動(dòng)時(shí)會(huì)讀取配置,所以RDB文件不需要手動(dòng)導(dǎo)入酷含,Redis會(huì)直接讀取里面的數(shù)據(jù)鄙早。
- 優(yōu)點(diǎn):由于RDB文件具有緊湊的單一文件,所以可以方便的被異地備份椅亚,常用的容災(zāi)手段蝶锋。
禁用RDB
修改配置文件:清除未被注釋的save項(xiàng),改為一個(gè)save ""
什往。
AOF(Append Only File扳缕、追加寫,增量保存)
- 極簡(jiǎn)概括:和RDB是并列關(guān)系别威,將Redis服務(wù)器執(zhí)行的寫命令追加到一個(gè)文件的末尾躯舔,由于備份和執(zhí)行不是實(shí)時(shí)的原子性操作,所以仍舊有丟失的可能(Redis存在重點(diǎn)是快速用于組件間通信省古,而不是持久化存儲(chǔ))粥庄。
- 誤區(qū):這里的only單詞很多余,有only不代表RDB模式不能被同時(shí)啟用豺妓。
- 存在意義:
- 畢竟是主流的數(shù)據(jù)庫(kù)惜互,所以要在持久化上利用多備份機(jī)制做到位。
- AOF彌補(bǔ)了RDB備份時(shí)間間隙(最后一次備份~當(dāng)前時(shí)間未保存)的問(wèn)題琳拭。
- AOF彌補(bǔ)了RDB備份時(shí)產(chǎn)生大量磁盤IO的情況發(fā)生训堆。
- 配置
找到redis.conf
appendonly no 改為yes
配置持久化模式
appendfsync everysec/always/no
always:每次寫操作,都進(jìn)行一次追加白嘁,最安全但性能最差坑鱼。
everysec:默認(rèn)值,每秒進(jìn)行一次追加絮缅,最多丟失一秒鐘的數(shù)據(jù)鲁沥。
no:讓操作系統(tǒng)來(lái)處理數(shù)據(jù)同步,由操作系統(tǒng)自行決定何時(shí)將數(shù)據(jù)刷新到磁盤耕魄。
三者從上到下性能依次提升画恰,高可用依次降低。
配置保存路徑吸奴,Redis7新配置允扇,若低版本沒(méi)有马靠,就和RDB目錄一個(gè)位置
appenddirname 'appendonlydir'
配置文件名稱
appendfilename "appendonly.aof"
Redis7針對(duì)aof文件做了拆分
appendonly.aof.base:基本文件,在壓縮文件時(shí)蔼两,會(huì)將壓縮后的最小指令集保留在此當(dāng)中。
appendonly.aof.incr:增量文件逞度,該文件存儲(chǔ)對(duì)基本AOF文件進(jìn)行的增量更改额划。
appendonly.aof.manifest:清單文件,該文件可能與管理和跟蹤AOF文件的狀態(tài)或元數(shù)據(jù)档泽。
備份壓縮相關(guān)配置俊戳,下文有講
上次重寫之后的增長(zhǎng)百分比,這里默認(rèn)為100
auto-aof-rewrite-percentage 100
表示aof文件超過(guò)64MB馆匿。
auto-aof-rewrite-min-size 64mb
雜項(xiàng)配置
no-appendfsync-on-rewrite no
這個(gè)配置指示Redis如何將數(shù)據(jù)寫入磁盤抑胎,設(shè)置為no表示Redis在重寫時(shí)不會(huì)改變其關(guān)于appendfsync設(shè)置的行為。
AOF恢復(fù)數(shù)據(jù)
- 常規(guī)情況下:aof備份文件恢復(fù)數(shù)據(jù)是自動(dòng)的渐北,不需要手動(dòng)操作阿逃。
- 若手動(dòng)備份文件的方式恢復(fù):若對(duì)aof文件做了更名用于多文件備份,恢復(fù)時(shí)需要改為配置文件中的名稱赃蛛,然后重啟恃锉,即可恢復(fù)aof文件中的數(shù)據(jù)。
- 注意:由于flushall也是寫操作呕臂,所以執(zhí)行它有也會(huì)同步aof文件破托,但是由于aof是增量備份,所以在aof文件中刪除flushall字眼歧蒋,然后重啟土砂,就能恢復(fù)數(shù)據(jù)。
AOF破損修復(fù)與檢測(cè)
redis-check-aof 是專門用于檢測(cè)與修復(fù)aof文件的工具谜洽,在redis-cli同級(jí)目錄萝映。
檢測(cè),看到AOF is valid說(shuō)明文件無(wú)問(wèn)題:
./redis-check-aof ../appendonly.aof
AOF analyzed: size=131, ok_up_to=131, diff=0
AOF is valid
但是由于斷電阐虚,進(jìn)程被強(qiáng)制終止锌俱,或其它原因?qū)е碌奈募p壞,可以添加 --fix 去修復(fù)敌呈。
模擬文件損壞贸宏,編輯文件后隨意加載點(diǎn)東西
vim ../appendonly.aof
重啟redis服務(wù),發(fā)現(xiàn)redis服務(wù)起不來(lái)了(配置有服務(wù)磕洪,下文有講)
service redis restart
修復(fù)吭练,看見(jiàn)Successfully字眼,說(shuō)明修復(fù)成功析显,若是redis7鲫咽,請(qǐng)操作appendonly.aof.incr增量文件
./redis-check-aof --fix ../appendonly.aof
0x 83: Expected prefix '*', got: 'a'
AOF analyzed: size=139, ok_up_to=131, diff=8
This will shrink the AOF from 139 bytes, with 8 bytes, to 131 bytes
Continue? [y/N]: y
Successfully truncated AOF
啟動(dòng)redis
service redis start
AOF備份壓縮
- 簡(jiǎn)單概括:由于寫命令的增加,AOF文件越來(lái)越大,恢復(fù)速度也會(huì)隨之增加分尸,因此Redis新增了重寫機(jī)制锦聊,當(dāng)AOF超過(guò)所設(shè)定的最大值時(shí),Redis就會(huì)自動(dòng)啟動(dòng)文件壓縮箩绍,只保留可以恢復(fù)數(shù)據(jù)的最小有效指令集孔庭,或使用bgrewriteaof來(lái)進(jìn)行壓縮。
- 核心原理:原先set a 1材蛛,再執(zhí)行set a 2圆到,一直到set a 10,初始的aof記錄方式是記錄10條備份卑吭,而壓縮只需要記錄1條set a 10芽淡,這樣用于減小文件,也用于快速恢復(fù)數(shù)據(jù)豆赏,這就是最小有效的指令集挣菲。但是一開始就這樣做,意味著時(shí)間換空間(更多的計(jì)算)掷邦,會(huì)降低aof的性能己单。
- 自動(dòng)觸發(fā)(需同時(shí)滿足兩個(gè)配置文件中的條件):
- auto-aof-rewrite-percentage 100:上次重寫之后的增長(zhǎng)百分比,這里默認(rèn)為100耙饰。
- auto-aof-rewrite-min-size 64mb:表示aof文件超過(guò)64MB纹笼。
- 手動(dòng)觸發(fā):命令行執(zhí)行bgrewriteaof命令。
雙備份模式
上文有講苟跪,默認(rèn)開啟的RDB和手動(dòng)開啟AOF廷痘,不會(huì)互相影響,兩者是并列關(guān)系件已。
但是有備份粒度更小的AOF笋额,redis啟動(dòng)時(shí),就不會(huì)加載RDB篷扩。除非在配置文件中配置aof-use-rdb-preamble yes(實(shí)測(cè)這個(gè)配置yes或no不影響AOF+RDB的同時(shí)備份兄猩,版本5.0.9)。
這個(gè)配置值的意義是:用于控制是否在AOF文件的開頭使用RDB文件的格式鉴未。當(dāng)設(shè)置為yes時(shí)枢冤,Redis在AOF文件的開頭會(huì)添加一個(gè)RDB文件的內(nèi)容,以便在重啟時(shí)快速加載數(shù)據(jù)铜秆,提高啟動(dòng)速度和恢復(fù)能力淹真。
純緩存模式
- RDB:配置save ‘’
- AOF:配置appendonly no
- 注意:經(jīng)過(guò)實(shí)測(cè),仍舊可以使用bgsave或save生成rdb文件连茧,或bgrewriteaof生成aof文件核蘸。
擴(kuò)展巍糯,Redis服務(wù)編寫
或許你們好奇redis的啟動(dòng)、關(guān)閉客扎、重啟祟峦、狀態(tài)查看,上文用的service命令徙鱼,其實(shí)是利用bash shell做的宅楞,如下:
touch /etc/init.d/redis
chmod +x /etc/init.d/redis
chkconfig redis on,或 systemctl enable redis.service
vim /etc/init.d/redis
#! /bin/bash
REDISPORT=6379
EXEC=/usr/local/redis/bin/redis-server
REDIS_CLI=/usr/local/redis/bin/redis-cli
PIDFILE=/var/run/redis.pid
CONF="/usr/local/redis/etc/redis.conf"
case "$1" in
start)
if [ -f "$PIDFILE" ]; then
echo "$PIDFILE PID文件已存在疆偿,進(jìn)程已在運(yùn)行或崩潰"
else
echo -n "正在啟動(dòng)Redis..."
$EXEC $CONF
if [ "$?"="0" ]; then
echo "啟動(dòng)成功"
else
echo "啟動(dòng)失敗"
fi
fi
;;
stop)
if [ ! -f "$PIDFILE" ]; then
echo "$PIDFILE PID文件不存在,沒(méi)有被運(yùn)行"
else
PID=$(cat $PIDFILE)
echo "正在關(guān)閉Redis"
$REDIS_CLI -p $REDISPORT shutdown
if [ "$?"="0" ]; then
echo "關(guān)閉成功"
else
echo "關(guān)閉失敗"
fi
fi
;;
restart)
${0} stop
${0} start
;;
kill)
echo "強(qiáng)制終止Redis進(jìn)程"
killall redis-server
if [ "$?"="0" ]; then
echo "終止成功"
else
echo "終止失敗"
fi
;;
status)
if [ -f "$PIDFILE" ]; then
echo "Redis正在運(yùn)行"
else
echo "Redis已停止"
fi
;;
*)
echo "命令出錯(cuò)搓幌,只能執(zhí)行service redis start杆故、stop、restart溉愁、status处铛、kill" >&2
exit 1
esac