diff --git a/locales/en-US.yml b/locales/en-US.yml
index 0271a0b9bb..852013f8ba 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -154,6 +154,7 @@ renoteUnmute: "Unmute Boosts"
 block: "Block"
 unblock: "Unblock"
 markAsNSFW: "Mark all media from user as NSFW"
+markInstanceAsNSFW: "Mark as NSFW"
 suspend: "Suspend"
 unsuspend: "Unsuspend"
 blockConfirm: "Are you sure that you want to block this account?"
@@ -228,6 +229,7 @@ stopActivityDelivery: "Stop sending activities"
 blockThisInstance: "Block this instance"
 silenceThisInstance: "Silence this instance"
 mediaSilenceThisInstance: "Silence media from this instance"
+rejectReports: "Reject reports from this instance"
 operations: "Operations"
 software: "Software"
 version: "Version"
@@ -2579,6 +2581,10 @@ _moderationLogTypes:
   resetPassword: "Password reset"
   suspendRemoteInstance: "Remote instance suspended"
   unsuspendRemoteInstance: "Remote instance unsuspended"
+  setRemoteInstanceNSFW: "Set remote instance as NSFW"
+  unsetRemoteInstanceNSFW: "Set remote instance as NSFW"
+  rejectRemoteInstanceReports: "Rejected reports from remote instance"
+  acceptRemoteInstanceReports: "Accepted reports from remote instance"
   updateRemoteInstanceNote: "Moderation note updated for remote instance."
   markSensitiveDriveFile: "File marked as sensitive"
   unmarkSensitiveDriveFile: "File unmarked as sensitive"
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 8ab1dc0c8b..57d5536cf4 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -632,6 +632,10 @@ export interface Locale extends ILocale {
      * ユーザーのすべてのメディアをNSFWとしてマークする
      */
     "markAsNSFW": string;
+    /**
+     * Mark as NSFW
+     */
+    "markInstanceAsNSFW": string;
     /**
      * 凍結
      */
@@ -928,6 +932,10 @@ export interface Locale extends ILocale {
      * サーバーをメディアサイレンス
      */
     "mediaSilenceThisInstance": string;
+    /**
+     * Reject reports from this instance
+     */
+    "rejectReports": string;
     /**
      * 操作
      */
@@ -10000,6 +10008,22 @@ export interface Locale extends ILocale {
          * リモートサーバーを再開
          */
         "unsuspendRemoteInstance": string;
+        /**
+         * Set remote instance as NSFW
+         */
+        "setRemoteInstanceNSFW": string;
+        /**
+         * Set remote instance as NSFW
+         */
+        "unsetRemoteInstanceNSFW": string;
+        /**
+         * Rejected reports from remote instance
+         */
+        "rejectRemoteInstanceReports": string;
+        /**
+         * Accepted reports from remote instance
+         */
+        "acceptRemoteInstanceReports": string;
         /**
          * リモートサーバーのモデレーションノート更新
          */
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 2a022a7fe1..ceb8e04419 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -154,6 +154,7 @@ renoteUnmute: "ブーストのミュートを解除"
 block: "ブロック"
 unblock: "ブロック解除"
 markAsNSFW: "ユーザーのすべてのメディアをNSFWとしてマークする"
+markInstanceAsNSFW: "Mark as NSFW"
 suspend: "凍結"
 unsuspend: "解凍"
 blockConfirm: "ブロックしますか?"
@@ -228,6 +229,7 @@ stopActivityDelivery: "アクティビティの配送を停止"
 blockThisInstance: "このサーバーをブロック"
 silenceThisInstance: "サーバーをサイレンス"
 mediaSilenceThisInstance: "サーバーをメディアサイレンス"
+rejectReports: "Reject reports from this instance"
 operations: "操作"
 software: "ソフトウェア"
 version: "バージョン"
@@ -2647,6 +2649,10 @@ _moderationLogTypes:
   resetPassword: "パスワードをリセット"
   suspendRemoteInstance: "リモートサーバーを停止"
   unsuspendRemoteInstance: "リモートサーバーを再開"
+  setRemoteInstanceNSFW: "Set remote instance as NSFW"
+  unsetRemoteInstanceNSFW: "Set remote instance as NSFW"
+  rejectRemoteInstanceReports: "Rejected reports from remote instance"
+  acceptRemoteInstanceReports: "Accepted reports from remote instance"
   updateRemoteInstanceNote: "リモートサーバーのモデレーションノート更新"
   markSensitiveDriveFile: "ファイルをセンシティブ付与"
   unmarkSensitiveDriveFile: "ファイルをセンシティブ解除"
diff --git a/packages/backend/migration/1728177700920-add-reject-reports.js b/packages/backend/migration/1728177700920-add-reject-reports.js
new file mode 100644
index 0000000000..ed5f6bc559
--- /dev/null
+++ b/packages/backend/migration/1728177700920-add-reject-reports.js
@@ -0,0 +1,16 @@
+/*
+ * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export class AddRejectReports1728177700920 {
+    name = 'AddRejectReports1728177700920'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "instance" ADD "rejectReports" boolean NOT NULL DEFAULT false`);
+		}
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "rejectReports"`);
+		}
+}
diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts
index 6a28cbad15..bce67a458f 100644
--- a/packages/backend/src/core/activitypub/ApInboxService.ts
+++ b/packages/backend/src/core/activitypub/ApInboxService.ts
@@ -5,6 +5,7 @@
 
 import { Inject, Injectable } from '@nestjs/common';
 import { In } from 'typeorm';
+import * as Bull from 'bullmq';
 import { DI } from '@/di-symbols.js';
 import type { Config } from '@/config.js';
 import { UserFollowingService } from '@/core/UserFollowingService.js';
@@ -29,6 +30,7 @@ import { bindThis } from '@/decorators.js';
 import type { MiRemoteUser } from '@/models/User.js';
 import { GlobalEventService } from '@/core/GlobalEventService.js';
 import { AbuseReportService } from '@/core/AbuseReportService.js';
+import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
 import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js';
 import { ApNoteService } from './models/ApNoteService.js';
 import { ApLoggerService } from './ApLoggerService.js';
@@ -83,6 +85,7 @@ export class ApInboxService {
 		private apQuestionService: ApQuestionService,
 		private queueService: QueueService,
 		private globalEventService: GlobalEventService,
+		private federatedInstanceService: FederatedInstanceService,
 	) {
 		this.logger = this.apLoggerService.logger;
 	}
@@ -530,6 +533,12 @@ export class ApInboxService {
 
 	@bindThis
 	private async flag(actor: MiRemoteUser, activity: IFlag): Promise<string> {
+		// Make sure the source instance is allowed to send reports.
+		const instance = await this.federatedInstanceService.fetch(actor.host);
+		if (instance.rejectReports) {
+			throw new Bull.UnrecoverableError(`Rejecting report from instance: ${actor.host}`);
+		}
+
 		// objectは `(User|Note) | (User|Note)[]` だけど、全パターンDBスキーマと対応させられないので
 		// 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する
 		const uris = getApIds(activity.object);
diff --git a/packages/backend/src/models/Instance.ts b/packages/backend/src/models/Instance.ts
index dd625f95d3..ba93190c57 100644
--- a/packages/backend/src/models/Instance.ts
+++ b/packages/backend/src/models/Instance.ts
@@ -158,7 +158,12 @@ export class MiInstance {
 		default: false,
 	})
 	public isNSFW: boolean;
-	
+
+	@Column('boolean', {
+		default: false,
+	})
+	public rejectReports: boolean;
+
 	@Column('varchar', {
 		length: 16384, default: '',
 	})
diff --git a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
index 8b142910a6..daf19c4435 100644
--- a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
+++ b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
@@ -25,6 +25,7 @@ export const paramDef = {
 		host: { type: 'string' },
 		isSuspended: { type: 'boolean' },
 		isNSFW: { type: 'boolean' },
+		rejectReports: { type: 'boolean' },
 		moderationNote: { type: 'string' },
 	},
 	required: ['host'],
@@ -57,6 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 			await this.federatedInstanceService.update(instance.id, {
 				suspensionState,
 				isNSFW: ps.isNSFW,
+				rejectReports: ps.rejectReports,
 				moderationNote: ps.moderationNote,
 			});
 
@@ -74,6 +76,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				}
 			}
 
+			if (ps.isNSFW != null && instance.isNSFW !== ps.isNSFW) {
+				const message = ps.rejectReports ? 'setRemoteInstanceNSFW' : 'unsetRemoteInstanceNSFW';
+				this.moderationLogService.log(me, message, {
+					id: instance.id,
+					host: instance.host,
+				});
+			}
+
+			if (ps.rejectReports != null && instance.rejectReports !== ps.rejectReports) {
+				const message = ps.rejectReports ? 'rejectRemoteInstanceReports' : 'acceptRemoteInstanceReports';
+				this.moderationLogService.log(me, message, {
+					id: instance.id,
+					host: instance.host,
+				});
+			}
+
 			if (ps.moderationNote != null && instance.moderationNote !== ps.moderationNote) {
 				this.moderationLogService.log(me, 'updateRemoteInstanceNote', {
 					id: instance.id,
diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts
index d83d414096..d64d72c07f 100644
--- a/packages/backend/src/types.ts
+++ b/packages/backend/src/types.ts
@@ -77,8 +77,12 @@ export const moderationLogTypes = [
 	'deleteGlobalAnnouncement',
 	'deleteUserAnnouncement',
 	'resetPassword',
+	'setRemoteInstanceNSFW',
+	'unsetRemoteInstanceNSFW',
 	'suspendRemoteInstance',
 	'unsuspendRemoteInstance',
+	'rejectRemoteInstanceReports',
+	'acceptRemoteInstanceReports',
 	'updateRemoteInstanceNote',
 	'markSensitiveDriveFile',
 	'unmarkSensitiveDriveFile',
@@ -227,6 +231,14 @@ export type ModerationLogPayloads = {
 		userUsername: string;
 		userHost: string | null;
 	};
+	setRemoteInstanceNSFW: {
+		id: string;
+		host: string;
+	};
+	unsetRemoteInstanceNSFW: {
+		id: string;
+		host: string;
+	};
 	suspendRemoteInstance: {
 		id: string;
 		host: string;
@@ -235,6 +247,14 @@ export type ModerationLogPayloads = {
 		id: string;
 		host: string;
 	};
+	rejectRemoteInstanceReports: {
+		id: string;
+		host: string;
+	};
+	acceptRemoteInstanceReports: {
+		id: string;
+		host: string;
+	};
 	updateRemoteInstanceNote: {
 		id: string;
 		host: string;
diff --git a/packages/frontend/src/pages/admin/modlog.ModLog.vue b/packages/frontend/src/pages/admin/modlog.ModLog.vue
index f6f276de53..9fe804b2bd 100644
--- a/packages/frontend/src/pages/admin/modlog.ModLog.vue
+++ b/packages/frontend/src/pages/admin/modlog.ModLog.vue
@@ -23,6 +23,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 					'markSensitiveDriveFile',
 					'resetPassword',
 					'suspendRemoteInstance',
+					'setRemoteInstanceNSFW',
+					'unsetRemoteInstanceNSFW',
+					'rejectRemoteInstanceReports',
+					'acceptRemoteInstanceReports',
 				].includes(log.type),
 				[$style.logRed]: [
 					'suspend',
@@ -61,6 +65,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<span v-else-if="log.type === 'unmarkSensitiveDriveFile'">: @{{ log.info.fileUserUsername }}{{ log.info.fileUserHost ? '@' + log.info.fileUserHost : '' }}</span>
 		<span v-else-if="log.type === 'suspendRemoteInstance'">: {{ log.info.host }}</span>
 		<span v-else-if="log.type === 'unsuspendRemoteInstance'">: {{ log.info.host }}</span>
+		<span v-else-if="log.type === 'setRemoteInstanceNSFW'">: {{ log.info.host }}</span>
+		<span v-else-if="log.type === 'unsetRemoteInstanceNSFW'">: {{ log.info.host }}</span>
+		<span v-else-if="log.type === 'rejectRemoteInstanceReports'">: {{ log.info.host }}</span>
+		<span v-else-if="log.type === 'acceptRemoteInstanceReports'">: {{ log.info.host }}</span>
 		<span v-else-if="log.type === 'createGlobalAnnouncement'">: {{ log.info.announcement.title }}</span>
 		<span v-else-if="log.type === 'updateGlobalAnnouncement'">: {{ log.info.before.title }}</span>
 		<span v-else-if="log.type === 'deleteGlobalAnnouncement'">: {{ log.info.announcement.title }}</span>
diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue
index 821cd599eb..5401ea51e0 100644
--- a/packages/frontend/src/pages/instance-info.vue
+++ b/packages/frontend/src/pages/instance-info.vue
@@ -49,7 +49,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<MkSwitch v-model="isBlocked" :disabled="!meta || !instance || isBaseBlocked" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch>
 						<MkInfo v-if="isBaseSilenced" warn>{{ i18n.ts.silencedByBase }}</MkInfo>
 						<MkSwitch v-model="isSilenced" :disabled="!meta || !instance || isBaseSilenced" @update:modelValue="toggleSilenced">{{ i18n.ts.silenceThisInstance }}</MkSwitch>
-						<MkSwitch v-model="isNSFW" :disabled="!instance" @update:modelValue="toggleNSFW">Mark as NSFW</MkSwitch>
+						<MkSwitch v-model="isNSFW" :disabled="!instance" @update:modelValue="toggleNSFW">{{ i18n.ts.markInstanceAsNSFW }}</MkSwitch>
+						<MkSwitch v-model="rejectReports" :disabled="!instance" @update:modelValue="toggleRejectReports">{{ i18n.ts.rejectReports }}</MkSwitch>
 						<MkInfo v-if="isBaseMediaSilenced" warn>{{ i18n.ts.mediaSilencedByBase }}</MkInfo>
 						<MkSwitch v-model="isMediaSilenced" :disabled="!meta || !instance || isBaseMediaSilenced" @update:modelValue="toggleMediaSilenced">{{ i18n.ts.mediaSilenceThisInstance }}</MkSwitch>
 						<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
@@ -174,6 +175,7 @@ const suspensionState = ref<'none' | 'manuallySuspended' | 'goneSuspended' | 'au
 const isBlocked = ref(false);
 const isSilenced = ref(false);
 const isNSFW = ref(false);
+const rejectReports = ref(false);
 const isMediaSilenced = ref(false);
 const faviconUrl = ref<string | null>(null);
 const moderationNote = ref('');
@@ -219,6 +221,7 @@ async function fetch(): Promise<void> {
 	isBlocked.value = instance.value?.isBlocked ?? false;
 	isSilenced.value = instance.value?.isSilenced ?? false;
 	isNSFW.value = instance.value?.isNSFW ?? false;
+	rejectReports.value = instance.value?.rejectReports ?? false;
 	isMediaSilenced.value = instance.value?.isMediaSilenced ?? false;
 	faviconUrl.value = getProxiedImageUrlNullable(instance.value?.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.value?.iconUrl, 'preview');
 	moderationNote.value = instance.value?.moderationNote ?? '';
@@ -279,6 +282,14 @@ async function toggleNSFW(): Promise<void> {
 	});
 }
 
+async function toggleRejectReports(): Promise<void> {
+	if (!instance.value) throw new Error('No instance?');
+	await misskeyApi('admin/federation/update-instance', {
+		host: instance.value.host,
+		rejectReports: rejectReports.value,
+	});
+}
+
 function refreshMetadata(): void {
 	if (!instance.value) throw new Error('No instance?');
 	misskeyApi('admin/federation/refresh-remote-instance-metadata', {