From 353a488f01340fe6c6e706d348e30d7ada48fba8 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Tue, 29 Nov 2016 15:35:46 +0200 Subject: [PATCH 1/5] Extend the database for a upcoming feature before release --- db.go | 34 +++++++++++++++++++++++----------- types.go | 1 + 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/db.go b/db.go index aaa6cdb..868cf6e 100644 --- a/db.go +++ b/db.go @@ -17,7 +17,8 @@ var recordsTable = ` Password TEXT UNIQUE NOT NULL, Subdomain TEXT UNIQUE NOT NULL, Value TEXT, - LastActive INT + LastActive INT, + AllowFrom TEXT );` // getSQLiteStmt replaces all PostgreSQL prepared statement placeholders (eg. $1, $2) with SQLite variant "?" @@ -54,8 +55,9 @@ func (d *acmedb) Register() (ACMETxt, error) { Password, Subdomain, Value, - LastActive) - values($1, $2, $3, '', $4)` + LastActive, + AllowFrom) + values($1, $2, $3, '', $4, $5)` if DNSConf.Database.Engine == "sqlite3" { regSQL = getSQLiteStmt(regSQL) } @@ -64,7 +66,7 @@ func (d *acmedb) Register() (ACMETxt, error) { return a, errors.New("SQL error") } defer sm.Close() - _, err = sm.Exec(a.Username.String(), passwordHash, a.Subdomain, timenow) + _, err = sm.Exec(a.Username.String(), passwordHash, a.Subdomain, timenow, a.AllowFrom) if err != nil { return a, err } @@ -76,7 +78,7 @@ func (d *acmedb) GetByUsername(u uuid.UUID) (ACMETxt, error) { defer d.Unlock() var results []ACMETxt getSQL := ` - SELECT Username, Password, Subdomain, Value, LastActive + SELECT Username, Password, Subdomain, Value, LastActive, AllowFrom FROM records WHERE Username=$1 LIMIT 1 ` @@ -97,12 +99,11 @@ func (d *acmedb) GetByUsername(u uuid.UUID) (ACMETxt, error) { // It will only be one row though for rows.Next() { - a := ACMETxt{} - err = rows.Scan(&a.Username, &a.Password, &a.Subdomain, &a.Value, &a.LastActive) + txt, err := getModelFromRow(rows) if err != nil { return ACMETxt{}, err } - results = append(results, a) + results = append(results, txt) } if len(results) > 0 { return results[0], nil @@ -116,7 +117,7 @@ func (d *acmedb) GetByDomain(domain string) ([]ACMETxt, error) { domain = sanitizeString(domain) var a []ACMETxt getSQL := ` - SELECT Username, Password, Subdomain, Value + SELECT Username, Password, Subdomain, Value, LastActive, AllowFrom FROM records WHERE Subdomain=$1 LIMIT 1 ` @@ -136,8 +137,7 @@ func (d *acmedb) GetByDomain(domain string) ([]ACMETxt, error) { defer rows.Close() for rows.Next() { - txt := ACMETxt{} - err = rows.Scan(&txt.Username, &txt.Password, &txt.Subdomain, &txt.Value) + txt, err := getModelFromRow(rows) if err != nil { return a, err } @@ -171,6 +171,18 @@ func (d *acmedb) Update(a ACMETxt) error { return nil } +func getModelFromRow(r *sql.Rows) (ACMETxt, error) { + txt := ACMETxt{} + err := r.Scan( + &txt.Username, + &txt.Password, + &txt.Subdomain, + &txt.Value, + &txt.LastActive, + &txt.AllowFrom) + return txt, err +} + func (d *acmedb) Close() { d.DB.Close() } diff --git a/types.go b/types.go index d7239a2..c6bdf46 100644 --- a/types.go +++ b/types.go @@ -72,6 +72,7 @@ type ACMETxt struct { Password string ACMETxtPost LastActive int64 + AllowFrom string } // ACMETxtPost holds the DNS part of the ACMETxt struct From 70f45b374a47aa3aa97d3b5f343376dfb01ccbde Mon Sep 17 00:00:00 2001 From: Santeri Toikka Date: Wed, 30 Nov 2016 08:26:46 +0200 Subject: [PATCH 2/5] Updates to instructions. --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 24d078a..35d4e88 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ A simplified DNS server with a RESTful HTTP API to provide a simple way to autom ## Why? -Many DNS servers do not provide an API to enable automation for the ACME DNS challenges. And those which do, give the keys way too much power to leave them laying around your random boxes, which sadly would be required to have a meaningful way to automate the process. +Many DNS servers do not provide an API to enable automation for the ACME DNS challenges. Those which do, gives the keys way too much power. +Leaving them to lay around your random boxes is too often a requirement to have a meaningful process automation. So basically it boils down to **accessibility** and **security** @@ -20,19 +21,19 @@ So basically it boils down to **accessibility** and **security** [![asciicast](https://asciinema.org/a/94462.png)](https://asciinema.org/a/94462) -Using acme-dns is a three-step process (provided you already have the server set up, or are using a service): +Using acme-dns is a three-step process (provided you already have the self-hosted server set up, or are using a service like acme-dns.io): - Get credentials and unique subdomain (simple GET request to https://auth.exmaple.org/register) - Create a (ACME magic) CNAME record to your existing zone, pointing to the subdomain you got from the registration. (eg. `_acme-challenge.domainiwantcertfor.tld. CNAME a097455b-52cc-4569-90c8-7a4b97c6eba8.auth.example.org` ) - Use your credentials to POST a new DNS challenge values to an acme-dns server for the CA to validate them off of. - -After that, crontab and forget. +- Crontab and forget. ## API ### Register endpoint -The method returns a new unique subdomain to point the CNAME record to, along with credentials needed to update its TXT response. +The method returns a new unique subdomain and credentials needed to update your record. +Subdomain is where you can point your own `_acme-challenge` subdomain CNAME record along with credentials in TXT response. ```GET /register``` @@ -87,7 +88,7 @@ Check out how in the INSTALL section. ## As a service -I am running an acme-dns instance as a service for everyone wanting to get on in fast. The service is running at `auth.acme-dns.io`, so to get started, try: +Acme-dns instance as a service for everyone wanting to get on in fast. The service is running at `auth.acme-dns.io`, so to get started, try: ```curl -X GET https://auth.acme-dns.io/register``` @@ -105,7 +106,7 @@ I am running an acme-dns instance as a service for everyone wanting to get on in 6) Edit config.cfg to suit your needs (see [configuration](#configuration)) -7) Run acme-dns. Please note that acme-dns needs to open a privileged port (53, domain), so it needs to be run with according privileges. +7) Run acme-dns. Please note that acme-dns needs to open a privileged port (53, domain), so it needs to be run with correct privileges. ## Configuration @@ -116,13 +117,13 @@ I am running an acme-dns instance as a service for everyone wanting to get on in listen = ":53" # protocol, "udp", "udp4", "udp6" or "tcp", "tcp4", "tcp6" protocol = "udp" -# domain name to serve th requests off of +# domain name to serve the requests off of domain = "auth.example.org" # zone name server nsname = "ns1.auth.example.org" -# admin email address, with @ substituted with . +# admin email address, where @ is substituted with . nsadmin = "admin.example.org" -# predefined records that we're serving in addition to the TXT +# predefined records served in addition to the TXT records = [ # default A "auth.example.org. A 192.168.1.100", @@ -171,7 +172,7 @@ logformat = "text" ## TODO -- Ability to POST to /register endpoint, giving users the possibility to define CIDR masks to restrict the /update requests for the created user / key to. +- Ability to define the CIDR mask in POST request to /register endpoint which is authorized to make /update requests with the created user-key-pair. - Want to see something implemented, make a feature request! ## Contributing From 77729447d4697fa65deed2d5426c5defca0c2939 Mon Sep 17 00:00:00 2001 From: Santeri Toikka Date: Fri, 2 Dec 2016 17:44:58 +0200 Subject: [PATCH 3/5] Corrections to spelling and structure based on the discussions. --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 35d4e88..1f70aca 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ A simplified DNS server with a RESTful HTTP API to provide a simple way to autom ## Why? -Many DNS servers do not provide an API to enable automation for the ACME DNS challenges. Those which do, gives the keys way too much power. -Leaving them to lay around your random boxes is too often a requirement to have a meaningful process automation. +Many DNS servers do not provide an API to enable automation for the ACME DNS challenges. Those which do, give the keys way too much power. +Leaving the keys laying around your random boxes is too often a requirement to have a meaningful process automation. So basically it boils down to **accessibility** and **security** @@ -33,7 +33,8 @@ Using acme-dns is a three-step process (provided you already have the self-hoste ### Register endpoint The method returns a new unique subdomain and credentials needed to update your record. -Subdomain is where you can point your own `_acme-challenge` subdomain CNAME record along with credentials in TXT response. +Subdomain is where you can point your own `_acme-challenge` subdomain CNAME record to. +With the credentials, you can update the TXT response in the service to match the challenge token, later referred as ______my_43_char_dns_validation_token______, given out by the Certificate Authority. ```GET /register``` @@ -88,7 +89,7 @@ Check out how in the INSTALL section. ## As a service -Acme-dns instance as a service for everyone wanting to get on in fast. The service is running at `auth.acme-dns.io`, so to get started, try: +Acme-dns instance is running as a service for everyone wanting to get on in fast. You can find it at `auth.acme-dns.io`, so to get started, try: ```curl -X GET https://auth.acme-dns.io/register``` From ef64560fe5062520329aeba52e28b16211b69bb4 Mon Sep 17 00:00:00 2001 From: Santeri Toikka Date: Fri, 2 Dec 2016 17:48:36 +0200 Subject: [PATCH 4/5] Elevated modifications. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f70aca..6e8a845 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ Acme-dns instance is running as a service for everyone wanting to get on in fast 6) Edit config.cfg to suit your needs (see [configuration](#configuration)) -7) Run acme-dns. Please note that acme-dns needs to open a privileged port (53, domain), so it needs to be run with correct privileges. +7) Run acme-dns. Please note that acme-dns needs to open a privileged port (53, domain), so it needs to be run with elevated privileges. ## Configuration From b269777304d443888d0a9a298d9be64608188b33 Mon Sep 17 00:00:00 2001 From: Santeri Toikka Date: Fri, 2 Dec 2016 18:14:02 +0200 Subject: [PATCH 5/5] Documentation updates to config file. --- config.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.cfg b/config.cfg index b0d593f..4bf5643 100644 --- a/config.cfg +++ b/config.cfg @@ -3,13 +3,13 @@ listen = ":53" # protocol, "udp", "udp4", "udp6" or "tcp", "tcp4", "tcp6" protocol = "udp" -# domain name to serve th requests off of +# domain name to serve the requests off of domain = "auth.example.org" # zone name server nsname = "ns1.auth.example.org" -# admin email address, with @ substituted with . +# admin email address, where @ is substituted with . nsadmin = "admin.example.org" -# predefined records that we're serving in addition to the TXT +# predefined records served in addition to the TXT records = [ # default A "auth.example.org. A 192.168.1.100",