caddyserver / certmagic

Automatic HTTPS for any Go program: fully-managed TLS certificate issuance and renewal
https://pkg.go.dev/github.com/caddyserver/certmagic?tab=doc
Apache License 2.0
4.89k stars 278 forks source link

Certificate Import #266

Closed Cyb3rC3lt closed 5 months ago

Cyb3rC3lt commented 5 months ago

Hi there,

I am using a Pentesting tool called evilginx that uses certmagic under the hood. Whatever way it is calling my site I am finding that evilginx can't create certificates for my website. I have though managed to manually created .pem files for my site using certbot.

Do any of you have a basic standalone Go file to allow me to import them into cert magic storage by any chance? ChatGPT didn't work for me lol, but I will place the suggested code below as something to work from. Thanks

package main

import (
    "log"
    "os"

    "github.com/caddyserver/certmagic"
)

func main() {
    // Specify the domain for which you want to import a certificate
    domain := "mysite.com"

    // Specify the paths to the certificate and private key files
    certFile := "/home/david/.local/share/certmagic/acme/acme-v02.api.letsencrypt.org-directory/fullchain1.pem"
    keyFile  := "/home/david/.local/share/certmagic/acme/acme-v02.api.letsencrypt.org-directory/privkey1.pem"

    // Create a CertMagic certificate cache
    certCache, err := certmagic.NewCache(certmagic.CacheOptions{
        GetConfigForCert: func(certmagic.Certificate) (*certmagic.Config, error) {
            return &certmagic.Config{}, nil
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // Create a CertMagic storage instance and load the certificate
    storage := certmagic.FileStorage{
        Path: "/home/david/.local/share/certmagic/",
    }
    err = storage.StoreCert(domain, certFile, keyFile)
    if err != nil {
        log.Fatal(err)
    }

    // Create a CertMagic manager with the custom storage and cache
    certManager := &certmagic.Config{
        Certificates: []certmagic.Certificate{
            {
                CertFile: certFile,
                KeyFile:  keyFile,
            },
        },
    }
    certManager.Cache = certCache
    certManager.Storage = storage

    // Use CertMagic with the custom manager
    err = certmagic.HTTPS([]string{domain}, nil, certManager)
    if err != nil {
        log.Fatal(err)
    }

    // Your server logic goes here
}
mholt commented 5 months ago

Whatever way it is calling my site I am finding that evilginx can't create certificates for my website.

This seems like the actual problem. What are the errors?

This function may be useful to you for now: https://pkg.go.dev/github.com/caddyserver/certmagic#Config.CacheUnmanagedCertificatePEMFile

Cyb3rC3lt commented 5 months ago

Thanks a lot for the reply Matt, so I have tried a bunch of things, some that make less sense than others but I will show you the config below:

  1. I set an A record on Cloudflare to point to the subdomain I want to get a cert for which is login.redteaming.org but I set it to one of the Cloudflare nameservers image

And I get this error:

image

  1. I then update that same record in Cloudflare to the IP that my website is meant to have when you look it up which is: 172.67.137.37 and I get the below error. My hunch though in this case is that it does that as Cloudflare doesn't allow you to reference a domain via IP so maybe certmagic comes across the Cloudflare error page "Error 1003 Direct IP access not allowed" when you put that IP into a browser.

image

So the way I manually created them was to run this command which gave me the .pem files by adding a TXT code into Cloudflare.

sudo certbot certonly -d login.redteaming.org --register-unsafely-without-email --agree-tos --preferred-challenges dns --manual -v

These then imported fine into Kali but evilginx can't see them as they aren't in certmagic:

image

So that's where I am stuck. Happy to say I am no DNS expert so maybe I am missing something basic and I know some of what I tried may make no sense but I was clutching at straws.

Thanks

francislavoie commented 5 months ago

$ curl -v http://login.redteaming.org I see Cloudflare handling the request here. Are you sure you disabled Cloudflare proxying?

Cyb3rC3lt commented 5 months ago

Yeah the proxying is off currently. Just left it as per below

Screenshot_20240108-205953

mholt commented 5 months ago

I also see Cloudflare when I access that domain. If orange cloud is truly off, then I should access the site directly.

I would maybe contact Cloudflare support (or their forums) and see why proxying doesn't appear to be disabled even with the orange cloud off. (I'm not very familiar with their services.)

Cyb3rC3lt commented 5 months ago

Thanks guys, it looks like you at least figured out what may be the issue. So in theory, with proxying off then I should be able to access login.redteaming.org via IP so therefore Certmagic should be able to then create the certs. Hopefully I understand it right.

I'll contact Cloudflare support and will close this for now. Thanks again

francislavoie commented 5 months ago

Is 172.67.137.37 your server's IP address? You need to set your domain's A record to your server's IP, not something else.

Cyb3rC3lt commented 5 months ago

So looking it up Francis, I notice 2 are mentioned on some sites but I think the 172 one was the one I see referenced most often.

There were no A records pointing to either of them on Cloudflare until I added 1 to try to create certs. 4 other A records pointed to the Cloudflsre nameservers I believe.

IP results:

https://www.nslookup.io/domains/redteaming.org/webservers/

Screenshot_20240108-214958

mholt commented 5 months ago

Wait, why point A records to Cloudflare's nameservers? Was that intentional?

Cyb3rC3lt commented 5 months ago

I think that was a mistake now. I assumed that was the IP but looking back I should be hunting for the IP before I ever moved to Cloudflare! My site is hosted at github pages so it's https://Cyb3rC3lt.github.io so according to this site (https://www.site24x7.com/tools/find-ip-address-of-web-site.html) my IP is 185.199.110.153:

So maybe that is the one that is meant to go into the A record before! Weirdly putting only that IP into a browser doesn't take me to the site unlike using https://Cyb3rC3lt.github.io

Screenshot_20240108-223322

francislavoie commented 5 months ago

185.199.110.153 is Github's IP, not your server's.

What IP does your server have? Can't you SSH into your server? How do you access your server?

Cyb3rC3lt commented 5 months ago

All I do to publish my webpages is to push to that Github repository that holds my site. You can see the site contents here:

https://github.com/Cyb3rC3lt/Cyb3rC3lt.github.io

So I don't ssh into anything. What server my Github repository stores the data in or its IP is unknown to me unfortunately.

francislavoie commented 5 months ago

I don't understand what you're trying to do here. You can't get a certificate using the ACME HTTP or TLS-ALPN challenge if your domain isn't pointing to the IP address of your server. You'd need to use the DNS challenge.

mholt commented 5 months ago

So, I think you actually just want a custom domain for your GitHub pages site?

Have you followed these docs? https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site

Cyb3rC3lt commented 5 months ago

Thanks guys, so to answer your questions.

Yes I followed the custom domain route of Github. Most people use the domain provided which in my case is http://Cyb3rC3lt.github.io but I implemented a custom domain which allowed me to make that redteaming.org.

@francislavoie I think you are right. I hadn't really thought about the fact that I think my site doesn't have a single IP. I think it sits on a Github server with 1000s of other sites but some translation occurs to link to mine when requested.

I guess that's why I used the TXT record to get it working with LetsEncrypt. I think DNS is the way to go but even if certmagic can do that I'm not sure the evilginx implementation uses it but instead looks for an A record.

I guess that brings me back full circle to see if you guys have any simple Go import file to import pem files into certmagic using 'CacheUnmanagedCertificatePEMFile' which will do as a workaround? I'm not a Go dev but I could run something passing an existing key and cert path into it just to get them into cache.

Or actually, a simple little Go file to create the certs fresh via DNS would work also. Maybe like a test harness file you guys might have lying around.

Thanks again

mholt commented 5 months ago

I don't fully understand though, if you are using a custom domain for your GitHub pages site, you don't need to run a server at all: https://docs.github.com/en/pages/getting-started-with-github-pages/securing-your-github-pages-site-with-https

GitHub will get the cert for you...