使用fjpublish釋出前端專案(安全篇)

滿滿發表於2019-01-23

本系列文章共分為基礎篇,安全篇,擴充篇。
如果還不瞭解fjpublish或者不知本文所云的童鞋請先花個5分鐘看看基礎篇:
使用fjpublish釋出前端專案(基礎篇)

前言

自從上一期在掘金安利使用fjpublish來進行專案釋出後收到了不少小夥伴的star和建議,證明fjpublish確實是一個對前端圈有幫助的輪子,今天就著fjpublish2.0.0正式版釋出之機來談談如何使用fjpublish安全地釋出專案,也可以直接檢視文件原文

伺服器登入資訊保安

我相信這是小夥伴們關心的重點,對於把生產伺服器密碼什麼的放在別人開發的工具的配置檔案中,估計睡覺也不會安穩吧…
那麼怎麼樣使用fjpublish才能更安全呢,以下將列出幾個方法,請根據自己要釋出的環境和掌握難度自行配置。

1.版本忽略檔案(安全等級 ★)

將配置檔案新增至版本忽略列表是最簡單的方式也是最不穩定的方式,因為說不定什麼時候就忘記把配置檔案加入版本忽略列表導致密碼暴露,不過如果都是釋出內網,那麼問題也不大。

//例如在.gitignore中新增這一行
...
fjpublish.config.js
...複製程式碼

2.命令選項配置(安全等級 ★★)

可以使用fjpublish env <env> --ssh <server>選項在每次釋出時配置伺服器資訊,這樣在配置檔案中將可以不用配置ssh欄位。server引數的格式為:[env:]<username><@host>[:port][#password]

  • 密碼可以省略,如果省略密碼,fjpublish將在命令確認後單獨彈出一個輸入框填寫密碼,完全模擬ssh的登入行為,例如:fjpublish env test --ssh root@192.168.0.100

  • 若為同時釋出多個環境,請寫上當前設定的ssh資訊是為哪個環境設定,例如:fjpublish env test,public --ssh public:root@192.168.0.100#123456,若只釋出一個環境則可省略。

不過這個命令實際使用很麻煩,不過也免去了把密碼寫在配置檔案的擔憂。

3.免密釋出(安全等級 ★★★)

fjpublish配置檔案中的ssh選項完全就是ssh2庫的選項,那麼熟悉ssh登入伺服器的同學應該知道可以免密登入伺服器。
原理就是把本地的公鑰放到伺服器的授信檔案中,下次再登入伺服器時將不再需要密碼。下面簡單描述操作步驟:

  • 使用ssh-keygen -b 1024 -t rsa生成一對‘不帶密碼’的公私鑰;

  • 把其中的公鑰內容附加到伺服器的~/.ssh/authorized_keys中;

  • 好了,現在你可以每次ssh登入伺服器都不需要伺服器密碼了。

原諒我寫得那麼草率,因為這個過程不是我要說的重點,而且我也為你準備了一篇文章,也可以自行多谷歌幾篇`免密登入伺服器`的文章。
另外,fjpublish也有一個fjpublish auth <server> [--key <key>]的命令用於快速將公鑰檔案認證入伺服器,感興趣了可以瞭解一下。

那麼對應fjpublish的配置檔案需要改為如下配置:

module.exports = {
    modules: [{
        name: `測試環境`,
        env: `test`,
        ssh: {
            host: `12.23.345.678`,
            username: `root`,
            //rc版本的user選項和userName選項請在未來統一配置為username
            //privateKey為認證在伺服器的公鑰對應的私鑰地址,請靈活變通
            privateKey: require(`fs`).readFileSync(`/Users/manman/.ssh/id_rsa`) //mac使用者舉例
            privateKey: require(`fs`).readFileSync(`C:/User/manman/.ssh/id_rsa`) //window使用者舉例
            privateKey: require(`fs`).readFileSync(`${require(`os`).homedir()}/.ssh/id_rsa`) //通用寫法
        },
        buildCommand: `build`,
        localPath: `example`,
        remotePath: `/www/example`,
    }],
}複製程式碼

這樣配置,即使你的配置檔案不小心洩漏出去,但是沒拿到你的私鑰檔案也是無法登陸伺服器的。
不過較真來說,這對於fjpublish的開發者及依賴庫的開發者而言私鑰檔案還是可以讀取到的,不能算絕對安全。(我發誓我沒有寫後門,我也害怕依賴庫的開發者竊取我的私鑰)

4.免密釋出進階版(安全等級 ★★★★)

其實說是進階版,無非這次是生成一對帶密碼的公私鑰,這樣每次ssh登入伺服器需要輸入的是私鑰的密碼,而不是伺服器的密碼。
對應fjpublish的配置檔案中ssh項需要改為如下配置:

module.exports = {
    modules: [{
        name: `測試環境`,
        env: `test`,
        ssh: {
            host: `12.23.345.678`,
            username: `root`,
            //rc版本的user選項和userName選項請在未來統一配置為username
            //privateKey為認證在伺服器的公鑰對應的私鑰地址,請靈活變通
            privateKey: require(`fs`).readFileSync(`/Users/manman/.ssh/password`) //mac使用者
            privateKey: require(`fs`).readFileSync(`C:/User/manman/.ssh/password`) //window使用者
            privateKey: require(`fs`).readFileSync(`${require(`os`).homedir()}/.ssh/password`) //通用寫法
            passphrase: `123456` //私鑰的密碼
        },
        buildCommand: `build`,
        localPath: `example`,
        remotePath: `/www/example`,
    }],
}
...複製程式碼

不過這樣一樣沒有做到絕對的安全,請接著往下看。

5.終極大招(安全等級 ★★★★★)

是時候放出大招了,這是方法4的升級版,對於私鑰中的密碼,可以不用寫入配置檔案中,我們可以使用ssh代理(ssh-agent)先在本機記錄私鑰密碼,這樣釋出時就不需要私鑰密碼也不需要伺服器密碼。
簡單介紹一下,ssh-agent是一個用來幫你記住私鑰密碼的程式,它是OpenSSH中預設包括的ssh代理程式,因為篇幅有限,所以這裡不介紹如何配置ssh-agent,請一定一定要看這篇文章。這時fjpublish的配置檔案要改為這樣:

module.exports = {
    modules: [{
        name: `測試環境`,
        env: `test`,
        ssh: {
            host: `12.23.345.678`,
            username: `root`,
            //rc版本的user選項和userName選項請在未來統一配置為username
            agent: process.env.SSH_AUTH_SOCK,
            agentForward: true,
        },
        buildCommand: `build`,
        localPath: `example`,
        remotePath: `/www/example`,
    }],
}複製程式碼

這樣,再也不用擔心密碼洩露了,不過一路下來配置的過程是繁雜的,通常做到第四點已經很安全了,連大名鼎鼎的xshell都被爆出有後門,那麼還有什麼是絕對安全的呢。

檔案操作安全

fjpublish就像一個黑盒,使用者只管設定配置檔案,而後fjpublish就會完成既定任務,那麼問題就來了,如果配置不正確會不會對本地計算機或者遠端伺服器的檔案造成不可挽回的損壞呢。事實上fjpublish中寫了很多關鍵的判斷,也專門開發了一個--check選項來進行檢查,如果第一次使用有點忐忑不安,可以使用這個功能檢測一下。
例如下面的配置:

module.exports = {
    modules: [{
        name: `測試環境`,
        env: `test`,
        ssh: {
            host: `192.168.0.xxx`,
            username: `root`,
            //rc版本的user選項和userName選項請在未來統一配置為username
            password: `123456`
        },
        remotePath: `/abc`,
    }],
    completeHook(fj) {
        console.log(fj._metadata.modules.test);
    },
}複製程式碼

很明顯這個配置檔案是有以下問題:

  • buildCommand未設定;

  • localPath或localPathEntries沒有設定其中之一;

  • remotePath遠端檔案路徑是不安全的路徑(非二級目錄以上的絕對路徑)。

那麼我們敲入命令fjpublish env test --check,這時fjpublish會跳過所有中介軟體檔案操作的流程,只執行其中的引數判斷的部分,然後在最先檢測到錯誤的地方就停止並丟擲錯誤,你可以試一試並逐一改正再試試。

如果你的引數配置正確,那麼你可以關注一下completeHook這個鉤子函式列印出的資料,其中`_commands`就是表示將要在遠端環境執行的命令,如果沒有危險操作,那麼就是ok的。

其實說得再安全都是廢話,而且有些錯誤只在執行時才能發現,所以最保險的方式為:請先在測試環境試用fjpublish!!!

結語

感興趣的童鞋可以直接移步官方文件瞭解更多,別忘了在github上給我點個star哦。

下一期我們將談論如何使用fjpublish進行擴充,解鎖更多功能,拜拜∩__∩y。

fjpublish官方交流群:608809145

相關文章