使用fjpublish发布前端项目(安全篇)

本系列文章共分为基础篇,安全篇,拓展篇。
如果还不了解fjpublish或者不知本文所云的童鞋请先花个5分钟看看基础篇:
使用fjpublish发布前端项目(基础篇)

前言

自从上一期在sf安利使用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

    原文作者:满满
    原文地址: https://segmentfault.com/a/1190000012060917
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞