История изменений
Исправление DiKeert, (текущая версия) :
Я тут запарился для настройки kubernetes с этим, вот тебе Makefile который делает это.
В кратце все довольно просто - у тебя есть сертификат некоторого Authority - это сертификат которому ты просто доверяешь. Конечно для того, что бы этим сертификатом оперировать, нужен ключ. Поэтому сначала ты генерируешь ключ, потом сертификат, согласно этому ключу. Алгоритмы щас не очень важны, я саму суть объясняю.
У тебя теперь есть Authority, сертификат которому ты доверяешь. Теперь тебе нужно сделать сертификат, которому будут доверять все, кто доверяет этому Authority. Делается это через цифровую подпись.
То есть ты генерируешь новый ключ, согласно ему генерируешь сертификат и потом используешь Authority твою, что бы подписать новый сертификат. То есть этому сертификату будут доверять все, кто доверяет твоей Authority, без дополнительных вопросов. Этот сертификат ты используешь для своего сервера какого-нибудь. Ессно dns имя/IP сервака должны совпадать с указанными в сертификате. Можно указывать много имен - у меня в Makefile это используется.
Ты еще можешь сгенерировать промежуточные Authority основываясь на корневой.
Ну и дальше пошли всякие расширения - есть исключительно серверные сертификаты, есть сертификаты клиентские, есть комбинированные когда все в одном. Опять же, генерировать все эти ключи и подписывать можно разные алгоритмами, но на суть процесса это влияет мало (ну кроме того, что какой-нибудь устаревший алгоритм скомпроментировать могут). Потом openssl может сгенерировать тебе такую штуку когда сертификат и приватный ключ все вместе упаковано - у меня в Makefile такой момент тоже есть.
Надеюсь все это хоть немного поможет.
Makefile:
ROOT_DIR = $(shell pwd)
CA_DIR = ca
CA_DB = index.db
CA_SERIAL = serial
ETCD_DIR = etcd
KUBEAPI_DIR = api-server
KUBEAPI_CLIENT_DIR = api-client
FLANNEL_DIR = flannel
USER_DIR = user
SCHEDULER_DIR = scheduler
CONTROLLER_DIR = controller
OPENSSL_CFG_FILE = /tmp/openssl.cfg
define OPENSSL_CFG
[ca]
default_ca = CA_default
[CA_default]
dir = $(ROOT_DIR)/$(CA_DIR)
database = $$dir/$(CA_DB)
private_key = $$dir/key.pem
certificate = $$dir/crt.pem
new_certs_dir = $$dir
default_md = sha256
policy = policy_strict
serial = $$dir/$(CA_SERIAL)
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256
x509_extensions = v3_ca
req_extensions = v3_req
[req_distinguished_name]
countryName = AU
stateOrProvinceName = New South Wales
localityName = Sydney
0.organizationName = N/A
organizationUnitName = N/A
commonName = MyApp Cluster
emailAddress = aner@fastmail.com
countryName_default = AU
stateOrProvinceName_default = New South Wales
localityName_default = Sydney
0.organizationName_default = N/A
organizationUnitName_default = N/A
commonName_default = MyApp Cluster
emailAddress_default = aner@fastmail.com
[v3_ca]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = master.local
DNS.2 = master.myapp
DNS.3 = api.myapp
DNS.4 = scheduler.myapp
DNS.5 = controller.myapp
DNS.6 = etcd.myapp
IP.1 = 10.0.0.1
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
endef
define gen-key
openssl genrsa \
-out key.pem \
4096
endef
define gen-csr
openssl req \
-new \
-key key.pem \
-out csr.pem \
-config $(OPENSSL_CFG_FILE)
endef
define sign-csr
openssl ca \
-extensions $(1) \
-days 10000 \
-notext \
-cert ../$(CA_DIR)/crt.pem \
-keyfile ../$(CA_DIR)/key.pem \
-in csr.pem \
-out crt.pem \
-config $(OPENSSL_CFG_FILE)
endef
define gen-crt
@mkdir -p $(1)
cd $(1) && \
$(call gen-key) && \
$(call gen-csr) && \
$(call sign-csr,$(2))
endef
define gen-srv-crt
$(call gen-crt,$(1),server_cert)
endef
define gen-usr-crt
$(call gen-crt,$(1),usr_cert)
endef
define msg
@echo "---------- $(1) ----------"
endef
clean:
@ls | grep -v Makefile | xargs rm -rf
all: etcd kubeapi user flannel scheduler
controller: create-ca-crt
@$(call gen-usr-crt,$(CONTROLLER_DIR))
scheduler: create-ca-crt
@$(call gen-usr-crt,$(SCHEDULER_DIR))
flannel: create-ca-crt
$(call msg,FLANNEL CERTIFICATE)
@$(call gen-usr-crt,$(FLANNEL_DIR))
user: create-ca-crt
$(call msg,USER CERTIFICATE)
@$(call gen-usr-crt,$(USER_DIR))
@openssl pkcs12 \
-export \
-out $(USER_DIR)/user.pfx \
-inkey $(USER_DIR)/key.pem \
-in $(USER_DIR)/crt.pem
kubeapi: create-ca-crt
$(call msg,API SERVER CERTIFICATE)
@$(call gen-srv-crt,$(KUBEAPI_DIR))
$(call msg,API SERVER CLIENT CERTIFICATE)
@$(call gen-usr-crt,$(KUBEAPI_CLIENT_DIR))
etcd: create-ca-crt
$(call msg,ETCD CERTIFICATE)
@$(call gen-srv-crt,$(ETCD_DIR))
create-ca-crt: prepare-openssl-cfg create-ca-key create-ca-dir
$(call msg,ROOT CERTIFICATE)
@cd $(CA_DIR) && \
openssl req \
-x509 \
-new \
-nodes \
-key key.pem \
-days 10000 \
-out crt.pem \
-config $(OPENSSL_CFG_FILE)
create-ca-key: create-ca-dir
@cd $(CA_DIR) && \
$(call gen-key)
create-ca-dir:
@mkdir -p $(CA_DIR) && \
touch $(CA_DIR)/$(CA_DB) && \
touch $(CA_DIR)/$(CA_SERIAL) && \
echo 1000 > $(CA_DIR)/$(CA_SERIAL)
prepare-openssl-cfg: export OPENSSL_CFG_CONTENT:=$(OPENSSL_CFG)
prepare-openssl-cfg:
@echo "$${OPENSSL_CFG_CONTENT}" > $(OPENSSL_CFG_FILE)
Исходная версия DiKeert, :
Я тут запарился для настройки kubernetes с этим, вот тебе Makefile который делает это.
В кратце все довольно просто - у тебя есть сертификат некоторого Authority - это сертификат которому ты просто доверяешь. Конечно для того, что бы этим сертификатом оперировать, нужен ключ. Поэтому сначала ты генерируешь ключ, потом сертификат, согласно этому ключу. Алгоритмы щас не очень важны, я саму суть объясняю.
У тебя теперь есть Authority, сертификат которому ты доверяешь. Теперь тебе нужно сделать сертификат, которому будут доверять все, кто доверяет этому Authority. Делается это через цифровую подпись.
То есть ты генерируешь новый ключ, согласно ему генерируешь сертификат и потом используешь Authority твою, что бы подписать новый сертификат. То есть этому сертификату будут доверять все, кто доверяет твоей Authority, без дополнительных вопросов. Этот сертификат ты используешь для своего сервера какого-нибудь. Ессно dns имя/IP сервака должны совпадать с указанными в сертификате. Можно указывать много имен - у меня в Makefile это используется.
Ты еще можешь сгенерировать промежуточные Authority основываясь на корневой.
Ну и дальше пошли всякие расширения - есть исключительно серверные сертификаты, есть сертификаты клиентские, есть комбинированные когда все в одном. Опять же, генерировать все эти ключи и подписывать можно разные алгоритмами, но на суть процесса это влияет мало (ну кроме того, что какой-нибудь устаревший алгоритм скомпроментировать могут). Потом openssl может сгенерировать тебе такую штуку когда сертификат и приватный ключ все вместе упаковано - у меня в Makefile такой момент тоже есть.
Надеюсь все это хоть немного поможет.
Makefile:
ROOT_DIR = $(shell pwd)
CA_DIR = ca
CA_DB = index.db
CA_SERIAL = serial
ETCD_DIR = etcd
KUBEAPI_DIR = api-server
KUBEAPI_CLIENT_DIR = api-client
FLANNEL_DIR = flannel
USER_DIR = user
SCHEDULER_DIR = scheduler
CONTROLLER_DIR = controller
OPENSSL_CFG_FILE = /tmp/openssl.cfg
define OPENSSL_CFG
[ca]
default_ca = CA_default
[CA_default]
dir = $(ROOT_DIR)/$(CA_DIR)
database = $$dir/$(CA_DB)
private_key = $$dir/key.pem
certificate = $$dir/crt.pem
new_certs_dir = $$dir
default_md = sha256
policy = policy_strict
serial = $$dir/$(CA_SERIAL)
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256
x509_extensions = v3_ca
req_extensions = v3_req
[req_distinguished_name]
countryName = AU
stateOrProvinceName = New South Wales
localityName = Sydney
0.organizationName = N/A
organizationUnitName = N/A
commonName = MyApp Cluster
emailAddress = aner@fastmail.com
countryName_default = AU
stateOrProvinceName_default = New South Wales
localityName_default = Sydney
0.organizationName_default = N/A
organizationUnitName_default = N/A
commonName_default = MyApp Cluster
emailAddress_default = aner@fastmail.com
[v3_ca]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = master.local
DNS.2 = master.myapp
DNS.3 = api.myapp
DNS.4 = scheduler.myapp
DNS.5 = controller.myapp
DNS.6 = etcd.myapp
IP.1 = 10.0.0.1
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
endef
define gen-key
openssl genrsa \
-out key.pem \
4096
endef
define gen-csr
openssl req \
-new \
-key key.pem \
-out csr.pem \
-config $(OPENSSL_CFG_FILE)
endef
define sign-csr
openssl ca \
-extensions $(1) \
-days 10000 \
-notext \
-cert ../$(CA_DIR)/crt.pem \
-keyfile ../$(CA_DIR)/key.pem \
-in csr.pem \
-out crt.pem \
-config $(OPENSSL_CFG_FILE)
endef
define gen-crt
@mkdir -p $(1)
cd $(1) && \
$(call gen-key) && \
$(call gen-csr) && \
$(call sign-csr,$(2))
endef
define gen-srv-crt
$(call gen-crt,$(1),server_cert)
endef
define gen-usr-crt
$(call gen-crt,$(1),usr_cert)
endef
define msg
@echo "---------- $(1) ----------"
endef
clean:
@ls | grep -v Makefile | xargs rm -rf
all: etcd kubeapi user flannel scheduler
controller: create-ca-crt
@$(call gen-usr-crt,$(CONTROLLER_DIR))
scheduler: create-ca-crt
@$(call gen-usr-crt,$(SCHEDULER_DIR))
flannel: create-ca-crt
$(call msg,FLANNEL CERTIFICATE)
@$(call gen-usr-crt,$(FLANNEL_DIR))
user: create-ca-crt
$(call msg,USER CERTIFICATE)
@$(call gen-usr-crt,$(USER_DIR))
@openssl pkcs12 \
-export \
-out $(USER_DIR)/user.pfx \
-inkey $(USER_DIR)/key.pem \
-in $(USER_DIR)/crt.pem
kubeapi: create-ca-crt
$(call msg,API SERVER CERTIFICATE)
@$(call gen-srv-crt,$(KUBEAPI_DIR))
$(call msg,API SERVER CLIENT CERTIFICATE)
@$(call gen-usr-crt,$(KUBEAPI_CLIENT_DIR))
etcd: create-ca-crt
$(call msg,ETCD CERTIFICATE)
@$(call gen-srv-crt,$(ETCD_DIR))
create-ca-crt: prepare-openssl-cfg create-ca-key create-ca-dir
$(call msg,ROOT CERTIFICATE)
@cd $(CA_DIR) && \
openssl req \
-x509 \
-new \
-nodes \
-key key.pem \
-days 10000 \
-out crt.pem \
-config $(OPENSSL_CFG_FILE)
create-ca-key: create-ca-dir
@cd $(CA_DIR) && \
$(call gen-key)
create-ca-dir:
@mkdir -p $(CA_DIR) && \
touch $(CA_DIR)/$(CA_DB) && \
touch $(CA_DIR)/$(CA_SERIAL) && \
echo 1000 > $(CA_DIR)/$(CA_SERIAL)
prepare-openssl-cfg: export OPENSSL_CFG_CONTENT:=$(OPENSSL_CFG)
prepare-openssl-cfg:
@echo "$${OPENSSL_CFG_CONTENT}" > $(OPENSSL_CFG_FILE)