-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,11 @@ | ||
# acmeDeliver | ||
|
||
acme.sh 证书分发服务 | ||
|
||
将 acme.sh 获取的证书通过 http 服务分发到多台服务器 | ||
|
||
## Usage | ||
|
||
```bash | ||
./acmeDeliver | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module github.com/julydate/acmeDeliver | ||
|
||
go 1.17 | ||
|
||
require github.com/thinkeridea/go-extend v1.3.2 | ||
|
||
require github.com/zekroTJA/timedmap v1.4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/thinkeridea/go-extend v1.3.2 h1:0ZImRXpJc+wBNIrNEMbTuKwIvJ6eFoeuNAewvzONrI0= | ||
github.com/thinkeridea/go-extend v1.3.2/go.mod h1:xqN1e3y1PdVSij1VZp6iPKlO8I4jLbS8CUuTySj981g= | ||
github.com/zekroTJA/timedmap v1.4.0 h1:NIkLScX6kMzkzFP7kCIkkgKYdooAJ1itkMbJODX2WPU= | ||
github.com/zekroTJA/timedmap v1.4.0/go.mod h1:Go4uPxMN1Wjl5IgO6HYD1tM9IQhkYEVqcrrdsI4ljXo= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/md5" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"log" | ||
"net/http" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/thinkeridea/go-extend/exnet" | ||
"github.com/zekroTJA/timedmap" | ||
) | ||
|
||
// PORT 服务端口 | ||
const PORT string = "9090" | ||
|
||
// DIR 证书文件所在目录 | ||
const DIR string = "./" | ||
|
||
// KEY 密码 | ||
const KEY string = "passwd" | ||
|
||
// EXPTIME 时间戳误差,单位秒 | ||
const EXPTIME int64 = 86400 | ||
|
||
// 初始化全局变量 | ||
var domain, file, t, checksum, sign string | ||
|
||
// Creates a new timed map which scans for expired keys every 1 second | ||
var tm = timedmap.New(1 * time.Second) | ||
|
||
func main() { | ||
// 设置访问的路由 | ||
http.HandleFunc("/", check) | ||
// 设置监听的端口 | ||
err := http.ListenAndServe(":"+PORT, nil) | ||
if err != nil { | ||
log.Fatal("ListenAndServe:", err) | ||
} | ||
} | ||
|
||
func check(response http.ResponseWriter, req *http.Request) { | ||
// 解析 url 传递的参数,对于 POST 则解析响应包的主体(request body) | ||
err := req.ParseForm() | ||
if err != nil { | ||
log.Fatal("ParseForm:", err) | ||
return | ||
} | ||
|
||
// 获取来访 IP 地址 | ||
var ip = exnet.ClientPublicIP(req) | ||
if ip == "" { | ||
ip = exnet.ClientIP(req) | ||
} | ||
|
||
// 获取传入域名 | ||
if len(req.Form.Get("domain")) == 0 { | ||
fmt.Fprintf(response, "No domain specified.") | ||
return | ||
} | ||
domain = req.Form.Get("domain") | ||
// 获取传入文件名 | ||
if len(req.Form.Get("file")) == 0 { | ||
fmt.Fprintf(response, "No file specified.") | ||
return | ||
} | ||
file = req.Form.Get("file") | ||
// 获取传入签名 | ||
if len(req.Form.Get("sign")) == 0 { | ||
fmt.Fprintf(response, "No sign specified.") | ||
return | ||
} | ||
sign = req.Form.Get("sign") | ||
// 获取传入验证码 | ||
if len(req.Form.Get("checksum")) == 0 { | ||
fmt.Fprintf(response, "No checksum specified.") | ||
return | ||
} | ||
checksum = req.Form.Get("checksum") | ||
// 获取传入时间戳 | ||
if len(req.Form.Get("t")) == 0 { | ||
fmt.Fprintf(response, "No timestamp specified.") | ||
return | ||
} | ||
t = req.Form.Get("t") | ||
|
||
// 校验时间戳是否合法 | ||
reqTime, err := strconv.ParseInt(t, 10, 64) | ||
if err != nil { | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Incoming illegal timestamp:", t) | ||
fmt.Fprintf(response, "Timestamp not allowed.") | ||
return | ||
} | ||
expireTime := time.Now().Unix() - reqTime | ||
// 时间戳太超前可以判定为异常访问 | ||
if expireTime < -EXPTIME { | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Incoming illegal timestamp:", expireTime) | ||
fmt.Fprintf(response, "Timestamp not allowed.") | ||
return | ||
} | ||
// 校验时间戳是否过期 | ||
if expireTime > EXPTIME { | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Incoming expired access:", expireTime) | ||
fmt.Fprintf(response, "Timestamp expired.") | ||
return | ||
} | ||
|
||
// 计算 token | ||
token := md5.New() | ||
io.WriteString(token, domain) | ||
io.WriteString(token, file) | ||
io.WriteString(token, KEY) | ||
io.WriteString(token, t) | ||
io.WriteString(token, checksum) | ||
checkToken := fmt.Sprintf("%x", token.Sum(nil)) | ||
|
||
// 校验签名 | ||
if sign == checkToken { | ||
// 检测验证码是否重复 | ||
if checkTime, ok := tm.GetValue(checksum).(int64); ok { | ||
if checkTime > 0 && time.Now().Unix()-checkTime > EXPTIME { | ||
tm.Remove(checkTime) | ||
} else { | ||
// 检测到重放请求 | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Incoming repeat access:", checksum) | ||
fmt.Fprintf(response, "Repeat access.") | ||
return | ||
} | ||
} else { | ||
tm.Set(checksum, reqTime, time.Duration(EXPTIME)*time.Second) | ||
} | ||
|
||
// 校验域名是否在指定文件夹内 | ||
var checkDomain, checkFile bool = false, false | ||
files, _ := ioutil.ReadDir(DIR) | ||
for _, f := range files { | ||
if domain == f.Name() { | ||
checkDomain = true | ||
} | ||
} | ||
if checkDomain { | ||
// 对应域名的文件夹存在,校验内部文件是否存在 | ||
files, _ := ioutil.ReadDir(DIR + domain) | ||
for _, f := range files { | ||
if file == f.Name() { | ||
checkFile = true | ||
} | ||
} | ||
} else { | ||
// 获取的域名不存在 | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Incoming illegal domain:", domain) | ||
fmt.Fprintf(response, "Domain not exist.") | ||
return | ||
} | ||
if !checkFile { | ||
// 获取的文件不存在 | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Incoming illegal filename:", file) | ||
fmt.Fprintf(response, "File not exist.") | ||
return | ||
} | ||
// 全部校验通过,放行文件 | ||
filepath := DIR + domain + "/" + file | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Access file:", filepath) | ||
http.ServeFile(response, req, filepath) | ||
} else { | ||
// 签名错误 | ||
fmt.Println("Access from IP:", ip) | ||
fmt.Println("Incoming unauthorized access:", sign) | ||
fmt.Fprintf(response, "Unauthorized access.") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"version":"v1","main":"acmeDeliver","packages":[{"package":"github.com/thinkeridea/go-extend/exnet@github.com/thinkeridea/go-extend","version":"1.3.2"}]} |