Load TLS config files from config path before stash home (#1678)

* Load tls files from config or home directory
* Update README
* Require both ssl files if either present
This commit is contained in:
WithoutPants 2021-08-31 19:37:45 +10:00 committed by GitHub
parent 1774a3600c
commit 709d7ce1cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 84 additions and 65 deletions

View file

@ -66,7 +66,7 @@ Stash can run over HTTPS with some additional work. First you must generate a S
This command would need customizing for your environment. [This link](https://stackoverflow.com/questions/10175812/how-to-create-a-self-signed-certificate-with-openssl) might be useful.
Once you have a certificate and key file name them `stash.crt` and `stash.key` and place them in the `~/.stash` directory. Stash detects these and starts up using HTTPS rather than HTTP.
Once you have a certificate and key file name them `stash.crt` and `stash.key` and place them in the same directory as the `config.yml` file, or the `~/.stash` directory. Stash detects these and starts up using HTTPS rather than HTTP.
# Customization

View file

@ -27,7 +27,6 @@ import (
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/manager"
"github.com/stashapp/stash/pkg/manager/config"
"github.com/stashapp/stash/pkg/manager/paths"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/session"
"github.com/stashapp/stash/pkg/utils"
@ -286,34 +285,31 @@ func Start() {
displayAddress := displayHost + ":" + strconv.Itoa(c.GetPort())
address := c.GetHost() + ":" + strconv.Itoa(c.GetPort())
if tlsConfig := makeTLSConfig(); tlsConfig != nil {
httpsServer := &http.Server{
Addr: address,
Handler: r,
TLSConfig: tlsConfig,
}
tlsConfig, err := makeTLSConfig(c)
if err != nil {
// assume we don't want to start with a broken TLS configuration
panic(fmt.Errorf("error loading TLS config: %s", err.Error()))
}
go func() {
printVersion()
printLatestVersion()
logger.Infof("stash is listening on " + address)
server := &http.Server{
Addr: address,
Handler: r,
TLSConfig: tlsConfig,
}
go func() {
printVersion()
printLatestVersion()
logger.Infof("stash is listening on " + address)
if tlsConfig != nil {
logger.Infof("stash is running at https://" + displayAddress + "/")
logger.Error(httpsServer.ListenAndServeTLS("", ""))
}()
} else {
server := &http.Server{
Addr: address,
Handler: r,
}
go func() {
printVersion()
printLatestVersion()
logger.Infof("stash is listening on " + address)
logger.Error(server.ListenAndServeTLS("", ""))
} else {
logger.Infof("stash is running at http://" + displayAddress + "/")
logger.Error(server.ListenAndServe())
}()
}
}
}()
}
func printVersion() {
@ -328,27 +324,44 @@ func GetVersion() (string, string, string) {
return version, githash, buildstamp
}
func makeTLSConfig() *tls.Config {
cert, err := ioutil.ReadFile(paths.GetSSLCert())
if err != nil {
return nil
func makeTLSConfig(c *config.Instance) (*tls.Config, error) {
c.InitTLS()
certFile, keyFile := c.GetTLSFiles()
if certFile == "" && keyFile == "" {
// assume http configuration
return nil, nil
}
key, err := ioutil.ReadFile(paths.GetSSLKey())
// ensure both files are present
if certFile == "" {
return nil, errors.New("SSL certificate file must be present if key file is present")
}
if keyFile == "" {
return nil, errors.New("SSL key file must be present if certificate file is present")
}
cert, err := ioutil.ReadFile(certFile)
if err != nil {
return nil
return nil, fmt.Errorf("error reading SSL certificate file %s: %s", certFile, err.Error())
}
key, err := ioutil.ReadFile(keyFile)
if err != nil {
return nil, fmt.Errorf("error reading SSL key file %s: %s", keyFile, err.Error())
}
certs := make([]tls.Certificate, 1)
certs[0], err = tls.X509KeyPair(cert, key)
if err != nil {
return nil
return nil, fmt.Errorf("error parsing key pair: %s", err.Error())
}
tlsConfig := &tls.Config{
Certificates: certs,
}
return tlsConfig
return tlsConfig, nil
}
type contextKey struct {

View file

@ -16,17 +16,6 @@ import (
"github.com/stashapp/stash/pkg/utils"
)
func findInPaths(paths []string, baseName string) string {
for _, p := range paths {
filePath := filepath.Join(p, baseName)
if exists, _ := utils.FileExists(filePath); exists {
return filePath
}
}
return ""
}
func GetPaths(paths []string) (string, string) {
var ffmpegPath, ffprobePath string
@ -38,10 +27,10 @@ func GetPaths(paths []string) (string, string) {
// Check if ffmpeg exists in the config directory
if ffmpegPath == "" {
ffmpegPath = findInPaths(paths, getFFMPEGFilename())
ffmpegPath = utils.FindInPaths(paths, getFFMPEGFilename())
}
if ffprobePath == "" {
ffprobePath = findInPaths(paths, getFFProbeFilename())
ffprobePath = utils.FindInPaths(paths, getFFProbeFilename())
}
return ffmpegPath, ffprobePath

View file

@ -157,18 +157,11 @@ func (e MissingConfigError) Error() string {
return fmt.Sprintf("missing the following mandatory settings: %s", strings.Join(e.missingFields, ", "))
}
func HasTLSConfig() bool {
ret, _ := utils.FileExists(paths.GetSSLCert())
if ret {
ret, _ = utils.FileExists(paths.GetSSLKey())
}
return ret
}
type Instance struct {
cpuProfilePath string
isNewSystem bool
certFile string
keyFile string
sync.RWMutex
//deadlock.RWMutex // for deadlock testing/issues
}
@ -192,6 +185,26 @@ func (i *Instance) SetConfigFile(fn string) {
viper.SetConfigFile(fn)
}
func (i *Instance) InitTLS() {
configDirectory := i.GetConfigPath()
tlsPaths := []string{
configDirectory,
paths.GetStashHomeDirectory(),
}
i.certFile = utils.FindInPaths(tlsPaths, "stash.crt")
i.keyFile = utils.FindInPaths(tlsPaths, "stash.key")
}
func (i *Instance) GetTLSFiles() (certFile, keyFile string) {
return i.certFile, i.keyFile
}
func (i *Instance) HasTLSConfig() bool {
certFile, keyFile := i.GetTLSFiles()
return certFile != "" && keyFile != ""
}
// GetCPUProfilePath returns the path to the CPU profile file to output
// profiling info to. This is set only via a commandline flag. Returns an
// empty string if not set.

View file

@ -29,11 +29,3 @@ func GetStashHomeDirectory() string {
func GetDefaultDatabaseFilePath() string {
return filepath.Join(GetStashHomeDirectory(), "stash-go.sqlite")
}
func GetSSLKey() string {
return filepath.Join(GetStashHomeDirectory(), "stash.key")
}
func GetSSLCert() string {
return filepath.Join(GetStashHomeDirectory(), "stash.crt")
}

View file

@ -133,7 +133,7 @@ func (c Cache) makeServerConnection(ctx context.Context) common.StashServerConne
Dir: c.config.GetConfigPath(),
}
if config.HasTLSConfig() {
if c.config.HasTLSConfig() {
serverConnection.Scheme = "https"
}

View file

@ -346,3 +346,14 @@ func IsFsPathCaseSensitive(path string) (bool, error) {
}
return false, fmt.Errorf("can not determine case sensitivity of path %s", path)
}
func FindInPaths(paths []string, baseName string) string {
for _, p := range paths {
filePath := filepath.Join(p, baseName)
if exists, _ := FileExists(filePath); exists {
return filePath
}
}
return ""
}

View file

@ -12,6 +12,7 @@
* Added not equals/greater than/less than modifiers for resolution criteria. ([#1568](https://github.com/stashapp/stash/pull/1568))
### 🎨 Improvements
* Added support for loading TLS/SSL configuration files from the configuration directory. ([#1678](https://github.com/stashapp/stash/pull/1678))
* Added total scenes duration to Stats page. ([#1626](https://github.com/stashapp/stash/pull/1626))
* Move Play Selected Scenes, and Add/Remove Gallery Image buttons to button toolbar. ([#1673](https://github.com/stashapp/stash/pull/1673))
* Added image and gallery counts to tag list view. ([#1672](https://github.com/stashapp/stash/pull/1672))