Skip to content

Commit

Permalink
add support of waf (#18)
Browse files Browse the repository at this point in the history
* refactor

* nginx: refactor test-nginx && add to_location in policy && impl waf

* go: impl nginx_templ_cfg_ctl && swap policy && impl waf

* fix doc

* fix cors

* fix doc

* fix spell
  • Loading branch information
woodgear authored Sep 6, 2024
1 parent 53aa7b6 commit fee5ffc
Show file tree
Hide file tree
Showing 107 changed files with 4,005 additions and 1,402 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ kubectl*
fortio/*.json
.flame/
template/nginx/lua/vendor/opentelemetry
*.kconf
docs/.obsidian
template/share/dhparam.pem
5 changes: 5 additions & 0 deletions .vscode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# recommend plugins
```bash
code --install-extension sumneko.lua

```
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RUN go build -buildmode=pie -ldflags '-w -s -linkmode=external -extldflags=-Wl,-
RUN go build -buildmode=pie -ldflags '-w -s -linkmode=external -extldflags=-Wl,-z,relro,-z,now' -v -o /out/operator alauda.io/alb2/cmd/operator
RUN go build -buildmode=pie -ldflags '-w -s -linkmode=external -extldflags=-static' -v -o /out/albctl alauda.io/alb2/cmd/utils/albctl
RUN go build -buildmode=pie -ldflags '-w -s -linkmode=external -extldflags=-Wl,-z,relro,-z,now' -v -o /out/tweak_gen alauda.io/alb2/cmd/utils/tweak_gen
RUN go build -buildmode=pie -ldflags '-w -s -linkmode=external -extldflags=-Wl,-z,relro,-z,now' -v -o /out/ngx_gen alauda.io/alb2/cmd/utils/ngx_gen
RUN ldd /out/albctl || true

FROM ${OPENRESTY_BASE} AS base
Expand All @@ -33,9 +34,10 @@ FROM scratch
## openresty as base image
COPY --from=base / /
COPY ./template/nginx /alb/nginx
COPY ./template/nginx/nginx.tmpl /alb/ctl/template/nginx/nginx.tmpl
COPY ./pkg/controller/ngxconf/nginx.tmpl /alb/ctl/template/nginx/nginx.tmpl
COPY run-alb.sh /alb/ctl/run-alb.sh
COPY --from=go_builder /out/tweak_gen /alb/tools/tweak_gen
COPY --from=go_builder /out/ngx_gen /alb/tools/ngx_gen
COPY --from=go_builder /out/alb /alb/ctl/alb
COPY --from=go_builder /out/migrate /alb/ctl/tools/
COPY --from=go_builder /out/operator /alb/ctl/operator
Expand Down
6 changes: 3 additions & 3 deletions cmd/utils/albctl/cmd/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,10 @@ func checkingress(ctx Ctx) error {
}

should, reason := ing.NewIngressSelect(ing.IngressSelectOpt{
HttpPort: NullOr(alb.Spec.Config.IngressHTTPPort, 80),
HttpsPort: NullOr(alb.Spec.Config.IngressHTTPPort, 443),
HttpPort: NullOr(alb.Alb.Spec.Config.IngressHTTPPort, 80),
HttpsPort: NullOr(alb.Alb.Spec.Config.IngressHTTPPort, 443),
Domain: "cpaas.io",
Name: alb.Name,
Name: alb.Alb.Name,
}, drv).ShouldHandleIngress(alb, ingcr)
fmt.Println("alb:", albkey, "ing:", ingkey, "should-handle-ingress:", should, "reason:", reason)
return nil
Expand Down
27 changes: 27 additions & 0 deletions cmd/utils/ngx_gen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"fmt"
"io"
"os"
"strings"

. "alauda.io/alb2/pkg/controller/ngxconf"
)

func main() {
ngx_raw, err := io.ReadAll(os.Stdin)
if err != nil {
panic(err)
}
ngx, err := NgxTmplCfgFromYaml(string(ngx_raw))
if err != nil {
panic(err)
}

out, err := RenderNginxConfigEmbed(*ngx)
if err != nil {
panic(err)
}
fmt.Print(strings.TrimSpace(out))
}
3 changes: 1 addition & 2 deletions cmd/utils/tylua/tylua/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func (g *TyLua) SetTypeMapping(goType string, tsType string) {
}

func (g *TyLua) Generate(pkg_names []string, boot string, out string) error {

log.Printf("Generating for packages: %v", pkg_names)
pkgs, err := packages.Load(&packages.Config{
Mode: packages.NeedSyntax | packages.NeedFiles,
Expand Down Expand Up @@ -98,5 +97,5 @@ func (g *TyLua) Generate(pkg_names []string, boot string, out string) error {
codes[types_order[k]] = v
}
log.Printf("resolve ok %v", out)
return os.WriteFile(out, []byte(strings.Join(codes, "")), os.FileMode(0644))
return os.WriteFile(out, []byte(strings.Join(codes, "")), os.FileMode(0o644))
}
10 changes: 6 additions & 4 deletions cmd/utils/tylua/tylua/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import (
"github.com/fatih/structtag"
)

var validJSNameRegexp = regexp.MustCompile(`(?m)^[\pL_][\pL\pN_]*$`)
var backquoteEscapeRegexp = regexp.MustCompile(`([$\\])`)
var octalPrefixRegexp = regexp.MustCompile(`^0[0-7]`)
var unicode8Regexp = regexp.MustCompile(`\\\\|\\U[\da-fA-F]{8}`)
var (
validJSNameRegexp = regexp.MustCompile(`(?m)^[\pL_][\pL\pN_]*$`)
backquoteEscapeRegexp = regexp.MustCompile(`([$\\])`)
octalPrefixRegexp = regexp.MustCompile(`^0[0-7]`)
unicode8Regexp = regexp.MustCompile(`\\\\|\\U[\da-fA-F]{8}`)
)

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table
var jsNumberOperatorPrecedence = map[token.Token]int{
Expand Down
9 changes: 9 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ func (n Names) GetLabelSourceType() string {
func (n Names) GetLabelSourceIndex() string {
return fmt.Sprintf(FMT_SOURCE_INDEX, n.domain)
}

func (n Names) GetLabelSourceName() string {
return fmt.Sprintf(FMT_SOURCE_NAME, n.domain)
}
Expand Down Expand Up @@ -296,6 +297,14 @@ func (n Names) GetAlbRuleRewriteRequestAnnotation() string {
return fmt.Sprintf("alb.rule.%s/rewrite-request", n.domain)
}

func (n Names) GetAlbWafCmRefAnnotation() string {
return fmt.Sprintf("alb.modsecurity.%s/cmref", n.domain)
}

func (n Names) GetAlbWafUseRecommendAnnotation() string {
return fmt.Sprintf("alb.modsecurity.%s/use-recommend", n.domain)
}

type Flags struct {
ControllerFlags
ExtraConfig
Expand Down
8 changes: 4 additions & 4 deletions controller/cli/alb.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ func (c *AlbCli) GetLBConfig(ns string, name string) (*LoadBalancer, error) {
}

cAlb := &LoadBalancer{
Name: mAlb.Name,
Address: mAlb.Spec.Address,
Name: mAlb.Alb.Name,
Address: mAlb.Alb.Spec.Address,
Frontends: []*Frontend{},
Labels: mAlb.Labels,
Labels: mAlb.Alb.Labels,
}

// mft frontend struct from modules package.
for _, mft := range mAlb.Frontends {
ft := &Frontend{
FtName: mft.Name,
AlbName: mAlb.Name,
AlbName: mAlb.Alb.Name,
Port: mft.Spec.Port,
Protocol: mft.Spec.Protocol,
Rules: RuleList{},
Expand Down
9 changes: 4 additions & 5 deletions controller/cli/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"sync"

m "alauda.io/alb2/controller/modules"
"alauda.io/alb2/controller/types"
. "alauda.io/alb2/controller/types"
"alauda.io/alb2/driver"
albv1 "alauda.io/alb2/pkg/apis/alauda/v1"
Expand Down Expand Up @@ -396,20 +395,20 @@ func generateBackend(backendMap map[string][]*driver.Backend, services []*Backen
return sortedBackends
}

func (p *PolicyCli) setMetricsPortCert(cert map[string]types.Certificate) {
func (p *PolicyCli) setMetricsPortCert(cert map[string]Certificate) {
port := p.opt.MetricsPort
cert[fmt.Sprintf("%d", port)] = genMetricsCert()
}

var (
metricsCert types.Certificate
metricsCert Certificate
once sync.Once
)

func genMetricsCert() types.Certificate {
func genMetricsCert() Certificate {
once.Do(func() {
cert, key, _ := certutil.GenerateSelfSignedCertKey("localhost", []net.IP{}, []string{})
metricsCert = types.Certificate{
metricsCert = Certificate{
Cert: string(cert),
Key: string(key),
}
Expand Down
2 changes: 1 addition & 1 deletion controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func TestRuleOrder(t *testing.T) {
order := []string{}
for _, r := range rules {
order = append(order, r.Name)
t.Logf(r.Name)
t.Logf("%v", r.Name)
}
assert.Equal(t, expectOrder, order)
}
Expand Down
35 changes: 28 additions & 7 deletions controller/modules/alb2.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ import (
// a tree like struct to load all alb route related resource such as alb/ft/rule
type AlaudaLoadBalancer struct {
Alb *albv2.ALB2
Labels map[string]string // depr
Spec albv2.ALB2Spec
Status albv2.ALB2Status
Name string
Namespace string
Frontends []*Frontend
}

Expand All @@ -31,10 +26,36 @@ type Rule struct {
FT *Frontend
}

func (r *Rule) GetFtConfig() *alb2v1.FTConfig {
if r == nil {
return nil
}
if r.FT == nil {
return nil
}
return r.FT.Spec.Config
}

func (r *Rule) GetAlbConfig() *albv2.ExternalAlbConfig {
if r == nil {
return nil
}
if r.FT == nil {
return nil
}
if r.FT.LB == nil {
return nil
}
if r.FT.LB.Alb == nil {
return nil
}
return r.FT.LB.Alb.Spec.Config
}

func (alb *AlaudaLoadBalancer) GetAlbKey() client.ObjectKey {
return client.ObjectKey{
Namespace: alb.Namespace,
Name: alb.Name,
Namespace: alb.Alb.Namespace,
Name: alb.Alb.Name,
}
}

Expand Down
74 changes: 36 additions & 38 deletions controller/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"os"
"os/exec"
"strings"
"text/template"

"alauda.io/alb2/controller/cli"
m "alauda.io/alb2/controller/modules"
Expand All @@ -18,6 +17,9 @@ import (
. "alauda.io/alb2/controller/types"
"alauda.io/alb2/driver"
gateway "alauda.io/alb2/gateway/nginx"
"alauda.io/alb2/pkg/controller/ngxconf"
. "alauda.io/alb2/pkg/controller/ngxconf"
. "alauda.io/alb2/pkg/controller/ngxconf/types"
"k8s.io/klog/v2"
)

Expand All @@ -32,8 +34,9 @@ type NginxController struct {
log logr.Logger
lc *LeaderElection
PortProber *PortProbe
albcli cli.AlbCli
policycli cli.PolicyCli
albcli cli.AlbCli // load alb tree from k8s
policycli cli.PolicyCli // fetch policy needed cr from k8s into alb tree
ngxcli ngxconf.NgxCli // fetch ngxconf need cr from k8s into alb tree
}

func NewNginxController(kd *driver.KubernetesDriver, ctx context.Context, cfg *config.Config, log logr.Logger, leader *LeaderElection) *NginxController {
Expand All @@ -50,28 +53,11 @@ func NewNginxController(kd *driver.KubernetesDriver, ctx context.Context, cfg *c
lc: leader,
albcli: cli.NewAlbCli(kd, log),
policycli: cli.NewPolicyCli(kd, log, cli.PolicyCliOpt{MetricsPort: cfg.GetMetricsPort()}),
ngxcli: NewNgxCli(kd, log, NgxCliOpt{}),
}
return n
}

// +-------------------------+ +--------------------------+
// | load from alb/ft/rule | | load from gateway/route |
// | (cli/albcli) | | (gateway/nginx) |
// +--------+----------------+ +--------------------------+
//
// | |
// | |
// | +----------------------------------+ |
// +-> | types/loadbalancer |<----+
// +--------------+-------------------+
// | fill with backend ips (cli/policy)
// +--------------v--------------------+
// | types/loadbalancer |
// +--------------+--------------------+
// | translate to policy (cli/policy)
// +--------------v--------------------+
// | policy |
// +-----------------------------------+
func (nc *NginxController) GenerateConf() error {
nginxConfig, ngxPolicies, err := nc.GenerateNginxConfigAndPolicy()
if err != nil {
Expand All @@ -80,6 +66,28 @@ func (nc *NginxController) GenerateConf() error {
return nc.WriteConfig(nginxConfig, ngxPolicies)
}

// +-------------------------+ +--------------------------+
// | load from alb/ft/rule | | load from gateway/route |
// | (cli/albcli) | | (gateway/nginx) |
// +--------+----------------+ +--------------------------+
//
// | |
// | +----------------------------------+ |
// +-> | types/loadbalancer |<----+
// +--------------+-------------------+
// | fill with backend ips (cli/policy)
// +--------------v-------------------+
// | types/loadbalancer |
// +--------------+-------------------+
// | fill with cm which be referenced (cli/nginx)
// +--------------v-------------------+
// | types/loadbalancer |
// +--------------|-|-----------------+
// +---------+ +------------+
// | |
// +-----------v---------+ +---------v------------+
// | policy.new | | nginx.conf |
// +---------------------+ +----------------------+
func (nc *NginxController) GenerateNginxConfigAndPolicy() (nginxTemplateConfig NginxTemplateConfig, nginxPolicy NgxPolicy, err error) {
alb, err := nc.GetLBConfig()
l := nc.log
Expand All @@ -99,6 +107,7 @@ func (nc *NginxController) GenerateNginxConfigAndPolicy() (nginxTemplateConfig N
if phase != m.PhaseTerminating {
phase = m.PhaseRunning
}

// TODO move to other goroutine
if nc.albcfg.IsEnableVIP() && nc.lc != nil && nc.lc.AmILeader() {
nc.log.Info("enable vip and I am the leader")
Expand All @@ -107,7 +116,10 @@ func (nc *NginxController) GenerateNginxConfigAndPolicy() (nginxTemplateConfig N
}
}

cfg, err := GenerateNginxTemplateConfig(alb, string(phase), newNginxParam(nc.albcfg), nc.albcfg)
if err = nc.ngxcli.FillUpRefCms(alb); err != nil {
return NginxTemplateConfig{}, NgxPolicy{}, err
}
cfg, err := nc.ngxcli.GenerateNginxTemplateConfig(alb, string(phase), nc.albcfg)
if err != nil {
return NginxTemplateConfig{}, NgxPolicy{}, fmt.Errorf("generate nginx.conf fail %v", err)
}
Expand Down Expand Up @@ -198,25 +210,11 @@ func MergeLBConfig(alb *LoadBalancer, gateway *LoadBalancer) (*LoadBalancer, err
}

func (nc *NginxController) WriteConfig(nginxTemplateConfig NginxTemplateConfig, ngxPolicies NgxPolicy) error {
configWriter, err := os.Create(nc.NewConfigPath)
if err != nil {
klog.Errorf("Failed to create new config file |%v| %s", nc.NewConfigPath, err.Error())
return err
}
defer configWriter.Close()

t, err := template.New("nginx.tmpl").ParseFiles(nc.TemplatePath)
ngxconf, err := ngxconf.RenderNgxFromFile(nginxTemplateConfig, nc.TemplatePath)
if err != nil {
klog.Errorf("Failed to parse template %s", err.Error())
return err
}
err = t.Execute(configWriter, nginxTemplateConfig)
if err != nil {
klog.Error(err)
return err
}
if err := configWriter.Sync(); err != nil {
klog.Error(err)
if err := os.WriteFile(nc.NewConfigPath, []byte(ngxconf), 0o644); err != nil {
return err
}

Expand Down
Loading

0 comments on commit fee5ffc

Please sign in to comment.