Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mailinabox
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
mailinabox
Commits
4ae76aa2
Commit
4ae76aa2
authored
Oct 04, 2014
by
Joshua Tauberer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dnssec: use RSASHA256 keys for .email domains
parent
ba33669a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
45 additions
and
10 deletions
+45
-10
dns_update.py
management/dns_update.py
+11
-1
status_checks.py
management/status_checks.py
+6
-3
dns.sh
setup/dns.sh
+21
-6
migrate.py
setup/migrate.py
+7
-0
No files found.
management/dns_update.py
View file @
4ae76aa2
...
@@ -479,8 +479,18 @@ zone:
...
@@ -479,8 +479,18 @@ zone:
########################################################################
########################################################################
def
dnssec_choose_algo
(
domain
,
env
):
if
domain
.
endswith
(
".email"
):
# At least at GoDaddy, this is the only algorithm supported.
return
"RSASHA256"
# For any domain we were able to sign before, don't change the algorithm
# on existing users. We'll probably want to migrate to SHA256 later.
return
"RSASHA1-NSEC3-SHA1"
def
sign_zone
(
domain
,
zonefile
,
env
):
def
sign_zone
(
domain
,
zonefile
,
env
):
dnssec_keys
=
load_env_vars_from_file
(
os
.
path
.
join
(
env
[
'STORAGE_ROOT'
],
'dns/dnssec/keys.conf'
))
algo
=
dnssec_choose_algo
(
domain
,
env
)
dnssec_keys
=
load_env_vars_from_file
(
os
.
path
.
join
(
env
[
'STORAGE_ROOT'
],
'dns/dnssec/
%
s.conf'
%
algo
))
# In order to use the same keys for all domains, we have to generate
# In order to use the same keys for all domains, we have to generate
# a new .key file with a DNSSEC record for the specific domain. We
# a new .key file with a DNSSEC record for the specific domain. We
...
...
management/status_checks.py
View file @
4ae76aa2
...
@@ -210,14 +210,15 @@ def check_dnssec(domain, env, dns_zonefiles, is_checking_primary=False):
...
@@ -210,14 +210,15 @@ def check_dnssec(domain, env, dns_zonefiles, is_checking_primary=False):
# Some registrars may want the public key so they can compute the digest. The DS
# Some registrars may want the public key so they can compute the digest. The DS
# record that we suggest using is for the KSK (and that's how the DS records were generated).
# record that we suggest using is for the KSK (and that's how the DS records were generated).
dnssec_keys
=
load_env_vars_from_file
(
os
.
path
.
join
(
env
[
'STORAGE_ROOT'
],
'dns/dnssec/keys.conf'
))
alg_name_map
=
{
'7'
:
'RSASHA1-NSEC3-SHA1'
,
'8'
:
'RSASHA256'
}
dnssec_keys
=
load_env_vars_from_file
(
os
.
path
.
join
(
env
[
'STORAGE_ROOT'
],
'dns/dnssec/
%
s.conf'
%
alg_name_map
[
ds_alg
]))
dnsssec_pubkey
=
open
(
os
.
path
.
join
(
env
[
'STORAGE_ROOT'
],
'dns/dnssec/'
+
dnssec_keys
[
'KSK'
]
+
'.key'
))
.
read
()
.
split
(
"
\t
"
)[
3
]
.
split
(
" "
)[
3
]
dnsssec_pubkey
=
open
(
os
.
path
.
join
(
env
[
'STORAGE_ROOT'
],
'dns/dnssec/'
+
dnssec_keys
[
'KSK'
]
+
'.key'
))
.
read
()
.
split
(
"
\t
"
)[
3
]
.
split
(
" "
)[
3
]
# Query public DNS for the DS record at the registrar.
# Query public DNS for the DS record at the registrar.
ds
=
query_dns
(
domain
,
"DS"
,
nxdomain
=
None
)
ds
=
query_dns
(
domain
,
"DS"
,
nxdomain
=
None
)
ds_looks_valid
=
ds
and
len
(
ds
.
split
(
" "
))
==
4
ds_looks_valid
=
ds
and
len
(
ds
.
split
(
" "
))
==
4
if
ds_looks_valid
:
ds
=
ds
.
split
(
" "
)
if
ds_looks_valid
:
ds
=
ds
.
split
(
" "
)
if
ds_looks_valid
and
ds
[
0
]
==
ds_keytag
and
ds
[
1
]
==
'7'
and
ds
[
3
]
==
digests
.
get
(
ds
[
2
]):
if
ds_looks_valid
and
ds
[
0
]
==
ds_keytag
and
ds
[
1
]
==
ds_alg
and
ds
[
3
]
==
digests
.
get
(
ds
[
2
]):
if
is_checking_primary
:
return
if
is_checking_primary
:
return
env
[
'out'
]
.
print_ok
(
"DNSSEC 'DS' record is set correctly at registrar."
)
env
[
'out'
]
.
print_ok
(
"DNSSEC 'DS' record is set correctly at registrar."
)
else
:
else
:
...
@@ -236,7 +237,9 @@ def check_dnssec(domain, env, dns_zonefiles, is_checking_primary=False):
...
@@ -236,7 +237,9 @@ def check_dnssec(domain, env, dns_zonefiles, is_checking_primary=False):
env
[
'out'
]
.
print_line
(
""
)
env
[
'out'
]
.
print_line
(
""
)
env
[
'out'
]
.
print_line
(
"Key Tag: "
+
ds_keytag
+
(
""
if
not
ds_looks_valid
or
ds
[
0
]
==
ds_keytag
else
" (Got '
%
s')"
%
ds
[
0
]))
env
[
'out'
]
.
print_line
(
"Key Tag: "
+
ds_keytag
+
(
""
if
not
ds_looks_valid
or
ds
[
0
]
==
ds_keytag
else
" (Got '
%
s')"
%
ds
[
0
]))
env
[
'out'
]
.
print_line
(
"Key Flags: KSK"
)
env
[
'out'
]
.
print_line
(
"Key Flags: KSK"
)
env
[
'out'
]
.
print_line
(
"Algorithm: 7 / RSASHA1-NSEC3-SHA1"
+
(
""
if
not
ds_looks_valid
or
ds
[
1
]
==
'7'
else
" (Got '
%
s')"
%
ds
[
1
]))
env
[
'out'
]
.
print_line
(
(
"Algorithm:
%
s /
%
s"
%
(
ds_alg
,
alg_name_map
[
ds_alg
]))
+
(
""
if
not
ds_looks_valid
or
ds
[
1
]
==
ds_alg
else
" (Got '
%
s')"
%
ds
[
1
]))
# see http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
# see http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
env
[
'out'
]
.
print_line
(
"Digest Type: 2 / SHA-256"
)
env
[
'out'
]
.
print_line
(
"Digest Type: 2 / SHA-256"
)
# http://www.ietf.org/assignments/ds-rr-types/ds-rr-types.xml
# http://www.ietf.org/assignments/ds-rr-types/ds-rr-types.xml
...
...
setup/dns.sh
View file @
4ae76aa2
...
@@ -36,25 +36,39 @@ sudo mkdir -p /var/run/nsd
...
@@ -36,25 +36,39 @@ sudo mkdir -p /var/run/nsd
# Create DNSSEC signing keys.
# Create DNSSEC signing keys.
mkdir
-p
"
$STORAGE_ROOT
/dns/dnssec"
;
mkdir
-p
"
$STORAGE_ROOT
/dns/dnssec"
;
if
[
!
-f
"
$STORAGE_ROOT
/dns/dnssec/keys.conf"
]
;
then
echo
"Generating DNSSEC signing keys. This may take a few minutes..."
# TLDs don't all support the same algorithms, so we'll generate keys using a few
# different algorithms.
#
# Supports RSASHA1-NSEC3-SHA1 (didn't test with RSASHA256):
# .info and .me.
#
# Requires RSASHA256
# .email
FIRST
=
1
for
algo
in
RSASHA1-NSEC3-SHA1 RSASHA256
;
do
if
[
!
-f
"
$STORAGE_ROOT
/dns/dnssec/
$algo
.conf"
]
;
then
if
[
$FIRST
==
1
]
;
then
echo
"Generating DNSSEC signing keys. This may take a few minutes..."
FIRST
=
0
fi
# Create the Key-Signing Key (KSK) (-k) which is the so-called
# Create the Key-Signing Key (KSK) (-k) which is the so-called
# Secure Entry Point. Use a NSEC3-compatible algorithm (best
# Secure Entry Point. Use a NSEC3-compatible algorithm (best
# practice), and a nice and long keylength. The domain name we
# practice), and a nice and long keylength. The domain name we
# provide ("_domain_") doesn't matter -- we'll use the same
# provide ("_domain_") doesn't matter -- we'll use the same
# keys for all our domains.
# keys for all our domains.
KSK
=
$(
umask
077
;
cd
$STORAGE_ROOT
/dns/dnssec
;
ldns-keygen
-a
RSASHA1-NSEC3-SHA1
-b
2048
-k
_domain_
)
;
KSK
=
$(
umask
077
;
cd
$STORAGE_ROOT
/dns/dnssec
;
ldns-keygen
-a
$algo
-b
2048
-k
_domain_
)
;
# Now create a Zone-Signing Key (ZSK) which is expected to be
# Now create a Zone-Signing Key (ZSK) which is expected to be
# rotated more often than a KSK, although we have no plans to
# rotated more often than a KSK, although we have no plans to
# rotate it (and doing so would be difficult to do without
# rotate it (and doing so would be difficult to do without
# disturbing DNS availability.) Omit '-k' and use a shorter key.
# disturbing DNS availability.) Omit '-k' and use a shorter key.
ZSK
=
$(
umask
077
;
cd
$STORAGE_ROOT
/dns/dnssec
;
ldns-keygen
-a
RSASHA1-NSEC3-SHA1
-b
1024 _domain_
)
;
ZSK
=
$(
umask
077
;
cd
$STORAGE_ROOT
/dns/dnssec
;
ldns-keygen
-a
$algo
-b
1024 _domain_
)
;
# These generate two sets of files like:
# These generate two sets of files like:
#
#
# * `K_domain_.+007+08882.ds`: DS record
to provide to domain name registrar
# * `K_domain_.+007+08882.ds`: DS record
normally provided to domain name registrar (but it's actually invalid with "_domain_")
# * `K_domain_.+007+08882.key`: public key (goes into DS record & upstream DNS provider like your registrar)
# * `K_domain_.+007+08882.key`: public key (goes into DS record & upstream DNS provider like your registrar)
# * `K_domain_.+007+08882.private`: private key (secret!)
# * `K_domain_.+007+08882.private`: private key (secret!)
...
@@ -62,11 +76,12 @@ if [ ! -f "$STORAGE_ROOT/dns/dnssec/keys.conf" ]; then
...
@@ -62,11 +76,12 @@ if [ ! -f "$STORAGE_ROOT/dns/dnssec/keys.conf" ]; then
# options. So we'll store the names of the files we just generated.
# options. So we'll store the names of the files we just generated.
# We might have multiple keys down the road. This will identify
# We might have multiple keys down the road. This will identify
# what keys are the current keys.
# what keys are the current keys.
cat
>
$STORAGE_ROOT
/dns/dnssec/
keys
.conf
<<
EOF
;
cat
>
$STORAGE_ROOT
/dns/dnssec/
$algo
.conf
<<
EOF
;
KSK=
$KSK
KSK=
$KSK
ZSK=
$ZSK
ZSK=
$ZSK
EOF
EOF
fi
fi
done
# Force the dns_update script to be run every day to re-sign zones for DNSSEC.
# Force the dns_update script to be run every day to re-sign zones for DNSSEC.
cat
>
/etc/cron.daily/mailinabox-dnssec
<<
EOF
;
cat
>
/etc/cron.daily/mailinabox-dnssec
<<
EOF
;
...
...
setup/migrate.py
View file @
4ae76aa2
...
@@ -60,6 +60,13 @@ def migration_5(env):
...
@@ -60,6 +60,13 @@ def migration_5(env):
# The secret key for encrypting backups was world readable. Fix here.
# The secret key for encrypting backups was world readable. Fix here.
os
.
chmod
(
os
.
path
.
join
(
env
[
"STORAGE_ROOT"
],
'backup/secret_key.txt'
),
0o600
)
os
.
chmod
(
os
.
path
.
join
(
env
[
"STORAGE_ROOT"
],
'backup/secret_key.txt'
),
0o600
)
def
migration_6
(
env
):
# We now will generate multiple DNSSEC keys for different algorithms, since TLDs may
# not support them all. .email only supports RSA/SHA-256. Rename the keys.conf file
# to be algorithm-specific.
basepath
=
os
.
path
.
join
(
env
[
"STORAGE_ROOT"
],
'dns/dnssec'
)
shutil
.
move
(
os
.
path
.
join
(
basepath
,
'keys.conf'
),
os
.
path
.
join
(
basepath
,
'RSASHA1-NSEC3-SHA1.conf'
))
def
get_current_migration
():
def
get_current_migration
():
ver
=
0
ver
=
0
while
True
:
while
True
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment