Disclaimer: This information is provided as-is for the benefit of the Community. Please contact Sophos Professional Services if you require assistance with your specific environment.
Sophos Factory brings a new Tool to automate Script based approaches. This means, you can easily run a Script like Certbot or Lego in a Sophos Factory environment to generate the certificate.
Sophos Factory offers a free Community Edition. Sophos Factory Sophos Factory Community Edition
Requirements for this HowTo:
Having a Factory Account (Community or Paid).
Having a AWS Account, which has access to Route53 and S3.
Having a single domain within Route53 and a S3 Bucket in S3. For Pricing, see: https://aws.amazon.com/en/route53/pricing/ https://aws.amazon.com/s3/pricing/
In this HowTo we are going to do the following steps:
We build a Factory Pipeline, which renewals a LetsEncrypt (Wildcard or Single) Certificate with a tool called Lego using DNS Verification.
Lego gives us the opportunity to do it via DNS and with a CNAME Request. https://github.com/go-acme/lego
DNS Challenges are using a API of a DNS Provider, publishing the needed record on a "_acme-challange.customer.com" DNS record and fetching the certificate.
With Lego, we can do a CNAME Challenge as well - Meaning: You can point any Domain of X00 of domains via CNAME to a API capable DNS Provider (like Route53). See: https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme.html
We are going to zip encrypt the Certificates with a password and upload it to S3.
In S3, we are going to create a presigned URL, which allows us to make the Certificate ZIP downloadable for a short duration. See: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html
This links is send to us via Teams Messages.
This is our general Pipeline. Factory works with Variables: So it is highly customizable and can be used as a "Job". We can schedule it with different Variables on different timeframes.
We are using plenty of Variables, which indicates the option within Factory:
Afterwards we can create multiple Jobs based on every Domain:
What to do:
1. Create your Factory Account, if not already available. Create your AWS Account, if not already available.
2. Create the AWS Route53 Domain, you want to use for Renewal. See Pricing for more information. See: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-register.html
3. Create the S3 Bucket, you want to save the data. See: https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html
4. Create a CNAME in your Domain Provider of your Choice directly to your AWS Route53 Domain:
factory.saleseng.de is my LetsEncrypt Domain. saleseng.acmesaleseng.de is my Route53 Domain.
5. Create a AWS IAM User with the needed access to the S3 bucket and the Route53 Module. See: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html
6. Generate the IAM User Access Keys for Factory: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
7. Use the IAM Access Key in Factory:
You can copy/paste the code via editor into your setup.
The actual code would look like:
Pipeline P1:
--- variables: - type: Credential name: AWS Credential key: credential required: true visible: true default: false allowed_types: - aws_access_key description: AWS Credential with permissions to upload to S3 Bucket and Route53. value: Saleseng - type: StringArray name: Domains key: domains required: true visible: true default: false description: |- One or more domains for certificate. Format: Domain.com Or Wildcard Certificate: *.Domain.com. If you add multiple Domains, only one Certificate will be generated. See: https://github.com/go-acme/lego/issues/228 value: - factory.saleseng.de - type: String name: Email Address key: email value: admin@saleseng.de required: true visible: true default: false description: Email address for Certificate - type: String name: Lego Download URL key: url required: true visible: true default: true description: |- URL to download Lego. The Current version. Format: github .tar.gz See: https://github.com/go-acme/lego/releases value: 'https://github.com/go-acme/lego/releases/download/v4.10.0/lego_v4.10.0_linux_386.tar.gz' - type: String name: DNS Provider key: provider value: route53 required: true visible: true default: true description: DNS API Provider. For AWS add "Route53". - type: String name: DNS Resolvers key: resolvers value: 8.8.8.8 required: true visible: true default: true description: Resolvers for the lego module. Add Google. - type: Boolean name: Accept Terms of Service key: tos value: true required: true visible: true default: true description: By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service steps: - id: download name: Download Lego type: shell_script depends: [] properties: content: |- {|[ "wget", vars.url, "&& tar xf", (vars.url | split('/')) | last() ] | join(" ")|} - id: updateGo name: Update Go type: shell_script depends: - download properties: content: |- git clone https://github.com/udhos/update-golang cd update-golang sudo ./update-golang.sh - id: generateCertificate name: Generate Certificate type: aws_cli depends: - updateGo - installAwsCli properties: script_content: |- {|[ "./lego", "--email=" + vars.email, "--domains=" + (vars.domains | join(" --domains=")), "--dns=" + vars.provider, "--dns.resolvers=" + vars.resolvers, "-accept-tos" if vars.tos == true else undefined, "run" ] | join(" ")|} credential: '{|vars.credential|}' args: LEGO_EXPERIMENTAL_CNAME_SUPPORT=true - id: installAwsCli name: Install AWS CLI type: aws_install depends: [] properties: version: latest outputs: - key: presignedUrl value: '{|steps.generateUrl.result.output.presignedUrl|}' layout: elements: - id: download position: x: -235 'y': -445 links: [] image_id: 1e948e6a-dbc0-41e3-aa52-e964674b617a - id: updateGo position: x: -235 'y': -365 links: - sourceId: download sourcePort: bottom targetPort: top vertices: [] image_id: 6396ec88-90bf-4ddb-8749-fbb45d733fd1 - id: generateCertificate position: x: -235 'y': -285 links: - sourceId: updateGo sourcePort: bottom targetPort: top vertices: [] - sourceId: installAwsCli sourcePort: right targetPort: left vertices: [] image_id: 1e948e6a-dbc0-41e3-aa52-e964674b617a - id: installAwsCli position: x: -425 'y': -285 links: []
Zipping and Uploading in P2:
--- variables: - type: Credential name: AWS Credential key: credential required: true visible: true default: false allowed_types: - aws_access_key description: AWS Credential with permissions to upload to S3 Bucket value: Saleseng - type: String name: S3 URI key: s3Uri required: true visible: true default: false description: S3 URI to upload s3 value: '' - type: SecureString name: password key: password value: . required: true visible: true default: true - type: String name: zipname key: zipname value: Certs.zip required: true visible: true default: true steps: - id: installAwsCli name: Install AWS CLI type: aws_install depends: [] properties: version: latest - id: upload name: Upload Certificate to S3 type: aws_cli depends: - ZipCertificate properties: script_content: |- {|[ "aws s3 sync ", "./zip/ "+ vars.s3Uri ] | join(" ")|} credential: '{|vars.credential|}' - id: InstallZip name: Install Zip type: shell_script depends: [] properties: content: sudo yum install zip - id: ZipCertificate name: Zip Certificate type: shell_script depends: - InstallZip - installAwsCli - CreateZip properties: content: |- {|[ "cd .lego/certificates/ && zip", "--password " + vars.password, "../../zip/" + vars.zipname, " ./*" ] | join(" ")|} - id: CreateZip name: Create a Folder for Zip type: shell_script depends: [] properties: content: mkdir zip outputs: [] layout: elements: - id: installAwsCli position: x: -445 'y': -200 links: [] - id: upload position: x: -235 'y': -120 links: - sourceId: ZipCertificate sourcePort: bottom targetPort: top vertices: [] - id: InstallZip position: x: -45 'y': -200 links: [] - id: ZipCertificate position: x: -235 'y': -200 links: - sourceId: CreateZip sourcePort: bottom targetPort: top vertices: [] - sourceId: InstallZip sourcePort: left targetPort: right vertices: [] - sourceId: installAwsCli sourcePort: right targetPort: left vertices: [] - id: CreateZip position: x: -235 'y': -295 links: []
If you want to try both pipelines, let me know if you encounter any problems. They will generate a Certificate for you and upload it to S3 in AWS as a encrypted file.
Updated.
[bearbeitet von: LuCar Toni um 10:04 AM (GMT -7) am 9 Sep 2023]