mirror of
https://github.com/apernet/OpenGFW.git
synced 2024-11-14 14:29:22 +08:00
feat: rules hot reload via SIGHUP (#44)
This commit is contained in:
parent
8d94400855
commit
f8f0153664
@ -25,6 +25,7 @@ OpenGFW は、Linux 上の [GFW](https://en.wikipedia.org/wiki/Great_Firewall)
|
|||||||
- フローベースのマルチコア負荷分散
|
- フローベースのマルチコア負荷分散
|
||||||
- 接続オフロード
|
- 接続オフロード
|
||||||
- [expr](https://github.com/expr-lang/expr) に基づく強力なルールエンジン
|
- [expr](https://github.com/expr-lang/expr) に基づく強力なルールエンジン
|
||||||
|
- ルールのホットリロード (`SIGHUP` を送信してリロード)
|
||||||
- 柔軟なアナライザ&モディファイアフレームワーク
|
- 柔軟なアナライザ&モディファイアフレームワーク
|
||||||
- 拡張可能な IO 実装(今のところ NFQueue のみ)
|
- 拡張可能な IO 実装(今のところ NFQueue のみ)
|
||||||
- [WIP] ウェブ UI
|
- [WIP] ウェブ UI
|
||||||
|
@ -29,6 +29,7 @@ Linux that's in many ways more powerful than the real thing. It's cyber sovereig
|
|||||||
- Flow-based multicore load balancing
|
- Flow-based multicore load balancing
|
||||||
- Connection offloading
|
- Connection offloading
|
||||||
- Powerful rule engine based on [expr](https://github.com/expr-lang/expr)
|
- Powerful rule engine based on [expr](https://github.com/expr-lang/expr)
|
||||||
|
- Hot-reloadable rules (send `SIGHUP` to reload)
|
||||||
- Flexible analyzer & modifier framework
|
- Flexible analyzer & modifier framework
|
||||||
- Extensible IO implementation (only NFQueue for now)
|
- Extensible IO implementation (only NFQueue for now)
|
||||||
- [WIP] Web UI
|
- [WIP] Web UI
|
||||||
|
@ -25,6 +25,7 @@ OpenGFW 是一个 Linux 上灵活、易用、开源的 [GFW](https://zh.wikipedi
|
|||||||
- 基于流的多核负载均衡
|
- 基于流的多核负载均衡
|
||||||
- 连接 offloading
|
- 连接 offloading
|
||||||
- 基于 [expr](https://github.com/expr-lang/expr) 的强大规则引擎
|
- 基于 [expr](https://github.com/expr-lang/expr) 的强大规则引擎
|
||||||
|
- 规则可以热重载 (发送 `SIGHUP` 信号)
|
||||||
- 灵活的协议解析和修改框架
|
- 灵活的协议解析和修改框架
|
||||||
- 可扩展的 IO 实现 (目前只有 NFQueue)
|
- 可扩展的 IO 实现 (目前只有 NFQueue)
|
||||||
- [开发中] Web UI
|
- [开发中] Web UI
|
||||||
|
35
cmd/root.go
35
cmd/root.go
@ -7,6 +7,7 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/apernet/OpenGFW/analyzer"
|
"github.com/apernet/OpenGFW/analyzer"
|
||||||
"github.com/apernet/OpenGFW/analyzer/tcp"
|
"github.com/apernet/OpenGFW/analyzer/tcp"
|
||||||
@ -267,14 +268,42 @@ func runMain(cmd *cobra.Command, args []string) {
|
|||||||
logger.Fatal("failed to initialize engine", zap.Error(err))
|
logger.Fatal("failed to initialize engine", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Signal handling
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
go func() {
|
go func() {
|
||||||
sigChan := make(chan os.Signal)
|
// Graceful shutdown
|
||||||
signal.Notify(sigChan, os.Interrupt, os.Kill)
|
shutdownChan := make(chan os.Signal)
|
||||||
<-sigChan
|
signal.Notify(shutdownChan, os.Interrupt, os.Kill)
|
||||||
|
<-shutdownChan
|
||||||
logger.Info("shutting down gracefully...")
|
logger.Info("shutting down gracefully...")
|
||||||
cancelFunc()
|
cancelFunc()
|
||||||
}()
|
}()
|
||||||
|
go func() {
|
||||||
|
// Rule reload
|
||||||
|
reloadChan := make(chan os.Signal)
|
||||||
|
signal.Notify(reloadChan, syscall.SIGHUP)
|
||||||
|
for {
|
||||||
|
<-reloadChan
|
||||||
|
logger.Info("reloading rules")
|
||||||
|
rawRs, err := ruleset.ExprRulesFromYAML(args[0])
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to load rules, using old rules", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
rs, err := ruleset.CompileExprRules(rawRs, analyzers, modifiers, rsConfig)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to compile rules, using old rules", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err = en.UpdateRuleset(rs)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to update ruleset", zap.Error(err))
|
||||||
|
} else {
|
||||||
|
logger.Info("rules reloaded")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
logger.Info("engine started")
|
logger.Info("engine started")
|
||||||
logger.Info("engine exited", zap.Error(en.Run(ctx)))
|
logger.Info("engine exited", zap.Error(en.Run(ctx)))
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,10 @@ func (w *worker) Run(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) UpdateRuleset(r ruleset.Ruleset) error {
|
func (w *worker) UpdateRuleset(r ruleset.Ruleset) error {
|
||||||
return w.tcpStreamFactory.UpdateRuleset(r)
|
if err := w.tcpStreamFactory.UpdateRuleset(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return w.udpStreamFactory.UpdateRuleset(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handle(streamID uint32, p gopacket.Packet) (io.Verdict, []byte) {
|
func (w *worker) handle(streamID uint32, p gopacket.Packet) (io.Verdict, []byte) {
|
||||||
|
Loading…
Reference in New Issue
Block a user