API 不該自動 HTTP 轉到 HTTPS

在「API Shouldn't Redirect HTTP to HTTPS (jviide.iki.fi)」這邊看到的,原始文章在「Your API Shouldn't Redirect HTTP to HTTPS」這邊。

仔細想一下沒錯,API 應該要一開始就被正確設定,所以要 fail fast。

另外在 id=40505525 這邊還提到了透過 HTTP 的 token 會自動被 revoke 掉,這個作法也很漂亮:

The Stack Exchange API used to revoke API keys sent over HTTP (and return an error message), which is my favorite way to handle this.

另外一個想法是直接不聽 port 80,不過這點在 Endpoint 的 IP 不是自己專用的情況下不一定能做到 (像是大多數的 CDN 環境)。

的確有戳中我手上預先準備好的 nginx config,來想看看怎麼改會比較好... 也許改成整個傳回 403,只開 /.well-known/acme-challenge/ACME (Let's Encrypt) 的 HTTP-01 認證可以過。

弄清楚 >/dev/null 2>&1 與 2>&1 >/dev/null 的差異

以前都是硬背起來的,如果要把所有的輸出都丟到 /dev/null,要用前面的方式才會是對的,但其實在 bash 的 manpage 裡面有提到:

Note that the order of redirections is significant. For example, the command

    ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist, while the command

    ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the standard error was duplicated from the standard output before the standard output was redirected to dirlist.

這是因為照順序跑 dup2() 的關係 (參考 bash 的 redir.c)。

前者會先把 dirlist 開起來後透過 dup2() 複製到 fd=1,再用一次 dup2() 把 fd=1 複製到 fd=2,達到我們要的效果。

後者則是先把 fd=1 複製到 fd=2 (於是大家都丟到 stdout 了),接下來再把 dirlist 開起來,丟到 fd=1。這樣變成 ls 寫到 stderr 的東西變成到 stdout 了,而本來寫到 stdout 的東西進到 dirlist 這個檔案裡。

剛剛寫 code 時想找一下有沒有官方文件或是 source code 有描述 ordering 或是有定義行為,結果發現 bash 的 manpage 裡面就有提到了...

第二堂:「Shell Tools and Scripting」

這個系列是從『MIT 的「The Missing Semester of Your CS Education」』這邊延伸出來的,這篇文章講第二堂課「Shell Tools and Scripting」。

這堂有點像是第一堂的延伸,在講更多 shell 的操作與工具,然後說明 shell script 怎麼寫。

開頭就先說明有 function,然後講了不少 magic variable,像是 $0$1$9,而 $@$# 也提到了 (但居然沒提到 $*),然後再來是 $$!!$_

然後提到 true 與 false,接著就講條件 || 與 && 了。後面就開始講 shell 裡面的 for 與 if,基本上到這邊已經能寫不少東西了?

後面就介紹更多工具...

第一堂:Course overview + the shell

這個系列是從『MIT 的「The Missing Semester of Your CS Education」』這邊延伸出來的,這篇文章講第一堂課「Course overview + the shell」。

前面大概講一下這 11 堂各一個小時的課大概是什麼,後面就開始講 shell 下的操作了。

先講了一些基本指令 (date & echo),然後提到了環境變數 $PATH,接著就講目錄結構與 ls,然後就順便提到 man 可以拿來查說明,接著是講 redirect 與 pipe 以及 root 權限的特殊性 (以及 sudo)。

在課程最後面的這個範例,你第一眼看不會想到是第一堂課就可以教完的東西,但的確是結合了上面提到的所有東西,可以細細品味一下:

$ echo 1 | sudo tee /sys/class/leds/input6::scrolllock/brightness

apt-get 的安全性漏洞

前幾天寫的「APT 不使用 HTTPS 的說明」的當下就已經有看到在講這個漏洞,但沒讀完就一直放著沒寫:「Remote Code Execution in apt/apt-get」。

漏洞出在實作上的問題,對於 HTTP 重導的程式碼沒有處理好外部字串,在還沒修正的機器上用這個指令關閉 redirect,避免在修正的過程反而被 RCE 打進去:

sudo apt update -o Acquire::http::AllowRedirect=false
sudo apt upgrade -o Acquire::http::AllowRedirect=false

但也不是 HTTPS 就能避免這個問題,因為 HTTPS 連線用的程式碼又是另外一份,裡面不知道有沒有問題 (像是之前經典的 Heartbleed),所以應該還是會繼續爭吵吧...

用 GitHub + Netlify + Cloudflare 管理靜態網站...

最近 GitHub Pages 支援 HTTPS (透過 Let's Encrypt,參考「GitHub 透過 Let's Encrypt 提供自訂網域的 HTTPS 服務」這篇),但測了一下不是我想要的效果,就找了一下網路上的資源,結果有找到還算可以的方案...

  • 先把網站放在 GitHub 上。(不需要設定 GitHub Pages)
  • 然後用 Netlify 變成網站並且開啟 HTTPS。(可以選擇使用系統內提供的 Let's Encrypt,會透過 http-01 認證。如果因為 DNS 還沒生效的話也沒關係,可以之後再開。)
  • 然後用 Cloudflare 管理 DNS 的部份 (主要是因為他的 root domain 可以設 CNAME,一般會提到的 ALIAS 就是指這個)。

這樣整個靜態服務都不用自己管理,而且有蠻多 header 可以設定,其中與 GitHub Pages 最主要的差異是 Netlify 支援 301/302 redirect。而關於 Netlify 的設定範例 (簡單的),可以參考我在 GitHub 上的 git.tw repository。

然後 Netlify 上可以自己設定 header,當設定 HSTS 之後,SSL Labs 的跑分也可以到 A+。

整包目前看起來唯一的限制是 Netlify 的 125k requests/month (平均下來大約 4k requests/day),不過只拿來做 redirect 應該還好...

PS:如果有人要推薦其他的組合也歡迎...

用 Amazon API Gateway 重導網域

在「Creating An Amazon API Gateway With aws-cli For Domain Redirect」這邊看到用 Amazon API Gateway 重導整個網域的方法。一般的做法是用 Amazon S3 (用 web hosting 重導) + Amazon CloudFront (for HTTPS) 堆出來,事實上這個方法成本也比較低,這篇文章只是示範怎麼用而已:

I’m not saying the API Gateway method is better than using S3 plus CloudFront for simple hostname redirection. In fact, it costs more (though still cheap), takes more commands to set up, and isn’t quite as flexible in what URL paths get redirected from the source domain. It does, however, work and may be useful as an API Gateway aws-cli example.

可以從中間學到一些東西,尤其是可以看到如何使用 aws-cli 操作 Amazon API Gateway 的部分...

強迫 Blogger (Blogspot) 使用 blogspot.com 的網域 (而非 .tw)

在「Prevent Blogger from Redirecting your Blogspot Blog to Country-Specific URLs」這篇文章裡提到了 Blog 的擁有人要怎麼避免 Google 把網址導到 country-based 的網域下。

目前 Google Chrome 的使用者端可以安裝「NoCountryRedirect (NCR)」這個套件來避開這個問題,但你總不能要求每個人都裝套件...

而這篇文章則說明了如何在 Blogger 裡插入一段 javascript 避免使用 country-based domain:

<script type="text/javascript">
 
  // Written by Amit Agarwal
  
  /* Get the full URL of the current blogger page */
  var blog = document.location.href.toLowerCase();
 
  /* Do not redirect if the domain is .com already */
  if (!blog.match(/\.blogspot\.com/)) {
 
    /* Replace the country TLD with .com and ncr switch */
    blog = blog.replace(/\.blogspot\..*?\//, ".blogspot.com/ncr/");
 
    /* Redirect to the new .com URL in the current tab */
    window.location.replace(blog);
  }
 
  // Source: http://labnol.org/?p=21031
  
</script>

這樣做的好處主要是來自於 url 統一,對於統計、廣告以及分享的問題會減少很多。

Yuren Ju 的 ptt redirect:從轉載網站自動轉回 Ptt 原文

Twitter 上看到的 Google Chrome Extension 專案,針對轉載自 Ptt 的網站自動轉回 Ptt 原文:

程式在「ptt redirect」這邊,而原始程式碼在 GitHub 的「yurenju/ptt-redirect」這邊。

目前只支援 disp.cc,應該還有好幾個站可以支援...

用 Amazon S3 送 301 重導

參考「Configure a Bucket for Website Hosting」這邊的說明就可以了,拿 test-redirect.abpe.org 當範例,先是 CNAMES3 的 website endpoint 上:(這個 bucket 我是放在 us-west-2 上,所以會指到 us-west-2 的 website endpoint)

;; ANSWER SECTION:
test-redirect.abpe.org. 7200    IN      CNAME   test-redirect.abpe.org.s3-website-us-west-2.amazonaws.com.

然後 S3 上指定 redirect rule:

  <RoutingRules>
    <RoutingRule>
    <Condition>
      <KeyPrefixEquals>img/</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <HostName>www.example.com</HostName>
      <ReplaceKeyPrefixWith>img/</ReplaceKeyPrefixWith>
    </Redirect>
    </RoutingRule>
  </RoutingRules>

也就是像是這樣:

也就是說,如果是 simple redirect 的話,可以善用 S3 的這個功能而不用自己架設 web server (自己架設需要另外考慮 High Availability),還算蠻方便的?