mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-05 07:26:36 +08:00
feat(waf): UA 非正常不含爬虫,并支持自定义正则屏蔽
block_abnormal_ua 仅 Other/Unknown;新增 block_custom_ua 与 custom_ua_patterns。
This commit is contained in:
@@ -218,6 +218,23 @@ function validateNodeConfig(node: WAFRuleNode): string | undefined {
|
||||
return `节点 ${node.id} 包含无效浏览器标签`;
|
||||
if (node.config.operating_systems.some((label) => !UA_OS_LABELS.has(label)))
|
||||
return `节点 ${node.id} 包含无效操作系统标签`;
|
||||
if (node.config.custom_ua_patterns.length > 32)
|
||||
return `节点 ${node.id} 的自定义 UA 正则不能超过 32 条`;
|
||||
for (const pattern of node.config.custom_ua_patterns) {
|
||||
if (!pattern.trim()) return `节点 ${node.id} 的自定义 UA 正则不能为空`;
|
||||
if (new TextEncoder().encode(pattern).length > 256)
|
||||
return `节点 ${node.id} 的自定义 UA 正则过长`;
|
||||
try {
|
||||
void new RegExp(pattern);
|
||||
} catch {
|
||||
return `节点 ${node.id} 的自定义 UA 正则无效`;
|
||||
}
|
||||
}
|
||||
if (
|
||||
node.config.block_custom_ua &&
|
||||
node.config.custom_ua_patterns.length === 0
|
||||
)
|
||||
return `节点 ${node.id} 开启屏蔽自定义 UA 时至少需要一条正则`;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ describe('createRuleNode ua_check', () => {
|
||||
match_mode: 'or',
|
||||
block_common_bots: false,
|
||||
block_abnormal_ua: false,
|
||||
block_custom_ua: false,
|
||||
custom_ua_patterns: [],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -50,6 +50,8 @@ export function createRuleNode(
|
||||
match_mode: 'or',
|
||||
block_common_bots: false,
|
||||
block_abnormal_ua: false,
|
||||
block_custom_ua: false,
|
||||
custom_ua_patterns: [],
|
||||
},
|
||||
};
|
||||
if (type === 'pow')
|
||||
|
||||
@@ -17,6 +17,8 @@ it('hides match and block until UA check is enabled', () => {
|
||||
match_mode: 'or',
|
||||
block_common_bots: false,
|
||||
block_abnormal_ua: false,
|
||||
block_custom_ua: false,
|
||||
custom_ua_patterns: [],
|
||||
},
|
||||
};
|
||||
const onChange = vi.fn();
|
||||
@@ -40,12 +42,9 @@ it('hides match and block until UA check is enabled', () => {
|
||||
);
|
||||
expect(screen.getByLabelText('屏蔽常见爬虫 UA')).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('屏蔽非正常 UA')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/浏览器或操作系统分类为 Bot/),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/浏览器分类为 Bot、Other 或 Unknown/),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('屏蔽自定义 UA')).toBeInTheDocument();
|
||||
expect(screen.getByText(/浏览器或操作系统分类为 Bot/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/浏览器分类为 Other 或 Unknown/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('edits display name for configurable nodes', () => {
|
||||
|
||||
@@ -277,7 +277,8 @@ function PropertyFields({
|
||||
屏蔽非正常 UA
|
||||
</FieldLabel>
|
||||
<FieldDescription>
|
||||
浏览器分类为 Bot、Other 或 Unknown(无法识别为已知浏览器)
|
||||
浏览器分类为 Other 或 Unknown(不含搜索引擎等爬虫
|
||||
Bot,爬虫请用上方开关)
|
||||
</FieldDescription>
|
||||
</div>
|
||||
<Switch
|
||||
@@ -292,6 +293,58 @@ function PropertyFields({
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
orientation='horizontal'
|
||||
className='items-start justify-between gap-3'
|
||||
>
|
||||
<div className='space-y-1'>
|
||||
<FieldLabel htmlFor={`${node.id}-block-custom`}>
|
||||
屏蔽自定义 UA
|
||||
</FieldLabel>
|
||||
<FieldDescription>
|
||||
原始 User-Agent 命中任一条正则时返回 false(Lua 模式语法)
|
||||
</FieldDescription>
|
||||
</div>
|
||||
<Switch
|
||||
id={`${node.id}-block-custom`}
|
||||
className='mt-0.5'
|
||||
checked={node.config.block_custom_ua}
|
||||
onCheckedChange={(block_custom_ua) =>
|
||||
onChange({
|
||||
...node,
|
||||
config: { ...node.config, block_custom_ua },
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
{node.config.block_custom_ua && (
|
||||
<Field>
|
||||
<FieldLabel htmlFor={`${node.id}-custom-patterns`}>
|
||||
自定义 UA 正则
|
||||
</FieldLabel>
|
||||
<Textarea
|
||||
id={`${node.id}-custom-patterns`}
|
||||
rows={4}
|
||||
value={node.config.custom_ua_patterns.join('\n')}
|
||||
placeholder={'python%-requests\ncurl/'}
|
||||
onChange={(event) =>
|
||||
onChange({
|
||||
...node,
|
||||
config: {
|
||||
...node.config,
|
||||
custom_ua_patterns: event.target.value
|
||||
.split('\n')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean),
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
<FieldDescription>
|
||||
每行一条 Lua 模式正则,命中任一条即 false;最多 32 条
|
||||
</FieldDescription>
|
||||
</Field>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -786,6 +786,8 @@ export interface UACheckConfig {
|
||||
match_mode: 'and' | 'or';
|
||||
block_common_bots: boolean;
|
||||
block_abnormal_ua: boolean;
|
||||
block_custom_ua: boolean;
|
||||
custom_ua_patterns: string[];
|
||||
}
|
||||
|
||||
export type WAFRuleNode =
|
||||
|
||||
Reference in New Issue
Block a user