dyndnsd 2.3.1 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
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