connection blacklisting
This commit is contained in:
@@ -2,10 +2,8 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/MDrollette/i2p-tools/reseed"
|
"github.com/MDrollette/i2p-tools/reseed"
|
||||||
@@ -153,17 +151,15 @@ func reseedAction(c *cli.Context) {
|
|||||||
|
|
||||||
// create a server
|
// create a server
|
||||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||||
|
blacklist := reseed.NewBlacklist()
|
||||||
|
server.Blacklist = blacklist
|
||||||
server.Reseeder = reseeder
|
server.Reseeder = reseeder
|
||||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||||
|
|
||||||
// load a blacklist
|
// load a blacklist
|
||||||
blacklistFile := c.String("blacklist")
|
blacklistFile := c.String("blacklist")
|
||||||
if blacklistFile != "" {
|
if "" != blacklistFile {
|
||||||
if content, err := ioutil.ReadFile(blacklistFile); err == nil {
|
blacklist.LoadFile(blacklistFile)
|
||||||
server.Blacklist = strings.Split(string(content), "\n")
|
|
||||||
} else {
|
|
||||||
log.Fatalln("Failed to load blacklist: ", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if tlsHost != "" && tlsCert != "" && tlsKey != "" {
|
if tlsHost != "" && tlsCert != "" && tlsKey != "" {
|
||||||
|
|||||||
78
reseed/blacklist.go
Normal file
78
reseed/blacklist.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package reseed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Blacklist struct {
|
||||||
|
blacklist map[string]bool
|
||||||
|
m sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBlacklist() *Blacklist {
|
||||||
|
return &Blacklist{blacklist: make(map[string]bool), m: sync.RWMutex{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Blacklist) LoadFile(file string) error {
|
||||||
|
if file != "" {
|
||||||
|
if content, err := ioutil.ReadFile(file); err == nil {
|
||||||
|
for _, ip := range strings.Split(string(content), "\n") {
|
||||||
|
s.BlockIp(ip)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Blacklist) BlockIp(ip string) {
|
||||||
|
s.m.Lock()
|
||||||
|
defer s.m.Unlock()
|
||||||
|
|
||||||
|
s.blacklist[ip] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Blacklist) isBlocked(ip string) bool {
|
||||||
|
s.m.RLock()
|
||||||
|
defer s.m.RUnlock()
|
||||||
|
|
||||||
|
blocked, found := s.blacklist[ip]
|
||||||
|
|
||||||
|
return found && blocked
|
||||||
|
}
|
||||||
|
|
||||||
|
type blacklistListener struct {
|
||||||
|
*net.TCPListener
|
||||||
|
blacklist *Blacklist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ln blacklistListener) Accept() (net.Conn, error) {
|
||||||
|
tc, err := ln.AcceptTCP()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ip, _, err := net.SplitHostPort(tc.RemoteAddr().String())
|
||||||
|
if err != nil {
|
||||||
|
tc.Close()
|
||||||
|
return tc, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ln.blacklist.isBlocked(ip) {
|
||||||
|
tc.Close()
|
||||||
|
log.Printf("blocked connection from: %s\n", ip)
|
||||||
|
return tc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return tc, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBlacklistListener(ln net.Listener, bl *Blacklist) blacklistListener {
|
||||||
|
return blacklistListener{ln.(*net.TCPListener), bl}
|
||||||
|
}
|
||||||
@@ -20,43 +20,52 @@ const (
|
|||||||
I2P_USER_AGENT = "Wget/1.11.4"
|
I2P_USER_AGENT = "Wget/1.11.4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Listener struct {
|
|
||||||
net.Listener
|
|
||||||
Blacklist []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (nl Listener) Accept() (net.Conn, error) {
|
|
||||||
for {
|
|
||||||
c, err := nl.Listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
host, port, err := net.SplitHostPort(c.RemoteAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
l.Printf("accept fail: %s\n", err.Error())
|
|
||||||
go c.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := net.ParseIP(host)
|
|
||||||
|
|
||||||
for _, cidr := range nl.Blacklist {
|
|
||||||
if _, ipnet, err := net.ParseCIDR(cidr); err == nil {
|
|
||||||
if ipnet.Contains(ip) {
|
|
||||||
l.Printf("allow conn from: %s:%s\n", host, port)
|
|
||||||
return c, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
go c.Close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
*http.Server
|
*http.Server
|
||||||
Reseeder Reseeder
|
Reseeder Reseeder
|
||||||
|
Blacklist *Blacklist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *Server) ListenAndServe() error {
|
||||||
|
addr := srv.Addr
|
||||||
|
if addr == "" {
|
||||||
|
addr = ":http"
|
||||||
|
}
|
||||||
|
ln, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return srv.Serve(newBlacklistListener(ln, srv.Blacklist))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
|
||||||
|
addr := srv.Addr
|
||||||
|
if addr == "" {
|
||||||
|
addr = ":https"
|
||||||
|
}
|
||||||
|
config := &tls.Config{}
|
||||||
|
if srv.TLSConfig != nil {
|
||||||
|
*config = *srv.TLSConfig
|
||||||
|
}
|
||||||
|
if config.NextProtos == nil {
|
||||||
|
config.NextProtos = []string{"http/1.1"}
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
config.Certificates = make([]tls.Certificate, 1)
|
||||||
|
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ln, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsListener := tls.NewListener(newBlacklistListener(ln, srv.Blacklist), config)
|
||||||
|
return srv.Serve(tlsListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(prefix string, trustProxy bool) *Server {
|
func NewServer(prefix string, trustProxy bool) *Server {
|
||||||
@@ -80,7 +89,7 @@ func NewServer(prefix string, trustProxy bool) *Server {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
h := &http.Server{TLSConfig: config}
|
h := &http.Server{TLSConfig: config}
|
||||||
server := Server{h, nil}
|
server := Server{Server: h, Reseeder: nil}
|
||||||
|
|
||||||
th := throttled.RateLimit(throttled.PerDay(4), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(100000))
|
th := throttled.RateLimit(throttled.PerDay(4), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(100000))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user