使用fjpublish發佈前端項目(安全篇)

本系列文章共分爲基礎篇,安全篇,拓展篇。
若是還不瞭解fjpublish或者不知本文所云的童鞋請先花個5分鐘看看基礎篇:
使用fjpublish發佈前端項目(基礎篇)html

前言

自從上一期在sf安利使用fjpublish來進行項目發佈後收到了很多小夥伴的star和建議,證實fjpublish確實是一個對前端圈有幫助的輪子,今天就着fjpublish2.0.0正式版發佈之機來談談如何使用fjpublish安全地發佈項目,也能夠直接查看文檔原文前端

服務器登陸信息安全

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

1.版本忽略文件(安全等級 ★)

將配置文件添加至版本忽略列表是最簡單的方式也是最不穩定的方式,由於說不定何時就忘記把配置文件加入版本忽略列表致使密碼暴露,不過若是都是發佈內網,那麼問題也不大。github

//例如在.gitignore中添加這一行
...
fjpublish.config.js
...

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

可使用fjpublish env <env> --ssh <server>選項在每次發佈時配置服務器信息,這樣在配置文件中將能夠不用配置ssh字段。server參數的格式爲:[env:]<username><@host>[:port][#password]shell

  • 密碼能夠省略,若是省略密碼,fjpublish將在命令確認後單獨彈出一個輸入框填寫密碼,徹底模擬ssh的登陸行爲,例如:fjpublish env test --ssh root@192.168.0.100segmentfault

  • 若爲同時發佈多個環境,請寫上當前設置的ssh信息是爲哪一個環境設置,例如:fjpublish env test,public --ssh public:root@192.168.0.100#123456,若只發佈一個環境則可省略。安全

不過這個命令實際使用很麻煩,不過也免去了把密碼寫在配置文件的擔心。服務器

3.免密發佈(安全等級 ★★★)

fjpublish配置文件中的ssh選項徹底就是ssh2庫的選項,那麼熟悉ssh登陸服務器的同窗應該知道能夠免密登陸服務器。
原理就是把本地的公鑰放到服務器的授信文件中,下次再登陸服務器時將再也不須要密碼。下面簡單描述操做步驟: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

相關文章
相關標籤/搜索