Skip to content

p2p: remove adjusted time #25908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed

Conversation

fanquake
Copy link
Member

After recent refactoring, the changes required to remove adjusted time are now quite straight forward. This PR removes the notion of adjusted time, along with the -maxtimeadjustment option. It doesn't do any other cleanup.

Opening for discussion of gotchas / brainstorming / concept (N)ACKs.

1 question from a reviewer was whether we should keep some sort of warning around for if our clock differs too much from our peers. Although it's unclear how useful that might be.

Commits can be cleaned up / sqaushed. Missing release notes etc.
Would close #4521.

@fanquake fanquake force-pushed the remove_adjusted_time branch from fae674e to 6a860cd Compare August 23, 2022 10:28
@fanquake fanquake changed the title [WIP] p2p: remove adjusted time p2p: remove adjusted time Aug 23, 2022
@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 23, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK naumenkogs, MarcoFalke, dergoegge, darosior

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #27534 (rpc: add 'getnetmsgstats', new rpc to view network message statistics by satsie)
  • #27491 (refactor: Move chain constants to the util library by TheCharlatan)
  • #26966 (index: blockfilter initial sync speedup, parallelize process by furszy)
  • #26621 (refactor: Continue moving application data from CNode to Peer by dergoegge)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@naumenkogs
Copy link
Member

Concept ACK, light code review ACK.

@@ -638,7 +636,6 @@ static RPCHelpMan getnetworkinfo()
if (node.peerman) {
obj.pushKV("localrelay", !node.peerman->IgnoresIncomingTxs());
}
obj.pushKV("timeoffset", GetTimeOffset());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe keep this field and instead return the median offset of the currently connected outbounds or so? See also #24606 (comment)

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK, but there should be an easy way for users to figure out if their clock is wrong, ideally at startup or early after startup. It wouldn't be the best UX if they found out by going out of consensus or by seeing their mined blocks be dropped.

// harder for others to tamper with our adjusted time.
AddTimeData(pfrom.addr, nTimeOffset);
}
pfrom.nTimeOffset = nTime - GetTime();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps:

if (!pfrom.IsInboundConn() && std::abs(pfrom.nTimeOffset) >= 1800) {
    ++m_bad_non_inbound_time_offset;
    if (m_bad_non_inbound_time_offset == 3) {
        SetMiscWarning("Please check your computer's date and time are correct");
    }
}

(ie, add a counter to PeerManagerImpl, and on the third outbound connection that has a time offset of 30mins or more, set a warning that will show up in getblockchaininfo, getnetworkinfo, getmininginfo until restart)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we regularly do new feeler and blocks-only connections, perhaps we could keep a rolling average of abs(peer.nTimeOffset) and report that in getnetworkinfo?

@dergoegge
Copy link
Member

Concept ACK

Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By removing the adjustement of our local clock time on the median of offsets from peers clocks, we're lowering the robustness of our operational time against time shifting attacks where an adversary shifts the local time of the host NTP client backward/forward. Before, this change even if the clock drifts, it's at least corrected in the bound of DEFAULT_MAX_TIME_ADJUSTEMENT. After, this change if the clock is controlled by malicious timeservers, I don't think there is corrective action or even warnings issued towards the operators.

With most of Linux distributions, the local time at a client is determined based on the clock readings received from timeservers from the NTP pool, an open set of public servers, segmented in geographical zones for load-balancing. It should be noted the policy of this pool recommends one to distrust time provided if high reliability is sought. An adversary could either fulfill the pool with crappy servers or exploit one of the unpatched vulnerabilities as the high-stratum servers are likely randomly maintained due to being run by volunteers.

For block consensus validation, we're relying on clock time accuracy w.r.t honest network of peers, a block timestamp too far in the future from the viewpoint of the local clock will be rejected (L3472 in ContextualCheckBlockHeader()). A successful time shifting attack against your time could fork you off from the network and from then escalate to a time-dilation attack variant against your Lightning node.

While I think this is valuable to overhaul or remove GetAdjustedTime(), I would prefer first that we introduce a warning system based on discrepancies between local clock and outbound peers ones, or allocate more thoughts if we can come up with better mitigations against NTP attacks at the application-level.

cc @TheBlueMatt @naumenkogs with whom I had discussions in the past on how fucking up with your NTP syncing can compromise your Lightning node funds security.

@maflcko
Copy link
Member

maflcko commented Oct 2, 2022

Before, this change even if the clock drifts, it's at least corrected in the bound of DEFAULT_MAX_TIME_ADJUSTEMENT.

No correction will happen if your time drifts and you only ever cycle through at most 4 distinct honest outbound connections. Also, no correction will happen if your time drifts after you made more than BITCOIN_TIMEDATA_MAX_SAMPLES/2+1 distinct honest outbound connections. Instead of a false promise that adjusted time will correct an incorrect system clock, it would be better for the system operator to correct the system clock.

I don't see a way that adjusted time can be helping some without also harming others. Every instance where it provides a "fix" for some users, it opens the attack surface for users that are not affected by the problem. For example, if an attacker can influence enough (not all) outgoing connections of your node, they can likely get you out of consensus with a perfectly synced system clock. This also breaks the assumption that a single honest connection would be sufficient for you to stay in consensus.

@ariard
Copy link

ariard commented Oct 7, 2022

No correction will happen if your time drifts and you only ever cycle through at most 4 distinct honest outbound connections. Also, no correction will happen if your time drifts after you made more than BITCOIN_TIMEDATA_MAX_SAMPLES/2+1 distinct honest outbound connections. Instead of a false promise that adjusted time will correct an incorrect system clock, it would be better for the system operator to correct the system clock.

From my understanding, there is at least a correction brought to your system clock once you have at most 4 distinct honest outbound connections and before you have made more than BITCOIN_TIMEDATA_MAX_SAMPLES/2+1, which I think made my point correct that the existence of a correction hardens the attack game for an adversary targeting your NTP syncing, even minimally. Noting this correction is featherweight if you're facing an adversary with BGP capabilities, I don't deny it.

I would agree a better protection would be effectively for the system operator to correct the system clock, a good question being if we can achieve this at the bitcoind-level with a warning system potentially based on peers clocks, or we should recommend high-stakes users to be their own stratum 0 servers, and directly get time from GPS or a non-Internet time source.

For example, if an attacker can influence enough (not all) outgoing connections of your node, they can likely get you out of consensus with a perfectly synced system clock.

Assuming you're starting with a perfectly synced system clock, as we're bounded with DEFAULT_MAX_TIME_ADJUSTEMENT, of an effective value of 70min, the attacker won't be able to make you reject block due to seen timestamp being too far in the future. From my comprehension, current adjusted time does not break the assumption that a single honest connection would be sufficient to stay in consensus.

@maflcko
Copy link
Member

maflcko commented Oct 7, 2022

They could delay your time by 70min and then mine blocks 2h ahead (or advance the time of another miner by 70min), which would make you lag on consensus and throw away your hashrate (if you have any) for as long as the latest block is too far ahead.

@darosior
Copy link
Member

Concept ACK.

@fanquake fanquake force-pushed the remove_adjusted_time branch from 769a6af to 8f3b09e Compare March 23, 2023 15:26
@DrahtBot
Copy link
Contributor

DrahtBot commented May 9, 2023

🐙 This pull request conflicts with the target branch and needs rebase.

@fanquake fanquake force-pushed the remove_adjusted_time branch from d29b81e to 644f93f Compare May 17, 2023 15:03
@fanquake fanquake closed this May 17, 2023
achow101 added a commit that referenced this pull request Jan 31, 2024
ff9039f Remove GetAdjustedTime (dergoegge)

Pull request description:

  This picks up parts of #25908.

  The use of adjusted time is removed from validation code while the warning to users if their clock is out of sync with the rest of the network remains.

ACKs for top commit:
  naumenkogs:
    ACK ff9039f
  achow101:
    ACK ff9039f
  maflcko:
    lgtm ACK ff9039f 🤽
  stickies-v:
    ACK ff9039f

Tree-SHA512: d1f6b9445c236915503fd2ea828f0d3b92285a5dbc677b168453276115e349972edbad37194d8becd9136d8e7219b576af64ec51c72bdb1923e57e405c0483fc
@fanquake fanquake deleted the remove_adjusted_time branch April 4, 2024 13:30
@bitcoin bitcoin locked and limited conversation to collaborators Apr 4, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AddTimeData will never update nTimeOffset past 199 samples
8 participants