adassault 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/adassault/cli/dns/duzdu/add.rb +34 -0
- data/lib/adassault/cli/dns/duzdu/baseaction.rb +59 -0
- data/lib/adassault/cli/dns/duzdu/check.rb +33 -0
- data/lib/adassault/cli/dns/duzdu/delete.rb +33 -0
- data/lib/adassault/cli/dns/duzdu/get.rb +34 -0
- data/lib/adassault/cli/dns/duzdu/replace.rb +34 -0
- data/lib/adassault/cli/dns/duzdu.rb +19 -0
- data/lib/adassault/cli/dns.rb +19 -27
- data/lib/adassault/cli.rb +1 -0
- data/lib/adassault/dns/duzdu.rb +175 -0
- data/lib/adassault/dns.rb +1 -0
- data/lib/adassault/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1388914e53e2194919173dcbe9cc809e1fff39b3843f8768459343ac68812fa3
|
4
|
+
data.tar.gz: 9c81ba10c6f2fc8dc0858b2bea49e3b399515d4d471b2255e469a9430f386425
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aabce798d3bf5b4bd1831751ee0416852f2904b439781d1e74fd41a3793dba6c17152ba991b6d334bf6b4507f4e892389697c7a90b8da527a292992faf26472e
|
7
|
+
data.tar.gz: d754da4dcf1516025be52d5e49a594f04d117717c8f82058b12899332a651a01c177387aa43a4ff80e7fb1c852a614c2f4f6f787f516e7e2d79f8726502b20b8
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adassault/cli/dns/duzdu/baseaction'
|
4
|
+
|
5
|
+
module ADAssault
|
6
|
+
class CLI
|
7
|
+
module DNS
|
8
|
+
module DUZDU
|
9
|
+
# command: `ada dns duzdu add`
|
10
|
+
class Add < BaseAction
|
11
|
+
def run(args)
|
12
|
+
res = @duz.addv4(args[0], args[1])
|
13
|
+
@duz.display(res, self.class.command_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def description
|
18
|
+
'Add a DNS A record (IPv4) via dynamic updates'
|
19
|
+
end
|
20
|
+
|
21
|
+
def long_description
|
22
|
+
'<name>: DNS name, A record. The domain is automatically appended, e.g. test ➡️ test.example.org' \
|
23
|
+
"\n\n<ip>: IP address."
|
24
|
+
end
|
25
|
+
|
26
|
+
def arguments
|
27
|
+
%i[<name> <ip>]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# AD Assault lib
|
4
|
+
require 'adassault/dns'
|
5
|
+
# options / arguments parsing lib
|
6
|
+
require 'gli'
|
7
|
+
|
8
|
+
module ADAssault
|
9
|
+
class CLI
|
10
|
+
extend GLI::App
|
11
|
+
|
12
|
+
module DNS
|
13
|
+
module DUZDU
|
14
|
+
# stuff common to all duzdu's sub-commands
|
15
|
+
class BaseAction
|
16
|
+
def initialize(options)
|
17
|
+
parent_options = options.dig(GLI::Command::PARENT, GLI::Command::PARENT)
|
18
|
+
dns_opts = parent_options[:nameserver].nil? ? nil : { nameserver: [parent_options[:nameserver]] }
|
19
|
+
@duz = ADAssault::DNS::DUZDU.new(parent_options[:domain], dns_opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(_args)
|
23
|
+
raise NotImplementedError, 'Sub-class must implement this method'
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def command_name
|
28
|
+
name.split('::').last.downcase
|
29
|
+
end
|
30
|
+
|
31
|
+
def description
|
32
|
+
raise NotImplementedError, 'Sub-class must implement this method'
|
33
|
+
end
|
34
|
+
|
35
|
+
def long_description
|
36
|
+
raise NotImplementedError, 'Sub-class must implement this method'
|
37
|
+
end
|
38
|
+
|
39
|
+
def arguments
|
40
|
+
raise NotImplementedError, 'Sub-class must implement this method'
|
41
|
+
end
|
42
|
+
|
43
|
+
def register(parent_command)
|
44
|
+
parent_command.desc description
|
45
|
+
parent_command.long_desc long_description unless long_description.empty?
|
46
|
+
arguments.each { |argument| parent_command.arg argument } # won't register args if arguments is empty
|
47
|
+
parent_command.command command_name.to_sym do |cmd|
|
48
|
+
cmd.action do |_global_options, options, args|
|
49
|
+
action = new(options)
|
50
|
+
action.run(args)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adassault/cli/dns/duzdu/baseaction'
|
4
|
+
|
5
|
+
module ADAssault
|
6
|
+
class CLI
|
7
|
+
module DNS
|
8
|
+
module DUZDU
|
9
|
+
# command: `ada dns duzdu check`
|
10
|
+
class Check < BaseAction
|
11
|
+
def run(_args)
|
12
|
+
res = @duz.checkv4
|
13
|
+
@duz.display(res, self.class.command_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def description
|
18
|
+
'Check if unsecure dynamic updates are allowed (IPv4)'
|
19
|
+
end
|
20
|
+
|
21
|
+
def long_description
|
22
|
+
''
|
23
|
+
end
|
24
|
+
|
25
|
+
def arguments
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adassault/cli/dns/duzdu/baseaction'
|
4
|
+
|
5
|
+
module ADAssault
|
6
|
+
class CLI
|
7
|
+
module DNS
|
8
|
+
module DUZDU
|
9
|
+
# command: `ada dns duzdu delete`
|
10
|
+
class Delete < BaseAction
|
11
|
+
def run(args)
|
12
|
+
res = @duz.deletev4(args[0])
|
13
|
+
@duz.display(res, self.class.command_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def description
|
18
|
+
'Remove a DNS A record (IPv4) via dynamic updates'
|
19
|
+
end
|
20
|
+
|
21
|
+
def long_description
|
22
|
+
'<name>: DNS name, A record. The domain is automatically appended, e.g. test ➡️ test.example.org'
|
23
|
+
end
|
24
|
+
|
25
|
+
def arguments
|
26
|
+
%i[<name>]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adassault/cli/dns/duzdu/baseaction'
|
4
|
+
|
5
|
+
module ADAssault
|
6
|
+
class CLI
|
7
|
+
module DNS
|
8
|
+
module DUZDU
|
9
|
+
# command: `ada dns duzdu get`
|
10
|
+
class Get < BaseAction
|
11
|
+
def run(args)
|
12
|
+
name = args.first
|
13
|
+
res = @duz.getv4(name)
|
14
|
+
@duz.display_record(name, res)
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def description
|
19
|
+
'Get the value(s) of a DNS A record (IPv4) from the domain'
|
20
|
+
end
|
21
|
+
|
22
|
+
def long_description
|
23
|
+
'<name>: DNS name, A record. The domain is automatically appended, e.g. test ➡️ test.example.org'
|
24
|
+
end
|
25
|
+
|
26
|
+
def arguments
|
27
|
+
%i[<name>]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'adassault/cli/dns/duzdu/baseaction'
|
4
|
+
|
5
|
+
module ADAssault
|
6
|
+
class CLI
|
7
|
+
module DNS
|
8
|
+
module DUZDU
|
9
|
+
# command: `ada dns duzdu replace`
|
10
|
+
class Replace < BaseAction
|
11
|
+
def run(args)
|
12
|
+
res = @duz.replacev4(args[0], args[1])
|
13
|
+
@duz.display(res, self.class.command_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def description
|
18
|
+
'Change the value of an existing DNS A record (IPv4) via dynamic updates'
|
19
|
+
end
|
20
|
+
|
21
|
+
def long_description
|
22
|
+
'<name>: DNS name, A record. The domain is automatically appended, e.g. test ➡️ test.example.org' \
|
23
|
+
"\n\n<ip>: IP address."
|
24
|
+
end
|
25
|
+
|
26
|
+
def arguments
|
27
|
+
%i[<name> <ip>]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# AD Assault CLI: DUZDU sub-commands
|
4
|
+
require 'adassault/cli/dns/duzdu/add'
|
5
|
+
require 'adassault/cli/dns/duzdu/check'
|
6
|
+
require 'adassault/cli/dns/duzdu/delete'
|
7
|
+
require 'adassault/cli/dns/duzdu/get'
|
8
|
+
require 'adassault/cli/dns/duzdu/replace'
|
9
|
+
|
10
|
+
module ADAssault
|
11
|
+
class CLI
|
12
|
+
# command: `ada dns`
|
13
|
+
module DNS
|
14
|
+
# command: `ada dns duzdu`
|
15
|
+
module DUZDU
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/adassault/cli/dns.rb
CHANGED
@@ -1,47 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'adassault/dns'
|
3
|
+
require 'adassault/cli/dns/duzdu'
|
4
4
|
require 'gli'
|
5
5
|
|
6
6
|
module ADAssault
|
7
7
|
class CLI
|
8
8
|
extend GLI::App
|
9
9
|
|
10
|
-
|
10
|
+
# dns
|
11
11
|
# since 0.0.1
|
12
|
+
desc 'DNS related commands'
|
12
13
|
command :dns do |dns|
|
13
|
-
dns.desc '
|
14
|
+
dns.flag %i[d domain], desc: 'Active Directory domain.', type: String, required: true, arg_name: 'DOMAIN'
|
15
|
+
dns.flag %i[s nameserver name-server],
|
16
|
+
desc: 'The IP address of the domain DNS server. If not provided uses your system DNS.',
|
17
|
+
type: String, required: false, arg_name: 'IP_ADDRESS'
|
18
|
+
|
19
|
+
# dns find_dcs
|
14
20
|
# since 0.0.1
|
21
|
+
dns.desc 'Spot all domain controllers in a Microsoft Active Directory environment'
|
15
22
|
dns.command :find_dcs do |find_dcs|
|
16
|
-
find_dcs.flag %i[d domain], desc: 'Active Directory domain.', type: String, required: false
|
17
|
-
find_dcs.flag %i[s nameserver name-server],
|
18
|
-
desc: 'The IP address of the domain DNS server. If not provided uses your system DNS.',
|
19
|
-
type: String
|
20
23
|
find_dcs.action do |_global_options, options, _args|
|
21
|
-
|
22
|
-
|
24
|
+
parent_options = options[GLI::Command::PARENT]
|
25
|
+
dns_opts = parent_options[:nameserver].nil? ? nil : { nameserver: [parent_options[:nameserver]] }
|
26
|
+
dcd = ADAssault::DNS::FindDCs.new(parent_options[:domain], dns_opts)
|
23
27
|
dcd.display
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
dns
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
dns.desc 'TODO'
|
35
|
-
dns.command :entry_delete do |entry_delete|
|
36
|
-
entry_delete.action do |_global_options, _options, _args|
|
37
|
-
puts 'entry_delete'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
dns.desc 'TODO'
|
42
|
-
dns.command :entry_update do |entry_update|
|
43
|
-
entry_update.action do |_global_options, _options, _args|
|
44
|
-
puts 'entry_update'
|
31
|
+
# dns duzdu
|
32
|
+
# since 0.0.2
|
33
|
+
dns.desc 'DNS unsecure zone dynamic update (DUZDU)'
|
34
|
+
dns.command :duzdu do |duzdu|
|
35
|
+
%w[add check delete get replace].each do |sub_command|
|
36
|
+
DNS::DUZDU.const_get(sub_command.capitalize).register(duzdu)
|
45
37
|
end
|
46
38
|
end
|
47
39
|
end
|
data/lib/adassault/cli.rb
CHANGED
@@ -0,0 +1,175 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ipaddr'
|
4
|
+
require 'random/formatter'
|
5
|
+
|
6
|
+
require 'dnsruby'
|
7
|
+
require 'paint'
|
8
|
+
|
9
|
+
module ADAssault
|
10
|
+
module DNS
|
11
|
+
# **DNS unsecure zone dynamic update (DUZDU).**
|
12
|
+
#
|
13
|
+
# On a misconfigured MS DNS zone, one can abuse dynamic updates to perform MiTM attacks in a very stealth way.
|
14
|
+
#
|
15
|
+
# On a Windows server with the DNS role, the `DSPROPERTY_ZONE_ALLOW_UPDATE` property defines whether dynamic updates are allowed. See [Microsoft - MS-DNSP - 2.3.2.1.1 Property Id](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dnsp/3af63871-0cc4-4179-916c-5caade55a8f3).
|
16
|
+
# The possible values (`fAllowUpdate`) are (see [Microsoft - MS-DNSP - 2.2.5.2.4.1 DNS_RPC_ZONE_INFO_W2K](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dnsp/e8651544-0fbb-4038-8232-375ff2d8a55e)):
|
17
|
+
#
|
18
|
+
# - `0` (`ZONE_UPDATE_OFF`): No updates are allowed for the zone.
|
19
|
+
# - `1` (`ZONE_UPDATE_UNSECURE`): All updates (secure and unsecure) are allowed for the zone.
|
20
|
+
# - `2` (`ZONE_UPDATE_SECURE`): The zone only allows secure updates, that is, DNS packet MUST have a TSIG [RFC2845] present in the additional section.
|
21
|
+
#
|
22
|
+
# One can see the property when connected to the DNS server (near 100% of times on the domain controller), with the command: `dnscmd.exe /ZoneInfo <example: thm.local>` and the value of `update`.
|
23
|
+
# Another option with the GUI, is to launch `DNS Manager` on the Windows server, then unfold the tree until the DNS zone, right click on it, select `Properties`, on the `General` tab, see the value of the select fields named `Dynamic updates`.
|
24
|
+
# Of course it is also possible to check remotly by trying to create a record. (see {DUZDU#checkv4})
|
25
|
+
#
|
26
|
+
# References:
|
27
|
+
#
|
28
|
+
# - [[FR] ANSSI - Points de contrôle Active Directory - Zones DNS mal configurées (vuln_dnszone_bad_prop)](https://www.cert.ssi.gouv.fr/uploads/ad_checklist.html)
|
29
|
+
# - [[FR] ANSSI - Bulletin d'alerte du CERT-FR - Multiples vulnérabilités dans Microsoft DNS server - CERTFR-2021-ALE-005](https://www.cert.ssi.gouv.fr/alerte/CERTFR-2021-ALE-005/)
|
30
|
+
# - [[EN] RFC 2136 - Dynamic Updates in the Domain Name System (DNS UPDATE)](https://datatracker.ietf.org/doc/html/rfc2136)
|
31
|
+
# - [[EN] RFC 2845 - Secret Key Transaction Authentication for DNS (TSIG)](https://datatracker.ietf.org/doc/html/rfc2845)
|
32
|
+
# - [[EN] RFC 3007 - Secure Domain Name System (DNS) Dynamic Update](https://datatracker.ietf.org/doc/html/rfc3007)
|
33
|
+
# - [[EN] RFC 4033 - DNS Security Introduction and Requirements](https://datatracker.ietf.org/doc/html/rfc4033)
|
34
|
+
# - [[EN] RFC 4034 - Resource Records for the DNS Security Extensions](https://datatracker.ietf.org/doc/html/rfc4034)
|
35
|
+
# - [[EN] RFC 4035 - Protocol Modifications for the DNS Security Extensions](https://datatracker.ietf.org/doc/html/rfc4035)
|
36
|
+
# - [[EN] RFC 6895 - Domain Name System (DNS) IANA Considerations](https://datatracker.ietf.org/doc/html/rfc6895)
|
37
|
+
# - [[EN] RFC 8945 - Secret Key Transaction Authentication for DNS (TSIG)](https://datatracker.ietf.org/doc/html/rfc8945)
|
38
|
+
# @since 0.0.2
|
39
|
+
class DUZDU
|
40
|
+
# **Create the DUZDU object**
|
41
|
+
# @param ad_domain [String] the Active Directory domain to work on.
|
42
|
+
# @param dns_opts [Hash] options for the DNS resolver. See [Resolv::DNS.new](https://ruby-doc.org/3.3.0/stdlibs/resolv/Resolv/DNS.html#method-c-new).
|
43
|
+
# @option dns_opts [Array|String] :nameserver the DNS server to contact
|
44
|
+
# @example
|
45
|
+
# duz = ADAssault::DNS::DUZDU.new('THM.local', nameserver: ['10.10.30.209'])
|
46
|
+
def initialize(ad_domain, dns_opts = nil)
|
47
|
+
@ad_domain = ad_domain
|
48
|
+
@dns_opts = dns_opts
|
49
|
+
end
|
50
|
+
|
51
|
+
# **Change the value of an existing DNS A record (IPv4) via dynamic updates**
|
52
|
+
#
|
53
|
+
# It will remove and recreate the record.
|
54
|
+
#
|
55
|
+
# **Warning**: if several entries exist for the same record, they will all be replaced by the new value.
|
56
|
+
# @param name [String] DNS name, A record. The domain is automatically appended, e.g. `test` ➡️ `test.example.org`
|
57
|
+
# @param ip [String] IP address
|
58
|
+
# @return [TrueClass|FalseClass] `true` if the record was changed successfully
|
59
|
+
# @example
|
60
|
+
# duz.replacev4('noraj', '10.10.56.126') # => true
|
61
|
+
def replacev4(name, ip)
|
62
|
+
deletev4(name)
|
63
|
+
addv4(name, ip)
|
64
|
+
end
|
65
|
+
|
66
|
+
# **Add a DNS A record (IPv4) via dynamic updates**
|
67
|
+
#
|
68
|
+
# **Warning**: adding 2nd value the same name will result in two entries for the same record, not updating the name (for that use {replacev4}).
|
69
|
+
# @param name [String] DNS name, A record. The domain is automatically appended, e.g. `test` ➡️ `test.example.org`
|
70
|
+
# @param ip [String] IP address
|
71
|
+
# @return [TrueClass|FalseClass] `true` if the record was added successfully
|
72
|
+
# @example
|
73
|
+
# duz.addv4('noraj', '10.10.56.125') # => true
|
74
|
+
def addv4(name, ip)
|
75
|
+
update = Dnsruby::Update.new(@ad_domain)
|
76
|
+
update.add("#{name}.#{@ad_domain}.", 'A', 300, ip)
|
77
|
+
send_update(update)
|
78
|
+
end
|
79
|
+
|
80
|
+
# **Remove a DNS A record (IPv4) via dynamic updates**
|
81
|
+
#
|
82
|
+
# **Warning**: if several entries exist for the same record, they will all be deleted.
|
83
|
+
# @param name [String] DNS name, A record. The domain is automatically appended, e.g. `test` ➡️ `test.example.org`
|
84
|
+
# @return [TrueClass|FalseClass] `true` if the record was removed successfully
|
85
|
+
# @example
|
86
|
+
# duz.deletev4('noraj') # => true
|
87
|
+
def deletev4(name)
|
88
|
+
update = Dnsruby::Update.new(@ad_domain)
|
89
|
+
update.present("#{name}.#{@ad_domain}", 'A')
|
90
|
+
update.delete("#{name}.#{@ad_domain}", 'A')
|
91
|
+
send_update(update)
|
92
|
+
end
|
93
|
+
|
94
|
+
# rubocop:disable Metrics/AbcSize
|
95
|
+
|
96
|
+
# **Check if unsecure dynamic updates are allowed (IPv4)**
|
97
|
+
#
|
98
|
+
# It will try to create a random IPv4 record in the zone and remove it.
|
99
|
+
# @return [TrueClass|FalseClass] `true` means unsecure dynamic updates are enabled
|
100
|
+
# @example
|
101
|
+
# duz.checkv4 # => false
|
102
|
+
def checkv4
|
103
|
+
networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'].map { |x| IPAddr.new(x) }
|
104
|
+
network = networks.sample
|
105
|
+
name = Random.uuid_v4
|
106
|
+
ip = IPAddr.new(rand(network.to_range.begin.succ.to_i..network.to_range.end.to_i - 1), network.family)
|
107
|
+
created = addv4(name, ip)
|
108
|
+
# if created
|
109
|
+
# deletev4(name)
|
110
|
+
# true
|
111
|
+
# else
|
112
|
+
# false
|
113
|
+
# end
|
114
|
+
created ? deletev4(name) || true : false
|
115
|
+
end
|
116
|
+
# rubocop:enable Metrics/AbcSize
|
117
|
+
|
118
|
+
# **Get the value(s) of a DNS A record (IPv4)**
|
119
|
+
# @param name [String] DNS name, A record. The domain is automatically appended, e.g. `test` ➡️ `test.example.org`
|
120
|
+
# @return [Array<String>] the IP address(es) as string(s)
|
121
|
+
# @example
|
122
|
+
# duz.getv4('noraj') # => ["10.10.56.128", "10.10.56.126"]
|
123
|
+
def getv4(name)
|
124
|
+
Dnsruby::DNS.open(@dns_opts) do |dns|
|
125
|
+
ress = dns.getresources("#{name}.#{@ad_domain}", 'A')
|
126
|
+
ress.map { |x| x.address.to_s }
|
127
|
+
rescue Dnsruby::NXDomain # The requested domain does not exist
|
128
|
+
['']
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Display a CLI-friendly output showing if the executed method was successful or not
|
133
|
+
# @param success [TrueClass|FalseClass] result of the command
|
134
|
+
# @param cmd [String] name of the executed command
|
135
|
+
# @return [nil]
|
136
|
+
def display(success, cmd)
|
137
|
+
# allowed_methods = DUZDU.public_instance_methods(false) - [:display]
|
138
|
+
# success = allowed_methods.include?(cmd.to_sym) ? send(cmd) : nil
|
139
|
+
message = if success
|
140
|
+
Paint["✅ #{cmd} was executed successfully",
|
141
|
+
'green']
|
142
|
+
else
|
143
|
+
Paint["❌ #{cmd} was unsuccessful", 'red']
|
144
|
+
end
|
145
|
+
puts message
|
146
|
+
end
|
147
|
+
|
148
|
+
# Display a CLI-friendly output formating the DNS record with its FQDN and IP addresses.
|
149
|
+
# @param name [String] record name, e.g. the argument of {getv4}
|
150
|
+
# @param ips [Array<String>] list of IP addresses, e.g. the return value of {getv4}
|
151
|
+
# @return [nil]
|
152
|
+
def display_record(name, ips)
|
153
|
+
fqdn = "#{name}.#{@ad_domain}"
|
154
|
+
puts "#{Paint[fqdn, 'cyan']} - #{Paint[ips.join(', '), 'aquamarine']}"
|
155
|
+
end
|
156
|
+
|
157
|
+
protected
|
158
|
+
|
159
|
+
# **Send a DNS update request via dynamic updates**
|
160
|
+
# @param update [Dnsruby::Update]
|
161
|
+
# @return [TrueClass|FalseClass] `true` if the update succeeded
|
162
|
+
# @example see {addv4} and {deletev4}
|
163
|
+
def send_update(update)
|
164
|
+
res = Dnsruby::Resolver.new(@dns_opts)
|
165
|
+
begin
|
166
|
+
res.send_message(update)
|
167
|
+
true
|
168
|
+
rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout => e
|
169
|
+
puts "Update failed: #{e}"
|
170
|
+
false
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/lib/adassault/dns.rb
CHANGED
data/lib/adassault/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adassault
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre ZANNI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dnsruby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.72'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.72.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.72'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.72.1
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: gli
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +73,15 @@ files:
|
|
53
73
|
- lib/adassault.rb
|
54
74
|
- lib/adassault/cli.rb
|
55
75
|
- lib/adassault/cli/dns.rb
|
76
|
+
- lib/adassault/cli/dns/duzdu.rb
|
77
|
+
- lib/adassault/cli/dns/duzdu/add.rb
|
78
|
+
- lib/adassault/cli/dns/duzdu/baseaction.rb
|
79
|
+
- lib/adassault/cli/dns/duzdu/check.rb
|
80
|
+
- lib/adassault/cli/dns/duzdu/delete.rb
|
81
|
+
- lib/adassault/cli/dns/duzdu/get.rb
|
82
|
+
- lib/adassault/cli/dns/duzdu/replace.rb
|
56
83
|
- lib/adassault/dns.rb
|
84
|
+
- lib/adassault/dns/duzdu.rb
|
57
85
|
- lib/adassault/dns/find_dcs.rb
|
58
86
|
- lib/adassault/version.rb
|
59
87
|
homepage: https://noraj.github.io/adassault/
|