dyndnsd 2.3.1 → 3.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bfdbe62ef8dcbfc69c8a62e0dd06a2ee5bcdddaf1acc3bbbc5ed238e5286e5f
4
- data.tar.gz: a61794c2d98d0aba28fc37ce5ebe7928f4455a2fda5ce945591715db3c85df97
3
+ metadata.gz: 6c42962fd7f8ba91a340791ff120aff65d5c309fb48f636ecafa7e797b4db080
4
+ data.tar.gz: d63fcb45a32507f06e238c517f5c5ca9944b0c235e03dc2ea8a8f7f02cdf6f53
5
5
  SHA512:
6
- metadata.gz: fbeeb01c67a5aeb4098b19d7eb91abaf532b24fc007dec60eff1a3dcba771aa9a1d648fa7041319f770eabc3461ea211c6818dd8c1fb15c9d5b201f5df9c014c
7
- data.tar.gz: 907c75c30d95843b0fa32544db157b67dba8921ba167e909e5aeb96133e9abe887a3a4709fa300b4437563bd2f0d558a03ebb18978f030beab043361d421dd6f
6
+ metadata.gz: 6d287f704fa72399ae818a41fe2b3d152bab9cf7171826189f0332a1f1514540f16374d2465bb502ebbbc2df5b2d64c5a6a21a17109272375ac17ff397a914e1
7
+ data.tar.gz: e26fb3814134509aee783362f91cae332899135684f1605cbbc4cc752d4c8f888bd8c4148744ab8a6c9f3e7722e2498fbf195b228e68e39e2d48b786b7621ad0
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.2 (December 20, 2020)
4
+
5
+ OTHER:
6
+
7
+ - fixes vulnerabilities in Docker image by using updated Alpine base image
8
+ - start using Github Actions CI for tests and drop Travis CI
9
+
10
+ ## 3.1.1 (October 3, 2020)
11
+
12
+ IMPROVEMENTS:
13
+
14
+ - Use webrick gem which contains fixes against [CVE-2020-25613](https://www.ruby-lang.org/en/news/2020/09/29/http-request-smuggling-cve-2020-25613/)
15
+
16
+ ## 3.1.0 (August 19, 2020)
17
+
18
+ IMPROVEMENTS:
19
+
20
+ - Add officially maintained [Docker image for dyndnsd](https://hub.docker.com/r/cmur2/dyndnsd)
21
+
22
+ ## 3.0.0 (July 29, 2020)
23
+
24
+ IMPROVEMENTS:
25
+
26
+ - Drop EOL Ruby 2.4 and lower support, now minimum version supported is Ruby 2.5
27
+
3
28
  ## 2.3.1 (July 27, 2020)
4
29
 
5
30
  IMPROVEMENTS:
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dyndnsd.rb
2
2
 
3
- [![Build Status](https://travis-ci.org/cmur2/dyndnsd.svg?branch=master)](https://travis-ci.org/cmur2/dyndnsd) [![Dependencies](https://badges.depfu.com/badges/4f25da8493f7a29f652ac892fbf9227b/overview.svg)](https://depfu.com/github/cmur2/dyndnsd)
3
+ ![ci](https://github.com/cmur2/dyndnsd/workflows/ci/badge.svg) [![Dependencies](https://badges.depfu.com/badges/4f25da8493f7a29f652ac892fbf9227b/overview.svg)](https://depfu.com/github/cmur2/dyndnsd)
4
4
 
5
5
  A small, lightweight and extensible DynDNS server written with Ruby and Rack.
6
6
 
@@ -64,7 +64,42 @@ users:
64
64
 
65
65
  Run dyndnsd.rb by:
66
66
 
67
- dyndnsd /path/to/config.yaml
67
+ ```bash
68
+ dyndnsd /path/to/config.yml
69
+ ```
70
+
71
+
72
+ ### Docker image
73
+
74
+ There is an officially maintained [Docker image for dyndnsd](https://hub.docker.com/r/cmur2/dyndnsd) available at Dockerhub. The goal is to have a minimal secured image available (currently based on Alpine) that works well for the `zone_transfer_server` updater use case.
75
+
76
+ Users can make extensions by deriving from the official Docker image or building their own.
77
+
78
+ The Docker image consumes the same configuration file in YAML format as the gem, inside the container it needs to be mounted/available as `/etc/dyndnsd/config.yml`. the following YAML should be used as a base and extended with user's settings:
79
+
80
+ ```yaml
81
+ host: "0.0.0.0"
82
+ port: 8080
83
+ # omit the logfile: option so logging to STDOUT will happen automatically
84
+ db: "/var/lib/dyndnsd/db.json"
85
+
86
+ # User's settings for updater and permissions follow here!
87
+ ```
88
+
89
+ more ports might be needed depending on if DNS zone transfer is needed
90
+
91
+ Run the Docker image exposing the DynDNS-API on host port 8080 via:
92
+
93
+ ```bash
94
+ docker run -d --name dyndnsd \
95
+ -p 8080:8080 \
96
+ -v /host/path/to/dyndnsd/config.yml:/etc/dyndnsd/config.yml \
97
+ -v /host/ptherpath/to/dyndnsd/datadir:/var/lib/dyndnsd \
98
+ cmur2/dyndnsd:vX.Y.Z
99
+ ```
100
+
101
+ *Note*: You may need to expose more then just port 8080 e.g. if you use the `zone_transfer_server` which can be done by appending additional `-p 5353:5353` flags to the `docker run` command.
102
+
68
103
 
69
104
 
70
105
  ## Using dyndnsd.rb with any nameserver via DNS zone transfers (AXFR)
@@ -187,9 +222,11 @@ If you want to provide an additional IPv6 address as myip6 parameter, the myip p
187
222
  Use a webserver as a proxy to handle SSL and/or multiple listen addresses and ports. DynDNS.com provides HTTP on port 80 and 8245 and HTTPS on port 443.
188
223
 
189
224
 
190
- ### Init scripts
225
+ ### Startup
226
+
227
+ There is a [Dockerfile](docs/Dockerfile) that can be used to build a Docker image for running dyndnsd.rb.
191
228
 
192
- The [Debian 6 init.d script](init.d/debian-6-dyndnsd) assumes that dyndnsd.rb is installed into the system ruby (no RVM support) and the config.yaml is at /opt/dyndnsd/config.yaml. Modify to your needs.
229
+ The [Debian 6 init.d script](docs/debian-6-init-dyndnsd) assumes that dyndnsd.rb is installed into the system ruby (no RVM support) and the config.yaml is at /opt/dyndnsd/config.yaml. Modify to your needs.
193
230
 
194
231
 
195
232
  ### Monitoring
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'date'
3
4
  require 'etc'
4
5
  require 'logger'
5
6
  require 'ipaddr'
@@ -80,7 +81,7 @@ module Dyndnsd
80
81
  end
81
82
 
82
83
  # @param env [Hash{String => String}]
83
- # @return [Array{Integer,Hash{String => String},Array{String}}]
84
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
84
85
  def call(env)
85
86
  return [422, {'X-DynDNS-Response' => 'method_forbidden'}, []] if env['REQUEST_METHOD'] != 'GET'
86
87
  return [422, {'X-DynDNS-Response' => 'not_found'}, []] if env['PATH_INFO'] != '/nic/update'
@@ -134,7 +135,7 @@ module Dyndnsd
134
135
  private
135
136
 
136
137
  # @param params [Hash{String => String}]
137
- # @return [Array{String}]
138
+ # @return [Array<String>]
138
139
  def extract_v4_and_v6_address(params)
139
140
  return [] if !(params['myip'])
140
141
  begin
@@ -148,7 +149,7 @@ module Dyndnsd
148
149
 
149
150
  # @param env [Hash{String => String}]
150
151
  # @param params [Hash{String => String}]
151
- # @return [Array{String}]
152
+ # @return [Array<String>]
152
153
  def extract_myips(env, params)
153
154
  # require presence of myip parameter as valid IPAddr (v4) and valid myip6
154
155
  return extract_v4_and_v6_address(params) if params.key?('myip6')
@@ -164,8 +165,8 @@ module Dyndnsd
164
165
  end
165
166
 
166
167
  # @param hostnames [String]
167
- # @param myips [Array{String}]
168
- # @return [Array{Symbol}]
168
+ # @param myips [Array<String>]
169
+ # @return [Array<Symbol>]
169
170
  def process_changes(hostnames, myips)
170
171
  changes = []
171
172
  Helper.span('process_changes') do |span|
@@ -200,7 +201,7 @@ module Dyndnsd
200
201
  end
201
202
 
202
203
  # @param env [Hash{String => String}]
203
- # @return [Array{Integer,Hash{String => String},Array{String}}]
204
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
204
205
  def handle_dyndns_request(env)
205
206
  params = Rack::Utils.parse_query(env['QUERY_STRING'])
206
207
 
@@ -245,7 +246,7 @@ module Dyndnsd
245
246
  if config['logfile']
246
247
  Dyndnsd.logger = Logger.new(config['logfile'])
247
248
  else
248
- Dyndnsd.logger = Logger.new(STDOUT)
249
+ Dyndnsd.logger = Logger.new($stdout)
249
250
  end
250
251
 
251
252
  Dyndnsd.logger.progname = 'dyndnsd'
@@ -27,7 +27,7 @@ module Dyndnsd
27
27
  ips.each do |ip|
28
28
  ip = IPAddr.new(ip).native
29
29
  type = ip.ipv6? ? 'AAAA' : 'A'
30
- name = hostname.chomp('.' + @domain)
30
+ name = hostname.chomp(".#{@domain}")
31
31
  out << "#{name} IN #{type} #{ip}"
32
32
  end
33
33
  end
@@ -60,7 +60,7 @@ module Dyndnsd
60
60
  message: e.message,
61
61
  stack: e.backtrace&.join("\n") || ''
62
62
  )
63
- raise
63
+ raise e
64
64
  ensure
65
65
  scope.close
66
66
  end
@@ -9,7 +9,7 @@ module Dyndnsd
9
9
  end
10
10
 
11
11
  # @param env [Hash{String => String}]
12
- # @return [Array{Integer,Hash{String => String},Array{String}}]
12
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
13
13
  def call(env)
14
14
  @app.call(env).tap do |status_code, headers, body|
15
15
  if headers.key?('X-DynDNS-Response')
@@ -24,30 +24,32 @@ module Dyndnsd
24
24
 
25
25
  # @param status_code [Integer]
26
26
  # @param headers [Hash{String => String}]
27
- # @param body [Array{String}]
28
- # @return [Array{Integer,Hash{String => String},Array{String}}]
27
+ # @param body [Array<String>]
28
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
29
29
  def decorate_dyndnsd_response(status_code, headers, body)
30
- if status_code == 200
30
+ case status_code
31
+ when 200
31
32
  [200, {'Content-Type' => 'text/plain'}, [get_success_body(body[0], body[1])]]
32
- elsif status_code == 422
33
+ when 422
33
34
  error_response_map[headers['X-DynDNS-Response']]
34
35
  end
35
36
  end
36
37
 
37
38
  # @param status_code [Integer]
38
39
  # @param headers [Hash{String => String}]
39
- # @param _body [Array{String}]
40
- # @return [Array{Integer,Hash{String => String},Array{String}}]
40
+ # @param _body [Array<String>]
41
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
41
42
  def decorate_other_response(status_code, headers, _body)
42
- if status_code == 400
43
+ case status_code
44
+ when 400
43
45
  [status_code, headers, ['Bad Request']]
44
- elsif status_code == 401
46
+ when 401
45
47
  [status_code, headers, ['badauth']]
46
48
  end
47
49
  end
48
50
 
49
- # @param changes [Array{Symbol}]
50
- # @param myips [Array{String}]
51
+ # @param changes [Array<Symbol>]
52
+ # @param myips [Array<String>]
51
53
  # @return [String]
52
54
  def get_success_body(changes, myips)
53
55
  changes.map { |change| "#{change} #{myips.join(' ')}" }.join("\n")
@@ -9,7 +9,7 @@ module Dyndnsd
9
9
  end
10
10
 
11
11
  # @param env [Hash{String => String}]
12
- # @return [Array{Integer,Hash{String => String},Array{String}}]
12
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
13
13
  def call(env)
14
14
  @app.call(env).tap do |status_code, headers, body|
15
15
  if headers.key?('X-DynDNS-Response')
@@ -24,30 +24,32 @@ module Dyndnsd
24
24
 
25
25
  # @param status_code [Integer]
26
26
  # @param headers [Hash{String => String}]
27
- # @param body [Array{String}]
28
- # @return [Array{Integer,Hash{String => String},Array{String}}]
27
+ # @param body [Array<String>]
28
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
29
29
  def decorate_dyndnsd_response(status_code, headers, body)
30
- if status_code == 200
30
+ case status_code
31
+ when 200
31
32
  [200, {'Content-Type' => 'text/plain'}, [get_success_body(body[0], body[1])]]
32
- elsif status_code == 422
33
+ when 422
33
34
  error_response_map[headers['X-DynDNS-Response']]
34
35
  end
35
36
  end
36
37
 
37
38
  # @param status_code [Integer]
38
39
  # @param headers [Hash{String => String}]
39
- # @param _body [Array{String}]
40
- # @return [Array{Integer,Hash{String => String},Array{String}}]
40
+ # @param _body [Array<String>]
41
+ # @return [Array{Integer,Hash{String => String},Array<String>}]
41
42
  def decorate_other_response(status_code, headers, _body)
42
- if status_code == 400
43
+ case status_code
44
+ when 400
43
45
  [status_code, headers, ['Bad Request']]
44
- elsif status_code == 401
46
+ when 401
45
47
  [status_code, headers, ['Unauthorized']]
46
48
  end
47
49
  end
48
50
 
49
- # @param changes [Array{Symbol}]
50
- # @param myips [Array{String}]
51
+ # @param changes [Array<Symbol>]
52
+ # @param myips [Array<String>]
51
53
  # @return [String]
52
54
  def get_success_body(changes, myips)
53
55
  changes.map { |change| change == :good ? "Changed to #{myips.join(' ')}" : "No change needed for #{myips.join(' ')}" }.join("\n")
@@ -18,7 +18,7 @@ module Dyndnsd
18
18
 
19
19
  @registry = options[:registry] || Metriks::Registry.default
20
20
  @interval = options[:interval] || 60
21
- @on_error = options[:on_error] || proc { |ex| }
21
+ @on_error = options[:on_error] || proc { |ex| } # default: ignore errors
22
22
  end
23
23
 
24
24
  # @return [void]
@@ -28,11 +28,9 @@ module Dyndnsd
28
28
  sleep @interval
29
29
 
30
30
  Thread.new do
31
- begin
32
- write
33
- rescue StandardError => e
34
- @on_error[e] rescue nil
35
- end
31
+ write
32
+ rescue StandardError => e
33
+ @on_error[e] rescue nil
36
34
  end
37
35
  end
38
36
  end
@@ -96,8 +94,8 @@ module Dyndnsd
96
94
  # @param file [String]
97
95
  # @param base_name [String]
98
96
  # @param metric [Object]
99
- # @param keys [Array{Symbol}]
100
- # @param snapshot_keys [Array{Symbol}]
97
+ # @param keys [Array<Symbol>]
98
+ # @param snapshot_keys [Array<Symbol>]
101
99
  # @return [void]
102
100
  def write_metric(file, base_name, metric, keys, snapshot_keys = [])
103
101
  time = Time.now.to_i
@@ -85,7 +85,7 @@ module Dyndnsd
85
85
 
86
86
  # converts into suitable parameter form for Async::DNS::Resolver or Async::DNS::Server
87
87
  #
88
- # @param endpoint_list [Array{String}]
88
+ # @param endpoint_list [Array<String>]
89
89
  # @return [Array{Array{Object}}]
90
90
  def self.parse_endpoints(endpoint_list)
91
91
  endpoint_list.map { |addr_string| addr_string.split('@') }
@@ -139,7 +139,7 @@ module Dyndnsd
139
139
 
140
140
  # @param name [String]
141
141
  # @param resource_class [Resolv::DNS::Resource]
142
- # @param transaction [Async::DNS::Transaction]
142
+ # Since solargraph cannot parse this: param transaction [Async::DNS::Transaction]
143
143
  # @return [void]
144
144
  def process(name, resource_class, transaction)
145
145
  if name != @domain || resource_class != Resolv::DNS::Resource::Generic::Type252_Class1
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dyndnsd
4
- VERSION = '2.3.1'
4
+ VERSION = '3.1.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyndnsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Nicolai
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-27 00:00:00.000000000 Z
11
+ date: 2020-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-dns
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.10.0
33
+ version: 1.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.10.0
40
+ version: 1.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: metriks
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.9.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: webrick
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 1.6.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 1.6.1
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: bundler
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -170,28 +184,14 @@ dependencies:
170
184
  requirements:
171
185
  - - "~>"
172
186
  - !ruby/object:Gem::Version
173
- version: 0.81.0
187
+ version: 1.6.1
174
188
  type: :development
175
189
  prerelease: false
176
190
  version_requirements: !ruby/object:Gem::Requirement
177
191
  requirements:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
- version: 0.81.0
181
- - !ruby/object:Gem::Dependency
182
- name: solargraph
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
194
+ version: 1.6.1
195
195
  description: A small, lightweight and extensible DynDNS server written with Ruby and
196
196
  Rack.
197
197
  email:
@@ -207,7 +207,6 @@ files:
207
207
  - LICENSE
208
208
  - README.md
209
209
  - exe/dyndnsd
210
- - init.d/debian-6-dyndnsd
211
210
  - lib/dyndnsd.rb
212
211
  - lib/dyndnsd/database.rb
213
212
  - lib/dyndnsd/generator/bind.rb
@@ -233,14 +232,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
233
232
  requirements:
234
233
  - - ">="
235
234
  - !ruby/object:Gem::Version
236
- version: '2.3'
235
+ version: '2.5'
237
236
  required_rubygems_version: !ruby/object:Gem::Requirement
238
237
  requirements:
239
238
  - - ">="
240
239
  - !ruby/object:Gem::Version
241
240
  version: '0'
242
241
  requirements: []
243
- rubygems_version: 3.1.2
242
+ rubygems_version: 3.1.4
244
243
  signing_key:
245
244
  specification_version: 4
246
245
  summary: dyndnsd.rb
@@ -1,43 +0,0 @@
1
- #! /bin/sh
2
- ### BEGIN INIT INFO
3
- # Provides: dyndnsd
4
- # Required-Start: $remote_fs $syslog
5
- # Required-Stop: $remote_fs $syslog
6
- # Default-Start: 2 3 4 5
7
- # Default-Stop: 0 1 6
8
- # Short-Description: Handle dyndnsd.rb gem
9
- ### END INIT INFO
10
-
11
- # using the system ruby's gem binaries directory
12
- DAEMON="/var/lib/gems/1.8/bin/dyndnsd"
13
-
14
- CONFIG_FILE="/opt/dyndnsd/config.yaml"
15
-
16
- DAEMON_OPTS="$CONFIG_FILE"
17
-
18
- test -x $DAEMON || exit 0
19
-
20
- . /lib/lsb/init-functions
21
-
22
- case "$1" in
23
- start)
24
- log_daemon_msg "Starting dyndnsd.rb" "dyndnsd"
25
- start-stop-daemon --start --quiet --oknodo --make-pidfile --pidfile "/var/run/dyndnsd.pid" --background --exec $DAEMON -- $DAEMON_OPTS
26
- log_end_msg $?
27
- ;;
28
- stop)
29
- log_daemon_msg "Stopping dyndnsd.rb" "dyndnsd"
30
- start-stop-daemon --stop --quiet --oknodo --pidfile "/var/run/dyndnsd.pid"
31
- log_end_msg $?
32
- ;;
33
- restart|force-reload)
34
- log_daemon_msg "Restarting dyndnsd.rb" "dyndnsd"
35
- start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile "/var/run/dyndsd.pid"
36
- start-stop-daemon --start --quiet --oknodo --make-pidfile --pidfile "/var/run/dyndnsd.pid" --background --exec $DAEMON -- $DAEMON_OPTS
37
- log_end_msg $?
38
- ;;
39
- *)
40
- log_action_msg "Usage: $0 {start|stop|restart|force-reload}"
41
- exit 2
42
- ;;
43
- esac