Skip to content
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

Use lego binary for http 01 challenge #1770

Merged
merged 6 commits into from
Mar 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions cmd/incusd/acme.go → cmd/incusd/api_acme.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package main

import (
"context"
"io"
"net"
"net/http"
"net/url"

"github.com/gorilla/mux"
"strings"

"github.com/lxc/incus/v6/internal/server/acme"
"github.com/lxc/incus/v6/internal/server/cluster"
Expand All @@ -32,11 +32,7 @@ var acmeChallengeCmd = APIEndpoint{
func acmeProvideChallenge(d *Daemon, r *http.Request) response.Response {
s := d.State()

token, err := url.PathUnescape(mux.Vars(r)["token"])
if err != nil {
return response.SmartError(err)
}

// Redirect to the leader when clustered.
if s.ServerClustered {
leader, err := s.Cluster.LeaderAddress()
if err != nil {
Expand All @@ -57,14 +53,44 @@ func acmeProvideChallenge(d *Daemon, r *http.Request) response.Response {
}
}

if d.http01Provider == nil || d.http01Provider.Token() != token {
return response.NotFound(nil)
// Forward to the lego listener.
addr := s.GlobalConfig.ACMEHTTP()
if strings.HasPrefix(addr, ":") {
addr = "127.0.0.1" + addr
}

domain, _, _, _, _ := s.GlobalConfig.ACME()

client := http.Client{}
client.Transport = &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return net.Dial("tcp", addr)
},
}

req, err := http.NewRequest("GET", "http://"+domain+r.URL.String(), nil)
if err != nil {
return response.InternalError(err)
}

req.Header = r.Header

resp, err := client.Do(req)
if err != nil {
return response.InternalError(err)
}

defer resp.Body.Close()

challenge, err := io.ReadAll(resp.Body)
if err != nil {
return response.InternalError(err)
}

return response.ManualResponse(func(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "text/plain")

_, err := w.Write([]byte(d.http01Provider.KeyAuth()))
_, err = w.Write(challenge)
if err != nil {
return err
}
Expand Down Expand Up @@ -98,7 +124,7 @@ func autoRenewCertificate(ctx context.Context, d *Daemon, force bool) error {
}

opRun := func(op *operations.Operation) error {
newCert, err := acme.UpdateCertificate(s, challengeType, d.http01Provider, s.ServerClustered, domain, email, caURL, force)
newCert, err := acme.UpdateCertificate(s, challengeType, s.ServerClustered, domain, email, caURL, force)
if err != nil {
return err
}
Expand Down
5 changes: 0 additions & 5 deletions cmd/incusd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
internalIO "github.com/lxc/incus/v6/internal/io"
"github.com/lxc/incus/v6/internal/linux"
"github.com/lxc/incus/v6/internal/rsync"
"github.com/lxc/incus/v6/internal/server/acme"
"github.com/lxc/incus/v6/internal/server/apparmor"
"github.com/lxc/incus/v6/internal/server/auth"
"github.com/lxc/incus/v6/internal/server/auth/oidc"
Expand Down Expand Up @@ -156,9 +155,6 @@ type Daemon struct {

lokiClient *loki.Client

// HTTP-01 challenge provider for ACME
http01Provider acme.HTTP01Provider

// Authorization.
authorizer auth.Authorizer

Expand Down Expand Up @@ -198,7 +194,6 @@ func newDaemon(config *DaemonConfig, os *sys.OS) *Daemon {
devIncusEvents: devIncusEvents,
events: incusEvents,
db: &db.DB{},
http01Provider: acme.NewHTTP01Provider(),
os: os,
setupChan: make(chan struct{}),
waitReady: cancel.New(context.Background()),
Expand Down
4 changes: 4 additions & 0 deletions doc/api-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2740,3 +2740,7 @@ This is used to get the OVN logical switch name.

Introduces the `dns.nameservers` configuration option on bridged and OVN networks.
This allows specifying IPv4 and IPv6 DNS server addresses to be announced by the DHCP server and via Router Advertisements.

## `acme_http01_port`

Adds `acme.http.port` to control an alternative HTTP port for `HTTP-01` validation.
8 changes: 8 additions & 0 deletions doc/config_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,14 @@ Possible values are `DNS-01` and `HTTP-01`.

```

```{config:option} acme.http.port server-acme
:defaultdesc: "`:80`"
:scope: "global"
:shortdesc: "Port and interface for HTTP server (used by HTTP-01)"
:type: "string"
Set the port and interface to use for HTTP-01 based challenges to listen on
```

```{config:option} acme.provider server-acme
:defaultdesc: "``"
:scope: "global"
Expand Down
49 changes: 23 additions & 26 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ require (
github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0
github.com/flosch/pongo2/v6 v6.0.0
github.com/fvbommel/sortorder v1.1.0
github.com/go-acme/lego/v4 v4.22.2
github.com/go-chi/chi/v5 v5.2.1
github.com/go-jose/go-jose/v4 v4.0.5
github.com/go-logr/logr v1.4.2
Expand All @@ -35,15 +34,15 @@ require (
github.com/mdlayher/netx v0.0.0-20230430222610-7e21880baee8
github.com/mdlayher/vsock v1.2.1
github.com/miekg/dns v1.1.63
github.com/minio/minio-go/v7 v7.0.87
github.com/minio/minio-go/v7 v7.0.88
github.com/mitchellh/mapstructure v1.5.0
github.com/olekukonko/tablewriter v0.0.5
github.com/opencontainers/runtime-spec v1.2.0
github.com/opencontainers/runtime-spec v1.2.1
github.com/openfga/go-sdk v0.6.5
github.com/osrg/gobgp/v3 v3.34.0
github.com/osrg/gobgp/v3 v3.35.0
github.com/ovn-org/libovsdb v0.7.0
github.com/pierrec/lz4/v4 v4.1.22
github.com/pkg/sftp v1.13.7
github.com/pkg/sftp v1.13.8
github.com/pkg/xattr v0.4.10
github.com/robfig/cron/v3 v3.0.1
github.com/sirupsen/logrus v1.9.3
Expand All @@ -52,16 +51,16 @@ require (
github.com/stretchr/testify v1.10.0
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/vishvananda/netlink v1.3.0
github.com/zitadel/oidc/v3 v3.35.0
github.com/zitadel/oidc/v3 v3.36.1
go.starlark.net v0.0.0-20250225190231-0d3f41d403af
golang.org/x/crypto v0.35.0
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa
golang.org/x/oauth2 v0.27.0
golang.org/x/sync v0.11.0
golang.org/x/sys v0.30.0
golang.org/x/term v0.29.0
golang.org/x/text v0.22.0
golang.org/x/tools v0.30.0
golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394
golang.org/x/oauth2 v0.28.0
golang.org/x/sync v0.12.0
golang.org/x/sys v0.31.0
golang.org/x/term v0.30.0
golang.org/x/text v0.23.0
golang.org/x/tools v0.31.0
google.golang.org/protobuf v1.36.5
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
gopkg.in/yaml.v2 v2.4.0
Expand All @@ -77,15 +76,14 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
github.com/digitalocean/go-libvirt v0.0.0-20250226181018-4d5f24afb7c2 // indirect
github.com/digitalocean/go-libvirt v0.0.0-20250313214939-3c0f2fe97d18 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eapache/channels v1.1.0 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/renameio v1.0.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
Expand All @@ -110,9 +108,9 @@ require (
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.21.0 // indirect
github.com/prometheus/client_golang v1.21.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/common v0.63.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/cors v1.11.1 // indirect
Expand All @@ -130,15 +128,14 @@ require (
github.com/zitadel/logging v0.6.1 // indirect
github.com/zitadel/schema v1.3.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/net v0.35.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250224174004-546df14abb99 // indirect
google.golang.org/grpc v1.70.0 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.37.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
google.golang.org/grpc v1.71.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading
Loading