Skip to content

Latest commit

 

History

History
executable file
·
820 lines (655 loc) · 19.4 KB

8.CA-TLS.md

File metadata and controls

executable file
·
820 lines (655 loc) · 19.4 KB

CA'nin ve TLS Sertifikalarının Oluşturulması

Büyük ihtimalle yazı dizisinin en uzun makalesi bu olacak. Uzun sebebi fazla komut olması değil aslında, sertifikaları oluştururken kullanığımız json konfigürasyon dosyalarını biraz uzun olmasından kaynaklarnıyor.

Daha önce CFSSL kurulumunu yaptığımız bölümde de bahsetmiştim ancak tekrarda fayda vardır diyerek hatırlatmak istiyorum. Eğer PKI ve TLS hakkında yetersiz olduğunuzu düşünüyorsanız Gökhan Şengün'ün "Pratik Kriptogafi ve Güvenlik Konseptleri" başlıklı sunumunu izlemenizi kesinlikle tavsiye ederim.

Sırasıyla şu işlemleri gerçekleştiriyor olacağız.

  1. CA (Certificate Authoirty) oluşturacağız.
  2. Daha sonra her bir bileşen ve makina için CSR (Certificate Signing Request) oluşturacağız.
  3. Ve son olarak CSR kullanak TLS sertifikalarımızı CA ile imzalayıp oluşturuyor olacağız.

Sertifikaları oluştururken kullanılan bazı kısaltmalar ve anlamları.

  • Country (countryName, C),
  • Organization (organizationName, O),
  • Organizational unit (organizationalUnitName, OU),
  • Distinguished name qualifier (dnQualifier),
  • State or province name (stateOrProvinceName, ST),
  • Common name (commonName, CN) and
  • Serial number (serialNumber)

Kubernetes resmi sayfasından sertifikaların kullanımı ve best practice'ler hakkında bilgi almak için Kubernetes resm isayafasını ziyaret edebilirsiniz.

Örneğin Kubernetes API servisine ulaşmak için kullanılan kubectl veya bir client library kimlik doğrulamasından sonra API'yi kullanılabilecektir. Bu süreç için de sertifikaya ihtiyaç duyulacaktır. Aşağıdaki şekilde bu süreç gösterilmiştir.

access-control-overview.svg Daha fazla bilgi için şu sayfayı ziyeret ediniz.

Setifikaları host makinamızda oluşturduktan sonra makinalarımıza taşıyacağız.

CA (Certificate Authority)

Windows kullanıcıları

  • Ya CFSSL kurulumunda bahsettiğim gibi lb-01 makinası üzerinden sertifikaları oluşturabilirler. Altta unix tabanlı sistemler için yazılan komutları doğrudan kullanabilirsiniz.
  • Windows'la devam edecekseniz powershell için burada örneğini vereceğim şekilde sertifikaları oluşturabilirsiniz. Komutlar powershell core 7.2 versiyonunda test edilmiştir.

Linux ve Mac için

mkdir ~/kubernetes && cd ~/kubernetes

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
EOF

cat > ca-csr.json <<EOF
{
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "CA",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

Windows için

mkdir ~/kubernetes
cd ~/kubernetes

@'
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
'@ | tee ca-config.json

@'
{
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "CA",
      "ST": "Oregon"
    }
  ]
}
'@ | tee ca-csr.json

.\cfssl_windows-amd64.exe gencert -initca ca-csr.json | .\cfssljson_windows-amd64.exe -bare ca

Sonuç olarak 2 adet pem dosyası oluşmuş olmalıdır.

  • ca-key.pem
  • ca.pem

İstemci ve Sunucu Sertifikalarının Oluşturulması

Admin Sertifikası

Linux ve Mac için

cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:masters",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  admin-csr.json | cfssljson -bare admin

Windows İçin

@'
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:masters",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
'@ | tee admin-csr.json


.\cfssl_windows-amd64.exe gencert `
  -ca="ca.pem" `
  -ca-key="ca-key.pem" `
  -config="ca-config.json" `
  -profile="kubernetes" `
  admin-csr.json | .\cfssljson_windows-amd64.exe -bare admin

Sonuç olarak 2 adet pem dosyası oluşmuş olmalıdır.

  • admin-key.pem
  • admin.pem

Kubelet İstemci Sertifikaları

Kubernetes, Kubelets tarafından yapılan API isteklerini özel olarak yetkilendiren "Node Authorizer" adlı özel amaçlı bir yetkilendirme modu kullanır. Node Authorizer tarafından yetkilendirilmek için Kubelets'ler, system:nodes grubunda olduklarını gösteren ve kullanıcı adı system:node: olan bir kullanıcı adıyla kullanılmalıdır.

Bu bölümde, "Node Authorizer" gereksinimlerini karşılayan her Kubernetes worker nodu için sertifika oluşturuyor olacağız.

Bizde makinaların external ip adresleri olamadığı için sertifikaları sadece internal domain ve makina adları için oluşturyoruz.

Linux LXC için Ip adreslerini otomatik almak isterseniz

for instance in worker-01 worker-02 worker-03; do

cat > ${instance}-csr.json <<EOF
{
  "CN": "system:node:${instance}",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:nodes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

INTERNAL_IP=$(lxc info ${instance} | grep eth0 | head -1 | awk '{print $3}')

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=${instance},${INTERNAL_IP} \
  -profile=kubernetes \
  ${instance}-csr.json | cfssljson -bare ${instance}
done

SSH ile bağlanıldığında ip listesi ile

INTERNAL_IP=
WORKER=

WORKERS=(worker-01,10.240.10.7 worker-02,10.240.10.8 worker-03,10.240.10.9)

for i in "${WORKERS[@]}" ; do 
  KEY=${i%,*};
  VAL=${i#*,};
  INTERNAL_IP=$VAL;
  WORKER=$KEY;

cat > ${WORKER}-csr.json <<EOF
{
  "CN": "system:node:${WORKER}",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:nodes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=${instance},${INTERNAL_IP} \
  -profile=kubernetes \
  ${WORKER}-csr.json | cfssljson -bare ${WORKER}
  
done

Windows için

$instances = @{"worker-01"="10.240.10.7"; "worker-02"="10.240.10.8";"worker-03"="10.240.10.9"} 

foreach ($key in $instances.keys)
{

  $instance=$key
  $internal_ip=$instances[$key]
  #Write-Host $internal_ip
  #Write-Host $instance

@'
  {
    "CN": "system:node:$instance",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
      {
        "C": "US",
        "L": "Portland",
        "O": "system:nodes",
        "OU": "Kubernetes The Hard Way",
        "ST": "Oregon"
      }
    ]
  }
'@ | tee $instance-csr.json



  .\cfssl_windows-amd64.exe gencert `
    -ca="ca.pem" `
    -ca-key="ca-key.pem" `
    -config="ca-config.json" `
    -hostname="$instance ,$internal_ip" `
    -profile="kubernetes" `
    $instance-csr.json | .\cfssljson_windows-amd64.exe -bare $instance

}

sonuçta 6 adet pem dosyası oluşmuş olmalıdır.

  • worker-01-key.pem
  • worker-01.pem
  • worker-02-key.pem
  • worker-02.pem
  • worker-03-key.pem
  • worker-03.pem

Controller Manager İstemci Sertifikaları

Linux ve Mac için

cat > kube-controller-manager-csr.json <<EOF
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

Windows için

@'
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}

'@ | tee kube-controller-manager-csr.json 

.\cfssl_windows-amd64.exe gencert `
  -ca="ca.pem" `
  -ca-key="ca-key.pem" `
  -config="ca-config.json" `
  -profile="kubernetes" `
  kube-controller-manager-csr.json | .\cfssljson_windows-amd64.exe -bare kube-controller-manager
  

Sonuçta 2 adet pem dosyası oluşmuş olmalıdır.

  • kube-controller-manager-key.pem
  • kube-controller-manager.pem

Kube Proxy İstemci Sertifikaları

Linux ve Mac için

cat > kube-proxy-csr.json <<EOF
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:node-proxier",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-proxy-csr.json | cfssljson -bare kube-proxy

Windows için

@'
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:node-proxier",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}

'@ | tee kube-proxy-csr.json

.\cfssl_windows-amd64.exe gencert `
  -ca="ca.pem" `
  -ca-"key=ca-key.pem" `
  -config="ca-config.json" `
  -profile="kubernetes" `
  kube-proxy-csr.json | .\cfssljson_windows-amd64.exe -bare kube-proxy

Sonuçta 2 adet pem dosyası oluşmuş olmalıdır.

  • kube-proxy-key.pem
  • kube-proxy.pem

Scheduler İstemci Sertifikaları

Linux ve Mac için

cat > kube-scheduler-csr.json <<EOF
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-scheduler-csr.json | cfssljson -bare kube-scheduler

Windows için

@'
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
'@ | tee kube-scheduler-csr.json

.\cfssl_windows-amd64.exe gencert `
  -ca="ca.pem" `
  -ca-key="ca-key.pem" `
  -config="ca-config.json" `
  -profile="kubernetes" `
  kube-scheduler-csr.json | .\cfssljson_windows-amd64.exe -bare kube-scheduler

Sonuçta 2 adet pem dosyası oluşmuş olmalıdır.

  • kube-scheduler-key.pem
  • kube-scheduler.pem

Kubernetes API Sunucu Sertifikası

Bu kısımda belirttiğimiz ip adresleri ve domain name'ler biaz kafa karıştırıcı olabiliyor. Aslında çok basit bir mantığı var. Şöyleki Kubernetes API'sine ulaşabilecek tüm istemcilerin bilgisini sertifikaya belirtiyoruz. Çünkü örneğin load balancer'lar üzerinden kubernetes API'si çağrıldığında sertifikanın load balancer hostname'i veya ip'si üzerinden cevap verebilmesi gerekiyor. Detaylar için şu sayfayı ziyaret ediniz.

KUBERNETES_PUBLIC_ADDRESS değişkeni ile load balancer ip adreslerimizi veriyoruz. aslında bizim kurgumuzda bu ip adresleri iç ip aralığında ancak mantığın oluşması adına kaynaklarda geçtiği üzere public ip olarak ekledik. Çünki gerçek ortamlarda bu makinaların yada load balancer cihazının iç sunuculardan olmama ihtimali daha büyük. Ayrıca VIP (10.240.10.10) adresimizi de ekliyoruz.

Diğer dikkat edilmesi gereken bir husus da "kubernetes" domain adının API'ye atanması ve ileride "Control Pane" oluşturulurken vereceğimiz servis ip aralığındaki ilk ip olan 10.32.0.1 ip'si ile bağlanmasıdır. Bu nedenle sertifika hostname'ine bu ip'yi de ekliyoruz.

Linux ve Mac için

KUBERNETES_PUBLIC_ADDRESS=10.240.10.2,lb-01,10.240.10.3,lb-02,10.240.10.10

KUBERNETES_HOSTNAMES=kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.svc.cluster.local

CONTROLLER_ADDRESS=10.240.10.4,controller-01,10.240.10.5,controller-02,10.240.10.6,controller-03

cat > kubernetes-csr.json <<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=10.32.0.1,${CONTROLLER_ADDRESS},${KUBERNETES_PUBLIC_ADDRESS},127.0.0.1,${KUBERNETES_HOSTNAMES} \
  -profile=kubernetes \
  kubernetes-csr.json | cfssljson -bare kubernetes

Windows için

$KUBERNETES_PUBLIC_ADDRESS="10.240.10.2,lb-01,10.240.10.3,lb-02,10.240.10.10"

KUBERNETES_HOSTNAMES="kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.svc.cluster.local"

$CONTROLLER_ADDRESS="10.240.10.4,controller-01,10.240.10.5,controller-02,10.240.10.6,controller-03"


@'
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
'@ | tee kubernetes-csr.json

.\cfssl_windows-amd64.exe gencert `
  -ca="ca.pem" `
  -ca-key="ca-key.pem" `
  -config="ca-config.json" `
  -hostname="10.32.0.1,$CONTROLLER_ADDRESS,$KUBERNETES_PUBLIC_ADDRESS,127.0.0.1,$KUBERNETES_HOSTNAMES" `
  -profile="kubernetes" `
  kubernetes-csr.json | .\cfssljson_windows-amd64.exe -bare kubernetes

Sonuçta 2 adet pem dosyası oluşmuş olmalıdır.

  • kubernetes-key.pem
  • kubernetes.pem

Service Account Key Pair

Controller manager hizmet hesabı oluşturmak ve imzalamak için key pair'e ihtiyaç duyar. Bunun için sertifika oluşturmamız gerekiyor. Detaylar için şu sayfayı ziyaret ediniz.

cat > service-account-csr.json <<EOF
{
  "CN": "service-accounts",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  service-account-csr.json | cfssljson -bare service-account

Windows için

@'
{
  "CN": "service-accounts",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
'@ | tee service-account-csr.json

.\cfssl_windows-amd64.exe gencert `
  -ca="ca.pem" `
  -ca-key="ca-key.pem" `
  -config="ca-config.json" `
  -profile="kubernetes" `
  service-account-csr.json | .\cfssljson_windows-amd64.exe -bare service-account

Sonuçta 2 adet pem dosyası oluşmuş olmalıdır.

  • service-account-key.pem
  • service-account.pem

İstemci ve Sunucu Sertifikalarının Dağıtılması

LXC kullananlar için

Uygun sertifika ve private key'leri worker makinalarımıza kopyalıyoruz.

for instance in worker-01 worker-02 worker-03; do
  lxc file push ca.pem ${instance}-key.pem ${instance}.pem ${instance}/home/ubuntu/
done

Uygun sertifika ve private key'leri controller makinalarımıza kopyalıyoruz.

for instance in controller-01 controller-02 controller-03; do
   lxc file push ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
    service-account-key.pem service-account.pem ${instance}/home/ubuntu/
done

(Linux ve Mac) SSH kullananlar için Uygun sertifika ve private key'leri worker makinalarımıza kopyalıyoruz.

INTERNAL_IP=
WORKER=

WORKERS=(worker-01,10.240.10.7 worker-02,10.240.10.8 worker-03,10.240.10.9)

for i in "${WORKERS[@]}" ; do 
  KEY=${i%,*};
  VAL=${i#*,};
  INTERNAL_IP=$VAL;
  WORKER=$KEY;

  scp ca.pem ${WORKER}-key.pem ${WORKER}.pem ${VAL}:~/kubernetes
done

Uygun sertifika ve private key'leri controller makinalarımıza kopyalıyoruz.

for instance in (10.240.10.4, 10.240.10.5, 10.240.10.6); do
   scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
    service-account-key.pem service-account.pem ${instance}:~/kubernetes
done

Windows kullananlar için

Uygun sertifika ve private key'leri worker makinalarımıza kopyalıyoruz.

$instances = @{"worker-01"="10.240.10.7"; "worker-02"="10.240.10.8";"worker-03"="10.240.10.9"} 

foreach ($key in $instances.keys)
{
  $instance=$key
  $internal_ip=$instances[$key]

  scp ca.pem $instance-key.pem $instance.pem $internal_ip:~/kubernetes
}

Uygun sertifika ve private key'leri controller makinalarımıza kopyalıyoruz.

$instances = @{"controller-01"="10.240.10.4"; "controller-02"="10.240.10.5";"controller-03"="10.240.10.6"} 

foreach ($key in $instances.keys)
{
  $instance=$key
  $internal_ip=$instances[$key]

  scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem `
    service-account-key.pem service-account.pem  $internal_ip:~/kubernetes
}

kube-proxy, kube-controller-manager, kube-scheduler, ve kubelet istemci sertifikalarını sonraki bölümde istemci authentication konfigürasyon dosyalarını oluşturmak için kullanacağız.