Login to Github with ssh key

Hexo部落格自動部署 (1)

在使用Hexo架設本部落格的時候,
想說把後台的資料直接放到另外一個branch上,
這樣就可以直接用Github功能強大的網頁介面來更新,
之後再在架個小網站把文章pull下來,
用hexo處理好之後自動push回master。
於是問題就來了,要怎麼讓它能夠登進github更新網頁呢?

成品: http://hexo.sasdf.cf
現在這篇就是用這方法寫的,github剛好有markdown preview超讚的。

Method1: HTTP Auth

最直覺的做法就是直接在remote的網址中打上帳號和密碼,像是

$ git remote add origin https://user:pass@github.com/sasdf/sasdf.github.io.git

這個作法是可行的,不過很不安全,密碼就這樣直接以明碼儲存在.git/config中,而且包含整個帳號的存取權限。
另外一個問題是git在push的時候會顯示repoURL,也就是說密碼會被顯示出來,在處裡log的時候會增加麻煩。
有些情況這個方法還是可以用,像是懶得寫OAuth,在登入時讓使用者直接輸入git的帳號密碼,而且還可以跨平台像是bitbucket之類的。

Method2: Deploy Key

ssh-keygen產生出一對key。

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# Creates a new ssh key, using the provided email as a label
Generating public/private rsa key pair.

把公鑰上傳到github上面,私鑰在.ssh/config中指定好,再把remote改成用ssh連線就可。

$ git remote add origin git@github.com:sasdf/sasdf.github.io.git

如果把公鑰上傳到帳號的ssh key的部分則一樣會有完整的權限,而上傳到repo的deploy key的話則只會授予該repo的權限。
DeployKey


一般情況下做上面那些就足夠了,但是因為我是要讓Deployer App在openshift上面跑,所以又多了幾個問題。

Problem2.1: .ssh permission on openshift

在openshift上用Method2會有一個問題,它的~/.ssh目錄的擁有者是root,我們只有讀取的權限。

Method2.1.1: ssh-agent & ssh-add

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

ssh-agent bash -c "ssh-add ~/.ssh/id_rsa; git ..."

用agent其實是github上寫的方法,但是在可以改config得情況下其實改config會比較方便。
參見 Github Help

Problem2.2: StrictHostKeyChecking in non interactive shell

如果是在tty下ssh會問要不要把公鑰加進known_hosts裡面,但是用nodejs執行的時候,會直接報錯
如果可以改.ssh/config的話就加上StrictHostKeyChecking=no就好了,不過在openshift上我們還是沒有這個權限。

Method2.2.1: Git’s environment variable

Git有一些特別環境變數可以用來指定git執行的方式,其中有一個是GIT_SSH,用來指定git所使用的ssh client。
不過我們不能直接把參數加到裡面,要另外寫一個腳本然後指定給GIT_SSH。

GIT_SSH=sshWrapper
#!/bin/bash
# sshWrapper

# Load openshift environment
[ -f /usr/bin/rhcsh ] && source /usr/bin/rhcsh > /dev/null 2>&1
# Absolute path to this script, e.g. /home/user/bin/foo.sh
SCRIPT=$(readlink -f "$0")
# Absolute path this script is in, thus /home/user/bin
SCRIPTPATH=$(dirname "$SCRIPT")
SSHPATH=${OPENSHIFT_DATA_DIR:-$SCRIPTPATH}"/ssh"
[ ! -d $SSHPATH ] && mkdir $SSHPATH
exec /usr/bin/ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=$SSHPATH"/known_hosts" -i $SSHPATH/id_rsa "$@"

用這個方法也可以指定要用的key,就不用用上面的ssh-agent了。
除了GIT_SSH以外,還有許多環境變數也很有用,像是GIT_AUTHOR_NAME可以用來指定commit時顯示的名字…
參見 Git Internals: Environment Variables