目次
「特定のサーバーからだけ外部APIの認証に失敗する」「ログインした直後なのにトークンが期限切れと言われる」「障害のログを2台のサーバーで突き合わせたら、順番が矛盾している」。原因を追うと、サーバーの時計が数分ずれていた、という結末は決して珍しくありません。時刻はあらゆる処理の前提にあるため、ずれると症状が別の場所に現れ、原因にたどり着くまでに時間がかかります。
この記事では、時刻ずれが引き起こす具体的な障害を整理したうえで、NTPの階層構造、Linuxで標準的な時刻同期デーモンであるchronyの設定と確認方法、AWS・GCP・Azureが提供する時刻ソース、うるう秒とスミアリングの考え方、そしてDockerコンテナ内の時刻がどう決まるかを解説します。読み終えれば、自分のサーバーの時刻が信頼できる状態かを確認し、ずれていれば直せるようになります。
時刻ずれが引き起こす障害
数分のずれで壊れるもの
時刻ずれの影響は「時計が合っていない」という見た目の問題にとどまりません。多くのプロトコルやライブラリが「双方の時計がおおむね合っている」前提で動いているためです。
| 領域 | 症状 | 仕組み |
|---|---|---|
| TLS / HTTPS | 証明書エラーで接続失敗 | 証明書の有効期間(notBefore / notAfter)と現在時刻を比較する |
| JWT・OAuth | 発行直後のトークンが期限切れ、または「まだ有効でない」扱い | exp・nbf・iatクレームを検証側の時計で判定する |
| クラウドAPI署名 | AWSでRequestTimeTooSkewedエラー | リクエストの署名に時刻が含まれ、許容差を超えると拒否される |
| Kerberos・AD認証 | ドメイン認証失敗 | チケットの時刻検証に許容差がある |
| ログ照合 | 複数サーバーのログの前後関係が矛盾 | タイムスタンプの基準がサーバーごとに異なる |
| 分散DB・レプリケーション | 後から書いたはずのデータが古い値で上書きされる | タイムスタンプで競合を解決する方式(last-write-wins)は時計に依存する |
| cron・バッチ | 締め処理が想定外の時刻に走る | スケジューラはシステム時刻を信じて動く |
特にJWTは、認証サーバーとAPIサーバーの時計が数十秒ずれるだけで、有効期間の短いアクセストークンが使えなくなります。仕組みの詳細はJWT認証の解説記事を参照してください。障害調査の基本であるログの突き合わせも、時刻が揃っていなければ成り立ちません(Linuxのログ管理入門)。
NTPの仕組みと階層構造
stratumで表される信頼の階層
NTP(Network Time Protocol)は、ネットワーク越しに時刻を問い合わせ、往復の遅延を差し引いて自分の時計を補正するプロトコルです。時刻源はstratum(階層)で表され、原子時計やGPS受信機がstratum 0、それに直結したサーバーがstratum 1、そこから同期したサーバーがstratum 2と続きます。数字が小さいほど時刻源に近く、通常のサーバーはstratum 2〜4程度の公開サーバーやクラウド提供のサーバーに同期すれば十分です。日本では情報通信研究機構(NICT)がntp.nict.jpを公開しており、pool.ntp.orgのようなプールも広く使われています。
補正は「ずらす」のではなく「速度を変える」
NTPクライアントは、ずれを見つけたときに時計を一気に飛ばすのではなく、時計の進む速度をわずかに変えて滑らかに追いつくslew(スルー)方式を基本とします。時刻が逆行するとログの順序やタイマー処理が壊れるためです。ただし起動直後に大きくずれている場合は、いったんstep(即時修正)してから滑らかな補正に移る設定が一般的です。この違いを知っておくと、「同期しているはずなのに数分のずれがなかなか直らない」理由が理解できます。
chronyの設定と確認
現在の状態を確認する
現在のRHEL系(Rocky・AlmaLinux)はchronyが標準で、Ubuntu Serverはsystemd-timesyncdが既定ですがchronyへの置き換えは簡単です。chronyは断続的な接続や仮想マシンでの精度に優れ、サーバー用途では第一選択と考えて問題ありません。まずは状態確認から始めます。
# 同期の全体状況(System time の行が現在のずれ、Leap status が Normal なら正常)
chronyc tracking
# 参照している時刻源の一覧(先頭の ^* が現在同期中のサーバー)
chronyc sources -v
# systemd経由の簡易確認(System clock synchronized: yes を確認)
timedatectl
chronyc trackingのSystem timeが「0.000123456 seconds fast of NTP time」のようにミリ秒以下で収まっていれば健全です。sourcesで^*が1つもない場合は、どのサーバーにも到達できていないことを意味し、ファイアウォールでUDP 123番が塞がれている可能性を疑います。
設定ファイルの書き方
設定ファイルはDebian/Ubuntuが/etc/chrony/chrony.conf、RHEL系が/etc/chrony.confです。最小限の設定は次のとおりです。
# /etc/chrony/chrony.conf(抜粋)
# 時刻源。iburst は起動直後に素早く同期するためのオプション
server ntp.nict.jp iburst
pool ntp.ubuntu.com iburst maxsources 3
# 起動後3回の更新までは、1秒以上のずれをstepで即時修正する
makestep 1.0 3
# ハードウェアクロックにも定期的に反映する
rtcsync
# 計測結果の保存先(再起動後の収束を速める)
driftfile /var/lib/chrony/chrony.drift
# 反映と確認
sudo systemctl restart chronyd # Ubuntuでは chrony
sudo systemctl enable chronyd
chronyc sources -v
# 大きくずれているのを今すぐ直したいとき(手動step)
sudo chronyc makestep
makestep 1.0 3は「最初の3回の更新までは、1秒以上ずれていたら即時修正する」という意味で、多くのディストリビューションの既定設定に含まれています。この3回を過ぎると滑らかな補正しか行わないため、長時間停止していたVMを起動した直後などはchronyc makestepで手動修正するのが確実です。
クラウドの時刻ソースを使う
各クラウドが提供する専用サーバー
主要クラウドは、インスタンスから低遅延で到達できる時刻サーバーを用意しており、インターネット上の公開サーバーよりも精度と安定性で有利です。
- AWS:Amazon Time Sync Serviceをリンクローカルアドレス
169.254.169.123で提供。Amazon Linuxでは既定で設定済みで、他のOSでもserver 169.254.169.123 prefer iburstを追加すれば利用できます - GCP:
metadata.google.internalがNTPサーバーとして機能し、Google提供のイメージでは既定で設定されています - Azure:ホスト側の時刻をHyper-Vの仮想デバイス経由で提供しており、Azure提供のLinuxイメージではchronyがこれを参照する設定になっています
いずれも「ネットワークの外に出ずに同期できる」ため、アウトバウンド通信を制限したプライベートサブネットのサーバーでも時刻同期を維持できる点が重要です。NTP用にセキュリティグループを緩める必要がなくなります。
うるう秒とスミアリング
うるう秒は、地球の自転とのずれを補正するために不定期に挿入される1秒で、UTCでは23:59:60という通常あり得ない秒が出現します。過去にはこの瞬間にJavaやMySQLのプロセスがCPUを消費し続ける不具合が起きた事例があり、時刻の連続性に依存するソフトウェアにとってリスクとなります。GoogleやAWSの時刻サーバーは、この1秒を前後の長時間(たとえば24時間)にわたって少しずつ薄めて配るスミアリング(leap smear)を採用しており、クライアントには23:59:60が現れません。注意点は、スミアリングするサーバーとしないサーバーを混在させると、うるう秒の前後で時刻源同士が食い違い、chronyが混乱することです。クラウド提供の時刻サーバーを使うなら、それに統一するのが原則です。
コンテナ内の時刻
コンテナはホストの時計を共有する
Dockerコンテナは独立したOSではなくホストのカーネルを共有するプロセスなので、時刻もホストのカーネルの時計をそのまま使います。コンテナ内でNTPデーモンを動かす必要はなく、動かそうとしても既定ではシステム時刻を変更する権限(CAP_SYS_TIME)がないため失敗します。つまり「コンテナの時刻がずれている」ときに直すべきはホストであり、Kubernetesならノードのchrony設定を確認することになります。
コンテナで混同しやすいのは「時刻」と「タイムゾーン」の違いです。時刻(UTCで何時か)はホストと同じですが、表示に使うタイムゾーンはコンテナ内の設定に依存するため、ログの見た目が9時間ずれているように見えることがあります。この扱いはタイムゾーン・ロケール・文字コード設定で詳しく解説します。
トラブル事例:スナップショットから復元したVMだけ認証に失敗する
症状:検証環境のVMをスナップショットから復元したところ、そのサーバーからだけ外部SaaSのAPI呼び出しが401で失敗する。他のサーバーは正常。
原因:chronyc trackingを確認すると、システム時刻がNTP時刻より約6日遅れていた。スナップショット取得時点の時刻で起動し、ずれが大きすぎてchronyのmakestepの条件(起動後3回)を過ぎた後は滑らかな補正しか行われず、6日分のずれは事実上直らない状態だった。APIはリクエスト署名の時刻を検証しており、許容範囲を超えて拒否されていた。
対処:sudo chronyc makestepで即時修正して復旧。再発防止として、makestep 1.0 -1(回数制限なしで常にstepを許可する設定)を検証環境にのみ適用し、本番環境では監視ツールでchronyc trackingのずれをメトリクスとして収集して、1秒を超えたら警告するようにしました。時刻が逆行しても問題ない環境かどうかで、stepを常時許可するかを判断するのが実務的な線引きです。
まとめ
時刻ずれはTLS・JWT・API署名・ログ照合・分散DBと、システムのあらゆる層に別の顔をした障害として現れます。対策の基本は、chronyを有効にしてクラウド提供または信頼できる公開NTPサーバーに同期させ、chronyc trackingとchronyc sources -vで同期状態を確認し、ずれをメトリクスとして監視することです。うるう秒対策としてはスミアリングを行う時刻源に統一し、コンテナではホストの時刻を直す、と覚えておいてください。まずは本番サーバーでchronyc trackingを実行し、Leap status: Normalとミリ秒以下のずれになっているかを確認するところから始めましょう。
サーバー運用の基盤整備や監視設計でお困りの際は、Harmonic Societyのシステム開発・インフラ支援にご相談ください。
Harmonic Society
この記事の内容、自社の業務でも活かせそうですか?
ローカルLLM・AI・クラウドなどの技術導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK。まずは30分の無料相談から。売り込みはしません。
関連記事
Related / 9 articles
Notes & Insights
- プログラミング
DDoS攻撃の仕組みと対策入門|レイヤー別の防御とCDN・クラウドの活用
DDoS攻撃をボリューム型・プロトコル型・アプリ層に分けて仕組みを解説し、自前サーバーで防げない理由、CloudflareやAWS Shieldの標準防御、オリジンIPの隠し方、レートリミットとBot対策、攻撃を受けたときの初動、費用が跳ね上がるDenial of Walletへの備えまでわかります。
- プログラミング
WAFとは?仕組み・導入パターン・誤検知対策|Webアプリを攻撃から守る実践ガイド
WAFがファイアウォールやIDSと何が違うのか、シグネチャとマネージドルールの仕組み、Cloudflare WAF・AWS WAF・ModSecurityの比較、フォーム送信がブロックされる誤検知の調査と例外設定、ログ監視、WAFが代替できないことまで実践的に解説します。
- プログラミング
セキュリティヘッダー入門|CSP・HSTS・X-Frame-Optionsの設定と効果を実践解説
CSP・HSTS・X-Frame-Options・X-Content-Type-Optionsなど主要セキュリティヘッダーが防ぐ攻撃と、CSPのReport-Onlyからの段階導入、nonce/hash、HSTS preloadの不可逆リスク、Nginx・Next.js・Astroでの設定例、確認方法を解説します。
- プログラミング
クラウドの通信費(Egress)入門|データ転送量課金の仕組みと転送コストを抑える設計
クラウドの「受信無料・送信有料」の原則、AZ間・リージョン間・インターネット向けの単価差、NATゲートウェイ処理料の罠、CDNで転送量を減らす方法、バックアップやログ転送の見落とし、請求書で転送料を特定する手順を解説。想定外の請求を防げます。
- プログラミング
秘密情報をGitに入れない仕組み|.gitignore・git-secrets・履歴から漏れた鍵の削除
APIキーや.envをGitにコミットしてしまう典型経路と、.gitignore・.env.exampleの運用、pre-commitでのgitleaks検知、GitHub secret scanningの活用、漏れた鍵の無効化と履歴書き換え(git filter-repo)の手順を解説。仕組みで再発を防げます。
- プログラミング
開発・ステージング・本番環境の分離設計|環境差分をなくす構成とアクセス制御
開発・ステージング・本番それぞれの目的と、構成をコードで揃える方法、環境別の設定注入、本番データを使わないテストデータ戦略、ステージングの保護(Basic認証・IP制限・noindex)、コストを抑える運用までを解説。環境差分による本番障害を防げます。
- プログラミング
ngrok・Cloudflare Tunnelでローカルを公開|Webhook開発とデモ環境の作り方
NAT内のローカル環境にStripeやLINEのWebhookを届けるトンネリングの仕組みを解説。ngrok・Cloudflare Tunnel・localtunnelの比較、固定ドメインと認証、リクエスト検査、公開時のセキュリティ、自宅サーバー公開への応用までわかります。
- プログラミング
ローカル開発環境のHTTPS化|mkcert・hostsファイル・自己署名証明書の正しい使い方
ローカル開発をHTTPS前提にすべき理由(Secure Cookie・Service Worker・OAuth)と、mkcertでローカルCAを作りhostsで独自ドメインを割り当ててVite・Next.js・Dockerで使う手順を解説。証明書警告を無視する癖の危険も理解できます。
- プログラミング
localhost・0.0.0.0・127.0.0.1の違い|ポートとUnixソケットを理解して「つながらない」を解決
localhost・127.0.0.1・0.0.0.0の意味の違い、Dockerで外から接続できない原因、host.docker.internal、ポート競合の調べ方、Unixソケットの利点と権限、1024未満ポートの制約を解説。「つながらない」を仕組みから解決できます。
Harmonic Society
「読んで終わり」にせず、自社の業務で試してみませんか?
AI・ローカルLLM・クラウドの導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK・売り込みなし。
無料・30分・オンラインOK|1営業日以内に返信します