Skip to content

Commit

Permalink
Merge pull request #484 from jcmoraisjr/jm-security
Browse files Browse the repository at this point in the history
Add security options
  • Loading branch information
jcmoraisjr authored Dec 20, 2019
2 parents a8e50b6 + 35c8250 commit e9976a4
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 9 deletions.
35 changes: 35 additions & 0 deletions docs/content/en/docs/configuration/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ The table below describes all supported configuration keys.
| [`timeout-stop`](#timeout) | time with suffix | Global | no timeout |
| [`timeout-tunnel`](#timeout) | time with suffix | Backend | `1h` |
| [`tls-alpn`](#tls-alpn) | TLS ALPN advertisement | Global | `h2,http/1.1` |
| [`use-chroot`](#security) | [true\|false] | Global | `false` |
| [`use-haproxy-user`](#security) | [true\|false] | Global | `false` |
| [`use-htx`](#use-htx) | [true\|false] | Global | `false` |
| [`use-proxy-protocol`](#proxy-protocol) | [true\|false] | Global | `false` |
| [`use-resolver`](#dns-resolvers) | resolver name | Backend | |
Expand Down Expand Up @@ -1251,6 +1253,39 @@ See also:

---

## Security

| Configuration key | Scope | Default | Since |
|--------------------|----------|---------|-------|
| `use-chroot` | `Global` | `false` | v0.9 |
| `use-haproxy-user` | `Global` | `false` | v0.9 |

Change security options.

* `use-chroot`: If `true`, configures haproxy to perform a `chroot()` in the empty and non-writable directory `/var/empty` during the startup process, just before it drops its own privileges. Only root can perform a `chroot()`, so HAProxy Ingress container should start as UID `0` if this option is configured as `true`.
* `use-haproxy-user`: Defines if the haproxy's process should be changed to `haproxy`, UID `1001`. The default value `false` leaves haproxy running as root. Note that even running as root, haproxy always drops its own privileges before start its event loop.

In the default configuration, HAProxy Ingress container starts as root. It is also possible to configure the container to start as `haproxy` user, UID `1001`. Read the [Security considerations](http://cbonte.github.io/haproxy-dconv/1.9/management.html#13) from HAProxy doc before change the starting user. The starting user can be changed in the deployment or daemonset's pod template using the following configuration:

```yaml
...
template:
spec:
securityContext:
runAsUser: 1001
```

Note that ports below 1024 cannot be bound if the container starts as non-root.

See also:

* http://cbonte.github.io/haproxy-dconv/1.9/management.html#13
* http://cbonte.github.io/haproxy-dconv/1.9/configuration.html#3.1-chroot
* http://cbonte.github.io/haproxy-dconv/1.9/configuration.html#3.1-uid
* http://cbonte.github.io/haproxy-dconv/1.9/configuration.html#3.1-gid

---

## Server alias

| Configuration key | Scope | Default | Since |
Expand Down
6 changes: 3 additions & 3 deletions pkg/common/ingress/controller/launch.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,15 @@ func NewIngressController(backend ingress.Controller) *GenericController {
glog.Fatalf("resync period (%vs) is too low", resyncPeriod.Seconds())
}

err = os.MkdirAll(ingress.DefaultSSLDirectory, 0655)
err = os.MkdirAll(ingress.DefaultSSLDirectory, 0755)
if err != nil {
glog.Fatalf("Failed to mkdir SSL directory: %v", err)
}
err = os.MkdirAll(ingress.DefaultCACertsDirectory, 0655)
err = os.MkdirAll(ingress.DefaultCACertsDirectory, 0755)
if err != nil {
glog.Fatalf("Failed to mkdir cacerts directory: %v", err)
}
err = os.MkdirAll(ingress.DefaultCrlDirectory, 0655)
err = os.MkdirAll(ingress.DefaultCrlDirectory, 0755)
if err != nil {
glog.Fatalf("Failed to mkdir crl directory: %v", err)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/converters/ingress/annotations/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ func (c *updater) UpdateGlobalConfig(haproxyConfig haproxy.Config, mapper *Mappe
d.global.LoadServerState = mapper.Get(ingtypes.GlobalLoadServerState).Bool()
d.global.SSL.ALPN = mapper.Get(ingtypes.GlobalTLSALPN).Value
d.global.StrictHost = mapper.Get(ingtypes.GlobalStrictHost).Bool()
d.global.UseChroot = mapper.Get(ingtypes.GlobalUseChroot).Bool()
d.global.UseHAProxyUser = mapper.Get(ingtypes.GlobalUseHAProxyUser).Bool()
d.global.UseHTX = mapper.Get(ingtypes.GlobalUseHTX).Bool()
c.buildGlobalAcme(d)
c.buildGlobalBind(d)
Expand Down
2 changes: 2 additions & 0 deletions pkg/converters/ingress/types/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ const (
GlobalTCPLogFormat = "tcp-log-format"
GlobalTimeoutStop = "timeout-stop"
GlobalTLSALPN = "tls-alpn"
GlobalUseChroot = "use-chroot"
GlobalUseHAProxyUser = "use-haproxy-user"
GlobalUseHTX = "use-htx"
GlobalUseProxyProtocol = "use-proxy-protocol"
)
6 changes: 3 additions & 3 deletions pkg/haproxy/instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ func TestInstanceEmpty(t *testing.T) {
c.checkConfig(`
global
daemon
stats socket /var/run/haproxy.sock level admin expose-fd listeners
stats socket /var/run/haproxy.sock level admin expose-fd listeners mode 600
maxconn 2000
hard-stop-after 15m
lua-load /usr/local/etc/haproxy/lua/auth-request.lua
Expand Down Expand Up @@ -2065,7 +2065,7 @@ func TestInstanceSyslog(t *testing.T) {
c.checkConfig(`
global
daemon
stats socket /var/run/haproxy.sock level admin expose-fd listeners
stats socket /var/run/haproxy.sock level admin expose-fd listeners mode 600
maxconn 2000
hard-stop-after 15m
log 127.0.0.1:1514 len 2048 format rfc3164 local0
Expand Down Expand Up @@ -2957,7 +2957,7 @@ func (c *testConfig) checkConfig(expected string) {
replace := map[string]string{
"<<global>>": `global
daemon
stats socket /var/run/haproxy.sock level admin expose-fd listeners
stats socket /var/run/haproxy.sock level admin expose-fd listeners mode 600
maxconn 2000
hard-stop-after 15m
lua-load /usr/local/etc/haproxy/lua/auth-request.lua
Expand Down
2 changes: 2 additions & 0 deletions pkg/haproxy/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ type Global struct {
Healthz HealthzConfig
Stats StatsConfig
StrictHost bool
UseChroot bool
UseHAProxyUser bool
UseHTX bool
CustomConfig []string
CustomDefaults []string
Expand Down
9 changes: 7 additions & 2 deletions rootfs/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@
# limitations under the License.

FROM haproxy:1.9.13-alpine
RUN apk --no-cache add socat openssl lua5.3 lua-socket dumb-init \
&& mkdir -p /ingress-controller /etc/haproxy/maps
RUN apk --no-cache add socat openssl lua5.3 lua-socket dumb-init

COPY . /

RUN addgroup -g 1001 haproxy\
&& adduser -u 1001 -G haproxy -D -s /bin/false haproxy\
&& mkdir -p /var/empty /var/lib/haproxy /etc/haproxy/maps /ingress-controller\
&& chown -R haproxy:haproxy /run /var/lib/haproxy /etc/haproxy /ingress-controller\
&& chmod 0 /var/empty

STOPSIGNAL SIGTERM
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/start.sh"]
9 changes: 8 additions & 1 deletion rootfs/etc/haproxy/template/haproxy.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
{{- $global := $cfg.Global }}
global
daemon
{{- if $global.UseHAProxyUser }}
user haproxy
group haproxy
{{- end }}
{{- if $global.UseChroot }}
chroot /var/empty
{{- end }}
{{- if gt $global.Procs.Nbproc 1 }}
nbproc {{ $global.Procs.Nbproc }}
{{- end }}
Expand All @@ -19,7 +26,7 @@ global
{{- if $global.Procs.CPUMap }}
cpu-map {{ $global.Procs.CPUMap }}
{{- end }}
stats socket {{ default "--" $global.AdminSocket }} level admin expose-fd listeners
stats socket {{ default "--" $global.AdminSocket }} level admin expose-fd listeners mode 600
{{- if gt $global.Procs.Nbproc 1 }} process 1{{ end }}
{{- if $global.LoadServerState }}
server-state-file state-global
Expand Down

0 comments on commit e9976a4

Please sign in to comment.