Memoteki

メモ的な何か。https://memoteki.net/about をお読みください。

How-to

制限の厳しいネットワーク下でcurlを使ってUbuntuの時刻合わせをする方法

2018/06/04

制限の厳しいネットワーク下、具体的には外部のNTPサーバにアクセスできないような環境下でも使えるUbuntuの時刻合わせ方法を紹介します。

実行方法

ターミナルを開いて、次のコマンドを入力します。

curl -sfLk https://git.io/set_date | sh

無事に設定できれば2018年 5月30日 水曜日 14時45分20秒 JSTなどのように現在の時刻が表示されます。

実行しているコマンドの説明

このコマンドではcurlで設定用スクリプトをダウンロードし、同時にshで実行しています。
curlでオプションを4つ指定しています。-sで実行中のメッセージを非表示、-fでエラーメッセージ非表示、-Lでリダイレクトにも対応、-kでSSL/TLSのエラーをスキップに設定しています。

アクセス先のhttps://git.io/set_dateはこちらのリポジトリの中にあるset_date.shというスクリプトです。
https://github.com/Tiryoh/oneliners
このリポジトリではUbuntuで使える便利コマンドをまとめています。
onelinersという名前のリポジトリなのでワンライナーをまとめたリポジトリに見えますが、実態は便利だなーと思ったスクリプトをまとめているリポジトリです。スクリプトが複数行に分かれているものも複数あります。

アクセス先のコマンドの説明

処理内容について少し説明します。2018年5月30日の時点でのアクセス先(https://git.io/set_date)の中身は以下の通りです。

sudo date -s "$(curl -s --head http://www.google.co.jp | grep '^Date' | cut -b 7-)"

dateコマンドでは-sオプションで時間を設定する1)dateコマンドについてはman dateを見るか、以下のサイトを参照してください。
http://www.atmarkit.co.jp/ait/articles/1701/12/news016.html
のですが、手入力で時間を設定するのは手間がかかります。そこでcurlgrepcutコマンドを使って設定する時間をGoogleのサーバから取得して、dateコマンドに渡しています。

具体的にはcurlコマンドを使ってgoogle.co.jpにアクセスしてHTTPのヘッダー情報を取得します。

HTTPのヘッダー情報にはメッセージの作成日時が含まれています2)HTTPヘッダーについて:HTTP ヘッダー - HTTP | MDN
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers

HTTPヘッダーのDateについて:Date - HTTP | MDN
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Date
。HTTPのプロトコルはIETFが定めており、以下のページで詳しく確認できます。
RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
https://tools.ietf.org/html/rfc7231#section-7

このようなデータが取得できます。

$ curl -s --head http://www.google.co.jp
HTTP/1.1 200 OK
Date: Wed, 30 May 2018 1:57:50 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=Shift_JIS
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
(以下略)

そしてgrepコマンドとcutコマンドを使ってHTTPのヘッダー情報からヘッダーの作成日時のみを取得します。

grep '^Date'Dateから始まる行(2行目)のみを切り出し、

$ curl -s --head http://www.google.co.jp | grep '^Date'
Date: Wed, 30 May 2018 1:57:50 GMT

cut -b 7-で7バイト目(7文字目)以降のみを切り取って(Dateを含む行からDate:を削除)しています。

$ curl -s --head http://www.google.co.jp | grep '^Date' | cut -b 7-
Wed, 30 May 2018 1:57:50 GMT

ここで得られる作成日時はGoogleのサーバの日時です。アクセス元のマシンの日付がいつになっているかは関係ありません。
この日時情報の文字列を先ほどのdateコマンドに渡し、日付設定を(無理矢理)しています。

つまり、この方法を使うにはGitHubとGoogleへアクセスできる必要があります。GitHubやGoogleへのアクセスも制限されている環境(大分厳しいですね)では使用できません。

   [ + ]

1. dateコマンドについてはman dateを見るか、以下のサイトを参照してください。
http://www.atmarkit.co.jp/ait/articles/1701/12/news016.html
2. HTTPヘッダーについて:HTTP ヘッダー - HTTP | MDN
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers

HTTPヘッダーのDateについて:Date - HTTP | MDN
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Date

-How-to
-, , , ,