Giter VIP home page Giter VIP logo

roughtime's Introduction

Roughtime

A fork of Google's Roughtime protocol and utilities for building Roughtime clients. This repository also implements the IETF version.

For more information about Roughtime and tips for writing your own client or server, visit the developer documentation.

Note on status

This repository currently supports draft-ietf-ntp-roughtime-08. Backwards compatibility with this version is not guaranteed; users should expect breaking changes as the IETF process continues. Likewise, the API should be regarded as unstable.

If you want to use this code and the protocol please join the NTP WG mailing list so that you are aware of the evolution of the protocol and issues that others discover.

** DO NOT USE IN PRODUCTION SOFTWARE **

Ecosystem guidelines

We welcome pull requests for adding your Roughtime service to our list. Your PR should do the following:

  • Add your server's configuration to ecosystem.json. The list of servers will be alphabetized by the "name" field.

  • Add some information about your service to ecosystem.md. (This is also kept in alphabetical order.) This should include details about how your service is provisioned:

    1. how you synchronize your server's clock;
    2. if your code is open source, a link to the code;
    3. where in the world your server is located; and
    4. whether you will guarantee up time, and if so, how you will do so.
    5. what version you run
  • Generate the ecosystem.json.go from the ecosystem.json. Use the go generate command for this.

A couple things to keep in mind:

  • To be healthy, the Roughtime ecosystem needs a diverse set of time sources. The list already contains servers that are synced with Google's NTP servers; as such, servers that expose new sources will be preferred. (An atomic clock would be cool!)

  • We reserve the right to prune this list at any time. (For example, if a server is unreliable, or its root secret key has been compromised.)

  • As new versions come out we may prune servers that do not update.

Finally, a disclaimer: the ecosystem is growing, and ours might not be the definitive list of who is serving Roughtime at any given time.

Contributing

We welcome your bug fixes, issues, and improvements to either the protocol or this code. Note that substantive changes to the protocol need to be discussed on the NTP WG mailing list.

roughtime's People

Contributors

bluecmd avatar cjpatton avatar crooks avatar dependabot[bot] avatar gabbifish avatar int08h avatar jamesits avatar kivutar avatar lekensteyn avatar lukevalenta avatar marek22k avatar mdr164 avatar skillful-alex avatar tannerryan avatar vadiminshakov avatar wbl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

roughtime's Issues

Support IPv6 only connectivity

Hi,

I have a host that may only have IPv6 external connectivity, or only IPv4, or both.

The serverUDPAddr function will always resolve to IPv4 addresses, even if there is no default route or any sign of external connectivity. Ideally, having a server that is capable of both IPv4 and IPv6 one should be tried and then if that doesn't work it should try with the other. Right now, only IPv4 will be tried.

Example where the DNS resolution works since the system uses IPv6 DNS resolvers, but roughtime is not able to connect:

1970/01/01 00:11:02 Failed to get roughtime from roughtime.sandbox.google.com:2002 (skipping): dial udp 64.233.164.158:2002: connect: network is unreachable

Can we hardcode roughtime IP?

Hi all,

A common problem faced by many is that DNS-over-HTTPS won't work if your clock is wrong, and you can't fix your clock because you can't resolve NTP domain names to IPs. The same problem seems to be present with roughtime - we can't connect to roughtime server if we can't resolve the roughtime domain names to IPs.

Is it possible to get a roughtime IP that we can just hardcode?

Thanks a lot.

Client is incompatible with existing servers (was "No reply from any roughtime server")

I've tried to get started with roughtime, but I couldn't get a response from any of the listed ecosystem servers. I've also tried this from multiple machines/locations. Cloudflarestatus.com states that Cloudflare's Roughtime server is operational. Any idea why this isn't working?

$ go run ./getroughtime/main.go -ping roughtime.cloudflare.com:2002 -pubkey gD63hSj3ScS+wuOeGrubXlq35N1c5Lby/S+T7MNTjxo=
ping error: no reply
exit status 1
$ go run ./recipes/tls.go
skipped Chainpoint-Roughtime: no reply
skipped Cloudflare-Roughtime: no reply
skipped Google-Sandbox-Roughtime: no reply
skipped int08h-Roughtime: no reply
skipped ticktock: no reply
skipped time.0xt.ca: no reply
no valid responses
exit status 1

large difference in deltas from 1st and 2nd runs with alerter

Looking into this code and idea I was trying out the alerter recipe
and I'm seeing around a 250ms difference in 1st and 2nd runs of the program run in rapid succession
below is output from 1 such run, not sure how much time is needed to wait for it to reset and give similar results, 10ish or less minutes
I'm still not understanding code fully but I did notice in client.go line 323 says to "Reset the delay accumulator."
but code on following line doesn't feel like a reset is happening, perhaps that's the issue?

chronus-pi ~ # ./alerter -rt go/src/github.com/cloudflare/roughtime/ecosystem.config
2018/09/21 client.go:272: Cloudflare-Roughtime: 2018-09-21 21:10:52.191 -0700 PDT ±1s (in 74ms)
2018/09/21 client.go:272: Google-Sandbox-Roughtime: 2018-09-21 21:10:52.304921 -0700 PDT ±1s (in 100ms)
2018/09/21 client.go:272: int08h-Roughtime: 2018-09-21 21:10:52.401288 -0700 PDT ±1s (in 111ms)
2018/09/21 alerter.go:60: delta: 148ms
chronus-pi ~ # ./alerter -rt go/src/github.com/cloudflare/roughtime/ecosystem.config
2018/09/21 client.go:272: Cloudflare-Roughtime: 2018-09-21 21:10:53.711 -0700 PDT ±1s (in 73ms)
2018/09/21 client.go:272: Google-Sandbox-Roughtime: 2018-09-21 21:10:53.821151 -0700 PDT ±1s (in 92ms)
2018/09/21 client.go:272: int08h-Roughtime: 2018-09-21 21:10:53.907014 -0700 PDT ±1s (in 103ms)
2018/09/21 alerter.go:60: delta: -17ms

Vendor error when using client library

Hi,

I'm trying to use your server library, but running into vendoring issues.

You're expecting a roughtime.googlesource.com/go/config.Server as input to e.g. roughtime.Get. When I'm trying to use it like this:

package ttime

import (
	"log"
	"time"

	"github.com/cloudflare/roughtime"
	"golang.org/x/sync/errgroup"
	"roughtime.googlesource.com/go/config"
)

const (
	KEY_TYPE_ED25519 = "ed25519"
	roughtimeAttempts = 3
	roughtimeTimeout = 15 * time.Second
)

type RoughtimeServer struct {
	Protocol      string
	Address       string
	PublicKey     string
	PublicKeyType string
}

type NtpServer string

func getOneRoughtime(rs []RoughtimeServer) (*roughtime.Roughtime) {
	var g errgroup.Group
	cr := make(chan *roughtime.Roughtime, len(rs))
	for _, r := range rs {
		srv := &config.Server{
			Name: r.Address,
			PublicKeyType: r.PublicKeyType,
			PublicKey: []byte(r.PublicKey),
			Addresses: []config.ServerAddress{
				config.ServerAddress{Protocol: r.Protocol, Address: r.Address},
			},}
		g.Go(func() error {
			res, err := roughtime.Get(srv, roughtimeAttempts, roughtimeTimeout, nil)
			if err != nil {
				log.Printf("Failed to get roughtime from %s (skipping): %v", err)
				return err
			}
			cr <- res
			return nil
		})
	}

	go func() {
		// In the case of an error, put a nil in on the queue to ensure that
		// this function never deadlocks
		if err := g.Wait(); err != nil {
			cr <- nil
		}
	}()

	return <-cr
}

With roughtime.googlesource.com/go/config in my vendor directory, I get this:

./roughtime.go:43:29: cannot use srv (type *"github.com/u-root/u-bmc/vendor/roughtime.googlesource.com/go/config".Server) as type *"github.com/cloudflare/roughtime/vendor/roughtime.googlesource.com/go/config".Server in argument to roughtime.Get

Do you have any ideas on how to solve this?

Prune dead servers from `ecosystem.json`

Some servers appear to be down:

[master][~/github.com/cloudflare/roughtime]$ go run ./cmd/getroughtime -config ecosystem.json
skipped Chainpoint-Roughtime: no reply
Cloudflare-Roughtime: 2023-12-15 08:12:05.05 -0800 PST ±1s (in 38ms)
skipped Google-Sandbox-Roughtime: no reply
int08h-Roughtime: 2023-12-15 08:12:08.117072 -0800 PST ±1s (in 89ms)
skipped ticktock: no reply
time.txryan.com: 2023-12-15 08:12:11.225653 -0800 PST ±1s (in 110ms)
delta: 12ms

If they're permanently dead then they should be removed from the list. However we should try to reach out to the maintainers: It may be that they implement a version of Roughtime that we're not compatible with or they have moved their server to a different address.

Response with merkle tree of several requests

I am developing a roughtime client for a major cryptographic library and I am unable to get a response which contains a merkle tree of several requests. I imagine my point of presence (both Google and Cloudflare) are under used and I always get a individual signature.

Is there a good time of day or point of the globe where I can typically obtain such answers?

Or can someone get me a request-response dump?

Thanks!

possible to get signed server lists?

i want to be able to audit a chain of times produced by someone else

the docs say that clients need to dynamically pull lists of servers and to never hardcode trust or expect any particular server to exist

so how do i know that someone else's chain of times wasn't simply generated by themselves to point at a list of servers they control?

is there some way that i can ask them to provide a signed whitelist of servers, so that i can at least choose to trust the whitelist itself? that way, even if the whitelist is dynamic and arbitrary i can verify the source

i had a look here - https://github.com/cloudflare/roughtime/blob/master/ecosystem.json - and i only see keys of servers, i don't see any signature for the json itself

Improvements for generating `ecoysystem.json.go`

As described in #15, the idea is to convert ecosystem.json to a version readily consumable in Go. Ideas for improvements:

  1. Use go generate to run it. This seems to have been the original intent, but it currently doesn't work.
  2. Move to an internal package, similar to protocol/internal/cmd/gen_test_vectors.go.

Cloudflare's roughtime broken?

Not sure where to report this, but I'm having trouble interregating your roughtime server:

2018/10/02 21:47:43 Failed to get roughtime from roughtime.cloudflare.org:2002 (skipping): lookup roughtime.cloudflare.org on 8.8.8.8:53: server misbehaving

The first error can be an DNS error on my part, but it also doesn't work on my laptop:

[bluecmd]$ go/bin/getroughtime -ping roughtime.cloudflare.com:2002 -pubkey gD63hSj3ScS+wuOeGrubXlq35N1c5Lby/S+T7MNTjxo=
ping error: no reply
[bluecmd]$ ping roughtime.cloudflare.com
PING roughtime.cloudflare.com (104.19.195.151) 56(84) bytes of data.
64 bytes from 104.19.195.151: icmp_seq=1 ttl=58 time=7.79 ms
64 bytes from 104.19.195.151: icmp_seq=2 ttl=58 time=9.00 ms

Compare with:

[bluecmd]$ go/bin/getroughtime -ping roughtime.sandbox.google.com:2002 -pubkey etPaaIxcBMY1oUeGpwvPMCJMwlRVNxv51KK/tktoJTQ=
ping response: 2018-10-02 23:50:22.775003 +0200 CEST ±1s (in 70ms)

`Chain.Verify()` fails with mixture of Roughtime versions

To reproduce:

Start a couple of Roughtime servers:

$ go run ./cmd/testserver -addr 127.0.0.1:2002
main.go:64: Root public key: sm2tho24GOkdU26vpQInrruJKumCEDLCVHTArPBPqDY=
go run ./cmd/testserver -addr 127.0.0.1:2003
main.go:64: Root public key: bPDagpXQCofeGLeu8GwrX2CQ5Udy8rk1ziiFJGowZIw=

Then create a configuration file for which the client will try IETF-Roughitme for one server but not the other:

{
  "servers": [
    {
      "name": "server1",
      "version": "IETF-Roughtime",
      "publicKeyType": "ed25519",
      "publicKey": "sm2tho24GOkdU26vpQInrruJKumCEDLCVHTArPBPqDY=",
      "addresses": [
        {
          "protocol": "udp",
          "address": "127.0.0.1:2002"
        }
      ]
    },
    {
      "name": "server2",
      "publicKeyType": "ed25519",
      "publicKey": "bPDagpXQCofeGLeu8GwrX2CQ5Udy8rk1ziiFJGowZIw=",
      "addresses": [
        {
          "protocol": "udp",
          "address": "127.0.0.1:2003"
        }
      ]
    }
  ]
}

Finally, test this as follows:

package main

import (
	"testing"

	"github.com/cloudflare/roughtime/client"
)

func TestRoughtimeServer(t *testing.T) {
	results, err := client.DoFromFile("devdata/config/client.config", client.DefaultQueryAttempts, client.DefaultQueryTimeout, nil)
	if err != nil {
		t.Fatal(err)
	}

	chain := client.NewChain(results)
	if chain == nil {
		t.Fatal("chain  == nil, want chin != nil")
	}

	ok, err := chain.Verify(nil)
	if err != nil {
		t.Errorf("verification fails: %s", err)
	} else if !ok {
		t.Error("chain not valid, want valid")
	}
}

You should see something like:

$ go test client_test.go
--- FAIL: TestRoughtimeServer (0.00s)
    client_test.go:24: verification fails: missing VER tag
FAIL
FAIL	command-line-arguments	0.407s
FAIL

It seems to me that it should be valid to chain together signed timestamps across versions, but this requires a bit of thought.

Client robustness to misbehaving server

Right now if a server misbehaves it can lead to the client averaging in the cheating offset, leading to high offsets.

What we should do instead is is validate the server responses first, store the offsets, then find the majority region and report any cheaters that are impeachable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.