1
0

firewall-rules-generator.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. 'use client';
  2. import { useState } from 'react';
  3. import {
  4. buildUfwCommands,
  5. buildNftablesRuleset,
  6. type FirewallOptions,
  7. type PortProtocol,
  8. type PortRule,
  9. } from '@/lib/xray/firewall';
  10. import { ToolFrame } from './tool-frame';
  11. import { CheckboxField } from './shared/fields';
  12. import { OutputBlock } from './shared/output-block';
  13. interface Row {
  14. label: string;
  15. port: string;
  16. protocol: PortProtocol;
  17. enabled: boolean;
  18. }
  19. const DEFAULT_ROWS: Row[] = [
  20. { label: 'panel', port: '2053', protocol: 'tcp', enabled: true },
  21. { label: 'subscription', port: '2096', protocol: 'tcp', enabled: false },
  22. { label: 'inbound (HTTPS)', port: '443', protocol: 'tcp', enabled: true },
  23. { label: 'inbound (UDP)', port: '443', protocol: 'udp', enabled: false },
  24. ];
  25. export function FirewallRulesGenerator() {
  26. const [allowSsh, setAllowSsh] = useState(true);
  27. const [sshPort] = useState('22');
  28. const [rows, setRows] = useState<Row[]>(DEFAULT_ROWS);
  29. function toggle(index: number, enabled: boolean) {
  30. setRows((prev) => prev.map((r, i) => (i === index ? { ...r, enabled } : r)));
  31. }
  32. const ports: PortRule[] = rows
  33. .filter((r) => r.enabled && Number(r.port) > 0)
  34. .map((r) => ({ port: Number(r.port), protocol: r.protocol, label: r.label }));
  35. const options: FirewallOptions = { ports, allowSsh, sshPort: Number(sshPort) || 22 };
  36. return (
  37. <ToolFrame
  38. title="Firewall rules generator"
  39. description="Pick the ports to open and copy ready-made ufw and nftables rules."
  40. >
  41. <div className="flex flex-col gap-2">
  42. <CheckboxField
  43. label={`Allow SSH (port ${sshPort})`}
  44. checked={allowSsh}
  45. onChange={setAllowSsh}
  46. />
  47. {rows.map((row, i) => (
  48. <CheckboxField
  49. key={`${row.label}-${row.protocol}`}
  50. label={`${row.label} — ${row.port}/${row.protocol}`}
  51. checked={row.enabled}
  52. onChange={(c) => toggle(i, c)}
  53. />
  54. ))}
  55. </div>
  56. <div className="mt-4 grid grid-cols-1 gap-4">
  57. <OutputBlock label="ufw" value={buildUfwCommands(options)} />
  58. <OutputBlock label="nftables (/etc/nftables.conf)" value={buildNftablesRuleset(options)} />
  59. </div>
  60. </ToolFrame>
  61. );
  62. }