没网?没问题。用Air Gap使用Artifactory

26 篇文章 0 订阅
11 篇文章 0 订阅

没网?没问题。用Air Gap使用Artifactory

几乎所有的开发组织都需要访问 JCenter,NuGet Gallery,npmjs.org,Docker Hub 等远程公共资源,以下载构建所需的依赖关系。使用 Artifactory 的一大好处是它作为代理仓库来下载远程资源和缓存工件。 这样,任何开发人员或 CI 服务器只要在第一次请求了工件,就可以在内部网络上的 Artifactory 中的远程资源库中进行缓存和直接使用。这是通过 Artifactory 使用远程资源的常用方法。

这里写图片描述

然而,金融机构和军事设施等组织却有严格的安全要求,例如配置,暴露在互联网上的行为是被禁止的。

用 Air gap 来拯救

为了适应这些案例,我们推荐一个至少有两个 Artifactory 实例的配置; 一个在 DMZ 上,另一个在内部网络上,通常称为 Air Gap。

我们通常会看到以下两种情况之一:

1、无网络连接
2、单向连接

无网络连接

在这种情况下,两个 Artifactory 实例之间没有网络连接。 为了从互联网获得依赖关系,外部实例必须下载它们,将它们导出到外部设备(如硬盘驱动器或 USB 闪存驱动器),然后内部实例必须导入它们供开发人员和 CI 服务器使用。

这里写图片描述

获取依赖关系

有两种方法可以从远程仓库获取依赖关系:

1、依赖声明

剥离你的代码,只留下依赖声明。 在具有运行所需工具的 DMZ 上的虚拟机上安装精简代码(例如,如果您正在开发 npm 软件包,则需要安装在 DMZ 机器上的 npm 客户端)。 相应的客户端通过递归地下载它们的 Artifactory 来请求所需的依赖关系,以及它们所需要的任何第 n 级依赖关系。

2、专用脚本
实现一个遍历所有你需要的包的脚本或机制,并向 Artifactory 发送“头部请求”,以便从远程资源下载这些包。 例如,要从 JCenter中 获取 jQuery 的版本2.1.0到2.1.5,可以使用下面的代码片段:

for i in ‘seq 0 5’; do curl -uadmin:password -l http://
localhost:8081/artifactory/jcenter/org/webjars/jquery/
2.1.$i/jquery-2.1.$i.pom

导出和导入

有两种方法可以导出新的依赖关系(即自上次运行导出以来下载的依赖项),然后将其导入到内部文件夹。

1、使用 AQL 查询的 Groovy 脚本

编写一个使用 AQL 查询的 Groovy 脚本,根据下载日期查找正确的工件。 这样,我们可以确保只导出自上次导出以来下载的那些工件。 例如,要导出2016年8月16日之后创建的所有工件,您可以使用类似以下代码段的东西:

// replace this with your AQL query
def query = 'items.find({"type":"file","created" : {"$gt" : "2016-08-16T19:20:30.45+01:00"},"repo" : "generic-local-archived"})' 

// replace this with your Artifactory server
def artifactoryURL = 'http://localhost:8081/artifactory/' 
def restClient = new RESTClient(artifactoryURL)
.
.
.
   try {
       response = restClient.post(path: 'api/search/aql',
               body: query,
               requestContentType: 'text/plain'
       )
   } catch (Exception e) {
       println(e.message)
   }

要下载导出到文件系统或便携式驱动器中的所有工件(到“今天的日期”文件夹中):

public download(RESTClient restClient, List itemsToExport, def dryRun) {
   def date = demoFormat()
   def folder = "$date"
   def dir = "/path/to/export"
   def file = new File("$dir/$folder");
   file.mkdirs();
   dryMessage = (dryRun) ? "*** This is a dry run ***" : "";
   itemsToExport.each {
       println("Trying to download artifact: '$it'")
       try {
           if (!dryRun) {
               def response = restClient.get(path:String.valueOf(it))
               if (response.status == 200) {
                   String s = it.toString().substring(it.toString().indexOf("/") + 1)
                   file = new File("$dir/$folder/"+s)
                   file << response.getData()
                   println("Artifact '$it' has been successfully downloaded. $dryMessage")
               }
               else
                   println("response status: '$response.status'")
           }
       } catch (HttpResponseException e) {
           println("Cannot download artifact '$it': $e.message" +
                   ", $e.statusCode")
       }
   }
}

现在,我们已经准备好把这个文件夹导入到我们内部的 Artifactory 实例的选定的仓库中

2、使用 JFrog CLI

由于导出基本上是将文件从一个位置复制到另一个位置,因此 JFrog CLI 是完成该操作的完美工具。 我们要做的是从外部 Artifactory 实例的“clean repository”中下载所有新的包,然后将它们上传到内部实例。 下载新文件最直接的方法是使用以下命令:

jfrog rt dl generic-local-archived NewFolder/

“但是等一下”你会问 “是不是下载了所有的文件?”看起来像这样,但是由于 JFrog CLI 是基于 checksum 的,它只会下载自上次下载以来添加的新的二进制文件。 在底层,JFrog CLI 实际上运行一个 AQL 查询来查找你需要的文件,所以你的回应如下所示:

[Info:] Pinging Artifactory...
[Info:] Done pinging Artifactory.
[Info:] Searching Artifactory using AQL query: items.find({"repo": "generic-local-archived","$or": [{"$and": [{"path": {"$match":"*"},"name":{"$match":"*"}}]}]}).include("name","repo","path","actual_md5","actual_sha1","size")
[Info:] Artifactory response: 200 OK
[Info:] Found 2 artifacts.
[Info:] [Thread 0] Downloading generic-local-archived/jerseywar.tgz
[Info:] [Thread 1] Downloading generic-local-archived/plugin.groovy
[Info:] [Thread 1] Artifactory response: 200 OK
[Info:] [Thread 0] Artifactory response: 200 OK
[Info:] Downloaded 2 artifacts from Artifactory.

现在,您可以将“NewFolder”添加到您的内部实例,并使用 JFrog CLI 再次上传其内容:

jfrog rt u NewFolder/ generic-local-archive

而且由于 JFrog CLI 使用 checksum 和部署(类似于下载的情况),内部实例中目标上已经存在的二进制文件将不会被部署。 下面的输出显示只有一个新文件是 Checksum deploy,apex-0.3.4.tar。

[Info:] Pinging Artifactory...
[Info:] Done pinging Artifactory.
[Info:] [Thread 2] Uploading artifact: http://localhost:8081/artifactory/generic-local-archived/plugin.groovy
[Info:] [Thread 1] Uploading artifact: http://localhost:8081/artifactory/generic-local-archived/jerseywar.tgz
[Info:] [Thread 0] Uploading artifact: http://localhost:8081/artifactory/generic-local-archived/apex-0.3.4.tar
[Info:] [Thread 1] Artifactory response: 201 Created
[Info:] [Thread 2] Artifactory response: 201 Created
[Info:] [Thread 0] Artifactory response: 201 Created (Checksum deploy)
[Info:] Uploaded 3 artifacts to Artifactory.

在文件规范中制定复杂查询的简单方法

但是方式并不总是这么简单。 如果我们不想将所有新文件从外部实例移动到内部实例,而是只有那些具有某种“批准标记”的文件。 这就是 AQLs 制定复杂查询的能力,打开了一个操作的世界。 通过使用 AQL,创建查询非常简单,例如,只需将2016年10月15日之后创建的文件,并使用属性 workflow.status = PASSED 注释,从我们的通用本地归档存储库迁移到 NewFolder 库。 由于 JFrog CLI 可以接受参数作为文件规格,我们在名为 newandpassed.JSON 的文件中创建以下 AQL 查询:

{
  "files": [
    {
      "aql": {
        "items.find": {
          "repo": "generic-local-archived",
          "created" : {"$gt" : "2016-10-15"},
          "@workflow.status" : "PASSED"
        }
      },
      "target": "NewFolder/"
    }
  ]
}

现在在 JFrog CLI 执行:

jfrog rt dl --spec NewAndPassed.json

现在我们只需要像以前一样将 NewFolder 的内容上传到内部实例。

单线链接

一些高度安全的机构要求将互联网与其内部网络分开,但政策略宽松,并且允许单向连接。 在这种情况下,内部 Artifactory 实例可以通过代理或通过安全的单向 HTTP 网络连接连接到外部实例。 这种设置打开了内部实例获取依赖关系的其他方法:

使用智能远程仓库
使用拉取复制

使用智能远程仓库

Artifactory 中的远程仓库是代理远程资源(如 Internet 上的公共存储库,如 JCenter)的存储库。 一个智能远程仓库就是远程资源实际上是另一个 Artifactory 实例中的一个仓库。

以下是您可以使用的设置:

这里写图片描述

DMZ上的外部实例包括:

托管已列入白名单的本地存储库已下载,扫描和批准的工件
代理远程资源的远程仓库,需要从中下载依赖关系
一个虚拟资源库,可以聚合所有其他资源

内部实例包括:

托管本地工件的本地存储库,例如版本和其他批准的本地包
远程存储库 - 实际上是一个智能远程存储库,代理外部实例中的虚拟存储库
一个虚拟资源库,可以聚合所有其他资源

这是如何工作的:

构建工具从内部 Artifactory 实例的虚拟库中请求依赖关系
如果在内部(在任何本地存储库或远程存储库高速缓存中)找不到依赖关系,那么智能远程存储库将从其外部资源(实际上是外部实例上的虚拟存储库)请求它
外部实例的虚拟存储库尝试从其聚集的本地存储库之一或从其远程存储库高速缓存中提供请求的依赖关系。 如果找不到依赖关系,则远程存储库将从远程资源下载该资源,然后将资源从该远程资源提供回请求的内部实例。

有一个小的设置,你需要记住。 内部实例上的虚拟存储库必须具有“Artifactory 请求可以检索远程工件”复选框集。

这里写图片描述

使用拉取复制

在这种方法中,您可以使用上述任何一种方式将依赖关系下载到外部 Artifactory 实例(在 DMZ 中)。 现在,您只需在内部实例中创建一个远程存储库,并根据 cron 作业从外部实例中的“clean”存储库调用 pull 复制,以将所有列入白名单的依赖关系提供给内部实例。

关于 JFrog Xray 的说明

如果您在内部 Artifactory 实例中使用 JFrog Xray,则会遇到类似的问题。 为了扫描索引的工件,它必须从与其连接的各种源中收集关于问题和漏洞的数据。 主要来源于 JFrog 维护的全球数据库服务器,您需要定期与其进行同步以下载新数据。 当你有一个互联网连接时,数据库会自动同步,但是如果没有互联网连接,你必须通过一个类似于上面描述的手动过程来使用离线模式进行依赖。 基本上,您可以在 DMZ 中的外部实例上使用 JFrog CLI 下载 Xray 数据库更新(Xray 将为您生成所需的命令),将下载的文件复制到内部 Xray 服务器,然后执行本地更新。

为了维护与互联网断开连接的安全环境,组织必须付出代价,但这并不意味着他们不能使用市场上的领先工具。 通过一些工具和脚本,以及一些手动交互,他们可以使用 Air Gap 来访问 JFrog Artifactory(和 JFrog Xray),以获得近乎在线的体验,同时在其开发环境中保持严格的安全策略。

原网址:https://www.jfrog.com/blog/using-artifactory-with-an-air-gap/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值