updated ipbl
This commit is contained in:
parent
5b6fd8654a
commit
8eecf6d52d
@ -29,6 +29,7 @@ build() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Building project"
|
echo "Building project"
|
||||||
|
go generate ${SRCFILES}
|
||||||
go build -o ${PROJECTNAME} ${GOOPTIONS} ${SRCFILES}
|
go build -o ${PROJECTNAME} ${GOOPTIONS} ${SRCFILES}
|
||||||
|
|
||||||
if [[ ! -z ${DRONE_TAG} ]]
|
if [[ ! -z ${DRONE_TAG} ]]
|
||||||
|
@ -1,42 +1,44 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"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"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/ipbl"
|
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/ipblws"
|
"git.paulbsd.com/paulbsd/ipbl/src/routers"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"github.com/robfig/cron"
|
"github.com/robfig/cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
//var version string
|
//go:generate ../../scripts/version.sh
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
var ctx context.Context
|
||||||
var cfg config.Config
|
var cfg config.Config
|
||||||
cfg.GetConfig()
|
cfg.GetConfig()
|
||||||
//cfg.Options.Version = version
|
cfg.Options.Version = version
|
||||||
|
|
||||||
// Initialize database app context
|
// Initialize database app context
|
||||||
err := database.Init(&cfg)
|
err := database.Initialize(&ctx, &cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
defer cfg.Db.Close()
|
defer cfg.Db.Close()
|
||||||
|
|
||||||
// Handles IP with no reverse DNS
|
// Handles IP with no reverse DNS
|
||||||
go ipbl.ScanIP(&cfg)
|
go models.ScanIP(&cfg)
|
||||||
|
|
||||||
// Add cron task to handle them
|
// Add cron task to handle them
|
||||||
cr := cron.New()
|
cr := cron.New()
|
||||||
cr.AddFunc("0 * * * * *", func() {
|
cr.AddFunc("0 * * * * *", func() {
|
||||||
ipbl.ScanIP(&cfg)
|
models.ScanIP(&cfg)
|
||||||
})
|
})
|
||||||
cr.Start()
|
cr.Start()
|
||||||
|
|
||||||
// Run the ipbl web service
|
// Run the ipbl web service
|
||||||
err = ipblws.RunServer(&cfg)
|
err = routers.RunServer(&ctx, &cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
3
cmd/ipbl/version.go
Normal file
3
cmd/ipbl/version.go
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
var version = "1.0.0"
|
6
scripts/version.sh
Executable file
6
scripts/version.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
VERSION=$(git tag | tail -n 1)
|
||||||
|
echo 'package main
|
||||||
|
|
||||||
|
var version = "'${VERSION}'"' > version.go
|
9
src/api/ip.go
Normal file
9
src/api/ip.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
// IP describe IP objects via API calls
|
||||||
|
type IP struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
IP string `json:"ip"`
|
||||||
|
Rdns string `json:"rdns"`
|
||||||
|
Src string `json:"src"`
|
||||||
|
}
|
@ -31,12 +31,12 @@ func (cfg *Config) GetConfig() error {
|
|||||||
cfg.Switchs.Init = init
|
cfg.Switchs.Init = init
|
||||||
cfg.Switchs.Port = port
|
cfg.Switchs.Port = port
|
||||||
|
|
||||||
inicfg, err := ini.Load(configfile)
|
var inicfg, err = ini.Load(configfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ipblsection := inicfg.Section("ipbl")
|
var ipblsection = inicfg.Section("ipbl")
|
||||||
|
|
||||||
cfg.DbParams.DbHostname = ipblsection.Key("hostname").MustString("localhost")
|
cfg.DbParams.DbHostname = ipblsection.Key("hostname").MustString("localhost")
|
||||||
cfg.DbParams.DbUsername = ipblsection.Key("username").MustString("username")
|
cfg.DbParams.DbUsername = ipblsection.Key("username").MustString("username")
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/ipbl"
|
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
"xorm.io/xorm/names"
|
"xorm.io/xorm/names"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Init creates connection to database and exec Schema
|
// Init creates connection to database and exec Schema
|
||||||
func Init(cfg *config.Config) (err error) {
|
func Initialize(ctx *context.Context, cfg *config.Config) (err error) {
|
||||||
databaseEngine := "postgres"
|
var databaseEngine = "postgres"
|
||||||
tables := []interface{}{ipbl.IP{}, ipbl.Cfg{}, ipbl.Src{}}
|
var tables = []interface{}{models.IP{}, models.Cfg{}, models.Src{}}
|
||||||
|
|
||||||
cfg.Db, err = xorm.NewEngine(databaseEngine,
|
cfg.Db, err = xorm.NewEngine(databaseEngine,
|
||||||
fmt.Sprintf("%s://%s:%s@%s/%s",
|
fmt.Sprintf("%s://%s:%s@%s/%s",
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package ipbl
|
|
||||||
|
|
||||||
// Cfg is ipbl config
|
|
||||||
type Cfg struct {
|
|
||||||
ID int `xorm:"pk autoincr" json:"-"`
|
|
||||||
Key string `xorm:"text notnull unique" json:"key"`
|
|
||||||
Value string `xorm:"text default" json:"value"`
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
package ipblws
|
|
@ -1,17 +0,0 @@
|
|||||||
package ipblws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ConfigAccess make ip authorization to configuration
|
|
||||||
func ConfigAccess(cfg config.Config, ip string) (ret bool) {
|
|
||||||
switch ip {
|
|
||||||
case "127.0.0.1":
|
|
||||||
return true
|
|
||||||
case "::1":
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
21
src/models/cfg.go
Normal file
21
src/models/cfg.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetWhitelists(cfg config.Config) (res []string) {
|
||||||
|
var w = Cfg{Key: "whitelist"}
|
||||||
|
cfg.Db.Get(&w)
|
||||||
|
res = strings.Split(w.Value, ",")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cfg is ipbl config
|
||||||
|
type Cfg struct {
|
||||||
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
|
Key string `xorm:"text notnull unique" json:"key"`
|
||||||
|
Value string `xorm:"text default" json:"value"`
|
||||||
|
}
|
@ -1,21 +1,50 @@
|
|||||||
package ipbl
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.paulbsd.com/paulbsd/ipbl/src/api"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i *IP) UpdateRDNS() (result string) {
|
// GetIps ...
|
||||||
|
func GetIps(ctx *context.Context, config *config.Config, limit int) (apimailboxes []*api.IP, err error) {
|
||||||
|
var ips []IP
|
||||||
|
err = config.Db.Limit(limit).Find(&ips)
|
||||||
|
for _, ml := range ips {
|
||||||
|
apimailboxes = append(apimailboxes, ml.APIFormat())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIp ...
|
||||||
|
func GetIp(ctx *context.Context, config *config.Config, ipquery interface{}) (apiip *api.IP, err error) {
|
||||||
|
var ip IP
|
||||||
|
has, err := config.Db.Where("ip = ?", ipquery).Get(&ip)
|
||||||
|
if !has {
|
||||||
|
err = fmt.Errorf("Not Found")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apiip = ip.APIFormat()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IP) UpdateRDNS() (result string, err error) {
|
||||||
res, err := net.LookupAddr(i.IP)
|
res, err := net.LookupAddr(i.IP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
result = ""
|
||||||
|
} else {
|
||||||
|
result = res[0]
|
||||||
}
|
}
|
||||||
return res[0]
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IP) InsertIP(cfg *config.Config) (num int64, err error) {
|
func (i *IP) InsertIP(cfg *config.Config) (num int64, err error) {
|
||||||
@ -36,13 +65,12 @@ func InsertIPBulk(cfg *config.Config, ips *[]IP) (numinserts int64, numfail int6
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ScanIP(cfg *config.Config) (err error) {
|
func ScanIP(cfg *config.Config) (err error) {
|
||||||
log.Println("Starting set of rdns")
|
|
||||||
for {
|
for {
|
||||||
var orphans = []IP{}
|
var orphans = []IP{}
|
||||||
cfg.Db.Where("rdns IS NULL").Asc("ip").Find(&orphans)
|
cfg.Db.Where("rdns IS NULL").Asc("ip").Find(&orphans)
|
||||||
if 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 == "" {
|
||||||
fmt.Printf("Set \"none\" rdns to IP %s\n", i.IP)
|
fmt.Printf("Set \"none\" rdns to IP %s\n", i.IP)
|
||||||
i.Rdns.String = "none"
|
i.Rdns.String = "none"
|
||||||
@ -60,10 +88,22 @@ func ScanIP(cfg *config.Config) (err error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Println("End set of rdns")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// APIFormat returns a JSON formatted object of IP
|
||||||
|
func (admin *IP) APIFormat() *api.IP {
|
||||||
|
if admin == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &api.IP{
|
||||||
|
ID: admin.ID,
|
||||||
|
IP: admin.IP,
|
||||||
|
Rdns: admin.Rdns.String,
|
||||||
|
Src: admin.Src,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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:"-"`
|
@ -1,4 +1,4 @@
|
|||||||
package ipbl
|
package models
|
||||||
|
|
||||||
// Src is src types
|
// Src is src types
|
||||||
type Src struct {
|
type Src struct {
|
3
src/models/utils.go
Normal file
3
src/models/utils.go
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
const keyname string = "id"
|
@ -1,23 +1,20 @@
|
|||||||
package ipblws
|
package routers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/ipbl"
|
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunServer runs the main echo HTTP server
|
// RegisterRoutes runs the main echo HTTP server
|
||||||
func RunServer(cfg *config.Config) (err error) {
|
func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
||||||
e := echo.New()
|
|
||||||
|
|
||||||
e.HideBanner = cfg.Options.HideBanner
|
|
||||||
|
|
||||||
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">
|
||||||
@ -25,58 +22,56 @@ func RunServer(cfg *config.Config) (err error) {
|
|||||||
</body>
|
</body>
|
||||||
</html>`)
|
</html>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// IPs
|
||||||
e.GET("/ip/:ip", func(c echo.Context) (err error) {
|
e.GET("/ip/:ip", func(c echo.Context) (err error) {
|
||||||
var ip = ipbl.IP{IP: c.Param("ip")}
|
ret, err := models.GetIp(ctx, cfg, c.Param("ip"))
|
||||||
res, _ := cfg.Db.Get(&ip)
|
return JSONResult(c, err, ret)
|
||||||
if res {
|
|
||||||
return c.JSON(http.StatusOK, ip)
|
|
||||||
}
|
|
||||||
msg := fmt.Sprintf("IP %s not found", c.Param("ip"))
|
|
||||||
log.Println(msg)
|
|
||||||
return c.JSON(http.StatusNotFound, msg)
|
|
||||||
})
|
})
|
||||||
e.POST("/ip", func(c echo.Context) (err error) {
|
e.POST("/ip", func(c echo.Context) (err error) {
|
||||||
var ip = new(ipbl.IP)
|
var ip = new(models.IP)
|
||||||
err = c.Bind(ip)
|
err = c.Bind(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, "Error when parsing body")
|
return JSONResult(c, fmt.Errorf("Error when parsing body"), "")
|
||||||
}
|
}
|
||||||
num, err := ip.InsertIP(cfg)
|
num, err := ip.InsertIP(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, "Error inserting data")
|
return JSONResult(c, fmt.Errorf("Error inserting data"), "")
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintf("Inserted %d IP", num)
|
var msg = fmt.Sprintf("Inserted %d IP", num)
|
||||||
log.Println(msg)
|
log.Println(msg)
|
||||||
return c.JSON(http.StatusOK, msg)
|
return c.JSON(http.StatusOK, msg)
|
||||||
})
|
})
|
||||||
e.GET("/ips", func(c echo.Context) (err error) {
|
e.GET("/ips", func(c echo.Context) (err error) {
|
||||||
var ips = []ipbl.IP{}
|
limit := 50
|
||||||
var limit int = 50
|
|
||||||
if c.QueryParam("limit") != "" {
|
if c.QueryParam("limit") != "" {
|
||||||
limit, err = strconv.Atoi(c.QueryParam("limit"))
|
limit, _ = strconv.Atoi(c.QueryParam("limit"))
|
||||||
if err != nil {
|
|
||||||
limit = 50
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cfg.Db.Limit(limit).Desc("created").Find(&ips)
|
ret, err := models.GetIps(ctx, cfg, limit)
|
||||||
return c.JSON(http.StatusOK, ips)
|
return JSONResult(c, err, ret)
|
||||||
})
|
})
|
||||||
e.POST("/ips", func(c echo.Context) (err error) {
|
e.POST("/ips", func(c echo.Context) (err error) {
|
||||||
var ips = []ipbl.IP{}
|
var ips = []models.IP{}
|
||||||
err = c.Bind(&ips)
|
err = c.Bind(&ips)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, "Error when parsing body")
|
return c.JSON(http.StatusInternalServerError, "Error when parsing body")
|
||||||
}
|
}
|
||||||
numinsert, numfail, _ := ipbl.InsertIPBulk(cfg, &ips)
|
numinsert, numfail, _ := models.InsertIPBulk(cfg, &ips)
|
||||||
msg := fmt.Sprintf("Inserted %d IP, %d errors", numinsert, numfail)
|
msg := fmt.Sprintf("Inserted %d IP, %d errors", numinsert, numfail)
|
||||||
log.Println(msg)
|
log.Println(msg)
|
||||||
return c.JSON(http.StatusOK, msg)
|
return c.JSON(http.StatusOK, msg)
|
||||||
})
|
})
|
||||||
|
e.GET("/ips/whitelist", func(c echo.Context) (err error) {
|
||||||
|
var whitelists = models.GetWhitelists(*cfg)
|
||||||
|
if len(whitelists) > 0 {
|
||||||
|
return c.JSON(http.StatusOK, whitelists)
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusInternalServerError, "")
|
||||||
|
})
|
||||||
|
|
||||||
e.Logger.Fatal(
|
e.Logger.Fatal(
|
||||||
e.Start(
|
e.Start(
|
||||||
fmt.Sprintf(":%d",
|
fmt.Sprintf(":%d",
|
||||||
cfg.Switchs.Port)))
|
cfg.Switchs.Port)))
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
47
src/routers/main.go
Normal file
47
src/routers/main.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package routers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RunServer runs the main echo server
|
||||||
|
func RunServer(ctx *context.Context, cfg *config.Config) (err error) {
|
||||||
|
e := echo.New()
|
||||||
|
e.HideBanner = true
|
||||||
|
|
||||||
|
RegisterRoutes(e, ctx, cfg)
|
||||||
|
|
||||||
|
e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", cfg.Switchs.Port)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONResult handles returns and error management on backend api
|
||||||
|
func JSONResult(c echo.Context, inputerr error, data interface{}) (err error) {
|
||||||
|
if inputerr != nil {
|
||||||
|
if inputerr.Error() == "Not Found" {
|
||||||
|
return c.JSON(http.StatusNotFound, inputerr.Error())
|
||||||
|
}
|
||||||
|
if inputerr.Error() == "Error when parsing body" {
|
||||||
|
return c.JSON(http.StatusBadRequest, inputerr.Error())
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusInternalServerError, inputerr.Error())
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigAccess make ip authorization to configuration
|
||||||
|
func ConfigAccess(cfg config.Config, ip string) (ret bool) {
|
||||||
|
switch ip {
|
||||||
|
case "127.0.0.1":
|
||||||
|
return true
|
||||||
|
case "::1":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user