Commit Graph

7 Commits

Author SHA1 Message Date
Azat Khuzhin
3e68103ac8 Fix interserver secret for Distributed over Distributed from remote()
Right if you are executing remote() and later the query will
go to the cluster with interserver secret, then you should have the same
user on the nodes from that cluster, otherwise the query will fail with:

    DB::NetException: Connection reset by peer

And on the remote node:

    <Debug> TCPHandler: User (initial, interserver mode): new_user (client: 172.16.1.5:40536)
    <Debug> TCP_INTERSERVER-Session: d29ecf7d-2c1c-44d2-8cc9-4ab08175bf05 Authentication failed with error: new_user: Authentication failed: password is incorrect, or there is no user with such name.
    <Error> ServerErrorHandler: Code: 516. DB::Exception: new_user: Authentication failed: password is incorrect, or there is no user with such name. (AUTHENTICATION_FAILED), Stack trace (when copying this message, always include the lines below):

The problem is that remote() will not use passed to it user in
any form, and instead, the initial user will be used, i.e. "cli_user"
not "query_user":

    chc --user cli_user -q "select * from remote(node, default, some_dist_table, 'query_user')"

Fix this by using the user from query for the remote().

Note, that the Distributed over Distributed in case of tables still wont
work, for this you have to have the same users on all nodes in all
clusters that are involved in case of interserver secret is enabled (see
also test).

Signed-off-by: Azat Khuzhin <a.khuzhin@semrush.com>

v2: move client initial_user adjustment into ClusterProxy/executeQuery.cpp
v3: we cannot check for interserver_mode in
    updateSettingsAndClientInfoForCluster() since it is not yet
    interserver in remote() context
2024-04-29 07:12:17 +02:00
Azat Khuzhin
bcf381c5ae Reimplement interserver mode to avoid replay attacks
Prevous implementation (DBMS_MIN_REVISION_WITH_INTERSERVER_SECRET)
accepts the salt from the client, which make it useless.

Reimplement the protocol to send the salt by the server and use it in
the client instead.

Signed-off-by: Azat Khuzhin <a.khuzhin@semrush.com>
2023-03-15 08:28:43 +01:00
Alexey Milovidov
b42d26acfe Remove one line from XML, because we do not care 2022-08-28 02:44:02 +02:00
Vitaly Baranov
27f6d5864d
Merge pull request #29060 from azat/inter-server-secret-auth-fix
Do not allow to reuse previous credentials in case of inter-server secret
2021-10-01 20:44:48 +03:00
Azat Khuzhin
1af02f02bd Add a test for INSERT w/o user in interserver mode
v2: ensure that the test fails with the version w/o fix
v3: force connect by modifying config and reload it
v4: add comments
2021-10-01 01:13:08 +03:00
Alexey Milovidov
e513a5db32 Change <yandex> to <clickhouse> in configs 2021-09-20 01:38:53 +03:00
Azat Khuzhin
0159c74f21 Secure inter-cluster query execution (with initial_user as current query user) [v3]
Add inter-server cluster secret, it is used for Distributed queries
inside cluster, you can configure in the configuration file:

  <remote_servers>
      <logs>
          <shard>
              <secret>foobar</secret> <!-- empty -- works as before -->
              ...
          </shard>
      </logs>
  </remote_servers>

And this will allow clickhouse to make sure that the query was not
faked, and was issued from the node that knows the secret. And since
trust appeared it can use initial_user for query execution, this will
apply correct *_for_user (since with inter-server secret enabled, the
query will be executed from the same user on the shards as on initator,
unlike "default" user w/o it).

v2: Change user to the initial_user for Distributed queries if secret match
v3: Add Protocol::Cluster package
v4: Drop Protocol::Cluster and use plain Protocol::Hello + user marker
v5: Do not use user from Hello for cluster-secure (superfluous)
2020-09-15 01:36:28 +03:00