75 lines
2.5 KiB
Elixir
75 lines
2.5 KiB
Elixir
defmodule Mix.Tasks.Totp.TimeCheck do
|
|
@shortdoc "Check server time and TOTP time synchronization"
|
|
|
|
@moduledoc """
|
|
Diagnostic tool to check if the server's clock is correct.
|
|
|
|
Usage:
|
|
mix totp.time_check
|
|
|
|
This will:
|
|
1. Show the server's current time (BEAM VM time)
|
|
2. Show the system's current time
|
|
3. Calculate what TOTP codes should be valid right now for a test secret
|
|
"""
|
|
|
|
use Mix.Task
|
|
|
|
require Logger
|
|
|
|
def run(_args) do
|
|
Mix.Task.run("app.start")
|
|
|
|
IO.puts("\n=== Time Synchronization Check ===\n")
|
|
|
|
# Get different time sources
|
|
system_time = System.system_time(:second)
|
|
os_time = :os.system_time(:second)
|
|
datetime_now = DateTime.utc_now()
|
|
|
|
IO.puts("System.system_time(:second): #{system_time}")
|
|
IO.puts(" → #{DateTime.from_unix!(system_time)}")
|
|
IO.puts("")
|
|
IO.puts(":os.system_time(:second): #{os_time}")
|
|
IO.puts(" → #{DateTime.from_unix!(os_time)}")
|
|
IO.puts("")
|
|
IO.puts("DateTime.utc_now(): #{datetime_now}")
|
|
IO.puts(" → unix: #{DateTime.to_unix(datetime_now)}")
|
|
IO.puts("")
|
|
|
|
# Check if they match
|
|
if system_time == os_time and system_time == DateTime.to_unix(datetime_now) do
|
|
IO.puts("✓ All time sources agree")
|
|
else
|
|
IO.puts("⚠️ WARNING: Time sources disagree!")
|
|
IO.puts(" System vs OS diff: #{system_time - os_time} seconds")
|
|
IO.puts(" System vs DateTime diff: #{system_time - DateTime.to_unix(datetime_now)} seconds")
|
|
end
|
|
|
|
IO.puts("")
|
|
|
|
# Show what TOTP codes would be generated now
|
|
test_secret = NimbleTOTP.secret()
|
|
current_code = NimbleTOTP.verification_code(test_secret, time: system_time)
|
|
prev_code = NimbleTOTP.verification_code(test_secret, time: system_time - 30)
|
|
next_code = NimbleTOTP.verification_code(test_secret, time: system_time + 30)
|
|
|
|
IO.puts("Test TOTP codes (with random secret):")
|
|
IO.puts(" Current window: #{current_code}")
|
|
IO.puts(" Previous (-30s): #{prev_code}")
|
|
IO.puts(" Next (+30s): #{next_code}")
|
|
IO.puts("")
|
|
|
|
# Recommend action
|
|
IO.puts("=== Recommendations ===")
|
|
IO.puts("")
|
|
IO.puts("Compare the server time above with actual UTC time:")
|
|
IO.puts(" Current actual UTC: Run 'date -u' on your local machine")
|
|
IO.puts("")
|
|
IO.puts("If the server time is wrong:")
|
|
IO.puts(" 1. Check K8s node time: kubectl exec -it <pod> -- date -u")
|
|
IO.puts(" 2. Check if NTP is running on the node")
|
|
IO.puts(" 3. Restart the pod to resync time")
|
|
IO.puts("")
|
|
end
|
|
end
|