-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add acme-proxy provider #708
Conversation
Please don't use your master to open PR. |
For me the provider |
Should I best create a branch? (sorry, I'm not well-versed yet in git)
Hmm, I didn't notice that one before. Indeed it does. Although I think an integration with lego for this specific purpose seem logical. Would you be willing to consider this? |
You can also look at the |
More information about the When you want to open a PR, I recommend that you create a dedicated branch. |
I rebased your branch and clean your code (amend). To open a PR:
# Create the root folder
mkdir $GOPATH/src/github.com/xenolf
cd $GOPATH/src/github.com/xenolf
# clone your fork
git clone [email protected]:yourusername/lego.git
cd lego
# Add the xenolf/lego remote
git remote add upstream [email protected]:xenolf/lego.git
git fetch upstream
# Create your branch
git checkout -b my-feature
## Create your code ##
# Linters
make checks
# Tests
make test
# Complle
make build
# push your branch
git push -u origin my-feature
# create a pull request |
I read the code of your acme-proxy and you can write something like that: refactorpackage main
import (
"encoding/json"
"log"
"net"
"net/http"
"strconv"
"github.com/xenolf/lego/platform/config/env"
"github.com/xenolf/lego/providers/dns"
)
type Message struct {
Domain string `json:"domain"`
Token string `json:"token"`
KeyAuth string `json:"keyAuth"`
}
type Config struct {
Host string
Port int
Provider string
}
func NewDefaultConfig() *Config {
return &Config{
Host: env.GetOrDefaultString("ACMEPROXY_HOST", "127.0.0.1"),
Port: env.GetOrDefaultInt("ACMEPROXY_PORT", 9095),
}
}
func main() {
values, err := env.Get("ACMEPROXY_PROVIDER")
if err != nil {
panic(err)
}
config := NewDefaultConfig()
config.Provider = values["ACMEPROXY_PROVIDER"]
mux := http.NewServeMux()
mux.HandleFunc("/present", func(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
http.Error(rw, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
msg := &Message{}
err := json.NewDecoder(req.Body).Decode(msg)
if err != nil {
http.Error(rw, err.Error(), http.StatusBadRequest)
return
}
provider, err := dns.NewDNSChallengeProviderByName(config.Provider)
if err != nil {
http.Error(rw, err.Error(), http.StatusBadRequest)
return
}
err = provider.Present(msg.Domain, msg.Token, msg.KeyAuth)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
})
mux.HandleFunc("/cleanup", func(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
http.Error(rw, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
msg := &Message{}
err := json.NewDecoder(req.Body).Decode(msg)
if err != nil {
http.Error(rw, err.Error(), http.StatusBadRequest)
return
}
provider, err := dns.NewDNSChallengeProviderByName(config.Provider)
if err != nil {
http.Error(rw, err.Error(), http.StatusBadRequest)
return
}
err = provider.CleanUp(msg.Domain, msg.Token, msg.KeyAuth)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
})
log.Fatal(http.ListenAndServe(net.JoinHostPort(config.Host, strconv.Itoa(config.Port)), mux))
} But I still think that what you are trying to do can be obtained by either the simple exec example#!/usr/bin/env bash
# Simple DNS challenge exec solver.
set -e
case "$1" in
"present")
echo "Present"
payload="{\"host\":\"$2\", \"value\":\"$3\"}"
echo "payload=${payload}"
curl -s -X POST -d "${payload}" http://my-host:8055/present
;;
"cleanup")
echo "cleanup"
payload="{\"host\":\"$2\"}"
echo "payload=${payload}"
curl -s -X POST -d "${payload}" http://my-host:8055/cleanup
;;
*)
echo "OOPS"
;;
esac |
@ldez thanks so much for these very detailed instructions. This helps me a lot making better code and PR. I'm amazed at the speed and details you can refactor things like this. Are you doing this by hand or is it a combination of linting and other tools? It would be good to maybe add this to the documentation / wiki to show other developers the best way to suggest changes to the code (or this is just known by everyone and I'm the one that's lagging ;-)
I did and I even wrote a functional CNAME record updater. See the discussion here: joohoi/acme-dns#126. But practically it's overload as I don't necessarily need the acme-dns method, "just" a proxy would be enough as I do have an API + credentials but I don't want the credentials to be on all the hosts requesting certificates.
I'm thinking about this and technically you're absolutely right. I've started this to be able to integrate this "proxy" functionality into Caddy in the end (which integrates directly with lego). To have this contained in a single binary would be the preferred way. Also this would need two extra dependencies: curl and a separate bash script (very possible, but if you'd be willing to consider this I'd be very happy as I think it's a relevant option) |
@ldez I've created a new branch with updated code for the acme-proxy provider. Should I create a new PR and close this one? https://github.com/mdbraber/lego/tree/add-acmeproxy-provider |
After further thoughts, I understand your need but I want to implement it differently. |
@ldez thanks - I'd be happy to see your implementation. Do I need to do something specific or do you just want to create your own PR based on this idea (which is fine)? |
I will create my own PR based on your idea. |
In my effort to centralize certificate requests for hosts in my network (and not having to spread out credentials) I've written an acme-proxy provider to be used with http://github.com/mdbraber/acme-proxy. It works fine (see below) and the nice thing is because it plugs in to lego, you can simply use any provider that lego offers.
I'm submitting this PR to get comments on tips for the suggested implementation. I'm not sure what's the best way to do this, as I had to change some imports to work with my local branch that obviously shouldn't be in the PR.
Running the proxy:
$ ACMEPROXY_PROVIDER="transip" TRANSIP_ACCOUNT_NAME="mdbraber" TRANSIP_PRIVATE_KEY_PATH="/Users/mdbraber/transip.key" go run acme-proxy.go
Requesting a certificate: