Skip to content

lyrasoft/luna-firewall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LYRASOFT Firewall Package

Installation

Install from composer

composer require lyrasoft/firewall

Then copy files to project

php windwalker pkg:install lyrasoft/firewall -t routes -t migrations

Language Files

Add this line to admin & front middleware if you don't want to override languages:

$this->lang->loadAllFromVendor('lyrasoft/firewall', 'ini');

// OR
$this->lang->loadAllFromVendor(\Lyrasoft\Firewall\FirewallPackage::class, 'ini');

Or run this command to copy languages files:

php windwalker pkg:install lyrasoft/firewall -t lang

Register Admin Menu

Edit resources/menu/admin/sidemenu.menu.php

$menu->link($this->trans('unicorn.title.grid', title: $this->trans('firewall.redirect.title')))
    ->to($nav->to('redirect_list')->var('type', 'main'))
    ->icon('fal fa-angles-right');

$menu->link($this->trans('unicorn.title.grid', title: $this->trans('firewall.ip.rule.title')))
    ->to($nav->to('ip_rule_list')->var('type', 'main'))
    ->icon('fal fa-network-wired');

Redirect

Add RedirectMiddleware to etc/app/main.php

use Lyrasoft\Firewall\Middleware\RedirectMiddleware;

    // ...

    'middlewares' => [
        \Windwalker\DI\create(
            RedirectMiddleware::class,
            ignores: [
                'admin/*'
            ]
        ),
        
        // ...
    ],

Now you can add redirect records at admin:

The Source Path Rules

  • Add / at start, the path will compare from site base root (not domain root).
  • If you enable the Regex:
    • Add * will compare a path segment with any string.
    • Add ** will compare cross-segments.
    • You can add custom regex rules, like: /foo/(\d+)

The Dest Path

Thr dest path can be relative path: foo/bar or full URL: https://simular.co/foo/bar.

If you enabne the Regex, you may use variables start with $ to insert matched string. For example, a foo/*/edit/(\d+), can redirect to new/path/$1/edit/$2

Other Params

  • Only 404: Only redirect if a page is 404, if page URL exists, won't redirect.
  • Handle Locale: If this site is multi-language, this params will auto auto detect the starting ;anguage prefix and auto add it to dest path, you may use {lang} in dest path to custom set lang alias position.

Use Different Type from DB

Redirect tables has type colimn, you can use admin/redirect/list/{type} to manage different types.

And if you want to choose types for middleware, you can do this:

    // ...

    'middlewares' => [
        \Windwalker\DI\create(
            RedirectMiddleware::class,
            type: 'other_type',
            ignores: [
                'admin/*'
            ]
        ),
        
        // ...
    ],

The type supports string|Enum|array|null|false, if you send NULL into it, means all redirect records. If you send FALSE, means don't use DB recods.

Use Custom List

You can use custom redirect list, custom list will auto-enable the regex:

This settings will merge DB list and custom list.

    // ...

    'middlewares' => [
        \Windwalker\DI\create(
            RedirectMiddleware::class,
            type: 'flower',
            list: [
                'foo/bar' => 'hello/world',            
                'foo/yoo/*' => 'hello/mountain/$1',            
            ],
            ignores: [
                'admin/*'
            ]
        ),
        
        // ...
    ],

This settings will disable DB list and only use custom list.

    // ...

    'middlewares' => [
        \Windwalker\DI\create(
            RedirectMiddleware::class,
            type: false,
            list: [
                'foo/bar' => 'hello/world',            
                'foo/yoo/*' => 'hello/mountain/$1',            
            ],
            ignores: [
                'admin/*'
            ]
        ),
        
        // ...
    ],

Custom List can use Closure to generate list:

// ...

    'middlewares' => [
        \Windwalker\DI\create(
            RedirectMiddleware::class,
            // ...
            list: raw(function (FooService $fooService) {
                return ...; 
            });
        ),
        
        // ...
    ],

The custom list redirect status code default is 301, if you want to use other status, set it to
REDIRECT_DEFAULT_STATUS env varialbe.

Instant Redirect

If there has some reason you can not wait RedirectResponse return, you may use instant redirect:

    // ...

    'middlewares' => [
        \Windwalker\DI\create(
            RedirectMiddleware::class,
            // ...
            instantRedirect: true,
        ),
        
        // ...
    ],

Disable

If you wanr to disable this middleware in debug mode, add this options:

        \Windwalker\DI\create(
            RedirectMiddleware::class,
            enabled: !WINDWALKER_DEBUG
        ),

Hook

Add afterHit hook that you can do somthing or log if redirect hit.

        \Windwalker\DI\create(
            RedirectMiddleware::class,
            afterHit: raw(function (string $dest, \Redirect $redirect) {
                \Windwalker\Core\Manager\Logger::info('Redirect to: ' . $dest);
            })
        ),

IP Allow/Block (Firewall)

To enable IP Rules, add FirewallMiddleware to front.route.php

use Lyrasoft\Firewall\Middleware\FirewallMiddleware;

    // ...

    ->middleware(
        FirewallMiddleware::class,
    )

    // ...

Admin IP Rules Management

Select Allow or Block, and enter the IP Range format:

The supported formats:

Type Syntax Details
IPV6 ::1 Short notation
IPV4 192.168.0.1
Range 192.168.0.0-192.168.1.60 Includes all IPs from 192.168.0.0 to 192.168.0.255
and from 192.168.1.0 to 198.168.1.60
Wild card 192.168.0.* IPs starting with 192.168.0
Same as IP Range 192.168.0.0-192.168.0.255
Subnet mask 192.168.0.0/255.255.255.0 IPs starting with 192.168.0
Same as 192.168.0.0-192.168.0.255 and 192.168.0.*
CIDR Mask 192.168.0.0/24 IPs starting with 192.168.0
Same as 192.168.0.0-192.168.0.255 and 192.168.0.*
and 192.168.0.0/255.255.255.0

We use mlocati/ip-lib as IP Range parser.

Select DB Type

You can also access different type from ip-rule/list/{type}.

And set type name to middleware

    ->middleware(
        FirewallMiddleware::class,
        type: 'foo'
    )

type can also supports string, array and enum. Use NULL to select all, FALSE to disable DB.

Custom List

If you want to manually set ip list, FirewallMiddleware custom list must use 2 lists, allowList and blockList.

    ->middleware(
        FirewallMiddleware::class,
        type: false,
        allowList: [
            '0.0.0.0',
            '144.122.*.*',
        ],
        blockList: [
            '165.2.90.45',
            '222.44.55.66',
        ],
    )

Disable

If you wanr to disable this middleware in debug mode, add this options:

        \Windwalker\DI\create(
            FirewallMiddleware::class,
            enabled: !WINDWALKER_DEBUG
        ),

Hook

Add afterHit hook that you can do somthing or log if an IP was be blocked.

        \Windwalker\DI\create(
            FirewallMiddleware::class,
            afterHit: raw(function (AppRequest $appRequest) {
                \Windwalker\Core\Manager\Logger::info('Attack from: ' . $appRequest->getClientIp());
            })
        ),

Cache

Cache Lifetime

Both middlewares has a cacheTtl param, default is 3600 seconds.

        \Windwalker\DI\create(
            FirewallMiddleware::class,
            cacheTtl: 3600
        ),

Cache Clear

Everytime you edit Redirect or IpRule will auto clear all caches.

The cache files is located at caches/firewall/, and you can add firewall to clear cache command in composer.json

        "post-autoload-dump": [
            ...
            "php windwalker cache:clear renderer html firewall" <-- Add firewall 
        ],

Cache Disable

Cache will disable in debug mode or when ttl set to 0.

Packages

No packages published

Languages