From 0150c0d0219c01150cc2d2567d895aa98bd994ea Mon Sep 17 00:00:00 2001 From: Tejas <47889755+0xtejas@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:51:48 +0530 Subject: [PATCH] Refactor nginx service, TLS support with Letsencrypt and certmanager with fallback with custom certs - Changed the service type from LoadBalancer to ClusterIP in the nginx service configuration. - Updated the containerPort in the nginx deployment configuration from 8082 to 80. - Added new files for cert-manager configuration: certificate.yaml and cluster-issuer.yml. - Created an ingress configuration for nginx with SSL redirection and rewrite rules. --- k8s/cert-manager/certificate.yaml | 12 ++++++++++++ k8s/cert-manager/cluster-issuer.yml | 14 ++++++++++++++ k8s/nginx/configmap.yml | 22 +-------------------- k8s/nginx/deployment.yml | 2 +- k8s/nginx/ingress.yml | 30 +++++++++++++++++++++++++++++ k8s/nginx/service.yml | 2 +- k8s/web/secret.yml | 7 +++---- 7 files changed, 62 insertions(+), 27 deletions(-) create mode 100644 k8s/cert-manager/certificate.yaml create mode 100644 k8s/cert-manager/cluster-issuer.yml create mode 100644 k8s/nginx/ingress.yml diff --git a/k8s/cert-manager/certificate.yaml b/k8s/cert-manager/certificate.yaml new file mode 100644 index 000000000..39e46270c --- /dev/null +++ b/k8s/cert-manager/certificate.yaml @@ -0,0 +1,12 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: rengine-cert + namespace: default +spec: + secretName: rengine-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - rengine.example.com diff --git a/k8s/cert-manager/cluster-issuer.yml b/k8s/cert-manager/cluster-issuer.yml new file mode 100644 index 000000000..4f0d9d3cf --- /dev/null +++ b/k8s/cert-manager/cluster-issuer.yml @@ -0,0 +1,14 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: rengine@example.com + privateKeySecretRef: + name: letsencrypt-prod + solvers: + - http01: + ingress: + class: nginx \ No newline at end of file diff --git a/k8s/nginx/configmap.yml b/k8s/nginx/configmap.yml index 556f47f87..fda770dfc 100644 --- a/k8s/nginx/configmap.yml +++ b/k8s/nginx/configmap.yml @@ -7,14 +7,7 @@ data: server { listen 80; listen [::]:80; - server_name rengine recon; - return 301 https://$host$request_uri; - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name rengine recon; + server_name rengine.example.com; charset utf-8; keepalive_timeout 70; @@ -42,17 +35,4 @@ data: alias /usr/src/scan_results/; autoindex off; } - - ssl_protocols TLSv1.2; - ssl_certificate /etc/nginx/certs/rengine.pem; - ssl_certificate_key /etc/nginx/certs/rengine_rsa.key; - ssl_trusted_certificate /etc/nginx/certs/rengine_chain.pem; - - ssl_ciphers '!EDH:!EXP:!SHA:!DSS:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256'; - ssl_prefer_server_ciphers on; - ssl_ecdh_curve secp384r1:X25519:prime256v1; - - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 5m; - ssl_session_tickets off; } \ No newline at end of file diff --git a/k8s/nginx/deployment.yml b/k8s/nginx/deployment.yml index 5f01503ec..72981d140 100644 --- a/k8s/nginx/deployment.yml +++ b/k8s/nginx/deployment.yml @@ -24,7 +24,7 @@ spec: - name: static-files mountPath: /usr/src/app/staticfiles ports: - - containerPort: 8082 + - containerPort: 80 - containerPort: 443 volumes: - name: nginx-config-volume diff --git a/k8s/nginx/ingress.yml b/k8s/nginx/ingress.yml new file mode 100644 index 000000000..fad6297d6 --- /dev/null +++ b/k8s/nginx/ingress.yml @@ -0,0 +1,30 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: nginx-ingress + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/proxy-body-size: "800m" + nginx.ingress.kubernetes.io/proxy-read-timeout: "300" + nginx.ingress.kubernetes.io/proxy-connect-timeout: "300" + nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" + acme.cert-manager.io/http01-edit-in-place: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod +spec: + ingressClassName: nginx + tls: + - hosts: + - rengine.example.com + secretName: rengine-tls + rules: + - host: rengine.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx + port: + number: 80 diff --git a/k8s/nginx/service.yml b/k8s/nginx/service.yml index af38aef77..94e728065 100644 --- a/k8s/nginx/service.yml +++ b/k8s/nginx/service.yml @@ -3,7 +3,7 @@ kind: Service metadata: name: nginx spec: - type: LoadBalancer + type: ClusterIP selector: app: nginx ports: diff --git a/k8s/web/secret.yml b/k8s/web/secret.yml index 334e88d80..def3f1b58 100644 --- a/k8s/web/secret.yml +++ b/k8s/web/secret.yml @@ -10,10 +10,9 @@ data: --- apiVersion: v1 kind: Secret +type: kubernetes.io/tls metadata: name: nginx-certificates -type: Opaque data: - rengine_chain.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZvakNDQTRxZ0F3SUJBZ0lVQXBhMEtnV1IwWkFWVlpSbHpVanJZZVpHb0J3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd01URUxNQWtHQTFVRUJoTUNWVk14RURBT0JnTlZCQW9NQjNKbFRtZHBibVV4RURBT0JnTlZCQU1NQjNKbApUbWRwYm1Vd0hoY05NalF4TURJd01UVXhNekE0V2hjTk16UXhNREU0TVRVeE16QTRXakF4TVFzd0NRWURWUVFHCkV3SlZVekVRTUE0R0ExVUVDZ3dIY21WT1oybHVaVEVRTUE0R0ExVUVBd3dIY21WT1oybHVaVENDQWlJd0RRWUoKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBS0ZRc3ZaTXhBSENyQ1ZXcFVZbStJU3BXdThVbmowNQpPY240NUY0RnlONWJIZ1dnQzNTcUloT1BKSlJDd3BqOFdETEJLeHZoUE8xcjZNMFNJME1MbnJSRElxd1hvZ1JmClhScnNHZFFLMUVuT0F2Skt6a0dzSENzUkdZQWdjek51MnF2SUtlRjF1NVV3aFhZYzNZaCsxMkJNNVM2NUlTT0MKTEtBYXpGb1ZTWE9vWWIvNDJ1U2tJbDZJQnpCRWVKcXJnelROb0pEKzdvaXdNS3lHNlZtTmFENkpvTTh6R1JPdwp1T1k4WHZmeDJNS3BCYUtnZmRSdkZmOENoWXB6UW5wYldsQ05hUzk1MkYvVnhUSksvcENvQjduUHpCSGRzTXhhClFpNkEvamZxdTRtRHpicGxFYmlxY1pHVTVXejdPYlNScVhIN0FRUU55UTFoN2YvRjNvblgvUFFsQXZnM25aZ20KR21tbmdqaEpuYThuV084L2s1WFhjSktVSHc4SWRJeFFlTU0wbVVVQnEzVW4rbEJiK21rRlIwZVlDbGR6blBCQQoxMUNRMlEyS1RvWTVGTlNsL2YzOFNoa2w4MTNnUWs5WThnN2VUUEoxVG41TzhXTHdpbHZlbGljVisza242OXAwCmwxTUpWOTVUNTlvTTRkYlZELzBFUVZyQlRYQWJVYVlrU3haRDIwaVBPVGM0cFRtRVRqRG9oQW5ic2kvdzdCZG4KK0I3S29oUGVMVitvYXpvQXhhTTBKazhKVC95Zk9JcklJOURvanljTVVaV3B5NnFTUzIvWk1OVzVpS1QxT1Q4MQo2Vno0SWtLdFlFRFBsL3g2QVVOeDRPellWaTZabkVteUxIZGhUK3BtaldtOTBIZjVGejR5QTdtY2RCZVg1TVF5ClI5NllqRXpKZ0RsL0FnTUJBQUdqZ2JFd2dhNHdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVUKNzZ1SGlEeVFnRDE1MDBlYnNrQVNTQ3VUc3J3d2JBWURWUjBqQkdVd1k0QVU3NnVIaUR5UWdEMTUwMGVic2tBUwpTQ3VUc3J5aE5hUXpNREV4Q3pBSkJnTlZCQVlUQWxWVE1SQXdEZ1lEVlFRS0RBZHlaVTVuYVc1bE1SQXdEZ1lEClZRUUREQWR5WlU1bmFXNWxnaFFDbHJRcUJaSFJrQlZWbEdYTlNPdGg1a2FnSERBT0JnTlZIUThCQWY4RUJBTUMKQVlZd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFFWEJMak1yOE9nczlzQjhndEozdlRQSlpmTXNrTjFBTlQ2SAp3RVkzcmZONVgvK0JDSURtQWZURElQMzd1K0pjeXRZazc5UWk0eVdlUkRWamZyM2V2Y1dJQ3NQWjNUYnVzTzllCnJuUzIrVTBDdTE1UkRqRWh4YlNISUU3VG9KOEQrSFFUZ3Q2K0dXcndPNVhWNmh4YU1VMGI3Tk1OekNYL0ZOcjQKTzlXbXF3blpmU1R2ZmowaW0ybGVJWVNqL3ZYRFpmL01jd09RbUp6dW9UZW15RTczNHZEVFZzWW4zRDE5REVOSwptWjlMdFdLTGwxWlZNKzYvM2NEUi9HUENNeE1PUEZzcEE5YzI2aEUvcC8vQXZrSjZCc0FFcEhINnQwZEJHdEpzCndZNDhmaFZoTWEzYzFNbUJpZmdpWmJVVUZObWRqNHZJTCtrWTlvL0YwVUs3S0JFbkZibkIzN2txZHpScEhPZ2cKTkhCeEZEYTl1b2JWK0tPUzhwTU5UeXNqZlVldXV1SDJJOEIrMHhtSUQyYkxVZDNhUHh5MlBXZ2FzbDByUUw4dQpUcXEyUjJxQkRNVG9hOHJhR0huUUs1RWtibGdpaHZ4SzBGc2RVOFBMWGZ0WEVBN2lFYUJ3UUJ2dS9kN3h3UjQ1CjhEOGIxeUlkZXRqZzBXcXY2S1ltSE41ejVadGRJczgxaDkwSnRJRks0YXRYVWJrMGxyNlRsWGNJTjUxdXh2SncKM0liZjZ0Rm5RTVpBSGNlZm1jSUlXUXY5TmNxQ1luWUYybUprbkRvbGNGNVNxdnNlcVNaRHV3SjB6VTlORi94ZApaU2ozUUdETWJwUE1VTDlmTmg1SUNwV2tURUN6dHMrMXVYUjZYNUpwUFpoMy8zb1RLNFVPWklPcXF4SHBybm9WCjhKRHcrY3BKCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - rengine_rsa.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRUUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Nzd2dna25BZ0VBQW9JQ0FRRG5YbnlzbnhkMUkxV3UKTTBtekVvWFhVazcxaVd3Rjd5MzlKaG9OdWRHbFFIdkVmVEdpVnFaSVE1cDk1cnNjWFFNOENML3FyV2MxSXpQOQpvNDluREI2YW42MmFpSFdlZWVMb2ZaSTNUSUQvelRGU0JKc1F3SkE4dmpPSXFnRnhmcHJ0K0NBanBHdHZNeTJECngwTFk2Q2o2TXBISlFkVElXRzF0VTRDejVyZ01YWk91MDNKQzVEYlZuY1Q4cExaSS9KSEVmVUk4SW9LdHBySjQKWjdvbE1WN3MyNkFwWE9mYzJRZStlN1F0NlN2cHhsYkxiQ3RKZmp6OTlBTkpQR004ZUdRNkRXTm9IZEFiak5xTQpNUWhXbXZVUFQyU2FCdTR5ekVDREZ2T1drcERqaFdLT0ZxWVN1ZElHRW9wejZwdU4vaUl3b3JLUkFLQ1lsSGEvCjM0R2xJOGdVbDAvMG9FT2J6dTBML2Z1dXdBUE1sTVZ0ZUN6RWZnRHk0VnNxQlM4ZUJ0dFl6UU45NmJuanBKWUsKZVBtVFBQYjIxdU4zVVNBZGV5UHd0TVJvOFB2c2hub2tvR0kzdGhaOTVqSFZUMFN1QUEzbmdaakI3djN5bEdMZQpIdGFhRUFXcmgwSW4xVHFnRFVITzZTMHhJMFJkQytwTUVKdzFJN01iODA3eTB4a0FlaUg1Z1pDUmVVNjRHbEhMCkpmV0hFNTQyTEQyN3FwOHFQM01NNjNucmcxZ3ovRVBXZFNLbjdyZEVLbjAxSWZnSGlLckZKci9pRHZaa0djaGQKVFdSOU5tbVg4TWVPOHhzeUZ0aXdiSWVsMlN1OWpjMGt5TXlpdW9qbWxOMUZwOFFBTHFsWXp0WmRDRE5oYWYveQpSbTVmdm9aNFB0RDhkeUp6ajdkQ3BwNXVUTitDZ1FJREFRQUJBb0lDQUFITUNLOVVlNitrbFhGVFFWOFUwNHVUCnFuQ2MvWFR3QjdZbFZwRVBJWjJiT2kvZGJDQTRiSm1McmYrTXZpemtKSHk5N1pmTEFxWG5uZXRPTXR4N1JEbkYKc0NENjFzRW5MYXJpSW11TDBHM2VNUndUdkZ5bVhudHNpN0xqMVVPeGFzNmF3M1VENlhSRVVqbjVmMFdIQzNZTwpwR1lEQ1FZUXBPSlBNbTBCUjRwRDYvd3M3UGlQMER6SFdUL0lKNmphVG5kM2ZLY3A4bVJxNnJ5SmM1VkhSbmM3CjlTVHJtWExjU0J1QnYyMXVxK1ZJbWJrU0dDMnBuM3VlWm9QeUprUWFoRGFreHVJVXJ0S1BOTzJIT2ljZUxGVisKNzVsVU9OdDkzV21ZUFJaeEdWTkZVSDI1ajRiK1RNTXdsOFQ2M2t3VmRHeCt6OERGVjczNkk1aEp3aHFCUkRnWQpFUGRZU0JJWWw3YU5YeEcrM0dmYUYvMnkrb2g5VHJpWGM4TEMxYXdKR1IzSjIzTm95K2FMUURmcUV0ZGdPVjYxClJGa0M5bURzWE5BM1l3M0RDaUFnR1d3Zzg1STU4bENuRXJTUXEwOEVJZklDcmZyQStMWVBmeGthUnZWdjgvQjcKWUFPbFAzTWNqaHNDM3pMZUtZL3ZKOGoyRU9sZGpQOGFtWnNRZStaSnFvZGZ1ZDNSNzR3THRGNTQrajh2L05zMApvaWcxNjlZUjBNMk1GQ3FkWWlQa0JiV0VxbzdxU2Z2dGxZb1hydUFFZytYNW0wVWp6MnYzZ1NJdDl5NWxzMmVqCndRY240d0p6VDdJV1ZPZlFWNmRMek81TXh3M2dIT2o3bVJwMlk1cnE3VnB5bHNNYzA1N29ZNEpRTDdnUXJXQmsKb0lvaVdZVGpGSk5XT3kvMytib0JBb0lCQVFENWRGT2xvNjdQdFBLUzR6SUxjOU44YjJPaXJwUkZCcHF0KzhNYgpOOVY5VTJiUStHTCswdjlNU1RwbnJDc3BxT3FZdWE2Z2tmUGN6UUFEazVmYjBnbExJZkVJYkpvME1JWmhVZ3QzCkVjVFhZSitySmxhbU5ySVBIRXJ0RkM2dm1IbzRReDR0UU1IbzlqVlk5ckRISXVSa29mZEViVFdhbFpBSWFTTm8KMnVXdmVUZWFNa1Irb0pIb3hqWFJWankzak9EM1lndkY4RkFKUnBmSVZsK1FzYlI0SWdaUWJWbXhPMTBqdVdCRQpVUk8xMWhFTTVCNWYxK21YNzIxNUpRRjBLcWFvNitFNEQ5K3k5U0NxWHdoZitPVGU2bUo0VktMbGlWazFRS2NyCkticDlhTFJHWnRMUUxBK2x4L290NWNRTXNvK08vT3NXNk9oK0ZabVM4Y084YXQrQkFvSUJBUUR0Y0t6Q2Z2dUIKOTZDc0cvRGszTEJSMGVzenF2c2tLbGE3QUs1R080YjhJNFNrUTN6dGZ4ZmgwbkJSQzh5ay8veHhEcFp6NWJUaApSb2diZnQ2QlA1YUFFcVNjd1M2Qi9zL21Fd0tXNzY4Zm1LakJFYzJqejVMVmhnVXQwSzB4ODZCQVM1ZEJ1UnVCClFJYU12SEdMejVJVlhvc0VKc3dSSWk4SjgxQ0ZhVUpuWEJCVnlFazZaajFEdzY1ZG5xSkROcVlrODRkdVNDNHUKQ0tFOEZXd1l2clNPZW50RUJEdVhOS3oxWWc1YTlCTTF0UUFLalkxdjVENGxPZUx5V0RZM2sxbW5SSmZUUms5QQpJWUVzNXRLczJocUpDVHJkcldIbjgwalFRN0FKd2tBVXZtbzgxK1FpMWRQcE5kRUpPNmFwZU9ma0xNeFZYN3ZCCmpQVEhYN1ltNWlNQkFvSUJBQ05DL2svN3cwbzVHZEVKckpsUjFpTlEyNVN6ZU9JSS9QUjdFaWxXeXliY0V6eVcKMytlRmkvRU1xT1Rld1hzeUZYZGhSLzRLbzU0aW5FM2xIeUpEbm15d2I1SHhTQnI0Z1FaZ3dwNGlOT0Q5RjVUcAo1blc0WlpNZFBMb21rRExpS3VTcEdDcnRiSHV4MGZpeFptdS8wdWttdS8xQU1zT1hRTFR2cDhHNnI1ME9WWDNHCmZVZ3BDbmNORGE1NXNqdC8vb3o1bnhCcjErUjN4aHpibU1hcldBZGpSK0UyaytjcHJSRFBzM3YwdWdTS0xmN1UKZ0Rhc0hxa0xmejRRclJQdXM0Qk5WNWpGSmFuMlhKZTR0MFpadUlDS1FVRWhOYVdjdEsrQ1pCOEYxd2JETmpoOQpjRzljeXhsMEd6bEJzV1RhR05EdGo0MjlmcC9VRGRGbnUzTjI2QUVDZ2dFQU9wRFJQQVFnT3pWK0h4V2hQSUltCngzZTB3UURLZzJnaURtd2prRlU4ZlZLeGMrYmxtSnNCcEFUSkNXU1VySm9yaFNOby90dEkyMHdQWkdETnR5bWQKRUtnSWpGV21DQkIyN1RRQkxvT2VPWGZwSC80cEw5K1NRektVY25HSFZzdlYyaVlLLy80Tmg3c0h0UTBDSU04cApKRFkycWVaNzdUbjJTa2tHc25GOUhJdDd4L3puK3d5ZXpla2xTQmhKdzdSbUZMVXcwWVhpUmg2QXpwWW1ISkJsCmJzTk5Sa0NaQmpuSzg1ZWxITkFaTU9VZFJuMFZ4dVNRWTVROG96UVk0MnBuOGJjY2o5TkcxdldzckF1ZktWMSsKc0JCandhdnplMGZwek56MVBlTDQ5V1RtUlcybTZ1UzlLVWZKOExJUzhMaE8wbHd1Wmx4L3JrVDdWM1lITXQ4UApBUUtDQVFCZ2FHOGFXNUZlcFRKMEpCRkc1ZHVqY0NIUGxqdEZOTkd2TlNkTFFsL2VERWVyd2RZR3FvbEFjY1JqCmV1TUlwZ29wM2YreWN6V29wQWs2VkhxREZ2SlJZQ1ppYXkvUUdLNjNRUTlPeGpmM0M2SnhBVnJ6blNGTVkzakMKNllFOHRYNFAyamhPUVlVYkpKZysyVVc0MGlubFZjUG44eE1YbmlCVHVhNlRjWG90Ym5paWp5YTRmK3BnL1VGLwpXS01uS0tTTUQ3RW1wY2ZROWw5SjBBR0YvaElDQmJCWG5rY0Q3VzVuSkR2YkJCOEE4T0ZVQThaaHkwcDBLcmg2Cmo2YnFDamRJVFdWeVM0YzR0T0FwZmZ1NFFJamR6RmU0OHd0N1JGOC9LSkNEVk9QRk9mODNRUThZVnFGV1hGczYKL2t1TzdpdEtsOEIwcXgwTmNqcC9CbHJNSU1LdwotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg== - rengine.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZiekNDQTFlZ0F3SUJBZ0lCQWpBTkJna3Foa2lHOXcwQkFRc0ZBREF4TVFzd0NRWURWUVFHRXdKVlV6RVEKTUE0R0ExVUVDZ3dIY21WT1oybHVaVEVRTUE0R0ExVUVBd3dIY21WT1oybHVaVEFlRncweU5ERXdNakF4TlRFegpNRGhhRncwek5ERXdNVGd4TlRFek1EaGFNR0V4Q3pBSkJnTlZCQVlUQWxWVE1SQXdEZ1lEVlFRSURBZEhaVzl5CloybGhNUkF3RGdZRFZRUUhEQWRCZEd4aGJuUmhNUkF3RGdZRFZRUUtEQWR5WlU1bmFXNWxNUnd3R2dZRFZRUUQKREJOeVpXNW5hVzVsTG1WNFlXMXdiR1V1WTI5dE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQwpDZ0tDQWdFQTUxNThySjhYZFNOVnJqTkpzeEtGMTFKTzlZbHNCZTh0L1NZYURiblJwVUI3eEgweG9sYW1TRU9hCmZlYTdIRjBEUEFpLzZxMW5OU016L2FPUFp3d2VtcCt0bW9oMW5ubmk2SDJTTjB5QS84MHhVZ1NiRU1DUVBMNHoKaUtvQmNYNmE3ZmdnSTZScmJ6TXRnOGRDMk9nbytqS1J5VUhVeUZodGJWT0FzK2E0REYyVHJ0TnlRdVEyMVozRQovS1MyU1B5UnhIMUNQQ0tDcmFheWVHZTZKVEZlN051Z0tWem4zTmtIdm51MExla3I2Y1pXeTJ3clNYNDgvZlFEClNUeGpQSGhrT2cxamFCM1FHNHphakRFSVZwcjFEMDlrbWdidU1zeEFneGJ6bHBLUTQ0VmlqaGFtRXJuU0JoS0sKYytxYmpmNGlNS0t5a1FDZ21KUjJ2OStCcFNQSUZKZFA5S0JEbTg3dEMvMzdyc0FEekpURmJYZ3N4SDRBOHVGYgpLZ1V2SGdiYldNMERmZW01NDZTV0NuajVrenoyOXRiamQxRWdIWHNqOExURWFQRDc3SVo2SktCaU43WVdmZVl4CjFVOUVyZ0FONTRHWXdlNzk4cFJpM2g3V21oQUZxNGRDSjlVNm9BMUJ6dWt0TVNORVhRdnFUQkNjTlNPekcvTk8KOHRNWkFIb2grWUdRa1hsT3VCcFJ5eVgxaHhPZU5pdzl1NnFmS2o5ekRPdDU2NE5ZTS94RDFuVWlwKzYzUkNwOQpOU0g0QjRpcXhTYS80ZzcyWkJuSVhVMWtmVFpwbC9ESGp2TWJNaGJZc0d5SHBka3J2WTNOSk1qTW9ycUk1cFRkClJhZkVBQzZwV003V1hRZ3pZV24vOGtadVg3NkdlRDdRL0hjaWM0KzNRcWFlYmt6ZmdvRUNBd0VBQWFOaU1HQXcKSGdZRFZSMFJCQmN3RllJVGNtVnVaMmx1WlM1bGVHRnRjR3hsTG1OdmJUQWRCZ05WSFE0RUZnUVVlUFQ2OWptUworeUVuQU1iTXlyU1hkK3NRMjYwd0h3WURWUjBqQkJnd0ZvQVU3NnVIaUR5UWdEMTUwMGVic2tBU1NDdVRzcnd3CkRRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFDMm5ZVWhMMmxTVE5kTjhnUDZGYVczYXJ4WnVNUzhBMVM3dk1Wb08KK0k3eFNzTHZhVG9xbnZHRUErL1F2dTV3a3ZRSTIwaXdqRVRrTnpRY284OFJJTzBicE0zVGhkVWpxUjViMVY0YgozKzBqTXQ1V3ZFR05GUlBWdkR6cXJGWGtjQ1ZhUmNsWGx2K081RDh4WUQwMGxzcjRFYTlaRFZGN3A2SFBIU2gyCkR3ZHhsZU5oVzdrWHNpZVkzSXBXS3RVelZmSXI0UXpUSFNaQ3VVemVBRkcrOVFsQXhQWHRxa09sQXpoeDNRSVUKRkMxVTludVJQVTFGYmdsRHBUek90anIxQVV4MmJEL1lDUkhKeDRIbS9KTXlTUGJjTko4RS9xVnpJVVhXT0EzQQpSblZYQ3pXZ3lUdDVDd2ExdnJROFg5SnNpdzdWc1pGcDk3NFIxN1BxWVRqQzRVbXVLMjRqQ1hjSEdkMEh2b0hYCmNnVHkzUS91SlYrY0xRdXVaZE9qUnJ1UFEzZ1ZNV1RRbnY1QTdlNUlIVTV0NGdtekl1RlJxblZJZ21DM2VIVzQKWU5kRllIVGtLd0NscCtZd3BvT1ZvYmpndWpMRzVVaDgwcEY3eEY0RGU0OWt2MUkyYWJmM0xtNWo1SnRFUGFyUQo5WEltZ29GRWZiU0NOSWY1OXRTa0FURWc3WnUxQ21nNE9HZkJVTGFubUdkMFNyK1MwK1lkWTloVnpuZ2x5OThECmlPM0F3QXVCSUUxZE1mWHVjV3VsdVJxKzFvVHJ0OFJnOTJqRmROcmFTbzI5SXYrQUxpS0lucm54bUEzT0R6RnQKSWFpd1QzOFNxa2x2YytmWXhqeUtkVFRyN0s1VmQyYitUeXpSRnFES2ZJREs3R2NsQmE4T3JRSUMwNGE3TlVVbQpqVXR0Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZiVENDQTFXZ0F3SUJBZ0lCQXpBTkJna3Foa2lHOXcwQkFRc0ZBREF4TVFzd0NRWURWUVFHRXdKVlV6RVEKTUE0R0ExVUVDZ3dIY21WT1oybHVaVEVRTUE0R0ExVUVBd3dIY21WT1oybHVaVEFlRncweU5ERXdNamd4TkRJMQpNekphRncwek5ERXdNall4TkRJMU16SmFNR0F4Q3pBSkJnTlZCQVlUQWxWVE1SQXdEZ1lEVlFRSURBZEhaVzl5CloybGhNUkF3RGdZRFZRUUhEQWRCZEd4aGJuUmhNUkF3RGdZRFZRUUtEQWR5WlU1bmFXNWxNUnN3R1FZRFZRUUQKREJKeVpXNW5hVzVsTGpCNGRHVnFZWE11YldVd2dnSWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJSwpBb0lDQVFDaXlGalVna0xZREUxRVMzbkYvV1d6NUZVdGNGYUJVdjc0eDZYMGt5WTdsYzVkMWRObXhlNnpnZmxVCmJlUUU1YTIxOHZvUFdsOTBzL3UxaUZ6YW8xTmhHR20xb1Z3c0p3NmFJT1lkdHRGbWI0KzA3SlZFYXpRR2tHWlMKS3l0YXpZUGVLcytTME9ZbDZ4TzNmeUthc3dCVHBkeldGbE9kU3pnVWRFaSt6anl4aCsvbE0xazVvNzRXVWwwRgpYMjNjOWtJK29uZmtXcXBndzRZcVJ2cWxCZHQzZ3lwVndaK3lidCtBQmRyNmxFcUdrYnZVNk1uYlk4b0V1RTYvCnBIRVdQYm8rQ1I4R0tWQXROQkgzSUZpRWlzNlpsWDA5Q0MzUjEwcmZ6MWdoNDN2WVJrZXkyQU1aTEw2TUZvMEUKd3JNTnJYN2hZRWVVZUswQlN6c3NTTjl0SWFGUCtqWGpEQ0gxNmlzU1d0eHlaOTlSYnM1N2pCWHkwWTVXQmNPRwpNaTFHZTFXRjdJYUU1SHptbTlhK0k4OHRNNkVuek8wOHRjUlJuYW5ON28vVXNZeTRreVZ2TkdzMmF2NlBJZDQ1CnV3dkRSQXlqNGw0M1pVWkdEei9pZG8rdFU1SzdQU2NwRkphU0N0cExwU1RNQnZXNGtRejEzalF4UnR6YVZtcHkKS3dxejlqNm1pbFFWazY2OVRVSS9pcGV2cFpRY1NsOWE0QUpSQ2U1dnA5UnpUaHlQa20vQldEdEJzUTk2YndULwp1V0I3MkR5U2VwL0Z0QnBWbHd5aiswQ2ZLMm11Nk9HcTRpVlg1c3RsSXhKMW1GaGc2aENVMVFpY09PWDl1ZUZTCnVKc2FjTklHVjlkUVR6c2I2Mm5NN3B6NzVsT1RrTG4rZ3lBam9mWFFwU2s2b1l0VmN3SURBUUFCbzJFd1h6QWQKQmdOVkhSRUVGakFVZ2hKeVpXNW5hVzVsTGpCNGRHVnFZWE11YldVd0hRWURWUjBPQkJZRUZHQzk2d3BRSi9UTApOSU9FSlRGb1JxTXZSdmErTUI4R0ExVWRJd1FZTUJhQUZPK3JoNGc4a0lBOWVkTkhtN0pBRWtncms3SzhNQTBHCkNTcUdTSWIzRFFFQkN3VUFBNElDQVFCVWp1b3Myc0pZbkZ5Vlo3VEpONUg3ai9ZazFEZ3A1NUYraS9wQ1loTEYKeldtVFk1K1EyVG5UcHk1WGFhT1QzQTFOSnNLZWlLL01QV2VVa2U4ODNUSEhTV1JoQXZ4QlhCVXRrMEc4WU9TUQpuNVJEdVp5UmFqcmNNTU0waDViaGRQajJjdFZqY2U0NVQxajI1V3R0T0lVT1NMbXdRWkVXNUFYWFpuUnNFMUhwCklHV25OOWFuOUhEOWJaSWN2ODFtZEt4UlloVmtCZlk2ZU5LY1Bqa0JpNVJtUnFFc1B1ckFzTVNMWlEwek12MWcKM2F5UzlLSVJXUmJKdHhiWEdyS05saWZ0RGo1cVhmSEhWYzhoWXZXcm9CV0R6M2F5aTR6ci80UmVrVW1Ia0JiZQpTZVVJMzZmWHdVeXhKa1JqdnE3YytSRzJwK2Q4WTFQUlJIUXlOVVRxVWZMWnRxYVkzbEVpNTcxNTNQUG1xSjBqCmgyUE1rWC9OanJqWnpQUUpIZTJrNGJwa2dYNXRaODR4QnpvODhIUGM3dVFMeXNsa2dMRHErUnlUZlpUbE9KVWMKQ2k3U2FUVk1NN21aR0xlclo2eXlHb24yVWliNEQ3ZHBsN1EvN1RMZE91U2lQVzJWdzZta09VK3BXam5CRWFudAp5RHFzTDIzL25VL0ZrNXhXeW80VDdDVncwUkROTzZ6ekcvRjEvVXd2RW1EZlRSa3VETTlPS3pPbGo5WUJIRzBkCm93Qk9iYnFQVUhZT2hnZ2NFRE1GeE9aQktDRlFOcGY3TTFQOWZacFF6dUplaXdkVW9XWnJ0VGY2U0R2ZW1iWG4KUktyVk1pT096KzFUTTI2UHlMbm5jVTQ0VmRLbnc4a0FES3AydUE5ckhoZUZ6SE8wKzB5eVNjMkJxeDJWWU9GVQpodz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQ2l5RmpVZ2tMWURFMUUKUzNuRi9XV3o1RlV0Y0ZhQlV2NzR4Nlgwa3lZN2xjNWQxZE5teGU2emdmbFViZVFFNWEyMTh2b1BXbDkwcy91MQppRnphbzFOaEdHbTFvVndzSnc2YUlPWWR0dEZtYjQrMDdKVkVhelFHa0daU0t5dGF6WVBlS3MrUzBPWWw2eE8zCmZ5S2Fzd0JUcGR6V0ZsT2RTemdVZEVpK3pqeXhoKy9sTTFrNW83NFdVbDBGWDIzYzlrSStvbmZrV3FwZ3c0WXEKUnZxbEJkdDNneXBWd1oreWJ0K0FCZHI2bEVxR2tidlU2TW5iWThvRXVFNi9wSEVXUGJvK0NSOEdLVkF0TkJIMwpJRmlFaXM2WmxYMDlDQzNSMTByZnoxZ2g0M3ZZUmtleTJBTVpMTDZNRm8wRXdyTU5yWDdoWUVlVWVLMEJTenNzClNOOXRJYUZQK2pYakRDSDE2aXNTV3R4eVo5OVJiczU3akJYeTBZNVdCY09HTWkxR2UxV0Y3SWFFNUh6bW05YSsKSTg4dE02RW56TzA4dGNSUm5hbk43by9Vc1l5NGt5VnZOR3MyYXY2UElkNDV1d3ZEUkF5ajRsNDNaVVpHRHovaQpkbyt0VTVLN1BTY3BGSmFTQ3RwTHBTVE1Cdlc0a1F6MTNqUXhSdHphVm1weUt3cXo5ajZtaWxRVms2NjlUVUkvCmlwZXZwWlFjU2w5YTRBSlJDZTV2cDlSelRoeVBrbS9CV0R0QnNROTZid1QvdVdCNzJEeVNlcC9GdEJwVmx3eWoKKzBDZksybXU2T0dxNGlWWDVzdGxJeEoxbUZoZzZoQ1UxUWljT09YOXVlRlN1SnNhY05JR1Y5ZFFUenNiNjJuTQo3cHo3NWxPVGtMbitneUFqb2ZYUXBTazZvWXRWY3dJREFRQUJBb0lDQUFUMkJpbXoyVVdzV2s1OU03WTNzQ1I0CnVQL1cyZmE4WGlPY01nL3ZkczEvYTAxV0pFaVFPbU40eiszUUlPV1ArbWlwTEdYUXVKMWQ2WXRHeWZoVk1mS3IKbVNKOVN4OHRYRGM3cEIwVHQvTmZRd256Tm82M1FGdjloVXQyZFZraHhQc1REWnNlaUEvRkhQeTRBSWltY1VRYgpYS0pKc1QxWFVERGt1bDJBKzVNNE5Bb2xpU1ZGNVpmWWtCZmNmZ1NyUjFROEJMQzQ4cWhhOTg1M1lLYlczdHdZClFKb01lZlFvM09HUjlzZmNRblBjelNvQ280N3V6a3dHaDBxS2xjZTZhZC8vZHlxV1BSTk9SWjNsSm5nam90aEcKR0xoYmRNb0lhRjBaMGZNaEhtSjJWek81ZkVsYXk3NkpQQk1CRVdQci9iU2JYVDNHZW1uOUE2TlROVHY3alJHagp3S1pOTE8zTklPYjZ3cGhMY2J1bTVMcVhiTUpOaGJWWUo1aXFKZ3pEeUhRd3d2cnpMaDkrOXRvQnd5R0o0djNjCnVveEJ6cXZ3NkJCZnUvMjdUbUlXWk9XSTU1QW0zSWxLd2lwTjZTN1FBSHVoTXlVU0RMeVRsOGJWTXB4VVlubWwKQlZ6a2dycTFsRXB4TXZHUXkvY0VTUnduWE1mMk5DQ2Q5Vnl2MUd3bkxyZ295MEsvbitVRVRCL2ZZS2R3RWN4UApaQ0EvV1JzRGd6OURnTWpTVnBOUDF6TE1rd1V3ZlcvMVFGTDBySFpIWVlmbVF3cmRjTnovc3VNekZiOUxFQm1nCjd2bEh1eFhqNzZQZklPWXRwakdyM2owclVJQWpLYjZLYnpySnpicEFncGZGczc5RUhLWEttMmRrMnU2dE9mTnoKR2VMaWdRMEZxQVpkZThKQmovSUJBb0lCQVFEaENFTlZlemI3N0VudGFsOGthRTQrZ1lxaEpGc3VaNC91ajcxTApSaUVSam9tSU55bytjMTFvUWRFS2RYRnk2RnFQQVdvVVIyVWR3bEpZMk1TeWUyVVlVV2pXTjhLZHppMUVxNnZSClQ2Z2ExQVRsUndyb0kwRTFzSzhsYXBsSmlOQXhKVzJoc0o3UTQ2blk1UXBUdTI3QWZLNHdFZU81dlI1MmY3MTEKQk1WNjJnUjExZjBSMkZHeGhhaHV3MzIxT2xRWkxodzMwOCtpMzBaZWJsLzVGUDUwNUtROGg0L1g5YnowZk1IQQpPZjBsTjIrYzZaRXI4TFkxQjlZbWgyc3h1QnFzRE1uaFJjaHE5ODUyS241WGxCWlo3dVU1aWpHU05CZzh0UndhCnBkamN2R0ZyUFhWeVBOSlNNbVl6T0dYVFhnY0p5MnNTbDRhU0V4VzRjYjVpaVRQVEFvSUJBUUM1THhITzJKdDIKY1laVnFRMjBWbEVKU2F5MkRMYktIUzJWdHUwLzdzNEZwZFgwcHJmWjJnYXJhM0g1N2xTU3J1d0o2cXZLejVWbAp3YmpLZVlZQTdzd3ozY1prdWFQYW1mbTFjdGhwek82VG01Mi9ZajlPRkgrQ2gxN0ZLd2pqa2R4cUlEOTdKazV4CnpaMVZwRHJseVlXWWZuTmVZSmhjdjllaVQrRFI2RjUzOHViWGpyc3J0YktCUmN2Nm01d2tmR3pJTlF6K2V4cjEKSCtVV3pzclFmaUNITFNBSzVGZ3c4Z2tDM3JBc2ZreE9OM2l1Z25OYjc0d3JzRm81Ymd2aDJLQVJXTjRYNWEwQQp3ZGNXN3M0VkpCUkx5UWVYQWVlZVFEUS9tRHVjaGxhblNZOWFqRHJzamtkTkw2QWVqaXh3M3VkNm9KQjcvZWhyCjNSYUFjRzAxZjNQaEFvSUJBQmpJd2pHOStsWlF0ZXV5Rlh4N0NITVY3V0RHRWt6UUZ5Z2RLS29MdFVTcndEWUMKYldLbmJoZzNkNENCWXRkWEEvSlFJNURNTkRUTTNDanc1dWtKY2g3MWlHaGZoODI5a1hySXRZbStEak8yT2p2TwpVVU16N3RDcy92MU4ra2dCQzN6K05FN2tsdmxHdWNRcnBiR0hLVEdHQ2VFOWR5bFR6UEVjTEkrZzBPY3c3K0RTCmlxYldmbGpnOGFZUlhkMEI2WlZFWU5NOVB0Y2ZaQzZ1VlYrbmtrYnBqN1VpOFJMRisrT3BnZVZiL2FlRnJZTkkKcmpaNnNuYXd3RU5LRXVKTTlwTVFiWU9rSGVpNkZrRXBlUFRJV0pYYkc5LzBlblV4eTZHVUNONWVlYjRGK1d6SQpQaEV3NWJFcjM5bXdVbmF2R25OWHRoazhHeFFuaWZMZ2hDbHlGd1VDZ2dFQVdVeDBadTJYRWlldVl0SlJ0SHZICk9oWlgvYlhsMDFMOHIyeDF2ZFczYll2SnY5OUJXd0ZESkJoODdzdlo1cDRKWHNMV01zZWxRRnVKYzhIa044RHYKb2JjNU8wczEwMjFhdC8vNGtoUnJtNng0Qmxrbk04eTRyRVlCRWswdFRTZ0NSUDdsL2NtOEhDN054d1dhRFVMLwpkRWpOODEzYk95YWJvajZvcURCSWxja0JQa01xeU9vbWVTWWlOZWdpQklvbm51Zk9LMDFMODVaOHoySEs5WDFNCnpFS2JhQVV5N2U5Wkh4UXBtbHNSQ3NxL0hFLzF0d2l0N0VkdlNyQmhkSGdVd0NpOWVJS2R5WGF2OVBRVlZxWisKVHdsUzZxUFZnRDl2c3BjRGIvaHNBdUY3Q213QzRoMitEbDkvOUJ3VkhCeXhQVFgrVm54YlB1QnZRR0oybDB5dApvUUtDQVFFQTJLRHhZeXVxRDJhbU42M3FhMjgxYWZmRDQwaFc4TXJoRktpWXVlZnNIYmVDTWFyR3Bub3dINnNXCkwzbDdtUURTOS9oT0lMVHRRcGFqcFVNWHA3cC9tVEVOcHVMZHBHM0NUV093Z2hDUTFBZXJYa3FFbWtFcEc3enUKeFVWb25CbU1YWGFoV3Z2cHJnZTUvVlNIZU5xNkJTcFZmYUVzL3Q0cXVxWGNmRk1yOHZiUml3QjNCME80Uy83egp3RWp6TjRpRThsY1BTWk5FejZZYklGU1lBRkFIeHZhWEhuSkhQc2VyRnFvdnhHUVN1ZURuNjVnUDVyRUlQYkdqCjRoUDFvSjhUaHdzQlJIeVl4VzVYc29GZHkzQTNXMy9ob3dIcUJ1Mk4rdGVySGNGamkrcXhURHU0UjU0cUJqYUQKaFc0SDVDM25YS0NiS1ZOeUFGdHNYcGJiTThoamdnPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= \ No newline at end of file