Add support of Unix socket (#912)
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/912 Reviewed-by: konrad <konrad@kola-entertainments.de> Co-authored-by: andreymal <andriyano-31@mail.ru> Co-committed-by: andreymal <andriyano-31@mail.ru>
This commit is contained in:
parent
8b6aeb8571
commit
50b49ffab6
5 changed files with 90 additions and 0 deletions
|
@ -5,6 +5,10 @@ service:
|
||||||
JWTSecret: "<jwt-secret>"
|
JWTSecret: "<jwt-secret>"
|
||||||
# The interface on which to run the webserver
|
# The interface on which to run the webserver
|
||||||
interface: ":3456"
|
interface: ":3456"
|
||||||
|
# Path to Unix socket. If set, it will be created and used instead of tcp
|
||||||
|
unixsocket:
|
||||||
|
# Permission bits for the Unix socket. Note that octal values must be prefixed by "0o", e.g. 0o660
|
||||||
|
unixsocketmode:
|
||||||
# The URL of the frontend, used to send password reset emails.
|
# The URL of the frontend, used to send password reset emails.
|
||||||
frontendurl: ""
|
frontendurl: ""
|
||||||
# The base path on the file system where the binary and assets are.
|
# The base path on the file system where the binary and assets are.
|
||||||
|
|
|
@ -18,6 +18,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
|
@ -29,7 +30,9 @@ import (
|
||||||
"code.vikunja.io/api/pkg/log"
|
"code.vikunja.io/api/pkg/log"
|
||||||
"code.vikunja.io/api/pkg/routes"
|
"code.vikunja.io/api/pkg/routes"
|
||||||
"code.vikunja.io/api/pkg/swagger"
|
"code.vikunja.io/api/pkg/swagger"
|
||||||
|
"code.vikunja.io/api/pkg/utils"
|
||||||
"code.vikunja.io/api/pkg/version"
|
"code.vikunja.io/api/pkg/version"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,6 +40,31 @@ func init() {
|
||||||
rootCmd.AddCommand(webCmd)
|
rootCmd.AddCommand(webCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupUnixSocket(e *echo.Echo) error {
|
||||||
|
path := config.ServiceUnixSocket.GetString()
|
||||||
|
|
||||||
|
// Remove old unix socket that may have remained after a crash
|
||||||
|
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.ServiceUnixSocketMode.Get() != nil {
|
||||||
|
// Use Umask instead of Chmod to prevent insecure race condition
|
||||||
|
// (no-op on Windows)
|
||||||
|
mode := config.ServiceUnixSocketMode.GetInt()
|
||||||
|
oldmask := utils.Umask(0o777 &^ mode)
|
||||||
|
defer utils.Umask(oldmask)
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := net.Listen("unix", path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Listener = l
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var webCmd = &cobra.Command{
|
var webCmd = &cobra.Command{
|
||||||
Use: "web",
|
Use: "web",
|
||||||
Short: "Starts the rest api web server",
|
Short: "Starts the rest api web server",
|
||||||
|
@ -56,6 +84,12 @@ var webCmd = &cobra.Command{
|
||||||
routes.RegisterRoutes(e)
|
routes.RegisterRoutes(e)
|
||||||
// Start server
|
// Start server
|
||||||
go func() {
|
go func() {
|
||||||
|
// Listen unix socket if needed (ServiceInterface will be ignored)
|
||||||
|
if config.ServiceUnixSocket.GetString() != "" {
|
||||||
|
if err := setupUnixSocket(e); err != nil {
|
||||||
|
e.Logger.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := e.Start(config.ServiceInterface.GetString()); err != nil {
|
if err := e.Start(config.ServiceInterface.GetString()); err != nil {
|
||||||
e.Logger.Info("shutting down...")
|
e.Logger.Info("shutting down...")
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ const (
|
||||||
// #nosec
|
// #nosec
|
||||||
ServiceJWTSecret Key = `service.JWTSecret`
|
ServiceJWTSecret Key = `service.JWTSecret`
|
||||||
ServiceInterface Key = `service.interface`
|
ServiceInterface Key = `service.interface`
|
||||||
|
ServiceUnixSocket Key = `service.unixsocket`
|
||||||
|
ServiceUnixSocketMode Key = `service.unixsocketmode`
|
||||||
ServiceFrontendurl Key = `service.frontendurl`
|
ServiceFrontendurl Key = `service.frontendurl`
|
||||||
ServiceEnableCaldav Key = `service.enablecaldav`
|
ServiceEnableCaldav Key = `service.enablecaldav`
|
||||||
ServiceRootpath Key = `service.rootpath`
|
ServiceRootpath Key = `service.rootpath`
|
||||||
|
@ -224,6 +226,7 @@ func InitDefaultConfig() {
|
||||||
// Service
|
// Service
|
||||||
ServiceJWTSecret.setDefault(random)
|
ServiceJWTSecret.setDefault(random)
|
||||||
ServiceInterface.setDefault(":3456")
|
ServiceInterface.setDefault(":3456")
|
||||||
|
ServiceUnixSocket.setDefault("")
|
||||||
ServiceFrontendurl.setDefault("")
|
ServiceFrontendurl.setDefault("")
|
||||||
ServiceEnableCaldav.setDefault(true)
|
ServiceEnableCaldav.setDefault(true)
|
||||||
|
|
||||||
|
|
25
pkg/utils/umask_unix.go
Normal file
25
pkg/utils/umask_unix.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public Licensee for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public Licensee
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
func Umask(mask int) int {
|
||||||
|
return unix.Umask(mask)
|
||||||
|
}
|
24
pkg/utils/umask_windows.go
Normal file
24
pkg/utils/umask_windows.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public Licensee for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public Licensee
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
// Windows doesn't provide the umask syscall, so there is a no-op stub.
|
||||||
|
func Umask(mask int) int {
|
||||||
|
return 077
|
||||||
|
}
|
Loading…
Reference in a new issue