顯示具有 backup 標籤的文章。 顯示所有文章
顯示具有 backup 標籤的文章。 顯示所有文章

2021年8月25日 星期三

[macOS] 使用 hashcat 驗證/回憶 iOS iPhone/iPad iTunes 備份檔 密碼

故事起源於幫長輩換手機,這時手機有用過 itunes 備份過一份並且加密,但...怎麼都想不起密碼。在網路上找尋解法時,大概可以看到幾款破解軟體(推論是免費試用,真正要破解時需加價)。此刻的不方便,反而要感謝起 Apple 資安服務,高規格保護資料!大家的破解原理都是一樣的:暴力解-猜密碼。

研究後,發現有個 hashcat 的 open source 統包了眾多加密系統的猜密碼任務,而網路上 2017年也以人講解使用過程,還滿仔細的:

Crack Encrypted iOS backups with Hashcat

筆記一下過程:
  1. 先找到 iOS 備份檔擺放的位置: https://support.apple.com/en-us/HT204215
    • macOS: ~/Library/Application Support/MobileSync/Backup/
  2. 備份都是目錄結構,找到目錄中的 Manifest.plist 檔案
  3. 依照裡頭的資訊,準備餵給 hashcat 的資料,可分成 iOS 10 以上跟 iOS 9 以前,組成 inputFromManifest.txt 資料
    • Less then iOS 10:
      • $itunes_backup$*<ver>*<WPKY>*<ITER>*<SALT>**
    • iOS 10 or later:
      • $itunes_backup$*<ver>*<WPKY>*<ITER>*<SALT>*<DPIC>*<DPSL>
如此,就可以靠 hashcat 來運算,其原理包括支援平行處理(GPU)去算出密碼,包括從字典檔、暴力猜等等的。此外,關於上述 2~3 步驟,其實也有人佛心提供工具:github.com/philsmd/itunes_backup2hashcat,透過 perl 小程式自動幫人從 Manifest.plist 組出資訊:

% perl itunes_backup2hashcat.pl yourBackupDir/Manifest.plist 
$itunes_backup$*10*#######*####*######*######*##################
% perl itunes_backup2hashcat.pl yourBackupDir/Manifest.plist > inputFromManifest.txt

後續就著重 hashcat 的指令筆記,若要更多指令資訊,逛個官方網站是最方便的:hashcat.net/wiki/doku.php?id=hashcat

以在 https://www.youtube.com/watch?v=MMySnPzsPYU 內提供的範例資訊:

% cat inputFromManifest.txt 
$itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76be166232b4a01bd6974abb27c39034993591c15ba03a14e3b*10000*0ca3ccfc453b32f9ca9aceb754b87f4e0ab9cb95*10000000*bdee6869caa7999e9576f390a248a29f38d10d6f

這時都是 iOS 10 的密碼,因此在使用 hashcat 會採用 -m 148000 參數。若是 iOS 9 以前,要用 -m 14700 參數這些都有定義在官方網站的 wiki 中。

第一招:暴力解,此例猜4個數字:

% hashcat -d 1 -m 14800 ./inputFromManifest.txt -a 3 '?d?d?d?d'
hashcat (v6.2.3) starting

OpenCL API (OpenCL 1.2 (Jun 17 2021 15:24:17)) - Platform #1 [Apple]
====================================================================
* Device #1: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz, 16320/16384 MB (4096 MB allocatable), 4MCU
* Device #2: Intel(R) Iris(TM) Plus Graphics 640, skipped

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates

Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
* Brute-Force
* Slow-Hash-SIMD-LOOP
* (null)

Watchdog: Temperature abort trigger set to 100c

Host memory required for this attack: 1 MB

[s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit => 

這時隨時都可以按 s 去看暴力解的進度:

Session..........: hashcat
Status...........: Running
Hash.Name........: iTunes backup >= 10.0
Hash.Target......: $itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76b...d10d6f
Time.Started.....: Wed Aug 25 20:37:03 2021 (6 mins, 50 secs)
Time.Estimated...: Wed Aug 25 23:30:00 2021 (2 hours, 46 mins)
Kernel.Feature...: Pure Kernel
Guess.Mask.......: ?d?d?d?d [4]
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:        1 H/s (13.34ms) @ Accel:128 Loops:256 Thr:1 Vec:4
Recovered........: 0/1 (0.00%) Digests
Progress.........: 0/10000 (0.00%)
Rejected.........: 0/0 (0.00%)
Restore.Point....: 0/1000 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:8056320-8056576
Candidate.Engine.: Device Generator
Candidates.#1....: 1234 -> 1124
Hardware.Mon.SMC.: Fan0: 100%
Hardware.Mon.#1..: Temp: 66c

[s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit => 

而幸運解出密碼時,會顯示以下資訊,主要是 Status 會顯示 Cracked 而密碼則是紀錄在冒號後面 (:1234)

$itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76be166232b4a01bd6974abb27c39034993591c15ba03a14e3b*10000*0ca3ccfc453b32f9ca9aceb754b87f4e0ab9cb95*10000000*bdee6869caa7999e9576f390a248a29f38d10d6f:1234
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Name........: iTunes backup >= 10.0
Hash.Target......: $itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76b...d10d6f
Time.Started.....: Wed Aug 25 20:37:03 2021 (8 mins, 26 secs)
Time.Estimated...: Wed Aug 25 20:45:29 2021 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Mask.......: ?d?d?d?d [4]
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:        1 H/s (11.09ms) @ Accel:128 Loops:256 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests
Progress.........: 512/10000 (5.12%)
Rejected.........: 0/512 (0.00%)
Restore.Point....: 0/1000 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:9984-9999
Candidate.Engine.: Device Generator
Candidates.#1....: 1234 -> 1124
Hardware.Mon.SMC.: Fan0: 100%
Hardware.Mon.#1..: Temp: 65c

Started: Wed Aug 25 20:36:57 2021
Stopped: Wed Aug 25 20:45:30 2021

第二招:將可能的密碼寫在 myPasswordlist.txt 中去驗證,指令:

% cat myPasswords.txt 
5678
09876
1234

% hashcat -d 1 -m 14800 ./inputFromManifest.txt ./myPasswords.txt 
hashcat (v6.2.3) starting

OpenCL API (OpenCL 1.2 (Jun 17 2021 15:24:17)) - Platform #1 [Apple]
====================================================================
* Device #1: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz, 16320/16384 MB (4096 MB allocatable), 4MCU
* Device #2: Intel(R) Iris(TM) Plus Graphics 640, skipped

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
* Slow-Hash-SIMD-LOOP
* (null)

Watchdog: Temperature abort trigger set to 100c

Host memory required for this attack: 1 MB

Dictionary cache built:
* Filename..: ./myPasswords.txt
* Passwords.: 3
* Bytes.....: 16
* Keyspace..: 3
* Runtime...: 0 secs

The wordlist or mask that you are using is too small.     
This means that hashcat cannot use the full parallel power of your device(s).
Unless you supply more work, your cracking speed will drop.
For tips on supplying more work, see: https://hashcat.net/faq/morework

Approaching final keyspace - workload adjusted.           

$itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76be166232b4a01bd6974abb27c39034993591c15ba03a14e3b*10000*0ca3ccfc453b32f9ca9aceb754b87f4e0ab9cb95*10000000*bdee6869caa7999e9576f390a248a29f38d10d6f:1234
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Name........: iTunes backup >= 10.0
Hash.Target......: $itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76b...d10d6f
Time.Started.....: Wed Aug 25 20:52:58 2021 (10 secs)
Time.Estimated...: Wed Aug 25 20:53:08 2021 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (./myPasswords.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:        0 H/s (0.18ms) @ Accel:128 Loops:256 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests
Progress.........: 3/3 (100.00%)
Rejected.........: 0/3 (0.00%)
Restore.Point....: 0/3 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:9984-9999
Candidate.Engine.: Device Generator
Candidates.#1....: 5678 -> 1234
Hardware.Mon.SMC.: Fan0: 20%
Hardware.Mon.#1..: Temp: 58c

...

大概就這兩招筆記一下,未來忘記密碼時,就可以靠 hashcat 幫忙批次測試記憶中的密碼了

2016年2月18日 星期四

[Linux] 使用 find -ctime 刪除指定時間區間的檔案 @ Ubuntu 14.04

find -ctime 指令非常方便,例如找時間大於七天的資料:

$ find /path -ctime +7

所以要刪除七天以上的資料,的確可以靠上述完成,但如果有備份程式掛了沒產出時,豈不是會刪光資料?所以又有一招可以找最新七天內的資料:

$ find /path -ctime -7

因此,我就把自動清空指令改成:先判斷備份程式是否正常,正常的話,則刪除某段時期的資料。

連續動作:

$ sh -c  'files=`find /data/jenkins-backup -maxdepth 1 -ctime -7 | wc -l` && test $files -gt 20 && find /data/jenkins-backup -ctime +7 -delete '

而這段意思就是在處理 Jenkins 自動備份機制,因為一天會備份多次,所以用 20 個當作七天內至少要有 20 筆備份資料,當備份資料有正常產出時,在刪除大於七天內的資料。而採用 sh -c 的方式是可以埋在 crontab 中來做事,包含指定 sudo -u user 來限制不小心砍錯資料。

2015年10月18日 星期日

Bash 筆記 - 使用 s3fs、mysqldump、find 透過 s3 定期備份 MySQL 資料庫資料

由於資料庫恰好有 timestamp 這個數值,除設計完 incremental backup 方式後(Bash 筆記 - 使用時間區間備份 MySQL 資料表),而備份好的資料又感到麻煩,所以就往 s3 丟吧!而 s3 的丟法就用 s3fs 來執行。

流程:
  1. 執行 db incremental backup
  2. 使用 s3fs 掛載 s3 空間
  3. 確認 s3 是否已有資料,若沒有則複製過去
其中我把 db backup 的(tar.bz2)產物都有做一次 checksum (tar.bz2.md5),因此判斷是否已在 s3 上時,可以判斷 checksum file 即可:

mkdir -p /data/fuse-tmp/my-s3-bucket
mkdir -p /data/s3/my-s3-bucket
touch /data/s3/my-s3-bucket.password
s3fs my-s3-bucket /data/s3/my-s3-bucket -d -o use_cache=/data/fuse-tmp -o passwd_file=/data/s3/my-s3-bucket.password

find /data/db/ -name "*.bz2" -exec bash -c "test -e {}.md5 && test ! -e /data/s3/my-s3-bucket/\`basename {}\`.md5 && echo 'upload {} , {}.md5 ... ' && time cp {} {}.md5 /data/s3/smy-s3-bucket/ && echo 'done' " \;

sync;sync;sync

fusermount -u /data/s3/my-s3-bucket


其中,/data/db 是擺放一堆 db.sql.tar.bz2 跟 db.sql.tar.bz2.md5 的位置,而我讓備份過程中最後產出 db.sql.tar.bz2.md5 檔,因此先判斷 /data/db/db.sql.tar.bz2.md5 是否產生也代表備份流程是否跑完,接著才檢查 /data/s3/my-s3-bucket/db.sql.tar.bz2.md5 資料來決定是否要上傳到 s3 。

最後,s3 還可以開啟版本控制,這樣可以避免不小心蓋掉檔案的問題 :) 達成完整可自動化的備份方案

2015年5月16日 星期六

Bash 筆記 - 使用時間區間備份 MySQL 資料表

由於資料屬性的關係,剛好有幾個 table 都有 timestamp 這個資訊,拿來備份恰恰好,設計一下備份方式:
  • 一次備份 n 個月
  • 限制每 n 個月一次或是每次執行只備份前面符合條件的 n 個月
例如 n=6 時,在 1~6 月只能備份去年 7~12 月資料,在 7~12 月時,才能 1~6 月份的資料,並且讓程式能夠小小容錯,例如以產生過的資料就不要再匯出、匯出的資料要做壓縮、壓縮完要測試解壓縮、產生 md5 驗證等。

總之,技術細項:
  1. 使用 data 指令得知現況時間並計算出備份範圍
  2. 使用 mysqldump 搭配 --where 指令匯出指定 timestamp 資料
  3. 使用 tar -zcvf 備份資料為 tar.gz 格式
  4. 使用 gunzip -t 測試壓縮資料
  5. 使用 md5sum 建立壓縮檔案的驗證檔
執行方式,採用 bash, mysqldump, tar, gunzip, md5sum, date 指令:

#!/bin/bash
month_offset=0
month_range=6

current_month=`date +"%m"`
if [ ${current_month:0:1} -eq '0' ] ; then
        current_month=${current_month:1:1}
fi
month_offset=$(( $(($current_month + $month_range - 1)) % $month_range  ))
timestamp_begin_date=`date +"%Y-%m-01 00:00:00" -d "-$(($month_offset + $month_range)) month"`
timestamp_end_date=`date +"%Y-%m-01 00:00:00" -d "-$month_offset month"`
timestamp_init_date=`date +"%Y-%m-01"  -d "-$month_offset month"`
timestamp_out_date=`date +"%Y-%m-%d" -d "$timestamp_init_date -1 day" `
job_id=`date +"%Y-%m" -d "-$(($month_offset + 1)) month"`

DIR=/data/routine
log_dir=$DIR/log
dump_dir=$DIR/db
mkdir -p $log_dir $dump_dir
echo "[INFO] Job ID: $job_id , Begin: $timestamp_begin_date , End: $timestamp_end_date"
echo "[INFO] Working Dir: $DIR , log: $log_dir , export: $dump_dir"
echo "[INFO] Output suffix: $timestamp_out_date"
echo

arget_host=MyDBServerIP
target_user=UserID
target_pass=UserPassword
target_db=DatabaseName
target_table=("table1" "table2" "table3")
for table in "${target_table[@]}" ;do
if [ ! -f "$dump_dir/$table.$timestamp_out_date.sql" ] ; then
cmd="time mysqldump -h $target_host -u $target_user -p$target_pass --where \"timestamp >= '$timestamp_begin_date' AND timestamp < '$timestamp_end_date'\" --single-transaction --databases $target_db --tables $table > $dump_dir/$table.$timestamp_out_date.sql"
echo $cmd;
        fi        
done

echo
echo -n "Wanna go (y/N): "
read ans

if [ "$ans" == 'Y' ] || [ "$ans" == 'y' ] ; then
for table in "${target_table[@]}" ;do
output_file=$table.$timestamp_out_date.sql
output_archive_file=$output_file.tar.gz
output_archive_check_file=$output_archive_file.md5
echo
echo "build target: $output_file"
echo "\t$output_archive_file"
echo "\t$output_archive_check_file"
echo "..."
if [ ! -f "$dump_dir/$output_file" ] ; then
cmd="time mysqldump -h $target_host -u $target_user -p$target_pass --databases $target_db --tables $table --single-transaction --where \"timestamp >= '$timestamp_begin_date' AND timestamp < '$timestamp_end_date'\" > $dump_dir/$output_file"
echo $cmd
time mysqldump -h $target_host -u $target_user -p$target_pass --databases $target_db --tables $table --single-transaction --where "timestamp >= '$timestamp_begin_date' AND timestamp < '$timestamp_end_date'" > $dump_dir/$output_file
fi
if [ ! -f "$dump_dir/$output_archive_file" ] ; then
echo "time tar -zcf \"$table.$timestamp_out_date.sql.tar.gz\" \"$table.$timestamp_out_date.sql\""
cd $dump_dir && time tar -zcf "$output_archive_file" "$output_file"
fi
if [ -f "$dump_dir/$output_archive_file" ] && [ ! -f "$dump_dir/$output_archive_check_file" ] ; then
echo "time gunzip -t $output_archive_file && time md5sum $output_archive_file > $output_archive_check_file"
cd $dump_dir && time gunzip -t $output_archive_file && time md5sum $output_archive_file > $output_archive_check_file
fi
done
fi


若還有其他興趣的話,可以再結合 AWS glacier 的上傳,例如:

aws_glacier_bin="java -jar /path/uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar "
aws_glacier_region=https://glacier.region-id.amazonaws.com
aws_glacier_dir=db-log
aws_glacier_partsize=134217728

if [ "$aws_glacier" == 'Y' ] || [ "$aws_glacier" == 'y' ] ; then
for table in "${target_table[@]}" ;do
output_file=$table.$timestamp_out_date.sql
output_archive_file=$output_file.tar.gz
output_archive_check_file=$output_archive_file.md5
echo
echo "selected: $output_archive_file"
if [ -f "$dump_dir/$output_archive_file" ] && [ -f "$dump_dir/$output_archive_check_file" ] ; then
echo "do upload: $output_archive_file"
cmd="time $aws_glacier_bin --endpoint \"$aws_glacier_region\" -v \"$aws_glacier_dir\" --multipartupload \"$output_archive_file\" --partsize $aws_glacier_partsize  "
echo $cmd;
cd $dump_dir && eval $cmd;
fi
done
fi

2015年5月4日 星期一

GAE 筆記 - 將 Google App Engine 之儲存資料 DataStore 匯出處理

前陣子寫小的程式不斷地將資料儲存起來,最近想處理一下,打算用 offline 的方式處理。接著就是要把資料先匯出,再用程式分析每筆資料。

匯出方式很簡單,只需到 Google App Engine -> Application -> YourApp -> Data -> Datastore Admin -> 勾選想要的資料表(Entities) -> Backup Entities ,不一會兒就可看到 Backups 有資料了。

接著是下載方式,有一派是說用 gsutils ,但我沒試成功,可能跟 gsutils 使用時機有關,我則是透過網頁把各個檔案下載來使用:Google App Engine -> Application -> YourApp -> Data -> Blob Viewer -> 可看到幾個小檔資料,就簡易人工點擊下載。

最後,寫簡單的程式來分析吧:

import webapp2

from google.appengine.api.files import records
from google.appengine.datastore import entity_pb
from google.appengine.api import datastore

class MainPage(webapp2.RequestHandler):
        def get(self):
                self.response.headers['Content-Type'] = 'text/plain'
                for record in records.RecordsReader(open('file-part-1', 'r')):
                        entity_proto = entity_pb.EntityProto(contents=record)
                        entity = datastore.Entity.FromPb(entity_proto)
                        self.response.write(entity)

app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

2015年2月12日 星期四

AWS 筆記 - 使用 AWS Glacier 服務備份大量資料 @ Ubuntu 14.04

這個服務大概 2014 年夏天就開始關注並且在秋天嘗試使用,曾經也寫過一篇筆記但...最後沒發表 XD 實在是 AWS Glacier 如其名,大部份的指令真的像冰河緩慢移動 Orz 接著忙了就忘了。這次下定決心來寫一篇筆記。

簡言之,費用比 AWS S3 便宜,但是存取 AWS Glacier 的行為更像傳統磁帶模式,很多操作動作,會先給你一個 Job ID,還得手動用此 ID 去確認結果。例如想查閱已經有多少檔案,會發一個需求 Job ID 給你,而非馬上跟你說已經有多少檔案了。

整體上,要上傳資料一定要走 AWS API 方式,也就是到 AWS IAM 上建立一個 user,給予以下權限:
  • Amazon Glacier Full Access (另一個則是 Amazon Glacier Read Only Access)
  • Amazon SQS Full Access (下載檔案會用到, 若工作僅上傳則不需要, 沒有時的錯誤訊息: Access to the resource https://sqs.ap-northeast-1.amazonaws.com/ is denied)
  • Amazon SNS Full Access (下載檔案會用到, 若工作僅上傳則不需要, 沒有時的錯誤訊息: User: arn:aws:iam::####:user/#### is not authorized to perform: SNS:CreateTopic on resource)
我記得去年摸時,是使用 Amazon SimpleDB (sdb:*) 相關的權限,印象中跟 metadata 有關,不過現在卻沒查到了?! :P 接著,替使用者建立一組 access key/ secret key 來使用,而往後的上傳、下載等是靠這組 API KEY 工作。

此外,使用 AWS Glacier 前,要稍微瞭解一下操作方式
  • 不同的 Data Center 會因為電價等關係,所以儲存的費用不一樣。
  • 上傳資料前,除了要挑選 Data Center 外,還需要類似建立一個類似目錄的儲存單位 (Vault)
  • 除了網頁版 GUI 可以進行 Create Vault, Delete Vault 外,其餘都一律透過 API 進行,其中 Delete Vault 還必須確定裡頭沒其他檔案
  • 透過 API 操作時,需要的基本參數為 API KEY、Data Center (region/endpoint) 等資料
雖然用過 python 版工具 https://github.com/uskudnik/amazon-glacier-cmd-interface,這次就來用用 Java 版吧!https://github.com/MoriTanosuke/glacieruploader

建立 Vault (可透過 AWS Web Console)操作:

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault -c
INFO  Using end point: https://glacier.ap-northeast-1.amazonaws.com
INFO  Creating vault changyy-vault...
INFO  Vault changyy-vault created. {Location: /##########/vaults/changyy-vault}
LastInventoryDate: null
NumberOfArchives: 0
SizeInBytes: 0
VaultARN: arn:aws:glacier:ap-northeast-1:##########:vaults/changyy-vault
VaultName: changyy-vault


上傳檔案(最後的 archive 接的資料就是該筆料的 ID):

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault --upload ~/uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar
INFO  Using end point: https://glacier.ap-northeast-1.amazonaws.com
INFO  Starting to upload $HOME/uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar to vault changyy-vault...
INFO  Uploaded archive ########################################


切檔上傳,此例是 128MB 為單位,適合檔案很大的情境(Archive ID 接的資料就是該筆料的 ID):

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault --upload ~/uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar --multipartupload ~/TargetBigFile --partsize 134217728
INFO  Using end point: https://glacier.ap-northeast-1.amazonaws.com/
INFO  Multipart uploading TargetBigFile to vault changyy-vault with part size 134217728 (128.00MB).
INFO  Upload ID (token): ################################################
INFO  Part 1/187 (bytes 0-134217727/*) uploaded, checksum: e19319be5e3c5d3f45a1ce7ef9ab3644b6933ec01c0754285babf45eb46b5b0b
...
INFO  Part 187/187 (bytes 24964497408-24993715534/*) uploaded, checksum: d0219f53b4f54431495211bfd8880fe52597354acc51aa077dcb67cacee69f53
INFO  Uploaded Archive ID: ################################################
INFO  Local Checksum: a1500723e11892cc2bb297d5d6f97a08035e30810ae0e3342184fbed4e2c2d5b
INFO  Remote Checksum: a1500723e11892cc2bb297d5d6f97a08035e30810ae0e3342184fbed4e2c2d5b
INFO  Checksums are identical, upload succeeded.


然而,剛上傳完是無法馬上下載的 :P 而想要查詢檔案列也是,必須先發一個"查詢列表"的工作(得到 Job ID),等工作結束後才能查詢到結果(取得檔案列表)

發出"查詢 Vault 檔案列表"的需求:

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault -l
INFO  Using end point: https://glacier.ap-northeast-1.amazonaws.com
INFO  Starting inventory listing for vault changyy-vault...
INFO  Inventory Job created with ID
8KDBk2AS_9bYC8dIOBHxjitqxaLhEklXPfU6jZO-t-su3cp1k3NaHFIUpFaBiJDXDGFyzYyqaw-3MboGNlJ2W6kKDzmt


若這個 Vault 是剛建立的,還會有類似錯誤訊息:vaults/changyy-vault cannot be initiated yet, as Amazon Glacier has not yet generated an initial inventory for this vault.

取得"查詢 Vault 檔案列表"的結果:

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault -l 8KDBk2AS_9bYC8dIOBHxjitqxaLhEklXPfU6jZO-t-su3cp1k3NaHFIUpFaBiJDXDGFyzYyqaw-3MboGNlJ2W6kKDzmt

若工作未做完,會顯示錯誤訊息:ERROR The job is not currently available for download。做完的話,會顯示清單,其中 Description 在這套 Java 工具下,會自動填寫上傳的檔名:

ARN: arn:aws:glacier:ap-northeast-1:##############:vaults/changyy-vault
------------------------------------------------------------------------------
Description:  uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar
Archive ID: q_SfW7MNmTE1_9xBbmzP5MvnEGYYmF8wCIe2aYs4_7NAXjn8fEO4nl97QZ-deJ_hDsKni7n5z0avn8gEdAnFfzMV4xE9FlF2Fr3UualyZj0b4LNSq9cENWYWoueSma9Kq8zGuwA9IA
CreationDate: 2015-02-07T11:17:36Z
Size: 19496656 (18.60MB)
SHA: d07cddbcbe3a83dba2b4ca654760bba4b77f92ae1ecc9f1fbffad337730fece0


下載檔案:

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault --download q_SfW7MNmTE1_9xBbmzP5MvnEGYYmF8wCIe2aYs4_7NAXjn8fEO4nl97QZ-deJ_hDsKni7n5z0avn8gEdAnFfzMV4xE9FlF2Fr3UualyZj0b4LNSq9cENWYWoueSma9Kq8zGuwA9IA --target /tmp/test.jar
INFO  Using end point: https://glacier.ap-northeast-1.amazonaws.com
INFO  Downloading archive q_SfW7MNmTE1_9xBbmzP5MvnEGYYmF8wCIe2aYs4_7NAXjn8fEO4nl97QZ-deJ_hDsKni7n5z0avn8gEdAnFfzMV4xE9FlF2Fr3UualyZj0b4LNSq9cENWYWoueSma9Kq8zGuwA9IA from vault changyy-vault...
INFO Archive downloaded to /tmp/test.jar


整個過程不會馬上進入下載 Orz 例如我下載一個 52MB 的檔案,整個過程耗費 245 分鐘...絕對不是下載速度太慢,而是準備流程要等好一陣子。

刪除檔案:

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault --delete q_SfW7MNmTE1_9xBbmzP5MvnEGYYmF8wCIe2aYs4_7NAXjn8fEO4nl97QZ-deJ_hDsKni7n5z0avn8gEdAnFfzMV4xE9FlF2Fr3UualyZj0b4LNSq9cENWYWoueSma9Kq8zGuwA9IA
INFO  Using end point: https://glacier.ap-northeast-1.amazonaws.com
INFO  Deleting archive q_SfW7MNmTE1_9xBbmzP5MvnEGYYmF8wCIe2aYs4_7NAXjn8fEO4nl97QZ-deJ_hDsKni7n5z0avn8gEdAnFfzMV4xE9FlF2Fr3UualyZj0b4LNSq9cENWYWoueSma9Kq8zGuwA9IA from vault changyy-vault...
INFO  Archive q_SfW7MNmTE1_9xBbmzP5MvnEGYYmF8wCIe2aYs4_7NAXjn8fEO4nl97QZ-deJ_hDsKni7n5z0avn8gEdAnFfzMV4xE9FlF2Fr3UualyZj0b4LNSq9cENWYWoueSma9Kq8zGuwA9IA deletion started from vault changyy-vault.


刪除 Vault:

$ java -jar uploader-0.0.8-SNAPSHOT-jar-with-dependencies.jar -e "https://glacier.ap-northeast-1.amazonaws.com" -v changyy-vault --delete-vault
INFO  Using end point: https://glacier.ap-northeast-1.amazonaws.com
INFO  Deleting vault changyy-vault...


若 vault 內還有檔案會有錯誤訊息:Vault not empty or recently written to: arn:aws:glacier:ap-northeast-1:############:vaults/changyy-vault。此外,若先去刪檔案,再來執行也會有一樣的問題,因為這是冰川啊 XD 刪檔也是慢慢地

整體心得,AWS Glacier 操作上真的很煩,因為太慢了。此外,也必須把那些 File Archive ID 記好,或是任何工作的 Job ID 記好,後續才能工作。有興趣可以在玩看看視窗介面,例如 CrossFTP 等,在操作檔案列表時,會跟你說要數小時(>5小時)才會得知結果,唯一的好處就是 CrossFTP 會幫你把一些 Job ID 記住吧

2014年6月30日 星期一

[Linux] 簡易備份加密 MySQL / MySQLDump 資料 @ Ubuntu 14.04

採用 mysqldump 備份 MySQL 資料,可搭配 --where " timestamp < '2014-06-01' AND timestamp >= '2014-05-01' " 等月份備份方式;使用 md5sum 驗證;使用 tar 和 openssl des3 加密:

  • $ mysqldump -u root -p myDatabase myTable --where " timestamp < '2014-06-01' AND timestamp >= '2014-05-01' " > mydatabase_mytable.2014-06.sql
  • $ find * -name "*.sql" -exec sh -c 'test -e {}.md5sum || md5sum {} > {}.md5sum' \; 
  • $ find * -name "*.sql" -exec sh -c 'tar -zcf - {} {}.md5sum | openssl des3 -salt -k MyPassword | dd of={}.tgz.des3' \;
連續動作:
  • $ find * -name "*.sql" -exec sh -c 'test -e {}.md5sum || md5sum {} > {}.md5sum' \; && md5sum -c *.md5sum > /dev/null && find * -name "*.sql" -exec sh -c 'test -e {}.tgz.des3 || tar -zcf - {} {}.md5sum | openssl des3 -salt -k MyPassword | dd of={}.tgz.des3' \;
如此一來,即可透過 crontab 定期一直加密新增的 *.sql 檔案(大概要處理一下 md5sum 的指令驗證那塊),加密後就可以隨意丟一堆雲端儲存服務了吧

2014年5月15日 星期四

Linode - Free Upgrade、Restore from Backup、Resize 的時間花費

說真的 Linode 提供的服務對個人而言還滿好用的,只是對於公司營運 service 的不中斷的需求來說,則沒有 AWS 好用 Orz 雖然 Linode 也有 Node Balancer 可以用,但絕大部分的 High Availability 都仍透過 WebOps 負責處理,耗掉的人力並不低,而花在 AWS 的錢,其實就跟請 2~3 位 WebOps 的錢沒兩樣時,但底下的 WebOps 人力可以精簡又做得快樂時,何樂不為?

回到主題,這邊主要是趁 Free Upgrade 模式以及 Backup (Restore to) 機制,測試開一台機器所要耗費的時間,對 Linode 而言,原理都是把機器的硬碟資料 snapshot 起來,再搬到到另一台機器,啟動。所以最耗時的地方都落在資料搬移(複製)。



至於耗時為何需要在意?實在是使用 Linode 等 VPS 後,深深體會不能把這些機器都當做不會掛,某一派 SA 會覺得終於不用管"硬體"了,但這幾個月體驗了數次 Linode Hardware Issue 而直接強迫中斷服務,實在有夠痛 XD 雖然不用自己去修硬體,但服務中斷等同 WebOps 進入加班啊,因此,耗時對初期沒做 HA 的架構來說,就是代表要花多久解決中斷的服務,這時通常是透過 Backups 的 "Restore to" 。

此例分別以 Linode HDD Size 為例:
  • 48GB: 約 16 分鐘
  • 96GB: 約 23 分鐘
  • 384GB: 約 97 分鐘

2014年4月15日 星期二

Linode - 使用 Backup 服務處理事件: An issue affecting the physical hardware this Linode resides on has been detected.

下班前收到這個 event ,結果就是繼續加班 Orz 若下班前的會議沒 delay 的話,我應該是在回家的路上被狂 call XDD

An issue affecting the physical hardware this Linode resides on has been detected.

We are working to resolve the issue as quickly as possible and will update you as soon as we have more information.
Your Linode will return to its previous state once the issue is resolved. Thank you for your patience and understanding.

記得以前問過學弟,他說 Linode 也會有維護的情況,沒想到真的碰到了...直接把你的機器關掉,我跟老闆說,這就像我們租的機房碰到火災一樣 XD 沒轍。

至於解法也沒有啥好辦法,一種就是等他維護好,另一種則是另外建一台 backup server 出來用,由於我們的服務都有建 backup ,所以就來體驗一下。

切換到被關掉的那台機的 backup 區,可以看到有一些選項可用:


此例就選 daily backup 的 restore to 選項,接著選要去哪台機器:


由於我已經先開了新機器(最下面那台),不然可以點 Add a Linode,此例也意外發現只能 restore to 同一區 DataCenter 的機器。最後,那台新機器的情況就會顯示正在處理:

 

處理完後,就可以 Boot 啦 :P

註:還好 Linode 只花了 3 小時處理,接著就可以把新機器著手進行關閉了。