453 lines
11 KiB
Go
453 lines
11 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gdy666/lucky/socketproxy"
|
|
"github.com/gdy666/lucky/thirdlib/gdylib/logsbuffer"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type PortForwardsConfigure struct {
|
|
PortForwardsLimit int64 `json:"PortForwardsLimit"` //全局端口转发数量限制
|
|
TCPPortforwardMaxConnections int64 `json:"TCPPortforwardMaxConnections"` //端口转发全局TCP并发链接数限制
|
|
UDPReadTargetDataMaxgoroutineCount int64 `json:"UDPReadTargetDataMaxgoroutineCount"` //端口转发全局UDP读取目标地址数据协程数限制
|
|
}
|
|
|
|
type PortForwardsRule struct {
|
|
Name string `json:"Name"`
|
|
Key string `json:"Key"`
|
|
Enable bool `json:"Enable"`
|
|
ForwardTypes []string `json:"ForwardTypes"`
|
|
ListenAddress string `json:"ListenAddress"`
|
|
ListenPorts string `json:"ListenPorts"`
|
|
TargetAddressList []string `json:"TargetAddressList"`
|
|
TargetPorts string `json:"TargetPorts"`
|
|
Options socketproxy.RelayRuleOptions `json:"Options"`
|
|
ReverseProxyList *[]socketproxy.Proxy `json:"-"`
|
|
|
|
logsBuffer *logsbuffer.LogsBuffer
|
|
logrus *logrus.Logger
|
|
LogLevel int `json:"LogLevel"` //日志输出级别
|
|
LogOutputToConsole bool `json:"LogOutputToConsole"` //日志输出到终端
|
|
AccessLogMaxNum int `json:"AccessLogMaxNum"`
|
|
WebListShowLastLogMaxCount int `json:"WebListShowLastLogMaxCount"` //前端列表显示最新日志最大条数
|
|
}
|
|
|
|
func (r *PortForwardsRule) ProxyCount() int {
|
|
if r.ReverseProxyList == nil {
|
|
return 0
|
|
}
|
|
return len(*r.ReverseProxyList)
|
|
}
|
|
|
|
func (r *PortForwardsRule) StartAllProxys() {
|
|
if r.ReverseProxyList == nil {
|
|
return
|
|
}
|
|
for i := range *r.ReverseProxyList {
|
|
|
|
(*r.ReverseProxyList)[i].StartProxy()
|
|
}
|
|
}
|
|
|
|
func (r *PortForwardsRule) GetLastLogs(maxCount int) []any {
|
|
return r.GetLogsBuffer().GetLastLogs(WebLogConvert, maxCount)
|
|
}
|
|
|
|
func (r *PortForwardsRule) Fire(entry *logrus.Entry) error {
|
|
if !r.LogOutputToConsole {
|
|
return nil
|
|
}
|
|
s, _ := entry.String()
|
|
log.Print(s)
|
|
return nil
|
|
}
|
|
|
|
func (r *PortForwardsRule) Levels() []logrus.Level {
|
|
return logrus.AllLevels
|
|
}
|
|
|
|
func (r *PortForwardsRule) GetLogrus() *logrus.Logger {
|
|
if r.logrus == nil {
|
|
r.logrus = logrus.New()
|
|
r.logrus.SetLevel(logrus.Level(r.LogLevel))
|
|
r.logrus.SetOutput(r.GetLogsBuffer())
|
|
r.logrus.SetFormatter(&logrus.JSONFormatter{
|
|
TimestampFormat: "2006-01-02 15:04:05",
|
|
DisableTimestamp: true,
|
|
DisableHTMLEscape: true,
|
|
DataKey: "ExtInfo",
|
|
})
|
|
r.logrus.AddHook(r)
|
|
}
|
|
return r.logrus
|
|
}
|
|
|
|
func (r *PortForwardsRule) GetLogsBuffer() *logsbuffer.LogsBuffer {
|
|
if r.logsBuffer == nil {
|
|
r.logsBuffer = logsbuffer.CreateLogbuffer("portforward:"+r.Key, r.AccessLogMaxNum)
|
|
}
|
|
return r.logsBuffer
|
|
}
|
|
|
|
func (r *PortForwardsRule) StopAllProxys() {
|
|
if r.ReverseProxyList == nil {
|
|
return
|
|
}
|
|
for i := range *r.ReverseProxyList {
|
|
(*r.ReverseProxyList)[i].StopProxy()
|
|
}
|
|
}
|
|
|
|
// TidyReverseProxyCache 整理端口转发日志缓存
|
|
func TidyPortforwardLogsCache() {
|
|
ruleList := GetPortForwardsRuleList()
|
|
var keyListBuffer strings.Builder
|
|
for _, rule := range ruleList {
|
|
keyListBuffer.WriteString(rule.Key)
|
|
keyListBuffer.WriteString(",")
|
|
}
|
|
|
|
keyListStr := keyListBuffer.String()
|
|
logsbuffer.LogsBufferStoreMu.Lock()
|
|
defer logsbuffer.LogsBufferStoreMu.Unlock()
|
|
|
|
var needDeleteKeys []string
|
|
|
|
for k := range logsbuffer.LogsBufferStore {
|
|
if !strings.HasPrefix(k, "portforward:") {
|
|
continue
|
|
}
|
|
|
|
if len(k) <= 13 {
|
|
continue
|
|
}
|
|
|
|
if !strings.Contains(keyListStr, k[12:]) {
|
|
needDeleteKeys = append(needDeleteKeys, k)
|
|
}
|
|
}
|
|
|
|
for i := range needDeleteKeys {
|
|
delete(logsbuffer.LogsBufferStore, needDeleteKeys[i])
|
|
}
|
|
|
|
}
|
|
|
|
func (r *PortForwardsRule) InitProxyList() error {
|
|
listenPorts, err := PortsStrToIList(r.ListenPorts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
targetPorts, err := PortsStrToIList(r.TargetPorts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(listenPorts) != len(targetPorts) {
|
|
return fmt.Errorf("端口个数不一致")
|
|
}
|
|
var proxyList []socketproxy.Proxy
|
|
for i := range r.ForwardTypes {
|
|
for j := range listenPorts {
|
|
p, err := socketproxy.CreateProxy(r.GetLogrus(), r.ForwardTypes[i],
|
|
r.ListenAddress,
|
|
r.TargetAddressList,
|
|
listenPorts[j],
|
|
targetPorts[j],
|
|
&r.Options)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
proxyList = append(proxyList, p)
|
|
}
|
|
}
|
|
|
|
r.ReverseProxyList = &proxyList
|
|
return nil
|
|
}
|
|
|
|
func PortsCheck(ports1Str, ports2Str string) (bool, error) {
|
|
ports1, err := PortsStrToIList(ports1Str)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
ports2, err := PortsStrToIList(ports2Str)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if len(ports1) != len(ports2) {
|
|
return false, fmt.Errorf("端口个数不一致")
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
// portsStrToIList
|
|
func PortsStrToIList(portsStr string) (ports []int, err error) {
|
|
if portsStr == "" {
|
|
return
|
|
}
|
|
if strings.Contains(portsStr, ",") {
|
|
tmpStrList := strings.Split(portsStr, ",")
|
|
for i := range tmpStrList {
|
|
tps, e := PortsStrToIList(tmpStrList[i])
|
|
if e != nil {
|
|
err = fmt.Errorf("端口字符串处理出错:%s", e.Error())
|
|
return
|
|
}
|
|
ports = append(ports, tps...)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
portsStrList := strings.Split(portsStr, "-")
|
|
if len(portsStrList) > 2 {
|
|
err = fmt.Errorf("端口%s格式有误", portsStr)
|
|
return
|
|
}
|
|
|
|
if len(portsStrList) == 1 { //single listen port
|
|
listenPort, e := portStrToi(portsStrList[0])
|
|
if e != nil {
|
|
err = fmt.Errorf("端口格式有误!%s", e.Error())
|
|
return
|
|
}
|
|
ports = append(ports, listenPort)
|
|
}
|
|
|
|
if len(portsStrList) == 2 {
|
|
minListenPort, e := portStrToi(portsStrList[0])
|
|
if e != nil {
|
|
err = fmt.Errorf("端口格式有误!%s", portsStrList[0])
|
|
return
|
|
}
|
|
maxListenPort, e := portStrToi(portsStrList[1])
|
|
if e != nil {
|
|
err = fmt.Errorf("端口格式有误!%s", portsStrList[1])
|
|
return
|
|
}
|
|
|
|
if maxListenPort <= minListenPort {
|
|
err = fmt.Errorf("前一个端口[%d]要小于后一个端口[%d]", minListenPort, maxListenPort)
|
|
return
|
|
}
|
|
i := minListenPort
|
|
for {
|
|
if i > maxListenPort {
|
|
break
|
|
}
|
|
ports = append(ports, i)
|
|
i++
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func portStrToi(portStr string) (int, error) {
|
|
port, err := strconv.Atoi(portStr)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("端口格式有误:%s", err.Error())
|
|
}
|
|
if port < 1 || port > 65535 {
|
|
return 0, fmt.Errorf("端口[%d]超出范围", port)
|
|
}
|
|
return port, nil
|
|
}
|
|
|
|
func PortForwardsRuleListInit() {
|
|
programConfigureMutex.RLock()
|
|
defer programConfigureMutex.RUnlock()
|
|
var err error
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
err = programConfigure.PortForwardsRuleList[i].InitProxyList()
|
|
if err != nil {
|
|
log.Printf("InitProxyList error:%s\n", err.Error())
|
|
}
|
|
if programConfigure.PortForwardsRuleList[i].Enable {
|
|
programConfigure.PortForwardsRuleList[i].StartAllProxys()
|
|
}
|
|
}
|
|
}
|
|
|
|
func GetPortForwardsRuleList() []PortForwardsRule {
|
|
programConfigureMutex.RLock()
|
|
defer programConfigureMutex.RUnlock()
|
|
|
|
var resList []PortForwardsRule
|
|
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
r := programConfigure.PortForwardsRuleList[i]
|
|
resList = append(resList, r)
|
|
}
|
|
return resList
|
|
}
|
|
|
|
func GetPortForwardsGlobalProxyCount() int {
|
|
programConfigureMutex.RLock()
|
|
defer programConfigureMutex.RUnlock()
|
|
count := 0
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
count += programConfigure.PortForwardsRuleList[i].ProxyCount()
|
|
}
|
|
return count
|
|
}
|
|
|
|
func GetPortForwardsGlobalProxyCountExcept(key string) int {
|
|
programConfigureMutex.RLock()
|
|
defer programConfigureMutex.RUnlock()
|
|
count := 0
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
if key == programConfigure.PortForwardsRuleList[i].Key {
|
|
continue
|
|
}
|
|
count += programConfigure.PortForwardsRuleList[i].ProxyCount()
|
|
}
|
|
return count
|
|
}
|
|
|
|
func GetPortForwardsRuleByKey(key string) *PortForwardsRule {
|
|
programConfigureMutex.RLock()
|
|
defer programConfigureMutex.RUnlock()
|
|
index := -1
|
|
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
if programConfigure.PortForwardsRuleList[i].Key == key {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
if index == -1 {
|
|
return nil
|
|
}
|
|
res := programConfigure.PortForwardsRuleList[index]
|
|
return &res
|
|
}
|
|
|
|
func StopAllSocketProxysByRuleKey(key string) error {
|
|
programConfigureMutex.RLock()
|
|
defer programConfigureMutex.RUnlock()
|
|
index := -1
|
|
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
if programConfigure.PortForwardsRuleList[i].Key == key {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
if index == -1 {
|
|
return fmt.Errorf("找不到key:%s对应的规则", key)
|
|
}
|
|
programConfigure.PortForwardsRuleList[index].StopAllProxys()
|
|
return nil
|
|
}
|
|
|
|
func StartAllSocketProxysByRuleKey(key string) error {
|
|
programConfigureMutex.RLock()
|
|
defer programConfigureMutex.RUnlock()
|
|
index := -1
|
|
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
if programConfigure.PortForwardsRuleList[i].Key == key {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
if index == -1 {
|
|
return fmt.Errorf("找不到key:%s对应的规则", key)
|
|
}
|
|
programConfigure.PortForwardsRuleList[index].StartAllProxys()
|
|
return nil
|
|
}
|
|
|
|
func PortForwardsRuleListAdd(r *PortForwardsRule) error {
|
|
programConfigureMutex.Lock()
|
|
defer programConfigureMutex.Unlock()
|
|
r.Enable = true
|
|
programConfigure.PortForwardsRuleList = append(programConfigure.PortForwardsRuleList, *r)
|
|
return Save()
|
|
}
|
|
|
|
func PortForwardsRuleListDelete(key string) error {
|
|
programConfigureMutex.Lock()
|
|
defer programConfigureMutex.Unlock()
|
|
|
|
index := -1
|
|
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
if programConfigure.PortForwardsRuleList[i].Key == key {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if index == -1 {
|
|
return fmt.Errorf("找不到需要删除的端口转发规则")
|
|
}
|
|
|
|
programConfigure.PortForwardsRuleList[index].StopAllProxys()
|
|
|
|
programConfigure.PortForwardsRuleList = DeletePortForwardsRuleListSlice(programConfigure.PortForwardsRuleList, index)
|
|
return Save()
|
|
}
|
|
|
|
func EnablePortForwardsRuleByKey(key string, enable bool) error {
|
|
programConfigureMutex.Lock()
|
|
defer programConfigureMutex.Unlock()
|
|
index := -1
|
|
|
|
for i := range programConfigure.DDNSTaskList {
|
|
if programConfigure.PortForwardsRuleList[i].Key == key {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
if index == -1 {
|
|
return fmt.Errorf("开关端口转发规则失败,key查找失败")
|
|
}
|
|
|
|
if enable {
|
|
programConfigure.PortForwardsRuleList[index].StartAllProxys()
|
|
} else {
|
|
programConfigure.PortForwardsRuleList[index].StopAllProxys()
|
|
}
|
|
|
|
programConfigure.PortForwardsRuleList[index].Enable = enable
|
|
return Save()
|
|
}
|
|
|
|
func UpdatePortForwardsRuleToPortForwardsRuleList(key string, r *PortForwardsRule) error {
|
|
programConfigureMutex.Lock()
|
|
defer programConfigureMutex.Unlock()
|
|
index := -1
|
|
|
|
for i := range programConfigure.PortForwardsRuleList {
|
|
if programConfigure.PortForwardsRuleList[i].Key == key {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if index == -1 {
|
|
return fmt.Errorf("找不到需要更新的端口转发规则")
|
|
}
|
|
|
|
programConfigure.PortForwardsRuleList[index] = *r
|
|
return Save()
|
|
}
|
|
|
|
func DeletePortForwardsRuleListSlice(a []PortForwardsRule, deleteIndex int) []PortForwardsRule {
|
|
j := 0
|
|
for i := range a {
|
|
if i != deleteIndex {
|
|
a[j] = a[i]
|
|
j++
|
|
}
|
|
}
|
|
return a[:j]
|
|
}
|