DDNS keys are now not hardcoded

This commit is contained in:
nemunaire 2019-09-10 00:27:37 +02:00
parent 0b55b5fed3
commit cb50151678
4 changed files with 83 additions and 22 deletions

View File

@ -55,6 +55,10 @@ func addZone(p httprouter.Params, body io.Reader) Response {
uz.DomainName = uz.DomainName + "."
}
if len(uz.KeyName) > 1 && uz.KeyName[len(uz.KeyName)-1] != '.' {
uz.KeyName = uz.KeyName + "."
}
if libredns.ZoneExists(uz.DomainName) {
return APIErrorResponse{
err: errors.New("This zone already exists."),
@ -106,9 +110,9 @@ func axfrZone(zone libredns.Zone, body io.Reader) Response {
m := new(dns.Msg)
m.SetEdns0(4096, true)
t.TsigSecret = map[string]string{"ddns.": "so6ZGir4GPAqINNh9U5c3A=="}
t.TsigSecret = map[string]string{zone.KeyName: zone.Base64KeyBlob()}
m.SetAxfr(zone.DomainName)
m.SetTsig("ddns.", dns.HmacSHA256, 300, time.Now().Unix())
m.SetTsig(zone.KeyName, zone.KeyAlgo, 300, time.Now().Unix())
c, err := t.In(m, DefaultNameServer)
if err != nil {
@ -166,8 +170,8 @@ func addRR(zone libredns.Zone, body io.Reader) Response {
m.Insert([]dns.RR{rr})
c := new(dns.Client)
c.TsigSecret = map[string]string{"ddns.": "so6ZGir4GPAqINNh9U5c3A=="}
m.SetTsig("ddns.", dns.HmacSHA256, 300, time.Now().Unix())
c.TsigSecret = map[string]string{zone.KeyName: zone.Base64KeyBlob()}
m.SetTsig(zone.KeyName, zone.KeyAlgo, 300, time.Now().Unix())
in, rtt, err := c.Exchange(m, DefaultNameServer)
if err != nil {
@ -211,8 +215,8 @@ func delRR(zone libredns.Zone, body io.Reader) Response {
m.Remove([]dns.RR{rr})
c := new(dns.Client)
c.TsigSecret = map[string]string{"ddns.": "so6ZGir4GPAqINNh9U5c3A=="}
m.SetTsig("ddns.", dns.HmacSHA256, 300, time.Now().Unix())
c.TsigSecret = map[string]string{zone.KeyName: zone.Base64KeyBlob()}
m.SetTsig(zone.KeyName, zone.KeyAlgo, 300, time.Now().Unix())
in, rtt, err := c.Exchange(m, DefaultNameServer)
if err != nil {

View File

@ -37,21 +37,62 @@
>
<form ref="form" @submit.stop.prevent="handleSubmit">
<b-form-group
:state="domainNameState"
:state="newForm.domainNameState"
label="Domain name"
label-for="dn-input"
invalid-feedback="Domain name is required"
>
<b-form-input
id="dn-input"
v-model="toAttachDN"
:state="domainNameState"
v-model="newForm.domain"
:state="newForm.domainNameState"
required
placeholder="example.com"
ref="domainname"
></b-form-input>
<small id="dnHelp" class="form-text text-muted">Fill here the domain name you would like to manage with LibreDNS.</small>
</b-form-group>
<b-form-group
:state="newForm.domainServerState"
label="Server"
label-for="srv-input"
>
<b-form-input
id="srv-input"
v-model="newForm.server"
:state="newForm.domainServerState"
placeholder="ns0.libredns.com"
ref="domainserver"
></b-form-input>
</b-form-group>
<b-form-group
:state="newForm.keyNameState"
label="Dynamic DNS Update Key Name"
label-for="keyname-input"
>
<b-form-input
id="heyname-input"
v-model="newForm.keyname"
:state="newForm.keynameState"
required
placeholder="foo"
ref="keyname"
></b-form-input>
</b-form-group>
<b-form-group
:state="newForm.keyBlobState"
label="Dynamic DNS Update Key"
label-for="keyblob-input"
>
<b-form-input
id="heyblob-input"
v-model="newForm.keyblob"
:state="newForm.keyblobState"
required
placeholder="bar=="
ref="keyblob"
></b-form-input>
</b-form-group>
</form>
</b-modal>
</div>
@ -65,7 +106,7 @@ export default {
data: function () {
return {
domainNameState: null,
toAttachDN: '',
newForm: {},
zones: []
}
},
@ -77,10 +118,13 @@ export default {
},
methods: {
attachZone (dn) {
attachZone () {
axios
.post('/api/zones', {
domain: this.toAttachDN
domain: this.newForm.domain,
server: this.newForm.server,
keyname: this.newForm.keyname,
keyblob: this.newForm.keyblob
})
.then(
(response) => {
@ -112,13 +156,19 @@ export default {
},
resetModal () {
this.toAttachDN = ''
this.domainNameState = null
this.newForm.domain = ''
this.newForm.server = ''
this.newForm.keyname = ''
this.newForm.keyblob = ''
this.newForm.domainNameState = null
this.newForm.domainServerState = null
this.newForm.keyNameState = null
this.newForm.keyBlobState = null
},
checkFormValidity () {
const valid = this.$refs.form.checkValidity()
this.domainNameState = valid ? 'valid' : 'invalid'
this.newForm.domainNameState = valid ? 'valid' : 'invalid'
return valid
},
@ -132,7 +182,7 @@ export default {
return
}
this.attachZone(this.toAttachDN)
this.attachZone()
this.$nextTick(() => {
this.$refs.modal.hide()

View File

@ -73,6 +73,7 @@ CREATE TABLE IF NOT EXISTS zones(
domain VARCHAR(255) NOT NULL,
server VARCHAR(255),
key_name VARCHAR(255) NOT NULL,
key_algo ENUM("hmac-md5.sig-alg.reg.int.", "hmac-sha1.", "hmac-sha224.", "hmac-sha256.", "hmac-sha384.", "hmac-sha512.") NOT NULL DEFAULT "hmac-sha256.",
key_blob BLOB NOT NULL
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil {

View File

@ -1,6 +1,7 @@
package libredns
import (
"encoding/base64"
)
type Zone struct {
@ -8,18 +9,19 @@ type Zone struct {
DomainName string `json:"domain"`
Server string `json:"server,omitempty"`
KeyName string `json:"keyname,omitempty"`
KeyAlgo string `json:"algorithm,omitempty"`
KeyBlob []byte `json:"keyblob,omitempty"`
}
func GetZones() (zones []Zone, err error) {
if rows, errr := DBQuery("SELECT id_zone, domain, server, key_name, key_blob FROM zones"); errr != nil {
if rows, errr := DBQuery("SELECT id_zone, domain, server, key_name, key_algo, key_blob FROM zones"); errr != nil {
return nil, errr
} else {
defer rows.Close()
for rows.Next() {
var z Zone
if err = rows.Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyBlob); err != nil {
if err = rows.Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyAlgo, &z.KeyBlob); err != nil {
return
}
zones = append(zones, z)
@ -33,12 +35,12 @@ func GetZones() (zones []Zone, err error) {
}
func GetZone(id int) (z Zone, err error) {
err = DBQueryRow("SELECT id_user, domain, server, key_name, key_blob FROM zones WHERE id_zone=?", id).Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyBlob)
err = DBQueryRow("SELECT id_user, domain, server, key_name, key_algo, key_blob FROM zones WHERE id_zone=?", id).Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyAlgo, &z.KeyBlob)
return
}
func GetZoneByDN(dn string) (z Zone, err error) {
err = DBQueryRow("SELECT id_zone, domain, server, key_name, key_blob FROM zones WHERE domain=?", dn).Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyBlob)
err = DBQueryRow("SELECT id_zone, domain, server, key_name, key_algo, key_blob FROM zones WHERE domain=?", dn).Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyAlgo, &z.KeyBlob)
return
}
@ -49,7 +51,7 @@ func ZoneExists(dn string) bool {
}
func (z *Zone) NewZone() (Zone, error) {
if res, err := DBExec("INSERT INTO zones (domain, server, key_name, key_blob) VALUES (?, ?, ?, ?)", z.DomainName, z.Server, z.KeyName, z.KeyBlob); err != nil {
if res, err := DBExec("INSERT INTO zones (domain, server, key_name, key_algo, key_blob) VALUES (?, ?, ?, ?, ?)", z.DomainName, z.Server, z.KeyName, z.KeyAlgo, z.KeyBlob); err != nil {
return *z, err
} else if z.Id, err = res.LastInsertId(); err != nil {
return *z, err
@ -59,7 +61,7 @@ func (z *Zone) NewZone() (Zone, error) {
}
func (z *Zone) Update() (int64, error) {
if res, err := DBExec("UPDATE zones SET domain = ? WHERE id_zone = ?", z.DomainName, z.Id); err != nil {
if res, err := DBExec("UPDATE zones SET domain = ?, key_name = ?, key_algo = ?, key_blob = ? WHERE id_zone = ?", z.DomainName, z.KeyName, z.KeyAlgo, z.KeyBlob, z.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
@ -78,6 +80,10 @@ func (z *Zone) Delete() (int64, error) {
}
}
func (z *Zone) Base64KeyBlob() string {
return base64.StdEncoding.EncodeToString(z.KeyBlob)
}
func ClearZones() (int64, error) {
if res, err := DBExec("DELETE FROM zones"); err != nil {
return 0, err