added endpoints for cfg update
This commit is contained in:
parent
e47ed6adfe
commit
ee06baeb17
@ -1,9 +1,10 @@
|
|||||||
# ipbl
|
# ipbl
|
||||||
|
|
||||||
[![Build Status](https://drone.paulbsd.com/api/badges/paulbsd/ipbl/status.svg)](https://drone.paulbsd.com/paulbsd/ipbl)
|
[![Build Status](https://drone.paulbsd.com/api/badges/paulbsd/ipbl/status.svg)](https://drone.paulbsd.com/paulbsd/ipbl)
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
ipbl is ...
|
ipbl is a webservice storing IP address blacklist
|
||||||
|
|
||||||
## Howto
|
## Howto
|
||||||
|
|
||||||
@ -59,4 +60,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
The views and conclusions contained in the software and documentation are those
|
The views and conclusions contained in the software and documentation are those
|
||||||
of the authors and should not be interpreted as representing official policies,
|
of the authors and should not be interpreted as representing official policies,
|
||||||
either expressed or implied, of this project.
|
either expressed or implied, of this project.
|
||||||
```
|
```
|
||||||
|
@ -2,7 +2,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/database"
|
"git.paulbsd.com/paulbsd/ipbl/src/database"
|
||||||
@ -18,6 +20,10 @@ func main() {
|
|||||||
var cfg config.Config
|
var cfg config.Config
|
||||||
cfg.GetConfig()
|
cfg.GetConfig()
|
||||||
cfg.Options.Version = version
|
cfg.Options.Version = version
|
||||||
|
if cfg.Switchs.Version {
|
||||||
|
fmt.Printf("ipbl version %s\n", cfg.Options.Version)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize database app context
|
// Initialize database app context
|
||||||
err := database.Initialize(&ctx, &cfg)
|
err := database.Initialize(&ctx, &cfg)
|
||||||
|
@ -15,6 +15,7 @@ func (cfg *Config) GetConfig() error {
|
|||||||
var drop bool
|
var drop bool
|
||||||
var init bool
|
var init bool
|
||||||
var port int
|
var port int
|
||||||
|
var version bool
|
||||||
|
|
||||||
flag.Usage = utils.Usage
|
flag.Usage = utils.Usage
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ func (cfg *Config) GetConfig() error {
|
|||||||
flag.BoolVar(&debug, "debug", false, "If debug logging must be enabled")
|
flag.BoolVar(&debug, "debug", false, "If debug logging must be enabled")
|
||||||
flag.BoolVar(&drop, "drop", false, "If dropping tables must occur")
|
flag.BoolVar(&drop, "drop", false, "If dropping tables must occur")
|
||||||
flag.BoolVar(&init, "init", false, "If init of database must be done")
|
flag.BoolVar(&init, "init", false, "If init of database must be done")
|
||||||
|
flag.BoolVar(&version, "version", false, "Show version")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@ -30,6 +32,7 @@ func (cfg *Config) GetConfig() error {
|
|||||||
cfg.Switchs.Drop = drop
|
cfg.Switchs.Drop = drop
|
||||||
cfg.Switchs.Init = init
|
cfg.Switchs.Init = init
|
||||||
cfg.Switchs.Port = port
|
cfg.Switchs.Port = port
|
||||||
|
cfg.Switchs.Version = version
|
||||||
|
|
||||||
var inicfg, err = ini.Load(configfile)
|
var inicfg, err = ini.Load(configfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -61,10 +64,11 @@ type Config struct {
|
|||||||
HideBanner bool `json:"hidebanner"`
|
HideBanner bool `json:"hidebanner"`
|
||||||
} `json:"-"`
|
} `json:"-"`
|
||||||
Switchs struct {
|
Switchs struct {
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
NoFeed bool `json:"nofeed"`
|
NoFeed bool `json:"nofeed"`
|
||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
Drop bool `json:"drop"`
|
Drop bool `json:"drop"`
|
||||||
Init bool `json:"init"`
|
Init bool `json:"init"`
|
||||||
|
Version bool `json:"version"`
|
||||||
} `json:"-"`
|
} `json:"-"`
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,63 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//var ipv4_regex = `^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})/`
|
||||||
|
var ipv4_cidr_regex = `^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|)){4}\/([1-3])?([0-9])?$)`
|
||||||
|
|
||||||
// GetWhitelists ...
|
// GetWhitelists ...
|
||||||
func GetWhitelists(cfg config.Config) (res []string) {
|
func GetWhitelists(cfg config.Config) (res []string, err error) {
|
||||||
var w = Cfg{Key: "whitelist"}
|
var w = Cfg{Key: "whitelist"}
|
||||||
cfg.Db.Get(&w)
|
if exists, _ := cfg.Db.Get(&w); exists {
|
||||||
res = strings.Split(w.Value, ",")
|
res = strings.Split(w.Value, ",")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wl Whitelist) Insert(cfg config.Config) (err error) {
|
||||||
|
var w = Cfg{Key: "whitelist"}
|
||||||
|
exists, _ := cfg.Db.Get(&w)
|
||||||
|
if exists {
|
||||||
|
existing, _ := GetWhitelists(cfg)
|
||||||
|
existing = append(existing, wl.IP)
|
||||||
|
w.Value = strings.Join(existing, ",")
|
||||||
|
cfg.Db.ID(w.ID).Update(&w)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("no whitelist updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wl Whitelist) Delete(cfg config.Config, ip string) (err error) {
|
||||||
|
var w = Cfg{Key: "whitelist"}
|
||||||
|
exists, _ := cfg.Db.Get(&w)
|
||||||
|
var updated []string
|
||||||
|
if exists {
|
||||||
|
existing, _ := GetWhitelists(cfg)
|
||||||
|
for _, sip := range existing {
|
||||||
|
if sip != ip {
|
||||||
|
updated = append(updated, sip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Value = strings.Join(updated, ",")
|
||||||
|
cfg.Db.ID(w.ID).Update(&w)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("no whitelist updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wl Whitelist) Verify() bool {
|
||||||
|
reg := regexp.MustCompile(ipv4_cidr_regex)
|
||||||
|
return reg.MatchString(wl.IP)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Whitelist struct {
|
||||||
|
IP string `json:"ip"`
|
||||||
|
}
|
||||||
|
|
||||||
// Cfg is ipbl config
|
// Cfg is ipbl config
|
||||||
type Cfg struct {
|
type Cfg struct {
|
||||||
ID int `xorm:"pk autoincr" json:"-"`
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/api"
|
"git.paulbsd.com/paulbsd/ipbl/src/api"
|
||||||
@ -40,7 +39,7 @@ func GetIP(ctx *context.Context, config *config.Config, ipquery interface{}) (ap
|
|||||||
var ip IP
|
var ip IP
|
||||||
has, err := config.Db.Where("ip = ?", ipquery).Get(&ip)
|
has, err := config.Db.Where("ip = ?", ipquery).Get(&ip)
|
||||||
if !has {
|
if !has {
|
||||||
err = fmt.Errorf("Not Found")
|
err = fmt.Errorf("not found")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -93,9 +92,8 @@ func InsertIPBulk(cfg *config.Config, ips *[]IP) (numinserts int64, numupdates i
|
|||||||
// ScanIP ...
|
// ScanIP ...
|
||||||
func ScanIP(cfg *config.Config) (err error) {
|
func ScanIP(cfg *config.Config) (err error) {
|
||||||
for {
|
for {
|
||||||
var orphans = []IP{}
|
orphans := []IP{}
|
||||||
cfg.Db.Where("rdns IS NULL").Asc("ip").Find(&orphans)
|
if cfg.Db.Where("rdns IS NULL").Asc("ip").Find(&orphans); len(orphans) > 0 {
|
||||||
if len(orphans) > 0 {
|
|
||||||
for _, i := range orphans {
|
for _, i := range orphans {
|
||||||
reverse, _ := i.UpdateRDNS()
|
reverse, _ := i.UpdateRDNS()
|
||||||
if reverse == "" {
|
if reverse == "" {
|
||||||
@ -130,29 +128,6 @@ func (ip *IP) APIFormat() *api.IP {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func differ(sl1 []IP, sl2 []IP) (toinsert []IP, err error) {
|
|
||||||
var m = make(map[string]IPDiffer)
|
|
||||||
longslice := append(sl1, sl2...)
|
|
||||||
|
|
||||||
for _, v2 := range longslice {
|
|
||||||
if _, v := m[v2.IP]; !v {
|
|
||||||
m[v2.IP] = IPDiffer{IP: v2, Num: 1}
|
|
||||||
} else {
|
|
||||||
if this, ok := m[v2.IP]; ok {
|
|
||||||
this.Num += 1
|
|
||||||
m[v2.IP] = this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, j := range reflect.ValueOf(m).MapKeys() {
|
|
||||||
if m[j.String()].Num == 1 {
|
|
||||||
toinsert = append(toinsert, m[j.String()].IP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// IP describe IP objects
|
// IP describe IP objects
|
||||||
type IP struct {
|
type IP struct {
|
||||||
ID int `xorm:"pk autoincr" json:"-"`
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
@ -162,8 +137,3 @@ type IP struct {
|
|||||||
Created time.Time `xorm:"created notnull" json:"-"`
|
Created time.Time `xorm:"created notnull" json:"-"`
|
||||||
Updated time.Time `xorm:"updated notnull" json:"-"`
|
Updated time.Time `xorm:"updated notnull" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPDiffer struct {
|
|
||||||
IP IP
|
|
||||||
Num int
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,33 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
const keyname string = "id"
|
const keyname string = "id"
|
||||||
|
|
||||||
|
func differ(sl1 []IP, sl2 []IP) (toinsert []IP, err error) {
|
||||||
|
var m = make(map[string]IPDiffer)
|
||||||
|
longslice := append(sl1, sl2...)
|
||||||
|
|
||||||
|
for _, v2 := range longslice {
|
||||||
|
if _, v := m[v2.IP]; !v {
|
||||||
|
m[v2.IP] = IPDiffer{IP: v2, Num: 1}
|
||||||
|
} else {
|
||||||
|
if this, ok := m[v2.IP]; ok {
|
||||||
|
this.Num += 1
|
||||||
|
m[v2.IP] = this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, j := range reflect.ValueOf(m).MapKeys() {
|
||||||
|
if m[j.String()].Num == 1 {
|
||||||
|
toinsert = append(toinsert, m[j.String()].IP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPDiffer struct {
|
||||||
|
IP IP
|
||||||
|
Num int
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@ func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
|||||||
e.GET("/", func(c echo.Context) error {
|
e.GET("/", func(c echo.Context) error {
|
||||||
return c.HTML(http.StatusOK, `<html>
|
return c.HTML(http.StatusOK, `<html>
|
||||||
<body style="background-color: black">
|
<body style="background-color: black">
|
||||||
<p style="color:white">Welcome to ipbl software (https://git.paulbsd.com/paulbsd/ipbl)</p>
|
<p style="color:white">Welcome to ipbl software (<a href="https://git.paulbsd.com/paulbsd/ipbl">https://git.paulbsd.com/paulbsd/ipbl</a>)</p>
|
||||||
</body>
|
</body>
|
||||||
</html>`)
|
</html>`)
|
||||||
})
|
})
|
||||||
@ -76,12 +76,30 @@ func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
|||||||
return c.JSON(http.StatusOK, msg)
|
return c.JSON(http.StatusOK, msg)
|
||||||
})
|
})
|
||||||
e.GET("/ips/whitelist", func(c echo.Context) (err error) {
|
e.GET("/ips/whitelist", func(c echo.Context) (err error) {
|
||||||
var whitelists = models.GetWhitelists(*cfg)
|
whitelists, _ := models.GetWhitelists(*cfg)
|
||||||
if len(whitelists) > 0 {
|
if len(whitelists) > 0 {
|
||||||
return c.JSON(http.StatusOK, whitelists)
|
return c.JSON(http.StatusOK, whitelists)
|
||||||
}
|
}
|
||||||
return c.JSON(http.StatusInternalServerError, "")
|
return c.JSON(http.StatusInternalServerError, "")
|
||||||
})
|
})
|
||||||
|
e.PUT("/ips/whitelist", func(c echo.Context) (err error) {
|
||||||
|
var cidr models.Whitelist
|
||||||
|
err = c.Bind(&cidr)
|
||||||
|
if err == nil && cidr.Verify() {
|
||||||
|
cidr.Insert(*cfg)
|
||||||
|
return c.JSON(http.StatusOK, "Inserted new CIDR")
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusInternalServerError, "Invalid CIDR")
|
||||||
|
})
|
||||||
|
e.DELETE("/ips/whitelist/:ip", func(c echo.Context) (err error) {
|
||||||
|
var ip = c.Param("ip")
|
||||||
|
var cidr models.Whitelist
|
||||||
|
err = cidr.Delete(*cfg, ip)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(http.StatusOK, "Deleted old CIDR")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
e.Logger.Fatal(
|
e.Logger.Fatal(
|
||||||
e.Start(
|
e.Start(
|
||||||
|
@ -3,12 +3,13 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Usage displays possible arguments
|
// Usage displays possible arguments
|
||||||
func Usage() {
|
func Usage() {
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
log.Fatal()
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advice displays possible arguments with warning advices
|
// Advice displays possible arguments with warning advices
|
||||||
@ -17,5 +18,5 @@ func Advice(advice string) {
|
|||||||
if advice != "" {
|
if advice != "" {
|
||||||
log.Fatalln(advice)
|
log.Fatalln(advice)
|
||||||
}
|
}
|
||||||
log.Fatal()
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user