What username does the kubernetes kubelet use when contacting the kubernetes API? - authentication

So I've been trying to implement ABAC authorization in the kubernetes API, with the following arguments in my kube-api manifest file.
- --authorization-mode=ABAC
- --authorization-policy-file=/etc/kubernetes/auth/abac-rules.json
And the following content in the abac-rulse.json file.
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"*", "nonResourcePath": "*", "readonly": true}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"admin", "namespace": "*", "resource": "*", "apiGroup": "*" }}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"scheduler", "apiGroup": "*", "namespace": "*", "resource": "*", "readonly": false}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"kubelet", "apiGroup": "*", "namespace": "*", "resource": "*", "readonly": false }}
However, the kubelets can't seem to connect to the api servers. I read that the username is taken from the CN field of the -subject in the certificate used to authenticate the connection, see here. In this case that's the fqdn of the hose, i've tried that too with no luck.
Any ideas what i'm doing wrong?
Cheers in advance
Edit:
I'm using Kubernetes version 1.2.2, both kubectl and hyperkube docker image.

Figured out the answer, documenting here for anyone else having the same issue with ABAC.
The kubelet user is define in the worker configuration, which in my case is a yaml file which i store here - /etc/kubernetes/worker-kubeconfig.yaml, the content of which is shown below:
apiVersion: v1
kind: Config
clusters:
- name: default
cluster:
server: https://10.96.17.34:8443
certificate-authority: /etc/kubernetes/ssl/ca.pem
users:
- name: kubelet
user:
client-certificate: /etc/kubernetes/ssl/worker.pem
client-key: /etc/kubernetes/ssl/worker-key.pem
contexts:
- context:
cluster: default
user: kubelet
name: kubelet-context
current-context: kubelet-context
So the user it's connecting with is kubelet.
In my case I had create my certificates with the CN=${MINION_FQDN}, and since this did not match "kubelet" then the ABAC policies weren't met. I regenerated my certifcates with the following arguments and now the nodes authenticate succesfully :)
# Create worker key
openssl genrsa -out $OUT/${WORKER_HOSTNAME}/worker-key.pem 2048
#Creating Worker CSR...
WORKER_FQDN=${WORKER_FQDN} WORKER_IP=${WORKER_IP} openssl req -new -key $OUT/${WORKER_HOSTNAME}/worker-key.pem -out $OUT/${WORKER_HOSTNAME}/worker.csr -subj "/CN=kubelet" -config $SSL_CONFIG
# Creating Worker Cert
WORKER_FQDN=${WORKER_FQDN} WORKER_IP=${WORKER_IP} openssl x509 -req -in $OUT/${WORKER_HOSTNAME}/worker.csr -CA $CA/ca.pem -CAkey $CA/ca-key.pem -CAcreateserial -out $OUT/${WORKER_HOSTNAME}/worker.pem -days 365 -extensions v3_req -extfile $SSL_CONFIG
The important part of which is this:
-subj "/CN=kubelet"
Hope this helps someone else.

Related

Self-Signed SSL certificate for local IP

Development certificate created by command dotnet dev-certs https --trust is works. I want to create a self-signed certificate for local IP in my LAN.
I've created a self-signed certificate by command:
New-SelfSignedCertificate -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(2) -Subject "192.168.1.100" -KeyAlgorithm "RSA" -KeyLength 2048 -HashAlgorithm "SHA256" -CertStoreLocation "Cert:\LocalMachine\My" -KeyUsage KeyEncipherment -FriendlyName "HTTPS development certificate" -TextExtension #("2.5.29.19={critical}{text}","2.5.29.37={critical}{text}1.3.6.1.5.5.7.3.1","2.5.29.17={critical}{text}DNS=192.168.1.100")
Then I copied certificate in trusted folder in certificates store:
After this I edited appsettings.Development.json:
"Kestrel": {
"Endpoints": {
"localhostHttp": {
"Url": "http://192.168.1.100:5000"
},
"localhostHttps": {
"Url": "https://192.168.1.100:5001",
"Certificate": {
"Subject": "192.168.1.100",
"Store": "Root",
"Location": "CurrentUser",
"AllowInvalid": true
}
}
}
But no result:
Is possible to create certificate like this?

This certificate lacks a "hosts" field. This makes it unsuitable for websites

when I execute this command to generate kubernetes certificate:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kubernetes-csr.json | cfssljson -bare kubernetes
Why the cfssl took shows:
[root#iZuf63refzweg1d9dh94t8Z ssl]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
> -config=ca-config.json \
> -profile=kubernetes \
> kubernetes-csr.json | cfssljson -bare kubernetes
2019/08/25 20:02:12 [INFO] generate received request
2019/08/25 20:02:12 [INFO] received CSR
2019/08/25 20:02:12 [INFO] generating key: rsa-2048
2019/08/25 20:02:13 [INFO] encoded CSR
2019/08/25 20:02:13 [INFO] signed certificate with serial number 540759253485135214776496461610290604881680785507
2019/08/25 20:02:13 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
this is my kubernetes(kubernetes-csr.json) config:
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"172.19.104.230",
"172.19.150.82",
"172.19.104.231"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
obviously it contains hosts field. I am using cfssl version 1.2 .Is this a bug?
update cfssl version from v1.2 to v1.3.4(latest version):
go get -u github.com/cloudflare/cfssl/cmd/cfssl

mosquitto self signed certificate issue - handshake failure

I've created self signed CA and certs for mosquito acording to:
https://mosquitto.org/man/mosquitto-tls-7.html and
http://www.steves-internet-guide.com/mosquitto-tls/
Then added these to mosquitto dir and chmoded for mosquitto user, generally did that all with script which runs commands to:
- Create CA
- Create server certs
- Create client certs
#!/bin/bash
# FROM: https://mosquitto.org/man/mosquitto-tls-7.html and
# http://www.steves-internet-guide.com/mosquitto-tls/
set -e
# logging
RESTORE='\033[0m'
RED='\033[00;31m'
GREEN='\033[00;32m'
YELLOW='\033[00;33m'
BLUE='\033[00;34m'
PURPLE='\033[00;35m'
CYAN='\033[00;36m'
LIGHTGRAY='\033[00;37m'
LRED='\033[01;31m'
LGREEN='\033[01;32m'
LYELLOW='\033[01;33m'
LBLUE='\033[01;34m'
LPURPLE='\033[01;35m'
LCYAN='\033[01;36m'
WHITE='\033[01;37m'
REQNUM=0
print_err() {
echo -e "${RED}ERROR $# ${RESTORE}"
}
print_succ() {
echo -e "${GREEN} SUCCES: $# ${RESTORE}"
}
print_warn() {
echo -e "${BLUE} WARN: $# ${RESTORE}"
}
# CA & SRV need to have different params for mosquitto broker to work & to avoid needles asking
SUBJ="-subj "'/C=GB/ST=London/L=London/O='"$((++REQNUM))$1"'/OU=IT_Department/CN=localhost.local'
# gen CA
gen_CA() {
print_warn "generate CA"
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 ${DAYS} -out ca.crt ${SUBJ}
}
# SERVER
gen_server_keys() {
print_warn "Generate a server key"
openssl genrsa ${PSWD} -out server.key 2048 ${SUBJ}
print_warn "Generate a certificate signing request to send to the CA"
openssl req -out server.csr -key server.key -new ${SUBJ}
print_warn "Send the CSR to the CA, or sign it with your CA key"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt ${DAYS}
}
# CLIENT
gen_client_keys() {
print_warn "Generate a client key"
openssl genrsa ${PSWD} -out client.key 2048 ${SUBJ}
print_warn " Generate a certificate signing request to send to the CA"
openssl req -out client.csr -key client.key -new ${SUBJ}
print_warn "Send the CSR to the CA, or sign it with your CA key"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -addtrust clientAuth -CAcreateserial -out client.crt ${DAYS}
}
mosq_install() {
print_warn "Install mqtt certs"
sudo systemctl stop mosquitto
sudo cp server.* ca.crt /etc/mosquitto/certs/
sudo chown -R mosquitto:mosquitto /etc/mosquitto/certs
sudo bash -c 'cat << EOF > /etc/mosquitto/conf.d/tls.conf
listener 8883
tls_version tlsv1.2
require_certificate false
cafile /etc/mosquitto/certs/ca.crt
keyfile /etc/mosquitto/certs/server.key
certfile /etc/mosquitto/certs/server.crt
EOF'
sudo chown -R mosquitto:mosquitto /etc/mosquitto/certs/ /etc/mosquitto/conf.d/
sudo systemctl restart mosquitto && print_warn "MQTT restarted!"
}
print_help() {
echo "usage: "
echo "--CA or --SRV or --CLI"
echo "--des3 to use passwd on cers"
echo "--days 'N' to use expirydate"
echo "--mosq install to mosquitto certs"
}
[ $1 ] || print_help
for a in $#; do
case "$a" in
"--CA")
gen_CA && print_succ "CA" || print_err "CA failed"
;;
"--SRV")
gen_server_keys && print_succ "server" || print_err "server keys failed"
;;
"--CLI")
gen_client_keys && print_succ "cli" || print_err "client keys failed"
;;
"--pass")
PSWD="-des3"
;;
"--days")
DAYS="-days $2"
shift
;;
"--mosq")
mosq_install && print_succ "" || print_err "install mosquitto"
;;
-h|--help)
print_help
;;
*)
print_help;
echo "bad param! $a"
;;
esac
done
After that I get error in mosquitto logs:
159 1528809795: Config loaded from /etc/mosquitto/mosquitto.conf.
160 1528809795: Opening ipv4 listen socket on port 8883.
161 1528809795: Opening ipv6 listen socket on port 8883.
162 1528809806: New connection from 127.0.0.1 on port 8883.
163 1528809806: OpenSSL Error: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
164 1528809806: OpenSSL Error: error:140940E5:SSL routines:ssl3_read_bytes:ssl handshake failure
165 1528809806: Socket error on client , disconnecting.
166 1528809809: New connection from 127.0.0.1 on port 8883
mosquitto.conf
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
In sourced conf.d dir tls.conf:
listener 8883
tls_version tlsv1.2
require_certificate true
cafile /etc/mosquitto/certs/ca.crt
keyfile /etc/mosquitto/certs/server.key
certfile /etc/mosquitto/certs/server.crt
mosquitto_sub command to test:
mosquitto_sub -h localhost -p 8883 --cafile ca.crt -v -t '#'
The only issue in I get with openssl s_client I get is:
"verify return code: 18 (self signed certificate)"
I can't connect with either python paho mqtt, or mosquitto_sub/pub. I've wanted to test connections on localhost, then make certs for my local network server and use it with my devices for testing - but can't make it connect even on localhost.

Configuring SSL in JHipster

I am currently trying to implement a ssl into my current Jhipster application.
So far i have generated a certificate using keytool -genkey -alias iroApp -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 .
In application-dev.yml i changed the server options from:
server:
port: 8080
to:
server:
port: 8443
ssl:
key-store: keystore.p12
key-store-password: myPassword
keyStoreType: PKCS12
keyAlias: myApplicationName
In proxy.conf.json:
From
{
"*": {
"target": "http://localhost:8080",
"secure": false,
"loglevel": "debug"
}
}
To
{
"*": {
"target": "http://localhost:8443",
"secure": true,
"loglevel": "debug"
}
}
In webpack.dev.js i have changed the target ip ports(from 8080 to 8443) and the secure from false to true.
When i enter on the page i get the "This site can’t be reached.localhost unexpectedly closed the connection.ERR_CONNECTION_CLOSED"
Is there something i forgot to do?
Thank you
Your key-alias needs to be all lowercase. It fails silently if you have a capital letter in the alias. You also are missing an indentation in your config, and you shouldn't mix snake-case and camelCase config variables.
Your final config should look like:
server:
port: 8443
ssl:
key-store: keystore.p12
key-store-password: myPassword
key-store-type: PKCS12
key-alias: myapplicationname
This was reported and fixed recently in the generator code (issue link)

Webpack Dev Server running on HTTPS/Web Sockets Secure

Normally in developer mode Webpack runs using HTTP. There is usually a web server serving content through HTTP and webpack using http/websockets on a separate port.
Is it possible to run the web server on https and webpack on https/websocket secure ?
See the webpack docs
There is a flag you can add to the webpack-dev-server command
webpack-dev-server --https
While the above answer is correct for cli, if you are not in the CLI, you could do something like this (in a gulp task):
var WebpackDevServer = require('webpack-dev-server');
new WebpackDevServer(webpack(WebpackDevConfig), {
https: true,
hot: true,
watch: true,
contentBase: path.join(__dirname, 'src'),
historyApiFallback: true
}).listen(1337, 'localhost', function(err, result) {
if (err) {
console.log(err);
}
console.log('Dev server running at https://localhost:1337');
});
this for TEST environment only:
you need to configure your webpack-dev-server as follows:
webpack-dev-server --https --cert ./cert.pem --key ./key.pem
The easiest work around is to generate a key with no passphrase (I don't know the security consequences of this! but this is for test only) .
To take the passphrase out of your key use this command:
$ openssl rsa -in key.pem -out newKey.pem
and use the new key in the previews configuration line
With webpack-dev-server --https you create a self-signed certificate. But it works not for all use cases.
Browsers will ask you for a security exception and show in the url bar that connection is not secure.
Therefore it is recommended to create a locally trusted development certificate for localhost with mkcert
Then use it via CLI:
webpack-dev-server --https --key C:/Users/User/localhost-key.pem --cert C:/Users/User/localhost.pem --cacert C:/Users/User/AppData/Local/mkcert/rootCA.pem
or configure devServer.https option in webpack.config.js:
devServer: {
https: {
key: fs.readFileSync('C:/Users/User/localhost-key.pem'),
cert: fs.readFileSync('C:/Users/User/localhost.pem'),
ca: fs.readFileSync('C:/Users/User/AppData/Local/mkcert/rootCA.pem')
}
}
mkcert creates .pem files in Unix format by default. So if you're on Windows you'll probably need convert them to Windows format using e.g. Notepad++
Tested on Windows (04/22/2021). Easy (no installations required).
1. Project configuration
In your project root run in Powershell (or CMD):
npx mkcert create-ca
npx mkcert create-cert
Your webpack.config.js:
devServer: {
// ...
https: {
key: fs.readFileSync("cert.key"),
cert: fs.readFileSync("cert.crt"),
ca: fs.readFileSync("ca.crt"),
},
// ....
},
2. Install certificate
Double-click on ca.crt > Install Certificate > ...
... > Current User > Place all certificates in the following store > Trusted Root Certification Authorities > ...
... > Finish > Yes
3. Check correct installation
Start > Type: "cert" > Manage User Certificates > ...
... > Trusted Root Certification Authorities > Certificates > Test CA
4. Reload & Test
Reload your browser, Start yout webpack dev server and check the SSL Certificate validity:
Additional steps
If you get this error:
You can add this configuration to your webpack.config.js:
devServer: {
// ...
// https: { ... }
disableHostCheck: true,
// ....
},
For more info:
https://webpack.js.org/configuration/dev-server/#devserverhttps
https://www.npmjs.com/package/mkcert
In my case I had to run all these commands to get the certificate:
openssl genrsa -out private.key 4096
openssl req -new -sha256 -out private.csr -key private.key
openssl x509 -req -days 3650 -in private.csr -signkey private.key -out private.crt -extensions req_ext
openssl x509 -in private.crt -out private.pem -outform PEM
And then finally:
npm run dev -- --open --https --cert private.pem --key private.key
I'm working on react project, Now wanted to add SSL certificate on this project and run my website with https so have followed below step:
In add https in webpack.config.js
devServer: {
https: true,
host: '0.0.0.0', // you can change this ip with your ip
port: 443, // ssl defult port number
inline: true,
historyApiFallback: true,
publicPath: '/',
contentBase: './dist',
disableHostCheck: true
}
Add SSL public certificate on package.json file If you didn't want to add a certificate on your package.json file then you have to add it on your webpack.config.js it is mandatory to add your certificate in your project either you can it on package.json file or webpack.config.js
For Package.json
scripts: {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"start": "webpack-dev-server --open --https --cert /path/to/private.crt --key /path/to/private.key"
}
OR webpack.config.js
devServer: {
https: true,
host: '0.0.0.0', // you can change this ip with your ip
port: 443, // ssl defult port number
inline: true,
https: {
key: fs.readFileSync('/path/to/private.pem'),
cert: fs.readFileSync('/path/to/private.pem'),
ca: fs.readFileSync('/path/to/private.pem')
}
historyApiFallback: true,
publicPath: '/',
contentBase: './dist',
disableHostCheck: true
}
Run npm start command on a terminal or you can also use pm2 start npm -- start
Had similar case when webapp was served from docker container which internally uses http, but traefik is serving app though https (multiple ports: 4000, 3000), so socket client was trying to connect to http://my.app.url:3000.
After spending a few hours to figure out a solution, came up with this in webpack 5:
devServer: {
client: {
port: ' ', //<--must be empty to eliminate the 3000 port for connecting to socket client
},
devMiddleware: {
writeToDisk: true,
},
transportMode: 'sockjs',
port: 3000, // port which is dev server opening for the sockets
...(process.env.DOCKER_DEV && {
host: '0.0.0.0',
firewall: false,
public: 'https://my.app.url', <-- HTTPS here
}),
},