mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
Add client certificate authentication support to core Authenticator
This is required to make the websocket tunnel server functional on etcd-only nodes, and will save some code on the RKE2 side once pulled through. Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
This commit is contained in:
parent
e7437d4ad8
commit
af0b496ef3
56
pkg/authenticator/authenticator.go
Normal file
56
pkg/authenticator/authenticator.go
Normal file
@ -0,0 +1,56 @@
|
||||
package authenticator
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/k3s-io/k3s/pkg/authenticator/basicauth"
|
||||
"github.com/k3s-io/k3s/pkg/authenticator/passwordfile"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
"k8s.io/apiserver/pkg/authentication/group"
|
||||
"k8s.io/apiserver/pkg/authentication/request/union"
|
||||
"k8s.io/apiserver/pkg/authentication/request/x509"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
)
|
||||
|
||||
func FromArgs(args []string) (authenticator.Request, error) {
|
||||
var authenticators []authenticator.Request
|
||||
basicFile := getArg("--basic-auth-file", args)
|
||||
if basicFile != "" {
|
||||
basicAuthenticator, err := passwordfile.NewCSV(basicFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authenticators = append(authenticators, basicauth.New(basicAuthenticator))
|
||||
}
|
||||
|
||||
clientCA := getArg("--client-ca-file", args)
|
||||
if clientCA != "" {
|
||||
ca, err := dynamiccertificates.NewDynamicCAContentFromFile("client-ca", clientCA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authenticators = append(authenticators, x509.NewDynamic(ca.VerifyOptions, x509.CommonNameUserConversion))
|
||||
}
|
||||
|
||||
return Combine(authenticators...), nil
|
||||
}
|
||||
|
||||
func getArg(key string, args []string) string {
|
||||
for _, arg := range args {
|
||||
if !strings.HasPrefix(arg, key) {
|
||||
continue
|
||||
}
|
||||
return strings.SplitN(arg, "=", 2)[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func Combine(auths ...authenticator.Request) authenticator.Request {
|
||||
var authenticators []authenticator.Request
|
||||
for _, auth := range auths {
|
||||
if auth != nil {
|
||||
authenticators = append(authenticators, auth)
|
||||
}
|
||||
}
|
||||
return group.NewAuthenticatedGroupAdder(union.New(authenticators...))
|
||||
}
|
@ -20,17 +20,16 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
localAuthenticator "github.com/k3s-io/k3s/pkg/authenticator"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
)
|
||||
|
||||
// Authenticator authenticates requests using basic auth
|
||||
type Authenticator struct {
|
||||
auth localAuthenticator.Password
|
||||
auth Password
|
||||
}
|
||||
|
||||
// New returns a request authenticator that validates credentials using the provided password authenticator
|
||||
func New(auth localAuthenticator.Password) *Authenticator {
|
||||
func New(auth Password) *Authenticator {
|
||||
return &Authenticator{auth}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package authenticator
|
||||
package basicauth
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,30 +0,0 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"github.com/k3s-io/k3s/pkg/authenticator/basicauth"
|
||||
"github.com/k3s-io/k3s/pkg/authenticator/passwordfile"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
"k8s.io/apiserver/pkg/authentication/group"
|
||||
"k8s.io/apiserver/pkg/authentication/request/union"
|
||||
)
|
||||
|
||||
func basicAuthenticator(basicAuthFile string) (authenticator.Request, error) {
|
||||
if basicAuthFile == "" {
|
||||
return nil, nil
|
||||
}
|
||||
basicAuthenticator, err := passwordfile.NewCSV(basicAuthFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return basicauth.New(basicAuthenticator), nil
|
||||
}
|
||||
|
||||
func combineAuthenticators(auths ...authenticator.Request) authenticator.Request {
|
||||
var authenticators []authenticator.Request
|
||||
for _, auth := range auths {
|
||||
if auth != nil {
|
||||
authenticators = append(authenticators, auth)
|
||||
}
|
||||
}
|
||||
return group.NewAuthenticatedGroupAdder(union.New(authenticators...))
|
||||
}
|
@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/k3s-io/k3s/pkg/authenticator"
|
||||
"github.com/k3s-io/k3s/pkg/cluster"
|
||||
"github.com/k3s-io/k3s/pkg/daemons/config"
|
||||
"github.com/k3s-io/k3s/pkg/daemons/control/deps"
|
||||
@ -56,11 +57,15 @@ func Server(ctx context.Context, cfg *config.Control) error {
|
||||
cfg.Runtime.Tunnel = setupTunnel()
|
||||
proxyutil.DisableProxyHostnameCheck = true
|
||||
|
||||
basicAuth, err := basicAuthenticator(cfg.Runtime.PasswdFile)
|
||||
authArgs := []string{
|
||||
"--basic-auth-file=" + cfg.Runtime.PasswdFile,
|
||||
"--client-ca-file=" + cfg.Runtime.ClientCA,
|
||||
}
|
||||
auth, err := authenticator.FromArgs(authArgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Runtime.Authenticator = basicAuth
|
||||
cfg.Runtime.Authenticator = auth
|
||||
|
||||
if !cfg.DisableAPIServer {
|
||||
go waitForAPIServerHandlers(ctx, cfg.Runtime)
|
||||
@ -399,7 +404,7 @@ func waitForAPIServerHandlers(ctx context.Context, runtime *config.ControlRuntim
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to get request handlers from apiserver: %v", err)
|
||||
}
|
||||
runtime.Authenticator = combineAuthenticators(runtime.Authenticator, auth)
|
||||
runtime.Authenticator = authenticator.Combine(runtime.Authenticator, auth)
|
||||
runtime.APIServer = handler
|
||||
}
|
||||
|
||||
|
@ -9,13 +9,20 @@ import (
|
||||
|
||||
"github.com/rancher/remotedialer"
|
||||
"github.com/rancher/wrangler/pkg/kv"
|
||||
"github.com/sirupsen/logrus"
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||
)
|
||||
|
||||
func loggingErrorWriter(rw http.ResponseWriter, req *http.Request, code int, err error) {
|
||||
logrus.Debugf("remoteDialer error: %d %v", code, err)
|
||||
rw.WriteHeader(code)
|
||||
rw.Write([]byte(err.Error()))
|
||||
}
|
||||
|
||||
func setupTunnel() http.Handler {
|
||||
tunnelServer := remotedialer.New(authorizer, remotedialer.DefaultErrorWriter)
|
||||
tunnelServer := remotedialer.New(authorizer, loggingErrorWriter)
|
||||
setupProxyDialer(tunnelServer)
|
||||
return tunnelServer
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user