123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package traefik_safeline
- import (
- "context"
- "fmt"
- "log"
- "net/http"
- "os"
- "sync"
- t1k "github.com/chaitin/t1k-go"
- )
- // Package example a example plugin.
- // Config the plugin configuration.
- type Config struct {
- // Addr is the address for the detector
- Addr string `yaml:"addr"`
- PoolSize int `yaml:"pool_size"`
- }
- // CreateConfig creates the default plugin configuration.
- func CreateConfig() *Config {
- return &Config{
- Addr: "",
- PoolSize: 100,
- }
- }
- // Safeline a plugin.
- type Safeline struct {
- next http.Handler
- server *t1k.Server
- name string
- config *Config
- logger *log.Logger
- mu sync.Mutex
- }
- // New created a new plugin.
- func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
- logger := log.New(os.Stdout, "safeline", log.LstdFlags)
- logger.Printf("config: %+v", config)
- return &Safeline{
- next: next,
- name: name,
- config: config,
- logger: logger,
- }, nil
- }
- func (s *Safeline) initServer() error {
- if s.server != nil {
- return nil
- }
- s.mu.Lock()
- defer s.mu.Unlock()
- if s.server == nil {
- server, err := t1k.NewWithPoolSize(s.config.Addr, s.config.PoolSize)
- if err != nil {
- return err
- }
- s.server = server
- }
- return nil
- }
- func (s *Safeline) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
- defer func() {
- if r := recover(); r != nil {
- s.logger.Printf("panic: %s", r)
- }
- }()
- if err := s.initServer(); err != nil {
- s.logger.Printf("error in initServer: %s", err)
- s.next.ServeHTTP(rw, req)
- return
- }
- rw.Header().Set("X-Chaitin-waf", "safeline")
- result, err := s.server.DetectHttpRequest(req)
- if err != nil {
- s.logger.Printf("error in detection: \n%+v\n", err)
- s.next.ServeHTTP(rw, req)
- return
- }
- if result.Blocked() {
- rw.WriteHeader(result.StatusCode())
- msg := fmt.Sprintf(`{"code": %d, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "%s"}`,
- result.StatusCode(),
- result.EventID(),
- )
- _, _ = rw.Write([]byte(msg))
- return
- }
- s.next.ServeHTTP(rw, req)
- //rw.WriteHeader(http.StatusForbidden)
- //_, _ = rw.Write([]byte("Inject by safeline\n"))
- }
|