Skip to content

Commit

Permalink
Merge #34772
Browse files Browse the repository at this point in the history
34772: ccl/gssapiccl: add GSS authentication support on Linux r=mjibson a=mjibson

GSS support uses the same logic from postgres. It works by calling a C
method statically compiled into cockroach in a loop, passing back and
forth various GSS tokens until a completed authentication is done.

Enterprise license checks are done at the end of a GSS auth session. This
allows administrators to test and verify their GSS setup before needing
to buy an enterprise license.

We directly include the krb5 library so we can statically compile an
exact version into the binary. The builder image has been changed to add
(well, keep) bison/yacc which is needed to build krb5.

Testing is done by using a docker-compose file. It defines containers
for the kdc, cockroach server, and psql binary. This has proven to be
the easiest way to get a correct test written.

We support (and require) the include_realm=0 option to be present, which
strips the realm from the GSS username. This removes the immediate need to
either add user identity mapping or for allowing additional characters in
usernames. The krb_realm option is also supported, with the addition that
it can be specified more than once to support multiple realms at once.

Release note (enterprise change): Add a GSS auth method configurable by
the server.host_based_authentication.configuration cluster setting.

Co-authored-by: Matt Jibson <[email protected]>
  • Loading branch information
craig[bot] and maddyblue committed Feb 25, 2019
2 parents 078e758 + 668a74a commit 8617827
Show file tree
Hide file tree
Showing 28 changed files with 3,584 additions and 2,115 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@
[submodule "pkg/ui/yarn-vendor"]
path = pkg/ui/yarn-vendor
url = https://github.com/cockroachdb/yarn-vendored
[submodule "c-deps/krb5"]
path = c-deps/krb5
url = https://github.com/cockroachdb/krb5.git
37 changes: 33 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ PROTOBUF_SRC_DIR := $(C_DEPS_DIR)/protobuf
ROCKSDB_SRC_DIR := $(C_DEPS_DIR)/rocksdb
SNAPPY_SRC_DIR := $(C_DEPS_DIR)/snappy
LIBROACH_SRC_DIR := $(C_DEPS_DIR)/libroach
KRB5_SRC_DIR := $(C_DEPS_DIR)/krb5

# Derived build variants.
use-stdmalloc := $(findstring stdmalloc,$(TAGS))
Expand All @@ -429,6 +430,7 @@ PROTOBUF_DIR := $(BUILD_DIR)/protobuf$(if $(use-msan),_msan)
ROCKSDB_DIR := $(BUILD_DIR)/rocksdb$(if $(use-msan),_msan)$(if $(use-stdmalloc),_stdmalloc)$(if $(USE_ROCKSDB_ASSERTIONS),_assert)
SNAPPY_DIR := $(BUILD_DIR)/snappy$(if $(use-msan),_msan)
LIBROACH_DIR := $(BUILD_DIR)/libroach$(if $(use-msan),_msan)
KRB5_DIR := $(BUILD_DIR)/krb5$(if $(use-msan),_msan)
# Can't share with protobuf because protoc is always built for the host.
PROTOC_DIR := $(GOPATH)/native/$(HOST_TRIPLE)/protobuf

Expand All @@ -439,12 +441,20 @@ LIBROCKSDB := $(ROCKSDB_DIR)/librocksdb.a
LIBSNAPPY := $(SNAPPY_DIR)/libsnappy.a
LIBROACH := $(LIBROACH_DIR)/libroach.a
LIBROACHCCL := $(LIBROACH_DIR)/libroachccl.a
LIBKRB5 := $(KRB5_DIR)/lib/libgssapi_krb5.a
PROTOC := $(PROTOC_DIR)/protoc

C_LIBS_COMMON = $(if $(use-stdmalloc),,$(LIBJEMALLOC)) $(LIBPROTOBUF) $(LIBSNAPPY) $(LIBROCKSDB)
C_LIBS_OSS = $(C_LIBS_COMMON) $(LIBROACH)
C_LIBS_CCL = $(C_LIBS_COMMON) $(LIBCRYPTOPP) $(LIBROACHCCL)

# We only include krb5 on linux.
ifeq "$(findstring linux,$(TARGET_TRIPLE))" "linux"
C_LIBS_CCL += $(LIBKRB5)
KRB_CPPFLAGS := -I$(KRB5_DIR)/include
KRB_DIR := $(KRB5_DIR)/lib
endif

# Go does not permit dashes in build tags. This is undocumented.
native-tag := $(subst -,_,$(TARGET_TRIPLE))$(if $(use-stdmalloc),_stdmalloc)$(if $(use-msan),_msan)

Expand All @@ -466,7 +476,7 @@ native-tag := $(subst -,_,$(TARGET_TRIPLE))$(if $(use-stdmalloc),_stdmalloc)$(if
# constraint `{native-tag}` and are built the first time a Make-driven build
# encounters a given native tag. These tags are unset when building with the Go
# toolchain directly, so these files are only compiled when building with Make.
CGO_PKGS := cli server/status storage/engine ccl/storageccl/engineccl
CGO_PKGS := cli server/status storage/engine ccl/storageccl/engineccl ccl/gssapiccl
CGO_UNSUFFIXED_FLAGS_FILES := $(addprefix ./pkg/,$(addsuffix /zcgo_flags.go,$(CGO_PKGS)))
CGO_SUFFIXED_FLAGS_FILES := $(addprefix ./pkg/,$(addsuffix /zcgo_flags_$(native-tag).go,$(CGO_PKGS)))
CGO_FLAGS_FILES := $(CGO_UNSUFFIXED_FLAGS_FILES) $(CGO_SUFFIXED_FLAGS_FILES)
Expand All @@ -480,8 +490,8 @@ $(CGO_FLAGS_FILES): Makefile
@echo >> $@
@echo 'package $(notdir $(@D))' >> $@
@echo >> $@
@echo '// #cgo CPPFLAGS: -I$(JEMALLOC_DIR)/include' >> $@
@echo '// #cgo LDFLAGS: $(addprefix -L,$(CRYPTOPP_DIR) $(PROTOBUF_DIR) $(JEMALLOC_DIR)/lib $(SNAPPY_DIR) $(ROCKSDB_DIR) $(LIBROACH_DIR))' >> $@
@echo '// #cgo CPPFLAGS: -I$(JEMALLOC_DIR)/include $(KRB_CPPFLAGS)' >> $@
@echo '// #cgo LDFLAGS: $(addprefix -L,$(CRYPTOPP_DIR) $(PROTOBUF_DIR) $(JEMALLOC_DIR)/lib $(SNAPPY_DIR) $(ROCKSDB_DIR) $(LIBROACH_DIR) $(KRB_DIR))' >> $@
@echo 'import "C"' >> $@

# BUILD ARTIFACT CACHING
Expand Down Expand Up @@ -531,6 +541,19 @@ $(JEMALLOC_DIR)/Makefile: $(C_DEPS_DIR)/jemalloc-rebuild $(JEMALLOC_SRC_DIR)/con
@# https://github.com/jemalloc/jemalloc/issues/585.
cd $(JEMALLOC_DIR) && $(JEMALLOC_SRC_DIR)/configure $(xconfigure-flags) $(if $(findstring musl,$(TARGET_TRIPLE)),,--enable-prof)

$(KRB5_SRC_DIR)/src/configure.in: | bin/.submodules-initialized

$(KRB5_SRC_DIR)/src/configure: $(KRB5_SRC_DIR)/src/configure.in
cd $(KRB5_SRC_DIR)/src && autoreconf

$(KRB5_DIR)/Makefile: $(C_DEPS_DIR)/krb5-rebuild $(KRB5_SRC_DIR)/src/configure
rm -rf $(KRB5_DIR)
mkdir -p $(KRB5_DIR)
@# NOTE: If you change the configure flags below, bump the version in
@# $(C_DEPS_DIR)/krb5-rebuild. See above for rationale.
@# If CFLAGS is set to -g1 then make will fail. Use "env -" to clear the environment.
cd $(KRB5_DIR) && env -u CFLAGS -u CXXFLAGS $(KRB5_SRC_DIR)/src/configure $(xconfigure-flags) --enable-static --disable-shared

$(PROTOBUF_DIR)/Makefile: $(C_DEPS_DIR)/protobuf-rebuild | bin/.submodules-initialized
rm -rf $(PROTOBUF_DIR)
mkdir -p $(PROTOBUF_DIR)
Expand Down Expand Up @@ -639,8 +662,11 @@ $(LIBROACH): $(LIBROACH_DIR)/Makefile bin/uptodate .ALWAYS_REBUILD
$(LIBROACHCCL): $(LIBROACH_DIR)/Makefile bin/uptodate .ALWAYS_REBUILD
@uptodate $@ $(libroach-inputs) || $(MAKE) --no-print-directory -C $(LIBROACH_DIR) roachccl

$(LIBKRB5): $(KRB5_DIR)/Makefile bin/uptodate .ALWAYS_REBUILD
@uptodate $@ $(KRB5_SRC_DIR)/src || $(MAKE) --no-print-directory -C $(KRB5_DIR)

# Convenient names for maintainers. Not used by other targets in the Makefile.
.PHONY: protoc libcryptopp libjemalloc libprotobuf libsnappy librocksdb libroach libroachccl
.PHONY: protoc libcryptopp libjemalloc libprotobuf libsnappy librocksdb libroach libroachccl libkrb5
protoc: $(PROTOC)
libcryptopp: $(LIBCRYPTOPP)
libjemalloc: $(LIBJEMALLOC)
Expand All @@ -649,6 +675,7 @@ libsnappy: $(LIBSNAPPY)
librocksdb: $(LIBROCKSDB)
libroach: $(LIBROACH)
libroachccl: $(LIBROACHCCL)
libkrb5: $(LIBKRB5)

PHONY: check-libroach
check-libroach: ## Run libroach tests.
Expand Down Expand Up @@ -1404,6 +1431,7 @@ clean-c-deps:
rm -rf $(ROCKSDB_DIR)
rm -rf $(SNAPPY_DIR)
rm -rf $(LIBROACH_DIR)
rm -rf $(KRB5_DIR)

.PHONY: unsafe-clean-c-deps
unsafe-clean-c-deps:
Expand All @@ -1413,6 +1441,7 @@ unsafe-clean-c-deps:
git -C $(ROCKSDB_SRC_DIR) clean -dxf
git -C $(SNAPPY_SRC_DIR) clean -dxf
git -C $(LIBROACH_SRC_DIR) clean -dxf
git -C $(KRB5_SRC_DIR) clean -dxf

.PHONY: clean
clean: ## Remove build artifacts.
Expand Down
2 changes: 1 addition & 1 deletion build/builder.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -euo pipefail

image=cockroachdb/builder
version=20190115-153202
version=20190124-062428

function init() {
docker build --tag="${image}" "$(dirname "${0}")/builder"
Expand Down
1 change: 0 additions & 1 deletion build/builder/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ RUN apt-get purge -y \
apt-transport-https \
automake \
autopoint \
bison \
bzip2 \
file \
flex \
Expand Down
2 changes: 2 additions & 0 deletions build/variables.mk
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ define VALID_VARS
JEMALLOC_SRC_DIR
JS_PROTOS_CCL
KARMA
KRB_CPPFLAGS
KRB_DIR
LC_ALL
LDFLAGS
LIBCRYPTOPP
Expand Down
2 changes: 1 addition & 1 deletion build/verify-archive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
set -euo pipefail

apt-get update
apt-get install -y autoconf cmake libncurses-dev
apt-get install -y autoconf bison cmake libncurses-dev

workdir=$(mktemp -d)
tar xzf cockroach.src.tgz -C "$workdir"
Expand Down
1 change: 1 addition & 0 deletions c-deps/krb5
Submodule krb5 added at 97e3c4
4 changes: 4 additions & 0 deletions c-deps/krb5-rebuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Bump the version below when changing krb5 configure flags. Search for "BUILD
ARTIFACT CACHING" in build/common.mk for rationale.

1
7 changes: 7 additions & 0 deletions pkg/acceptance/cluster/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,21 @@ func GenerateCerts(ctx context.Context) func() {
certsDir, filepath.Join(certsDir, security.EmbeddedCAKey),
keyLen, 96*time.Hour, false, false))

// Root user.
maybePanic(security.CreateClientPair(
certsDir, filepath.Join(certsDir, security.EmbeddedCAKey),
512, 48*time.Hour, false, security.RootUser, true /* generate pk8 key */))

// Test user.
maybePanic(security.CreateClientPair(
certsDir, filepath.Join(certsDir, security.EmbeddedCAKey),
512, 48*time.Hour, false, "testuser", true /* generate pk8 key */))

// Certs for starting a cockroach server. Key size is from cli/cert.go:defaultKeySize.
maybePanic(security.CreateNodePair(
certsDir, filepath.Join(certsDir, security.EmbeddedCAKey),
2048, 48*time.Hour, false, []string{"localhost", "cockroach"}))

// Store a copy of the client certificate and private key in a PKCS#12
// bundle, which is the only format understood by Npgsql (.NET).
{
Expand Down
34 changes: 34 additions & 0 deletions pkg/acceptance/compose/gss/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: '3'
services:
kdc:
build: ./kdc
volumes:
- ./kdc/start.sh:/start.sh
- keytab:/keytab
cockroach:
image: ubuntu:xenial-20170214
depends_on:
- kdc
command: /cockroach/cockroach --certs-dir=/certs start --listen-addr cockroach
environment:
- KRB5_KTNAME=/keytab/crdb.keytab
volumes:
- ../../.localcluster.certs:/certs
- keytab:/keytab
- ../../../../cockroach-linux-2.6.32-gnu-amd64:/cockroach/cockroach
psql:
build: ./psql
depends_on:
- cockroach
environment:
- PGHOST=cockroach
- PGPORT=26257
- PGSSLCERT=/certs/node.crt
- PGSSLKEY=/certs/node.key
volumes:
- ./kdc/krb5.conf:/etc/krb5.conf
- ./psql/gss_test.go:/test/gss_test.go
- ./psql/start.sh:/start.sh
- ../../.localcluster.certs:/certs
volumes:
keytab:
13 changes: 13 additions & 0 deletions pkg/acceptance/compose/gss/kdc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM alpine:3.9

RUN apk add --no-cache \
krb5-server \
&& rm -rf /var/cache/apk/*

COPY krb5.conf /etc/krb5.conf

RUN kdb5_util create -s -P kpass \
&& kadmin.local -q "addprinc -pw psql [email protected]" \
&& kadmin.local -q "addprinc -randkey postgres/[email protected]"

CMD ["/start.sh"]
32 changes: 32 additions & 0 deletions pkg/acceptance/compose/gss/kdc/krb5.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

[libdefaults]
default_realm = MY.EX
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = yes

[realms]
MY.EX = {
kdc = kdc:88
admin_server = kdc:74
default_domain = my.ex
}

[domain_realm]
.my.ex = MY.EX
my.ex = MY.EX

[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
10 changes: 10 additions & 0 deletions pkg/acceptance/compose/gss/kdc/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

set -e

# The /keytab directory is volume mounted on both kdc and cockroach. kdc
# can create the keytab with kadmin.local here and it is then useable
# by cockroach.
kadmin.local -q "ktadd -k /keytab/crdb.keytab postgres/[email protected]"

krb5kdc -n
24 changes: 24 additions & 0 deletions pkg/acceptance/compose/gss/psql/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM postgres:11

RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \
build-essential \
ca-certificates \
curl \
git \
krb5-user

RUN curl https://dl.google.com/go/go1.11.5.linux-amd64.tar.gz | tar xz -C /usr/local

ENV PATH="/usr/local/go/bin:${PATH}"

COPY gss_test.go /test/

# Fetch the go packages we need but remove the script so it can be
# volume mounted at run-time enabling it to be changed without rebuilding
# the image.
RUN cd /test \
&& go get -d -t -tags gss \
&& rm -rf /test

ENTRYPOINT ["/start.sh"]
11 changes: 11 additions & 0 deletions pkg/acceptance/compose/gss/psql/empty.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2019 The Cockroach Authors.
//
// Licensed as a CockroachDB Enterprise file under the Cockroach Community
// License (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt

package gss

// This file is here so go test always finds at least one file.
Loading

0 comments on commit 8617827

Please sign in to comment.