feat: add support for setting a unix binding's socket file mode (#3376)
fix: linter issues and set default unix socket permissions to 0660 Signed-off-by: Jan Larwig <jan@larwig.com> Co-authored-by: Tristan <tristan@mangadex.org>
This commit is contained in:
parent
cdbdb1128d
commit
9ae0b325a6
|
|
@ -17,6 +17,7 @@
|
||||||
- [#3365](https://github.com/oauth2-proxy/oauth2-proxy/pull/3365) fix: filter empty strings from allowed groups (@Br1an67)
|
- [#3365](https://github.com/oauth2-proxy/oauth2-proxy/pull/3365) fix: filter empty strings from allowed groups (@Br1an67)
|
||||||
- [#3338](https://github.com/oauth2-proxy/oauth2-proxy/pull/3338) feat: add --config-test flag for validating configuration (@MayorFaj)
|
- [#3338](https://github.com/oauth2-proxy/oauth2-proxy/pull/3338) feat: add --config-test flag for validating configuration (@MayorFaj)
|
||||||
- [#3347](https://github.com/oauth2-proxy/oauth2-proxy/pull/3347) feat: add same site option for csrf cookies (@jvnoije)
|
- [#3347](https://github.com/oauth2-proxy/oauth2-proxy/pull/3347) feat: add same site option for csrf cookies (@jvnoije)
|
||||||
|
- [#3376](https://github.com/oauth2-proxy/oauth2-proxy/pull/3376) feat: allow setting unix socket file mode when declaring listener (@Tristan971 / @tuunit)
|
||||||
|
|
||||||
# V7.14.3
|
# V7.14.3
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -584,8 +584,8 @@ Server represents the configuration for an HTTP(S) server
|
||||||
|
|
||||||
| Field | Type | Description |
|
| Field | Type | Description |
|
||||||
| ----- | ---- | ----------- |
|
| ----- | ---- | ----------- |
|
||||||
| `bindAddress` | _string_ | BindAddress is the address on which to serve traffic.<br/>Leave blank or set to "-" to disable. |
|
| `bindAddress` | _string_ | BindAddress is the address on which to serve traffic.<br/>Different types of bind addresses are supported:<br/>* `[http://]<addr>:<port>`<br/>* `fd:<int>` (case insensitive)<br/>* `unix://<path>`<br/>Unix sockets are created with default system umask mode, which can be overridden, e.g.: `unix://my-socket,mode=0777`<br/>Square brackets are required for ipv6 address, e.g. `http://[::1]:4180`<br/>Leave blank or set to "-" to disable. |
|
||||||
| `secureBindAddress` | _string_ | SecureBindAddress is the address on which to serve secure traffic.<br/>Leave blank or set to "-" to disable. |
|
| `secureBindAddress` | _string_ | SecureBindAddress is the address on which to serve secure traffic.<br/>Secure bind addresses need to respond with valid SSL and use the following format:<br/>* `[https://]<addr>:<port>`<br/>Square brackets are required for ipv6 address, e.g. `https://[::1]:4180`<br/>Leave blank or set to "-" to disable. |
|
||||||
| `tls` | _[TLS](#tls)_ | TLS contains the information for loading the certificate and key for the<br/>secure traffic and further configuration for the TLS server. |
|
| `tls` | _[TLS](#tls)_ | TLS contains the information for loading the certificate and key for the<br/>secure traffic and further configuration for the TLS server. |
|
||||||
|
|
||||||
### TLS
|
### TLS
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ Provider specific options can be found on their respective subpages.
|
||||||
|
|
||||||
| Flag / Config Field | Type | Description | Default |
|
| Flag / Config Field | Type | Description | Default |
|
||||||
| ------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
| ------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||||
| flag: `--http-address`<br/>toml: `http_address` | string | `[http://]<addr>:<port>` or `unix://<path>` or `fd:<int>` (case insensitive) to listen on for HTTP clients. Square brackets are required for ipv6 address, e.g. `http://[::1]:4180` | `"127.0.0.1:4180"` |
|
| flag: `--http-address`<br/>toml: `http_address` | string | `[http://]<addr>:<port>` or `unix://<path>` or `fd:<int>` (case insensitive) to listen on for HTTP clients. Unix sockets are created with default system umask mode, which can be overridden, e.g. `unix://my-socket,mode=0777`. Square brackets are required for ipv6 address, e.g. `http://[::1]:4180` | `"127.0.0.1:4180"` |
|
||||||
| flag: `--https-address`<br/>toml: `https_address` | string | `[https://]<addr>:<port>` to listen on for HTTPS clients. Square brackets are required for ipv6 address, e.g. `https://[::1]:443` | `":443"` |
|
| flag: `--https-address`<br/>toml: `https_address` | string | `[https://]<addr>:<port>` to listen on for HTTPS clients. Square brackets are required for ipv6 address, e.g. `https://[::1]:443` | `":443"` |
|
||||||
| flag: `--metrics-address`<br/>toml: `metrics_address` | string | the address prometheus metrics will be scraped from | `""` |
|
| flag: `--metrics-address`<br/>toml: `metrics_address` | string | the address prometheus metrics will be scraped from | `""` |
|
||||||
| flag: `--metrics-secure-address`<br/>toml: `metrics_secure_address` | string | the address prometheus metrics will be scraped from if using HTTPS | `""` |
|
| flag: `--metrics-secure-address`<br/>toml: `metrics_secure_address` | string | the address prometheus metrics will be scraped from if using HTTPS | `""` |
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,19 @@ package options
|
||||||
// Server represents the configuration for an HTTP(S) server
|
// Server represents the configuration for an HTTP(S) server
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// BindAddress is the address on which to serve traffic.
|
// BindAddress is the address on which to serve traffic.
|
||||||
|
// Different types of bind addresses are supported:
|
||||||
|
// * `[http://]<addr>:<port>`
|
||||||
|
// * `fd:<int>` (case insensitive)
|
||||||
|
// * `unix://<path>`
|
||||||
|
// Unix sockets are created with default system umask mode, which can be overridden, e.g.: `unix://my-socket,mode=0777`
|
||||||
|
// Square brackets are required for ipv6 address, e.g. `http://[::1]:4180`
|
||||||
// Leave blank or set to "-" to disable.
|
// Leave blank or set to "-" to disable.
|
||||||
BindAddress string `yaml:"bindAddress,omitempty"`
|
BindAddress string `yaml:"bindAddress,omitempty"`
|
||||||
|
|
||||||
// SecureBindAddress is the address on which to serve secure traffic.
|
// SecureBindAddress is the address on which to serve secure traffic.
|
||||||
|
// Secure bind addresses need to respond with valid SSL and use the following format:
|
||||||
|
// * `[https://]<addr>:<port>`
|
||||||
|
// Square brackets are required for ipv6 address, e.g. `https://[::1]:4180`
|
||||||
// Leave blank or set to "-" to disable.
|
// Leave blank or set to "-" to disable.
|
||||||
SecureBindAddress string `yaml:"secureBindAddress,omitempty"`
|
SecureBindAddress string `yaml:"secureBindAddress,omitempty"`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -95,15 +96,62 @@ func (s *server) setupListener(opts Opts) error {
|
||||||
networkType := getNetworkScheme(opts.BindAddress)
|
networkType := getNetworkScheme(opts.BindAddress)
|
||||||
listenAddr := getListenAddress(opts.BindAddress)
|
listenAddr := getListenAddress(opts.BindAddress)
|
||||||
|
|
||||||
listener, err := net.Listen(networkType, listenAddr)
|
listener, err := func() (net.Listener, error) {
|
||||||
|
if networkType == "unix" {
|
||||||
|
return setupUnixSocketListener(networkType, listenAddr)
|
||||||
|
}
|
||||||
|
return net.Listen(networkType, listenAddr)
|
||||||
|
}()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("listen (%s, %s) failed: %w", networkType, listenAddr, err)
|
return fmt.Errorf("listen (%s, %s) failed: %w", networkType, listenAddr, err)
|
||||||
}
|
}
|
||||||
s.listener = listener
|
|
||||||
|
|
||||||
|
s.listener = listener
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupUnixSocketListener(networkType string, address string) (net.Listener, error) {
|
||||||
|
socketOpts := strings.Split(address, ",")
|
||||||
|
if len(socketOpts) < 2 {
|
||||||
|
return net.Listen(networkType, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
socketPath := socketOpts[0]
|
||||||
|
var socketMode os.FileMode
|
||||||
|
hasSocketMode := false
|
||||||
|
|
||||||
|
for _, socketOpt := range socketOpts[1:] {
|
||||||
|
socketOpt := strings.SplitN(socketOpt, "=", 2)
|
||||||
|
if len(socketOpt) != 2 {
|
||||||
|
return nil, fmt.Errorf("unix socket option %s expects a value", socketOpt[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if socketOpt[0] == "mode" {
|
||||||
|
mode, err := strconv.ParseUint(socketOpt[1], 8, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unix socket file mode has invalid value %s", socketOpt[1])
|
||||||
|
}
|
||||||
|
socketMode = os.FileMode(mode)
|
||||||
|
hasSocketMode = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listener, err := net.Listen(networkType, socketPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasSocketMode {
|
||||||
|
err = os.Chmod(socketPath, socketMode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot set unix socket file mode on %s: %v", socketPath, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listener, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseCipherSuites(names []string) ([]uint16, error) {
|
func parseCipherSuites(names []string) ([]uint16, error) {
|
||||||
cipherNameMap := make(map[string]uint16)
|
cipherNameMap := make(map[string]uint16)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ var _ = Describe("Server", func() {
|
||||||
expectedErr error
|
expectedErr error
|
||||||
expectHTTPListener bool
|
expectHTTPListener bool
|
||||||
expectTLSListener bool
|
expectTLSListener bool
|
||||||
|
expectedSocketMode os.FileMode
|
||||||
|
socketPath string
|
||||||
fdAddr string
|
fdAddr string
|
||||||
ipv6 bool
|
ipv6 bool
|
||||||
}
|
}
|
||||||
|
|
@ -57,6 +59,12 @@ var _ = Describe("Server", func() {
|
||||||
s, ok := srv.(*server)
|
s, ok := srv.(*server)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
|
|
||||||
|
if in.socketPath != "" {
|
||||||
|
fileInfo, err := os.Stat(in.socketPath)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(fileInfo.Mode().Perm()).To(Equal(in.expectedSocketMode.Perm()))
|
||||||
|
}
|
||||||
|
|
||||||
Expect(s.listener != nil).To(Equal(in.expectHTTPListener))
|
Expect(s.listener != nil).To(Equal(in.expectHTTPListener))
|
||||||
if in.expectHTTPListener {
|
if in.expectHTTPListener {
|
||||||
Expect(s.listener.Close()).To(Succeed())
|
Expect(s.listener.Close()).To(Succeed())
|
||||||
|
|
@ -648,6 +656,48 @@ var _ = Describe("Server", func() {
|
||||||
expectTLSListener: true,
|
expectTLSListener: true,
|
||||||
ipv6: true,
|
ipv6: true,
|
||||||
}),
|
}),
|
||||||
|
Entry("with a valid unix socket path", &newServerTableInput{
|
||||||
|
opts: Opts{
|
||||||
|
Handler: handler,
|
||||||
|
BindAddress: "unix:///tmp/oauth2-proxy.sock",
|
||||||
|
},
|
||||||
|
expectedErr: nil,
|
||||||
|
expectHTTPListener: true,
|
||||||
|
expectTLSListener: false,
|
||||||
|
ipv6: false,
|
||||||
|
}),
|
||||||
|
Entry("with a valid unix socket path and a valid socket file mode", &newServerTableInput{
|
||||||
|
opts: Opts{
|
||||||
|
Handler: handler,
|
||||||
|
BindAddress: "unix:///tmp/oauth2-proxy.sock,mode=0777",
|
||||||
|
},
|
||||||
|
expectedErr: nil,
|
||||||
|
expectHTTPListener: true,
|
||||||
|
expectTLSListener: false,
|
||||||
|
expectedSocketMode: 0o777,
|
||||||
|
socketPath: "/tmp/oauth2-proxy.sock",
|
||||||
|
ipv6: false,
|
||||||
|
}),
|
||||||
|
Entry("with a valid unix socket path and a value-less socket file mode argument", &newServerTableInput{
|
||||||
|
opts: Opts{
|
||||||
|
Handler: handler,
|
||||||
|
BindAddress: "unix:///tmp/oauth2-proxy.sock,mode",
|
||||||
|
},
|
||||||
|
expectedErr: errors.New("error setting up listener: listen (unix, /tmp/oauth2-proxy.sock,mode) failed: unix socket option mode expects a value"),
|
||||||
|
expectHTTPListener: false,
|
||||||
|
expectTLSListener: false,
|
||||||
|
ipv6: false,
|
||||||
|
}),
|
||||||
|
Entry("with a valid unix socket path and an invalid socket file mode value", &newServerTableInput{
|
||||||
|
opts: Opts{
|
||||||
|
Handler: handler,
|
||||||
|
BindAddress: "unix:///tmp/oauth2-proxy.sock,mode=-1",
|
||||||
|
},
|
||||||
|
expectedErr: errors.New("error setting up listener: listen (unix, /tmp/oauth2-proxy.sock,mode=-1) failed: unix socket file mode has invalid value -1"),
|
||||||
|
expectHTTPListener: false,
|
||||||
|
expectTLSListener: false,
|
||||||
|
ipv6: false,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue