Query a roughtime server to mitigate NTP attacks (#3151)

This commit is contained in:
Jean-André Santoni
2019-08-09 21:05:08 +07:00
committed by terence tsao
parent d860dbbb60
commit e1dfe73525
5 changed files with 115 additions and 1 deletions

View File

@@ -1260,3 +1260,16 @@ go_repository(
commit = "11bc5ee7ad5de4bf1380f3103eebdd40db99a666",
importpath = "github.com/prysmaticlabs/ethereumapis",
)
go_repository(
name = "com_github_cloudflare_roughtime",
commit = "6b7e31ac9cb2d6048096585d2e8563ee60b28f84",
importpath = "github.com/cloudflare/roughtime",
)
go_repository(
name = "com_googlesource_roughtime_roughtime_git",
build_file_generation = "on",
commit = "51f6971f5f06ec101e5fbcabe5a49477708540f3",
importpath = "roughtime.googlesource.com/roughtime.git",
)

View File

@@ -0,0 +1,12 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["roughtime.go"],
importpath = "github.com/prysmaticlabs/prysm/shared/roughtime",
visibility = ["//visibility:public"],
deps = [
"@com_github_cloudflare_roughtime//:go_default_library",
"@com_googlesource_roughtime_roughtime_git//go/config:go_default_library",
],
)

View File

@@ -0,0 +1,86 @@
// Package roughtime is a wrapper for a roughtime clock source
package roughtime
import (
"encoding/base64"
"time"
rt "github.com/cloudflare/roughtime"
"roughtime.googlesource.com/roughtime.git/go/config"
)
// offset is the difference between the system time and the time returned by
// the roughtime server
var offset time.Duration
// Decode or panic
func mustDecodeString(in string) []byte {
pk, err := base64.StdEncoding.DecodeString(in)
if err != nil {
panic(err)
}
return pk
}
func init() {
t0 := time.Now()
// A list of reliable roughtime servers with their public keys.
// From https://github.com/cloudflare/roughtime/blob/master/ecosystem.json
servers := []config.Server{
{
Name: "Caesium",
PublicKeyType: "ed25519",
PublicKey: mustDecodeString("iBVjxg/1j7y1+kQUTBYdTabxCppesU/07D4PMDJk2WA="),
Addresses: []config.ServerAddress{
{
Protocol: "udp",
Address: "caesium.tannerryan.ca:2002",
},
},
},
{
Name: "Chainpoint-Roughtime",
PublicKeyType: "ed25519",
PublicKey: mustDecodeString("bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE="),
Addresses: []config.ServerAddress{
{
Protocol: "udp",
Address: "roughtime.chainpoint.org:2002",
},
},
},
{
Name: "Cloudflare-Roughtime",
PublicKeyType: "ed25519",
PublicKey: mustDecodeString("gD63hSj3ScS+wuOeGrubXlq35N1c5Lby/S+T7MNTjxo="),
Addresses: []config.ServerAddress{
{
Protocol: "udp",
Address: "roughtime.cloudflare.com:2002",
},
},
},
}
results := rt.Do(servers, rt.DefaultQueryAttempts, rt.DefaultQueryTimeout, nil)
// Compute the average difference between the system's time and the
// Roughtime responses from the servers, rejecting responses whose radii
// are larger than 2 seconds.
var err error
offset, err = rt.AvgDeltaWithRadiusThresh(results, t0, 2*time.Second)
if err != nil {
panic(err)
}
}
// Since returns the duration since t, based on the roughtime response
func Since(t time.Time) time.Duration {
return time.Now().Add(offset).Sub(t)
}
// Until returns the duration until t, based on the roughtime response
func Until(t time.Time) time.Duration {
return t.Sub(time.Now().Add(offset))
}

View File

@@ -5,6 +5,7 @@ go_library(
srcs = ["slotticker.go"],
importpath = "github.com/prysmaticlabs/prysm/shared/slotutil",
visibility = ["//visibility:public"],
deps = ["//shared/roughtime:go_default_library"],
)
go_test(

View File

@@ -2,6 +2,8 @@ package slotutil
import (
"time"
"github.com/prysmaticlabs/prysm/shared/roughtime"
)
// SlotTicker is a special ticker for the beacon chain block.
@@ -34,7 +36,7 @@ func GetSlotTicker(genesisTime time.Time, secondsPerSlot uint64) *SlotTicker {
c: make(chan uint64),
done: make(chan struct{}),
}
ticker.start(genesisTime, secondsPerSlot, time.Since, time.Until, time.After)
ticker.start(genesisTime, secondsPerSlot, roughtime.Since, roughtime.Until, time.After)
return ticker
}