学习Go语言中的软件架构

322 阅读5分钟

安全是重要的

Security 安全是非常重要的,也是一个巨大复杂的话题,我肯定是在说显而易见的事情,但我想明确的是,这篇文章的重点是保护依赖关系的安全。这在实践中意味着有一种方法来确定我们使用的包是否没有暴露于已知的漏洞,这包括标准库包和第三方包。

我将与你分享一些不同的工具来确定我们使用的包是否安全和最新。为了使这一切发挥作用,我们需要有一些东西已经到位了。持续集成。如果你还没有,我建议你投资一些资源来拥有它,因为通过使用持续集成,我将要分享的很多东西将被自动化并更容易实现。

保证依赖关系的安全

无论你使用Github ActionsCircleCIJenkinsCI还是GitlabCi;我将向你展示的步骤都是相似的,关键的部分是要有一种方法来自动确定我们使用的软件包是否是。

  1. 是最新的
  2. 无漏洞

我建议添加到你的持续集成中,以确定是否满足这些要求的工具如下。

  • Dependabot,
  • gosec linter。
  • Snyk 服务。
  • CodeQL,以及
  • versions.

Dependabot

Dependabot是Github的一项服务,它允许我们保持我们的依赖性,它支持多种编程语言,它是开源的,在某些情况下,还有兼容具体CI服务的替代品,如GitlabCI

Dependabot的工作方式是定义一个与你的仓库相关联的配置文件,指出软件包生态系统,如Go Modules、NPM、Maven或Docker(仅举几例);以及用于检查正在使用的软件包是否有更新的具体时间间隔。

因为Dependabot是Github的一部分,它与Github Actions整合得很好,为我的To-Do微服务实例启用Go模块检查的简单配置如下。

 1version: 2
 2updates:
 3  - package-ecosystem: "gomod"
 4    directory: "/"
 5    schedule:
 6      interval: "daily"
 7  - package-ecosystem: "gomod"
 8    directory: "/internal/tools/"
 9    schedule:
10      interval: "daily"

例如,这将在有新版本时创建拉动请求。

Dependabot Pull Requests

gosec linter

gosec是一个Go linter,作为golangci-lint的一部分捆绑在一起,但如果你喜欢,它也可以独立工作。这个linter包括多个规则来检测,以及其他一些东西。

  • Harcoded credentials。
  • 使用字符串构建SQL查询,这可能导致SQL注入,以及
  • 检测标准库中一些crypto 包的使用情况。

当使用golangci-lint 时,请确保你启用了这个 linter,要做到这一点,请更新你的.golangci.yml 并确保它是启用的 linters 列表的一部分,例如。

linters:
  enable:
  - gosec

Snyk

Snyk是一项付费服务,用于检测在我们的项目中发现的漏洞,它不仅可以检测用于构建我们工件的软件包中的问题,还可以检测Dockerfiles等其他依赖项。我在Github上链接了一些我的开源项目,到目前为止,它们看起来是这样的。

Snyk Main Page

如果我们看一下 nit,你可以注意到它也在做一些代码分析,就像我之前提到的,它也在检查Dockerfiles。

Snyk nit Page

Snyk还包括一个列表漏洞数据库,例如Go,它看起来(到目前为止)像这样。

Snyk nit Page

最后,根据我们的配置,我们可能还想在检测到新问题时自动创建Pull Request,例如,Snyk在Dockerfile中为升级Alpine创建了这个请求。

CodeQL

CodeQL是一项服务,使用他们的语义代码分析引擎发现整个代码库的漏洞。与Dependabot类似,在Github上启用它很简单,我们只需要添加一个新的工作流程。

 1name: "CodeQL"
 2
 3on:
 4  push:
 5    branches: [main]
 6  pull_request:
 7    branches: [main]
 8  schedule:
 9    - cron: '19 4 * * 1'
10
11jobs:
12  analyze:
13    name: Analyze
14    runs-on: ubuntu-latest
15    permissions:
16      actions: read
17      contents: read
18      security-events: write
19    strategy:
20      fail-fast: false
21      matrix:
22        language: [ 'go' ]
23    steps:
24    - name: Checkout repository
25      uses: actions/checkout@v2
26    - name: Initialize CodeQL
27      uses: github/codeql-action/init@v1
28      with:
29        languages: ${{ matrix.language }}
30    - name: Autobuild
31      uses: github/codeql-action/autobuild@v1
32    - name: Perform CodeQL Analysis
33      uses: github/codeql-action/analyze@v1

公平地说,这实际上是在项目上启用它之后自动生成的,以做到这一点。

  1. 进入你的项目设置
  2. 点击 "安全与分析",然后
  3. 单击 "设置 代码扫描"。

从那里你可以添加CodeQL分析工作流,让你把配置文件直接推送到你的仓库。

versions 工具

versions我写了一个工具来确定多个项目使用的软件包版本,当时我还不知道Dependabot,所以做一些类似于自动打开Pull Requests来升级版本的事情是计划中的,但最后我决定更专注于建立一些其他工具可以导入的报告。

到目前为止,versions ,用来创建每个项目使用的软件包的列表,它们的版本以及它们使用的Go版本,然而它只适用于使用Go模块的项目。我很喜欢versions ,因为它也列出了Go的版本,这很重要,因为Go的发布政策,只支持最近的两个主要版本,有这样一个工具可以让我们知道什么时候该升级到一个新的主要版本。

总结

Security 在构建服务时,持续集成通常是一个事后的想法**,但**它不应该是这样的,我们已经有了可以让我们自动检测问题的工具和服务,然而这些在大多数情况下需要有持续集成,所以这是将其添加到你的开发管道的另一个伟大的理由。

这当然不是一个广泛的列表,我将在未来的文章中继续涵盖更多与Go相关的Security ,敬请关注。