mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-20 05:52:24 +00:00
Merge pull request #261 from hamid-gh98/main
Support set db and bin folder path from env
This commit is contained in:
commit
b70ecc12b3
5 changed files with 121 additions and 103 deletions
|
@ -45,6 +45,22 @@ func IsDebug() bool {
|
||||||
return os.Getenv("XUI_DEBUG") == "true"
|
return os.Getenv("XUI_DEBUG") == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDBPath() string {
|
func GetBinFolderPath() string {
|
||||||
return fmt.Sprintf("/etc/%s/%s.db", GetName(), GetName())
|
binFolderPath := os.Getenv("XUI_BIN_FOLDER")
|
||||||
|
if binFolderPath == "" {
|
||||||
|
binFolderPath = "bin"
|
||||||
|
}
|
||||||
|
return binFolderPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDBFolderPath() string {
|
||||||
|
dbFolderPath := os.Getenv("XUI_DB_FOLDER")
|
||||||
|
if dbFolderPath == "" {
|
||||||
|
dbFolderPath = "/etc/x-ui"
|
||||||
|
}
|
||||||
|
return dbFolderPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDBPath() string {
|
||||||
|
return fmt.Sprintf("%s/%s.db", GetDBFolderPath(), GetName())
|
||||||
}
|
}
|
||||||
|
|
2
main.go
2
main.go
|
@ -217,7 +217,7 @@ func main() {
|
||||||
|
|
||||||
v2uiCmd := flag.NewFlagSet("v2-ui", flag.ExitOnError)
|
v2uiCmd := flag.NewFlagSet("v2-ui", flag.ExitOnError)
|
||||||
var dbPath string
|
var dbPath string
|
||||||
v2uiCmd.StringVar(&dbPath, "db", "/etc/v2-ui/v2-ui.db", "set v2-ui db file path")
|
v2uiCmd.StringVar(&dbPath, "db", fmt.Sprintf("%s/v2-ui.db", config.GetDBFolderPath()), "set v2-ui db file path")
|
||||||
|
|
||||||
settingCmd := flag.NewFlagSet("setting", flag.ExitOnError)
|
settingCmd := flag.NewFlagSet("setting", flag.ExitOnError)
|
||||||
var port int
|
var port int
|
||||||
|
|
|
@ -1,28 +1,30 @@
|
||||||
package job
|
package job
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"x-ui/logger"
|
"encoding/json"
|
||||||
"x-ui/web/service"
|
"os"
|
||||||
|
"regexp"
|
||||||
|
ss "strings"
|
||||||
"x-ui/database"
|
"x-ui/database"
|
||||||
"x-ui/database/model"
|
"x-ui/database/model"
|
||||||
"os"
|
"x-ui/logger"
|
||||||
ss "strings"
|
"x-ui/web/service"
|
||||||
"regexp"
|
"x-ui/xray"
|
||||||
"encoding/json"
|
// "strconv"
|
||||||
// "strconv"
|
"github.com/go-cmd/cmd"
|
||||||
|
"net"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"net"
|
|
||||||
"github.com/go-cmd/cmd"
|
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type CheckClientIpJob struct {
|
type CheckClientIpJob struct {
|
||||||
xrayService service.XrayService
|
xrayService service.XrayService
|
||||||
inboundService service.InboundService
|
inboundService service.InboundService
|
||||||
}
|
}
|
||||||
|
|
||||||
var job *CheckClientIpJob
|
var job *CheckClientIpJob
|
||||||
var disAllowedIps []string
|
var disAllowedIps []string
|
||||||
|
|
||||||
func NewCheckClientIpJob() *CheckClientIpJob {
|
func NewCheckClientIpJob() *CheckClientIpJob {
|
||||||
job = new(CheckClientIpJob)
|
job = new(CheckClientIpJob)
|
||||||
|
@ -34,94 +36,91 @@ func (j *CheckClientIpJob) Run() {
|
||||||
processLogFile()
|
processLogFile()
|
||||||
|
|
||||||
// disAllowedIps = []string{"192.168.1.183","192.168.1.197"}
|
// disAllowedIps = []string{"192.168.1.183","192.168.1.197"}
|
||||||
blockedIps := []byte(ss.Join(disAllowedIps,","))
|
blockedIps := []byte(ss.Join(disAllowedIps, ","))
|
||||||
err := os.WriteFile("./bin/blockedIPs", blockedIps, 0755)
|
err := os.WriteFile(xray.GetBlockedIPsPath(), blockedIps, 0755)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func processLogFile() {
|
func processLogFile() {
|
||||||
accessLogPath := GetAccessLogPath()
|
accessLogPath := GetAccessLogPath()
|
||||||
if(accessLogPath == "") {
|
if accessLogPath == "" {
|
||||||
logger.Warning("xray log not init in config.json")
|
logger.Warning("xray log not init in config.json")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := os.ReadFile(accessLogPath)
|
data, err := os.ReadFile(accessLogPath)
|
||||||
InboundClientIps := make(map[string][]string)
|
InboundClientIps := make(map[string][]string)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
// clean log
|
// clean log
|
||||||
if err := os.Truncate(GetAccessLogPath(), 0); err != nil {
|
if err := os.Truncate(GetAccessLogPath(), 0); err != nil {
|
||||||
checkError(err)
|
checkError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := ss.Split(string(data), "\n")
|
lines := ss.Split(string(data), "\n")
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
ipRegx, _ := regexp.Compile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`)
|
ipRegx, _ := regexp.Compile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`)
|
||||||
emailRegx, _ := regexp.Compile(`email:.+`)
|
emailRegx, _ := regexp.Compile(`email:.+`)
|
||||||
|
|
||||||
matchesIp := ipRegx.FindString(line)
|
matchesIp := ipRegx.FindString(line)
|
||||||
if(len(matchesIp) > 0) {
|
if len(matchesIp) > 0 {
|
||||||
ip := string(matchesIp)
|
ip := string(matchesIp)
|
||||||
if( ip == "127.0.0.1" || ip == "1.1.1.1") {
|
if ip == "127.0.0.1" || ip == "1.1.1.1" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
matchesEmail := emailRegx.FindString(line)
|
matchesEmail := emailRegx.FindString(line)
|
||||||
if(matchesEmail == "") {
|
if matchesEmail == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
matchesEmail = ss.Split(matchesEmail, "email: ")[1]
|
matchesEmail = ss.Split(matchesEmail, "email: ")[1]
|
||||||
|
|
||||||
if(InboundClientIps[matchesEmail] != nil) {
|
if InboundClientIps[matchesEmail] != nil {
|
||||||
if(contains(InboundClientIps[matchesEmail],ip)){
|
if contains(InboundClientIps[matchesEmail], ip) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
InboundClientIps[matchesEmail] = append(InboundClientIps[matchesEmail],ip)
|
InboundClientIps[matchesEmail] = append(InboundClientIps[matchesEmail], ip)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
InboundClientIps[matchesEmail] = append(InboundClientIps[matchesEmail], ip)
|
||||||
}else{
|
}
|
||||||
InboundClientIps[matchesEmail] = append(InboundClientIps[matchesEmail],ip)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
disAllowedIps = []string{}
|
disAllowedIps = []string{}
|
||||||
|
|
||||||
for clientEmail, ips := range InboundClientIps {
|
for clientEmail, ips := range InboundClientIps {
|
||||||
inboundClientIps,err := GetInboundClientIps(clientEmail)
|
inboundClientIps, err := GetInboundClientIps(clientEmail)
|
||||||
sort.Sort(sort.StringSlice(ips))
|
sort.Sort(sort.StringSlice(ips))
|
||||||
if(err != nil){
|
if err != nil {
|
||||||
addInboundClientIps(clientEmail,ips)
|
addInboundClientIps(clientEmail, ips)
|
||||||
|
|
||||||
}else{
|
} else {
|
||||||
updateInboundClientIps(inboundClientIps,clientEmail,ips)
|
updateInboundClientIps(inboundClientIps, clientEmail, ips)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// check if inbound connection is more than limited ip and drop connection
|
// check if inbound connection is more than limited ip and drop connection
|
||||||
LimitDevice := func() { LimitDevice() }
|
LimitDevice := func() { LimitDevice() }
|
||||||
|
|
||||||
stop := schedule(LimitDevice, 1000 *time.Millisecond)
|
stop := schedule(LimitDevice, 1000*time.Millisecond)
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
stop <- true
|
stop <- true
|
||||||
|
|
||||||
}
|
}
|
||||||
func GetAccessLogPath() string {
|
func GetAccessLogPath() string {
|
||||||
|
|
||||||
config, err := os.ReadFile("bin/config.json")
|
config, err := os.ReadFile(xray.GetConfigPath())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
jsonConfig := map[string]interface{}{}
|
jsonConfig := map[string]interface{}{}
|
||||||
err = json.Unmarshal([]byte(config), &jsonConfig)
|
err = json.Unmarshal([]byte(config), &jsonConfig)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
if(jsonConfig["log"] != nil) {
|
if jsonConfig["log"] != nil {
|
||||||
jsonLog := jsonConfig["log"].(map[string]interface{})
|
jsonLog := jsonConfig["log"].(map[string]interface{})
|
||||||
if(jsonLog["access"] != nil) {
|
if jsonLog["access"] != nil {
|
||||||
|
|
||||||
accessLogPath := jsonLog["access"].(string)
|
accessLogPath := jsonLog["access"].(string)
|
||||||
|
|
||||||
|
@ -132,7 +131,7 @@ func GetAccessLogPath() string {
|
||||||
|
|
||||||
}
|
}
|
||||||
func checkError(e error) {
|
func checkError(e error) {
|
||||||
if e != nil {
|
if e != nil {
|
||||||
logger.Warning("client ip job err:", e)
|
logger.Warning("client ip job err:", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,20 +181,20 @@ func addInboundClientIps(clientEmail string, ips []string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func updateInboundClientIps(inboundClientIps *model.InboundClientIps,clientEmail string,ips []string) error {
|
func updateInboundClientIps(inboundClientIps *model.InboundClientIps, clientEmail string, ips []string) error {
|
||||||
|
|
||||||
jsonIps, err := json.Marshal(ips)
|
jsonIps, err := json.Marshal(ips)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
inboundClientIps.ClientEmail = clientEmail
|
inboundClientIps.ClientEmail = clientEmail
|
||||||
inboundClientIps.Ips = string(jsonIps)
|
inboundClientIps.Ips = string(jsonIps)
|
||||||
|
|
||||||
// check inbound limitation
|
// check inbound limitation
|
||||||
inbound, err := GetInboundByEmail(clientEmail)
|
inbound, err := GetInboundByEmail(clientEmail)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
if inbound.Settings == "" {
|
if inbound.Settings == "" {
|
||||||
logger.Debug("wrong data ",inbound)
|
logger.Debug("wrong data ", inbound)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,17 +204,17 @@ func updateInboundClientIps(inboundClientIps *model.InboundClientIps,clientEmail
|
||||||
|
|
||||||
for _, client := range clients {
|
for _, client := range clients {
|
||||||
if client.Email == clientEmail {
|
if client.Email == clientEmail {
|
||||||
|
|
||||||
limitIp := client.LimitIP
|
limitIp := client.LimitIP
|
||||||
|
|
||||||
if(limitIp < len(ips) && limitIp != 0 && inbound.Enable) {
|
if limitIp < len(ips) && limitIp != 0 && inbound.Enable {
|
||||||
|
|
||||||
disAllowedIps = append(disAllowedIps,ips[limitIp:]...)
|
disAllowedIps = append(disAllowedIps, ips[limitIp:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.Debug("disAllowedIps ",disAllowedIps)
|
logger.Debug("disAllowedIps ", disAllowedIps)
|
||||||
sort.Sort(sort.StringSlice(disAllowedIps))
|
sort.Sort(sort.StringSlice(disAllowedIps))
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err = db.Save(inboundClientIps).Error
|
err = db.Save(inboundClientIps).Error
|
||||||
|
@ -224,13 +223,13 @@ func updateInboundClientIps(inboundClientIps *model.InboundClientIps,clientEmail
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func DisableInbound(id int) error{
|
func DisableInbound(id int) error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
result := db.Model(model.Inbound{}).
|
result := db.Model(model.Inbound{}).
|
||||||
Where("id = ? and enable = ?", id, true).
|
Where("id = ? and enable = ?", id, true).
|
||||||
Update("enable", false)
|
Update("enable", false)
|
||||||
err := result.Error
|
err := result.Error
|
||||||
logger.Warning("disable inbound with id:",id)
|
logger.Warning("disable inbound with id:", id)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
job.xrayService.SetToNeedRestart()
|
job.xrayService.SetToNeedRestart()
|
||||||
|
@ -242,7 +241,7 @@ func DisableInbound(id int) error{
|
||||||
func GetInboundByEmail(clientEmail string) (*model.Inbound, error) {
|
func GetInboundByEmail(clientEmail string) (*model.Inbound, error) {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var inbounds *model.Inbound
|
var inbounds *model.Inbound
|
||||||
err := db.Model(model.Inbound{}).Where("settings LIKE ?", "%" + clientEmail + "%").Find(&inbounds).Error
|
err := db.Model(model.Inbound{}).Where("settings LIKE ?", "%"+clientEmail+"%").Find(&inbounds).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -250,45 +249,44 @@ func GetInboundByEmail(clientEmail string) (*model.Inbound, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LimitDevice() {
|
func LimitDevice() {
|
||||||
var destIp, destPort, srcIp, srcPort string
|
var destIp, destPort, srcIp, srcPort string
|
||||||
|
|
||||||
localIp,err := LocalIP()
|
|
||||||
checkError(err)
|
|
||||||
|
|
||||||
c := cmd.NewCmd("bash","-c","ss --tcp | grep -E '" + IPsToRegex(localIp) + "'| awk '{if($1==\"ESTAB\") print $4,$5;}'","| sort | uniq -c | sort -nr | head")
|
localIp, err := LocalIP()
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
<-c.Start()
|
c := cmd.NewCmd("bash", "-c", "ss --tcp | grep -E '"+IPsToRegex(localIp)+"'| awk '{if($1==\"ESTAB\") print $4,$5;}'", "| sort | uniq -c | sort -nr | head")
|
||||||
if len(c.Status().Stdout) > 0 {
|
|
||||||
ipRegx, _ := regexp.Compile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`)
|
|
||||||
portRegx, _ := regexp.Compile(`(?:(:))([0-9]..[^.][0-9]+)`)
|
|
||||||
|
|
||||||
for _, row := range c.Status().Stdout {
|
<-c.Start()
|
||||||
|
if len(c.Status().Stdout) > 0 {
|
||||||
|
ipRegx, _ := regexp.Compile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`)
|
||||||
|
portRegx, _ := regexp.Compile(`(?:(:))([0-9]..[^.][0-9]+)`)
|
||||||
|
|
||||||
data := strings.Split(row," ")
|
for _, row := range c.Status().Stdout {
|
||||||
|
|
||||||
if len(data) < 2 {
|
data := strings.Split(row, " ")
|
||||||
continue // Skip this row if it doesn't have at least two elements
|
|
||||||
}
|
|
||||||
|
|
||||||
destIp = string(ipRegx.FindString(data[0]))
|
if len(data) < 2 {
|
||||||
destPort = portRegx.FindString(data[0])
|
continue // Skip this row if it doesn't have at least two elements
|
||||||
destPort = strings.Replace(destPort,":","",-1)
|
}
|
||||||
|
|
||||||
srcIp = string(ipRegx.FindString(data[1]))
|
destIp = string(ipRegx.FindString(data[0]))
|
||||||
srcPort = portRegx.FindString(data[1])
|
destPort = portRegx.FindString(data[0])
|
||||||
srcPort = strings.Replace(srcPort,":","",-1)
|
destPort = strings.Replace(destPort, ":", "", -1)
|
||||||
|
|
||||||
if contains(disAllowedIps,srcIp){
|
srcIp = string(ipRegx.FindString(data[1]))
|
||||||
dropCmd := cmd.NewCmd("bash","-c","ss -K dport = " + srcPort)
|
srcPort = portRegx.FindString(data[1])
|
||||||
dropCmd.Start()
|
srcPort = strings.Replace(srcPort, ":", "", -1)
|
||||||
|
|
||||||
logger.Debug("request droped : ",srcIp,srcPort,"to",destIp,destPort)
|
if contains(disAllowedIps, srcIp) {
|
||||||
}
|
dropCmd := cmd.NewCmd("bash", "-c", "ss -K dport = "+srcPort)
|
||||||
}
|
dropCmd.Start()
|
||||||
}
|
|
||||||
|
logger.Debug("request droped : ", srcIp, srcPort, "to", destIp, destPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func LocalIP() ([]string, error) {
|
func LocalIP() ([]string, error) {
|
||||||
// get machine ips
|
// get machine ips
|
||||||
|
|
||||||
|
@ -312,24 +310,23 @@ func LocalIP() ([]string, error) {
|
||||||
ip = v.IP
|
ip = v.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
ips = append(ips,ip.String())
|
ips = append(ips, ip.String())
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.Debug("System IPs : ",ips)
|
logger.Debug("System IPs : ", ips)
|
||||||
|
|
||||||
return ips, nil
|
return ips, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IPsToRegex(ips []string) string {
|
||||||
func IPsToRegex(ips []string) (string){
|
|
||||||
|
|
||||||
regx := ""
|
regx := ""
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
regx += "(" + strings.Replace(ip, ".", "\\.", -1) + ")"
|
regx += "(" + strings.Replace(ip, ".", "\\.", -1) + ")"
|
||||||
|
|
||||||
}
|
}
|
||||||
regx = "(" + strings.Replace(regx, ")(", ")|(.", -1) + ")"
|
regx = "(" + strings.Replace(regx, ")(", ")|(.", -1) + ")"
|
||||||
|
|
||||||
return regx
|
return regx
|
||||||
}
|
}
|
|
@ -106,8 +106,8 @@
|
||||||
"expireDate" = "Expire date"
|
"expireDate" = "Expire date"
|
||||||
"resetTraffic" = "Reset traffic"
|
"resetTraffic" = "Reset traffic"
|
||||||
"addInbound" = "Add Inbound"
|
"addInbound" = "Add Inbound"
|
||||||
"addTo" = "Add To"
|
"addTo" = "Create"
|
||||||
"revise" = "Revise"
|
"revise" = "Update"
|
||||||
"modifyInbound" = "Modify InBound"
|
"modifyInbound" = "Modify InBound"
|
||||||
"deleteInbound" = "Delete Inbound"
|
"deleteInbound" = "Delete Inbound"
|
||||||
"deleteInboundContent" = "Are you sure you want to delete inbound?"
|
"deleteInboundContent" = "Are you sure you want to delete inbound?"
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"x-ui/config"
|
||||||
"x-ui/util/common"
|
"x-ui/util/common"
|
||||||
|
|
||||||
"github.com/Workiva/go-datastructures/queue"
|
"github.com/Workiva/go-datastructures/queue"
|
||||||
|
@ -29,19 +30,23 @@ func GetBinaryName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBinaryPath() string {
|
func GetBinaryPath() string {
|
||||||
return "bin/" + GetBinaryName()
|
return config.GetBinFolderPath() + "/" + GetBinaryName()
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetConfigPath() string {
|
func GetConfigPath() string {
|
||||||
return "bin/config.json"
|
return config.GetBinFolderPath() + "/config.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGeositePath() string {
|
func GetGeositePath() string {
|
||||||
return "bin/geosite.dat"
|
return config.GetBinFolderPath() + "/geosite.dat"
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGeoipPath() string {
|
func GetGeoipPath() string {
|
||||||
return "bin/geoip.dat"
|
return config.GetBinFolderPath() + "/geoip.dat"
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetBlockedIPsPath() string {
|
||||||
|
return config.GetBinFolderPath() + "/blockedIPs"
|
||||||
}
|
}
|
||||||
|
|
||||||
func stopProcess(p *Process) {
|
func stopProcess(p *Process) {
|
||||||
|
@ -162,7 +167,7 @@ func (p *process) Start() (err error) {
|
||||||
return common.NewErrorf("Failed to write configuration file: %v", err)
|
return common.NewErrorf("Failed to write configuration file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command(GetBinaryPath(), "-c", configPath, "-restrictedIPsPath", "./bin/blockedIPs")
|
cmd := exec.Command(GetBinaryPath(), "-c", configPath, "-restrictedIPsPath", GetBlockedIPsPath())
|
||||||
p.cmd = cmd
|
p.cmd = cmd
|
||||||
|
|
||||||
stdReader, err := cmd.StdoutPipe()
|
stdReader, err := cmd.StdoutPipe()
|
||||||
|
|
Loading…
Reference in a new issue