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",
|
Name: "clear",
|
||||||
Usage: i18n.Lang.T("cmd.daemon.block.clear.Usage"),
|
Usage: i18n.Lang.T("cmd.daemon.block.clear.Usage"),
|
||||||
@@ -80,6 +86,37 @@ func cmdBlockAdd(_ context.Context, cmd *cli.Command) error {
|
|||||||
return nil
|
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 {
|
func cmdBlockClear(_ context.Context, _ *cli.Command) error {
|
||||||
sock, err := newSocket()
|
sock, err := newSocket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -160,24 +160,43 @@ func (d *daemon) socketCommand(command string, args map[string]string, socket so
|
|||||||
if args["ip"] == "" {
|
if args["ip"] == "" {
|
||||||
return socket.Write("ip argument is required")
|
return socket.Write("ip argument is required")
|
||||||
}
|
}
|
||||||
ip := net.ParseIP(args["ip"])
|
ipAddr := net.ParseIP(args["ip"])
|
||||||
if ip == nil {
|
if ipAddr == nil {
|
||||||
_ = socket.Write("invalid ip address")
|
_ = socket.Write("invalid ip address")
|
||||||
return errors.New("invalid ip address")
|
return errors.New("invalid ip address")
|
||||||
}
|
}
|
||||||
|
|
||||||
port := args["port"]
|
port := args["port"]
|
||||||
if port != "" {
|
if port != "" {
|
||||||
if err := d.cmdBlockAddIPWithPort(ip, port, args); err != nil {
|
if err := d.cmdBlockAddIPWithPort(ipAddr, port, args); err != nil {
|
||||||
return socket.Write("block add failed: " + err.Error())
|
_ = socket.Write("block add failed: " + err.Error())
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := d.cmdBlockAddIP(ip, args); err != nil {
|
if err := d.cmdBlockAddIP(ipAddr, args); err != nil {
|
||||||
return socket.Write("block add failed: " + err.Error())
|
_ = socket.Write("block add failed: " + err.Error())
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return socket.Write("ok")
|
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":
|
case "block_clear":
|
||||||
if err := d.firewall.UnblockAllIPs(); err != nil {
|
if err := d.firewall.UnblockAllIPs(); err != nil {
|
||||||
_ = socket.Write("block clear failed: " + err.Error())
|
_ = socket.Write("block clear failed: " + err.Error())
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package repository
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/db/entity"
|
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/db/entity"
|
||||||
@@ -13,6 +14,7 @@ import (
|
|||||||
type BlockingRepository interface {
|
type BlockingRepository interface {
|
||||||
Add(blockedIP entity.Blocking) error
|
Add(blockedIP entity.Blocking) error
|
||||||
List(callback func(entity.Blocking) error) error
|
List(callback func(entity.Blocking) error) error
|
||||||
|
DeleteByIP(ip net.IP, callback func(entity.Blocking) error) error
|
||||||
DeleteExpired(limit int) (int, error)
|
DeleteExpired(limit int) (int, error)
|
||||||
Clear() 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) {
|
func (r *blocking) DeleteExpired(limit int) (int, error) {
|
||||||
if limit <= 0 {
|
if limit <= 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type API interface {
|
|||||||
BlockIP(block BlockIP) (bool, error)
|
BlockIP(block BlockIP) (bool, error)
|
||||||
BlockIPWithPorts(block BlockIPWithPorts) (bool, error)
|
BlockIPWithPorts(block BlockIPWithPorts) (bool, error)
|
||||||
UnblockAllIPs() error
|
UnblockAllIPs() error
|
||||||
|
UnblockIP(ip net.IP) error
|
||||||
ClearDBData() error
|
ClearDBData() error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +172,33 @@ func (b *blocking) BlockIPWithPorts(block BlockIPWithPorts) (bool, error) {
|
|||||||
return true, nil
|
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 {
|
func (b *blocking) UnblockAllIPs() error {
|
||||||
err := b.blockingRepository.List(func(e entity.Blocking) error {
|
err := b.blockingRepository.List(func(e entity.Blocking) error {
|
||||||
ip := net.ParseIP(e.IP)
|
ip := net.ParseIP(e.IP)
|
||||||
@@ -214,3 +242,16 @@ func (b *blocking) UnblockAllIPs() error {
|
|||||||
func (b *blocking) ClearDBData() error {
|
func (b *blocking) ClearDBData() error {
|
||||||
return b.blockingRepository.Clear()
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/docker_monitor"
|
"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 Unblock all IP addresses.
|
||||||
UnblockAllIPs() error
|
UnblockAllIPs() error
|
||||||
|
|
||||||
|
// UnblockIP Unblock IP address.
|
||||||
|
UnblockIP(ip net.IP) error
|
||||||
|
|
||||||
// ClearDBData Clear all data from DB
|
// ClearDBData Clear all data from DB
|
||||||
ClearDBData() error
|
ClearDBData() error
|
||||||
|
|
||||||
@@ -129,6 +133,10 @@ func (f *firewall) UnblockAllIPs() error {
|
|||||||
return f.blockingService.UnblockAllIPs()
|
return f.blockingService.UnblockAllIPs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *firewall) UnblockIP(ip net.IP) error {
|
||||||
|
return f.blockingService.UnblockIP(ip)
|
||||||
|
}
|
||||||
|
|
||||||
func (f *firewall) ClearDBData() error {
|
func (f *firewall) ClearDBData() error {
|
||||||
return f.blockingService.ClearDBData()
|
return f.blockingService.ClearDBData()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,10 @@
|
|||||||
"cmd.daemon.block.add.FlagUsage.reason": "Reason for blocking.",
|
"cmd.daemon.block.add.FlagUsage.reason": "Reason for blocking.",
|
||||||
"block_add_ip_success": "The IP address has been successfully added to the block list.",
|
"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",
|
"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 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}}",
|
"invalid log encoding": "Invalid encoding setting. Currently set to: {{.Encoding}}. Valid values: {{.Encodings}}",
|
||||||
|
|||||||
@@ -38,6 +38,10 @@
|
|||||||
"cmd.daemon.block.add.FlagUsage.reason": "Блоктау себебі.",
|
"cmd.daemon.block.add.FlagUsage.reason": "Блоктау себебі.",
|
||||||
"block_add_ip_success": "IP мекенжайы блоктау тізіміне сәтті қосылды.",
|
"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": "Командалық қате",
|
"Command error": "Командалық қате",
|
||||||
"invalid log level": "Параметрлерде көрсетілген журнал деңгейі жарамсыз. Ол қазір мына күйге орнатылған: {{.Level}}. Жарамды мәндер: {{.Levels}}",
|
"invalid log level": "Параметрлерде көрсетілген журнал деңгейі жарамсыз. Ол қазір мына күйге орнатылған: {{.Level}}. Жарамды мәндер: {{.Levels}}",
|
||||||
"invalid log encoding": "Жарамсыз кодтау параметрі. Қазіргі уақытта орнатылған: {{.Encoding}}. Жарамды мәндер: {{.Encodings}}",
|
"invalid log encoding": "Жарамсыз кодтау параметрі. Қазіргі уақытта орнатылған: {{.Encoding}}. Жарамды мәндер: {{.Encodings}}",
|
||||||
|
|||||||
@@ -38,6 +38,10 @@
|
|||||||
"cmd.daemon.block.add.FlagUsage.reason": "Причина блокировки.",
|
"cmd.daemon.block.add.FlagUsage.reason": "Причина блокировки.",
|
||||||
"block_add_ip_success": "IP адрес успешно добавлен в список заблокированных.",
|
"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": "Ошибка команды",
|
"Command error": "Ошибка команды",
|
||||||
"invalid log level": "В настройках указан не верный уровень log. Сейчас указан: {{.Level}}. Допустимые значения: {{.Levels}}",
|
"invalid log level": "В настройках указан не верный уровень log. Сейчас указан: {{.Level}}. Допустимые значения: {{.Levels}}",
|
||||||
"invalid log encoding": "Неверная настройка encoding. Сейчас указан: {{.Encoding}}. Допустимые значения: {{.Encodings}}",
|
"invalid log encoding": "Неверная настройка encoding. Сейчас указан: {{.Encoding}}. Допустимые значения: {{.Encodings}}",
|
||||||
|
|||||||
Reference in New Issue
Block a user