mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
change work dir
This commit is contained in:
parent
ce850f5e59
commit
08b54b5bbb
31 changed files with 260 additions and 259 deletions
12
main.go
12
main.go
|
@ -3,10 +3,10 @@ package main
|
|||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/router"
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/0xJacky/Nginx-UI/tool"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/router"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
tool2 "github.com/0xJacky/Nginx-UI/server/tool"
|
||||
"log"
|
||||
"net/http"
|
||||
"os/signal"
|
||||
|
@ -31,9 +31,9 @@ func main() {
|
|||
Handler: router.InitRouter(),
|
||||
}
|
||||
|
||||
log.Printf("nginx config dir path: %s", tool.GetNginxConfPath(""))
|
||||
log.Printf("nginx config dir path: %s", tool2.GetNginxConfPath(""))
|
||||
|
||||
go tool.AutoCert()
|
||||
go tool2.AutoCert()
|
||||
|
||||
// Initializing the server in a goroutine so that
|
||||
// it won't block the graceful shutdown handling below
|
||||
|
|
|
@ -6,5 +6,6 @@ After=network.target
|
|||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/nginx-ui -d /usr/local/etc/nginx-ui
|
||||
Restart=on-failure
|
||||
TimeoutStopSec=5
|
||||
KillMode=mixed
|
||||
KillMode=mixed
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"net/http"
|
|
@ -1,7 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/unknwon/com"
|
||||
"net/http"
|
|
@ -2,7 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/0xJacky/Nginx-UI/tool"
|
||||
tool2 "github.com/0xJacky/Nginx-UI/server/tool"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
"log"
|
||||
|
@ -13,7 +13,7 @@ import (
|
|||
func CertInfo(c *gin.Context) {
|
||||
domain := c.Param("domain")
|
||||
|
||||
key := tool.GetCertInfo(domain)
|
||||
key := tool2.GetCertInfo(domain)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"subject_name": key.Subject.CommonName,
|
||||
|
@ -55,7 +55,7 @@ func IssueCert(c *gin.Context) {
|
|||
if string(message) == "go" {
|
||||
var m []byte
|
||||
|
||||
err = tool.IssueCert(domain)
|
||||
err = tool2.IssueCert(domain)
|
||||
if err != nil {
|
||||
m, err = json.Marshal(gin.H{
|
||||
"status": "error",
|
||||
|
@ -78,7 +78,7 @@ func IssueCert(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
sslCertificatePath := tool.GetNginxConfPath("ssl/" + domain + "/fullchain.cer")
|
||||
sslCertificatePath := tool2.GetNginxConfPath("ssl/" + domain + "/fullchain.cer")
|
||||
_, err = os.Stat(sslCertificatePath)
|
||||
|
||||
if err != nil {
|
||||
|
@ -104,7 +104,7 @@ func IssueCert(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
sslCertificateKeyPath := tool.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key")
|
||||
sslCertificateKeyPath := tool2.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key")
|
||||
_, err = os.Stat(sslCertificateKeyPath)
|
||||
|
||||
if err != nil {
|
|
@ -1,7 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/tool"
|
||||
tool2 "github.com/0xJacky/Nginx-UI/server/tool"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
@ -19,7 +19,7 @@ func GetConfigs(c *gin.Context) {
|
|||
"modify": "time",
|
||||
}
|
||||
|
||||
configFiles, err := ioutil.ReadDir(tool.GetNginxConfPath("/"))
|
||||
configFiles, err := ioutil.ReadDir(tool2.GetNginxConfPath("/"))
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
|
@ -40,7 +40,7 @@ func GetConfigs(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
configs = tool.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||
configs = tool2.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"configs": configs,
|
||||
|
@ -49,7 +49,7 @@ func GetConfigs(c *gin.Context) {
|
|||
|
||||
func GetConfig(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
path := filepath.Join(tool.GetNginxConfPath("/"), name)
|
||||
path := filepath.Join(tool2.GetNginxConfPath("/"), name)
|
||||
|
||||
content, err := ioutil.ReadFile(path)
|
||||
|
||||
|
@ -80,7 +80,7 @@ func AddConfig(c *gin.Context) {
|
|||
name := request.Name
|
||||
content := request.Content
|
||||
|
||||
path := filepath.Join(tool.GetNginxConfPath("/"), name)
|
||||
path := filepath.Join(tool2.GetNginxConfPath("/"), name)
|
||||
|
||||
log.Println(path)
|
||||
if _, err = os.Stat(path); err == nil {
|
||||
|
@ -98,7 +98,7 @@ func AddConfig(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
output := tool.ReloadNginx()
|
||||
output := tool2.ReloadNginx()
|
||||
|
||||
if output != "" {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
|
@ -126,7 +126,7 @@ func EditConfig(c *gin.Context) {
|
|||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
path := filepath.Join(tool.GetNginxConfPath("/"), name)
|
||||
path := filepath.Join(tool2.GetNginxConfPath("/"), name)
|
||||
content := request.Content
|
||||
|
||||
origContent, err := ioutil.ReadFile(path)
|
||||
|
@ -144,7 +144,7 @@ func EditConfig(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
output := tool.ReloadNginx()
|
||||
output := tool2.ReloadNginx()
|
||||
|
||||
if output != "" {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
|
@ -1,8 +1,8 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/tool"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
tool2 "github.com/0xJacky/Nginx-UI/server/tool"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -20,14 +20,14 @@ func GetDomains(c *gin.Context) {
|
|||
"modify": "time",
|
||||
}
|
||||
|
||||
configFiles, err := ioutil.ReadDir(tool.GetNginxConfPath("sites-available"))
|
||||
configFiles, err := ioutil.ReadDir(tool2.GetNginxConfPath("sites-available"))
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
enabledConfig, err := ioutil.ReadDir(filepath.Join(tool.GetNginxConfPath("sites-enabled")))
|
||||
enabledConfig, err := ioutil.ReadDir(filepath.Join(tool2.GetNginxConfPath("sites-enabled")))
|
||||
|
||||
enabledConfigMap := make(map[string]bool)
|
||||
for i := range enabledConfig {
|
||||
|
@ -53,7 +53,7 @@ func GetDomains(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
configs = tool.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||
configs = tool2.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"configs": configs,
|
||||
|
@ -62,10 +62,10 @@ func GetDomains(c *gin.Context) {
|
|||
|
||||
func GetDomain(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
path := filepath.Join(tool.GetNginxConfPath("sites-available"), name)
|
||||
path := filepath.Join(tool2.GetNginxConfPath("sites-available"), name)
|
||||
|
||||
enabled := true
|
||||
if _, err := os.Stat(filepath.Join(tool.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) {
|
||||
if _, err := os.Stat(filepath.Join(tool2.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ func EditDomain(c *gin.Context) {
|
|||
name := c.Param("name")
|
||||
request := make(gin.H)
|
||||
err = c.BindJSON(&request)
|
||||
path := filepath.Join(tool.GetNginxConfPath("sites-available"), name)
|
||||
path := filepath.Join(tool2.GetNginxConfPath("sites-available"), name)
|
||||
|
||||
err = ioutil.WriteFile(path, []byte(request["content"].(string)), 0644)
|
||||
if err != nil {
|
||||
|
@ -106,10 +106,10 @@ func EditDomain(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
enabledConfigFilePath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), name)
|
||||
enabledConfigFilePath := filepath.Join(tool2.GetNginxConfPath("sites-enabled"), name)
|
||||
if _, err = os.Stat(enabledConfigFilePath); err == nil {
|
||||
// 测试配置文件
|
||||
err = tool.TestNginxConf(enabledConfigFilePath)
|
||||
err = tool2.TestNginxConf(enabledConfigFilePath)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": err.Error(),
|
||||
|
@ -117,7 +117,7 @@ func EditDomain(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
output := tool.ReloadNginx()
|
||||
output := tool2.ReloadNginx()
|
||||
|
||||
if output != "" {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
|
@ -131,8 +131,8 @@ func EditDomain(c *gin.Context) {
|
|||
}
|
||||
|
||||
func EnableDomain(c *gin.Context) {
|
||||
configFilePath := filepath.Join(tool.GetNginxConfPath("sites-available"), c.Param("name"))
|
||||
enabledConfigFilePath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
||||
configFilePath := filepath.Join(tool2.GetNginxConfPath("sites-available"), c.Param("name"))
|
||||
enabledConfigFilePath := filepath.Join(tool2.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
||||
|
||||
_, err := os.Stat(configFilePath)
|
||||
|
||||
|
@ -149,7 +149,7 @@ func EnableDomain(c *gin.Context) {
|
|||
}
|
||||
|
||||
// 测试配置文件,不通过则撤回启用
|
||||
err = tool.TestNginxConf(enabledConfigFilePath)
|
||||
err = tool2.TestNginxConf(enabledConfigFilePath)
|
||||
if err != nil {
|
||||
_ = os.Remove(enabledConfigFilePath)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
|
@ -158,7 +158,7 @@ func EnableDomain(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
output := tool.ReloadNginx()
|
||||
output := tool2.ReloadNginx()
|
||||
|
||||
if output != "" {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
|
@ -173,7 +173,7 @@ func EnableDomain(c *gin.Context) {
|
|||
}
|
||||
|
||||
func DisableDomain(c *gin.Context) {
|
||||
enabledConfigFilePath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
||||
enabledConfigFilePath := filepath.Join(tool2.GetNginxConfPath("sites-enabled"), c.Param("name"))
|
||||
|
||||
_, err := os.Stat(enabledConfigFilePath)
|
||||
|
||||
|
@ -189,7 +189,7 @@ func DisableDomain(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
output := tool.ReloadNginx()
|
||||
output := tool2.ReloadNginx()
|
||||
|
||||
if output != "" {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
|
@ -206,8 +206,8 @@ func DisableDomain(c *gin.Context) {
|
|||
func DeleteDomain(c *gin.Context) {
|
||||
var err error
|
||||
name := c.Param("name")
|
||||
availablePath := filepath.Join(tool.GetNginxConfPath("sites-available"), name)
|
||||
enabledPath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), name)
|
||||
availablePath := filepath.Join(tool2.GetNginxConfPath("sites-available"), name)
|
||||
enabledPath := filepath.Join(tool2.GetNginxConfPath("sites-enabled"), name)
|
||||
|
||||
if _, err = os.Stat(availablePath); os.IsNotExist(err) {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
|
@ -1,8 +1,8 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
model2 "github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
@ -54,9 +54,9 @@ func InstallNginxUI(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
curd := model.NewCurd(&model.Auth{})
|
||||
curd := model2.NewCurd(&model2.Auth{})
|
||||
pwd, _ := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
|
||||
err = curd.Add(&model.Auth{
|
||||
err = curd.Add(&model2.Auth{
|
||||
Name: json.Username,
|
||||
Password: string(pwd),
|
||||
})
|
|
@ -1,7 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"net/http"
|
|
@ -2,7 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
model2 "github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/cast"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
@ -10,9 +10,9 @@ import (
|
|||
)
|
||||
|
||||
func GetUsers(c *gin.Context) {
|
||||
curd := model.NewCurd(&model.Auth{})
|
||||
curd := model2.NewCurd(&model2.Auth{})
|
||||
|
||||
var list []model.Auth
|
||||
var list []model2.Auth
|
||||
err := curd.GetList(&list)
|
||||
|
||||
if err != nil {
|
||||
|
@ -25,10 +25,10 @@ func GetUsers(c *gin.Context) {
|
|||
}
|
||||
|
||||
func GetUser(c *gin.Context) {
|
||||
curd := model.NewCurd(&model.Auth{})
|
||||
curd := model2.NewCurd(&model2.Auth{})
|
||||
id := c.Param("id")
|
||||
|
||||
var user model.Auth
|
||||
var user model2.Auth
|
||||
err := curd.First(&user, id)
|
||||
|
||||
if err != nil {
|
||||
|
@ -49,7 +49,7 @@ func AddUser(c *gin.Context) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
curd := model.NewCurd(&model.Auth{})
|
||||
curd := model2.NewCurd(&model2.Auth{})
|
||||
|
||||
pwd, err := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
|
@ -58,7 +58,7 @@ func AddUser(c *gin.Context) {
|
|||
}
|
||||
json.Password = string(pwd)
|
||||
|
||||
user := model.Auth{
|
||||
user := model2.Auth{
|
||||
Name: json.Name,
|
||||
Password: json.Password,
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ func EditUser(c *gin.Context) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
curd := model.NewCurd(&model.Auth{})
|
||||
curd := model2.NewCurd(&model2.Auth{})
|
||||
|
||||
var user, edit model.Auth
|
||||
var user, edit model2.Auth
|
||||
|
||||
err := curd.First(&user, c.Param("id"))
|
||||
|
||||
|
@ -120,8 +120,8 @@ func DeleteUser(c *gin.Context) {
|
|||
ErrHandler(c, errors.New("不允许删除默认账户"))
|
||||
return
|
||||
}
|
||||
curd := model.NewCurd(&model.Auth{})
|
||||
err := curd.Delete(&model.Auth{}, "id", id)
|
||||
curd := model2.NewCurd(&model2.Auth{})
|
||||
err := curd.Delete(&model2.Auth{}, "id", id)
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
|
@ -1,7 +1,7 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"time"
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
|
@ -3,9 +3,9 @@ package router
|
|||
import (
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"github.com/0xJacky/Nginx-UI/api"
|
||||
"github.com/0xJacky/Nginx-UI/frontend"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
api2 "github.com/0xJacky/Nginx-UI/server/api"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/gin-contrib/static"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/fs"
|
||||
|
@ -87,46 +87,46 @@ func InitRouter() *gin.Engine {
|
|||
|
||||
g := r.Group("/api")
|
||||
{
|
||||
g.GET("install", api.InstallLockCheck)
|
||||
g.POST("install", api.InstallNginxUI)
|
||||
g.GET("install", api2.InstallLockCheck)
|
||||
g.POST("install", api2.InstallNginxUI)
|
||||
|
||||
g.POST("/login", api.Login)
|
||||
g.DELETE("/logout", api.Logout)
|
||||
g.POST("/login", api2.Login)
|
||||
g.DELETE("/logout", api2.Logout)
|
||||
|
||||
g := g.Group("/", authRequired())
|
||||
{
|
||||
g.GET("/analytic", api.Analytic)
|
||||
g.GET("/analytic", api2.Analytic)
|
||||
|
||||
g.GET("/users", api.GetUsers)
|
||||
g.GET("/user/:id", api.GetUser)
|
||||
g.POST("/user", api.AddUser)
|
||||
g.POST("/user/:id", api.EditUser)
|
||||
g.DELETE("/user/:id", api.DeleteUser)
|
||||
g.GET("/users", api2.GetUsers)
|
||||
g.GET("/user/:id", api2.GetUser)
|
||||
g.POST("/user", api2.AddUser)
|
||||
g.POST("/user/:id", api2.EditUser)
|
||||
g.DELETE("/user/:id", api2.DeleteUser)
|
||||
|
||||
g.GET("domains", api.GetDomains)
|
||||
g.GET("domain/:name", api.GetDomain)
|
||||
g.POST("domain/:name", api.EditDomain)
|
||||
g.POST("domain/:name/enable", api.EnableDomain)
|
||||
g.POST("domain/:name/disable", api.DisableDomain)
|
||||
g.DELETE("domain/:name", api.DeleteDomain)
|
||||
g.GET("domains", api2.GetDomains)
|
||||
g.GET("domain/:name", api2.GetDomain)
|
||||
g.POST("domain/:name", api2.EditDomain)
|
||||
g.POST("domain/:name/enable", api2.EnableDomain)
|
||||
g.POST("domain/:name/disable", api2.DisableDomain)
|
||||
g.DELETE("domain/:name", api2.DeleteDomain)
|
||||
|
||||
g.GET("configs", api.GetConfigs)
|
||||
g.GET("config/:name", api.GetConfig)
|
||||
g.POST("config", api.AddConfig)
|
||||
g.POST("config/:name", api.EditConfig)
|
||||
g.GET("configs", api2.GetConfigs)
|
||||
g.GET("config/:name", api2.GetConfig)
|
||||
g.POST("config", api2.AddConfig)
|
||||
g.POST("config/:name", api2.EditConfig)
|
||||
|
||||
g.GET("backups", api.GetFileBackupList)
|
||||
g.GET("backup/:id", api.GetFileBackup)
|
||||
g.GET("backups", api2.GetFileBackupList)
|
||||
g.GET("backup/:id", api2.GetFileBackup)
|
||||
|
||||
g.GET("template/:name", api.GetTemplate)
|
||||
g.GET("template/:name", api2.GetTemplate)
|
||||
|
||||
g.GET("cert/issue/:domain", api.IssueCert)
|
||||
g.GET("cert/:domain/info", api.CertInfo)
|
||||
g.GET("cert/issue/:domain", api2.IssueCert)
|
||||
g.GET("cert/:domain/info", api2.CertInfo)
|
||||
|
||||
// 添加域名到自动续期列表
|
||||
g.POST("cert/:domain", api.AddDomainToAutoCert)
|
||||
g.POST("cert/:domain", api2.AddDomainToAutoCert)
|
||||
// 从自动续期列表中删除域名
|
||||
g.DELETE("cert/:domain", api.RemoveDomainFromAutoCert)
|
||||
g.DELETE("cert/:domain", api2.RemoveDomainFromAutoCert)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/0xJacky/Nginx-UI/tool"
|
||||
"github.com/0xJacky/Nginx-UI/server/tool"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
|
@ -2,7 +2,7 @@ package test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/0xJacky/Nginx-UI/tool"
|
||||
"github.com/0xJacky/Nginx-UI/server/tool"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
169
server/tool/cert.go
Normal file
169
server/tool/cert.go
Normal file
|
@ -0,0 +1,169 @@
|
|||
package tool
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v4/challenge/http01"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MyUser You'll need a user or account type that implements acme.User
|
||||
type MyUser struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
key crypto.PrivateKey
|
||||
}
|
||||
|
||||
func (u *MyUser) GetEmail() string {
|
||||
return u.Email
|
||||
}
|
||||
func (u MyUser) GetRegistration() *registration.Resource {
|
||||
return u.Registration
|
||||
}
|
||||
func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
|
||||
return u.key
|
||||
}
|
||||
|
||||
func AutoCert() {
|
||||
for {
|
||||
log.Println("[AutoCert] Start")
|
||||
autoCertList := model.GetAutoCertList()
|
||||
for i := range autoCertList {
|
||||
domain := autoCertList[i].Domain
|
||||
key := GetCertInfo(domain)
|
||||
// 未到一个月
|
||||
if time.Now().Before(key.NotBefore.AddDate(0, 1, 0)) {
|
||||
continue
|
||||
}
|
||||
// 过一个月了
|
||||
err := IssueCert(domain)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
time.Sleep(1 * time.Hour)
|
||||
}
|
||||
}
|
||||
|
||||
func GetCertInfo(domain string) (key *x509.Certificate) {
|
||||
ts := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: ts}
|
||||
|
||||
response, err := client.Get("https://" + domain)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
err = Body.Close()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
}(response.Body)
|
||||
|
||||
key = response.TLS.PeerCertificates[0]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func IssueCert(domain string) error {
|
||||
// Create a user. New accounts need an email and private key to start.
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
myUser := MyUser{
|
||||
Email: settings.ServerSettings.Email,
|
||||
key: privateKey,
|
||||
}
|
||||
|
||||
config := lego.NewConfig(&myUser)
|
||||
|
||||
//config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
config.Certificate.KeyType = certcrypto.RSA2048
|
||||
|
||||
// A client facilitates communication with the CA server.
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = client.Challenge.SetHTTP01Provider(
|
||||
http01.NewProviderServer("",
|
||||
settings.ServerSettings.HTTPChallengePort,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// New users will need to register
|
||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
myUser.Registration = reg
|
||||
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: []string{domain},
|
||||
Bundle: true,
|
||||
}
|
||||
certificates, err := client.Certificate.Obtain(request)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
saveDir := GetNginxConfPath("ssl/" + domain)
|
||||
if _, err := os.Stat(saveDir); os.IsNotExist(err) {
|
||||
err = os.Mkdir(saveDir, 0755)
|
||||
if err != nil {
|
||||
log.Println("fail to create", saveDir)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Each certificate comes back with the cert bytes, the bytes of the client's
|
||||
// private key, and a certificate URL. SAVE THESE TO DISK.
|
||||
err = ioutil.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
|
||||
certificates.Certificate, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(saveDir, domain+".key"),
|
||||
certificates.PrivateKey, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
ReloadNginx()
|
||||
|
||||
return nil
|
||||
}
|
169
tool/cert.go
169
tool/cert.go
|
@ -1,169 +0,0 @@
|
|||
package tool
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v4/challenge/http01"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MyUser You'll need a user or account type that implements acme.User
|
||||
type MyUser struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
key crypto.PrivateKey
|
||||
}
|
||||
|
||||
func (u *MyUser) GetEmail() string {
|
||||
return u.Email
|
||||
}
|
||||
func (u MyUser) GetRegistration() *registration.Resource {
|
||||
return u.Registration
|
||||
}
|
||||
func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
|
||||
return u.key
|
||||
}
|
||||
|
||||
func AutoCert() {
|
||||
for {
|
||||
log.Println("[AutoCert] Start")
|
||||
autoCertList := model.GetAutoCertList()
|
||||
for i := range autoCertList {
|
||||
domain := autoCertList[i].Domain
|
||||
key := GetCertInfo(domain)
|
||||
// 未到一个月
|
||||
if time.Now().Before(key.NotBefore.AddDate(0, 1, 0)) {
|
||||
continue
|
||||
}
|
||||
// 过一个月了
|
||||
err := IssueCert(domain)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
time.Sleep(1 * time.Hour)
|
||||
}
|
||||
}
|
||||
|
||||
func GetCertInfo(domain string) (key *x509.Certificate) {
|
||||
ts := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: ts}
|
||||
|
||||
response, err := client.Get("https://" + domain)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
err = Body.Close()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
}(response.Body)
|
||||
|
||||
key = response.TLS.PeerCertificates[0]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func IssueCert(domain string) error {
|
||||
// Create a user. New accounts need an email and private key to start.
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
myUser := MyUser{
|
||||
Email: settings.ServerSettings.Email,
|
||||
key: privateKey,
|
||||
}
|
||||
|
||||
config := lego.NewConfig(&myUser)
|
||||
|
||||
//config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
config.Certificate.KeyType = certcrypto.RSA2048
|
||||
|
||||
// A client facilitates communication with the CA server.
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = client.Challenge.SetHTTP01Provider(
|
||||
http01.NewProviderServer("",
|
||||
settings.ServerSettings.HTTPChallengePort,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// New users will need to register
|
||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
myUser.Registration = reg
|
||||
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: []string{domain},
|
||||
Bundle: true,
|
||||
}
|
||||
certificates, err := client.Certificate.Obtain(request)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
saveDir := GetNginxConfPath("ssl/" + domain)
|
||||
if _, err := os.Stat(saveDir); os.IsNotExist(err) {
|
||||
err = os.Mkdir(saveDir, 0755)
|
||||
if err != nil {
|
||||
log.Println("fail to create", saveDir)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Each certificate comes back with the cert bytes, the bytes of the client's
|
||||
// private key, and a certificate URL. SAVE THESE TO DISK.
|
||||
err = ioutil.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
|
||||
certificates.Certificate, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(saveDir, domain+".key"),
|
||||
certificates.PrivateKey, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
ReloadNginx()
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue