倉庫被封禁
在 2018 年 2 月 20 日,我們的開源專案放在 GitHub 上的倉庫由於收到了 DMCA Takedown 投訴被封禁,倉庫處於不可訪問狀態。此時在 GitHub 上訪問該倉庫時,會顯示一個公開訊息,表明該倉庫被封禁的原因。
按照 GitHub DMCA 的規則,GitHub 在確認投訴有效後,會給該倉庫的管理員傳送一封郵件,提示該倉庫需要在 24 小時內清理被投訴的內容,並回覆 GitHub 才行——否則,該倉庫會被封禁,禁止任何訪問和資料匯出。
我們在收到該 Takedown 投訴後,會有 24 小時的時間來響應,但由於過年期間,倉庫擁有者沒有及時看到郵件,未能及時發現這麼嚴重的通知。因此,在過了 24 小時後, Github 按照 DMCA 的規則,進行了倉庫的封禁。
倉庫被封禁後,我們發現無法訪問。根據封禁訊息的提示,發現原來之前倉庫內的某個檔案出了問題,侵犯了原作者的版權。原作者向 Github 發送了 DMCA 投訴。而由於我們的未及時處理,導致了倉庫的最終被封。當我們發現被封時,已經是深夜了。
緊急商討方案
在被封禁後,由於已經超過了 24 小時時限,在這個階段下, GitHub 的檔案中給出的解決方案僅有請求 GitHub 來刪除該倉庫並根據自己手裡的倉庫資料重建的方案。但對我們來說,這種方案是不可接受的,因為這種方案會導致丟失所有的 issue、PR、Wiki,以及你本地的倉庫和遠端的倉庫之間的版本差異。
我們在群內先找了更新最全的 fork,找到了一個群友提供的,和上游只差 2 個提交的版本,並將其儲存下來,作為最後的自救手段。
此外,在查詢 DMCA 的過程中,我瞭解到 DMCA 除了有 DMCA Takedown 以外,還有一個 DMCA Counter Notice,用於反向解除 DMCA 封禁。
DMCA Counter Notice
DMCA Counter Notice 用於向服務商發起申訴,說明 DMCA Takedown 投訴為惡意投訴且並無版權問題。
延展閱讀
https://www.plagiarismtoday.com/2010/06/03/7-common-questions-about-dmca-counter-notices/
https://help.github.com/articles/guide-to-submitting-a-dmca-counter-notice/
當時考慮到我們已經錯過了視窗期,沒辦法刪除 GitHub 上倉庫中的特定檔案,所以想透過 DMCA Counter Notice 來解除封禁。
為此,我透過 Github 發給我們的郵件,找到了那份侵權檔案,併在他的網站中找到了版權擁有者的郵件,傳送郵件說明情況,看看能否透過付費獲得授權。但其是挪威人,存在時差,所以我們只能邊等待,邊想辦法。
山重水復疑無路,柳暗花明又一村
在準備 DMCA Counter Notice 時,我們又向 Github 發送了郵件,說明瞭中國春節的特殊情況,導致我們沒有來得及處理檔案,請求給我們一個機會讓我們處理這些檔案。但是遲遲沒有回應,無奈之下,多位成員又以成員身份向 GitHub 傳送郵件,請求給予幫助。
令人驚奇的是,經過大約 9 個小時的等待,倉庫擁有者的請求郵件似乎開小差了,而各位成員的請求郵件得到了響應。Github 回信給大家說,根據其規則,給出了額外的 24 小時視窗期,讓我們處理這些檔案(後來經過仔細查閱 GitHub 的 DMCA Takedown 規則,對這種錯過了第一次視窗期的情況,可以給予第二個,也是最後一個視窗期)。但是這個開啟額外的視窗期,需要倉庫的擁有者向 GitHub 傳送郵件請求。
然後,我們就以倉庫擁有者的身份再次向 GitHub 發送了請求,可能是由於時差的原因,又是幾個小時沒有回應。
與此同時,我們也收到了版權擁有者的回覆。很遺憾,原作者不願意授權,也不打算收費。好在 Github 給的額外視窗期,讓我們有了改正錯誤的機會。
還好,在焦急的等待之中,我們終於收到了 GitHub 的回覆,並同時恢復了倉庫的訪問——寶貴的 24 小時視窗期。
使用 BFG 處理檔案
得到了視窗期後,我們開始處理倉庫內的檔案。
首先,你得清除了現在還在倉庫裡面的檔案,然後再使用下麵的方面來清除提交歷史中的資料。
推薦閱讀
以下文章建議按順序閱讀
https://help.github.com/articles/removing-sensitive-data-from-a-repository/
https://rtyley.github.io/bfg-repo-cleaner/
刪除 Git 倉庫的歷史資料有多種方法,一種是使用 git filter-branch
來處理,但是速度極慢。另外一種就是使用 BFG 來處理,我們採用的是 BFG 來處理(BFG 是git filter-branch
首字母的逆轉)。
BFG 需要 Java 的執行環境,如果無法執行,請檢查你的本地 Java 環境是否安裝,或高於 Java 7 。
Java 6 需要使用 bfg v1.12.3版本
BFG 的處理過程比較簡單,首先,你需要下載 BFG。
wget http://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar
然後克隆你的倉庫到本地,比如 bestony/test
。
git clone --mirror git://github.com/bestony/test.git
克隆時用不用 --mirror
樣式都可以,但是後續命令上會有所差距,所以我還是推薦大家使用映象樣式,畢竟按照官方的檔案走,出現了問題也好搜尋。(映象樣式克隆的倉庫和遠端倉庫完全一樣,但是不能直接看到倉庫裡面的檔案,而且也不能允許 git
的各種命令)
克隆到本地後,執行 BFG 命令來處理檔案。
cd test.git
java -jar bfg.jar --delete-files "filename"
這裡需要註意的是,
filename
不支援目錄路徑,只能是檔案名,而不能是dir/filename
這樣的形式,所以新增引數時你要註意這個。對於有同樣名字的檔案卻想只刪除某個目錄的情況,可能就沒有辦法了。此外,預設情況下, BFG 不會處理最新的提交,它認為你的最新提交應該是乾凈的(不包含需要刪除的敏感資料),如果你要刪除的檔案是最新的提交(比如你最新的一個提交是刪除那些敏感資料),可以加入
--no-blob-protection
引數來強制清除,也可以再新增一個提交,使包含了要被刪除檔案的提交不是最新的提交。
java -jar bfg.jar --delete-files "filename" --no-blob-protection
BFG 處理完成後,會提示你使用 git
命令進行垃圾回收,你需要執行如下命令來操作:
cd test.git # 進入標的目錄
git reflog expire --expire=now --all && git gc --prune=now --aggressive # 垃圾回收
這裡需要註意的是,如果你刪除多個檔案,每次刪除後執行和多個檔案都刪除後效果一樣,所以建議你刪除多個檔案後再進行垃圾回收,會更省時一些。
處理完成後,將資料推送到遠端即可(需要關閉 GitHub 上倉庫設定裡面對強制推送的防護):
git push
執行完成後,就可以到遠端上去看了,你的檔案會被刪除,相關的提交不會被刪除,但是提交裡面不包含該檔案了。
在推送時,可能會提示你有些更改被拒絕了,這些更改如果是和 Pull Request 有關的,你可以不需要在意,這是 GitHub 自身的問題。Github 設定 Pull Request 是隻讀不可改的。所以我們無法修改這些資訊。
具體可以參考 https://github.com/rtyley/bfg-repo-cleaner/issues/36
至此,我們將檔案進行了刪除處理,並清除了相關的資料。
後續處理
在完成檔案及歷史資料的刪除後,我們將我們的刪除結果回覆了 Github ,等待 Github 的確認。GitHub 會在 24 小時收到該回覆後,會通知投訴方進行確認。如果投訴方無異議,此事就此結束,不會再有下一步動作。如果有異議,則會重新進行此流程。
此外,由於 GitHub 存在垃圾快取回收的時間差,所以你推送到 GitHub 上的資料雖然並無需要被刪除的檔案,但是依舊在一定時間內可以看到。這種快取只能請 GitHub 自行操作刪除。此外,與要刪除的檔案相關的 Pull Request 也需要 GitHub 來刪除——因為使用者是沒有許可權刪除 Pull Request 的。這些請求也可以一併發給 GitHub 來操作(但似乎 GitHub 並不熱衷執行這些請求,只要被投訴的檔案訪問不到即可,也就是說,如果沒有被投訴歷史資料,其實或許並不用大動干戈清理歷史……)。
這種清除操作還有一個副作用就是,所有之前 fork 的倉庫,由於主倉庫被封禁而導致各個 fork 倉庫的 remote 意外地變為另外一個倉庫(該倉庫是最早的一個 fork 倉庫)。而主倉庫恢復之後,我們並沒有找到好的辦法將 remote 恢復回原來的主倉庫。因此,需要所有成員重新 fork 主倉庫並從緩慢的 GitHub 克隆到本地。
餘思
這個驚魂事件當中,我們首先要反思的是,我們對版權問題的認識不足,這是一切問題的根源。因此,這之後,我們對既有資料進行了排查。
其次,GitHub 在這種事件的處置上,我們認為也並不夠好。這麼嚴重的處置(整個庫封禁),僅僅透過一份普通的郵件通知,而且僅僅給出 24 小時的時間視窗。而 GitHub 其實掌握了倉庫擁有者的更可靠、更及時的聯絡方式,比如說手機簡訊,也完全可以在 GitHub 的網頁介面上以顯目的方式提醒。另外,雖然 DMCA 規則中提到了可以容情第二個時間視窗,但是似乎這個附加視窗期是後來才改變的政策,在前面的流程說明中並未提及,很容易忽視。
其三,由於封禁會導致對該倉庫的所有訪問均不可進行,這不僅包括了提交資料,也包括了並沒有存在於 Git 倉庫中的 issue、PR 和 Wiki 等資料,而 GitHub 不會讓你在封禁的情況下有機會匯出這些資料。所以,有機會的話,各種資料還是有個備份的好。
最後,感謝在這個事件中,所有不離不棄支援我們的成員,感謝小白進行的倉庫清理工作。
相關閱讀