Add command for removing IP addresses from the block list
- Introduced `block delete` command to remove IPs from the block list. - Added `UnblockIP` method to support IP removal in the firewall. - Updated internationalization files for delete command descriptions. - Enhanced repository with `DeleteByIP` for targeted IP removal.
This commit is contained in:
@@ -36,6 +36,12 @@ func CmdBlock() *cli.Command {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "delete",
|
||||
Usage: i18n.Lang.T("cmd.daemon.block.delete.Usage"),
|
||||
Description: i18n.Lang.T("cmd.daemon.block.delete.Description"),
|
||||
Action: cmdBlockDelete,
|
||||
},
|
||||
{
|
||||
Name: "clear",
|
||||
Usage: i18n.Lang.T("cmd.daemon.block.clear.Usage"),
|
||||
@@ -80,6 +86,37 @@ func cmdBlockAdd(_ context.Context, cmd *cli.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func cmdBlockDelete(_ context.Context, cmd *cli.Command) error {
|
||||
ip := net.ParseIP(cmd.Args().Get(0))
|
||||
if ip == nil {
|
||||
return errors.New("invalid ip address")
|
||||
}
|
||||
|
||||
sock, err := newSocket()
|
||||
if err != nil {
|
||||
return errors.New(i18n.Lang.T("daemon is not running"))
|
||||
}
|
||||
defer func() {
|
||||
_ = sock.Close()
|
||||
}()
|
||||
|
||||
result, err := sock.SendCommand("block_delete_ip", map[string]string{
|
||||
"ip": ip.String(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if result != "ok" {
|
||||
return errors.New(i18n.Lang.T("cmd.error", map[string]any{
|
||||
"Error": result,
|
||||
}))
|
||||
}
|
||||
|
||||
fmt.Println(i18n.Lang.T("block_delete_ip_success"))
|
||||
return nil
|
||||
}
|
||||
|
||||
func cmdBlockClear(_ context.Context, _ *cli.Command) error {
|
||||
sock, err := newSocket()
|
||||
if err != nil {
|
||||
|
||||
@@ -160,24 +160,43 @@ func (d *daemon) socketCommand(command string, args map[string]string, socket so
|
||||
if args["ip"] == "" {
|
||||
return socket.Write("ip argument is required")
|
||||
}
|
||||
ip := net.ParseIP(args["ip"])
|
||||
if ip == nil {
|
||||
ipAddr := net.ParseIP(args["ip"])
|
||||
if ipAddr == nil {
|
||||
_ = socket.Write("invalid ip address")
|
||||
return errors.New("invalid ip address")
|
||||
}
|
||||
|
||||
port := args["port"]
|
||||
if port != "" {
|
||||
if err := d.cmdBlockAddIPWithPort(ip, port, args); err != nil {
|
||||
return socket.Write("block add failed: " + err.Error())
|
||||
if err := d.cmdBlockAddIPWithPort(ipAddr, port, args); err != nil {
|
||||
_ = socket.Write("block add failed: " + err.Error())
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := d.cmdBlockAddIP(ip, args); err != nil {
|
||||
return socket.Write("block add failed: " + err.Error())
|
||||
if err := d.cmdBlockAddIP(ipAddr, args); err != nil {
|
||||
_ = socket.Write("block add failed: " + err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return socket.Write("ok")
|
||||
case "block_delete_ip":
|
||||
if args["ip"] == "" {
|
||||
return socket.Write("ip argument is required")
|
||||
}
|
||||
ipAddr := net.ParseIP(args["ip"])
|
||||
if ipAddr == nil {
|
||||
_ = socket.Write("invalid ip address")
|
||||
return errors.New("invalid ip address")
|
||||
}
|
||||
|
||||
if err := d.firewall.UnblockIP(ipAddr); err != nil {
|
||||
_ = socket.Write("block delete failed: " + err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return socket.Write("ok")
|
||||
|
||||
case "block_clear":
|
||||
if err := d.firewall.UnblockAllIPs(); err != nil {
|
||||
_ = socket.Write("block clear failed: " + err.Error())
|
||||
|
||||
@@ -3,6 +3,7 @@ package repository
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/db/entity"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
type BlockingRepository interface {
|
||||
Add(blockedIP entity.Blocking) error
|
||||
List(callback func(entity.Blocking) error) error
|
||||
DeleteByIP(ip net.IP, callback func(entity.Blocking) error) error
|
||||
DeleteExpired(limit int) (int, error)
|
||||
Clear() error
|
||||
}
|
||||
@@ -73,6 +75,44 @@ func (r *blocking) List(callback func(entity.Blocking) error) error {
|
||||
})
|
||||
}
|
||||
|
||||
func (r *blocking) DeleteByIP(ip net.IP, callback func(entity.Blocking) error) error {
|
||||
return r.db.Update(func(tx *bbolt.Tx) error {
|
||||
bucket, err := tx.CreateBucketIfNotExists([]byte(r.bucket))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c := bucket.Cursor()
|
||||
|
||||
for k, v := c.First(); k != nil; {
|
||||
blockedIP := entity.Blocking{}
|
||||
err := json.Unmarshal(v, &blockedIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parsedBlockedIP := net.ParseIP(blockedIP.IP)
|
||||
if parsedBlockedIP == nil || !parsedBlockedIP.Equal(ip) {
|
||||
k, v = c.Next()
|
||||
continue
|
||||
}
|
||||
|
||||
if err := callback(blockedIP); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nextK, nextV := c.Next()
|
||||
if err := bucket.Delete(k); err != nil {
|
||||
return err
|
||||
}
|
||||
k = nextK
|
||||
v = nextV
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *blocking) DeleteExpired(limit int) (int, error) {
|
||||
if limit <= 0 {
|
||||
return 0, nil
|
||||
|
||||
@@ -19,6 +19,7 @@ type API interface {
|
||||
BlockIP(block BlockIP) (bool, error)
|
||||
BlockIPWithPorts(block BlockIPWithPorts) (bool, error)
|
||||
UnblockAllIPs() error
|
||||
UnblockIP(ip net.IP) error
|
||||
ClearDBData() error
|
||||
}
|
||||
|
||||
@@ -171,6 +172,33 @@ func (b *blocking) BlockIPWithPorts(block BlockIPWithPorts) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (b *blocking) UnblockIP(ip net.IP) error {
|
||||
err := b.blockingRepository.DeleteByIP(ip, func(e entity.Blocking) error {
|
||||
if e.IsPorts() {
|
||||
l4Ports, err := e.ToL4Ports()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.removeIPWithPorts(ip, l4Ports)
|
||||
}
|
||||
|
||||
if err := b.blockListIP.DeleteIP(ip); err != nil {
|
||||
if strings.Contains(err.Error(), "element does not exist") {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *blocking) UnblockAllIPs() error {
|
||||
err := b.blockingRepository.List(func(e entity.Blocking) error {
|
||||
ip := net.ParseIP(e.IP)
|
||||
@@ -214,3 +242,16 @@ func (b *blocking) UnblockAllIPs() error {
|
||||
func (b *blocking) ClearDBData() error {
|
||||
return b.blockingRepository.Clear()
|
||||
}
|
||||
|
||||
func (b *blocking) removeIPWithPorts(ip net.IP, l4Ports []types.L4Port) error {
|
||||
for _, port := range l4Ports {
|
||||
if err := b.blockListIPWithPort.DeleteIP(ip, port); err != nil {
|
||||
if strings.Contains(err.Error(), "element does not exist") ||
|
||||
strings.Contains(err.Error(), "Error: Could not process rule: No such file or directory") {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package firewall
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/docker_monitor"
|
||||
@@ -31,6 +32,9 @@ type API interface {
|
||||
// UnblockAllIPs Unblock all IP addresses.
|
||||
UnblockAllIPs() error
|
||||
|
||||
// UnblockIP Unblock IP address.
|
||||
UnblockIP(ip net.IP) error
|
||||
|
||||
// ClearDBData Clear all data from DB
|
||||
ClearDBData() error
|
||||
|
||||
@@ -129,6 +133,10 @@ func (f *firewall) UnblockAllIPs() error {
|
||||
return f.blockingService.UnblockAllIPs()
|
||||
}
|
||||
|
||||
func (f *firewall) UnblockIP(ip net.IP) error {
|
||||
return f.blockingService.UnblockIP(ip)
|
||||
}
|
||||
|
||||
func (f *firewall) ClearDBData() error {
|
||||
return f.blockingService.ClearDBData()
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
"cmd.daemon.block.add.FlagUsage.reason": "Reason for blocking.",
|
||||
"block_add_ip_success": "The IP address has been successfully added to the block list.",
|
||||
|
||||
"cmd.daemon.block.delete.Usage": "Remove IP address from block list",
|
||||
"cmd.daemon.block.delete.Description": "Remove an IP address from the block list. \nExample: \nkor-elf-shield block delete 192.168.1.1",
|
||||
"block_delete_ip_success": "The IP address has been successfully removed from the block list.",
|
||||
|
||||
"Command error": "Command error",
|
||||
"invalid log level": "The log level specified in the settings is invalid. It is currently set to: {{.Level}}. Valid values: {{.Levels}}",
|
||||
"invalid log encoding": "Invalid encoding setting. Currently set to: {{.Encoding}}. Valid values: {{.Encodings}}",
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
"cmd.daemon.block.add.FlagUsage.reason": "Блоктау себебі.",
|
||||
"block_add_ip_success": "IP мекенжайы блоктау тізіміне сәтті қосылды.",
|
||||
|
||||
"cmd.daemon.block.delete.Usage": "IP мекенжайын блоктау тізімінен алып тастаңыз",
|
||||
"cmd.daemon.block.delete.Description": "IP мекенжайын блоктау тізімінен алып тастаңыз. \nМысал: \nkor-elf-shield block delete 192.168.1.1",
|
||||
"block_delete_ip_success": "IP мекенжайы блоктау тізімінен сәтті жойылды.",
|
||||
|
||||
"Command error": "Командалық қате",
|
||||
"invalid log level": "Параметрлерде көрсетілген журнал деңгейі жарамсыз. Ол қазір мына күйге орнатылған: {{.Level}}. Жарамды мәндер: {{.Levels}}",
|
||||
"invalid log encoding": "Жарамсыз кодтау параметрі. Қазіргі уақытта орнатылған: {{.Encoding}}. Жарамды мәндер: {{.Encodings}}",
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
"cmd.daemon.block.add.FlagUsage.reason": "Причина блокировки.",
|
||||
"block_add_ip_success": "IP адрес успешно добавлен в список заблокированных.",
|
||||
|
||||
"cmd.daemon.block.delete.Usage": "Удалить IP адрес из списка заблокированных",
|
||||
"cmd.daemon.block.delete.Description": "Удалить IP адрес из списка заблокированных. \nПример: \nkor-elf-shield block delete 192.168.1.1",
|
||||
"block_delete_ip_success": "IP адрес успешно удален из списка заблокированных.",
|
||||
|
||||
"Command error": "Ошибка команды",
|
||||
"invalid log level": "В настройках указан не верный уровень log. Сейчас указан: {{.Level}}. Допустимые значения: {{.Levels}}",
|
||||
"invalid log encoding": "Неверная настройка encoding. Сейчас указан: {{.Encoding}}. Допустимые значения: {{.Encodings}}",
|
||||
|
||||
Reference in New Issue
Block a user