## [頻率限制](https://letsencrypt.org/docs/rate-limits/) 每個domain每週50個憑證 每個帳號每個hostname(Subdomain)每小時有五次失敗的機會 每個帳號每三個小時最多申請300次 每個帳號最多可以有300個Pending Authorizations 每個憑證最多可以包含100個名稱(Subdomain) 每個IP每三小時可以建立3個帳號 Renewal唯一受到的限制只有每週重複申請成功5次同個憑證 Revoking不會重設限制 ## Certbot ### 透過 certbot 去取得 wildcard 憑證的指令 #### 手動做法 ```bash sudo certbot certonly --manual -d *.sam.com.tw --preferred-challenges dns ``` - 需要手動去 DNS Server 新增指定的 TXT Record ```bash samdeploy@sam3450:~$ sudo certbot certonly --manual -d *.sam.com -d sam.com --preferred-challenges dns Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for *.sam.com and sam.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please deploy a DNS TXT record under the name: _acme-challenge.sam.com. with the following value: gaQ9vSqEZrj6cJZvqQkw9rBSy0os-BNrO33JnlDrMz8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please deploy a DNS TXT record under the name: _acme-challenge.sam.com. with the following value: 3RdfZ2Gc4k2GfELL3mdDOeGsytKYlxEYMA51uQ4_1ho (This must be set up in addition to the previous challenges; do not remove, replace, or undo the previous challenge tasks yet. Note that you might be asked to create multiple distinct TXT records with the same name. This is permitted by DNS standards.) Before continuing, verify the TXT record has been deployed. Depending on the DNS provider, this may take some time, from a few seconds to multiple minutes. You can check if it has finished deploying with aid of online tools, such as the Google Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.sam.com. Look for one or more bolded line(s) below the line ';ANSWER'. It should show the value(s) you've just added. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue ``` - 確認 DNS Record 是否運作 ```bash dig -t txt hostName ``` #### Azure 的 pulgin [Github](https://github.com/terrycain/certbot-dns-azure) [Manual](https://docs.certbot-dns-azure.co.uk/en/latest/) ##### Install Plugin ``` Via Snap - not tested yet sudo snap install certbot --classic sudo snap install --channel=stable certbot-dns-azure sudo snap set certbot trust-plugin-with-root=ok sudo snap connect certbot:plugin certbot-dns-azure ``` ##### Usage - 前置作業 ```bash AZURE_CERT_MANAGER_NEW_SP_NAME=sam-cert-manager # This is the name of the resource group that you have your dns zone in. AZURE_DNS_ZONE_RESOURCE_GROUP=DNS # The DNS zone name. It should be something like domain.com or sub.domain.com. AZURE_DNS_ZONE=sam30606.com DNS_ID=$(az network dns zone show --name $AZURE_DNS_ZONE --resource-group $AZURE_DNS_ZONE_RESOURCE_GROUP --query "id" --output tsv) DNS_SP=$(az ad sp create-for-rbac --name $AZURE_CERT_MANAGER_NEW_SP_NAME --role "DNS Zone Contributor" --scope $DNS_ID --output json) echo $DNS_SP ``` ```bash dns_azure_sp_client_id = 912ce44a-0156-4669-ae22-c16a17d34ca5 dns_azure_sp_client_secret = E-xqXU83Y-jzTI6xe9fs2YC~mck3ZzUih9 dns_azure_tenant_id = ed1090f3-ab18-4b12-816c-599af8a88cf7 dns_azure_environment = "AzurePublicCloud" dns_azure_zone1 = example.com:/subscriptions/c135abce-d87d-48df-936c-15596c6968a5/resourceGroups/dns1 dns_azure_zone2 = example.org:/subscriptions/99800903-fb14-4992-9aff-12eaf2744622/resourceGroups/dns2 ``` - 取得Cert ```bash sudo certbot certonly --dns-azure-config azure.ini -d *.sam.com.tw ``` ```bash samadmin@sam3450:~/certbot$ sudo certbot certonly --dns-azure-config azure.ini -d *.sam.com.tw -d sam.com.tw Saving debug log to /var/log/letsencrypt/letsencrypt.log How would you like to authenticate with the ACME CA? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: Apache Web Server plugin (apache) 2: Obtain certificates using a DNS TXT record (if you are using Azure for DNS). (dns-azure) 3: Runs an HTTP server locally which serves the necessary validation files under the /.well-known/acme-challenge/ request path. Suitable if there is no HTTP server already running. HTTP challenge only (wildcards not supported). (standalone) 4: Saves the necessary validation files to a .well-known/acme-challenge/ directory within the nominated webroot path. A seperate HTTP server must be running and serving files from the webroot path. HTTP challenge only (wildcards not supported). (webroot) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-4] then [enter] (press 'c' to cancel): 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - An RSA certificate named sam.com.tw already exists. Do you want to update its key type to ECDSA? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (U)pdate key type/(K)eep existing key type: u Renewing an existing certificate for *.sam.com.tw and sam.com.tw Waiting 10 seconds for DNS changes to propagate Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/sam.com.tw/fullchain.pem Key is saved at: /etc/letsencrypt/live/sam.com.tw/privkey.pem This certificate expires on 2024-06-02. These files will be updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in the background. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - If you like Certbot, please consider supporting our work by: * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate * Donating to EFF: https://eff.org/donate-le - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ``` ## cert-manager [Install Manual](https://cert-manager.io/docs/installation/kubectl/) ### Prerequire - [cmctl](https://cert-manager.io/docs/reference/cmctl/#installation) - Installtion ``` OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -fsSL -o cmctl https://github.com/cert-manager/cmctl/releases/latest/download/cmctl_${OS}_${ARCH} chmod +x cmctl sudo mv cmctl /usr/local/bin ``` - Autocompletion ``` cmctl completion bash /etc/bash_completion.d/cmctl ``` - kubectl version >= v1.19.0 ### Installtion ``` kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.1/cert-manager.yaml ``` #### 驗證安裝 ``` $ cmctl check api The cert-manager API is ready ``` ### [Issuer Configuration](https://cert-manager.io/docs/configuration/) 設定憑證的發行商,Resource類型有Issuer或是ClusterIssuer 差異只在分別是Scope在Namespace或是Cluster而已 - HTTP-01 ```yaml= apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: http-cluster-issuer namespace: sam spec: acme: email: sam30606@gmail.com server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: name: sam30606.com solvers: - http01: ingress: serviceType: ClusterIP ingressClassName: traefik ``` ##### Azure DNS ```bash= # Choose a name for the service principal that contacts azure DNS to present # the challenge. AZURE_CERT_MANAGER_NEW_SP_NAME=sam-cert-manager # This is the name of the resource group that you have your dns zone in. AZURE_DNS_ZONE_RESOURCE_GROUP=DNS # The DNS zone name. It should be something like domain.com or sub.domain.com. AZURE_DNS_ZONE=sam30606.com DNS_ID=$(az network dns zone show --name $AZURE_DNS_ZONE --resource-group $AZURE_DNS_ZONE_RESOURCE_GROUP --query "id" --output tsv) DNS_SP=$(az ad sp create-for-rbac --name $AZURE_CERT_MANAGER_NEW_SP_NAME --role "DNS Zone Contributor" --scope $DNS_ID --output json) AZURE_CERT_MANAGER_SP_APP_ID=$(echo $DNS_SP | jq -r '.appId') AZURE_CERT_MANAGER_SP_PASSWORD=$(echo $DNS_SP | jq -r '.password') AZURE_TENANT_ID=$(echo $DNS_SP | jq -r '.tenant') AZURE_SUBSCRIPTION_ID=$(az account show --output json | jq -r '.id') az role assignment list --all --assignee $AZURE_CERT_MANAGER_SP_APP_ID ``` ```bash= kubectl create secret generic sam30606.com-azuredns-config --from-literal=client-secret=$AZURE_CERT_MANAGER_SP_PASSWORD -n cert-manager ``` ```bash= echo "AZURE_CERT_MANAGER_SP_APP_ID: $AZURE_CERT_MANAGER_SP_APP_ID" echo "AZURE_SUBSCRIPTION_ID: $AZURE_SUBSCRIPTION_ID" echo "AZURE_TENANT_ID: $AZURE_TENANT_ID" echo "AZURE_DNS_ZONE_RESOURCE_GROUP: $AZURE_DNS_ZONE_RESOURCE_GROUP" echo "AZURE_DNS_ZONE: $AZURE_DNS_ZONE" ``` ```yaml= apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: example-issuer spec: acme: email: sam30606@gmail.com server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-staging-sam30606.com solvers: solvers: - dns01: azureDNS: clientID: AZURE_CERT_MANAGER_SP_APP_ID clientSecretSecretRef: # The following is the secret we created in Kubernetes. Issuer will use this to present challenge to Azure DNS. name: azuredns-config key: client-secret subscriptionID: AZURE_SUBSCRIPTION_ID tenantID: AZURE_TENANT_ID resourceGroupName: AZURE_DNS_ZONE_RESOURCE_GROUP hostedZoneName: AZURE_DNS_ZONE # Azure Cloud Environment, default to AzurePublicCloud environment: AzurePublicCloud ``` #### [SelfSigned](https://cert-manager.io/docs/configuration/selfsigned/) ```yaml= apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-cluster-issuer namespace: sam spec: selfSigned: {} ``` ### [Certificate resource](https://cert-manager.io/docs/usage/certificate/) uses this input to generate a private key and CertificateRequest resource The signed certificate and private key are then stored in the specified Secret resource. cert-manager will ensure that the certificate is auto-renewed before it expires and re-issued if requested. - Ingress ```yaml= metadata: annotations: cert-manager.io/cluster-issuer: http-cluster-issuer ``` ## go-acme ```bash= sudo lego --server=https://acme-v02.api.letsencrypt.org/directory --email="sam30606@gmail.com " --domains="sam30606.com" --tls run ```