沒網?沒問題。用Air Gap使用Artifactory

沒網?沒問題。用Air Gap使用Artifactory

幾乎所有的開發組織都需要訪問JCenter,NuGet Gallery,npmjs.org,Docker Hub等遠程公共資源,以下載構建所需的依賴關係。使用Artifactory的一大好處是它作爲代理倉庫來下載遠程資源和緩存工件。 這樣,任何開發人員或CI服務器只要在第一次請求了工件,就可以在內部網絡上的Artifactory中的遠程資源庫中進行緩存和直接使用。這是通過Artifactory使用遠程資源的常用方法。

沒網?沒問題。用Air Gap使用Artifactory
然而,金融機構和軍事設施等組織卻有嚴格的安全要求,例如配置,暴露在互聯網上的行爲是被禁止的。

用Air gap來拯救

爲了適應這些案例,我們推薦一個至少有兩個Artifactory實例的配置; 一個在DMZ上,另一個在內部網絡上,通常稱爲Air Gap。

我們通常會看到以下兩種情況之一:

1、無網絡連接
2、單向連接

無網絡連接

在這種情況下,兩個Artifactory實例之間沒有網絡連接。 爲了從互聯網獲得依賴關係,外部實例必須下載它們,將它們導出到外部設備(如硬盤驅動器或USB閃存驅動器),然後內部實例必須導入它們供開發人員和CI服務器使用。

沒網?沒問題。用Air Gap使用Artifactory

獲取依賴關係

有兩種方法可以從遠程倉庫獲取依賴關係:

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實例中的一個倉庫。

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

沒網?沒問題。用Air Gap使用Artifactory

DMZ上的外部實例包括:

託管已列入白名單的本地存儲庫已下載,掃描和批准的工件</br>
代理遠程資源的遠程倉庫,需要從中下載依賴關係</br>
一個虛擬資源庫,可以聚合所有其他資源

內部實例包括:

託管本地工件的本地存儲庫,例如版本和其他批准的本地包</br>
遠程存儲庫 - 實際上是一個智能遠程存儲庫,代理外部實例中的虛擬存儲庫</br>
一個虛擬資源庫,可以聚合所有其他資源

這是如何工作的:

構建工具從內部Artifactory實例的虛擬庫中請求依賴關係</br>
如果在內部(在任何本地存儲庫或遠程存儲庫高速緩存中)找不到依賴關係,那麼智能遠程存儲庫將從其外部資源(實際上是外部實例上的虛擬存儲庫)請求它</br>
外部實例的虛擬存儲庫嘗試從其聚集的本地存儲庫之一或從其遠程存儲庫高速緩存中提供請求的依賴關係。 如果找不到依賴關係,則遠程存儲庫將從遠程資源下載該資源,然後將資源從該遠程資源提供回請求的內部實例。

有一個小的設置,你需要記住。 內部實例上的虛擬存儲庫必須具有“Artifactory請求可以檢索遠程工件”複選框集。

沒網?沒問題。用Air Gap使用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/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章