在线免费托管docker的平台选择

  1. dockerhub,目前在用,由于其商业化策略导致的不可控变化,打算放弃
  2. github,Container Registry:因为访问不稳定和token的问题,暂时不考虑
  3. gitlab,Container Registry
  4. ECR, amazon出品,这里不考虑,因为账号体系的原因

所以暂时就一个可选项:gitlab

放一个相关的比较参考图:
file

github 容器注册服务器介绍

你可以在ghcr.io上存储和管理你的Docker和OCI镜像。

关于容器注册服务器支持类型

  • Docker Image Manifest V2, Schema2
  • Open Container Initiative 规格

容器服务器支持外部layer,比如windows 镜像。

登陆容器注册服务器

登陆ghcr.io建议使用GITHUB_TOKEN工作流来提高安全性。

  1. 创建一个PAT。设置好权限
  2. 建议将PAT设置为环境变量
    $ export CR_PAT=YOUR_TOKEN
  3. 通过CLI登陆容器注册服务器
    $ echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
    > Login Succeeded

发布容器镜像

$ docker push ghcr.io/OWNER/IMAGE_NAME:latest
or
$ docker push ghcr.io/OWNER/IMAGE-NAME:2.5

当第一次发布容器时,默认是私有的,需要改变可见性,需要自己去设置:Configuring a package's access control and visibility

获取镜像

通过digest获取精准镜像

  1. 获取digest,通过docker inspect或者docker pull命令,然后拷贝得到的SHA值
    $ docker inspect ghcr.io/OWNER/IMAGE_NAME
  2. 删除本地镜像
    $ docker rmi  ghcr.io/OWNER/IMAGE_NAME:latest
  3. 通过@YOUR_SHA_VALUE 获取精准的镜像
    $ docker pull ghcr.io/OWNER/IMAGE_NAME@sha256:82jf9a84u29hiasldj289498uhois8498hjs29hkuhs

通过名字

docker pull ghcr.io/OWNER/IMAGE_NAME

通过名字和版本

$ docker pull ghcr.io/OWNER/IMAGE_NAME:1.14.1

获取当前最新版

$ docker pull ghcr.io/OWNER/IMAGE_NAME:latest

编译镜像

$ docker build -t hello_docker .

tagging镜像

  1. 找到image id
    $ docker images
    > REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE
    > ghcr.io/my-org/hello_docker         latest              38f737a91f39        47 hours ago        91.7MB
    > ghcr.io/my-username/hello_docker    latest              38f737a91f39        47 hours ago        91.7MB
    > hello-world                                           latest              fce289e99eb9        16 months ago       1.84kB
  2. 通过ID和镜像名字和托管的主机来tag对应的镜像
    $ docker tag 38f737a91f39 ghcr.io/OWNER/NEW_IMAGE_NAME:latest

通过GitHub Actions发布和安装软件包

关于Github packages和Github Actions

github packages是github的免费服务。

github actions可以用于实现自有仓库的CI和DI,配合github packages可以为其过程提供所需文件安装包。

登陆认证到Container registry

在通过github actions workflow认证容器注册服务器时,GITHUB_TOKEN是比较推荐的安全实践。

当你的workflow通过PAT登陆ghcr.io时,强烈建议使用GITHUB_TOKEN来完成整个过程。

登陆认证到github的package注册服务器

当你访问package注册服务器时,建议使用为仓库生成的GITHUB_TOKEN,而不是PAC。

我们应该为contents字段设置只读权限,为packages字段设置可写权限。

repository-owned packages的读写权限和package访问权限

当你使能Github Actions时,GITHUB_TOKEN就是Githubb app的安装访问token。你将通过GITHUB_TOKEN来允许对你的仓库进行Github app安装。

Container注册服务器的读写权限和package访问权限

ghrc.io允许用户创建和主导免费的容器。

用户访问Container注册服务器时应该用GITHUB_TOKEN而不是PAT。

通过workflow修改容器的默认权限和访问设置

当你增,删,改和安装容器时,管理员有一些默认的权限来保证对工作流的掌控。

比如,当你用GITHUB_TOKEN创建容器时:

  • 容器继承仓库的可见性和权限模型
  • 容器创建时,仓库的管理员也就变成了容器的管理员

通过Action发布一个软件包

你可以通过Github Actions在CI的过程中自动的发布软件包。也可以当你的代码达标时,通过CD生成新的部署包。例如你可以可以通过workflow创建一个CI任务,当测试通过时,自动生成软件包,然后发布到Github Packages。

当你更新代码时,就会自动触发workflow。

当workflow结束时,新生成的软件包就会出现在git仓库中。

通过Github Action安装软件包

当你通过GITHUB_TOKEN安装Github Packages上面的软件包时,你只需要简单的配置不需要额外的认证。当流量传输时,是免费的。

升级服务到ghcr.io

ghrc的docker注册服务器支持GITHUB_TOKEN实现安全的认证。当你使用PAT访问ghcr.io时,强烈建议使用GITHUB_TOKEN工作流。

当你使用GITHUB_TOKEN来增加安全性时,它让你不必为了能随时使用workflow而创建一个long-lived PAT。

附一个通过GITHUB_TOKEN来发布docker镜像的配置:

name: Demo Push

on:   
  push:
    # Publish `master` as Docker `latest` image.
    branches:
      - master
      - seed

    # Publish `v1.2.3` tags as releases.
    tags:
      - v*

  # Run tests for any PRs.
  pull_request:

env:
  IMAGE_NAME: ghtoken_product_demo

jobs:
  # Push image to GitHub Packages.
  # See also https://docs.docker.com/docker-hub/builds/
  push:
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read

    steps:
      - uses: actions/checkout@v2

      - name: Build image
        run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}"

      - name: Log in to registry
        # This is where you will update the PAT to GITHUB_TOKEN
        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

      - name: Push image
        run: |
          IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME

          # Change all uppercase to lowercase
          IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
          # Strip git ref prefix from version
          VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
          # Strip "v" prefix from tag name
          [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
          # Use Docker `latest` tag convention
          [ "$VERSION" == "master" ] && VERSION=latest
          echo IMAGE_ID=$IMAGE_ID
          echo VERSION=$VERSION
          docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
          docker push $IMAGE_ID:$VERSION

sigmastar更换sensor驱动

以最细的sdk架构为例,目前官方的代码顶层为boot,kernel,project,sdk共四个目录,默认sdk是不参与project的。

sensor的驱动在sdk下面,里面提供了很多驱动,需要更换时,先在sdk中单独编译,然后手动拷贝到project相关的目录下。

最后,需要在project单独编译命令make xxx的xxx配置文件中,更好默认的sensor驱动,从aaa.ko改为bbb.ko,然后重新编译project。

GitHub Actions安全强化

概述

本文主要解释对于GitHub Actions的部分特性,如何加强安全。

使用密码

敏感的数字不应该在工作流中明文存储,而应该使用密码。密码可以配置在组织,仓库,或者环境变量中,从而允许你在Github中存储敏感信息。

密码使用Libsodium sealed boxes技术,所以在接触Github前就已经被加密。当通过UI或者REST API提交时,密码就已经被加密了。这种在客户端加密的方式极大的减小了再登陆github时的泄露风险。一旦密码被上传后,Github可以解密密码,从而在工作流中使用。

  • 不要使用结构化数据当做密码
    • 因为结构化的数据会导致对日志中的密码掩写失败,尽量不要用JSON,xml,yaml来组织密码,而是对每一个敏感的数据创建单独的密码。
  • 所有使用的敏感数据都要注册为密码
    • 注册为密码后,当在日志中出现事,github将会对数据进行掩写。
    • 不光对敏感数据要注册为密码,对数据的变换值比如Base64或者URL-encoded都要进行注册。
  • 审查密码是如何被处理的
    • 审查密码是如何被使用的,你可以通过监视仓库的工作流源码,以确保他们符合预期的方式,而且要检查所有相关的actions。比如,确保密码没有被发往未知的服务器或者被打印在日志里。
    • 监视工作流的日志,检查密码被正确的使用而不是暴露。一般调命令和工具如何输出错误到STDOUT和STDERR中并不是那么明晰,密码可能无意中就被打印到日志中了。所以在测试输入输出时人工的检视工作流日志是一个很好的实践。
  • 最低限度的使用密码
    • 务必确保相关的权限应该设置为最小权限,时刻谨记任何拥有写权限的用户有权限能读取你仓库的所有密码的配置参数。
    • Actions可以用从github.token中获取的GITHUB_TOKEN来加强安全。给GITHUB_TOKEN默认设置当前仓库的只读权限是一个很好的安全实践,这个权限可以在使用中按需来增加。
  • 审查和轮转密码
    • 定期地检视密码以确保其仍然在被使用,及时删除不被使用的密码。
    • 定期轮转密码以减少密码的有效窗口期。
  • 使用审查员机制
    • 可以使用审查员来保护环境变量中的密码。一个工作流不能直接访问密码,直到被审查员授权。

使用CODEOWNERS 来监控变化

你可以使用CODEOWNERS 特性来监控工作流来如何产生变化。比如你的工作流文件存放在.github/workflows,你可以将这个文件夹添加到代码归属列表,任何对这些文件的变化都需要指定的检视员的审批。

了解脚本的注入风险

当创建了一个工作流或者custom actions或者composite actions时,你需要时刻想着你的代码可能需要处理攻击者的非法输入。比如,攻击者可能会添加恶意的命令和脚本在一个内容中,这些字符可能会被解释为代码,从而在你的目标中运行。

攻击者能添加恶意的内容到github context中,这些内容应该被当做非法输入。这些内容经常以body, default_branch, email, head_ref, label, message, name, page_name,ref, and title等关键字结尾。比如github.event.issue.title或者 github.event.pull_request.body。

你需要确保这些值不会直接执行在工作流,actions,API或者会被当做代码解释的任何地方。

另外还有一些不是很明显的潜在恶意输入,像分支名称,邮箱地址等,被灵活的用于内容中。比如zzz";echo${IFS}"hello";#将是一个可能的攻击向量。

脚本工具的例子

- name: Check PR title
        run: |
          title="${{ github.event.pull_request.title }}"
          if [[ $title =~ ^octocat ]]; then
          echo "PR title starts with 'octocat'"
          exit 0
          else
          echo "PR title did not start with 'octocat'"
          exit 1
          fi

此示例容易受到脚本注入的影响,因为 run 命令在运行器上的临时 shell 脚本中执行。 在运行 shell 脚本之前,${{ }} 中的表达式会被评估,然后用结果值替换,这可能使其容易受到 shell 命令注入的攻击。

要将命令注入此工作流,攻击者可以创建一个标题为 a"; ls $GITHUB_WORKSPACE" 的拉取请求:
file
在这个例子中单引号"打断了title="${{ github.event.pull_request.title }}",允许ls命令被执行。你可以在日志中看到ls的输出:
file

减轻脚本注入的最佳实践

以下是几种不同的减轻脚本注入风险的方式:

用action替代内部脚本

这个推荐的方法会创建一个action,输入的内容被当做action的输入参数。这个方法不会被攻击,因为内容不会产生shell脚本行为。

uses: fakeaction/checktitle@v3
with:
    title: ${{ github.event.pull_request.title }}

使用中间环境变量

对于内联脚本,处理不可信输入的首选方法是将表达式的值设置为中间环境变量。

以下示例使用 Bash 将 github.event.pull_request.title 值作为环境变量处理:

- name: Check PR title
        env:
          TITLE: ${{ github.event.pull_request.title }}
        run: |
          if [[ "$TITLE" =~ ^octocat ]]; then
          echo "PR title starts with 'octocat'"
          exit 0
          else
          echo "PR title did not start with 'octocat'"
          exit 1
          fi

这个例子,尝试的脚本注入不会成功:
file
使用这种方法,${{ github.event.issue.title }} 表达式的值存储在内存中并用作变量,并且不与脚本生成过程交互。 此外,考虑使用双引号 shell 变量来避免分词,但这是编写 shell 脚本的许多一般建议之一,并不特定于 GitHub Actions。

使用CodeQL 来分析你的代码

CodeQL Queries
是github 为js仓库提供的一项服务。想使用此服务,你的仓库中要至少有一个js文件。

限制tokens的权限

使用OpenID Connect来获取云端资源

如果您的 GitHub Actions 工作流程需要从支持 OpenID Connect (OIDC) 的云提供商访问资源,您可以将您的工作流程配置为直接向云提供商进行身份验证。 这将让您停止将这些凭据存储为长期机密,并能提供其他安全优势。 有关更多信息,请参阅“关于使用 OpenID Connect 进行安全加固”

使用第三方actions

工作流中的各个作业可以与其他作业交互(和妥协)。 例如,一个作业查询后面的作业使用的环境变量,将文件写入后面的作业处理的共享目录,或者更直接地通过与 Docker 套接字交互并检查其他正在运行的容器并在其中执行命令。

这意味着工作流中单个操作的破坏可能非常重要,因为该破坏的操作将有权访问存储库上配置的所有机密,并且可能能够使用 GITHUB_TOKEN 进行写仓库行为。 因此,从 GitHub 上的第三方仓库执行的action存在重大风险。 有关攻击者可能采取的一些步骤的信息,请参阅“受感染运行程序的潜在影响”。

您可以通过遵循以下良好做法来帮助减轻这种风险:

  • 通过完整的提交SHA来匹配actions
  • 审查action的源码
  • 只有在你信任创建者的情况下才使用tag

重用第三方工作流

要求跟第三方action一样。

密码泄露后,可能遭受的潜影响

一下将介绍攻击者可能通过以下的步骤在Github action中运行恶意命令

获取密码

工作流受puul_request触发,拥有只读权限,无权访问密码。issue_comment, issues 和 push等不同的事件拥有不同的权限,攻击者可能会窃取仓库的密码,从而使用GITHUB_TOKEN的写权限。

  • 如果密码或者token是被写入环境变量,可以使用printenv来显示。
  • 如果密码是明文存在于表达式中,形成的shell脚本将可被访问。
  • 在定制action中,风险取决于怎么使用参数传入的密码:
    uses: fakeaction/publish@v3
    with:
    key: ${{ secrets.PUBLISH_KEY }}

    尽管 GitHub Actions 从内存中清除密码,保证其不在工作流(或包含的操作)中未引用,但坚定的攻击者可以获取 GITHUB_TOKEN 和任何引用的密码。

从运行对象中窃取数据

窃取GITHUB_TOKEN

修改代码仓库数据

仓库交叉访问

当操作不当时,授权一个仓库的GITHUB_TOKEN能访问另一个时将影响github的权限模型。同理,给工作流添加权限时,也必须非常小心。

我们有一个计划去支持仓库交叉访问,但是目前还未实现。当前实现的方法就是将token或者ssh 用作工作流的密码。因为不同的token类型有不同的资源访问权限,用错token类型将产生预期意外的权限。

以下列出了几种在工作流中获取仓库数据的方法,按推荐度降序排列:

  1. GITHUB_TOKEN
    • 这个token在仓库的默认工作流中,有着write-access的权限。job开始时创建,job结束时消亡。
  2. 仓库部署key
  3. github app tokens
  4. Personal access tokens(PAT)
  5. 用户账户下的SSH Keys

自托管环境的加强

github-hosted:隔离的虚拟环境
self-hosted: 自己的vps或者物理系统环境

你应该考虑在子托管环境下:

  • 哪些敏感数据是存在运行目标中的?
  • 目标主机是否有网络权限能访问敏感服务?

一些客户可能会尝试通过实施在每次作业执行后自动销毁自托管运行器的系统来部分减轻这些风险。 但是,这种方法可能没有预期的那么有效,因为无法保证自托管运行器只运行一个作业。 一些作业将使用机密作为命令行参数,在同一运行器上运行的另一个作业可以看到这些参数,例如 ps x -w。 这可能导致秘密泄露。

为自托管环境设计你自己的管理策略

中心化管理

  • 如果每一个小组都管理他们自己的运行环境,那么推荐配置最高的权限。比如,每个小组都有自己的github organization,那么就给他们添加组织权限
  • 你自己是独立的组织

非中心化管理

向您的云提供商进行身份验证

如果您使用 GitHub Actions 部署到云提供商,或打算使用 HashiCorp Vault 进行秘密管理,那么建议您考虑使用 OpenID Connect 为您的工作流运行创建短期、范围广泛的访问令牌。 有关更多信息,请参阅“关于使用 OpenID Connect 进行安全强化”。

审核 GitHub Actions 事件

您可以使用审核日志来监控组织中的管理任务。 审核日志记录操作的类型、运行时间以及执行操作的用户帐户。

例如,您可以使用审计日志来跟踪 org.update_actions_secret 事件,该事件跟踪组织机密的更改:
file

关于github的GITHUB_TOKEN

这两天在研究github的docker托管服务,被GITHUB_TOKEN搞的有点迷糊,以为是一个新的token,经过研究:

  1. GITHUB_TOKEN只是PAT在action或者workflow中的特指符号语法,并不是一个新的token
  2. 其有对应成套的符号,比如${{ secrets.GITHUB_TOKEN }} 和${{ secrets.SECRET_NAME }}等,这套实践主要是考虑安全泄密和注入。

baota宝塔docker制作

这两天瞎折腾,因为数据库不一致的问题,一气之下把baota image删掉了,很多跟数据库相关的服务都歇了。

宝塔自用,在nas环境配合下数据库,搞个网络环境还是很方便的。

再重新拉取baota镜像时,发现怎么也访问不了,看日志,也没发现什么线索,所以才萌生了自己搞个docker的念头,主要是想定位下问题。

根据官方 www.bt.cn 最新的安装脚本制作了最新的 docker镜像:
https://gitlab.com/hiproz/baota-centos7-docker

特点:

  1. 和一般宝塔docker不同的是,采用延后安装的方式,支持将整个/www暴露出来,这样就可以将应用数据特别是数据库数据映射到用户空间,不至于不小心删除docker时,整个数据库数据丢失。
  2. 支持自动重新安装,如果系统发生未知问题,无法通过系统内更新,可以通过外部脚本的need_update 来更新。

docker的使用

docker run -tid --name baota --restart always -v /your-local-dir:/www -p your-local-port:8888 registry.gitlab.com/hiproz/baota-centos7-docker

安装进度日志

查看 run.log

默认登录路径和账号密码

查看映射路径下的default.txt, 注意要使用实际映射的端口,default.txt显示的是系统内部的端口。