Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F117520847
vyos-config-dns-forwarding.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
vyos-config-dns-forwarding.py
View Options
#!/usr/bin/env python3
#
# Copyright (C) 2018 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
import
sys
import
os
import
time
import
netifaces
from
vyos.config
import
Config
from
vyos.util
import
ConfigError
config_file
=
r'/etc/powerdns/recursor.conf'
# borrowed from: https://github.com/donjajo/py-world/blob/master/resolvconfReader.py, THX!
def
get_resolvers
(
file
):
resolvers
=
[]
try
:
with
open
(
file
,
'r'
)
as
resolvconf
:
for
line
in
resolvconf
.
readlines
():
line
=
line
.
split
(
'#'
,
1
)[
0
];
line
=
line
.
rstrip
();
if
'nameserver'
in
line
:
resolvers
.
append
(
line
.
split
()[
1
])
return
resolvers
except
IOError
:
return
[]
def
get_config
():
dns
=
{}
conf
=
Config
()
conf
.
set_level
(
'service dns forwarding'
)
if
not
conf
.
exists
(
''
):
return
dns
if
conf
.
exists
(
'cache-size'
):
cache
=
conf
.
return_value
(
'cache-size'
)
dns
.
setdefault
(
'cache-size'
,
cache
)
if
conf
.
exists
(
'dhcp'
):
dns
.
setdefault
(
'dhcp'
,
[])
interfaces
=
[]
interfaces
=
conf
.
return_values
(
'dhcp'
)
for
interface
in
interfaces
:
resolvers
=
get_resolvers
(
"/etc/resolv.conf.dhclient-new-{0}"
.
format
(
interface
))
if
len
(
resolvers
)
>
0
:
dhcp
=
{
"interface"
:
interface
,
"resolvers"
:
resolvers
}
dns
[
'dhcp'
]
.
append
(
dhcp
)
if
conf
.
exists
(
'domain'
):
dns
.
setdefault
(
'domain'
,
[])
for
node
in
conf
.
list_nodes
(
'domain'
):
server
=
conf
.
return_values
(
"domain {0} server"
.
format
(
node
))
domain
=
{
"name"
:
node
,
"server"
:
server
}
dns
[
'domain'
]
.
append
(
domain
)
if
conf
.
exists
(
'ignore-hosts-file'
):
dns
.
setdefault
(
'ignore-hosts-file'
,
True
)
if
conf
.
exists
(
'listen-on'
):
interfaces
=
[]
interfaces
=
conf
.
return_values
(
'listen-on'
)
dns
.
setdefault
(
'listen-on'
,
interfaces
)
if
conf
.
exists
(
'name-server'
):
nameservers
=
[]
nameservers
=
conf
.
return_values
(
'name-server'
)
dns
.
setdefault
(
'name-server'
,
nameservers
)
if
conf
.
exists
(
'system'
):
conf
.
set_level
(
'system'
)
nameservers
=
[]
nameservers
=
conf
.
return_values
(
'name-server'
)
if
len
(
nameservers
)
==
0
:
print
(
"DNS forwarding warning: No name-servers set under 'system name-server'
\n
"
)
else
:
dns
.
setdefault
(
'system-name-server'
,
nameservers
)
return
dns
def
verify
(
dns
):
if
len
(
dns
)
>
0
:
if
'listen-on'
not
in
dns
.
keys
():
raise
ConfigError
(
'Error: DNS forwarding requires a configured listen interface!'
)
for
interface
in
dns
[
'listen-on'
]:
try
:
netifaces
.
ifaddresses
(
interface
)[
netifaces
.
AF_INET
]
except
KeyError
as
e
:
raise
ConfigError
(
'Error: Interface {0} has no IP address assigned'
.
format
(
interface
))
if
'domain'
in
dns
.
keys
():
for
domain
in
dns
[
'domain'
]:
if
len
(
domain
[
'server'
])
==
0
:
raise
ConfigError
(
'Error: No server configured for domain {0}'
.
format
(
domain
[
'name'
]))
return
None
def
generate
(
dns
):
config_header
=
'### Autogenerated by vyos-config-dns-forwarding.py on {tm} ###
\n
'
.
format
(
tm
=
time
.
strftime
(
"%a,
%d
%b %Y %H:%M:%S"
,
time
.
localtime
()))
fwds
=
[]
fwds_src
=
[]
# write new configuration file
f
=
open
(
config_file
,
'w'
)
f
.
write
(
config_header
)
f
.
write
(
'daemon=yes
\n
'
)
f
.
write
(
'threads=1
\n
'
)
f
.
write
(
'allow-from=0.0.0.0/0
\n
'
)
f
.
write
(
'log-common-errors=yes
\n
'
)
if
'listen-on'
in
dns
.
keys
():
listen4
=
[]
listen6
=
[]
for
interface
in
dns
[
'listen-on'
]:
addrs
=
netifaces
.
ifaddresses
(
interface
)
for
ip4
in
addrs
[
netifaces
.
AF_INET
]:
listen4
.
append
(
ip4
[
'addr'
])
for
ip6
in
addrs
[
netifaces
.
AF_INET6
]:
listen6
.
append
(
ip6
[
'addr'
])
# build local-address string, example:
# local-address=172.16.37.240, 127.0.0.1, 172.16.254.35, 172.16.77.1, 2001:DB8::1:25, ::1
f
.
write
(
'local-address='
+
', '
.
join
(
listen4
)
+
', '
+
', '
.
join
(
listen6
)
+
'
\n
'
)
if
'cache-size'
in
dns
.
keys
():
f
.
write
(
"max-cache-entries={0}
\n
"
.
format
(
dns
[
'cache-size'
]))
if
'dhcp'
in
dns
.
keys
():
for
dhcp
in
dns
[
'dhcp'
]:
fwds_src
.
append
(
'DHCP: {0} ({1})'
.
format
(
dhcp
[
'interface'
],
', '
.
join
(
str
(
ns
)
for
ns
in
dhcp
[
'resolvers'
])))
fwds
.
append
(
', '
.
join
(
str
(
ns
)
for
ns
in
dhcp
[
'resolvers'
]))
if
'domain'
in
dns
.
keys
():
zones
=
[]
for
domain
in
dns
[
'domain'
]:
zones
.
append
(
'{0}={1}'
.
format
(
domain
[
'name'
],
';'
.
join
(
str
(
ns
)
for
ns
in
domain
[
'server'
])))
f
.
write
(
'forward-zones='
+
', '
.
join
(
zones
)
+
'
\n
'
)
if
'ignore-hosts-file'
in
dns
.
keys
():
f
.
write
(
"export-etc-hosts=no
\n
"
)
else
:
f
.
write
(
"export-etc-hosts=yes
\n
"
)
if
'name-server'
in
dns
.
keys
():
fwds_src
.
append
(
'statically configured: {0}'
.
format
(
', '
.
join
(
str
(
ns
)
for
ns
in
dns
[
'name-server'
])))
fwds
.
append
(
', '
.
join
(
str
(
ns
)
for
ns
in
dns
[
'name-server'
]))
if
'system-name-server'
in
dns
.
keys
():
fwds_src
.
append
(
'system: {0}'
.
format
(
', '
.
join
(
str
(
ns
)
for
ns
in
dns
[
'system-name-server'
])))
fwds
.
append
(
', '
.
join
(
str
(
ns
)
for
ns
in
dns
[
'system-name-server'
]))
if
len
(
fwds
)
>
0
:
f
.
write
(
'
\n
'
)
f
.
write
(
'# '
+
'
\n
# '
.
join
(
fwds_src
)
+
'
\n
'
)
f
.
write
(
'forward-zones-recurse=.='
+
'; '
.
join
(
fwds
)
+
'
\n
'
)
f
.
close
()
return
None
def
apply
(
dns
):
if
len
(
dns
)
==
0
:
cmd
=
"sudo systemctl stop pdns-recursor"
else
:
cmd
=
"sudo systemctl restart pdns-recursor"
os
.
system
(
cmd
)
return
None
if
__name__
==
'__main__'
:
try
:
c
=
get_config
()
verify
(
c
)
generate
(
c
)
apply
(
c
)
except
ConfigError
as
e
:
print
(
e
)
sys
.
exit
(
1
)
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Sat, Sep 26, 12:32 PM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4281779
Default Alt Text
vyos-config-dns-forwarding.py (6 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment