看各路神仙如何大戰MySQL insecure warning報警有感
一、問題由來
mysql在5.6.5上開始在命令列中直接填入使用者密碼會提示錯誤,例如:
$./mysql -h10.10.30.18 -uwoqutech -pwoqutech -ss -e 'select @@server_id'
Warning: Using a password on the command line interface can be insecure.
330618
如果你要寫一個指令碼呼叫mysql命令來獲得server_id的值,這個Warning的資訊絕對是你的噩夢。
提示這個安全原因本來無可厚非,但是坑爹的是,沒有任何一個引數或者開關能關閉這個Warning。
2012年liu wei同學就提交了這個,到了2017年的今天,還是沒有解決。期間有n多人開罵,其中Van Stokes罵的最經典:
How about this insane idea....
How about MySQL quits trying to save the world from itself and REMOVE THIS STUPID WARNING MESSAGE. It's NONE OF YOUR BUSINESS if I want to use a password on the command line or not. So quit worrying about it. Remove the warning. We don't need to be nannied to death by the likes of you.
翻譯過來就是:
你們腦子秀逗了,趕緊把這個傻×報警資訊清理掉,再不清理麻煩就大了!
罵歸罵,也有很多人提供了對應的解決方案,甚至包括修改MySQL的彙編程式碼來解決。
二、人間大炮一級準備:指令碼自己解決
最簡單的,mysql自己不解決,我們指令碼里面可以過濾。拿到這兩行資訊以後,透過grep -v或者各自程式語言去過濾掉這個錯誤資訊。
但是每個指令碼都需要有額外的邏輯來處理這個資訊,也是大家非常不爽的原因。
Karl Nicoletti就很不爽:
Does the MySQL development team have ANY idea how many man-hours of work they have inflicted on DBAs and developers relying on command line input responses that DO NOT return the word "Warning" or "Error" in the case of successful execution??? I alone will be spending at least 100 hours to upgrade and test all our in-house maintenance, and installation scripts to work around this idiotic warning. Maybe, just MAYBE you could use the word "NOTE:" instead of "Warning:"??? Better yet, provide an option, --no-cmd-line-warning that would shut the damn thing off?
三、人間大炮二級準備:MYSQL_PWD,mysql_config_editor解決
還好,有一些其他的解決方案也可以解決這個問題。
mysql_config_editor
利用mysql_config_editor來儲存使用者名稱密碼,避免輸出Warning資訊
mysql_config_editor set --login-path=woqutech --host=10.10.30.18 --user=woqutech --password
mysql --login-path=woqutech -e "select @@server_id"
這種方式必須手工輸入密碼,在指令碼里面用也非常坑爹。
MYSQL_PWD
透過設定MYSQL_PWD變數來避免輸出Warning資訊
$MYSQL_PWD='woqutech' ./mysql -h10.10.30.18 -uwoqutech -ss -e 'select @@server_id'
330618
這種方式相對接受度比較高。
四、人間大炮三級準備:原始碼解決
既然MySQL是開源的,那我們當然希望透過原始碼解決拉,
原始碼其實很簡單
void print_cmdline_password_warning()
{
static my_bool password_warning_announced= FALSE;
if (!password_warning_announced)
{
fprintf(stderr, "Warning: Using a password on the command line "
"interface can be insecure.\n");
(void) fflush(stderr);
password_warning_announced= TRUE;
}
}
就提交了一個 供大家參考。
五、人間大炮發射:彙編解決
原始碼解決方案的問題在於需要維護自己的版本,每次MySQL新的版本釋出都需要重新打patch,並重新編譯。
還有什麼其他的辦法列,Andrew McGill和Perry Harrington提供了在彙編層面解決這個問題的辦法!
5.1 刪除彙編中Warning資訊
Andrew McGill使用的是perl,解決方案如下
perl -p -i -e 's/(Warning: Using a password on the command line interface can be insecure..)/"\0"x(length($1))/es' /usr/local/mysql/bin/mysql
簡單解釋一下:
-
mysql程式編譯出來就是一個彙編的程式碼
-
\0代表是空字元,"\0"x(length($1)表示多個空字元,不會列印任何字元
-
Andrew McGill利用perl將Warning: Using a password on the command line interface can be insecure.的資訊都替換為空,也就不會列印Warning資訊了。
5.2print_cmdline_password_warning函式邏輯修改
Perry Harrington提供了一種匪夷所思的彙編程式碼修改方式:
原版在測試環境下不可用:
printf '\x75' | dd of=./mysql bs=1 seek=$((16#$(objdump --disassemble -F mysql |grep password_warning|grep je|awk '{print $1}'|cut -d: -f1|sed -e 's/^.//g'))) count=1 conv=notrunc
可用版本:
printf '\xeb' | dd of=./mysql bs=1 seek=$((16#$(objdump --disassemble -F mysql |grep password_warning|grep jne|awk '{print $1}'|cut -d: -f1|sed -e 's/^.//g'))) count=1 conv=notrunc
這個需要解釋一下
-
print_cmdline_password_warning函式中會判斷password_warning_announced是否為FALSE,由於password_warning_announced是靜態變數,再次進入這個函式將不會列印錯誤資訊,函式程式碼如下:
/**
* This function should be called to print a warning message
* if password string is specified on the command line.
*/
void print_cmdline_password_warning()
{
static my_bool password_warning_announced= FALSE;
if (!password_warning_announced)
{
fprintf(stderr, "Warning: Using a password on the command line "
"interface can be insecure.\n");
(void) fflush(stderr);
password_warning_announced= TRUE;
}
}
-
彙編程式碼中只需要把判斷password_warning_announced的邏輯修改成直接跳轉,就可以不列印出來了。
怎麼修改列,透過objdump 可以檢視到print_cmdline_password_warning函式的邏輯如下:
000000000044d980 <print_cmdline_password_warning> (File Offset: 0x4d980):
44d980: 55 push %rbp
44d981: 48 89 e5 mov %rsp,%rbp
44d984: 53 push %rbx
44d985: 48 83 ec 08 sub $0x8,%rsp
44d989: 80 3d e0 aa 59 00 00 cmpb $0x0,0x59aae0(%rip) # 9e8470 <_ZZ30print_cmdline_password_warningE26password_warning_announced> (File Of
fset: 0x5e8470)
44d990: 75 2f jne 44d9c1 <print_cmdline_password_warning+0x41> (File Offset: 0x4d9c1)
44d992: 48 8b 1d 07 00 4c 00 mov 0x4c0007(%rip),%rbx # 90d9a0 <_DYNAMIC+0xd50> (File Offset: 0x50d9a0)
44d999: 48 8d 3d 40 c7 08 00 lea 0x8c740(%rip),%rdi # 4da0e0 <special_opt_prefix_lengths+0x40> (File Offset: 0xda0e0)
44d9a0: ba 49 00 00 00 mov $0x49,%edx
44d9a5: be 01 00 00 00 mov $0x1,%esi
44d9aa: 48 8b 0b mov (%rbx),%rcx
44d9ad: e8 26 df fb ff callq 40b8d8 <fwrite@plt> (File Offset: 0xb8d8)
44d9b2: 48 8b 3b mov (%rbx),%rdi
44d9b5: e8 ce e0 fb ff callq 40ba88 <fflush@plt> (File Offset: 0xba88)
44d9ba: c6 05 af aa 59 00 01 movb $0x1,0x59aaaf(%rip) # 9e8470 <_ZZ30print_cmdline_password_warningE26password_warning_announced> (File Offset: 0x5e8470)
44d9c1: 48 83 c4 08 add $0x8,%rsp
44d9c5: 5b pop %rbx
44d9c6: c9 leaveq
44d9c7: c3 retq
44d9c8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
44d9cf: 00
我們看到44d990行,上一行比較了password_warning_announced的值,jne表示不等於就跳轉到函式尾44d9c1(退出堆疊),我們把彙編指令修改成無論如何都跳轉jmp不就解決了這個問題嗎?
44d990: 75 2f jne 44d9c1 <print_cmdline_password_warning+0x41> (File Offset: 0x4d9c1)
所以修改的策略就是把jne修改成jmp,對應的就是要把75修改為eb。彙編指令操作碼可以查考
-
75是jne
-
eb是jmp
所以最終的修改方式就是這麼一個詭異的命令:
printf '\xeb' | dd of=./mysql bs=1 seek=$((16#$(objdump --disassemble -F mysql |grep password_warning|grep jne|awk '{print $1}'|cut -d: -f1|sed -e 's/^.//g'))) count=1 conv=notrunc
-
objdump –disassemble -F mysql |grep password_warning|grep jne|awk '{print $1}'|cut -d: -f1|sed -e 's/^.//g' 獲得要修改的mysql彙編檔案位元組偏移位置
-
seek=$((16#$(objdump –disassemble -F mysql |grep password_warning|grep jne|awk '{print $1}'|cut -d: -f1|sed -e 's/^.//g'))) 獲得16進位制“要修改的mysql彙編檔案位元組偏移位置”
-
printf '\xeb' | dd of=./mysql bs=1 seek=$((16#$(objdump –disassemble -F mysql |grep password_warning|grep jne|awk '{print $1}'|cut -d: -f1|sed -e 's/^.//g'))) count=1 conv=notrunc 將mysql彙編檔案中print_cmdline_password_warning函式中jne修改為jmp,直接跳轉,不列印錯誤資訊
七、總結
MySQL出於安全的考慮,建議大家不要在命令列中寫password,但是隻是在命令列中提示,並且還不能關閉,確實比較坑,我們要做一個企業級的產品也需要對每一個細節和功能考慮的更加仔細和細緻,避免出現類似的問題。
雖然官方也不知道啥時候能解決這個Warning的問題,但是各路大神各出奇招來解決這個問題,也給我們提供了很多思路,很有借鑑意義。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2140329/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 看yangtingkun大師blog有感
- prometheus配置MySQL郵件報警PrometheusMySql
- DVWA靶場實戰(六)——Insecure CAPTCHAAPT
- mysql WarningMySql
- Centos下_MysqL5.7在使用mysqldump命令備份資料庫報錯:mysqldump: [Warning] Using a password on the command line interface can be insecure.CentOSMySql資料庫
- 如何解決 After Effects報警
- 神仙打架:大模型能力線上比拼大模型
- 警報:大模型正叩響“內容安全”大門大模型
- 大資料看郭韓大決戰——資訊圖大資料
- 報警系統QuickAlarm之報警規則解析UI
- Warning:The /usr/local/mysql/data directory is not owned by the 'mysql' or '_mysql'MySql
- 【MySQL】檔案描述符導致報警一則MySql
- 圍棋人機大戰|看各大巨頭如何落地人工智慧!人工智慧
- Python釘釘報警及Zabbix整合釘釘報警Python
- Elasticsearch開發實戰篇——基於ES的SQL報警引擎ElasticsearchSQL
- Oracle警報系統Oracle
- zabbix釘釘報警
- 減半警報器
- oracle 中 alert 報警日誌過大的處理方法Oracle
- Linux 下如何用 mutt 設定郵件報警Linux
- 報警機制如何用多執行緒實現執行緒
- 如何解決伺服器開機報警問題伺服器
- 【python 監控報警】python自動發微信監控報警Python
- vue 自定義報警元件Vue元件
- 專案報警機制
- zabbix郵件報警通知
- 大資料看北上廣深生存報告大資料
- 讀《mysql是怎樣執行的》有感MySql
- pinpoint-docker開啟郵件報警和整合釘釘報警推送Docker
- 如何處理Docker錯誤訊息:please add——insecure-registryDocker
- MySQL 大表最佳化方案,收藏了細看!MySql
- 看富士康七連跳事件,富娃有感而發事件
- 讀《大資料時代》開頭部分有感大資料
- Windows 神仙軟體Windows
- CentOS 配置OOM監控報警CentOSOOM
- zabbix報警指令碼(wechat,email)指令碼AI
- Prometheus監控報警系統Prometheus
- 伺服器開機報警伺服器