Skip to content

Commit 389535a

Browse files
committed
cleanup
1 parent 5da1e7d commit 389535a

File tree

3 files changed

+62
-25
lines changed

3 files changed

+62
-25
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,28 @@
22
switch cloudflare FW to under_attack mode when server load is high
33

44
[![Go](https://github.com/amnonbc/underattack/actions/workflows/go2.yml/badge.svg)](https://github.com/amnonbc/underattack/actions/workflows/go2.yml)
5+
6+
This runs on a web host which sits behind cloudflare.
7+
8+
It is run using a cron like
9+
10+
```
11+
*/5 * * * * ${HOME}/bin/underattack -config ${HOME}/etc/underatttack.conf -default_level high >> ${HOME}/logs/underattack.log 2>&1
12+
```
13+
14+
It checks the server's load, free memory and tries to connect to the db.
15+
If the load is too high, the free memory is too low, or if it can't connect to the db,
16+
then it sets CF into under-attack mode, which massively reduces bot traffic which usually allows server resources to recover.
17+
Once the server has recovered, then it turns off under-attack mode.
18+
19+
The config file looks like this:
20+
21+
```json
22+
{
23+
"domain": "mydomain.com",
24+
"apiKey": "cfApiKeyWithZoneZoneReadAmdZoneSecuritySet",
25+
"DbName": "nameOfDb",
26+
"DbUser": "NameOfDbUser",
27+
"DbPassword": "dbUserPassword"
28+
}
29+
```

checkdb.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import (
66
_ "github.com/go-sql-driver/mysql"
77
)
88

9-
func checkDb(conf Config) error {
9+
func (a *app) checkDb() error {
1010
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/%s",
11-
conf.DbUser, conf.DbPassword, conf.DbName))
11+
a.conf.DbUser, a.conf.DbPassword, a.conf.DbName))
1212
if err != nil {
1313
return err
1414
}

under.go

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@ type Config struct {
2424
DbPassword string
2525
}
2626

27-
var config Config
27+
type app struct {
28+
conf Config
29+
api *cloudflare.API
30+
zoneId string
31+
}
2832

29-
func loadConfig(fn string) error {
33+
func (a *app) loadConfig(fn string) error {
3034
f, err := os.Open(fn)
3135
if err != nil {
3236
return err
3337
}
3438
defer f.Close()
35-
return json.NewDecoder(f).Decode(&config)
39+
return json.NewDecoder(f).Decode(&a.conf)
3640
}
3741

3842
func loadAvg(text string) ([]float64, error) {
@@ -54,25 +58,27 @@ func loadAvg(text string) ([]float64, error) {
5458
return res, nil
5559
}
5660

57-
// setSecurityLevel sets the security level. value must be one of
58-
// off, essentially_off, low, medium, high, under_attack.
59-
func setSecurityLevel(value string) error {
60-
api, err := cloudflare.NewWithAPIToken(config.ApiKey)
61-
if err != nil {
62-
return err
63-
}
64-
zoneID, err := api.ZoneIDByName(config.Domain)
61+
func (a *app) init() error {
62+
var err error
63+
a.api, err = cloudflare.NewWithAPIToken(a.conf.ApiKey)
6564
if err != nil {
6665
return err
6766
}
67+
a.zoneId, err = a.api.ZoneIDByName(a.conf.Domain)
68+
return err
69+
}
6870

69-
currentLevel, err := currentLevel(api, zoneID)
71+
// setSecurityLevel sets the security level. value must be one of
72+
// off, essentially_off, low, medium, high, under_attack.
73+
// If the cf security is already at the reauested level, then do nothing.
74+
func (a *app) setSecurityLevel(value string) error {
75+
currentLevel, err := a.currentLevel()
7076
if currentLevel == value {
7177
return nil
7278
}
7379

7480
log.Println("setting security level to", value)
75-
_, err = api.UpdateZoneSettings(context.TODO(), zoneID, []cloudflare.ZoneSetting{
81+
_, err = a.api.UpdateZoneSettings(context.TODO(), a.zoneId, []cloudflare.ZoneSetting{
7682
{
7783
ID: securityLevel,
7884
Value: value,
@@ -81,15 +87,15 @@ func setSecurityLevel(value string) error {
8187
return err
8288
}
8389

84-
func mustSetSecurityLevel(value string) {
85-
err := setSecurityLevel(value)
90+
func (a *app) mustSetSecurityLevel(value string) {
91+
err := a.setSecurityLevel(value)
8692
if err != nil {
8793
log.Fatalln(err)
8894
}
8995
}
9096

91-
func currentLevel(api *cloudflare.API, zoneID string) (string, error) {
92-
settings, err := api.ZoneSettings(context.TODO(), zoneID)
97+
func (a *app) currentLevel() (string, error) {
98+
settings, err := a.api.ZoneSettings(context.TODO(), a.zoneId)
9399
if err != nil {
94100
return "", err
95101
}
@@ -114,7 +120,13 @@ func main() {
114120
if err != nil {
115121
log.Fatalln(err)
116122
}
117-
err = loadConfig(*cf)
123+
var a app
124+
err = a.loadConfig(*cf)
125+
if err != nil {
126+
log.Fatalln(err)
127+
}
128+
129+
err = a.init()
118130
if err != nil {
119131
log.Fatalln(err)
120132
}
@@ -131,23 +143,23 @@ func main() {
131143
log.Println("freeMem", humanize.Bytes(freeMem), "load", la)
132144
if freeMem < mb {
133145
log.Println("free memory is below", *minBytesStr)
134-
mustSetSecurityLevel("under_attack")
146+
a.mustSetSecurityLevel("under_attack")
135147
return
136148
}
137-
err = checkDb(config)
149+
err = a.checkDb()
138150
if err != nil {
139151
log.Println("checkDb returned", err)
140-
mustSetSecurityLevel("under_attack")
152+
a.mustSetSecurityLevel("under_attack")
141153
return
142154
}
143155

144156
if la[0] >= *maxLoad {
145157
log.Println("Load average is", la, "setting level to under_attack")
146-
mustSetSecurityLevel("under_attack")
158+
a.mustSetSecurityLevel("under_attack")
147159
return
148160
}
149161
if la[0] < *minLoad && la[1] < *minLoad && la[2] < *minLoad {
150-
mustSetSecurityLevel(*defaultSecurityLevel)
162+
a.mustSetSecurityLevel(*defaultSecurityLevel)
151163
return
152164
}
153165
}

0 commit comments

Comments
 (0)