NTP 簡要筆記、台灣常用的校時服務

NTP 全名為 Network Time Protocol,可用來同步不同電腦系統之間的時間,現在的智慧型手機幾乎也都會使用到這個服務來校準、設定裝置上的日期時間,而校時服務需要靠 NTP 伺服器來提供,雖然說校時伺服器全球都會有,但距離越遠也會有網路延遲造成的誤差問題,所以建議使用靠自己較近的伺服器進行校時。台灣常用的 NTP 服務來源為 國家時間與頻率標準實驗室 ,國家時間與頻率標準實驗室的伺服器放在中華電信,是在台灣非常常用到的校時服務來源。

另外有個來自全球志願者提供的 NTP Pool 專案,由全世界的志願者鎖維護,透過 GeoIP / DNS round-robin 等機制提供全世界的使用者簡單、易用的 NTP 服務,只要使用 ntp.pool.org 的網域存取服務就會被自動導向鄰近的校時伺服器,也可以透過指定 zone 的方式手動指向特定的伺服器群,自行透過網域來選擇不同的洲、國家伺服器機群,例如 tw.ntp.pool.org 或 asia.ntp.pool.org (PS: zone 的頁面上也可以看到各區域的伺服器數量資訊)。也許大家平常不常聽到,但像 Debian / Ubuntu / Arch / RedHat / CentOS 等大型 Linux 發行版或一些商業公司也會透過此專案提供其用戶的預設校時服務,也算是很重要的基礎服務,例如 0.{debian, ubuntu, arch, rhel, centos}.pool.ntp.org  (數字的部份通常為 0~3),甚至 Ubiquiti 、 AWS 、 Android 也都有 0.ubnt.pool.ntp.org 、 0.amazon.pool.ntp.org 和 0.android.pool.ntp.org 呢。(不過 AWS 官方現在已經改建議使用 169.254.169.123 囉,參考 Setting the Time for Your Linux Instance)

除此之外,Google 在 2016 年 11 月底也公開了自家的 Public NTP 服務,消息來源可以參考 Google Cloud Platform Blog 的這篇文章:Making every (leap) second count with our new public NTP servers,算是跟著 2016 年會遇到的閏秒議題趁勢推出的服務?服務的名稱就叫作 Google Public NTP,官方的說明為 “A free, global time service that you can use to synchronize to Google’s atomic clocks.“,伺服器名稱為: time.google.com ,只有一組對外網域,雖然多年前就有許多坊間消息指出 Google 有五組校時伺服器可以使用 (分別是 time.google.com 以及 time1.google.com ~ time4.google.com),雖然是真的可以用 … 不過當時並不是一個正式公開的服務,要在正式的環境上使用總覺得不太安心 ,現在 Google 大方的公告,我們也就可以大方的使用了!

對了,Ubuntu 也有自己的 ntp.ubuntu.com 、 Windows 也有自己的 time.windows.com 哦~

依照範圍及距離遠近排序應該會是 國家時間與頻率標準實驗室 / 台灣 -> 日本 -> 亞洲 -> 全球,Google 和 NTP Pool 都是會自動導向距離使用者鄰近的伺服器,如果不想弄的太複雜也可以直接使用 NTP Pool 或 Google 的就好(實測出來台灣各家電信 ping 值大概都在 20ms 內),也可以多設幾組不同來源作為備援。

關於設定的部份,unix-like 系統的校時工具如 ntpdate, ntpd 或 systemd 的 timesyncd 都可以設定一串 NTP server 清單,遇到服務有障礙時可依序向不同的伺服器進行對時,所以就稍微筆記一下自己常用的優先順序,不時會用到一下。其實很多作業系統、路由器、無線基地台裡面預設的 NTP server 不是太遠就是不穩或是服務滅掉了 … 還是手動設一個距離近服務又穩的比較好,時間的準確性對於除錯、系統日誌來說是很重要的,國家時間與頻率標準實驗室說法是 {time, tock, clock}.stdtime.gov.tw 的負載太重,所以我會把前面 tw.pool.ntp.org 和 watch.stdtime.gov.tw / tick.stdtime.gov.tw 設為優先值較高的伺服器,部分系統只能設定一組伺服器,那就隨興挑選吧!

Windows 的時間設定:

這邊雖然列了一串 NTP 伺服器列表,不過在台灣應該是 國家時間與頻率標準實驗室 + 台灣 NTP pool 或 Google Public NTP 就很夠用了,其他的主要是在亞洲開 VPS 的時候可以當作參考或是備用(雲端廠商如 AWS 也有可能已經預設了合適的設定,沒遇到問題也許就不必動了)

  • tw.pool.ntp.org
  • watch.stdtime.gov.tw
  • tick.stdtime.gov.tw
  • time.stdtime.gov.tw
  • tock.stdtime.gov.tw
  • clock.stdtime.gov.tw
  • jp.pool.ntp.org
  • asia.pool.ntp.org

將 Windows 時間設定由 tw.pool.ntp.org 同步:

其實台灣部份大專院學早期也有提供 NTP 校時服務,不過近年來都缺乏維護,和大部分的 FTP / BBS 站台一樣都倒站了,有興趣的可以再找找看,如果覺得 NTP Pool 好用的話也可以考慮加入專案貢獻己力~

其他資訊可以參考:
國家時間與頻率標準實驗室NTP pool project

C++ 的 void main() / int main() … 不要再用 void main() 了!

前陣子聽說有些人學 C++ 程式設計的時候學的 main function 型態都是 “void main()” … 個人是覺得很驚訝加上有點錯愕,因為這個用法是錯的,即便在 C89 規範裡面也只有允許單純用 main(),一是省略 int,因為預設就是 int,二是沒有回傳,則狀態為 undefined,但不是可以用 void main() 啊!

微軟的 Visual C++ 支援這樣古怪的寫法很久了,在 Visual Studio 2012 (編譯器:Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1) 上面實測都還可以順利編過沒問題,但這種寫法很是不合 C/C++ 規範的,到底當初怎麼冒出來這樣的用法恐怕已經無法考證,好像 Visual C++ 6.0 就是用 void main() 來當 function prototype,但又是誰教 Visual C++ 6.0 的程式設計師這樣做的呢? 該不會是微軟為了降低程式可攜性的一種手段吧 XD

底下兩個連結很清楚的說明了 void main() 是錯誤的用法,即便是 C++ 之父也不是空口說說,同時也附上在ISO的標準裡面的相關章節,如果你的學校老師同學還在用這樣的寫法,甚至教別人這樣寫的話 … 找個機會提醒他們一下吧!

Bjarne Stroustrup’s C++ Style and Technique FAQ – Can I write “void main()”?
http://www.stroustrup.com/bs_faq2.html#void-main

The definition void main() { /* ... */ } is not and never has been C++, nor has it even been C. See the ISO C++ standard 3.6.1[2] or the ISO C standard 5.1.2.2.1. A conforming implementation accepts

void main(void) – the Wrong Thing
http://users.aber.ac.uk/auj/voidmain.cgi

  • Because the standard says so. (To which the answer is usually of the form “but it works for me!”)
  • Because the startup routines that call main could be assuming that the return value will be pushed onto the stack. If main() does not do this, then this could lead to stack corruption in the program’s exit sequence, and cause it to crash. (To which the answer is usually of the form “but it works for me!”)
  • Because you are likely to return a random value to the invokation environment. This is bad, because if someone wants to check whether your program failed, or to call your program from a makefile, then they won’t be able to guarantee that a non-zero return code implies failure. (To which the answer is usually of the form “that’s their problem”).

這邊還是補充一下另外兩篇 …

一篇是 void main() is not legal in C++ but is legal in C.、另一篇是 A proposal to correct section 5.1.2.2.1.1 of the C standard,兩篇是同一位作者,比較有趣的是兩篇的論點略有不同,甚至有一點矛盾的感覺,前面認為 void main() 在C裡面是合法的,也列舉了幾個支援 void main() 的編譯器,在後篇作者提出了自己認為 C standard section 5.1.2.2.1.1 比較好(或說比較精確?)的描述,有興趣的話可以翻翻看

小結:

void main() 不應該在 C++ 裡面出現,至於在C語言裡面仍然是有些模糊地帶。無論如何,並不是每個編譯器都支援這樣的做法,就乖乖回傳狀態,讓程式碼的可攜性好一些也是有益無害啊!

DigitalOcean 推薦註冊 (Referral Program)

簡單來說,透過下面這個連結註冊DigitalOcean,我們都可以拿到折扣來底用主機租用費用(10$/25$):

https://www.digitalocean.com/?refcode=1fdd0a1d695a

最近GitHub在推的GitHub Student Developer Pack裡面就有送DigitalOcean的100$折扣,但這兩者是不衝突的,歡迎想要註冊的人使用我的推薦連結 :)

FreeBSD 10.0 的 fetch 噴 Certificate verification failed for …

看前陣子FreeBSD 10.1 RC1出來,著手試試看重頭灌一台乾淨的FreeBSD 10.0起來,看看跟升級上去的差在哪

沒想到剛灌好,要抓個東西就開始噴錯了…用內建的fetch去抓github上面的config…結果:

Certificate verification failed for /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
675067228:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed:/usr/src/secure/lib/libssl/../../../crypto/openssl/ssl/s3_clnt.c:1179:
fetch: https://raw.githubusercontent.com/PeterDaveHello/Unitial/master/gitconfig: Authentication error

把cert連一份到fetch需要讀的位置…
$ ln -s /usr/local/share/certs/ca-root-nss.crt /etc/ssl/cert.pem

搞定收工=__=