Skip to content
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

perf(federation): (re) Ed25519署名に対応する #14278

Draft
wants to merge 38 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0c9af9a
Revert "revert 5f88d56d96"
tamaina Jul 20, 2024
69bf858
admin/show-userで公開鍵(リモートユーザー)/秘密鍵公開鍵ペア(ローカルユーザー)を確認できるように
tamaina Jul 20, 2024
9e958c0
update res props @ admin/show-user
tamaina Jul 20, 2024
5ccc9d6
update res props @ admin/show-user
tamaina Jul 20, 2024
307e1c4
short cache ttl 12min → 5min
tamaina Jul 20, 2024
73e3427
autogen
tamaina Jul 20, 2024
dd8561f
modify InboxProcessorService
tamaina Jul 20, 2024
018f058
not skip
tamaina Jul 20, 2024
dd41dd0
remoteUserUpdatedでpublicKeyキャッシュを削除するように
tamaina Jul 20, 2024
88085fd
deliverでinboxに投げて401が返ってきた場合、時計が狂っている場合があるためリトライできるように
tamaina Jul 20, 2024
7503fc8
HTTP署名パースにおいてDateとサーバー時間のズレは両方向に300sを許容するように
tamaina Jul 20, 2024
1721c39
Merge branch 'develop' into re-ed25519
tamaina Jul 31, 2024
cf7b8ab
Update packages/backend/src/core/QueueService.ts
tamaina Jul 31, 2024
ac4e0dd
Update packages/backend/src/core/QueueService.ts
tamaina Jul 31, 2024
f67b268
Merge branch 'develop' into re-ed25519
tamaina Jul 31, 2024
4477f95
Merge branch 'develop' into re-ed25519
tamaina Aug 17, 2024
2a43258
fix conflict
tamaina Aug 17, 2024
d01cd15
Merge branch 'develop' into re-ed25519
tamaina Aug 18, 2024
e4b4e91
fix
tamaina Aug 18, 2024
40e08c7
Merge branch 'develop' into re-ed25519
tamaina Sep 9, 2024
be86213
Merge branch 'develop' into re-ed25519
tamaina Sep 9, 2024
61d5371
Merge branch 'develop' into re-ed25519
tamaina Sep 21, 2024
97cdde1
Merge branch 'develop' into re-ed25519
tamaina Sep 24, 2024
1c3f1a6
modosu
tamaina Sep 24, 2024
1b9494c
Revert "modosu"
tamaina Sep 24, 2024
1560646
Merge branch 'develop' into re-ed25519
tamaina Sep 26, 2024
fb6a979
Merge branch 'develop' into re-ed25519
tamaina Sep 26, 2024
310b3a5
Merge branch 'develop' into re-ed25519
tamaina Sep 26, 2024
c137167
Merge branch 'develop' into re-ed25519
tamaina Sep 29, 2024
3254297
Merge branch 'develop' into re-ed25519
tamaina Sep 29, 2024
585f77a
Merge branch 'develop' into re-ed25519
tamaina Oct 5, 2024
354a377
Merge branch 'develop' into re-ed25519
tamaina Oct 8, 2024
2d17315
Merge branch 'develop' into re-ed25519
tamaina Oct 15, 2024
bf8073e
fix lint (possibly 'null
tamaina Oct 15, 2024
c619825
Merge branch 'develop' into re-ed25519
tamaina Oct 29, 2024
d7aeebc
Merge branch 'develop' into re-ed25519
tamaina Nov 9, 2024
e211284
Merge branch 'develop' into re-ed25519
tamaina Nov 11, 2024
40756dc
Merge branch 'develop' into re-ed25519
tamaina Nov 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .config/docker_example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@ id: 'aidx'
#clusterLimit: 1

# Job concurrency per worker
# deliverJobConcurrency: 128
# inboxJobConcurrency: 16
# deliverJobConcurrency: 16
# inboxJobConcurrency: 4

# Job rate limiter
# deliverJobPerSec: 128
# inboxJobPerSec: 32
# inboxJobPerSec: 64

# Job attempts
# deliverJobMaxAttempts: 12
Expand Down
8 changes: 4 additions & 4 deletions .config/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,15 @@ id: 'aidx'
#clusterLimit: 1

# Job concurrency per worker
#deliverJobConcurrency: 128
#inboxJobConcurrency: 16
#deliverJobConcurrency: 16
#inboxJobConcurrency: 4
#relationshipJobConcurrency: 16
# What's relationshipJob?:
# Follow, unfollow, block and unblock(ings) while following-imports, etc. or account migrations.

# Job rate limiter
#deliverJobPerSec: 128
#inboxJobPerSec: 32
#deliverJobPerSec: 1024
#inboxJobPerSec: 64
#relationshipJobPerSec: 64

# Job attempts
Expand Down
8 changes: 4 additions & 4 deletions .devcontainer/devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,12 @@ id: 'aidx'
#clusterLimit: 1

# Job concurrency per worker
# deliverJobConcurrency: 128
# inboxJobConcurrency: 16
# deliverJobConcurrency: 16
# inboxJobConcurrency: 4

# Job rate limiter
# deliverJobPerSec: 128
# inboxJobPerSec: 32
# deliverJobPerSec: 1024
# inboxJobPerSec: 64

# Job attempts
# deliverJobMaxAttempts: 12
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
- Feat: 通報を受けた際、または解決した際に、予め登録した宛先に通知を飛ばせるように(mail or webhook) #13705
- Feat: ユーザーのアイコン/バナーの変更可否をロールで設定可能に
- 変更不可となっていても、設定済みのものを解除してデフォルト画像に戻すことは出来ます
- Feat: 連合に使うHTTP SignaturesがEd25519鍵に対応するように #13464
- Ed25519署名に対応するサーバーが増えると、deliverで要求されるサーバーリソースが削減されます
- ジョブキューのconfig設定のデフォルト値を変更しました。
default.ymlでジョブキューの並列度を設定している場合は、従前よりもconcurrencyの値をより下げるとパフォーマンスが改善する可能性があります。
* deliverJobConcurrency: 16 (←128)
* deliverJobPerSec: 1024 (←128)
* inboxJobConcurrency: 4 (←16)
* inboxJobPerSec: 64 (←32)
- Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正
- Fix: Dockerコンテナの立ち上げ時に`pnpm`のインストールで固まることがある問題
- Fix: デフォルトテーマに無効なテーマコードを入力するとUIが使用できなくなる問題を修正
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ TODO
## Environment Variable

- `MISSKEY_CONFIG_YML`: Specify the file path of config.yml instead of default.yml (e.g. `2nd.yml`).
- `MISSKEY_WEBFINGER_USE_HTTP`: If it's set true, WebFinger requests will be http instead of https, useful for testing federation between servers in localhost. NEVER USE IN PRODUCTION.
- `MISSKEY_USE_HTTP`: If it's set true, federation requests (like nodeinfo and webfinger) will be http instead of https, useful for testing federation between servers in localhost. NEVER USE IN PRODUCTION. (was `MISSKEY_WEBFINGER_USE_HTTP`)

## Continuous integration
Misskey uses GitHub Actions for executing automated tests.
Expand Down
8 changes: 4 additions & 4 deletions chart/files/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,12 @@ id: "aidx"
#clusterLimit: 1

# Job concurrency per worker
# deliverJobConcurrency: 128
# inboxJobConcurrency: 16
# deliverJobConcurrency: 16
# inboxJobConcurrency: 4

# Job rate limiter
# deliverJobPerSec: 128
# inboxJobPerSec: 32
# deliverJobPerSec: 1024
# inboxJobPerSec: 64

# Job attempts
# deliverJobMaxAttempts: 12
Expand Down
39 changes: 39 additions & 0 deletions packages/backend/migration/1708980134301-APMultipleKeys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class APMultipleKeys1708980134301 {
name = 'APMultipleKeys1708980134301'

async up(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_171e64971c780ebd23fae140bb"`);
await queryRunner.query(`ALTER TABLE "user_keypair" ADD "ed25519PublicKey" character varying(128)`);
await queryRunner.query(`ALTER TABLE "user_keypair" ADD "ed25519PrivateKey" character varying(128)`);
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`);
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "PK_10c146e4b39b443ede016f6736d"`);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "PK_0db6a5fdb992323449edc8ee421" PRIMARY KEY ("userId", "keyId")`);
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "PK_0db6a5fdb992323449edc8ee421"`);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "PK_171e64971c780ebd23fae140bba" PRIMARY KEY ("keyId")`);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "UQ_10c146e4b39b443ede016f6736d" UNIQUE ("userId")`);
await queryRunner.query(`CREATE INDEX "IDX_10c146e4b39b443ede016f6736" ON "user_publickey" ("userId") `);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`);
await queryRunner.query(`DROP INDEX "public"."IDX_10c146e4b39b443ede016f6736"`);
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "UQ_10c146e4b39b443ede016f6736d"`);
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "PK_171e64971c780ebd23fae140bba"`);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "PK_0db6a5fdb992323449edc8ee421" PRIMARY KEY ("userId", "keyId")`);
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "PK_0db6a5fdb992323449edc8ee421"`);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "PK_10c146e4b39b443ede016f6736d" PRIMARY KEY ("userId")`);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "followersVisibility" DROP DEFAULT`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "followersVisibility" TYPE "public"."user_profile_followersVisibility_enum_old" USING "followersVisibility"::"text"::"public"."user_profile_followersVisibility_enum_old"`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "followersVisibility" SET DEFAULT 'public'`);
await queryRunner.query(`ALTER TABLE "user_keypair" DROP COLUMN "ed25519PrivateKey"`);
await queryRunner.query(`ALTER TABLE "user_keypair" DROP COLUMN "ed25519PublicKey"`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_171e64971c780ebd23fae140bb" ON "user_publickey" ("keyId") `);
}
}
16 changes: 16 additions & 0 deletions packages/backend/migration/1709242519122-HttpSignImplLv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class HttpSignImplLv1709242519122 {
name = 'HttpSignImplLv1709242519122'

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" ADD "httpMessageSignaturesImplementationLevel" character varying(16) NOT NULL DEFAULT '00'`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "httpMessageSignaturesImplementationLevel"`);
}
}
16 changes: 16 additions & 0 deletions packages/backend/migration/1709269211718-APMultipleKeysFix1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class APMultipleKeys1709269211718 {
name = 'APMultipleKeys1709269211718'

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "UQ_10c146e4b39b443ede016f6736d"`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "UQ_10c146e4b39b443ede016f6736d" UNIQUE ("userId")`);
}
}
2 changes: 1 addition & 1 deletion packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@
"@fastify/multipart": "8.3.0",
"@fastify/static": "7.0.4",
"@fastify/view": "9.1.0",
"@misskey-dev/node-http-message-signatures": "0.0.10",
"@misskey-dev/sharp-read-bmp": "1.2.0",
"@misskey-dev/summaly": "5.1.0",
"@napi-rs/canvas": "^0.1.53",
"@nestjs/common": "10.3.10",
"@nestjs/core": "10.3.10",
"@nestjs/testing": "10.3.10",
"@peertube/http-signature": "1.7.0",
"@sentry/node": "8.13.0",
"@sentry/profiling-node": "8.13.0",
"@simplewebauthn/server": "10.0.0",
Expand Down
82 changes: 0 additions & 82 deletions packages/backend/src/@types/http-signature.d.ts

This file was deleted.

5 changes: 5 additions & 0 deletions packages/backend/src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ export const MAX_NOTE_TEXT_LENGTH = 3000;
export const USER_ONLINE_THRESHOLD = 1000 * 60 * 10; // 10min
export const USER_ACTIVE_THRESHOLD = 1000 * 60 * 60 * 24 * 3; // 3days

export const REMOTE_USER_CACHE_TTL = 1000 * 60 * 60 * 3; // 3hours
export const REMOTE_USER_MOVE_COOLDOWN = 1000 * 60 * 60 * 24 * 14; // 14days

export const REMOTE_SERVER_CACHE_TTL = 1000 * 60 * 60 * 3; // 3hours

//#region hard limits
// If you change DB_* values, you must also change the DB schema.

Expand Down
27 changes: 21 additions & 6 deletions packages/backend/src/core/AccountUpdateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { DI } from '@/di-symbols.js';
import type { UsersRepository } from '@/models/_.js';
import type { MiUser } from '@/models/User.js';
Expand All @@ -12,30 +13,44 @@ import { RelayService } from '@/core/RelayService.js';
import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';
import type { PrivateKeyWithPem } from '@misskey-dev/node-http-message-signatures';

@Injectable()
export class AccountUpdateService {
export class AccountUpdateService implements OnModuleInit {
private apDeliverManagerService: ApDeliverManagerService;
constructor(
private moduleRef: ModuleRef,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

private userEntityService: UserEntityService,
private apRendererService: ApRendererService,
private apDeliverManagerService: ApDeliverManagerService,
private relayService: RelayService,
) {
}

async onModuleInit() {
this.apDeliverManagerService = this.moduleRef.get(ApDeliverManagerService.name);
}

@bindThis
public async publishToFollowers(userId: MiUser['id']) {
/**
* Deliver account update to followers
* @param userId user id
* @param deliverKey optional. Private key to sign the deliver.
*/
public async publishToFollowers(userId: MiUser['id'], deliverKey?: PrivateKeyWithPem) {
const user = await this.usersRepository.findOneBy({ id: userId });
if (user == null) throw new Error('user not found');

// フォロワーがリモートユーザーかつ投稿者がローカルユーザーならUpdateを配信
if (this.userEntityService.isLocalUser(user)) {
const content = this.apRendererService.addContext(this.apRendererService.renderUpdate(await this.apRendererService.renderPerson(user), user));
this.apDeliverManagerService.deliverToFollowers(user, content);
this.relayService.deliverToRelays(user, content);
await Promise.allSettled([
this.apDeliverManagerService.deliverToFollowers(user, content, deliverKey),
this.relayService.deliverToRelays(user, content, deliverKey),
]);
}
}
}
7 changes: 3 additions & 4 deletions packages/backend/src/core/CreateSystemUserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { randomUUID } from 'node:crypto';
import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs';
import { IsNull, DataSource } from 'typeorm';
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
import { genRSAAndEd25519KeyPair } from '@/misc/gen-key-pair.js';
import { MiUser } from '@/models/User.js';
import { MiUserProfile } from '@/models/UserProfile.js';
import { IdService } from '@/core/IdService.js';
Expand Down Expand Up @@ -38,7 +38,7 @@ export class CreateSystemUserService {
// Generate secret
const secret = generateNativeUserToken();

const keyPair = await genRsaKeyPair();
const keyPair = await genRSAAndEd25519KeyPair();

let account!: MiUser;

Expand All @@ -64,9 +64,8 @@ export class CreateSystemUserService {
}).then(x => transactionalEntityManager.findOneByOrFail(MiUser, x.identifiers[0]));

await transactionalEntityManager.insert(MiUserKeypair, {
publicKey: keyPair.publicKey,
privateKey: keyPair.privateKey,
userId: account.id,
...keyPair,
});

await transactionalEntityManager.insert(MiUserProfile, {
Expand Down
Loading
Loading