mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-13 16:16:06 +00:00
feat(iplimit): gate IP limit on fail2ban and reset stale limits
Per-client IP limit only enforces where fail2ban is installed, so the panel now reports enforceability and disables the field otherwise: - Add GET /panel/api/server/fail2banStatus (enabled/installed/usable/windows), cached 30s. - ClientFormModal and ClientBulkAddModal disable the IP Limit input when not usable and show a hover tooltip; Windows gets a platform-specific message instead of the bash-menu hint. - One-time migration ResetIpLimitNoFail2ban zeroes existing client limitIp (inbound settings JSON + clients table) on hosts without fail2ban, where the limit never applied. - Drop the recurring '[LimitIP] Fail2Ban is not installed' warning. - Add limitIpFail2banMissing/limitIpFail2banWindows/limitIpDisabled across all 13 locales.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { HttpUtil } from '@/utils';
|
||||
import { keys } from '@/api/queryKeys';
|
||||
|
||||
export interface Fail2banStatus {
|
||||
enabled: boolean;
|
||||
installed: boolean;
|
||||
usable: boolean;
|
||||
windows: boolean;
|
||||
}
|
||||
|
||||
const FAIL_OPEN_STATUS: Fail2banStatus = {
|
||||
enabled: true,
|
||||
installed: true,
|
||||
usable: true,
|
||||
windows: false,
|
||||
};
|
||||
|
||||
async function fetchFail2banStatus(): Promise<Fail2banStatus> {
|
||||
const msg = await HttpUtil.get<Fail2banStatus>('/panel/api/server/fail2banStatus', undefined, { silent: true });
|
||||
if (!msg?.success || !msg.obj) throw new Error(msg?.msg || 'Failed to fetch fail2ban status');
|
||||
return { ...FAIL_OPEN_STATUS, ...msg.obj };
|
||||
}
|
||||
|
||||
export function getLimitIpNotice(status: Fail2banStatus, t: (key: string) => string): string {
|
||||
if (status.usable) return '';
|
||||
if (!status.enabled) return t('pages.clients.limitIpDisabled');
|
||||
if (status.windows) return t('pages.clients.limitIpFail2banWindows');
|
||||
return t('pages.clients.limitIpFail2banMissing');
|
||||
}
|
||||
|
||||
export function useFail2banStatusQuery() {
|
||||
const query = useQuery({
|
||||
queryKey: keys.server.fail2banStatus(),
|
||||
queryFn: fetchFail2banStatus,
|
||||
staleTime: 60_000,
|
||||
});
|
||||
|
||||
return query.data ?? FAIL_OPEN_STATUS;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
export const keys = {
|
||||
server: {
|
||||
status: () => ['server', 'status'] as const,
|
||||
fail2banStatus: () => ['server', 'fail2banStatus'] as const,
|
||||
},
|
||||
nodes: {
|
||||
root: () => ['nodes'] as const,
|
||||
|
||||
Reference in New Issue
Block a user