Moved v3 code from NginxProxyManager/nginx-proxy-manager-3 to NginxProxyManager/nginx-proxy-manager

This commit is contained in:
Jamie Curnow
2022-05-12 08:47:31 +10:00
parent 4db34f5894
commit 2110ecc382
830 changed files with 38168 additions and 36635 deletions

View File

@ -0,0 +1,28 @@
package config
import (
"fmt"
"os"
"github.com/alexflint/go-arg"
)
// ArgConfig is the settings for passing arguments to the command
type ArgConfig struct {
Version bool `arg:"-v" help:"print version and exit"`
}
var (
appArguments ArgConfig
)
// InitArgs will parse arg vars
func InitArgs(version, commit *string) {
// nolint: errcheck, gosec
arg.MustParse(&appArguments)
if appArguments.Version {
fmt.Printf("v%s (%s)\n", *version, *commit)
os.Exit(0)
}
}

View File

@ -0,0 +1,79 @@
package config
import (
"fmt"
golog "log"
"runtime"
"npm/internal/logger"
"github.com/getsentry/sentry-go"
"github.com/vrischmann/envconfig"
)
// Init will parse environment variables into the Env struct
func Init(version, commit, sentryDSN *string) {
// ErrorReporting is enabled until we load the status of it from the DB later
ErrorReporting = true
Version = *version
Commit = *commit
if err := envconfig.InitWithPrefix(&Configuration, "NPM"); err != nil {
fmt.Printf("%+v\n", err)
}
initLogger(*sentryDSN)
logger.Info("Build Version: %s (%s)", Version, Commit)
createDataFolders()
loadKeys()
}
// Init initialises the Log object and return it
func initLogger(sentryDSN string) {
// this removes timestamp prefixes from logs
golog.SetFlags(0)
switch Configuration.Log.Level {
case "debug":
logLevel = logger.DebugLevel
case "warn":
logLevel = logger.WarnLevel
case "error":
logLevel = logger.ErrorLevel
default:
logLevel = logger.InfoLevel
}
err := logger.Configure(&logger.Config{
LogThreshold: logLevel,
Formatter: Configuration.Log.Format,
SentryConfig: sentry.ClientOptions{
// This is the jc21 NginxProxyManager Sentry project,
// errors will be reported here (if error reporting is enable)
// and this project is private. No personal information should
// be sent in any error messages, only stacktraces.
Dsn: sentryDSN,
Release: Commit,
Dist: Version,
Environment: fmt.Sprintf("%s-%s", runtime.GOOS, runtime.GOARCH),
},
})
if err != nil {
logger.Error("LoggerConfigurationError", err)
}
}
// GetLogLevel returns the logger const level
func GetLogLevel() logger.Level {
return logLevel
}
func isError(errorClass string, err error) bool {
if err != nil {
logger.Error(errorClass, err)
return true
}
return false
}

View File

@ -0,0 +1,34 @@
package config
import (
"fmt"
"npm/internal/logger"
"os"
)
// createDataFolders will recursively create these folders within the
// data folder defined in configuration.
func createDataFolders() {
folders := []string{
"access",
"certificates",
"logs",
// Acme.sh:
Configuration.Acmesh.GetWellknown(),
// Nginx:
"nginx/hosts",
"nginx/streams",
"nginx/temp",
}
for _, folder := range folders {
path := folder
if path[0:1] != "/" {
path = fmt.Sprintf("%s/%s", Configuration.DataFolder, folder)
}
logger.Debug("Creating folder: %s", path)
if err := os.MkdirAll(path, os.ModePerm); err != nil {
logger.Error("CreateDataFolderError", err)
}
}
}

View File

@ -0,0 +1,112 @@
package config
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/asn1"
"encoding/pem"
"fmt"
"io/ioutil"
"os"
"npm/internal/logger"
)
var keysFolder string
var publicKeyFile string
var privateKeyFile string
func loadKeys() {
// check if keys folder exists in data folder
keysFolder = fmt.Sprintf("%s/keys", Configuration.DataFolder)
publicKeyFile = fmt.Sprintf("%s/public.key", keysFolder)
privateKeyFile = fmt.Sprintf("%s/private.key", keysFolder)
if _, err := os.Stat(keysFolder); os.IsNotExist(err) {
// nolint:errcheck,gosec
os.Mkdir(keysFolder, 0700)
}
// check if keys exist on disk
_, publicKeyErr := os.Stat(publicKeyFile)
_, privateKeyErr := os.Stat(privateKeyFile)
// generate keys if either one doesn't exist
if os.IsNotExist(publicKeyErr) || os.IsNotExist(privateKeyErr) {
generateKeys()
saveKeys()
}
// Load keys from disk
// nolint:gosec
publicKeyBytes, publicKeyBytesErr := ioutil.ReadFile(publicKeyFile)
// nolint:gosec
privateKeyBytes, privateKeyBytesErr := ioutil.ReadFile(privateKeyFile)
PublicKey = string(publicKeyBytes)
PrivateKey = string(privateKeyBytes)
if isError("PublicKeyReadError", publicKeyBytesErr) || isError("PrivateKeyReadError", privateKeyBytesErr) || PublicKey == "" || PrivateKey == "" {
logger.Warn("There was an error loading keys, proceeding to generate new RSA keys")
generateKeys()
saveKeys()
}
}
func generateKeys() {
reader := rand.Reader
bitSize := 4096
key, err := rsa.GenerateKey(reader, bitSize)
if isError("RSAGenerateError", err) {
return
}
privateKey := &pem.Block{
Type: "PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
}
privateKeyBuffer := new(bytes.Buffer)
err = pem.Encode(privateKeyBuffer, privateKey)
if isError("PrivatePEMEncodeError", err) {
return
}
asn1Bytes, err2 := asn1.Marshal(key.PublicKey)
if isError("RSAMarshalError", err2) {
return
}
publicKey := &pem.Block{
Type: "PUBLIC KEY",
Bytes: asn1Bytes,
}
publicKeyBuffer := new(bytes.Buffer)
err = pem.Encode(publicKeyBuffer, publicKey)
if isError("PublicPEMEncodeError", err) {
return
}
PublicKey = publicKeyBuffer.String()
PrivateKey = privateKeyBuffer.String()
logger.Info("Generated new RSA keys")
}
func saveKeys() {
err := ioutil.WriteFile(publicKeyFile, []byte(PublicKey), 0600)
if err != nil {
logger.Error("PublicKeyWriteError", err)
} else {
logger.Info("Saved Public Key: %s", publicKeyFile)
}
err = ioutil.WriteFile(privateKeyFile, []byte(PrivateKey), 0600)
if err != nil {
logger.Error("PrivateKeyWriteError", err)
} else {
logger.Info("Saved Private Key: %s", privateKeyFile)
}
}

View File

@ -0,0 +1,49 @@
package config
import (
"fmt"
"npm/internal/logger"
)
// Version is the version set by ldflags
var Version string
// Commit is the git commit set by ldflags
var Commit string
// IsSetup defines whether we have an admin user or not
var IsSetup bool
// ErrorReporting defines whether we will send errors to Sentry
var ErrorReporting bool
// PublicKey is the public key
var PublicKey string
// PrivateKey is the private key
var PrivateKey string
var logLevel logger.Level
type log struct {
Level string `json:"level" envconfig:"optional,default=info"`
Format string `json:"format" envconfig:"optional,default=nice"`
}
type acmesh struct {
Home string `json:"home" envconfig:"optional,default=/data/.acme.sh"`
ConfigHome string `json:"config_home" envconfig:"optional,default=/data/.acme.sh/config"`
CertHome string `json:"cert_home" envconfig:"optional,default=/data/.acme.sh/certs"`
}
// Configuration is the main configuration object
var Configuration struct {
DataFolder string `json:"data_folder" envconfig:"optional,default=/data"`
Acmesh acmesh `json:"acmesh"`
Log log `json:"log"`
}
// GetWellknown returns the well known path
func (a *acmesh) GetWellknown() string {
return fmt.Sprintf("%s/.well-known", a.Home)
}