1
0
mirror of https://github.com/cmur2/dyndnsd.git synced 2025-12-14 23:48:08 +01:00

Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
4672c1e350 gems: update base64 requirement from ~> 0.2.0 to >= 0.2, < 0.4
Updates the requirements on [base64](https://github.com/ruby/base64) to permit the latest version.
- [Release notes](https://github.com/ruby/base64/releases)
- [Commits](https://github.com/ruby/base64/compare/v0.2.0...v0.3.0)

---
updated-dependencies:
- dependency-name: base64
  dependency-version: 0.3.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 12:17:05 +00:00
14 changed files with 25 additions and 98 deletions

View File

@@ -40,7 +40,7 @@
customManagers: [ customManagers: [
{ {
customType: "regex", customType: "regex",
managerFilePatterns: ["/.rb$/", "/^Rakefile$/"], fileMatch: ["\.rb$", "^Rakefile$"],
matchStrings: [ matchStrings: [
"renovate: datasource=(?<datasource>.*?) depName=(?<depName>.*?)\\s.*_version = '(?<currentValue>.*)'\\s" "renovate: datasource=(?<datasource>.*?) depName=(?<depName>.*?)\\s.*_version = '(?<currentValue>.*)'\\s"
] ]

View File

@@ -11,7 +11,7 @@ jobs:
release-dockerimage: release-dockerimage:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- name: Extract dyndnsd version from tag name - name: Extract dyndnsd version from tag name
run: | run: |

View File

@@ -18,12 +18,13 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
ruby-version: ruby-version:
- '3.0'
- '3.1' - '3.1'
- '3.2' - '3.2'
- '3.3' - '3.3'
- '3.4' - '3.4'
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- name: Set up Ruby ${{ matrix.ruby-version }} - name: Set up Ruby ${{ matrix.ruby-version }}
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
@@ -37,7 +38,7 @@ jobs:
actionlint: actionlint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- name: Check workflow files - name: Check workflow files
run: | run: |
echo "::add-matcher::.github/actionlint-matcher.json" echo "::add-matcher::.github/actionlint-matcher.json"
@@ -50,6 +51,6 @@ jobs:
image: ghcr.io/renovatebot/renovate image: ghcr.io/renovatebot/renovate
options: --user root options: --user root
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- name: Check Renovate config - name: Check Renovate config
run: renovate-config-validator --strict run: renovate-config-validator --strict

View File

@@ -1,9 +1,10 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
--- ---
name: vulnscan name: vulnscan
on: on:
schedule: schedule:
- cron: '7 4 1 * *' # monthly on first day's morning - cron: '7 4 * * 4' # weekly on thursday morning
workflow_dispatch: workflow_dispatch:
jobs: jobs:

View File

@@ -1,19 +1,12 @@
# Changelog # Changelog
## 3.12.0 (December 4th, 2025) ## 3.11.0
IMPROVEMENTS:
- regex instead of hosts list can be used for hostname ownership
## 3.11.0 (October 2nd, 2025)
IMPROVEMENTS: IMPROVEMENTS:
- add Ruby 3.4 support - add Ruby 3.4 support
- update base of Docker image to Alpine 3.22.1 (from 3.19.0 before)
## 3.10.0 (January 18th, 2024) ## 3.10.0
IMPROVEMENTS: IMPROVEMENTS:

View File

@@ -307,37 +307,6 @@ users:
``` ```
### Matching with a regular expression
Instead of relying on `hosts`, you can use `regex` to employ a regular expression, which is very useful for avoiding having to repeatedly edit the configuration file to register a new host name.
```yaml
host: "0.0.0.0"
port: 5354
username: "dyndnsd"
group: "dyndnsd"
db: "/dyndnsd/db.json"
debug: false
domain: "dyn.dc-air.home.arpa"
updater:
name: "command_with_bind_zone"
params:
zone_file: "/nsd/zones/static/dyn.dc-air.home.arpa.zone"
command: "doas service nsd reload"
ttl: "5m"
dns: "ns.dc-air.home.arpa."
email_addr: "admin.example.org"
users:
myuser:
password: "superhypermegas3kurepassword1234"
regex: '^[a-z][0-9]\.dyn\.dc\-air\.home\.arpa$'
```
However, when using `regex`, `hosts` is simply ignored if defined, so you must choose one or the other. Recommendation: use `regex` for scripts or programs and `hosts` for regular users.
**Note**: Please note that when dyndnsd evaluates the regular expression, the `Regexp::EXTENDED` and `Regexp::IGNORECASE` options are used.
## License ## License
dyndnsd.rb is licensed under the Apache License, Version 2.0. See LICENSE for more information. dyndnsd.rb is licensed under the Apache License, Version 2.0. See LICENSE for more information.

View File

@@ -13,10 +13,10 @@ task :solargraph do
end end
# renovate: datasource=github-tags depName=hadolint/hadolint # renovate: datasource=github-tags depName=hadolint/hadolint
hadolint_version = 'v2.14.0' hadolint_version = 'v2.12.0'
# renovate: datasource=github-tags depName=aquasecurity/trivy # renovate: datasource=github-tags depName=aquasecurity/trivy
trivy_version = 'v0.67.0' trivy_version = 'v0.61.0'
namespace :docker do namespace :docker do
ci_image = 'cmur2/dyndnsd:ci' ci_image = 'cmur2/dyndnsd:ci'

View File

@@ -1,11 +1,11 @@
FROM alpine:3.22.2 FROM alpine:3.21.3
EXPOSE 5353 8080 EXPOSE 5353 8080
ARG DYNDNSD_VERSION ARG DYNDNSD_VERSION
RUN apk --no-cache add openssl ca-certificates && \ RUN apk --no-cache add openssl ca-certificates && \
apk --no-cache add ruby ruby-webrick && \ apk --no-cache add ruby ruby-etc ruby-io-console ruby-json ruby-webrick && \
apk --no-cache add --virtual .build-deps linux-headers ruby-dev build-base tzdata && \ apk --no-cache add --virtual .build-deps linux-headers ruby-dev build-base tzdata && \
gem install --no-document dyndnsd -v ${DYNDNSD_VERSION} && \ gem install --no-document dyndnsd -v ${DYNDNSD_VERSION} && \
rm -rf /usr/lib/ruby/gems/*/cache/ && \ rm -rf /usr/lib/ruby/gems/*/cache/ && \

View File

@@ -1,11 +1,11 @@
FROM alpine:3.22.2 FROM alpine:3.21.3
EXPOSE 5353 8080 EXPOSE 5353 8080
COPY pkg/dyndnsd-*.gem /tmp/dyndnsd.gem COPY pkg/dyndnsd-*.gem /tmp/dyndnsd.gem
RUN apk --no-cache add openssl ca-certificates && \ RUN apk --no-cache add openssl ca-certificates && \
apk --no-cache add ruby ruby-webrick && \ apk --no-cache add ruby ruby-etc ruby-io-console ruby-json ruby-webrick && \
apk --no-cache add --virtual .build-deps linux-headers ruby-dev build-base tzdata && \ apk --no-cache add --virtual .build-deps linux-headers ruby-dev build-base tzdata && \
gem install --no-document /tmp/dyndnsd.gem && \ gem install --no-document /tmp/dyndnsd.gem && \
rm -rf /usr/lib/ruby/gems/*/cache/ && \ rm -rf /usr/lib/ruby/gems/*/cache/ && \

View File

@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
s.add_dependency 'async', '~> 1.31.0' s.add_dependency 'async', '~> 1.31.0'
s.add_dependency 'async-dns', '~> 1.3.0' s.add_dependency 'async-dns', '~> 1.3.0'
s.add_dependency 'base64', '~> 0.2.0' # needed for async s.add_dependency 'base64', '>= 0.2', '< 0.4' # needed for async
s.add_dependency 'logger', '>= 1.6', '< 1.8' s.add_dependency 'logger', '>= 1.6', '< 1.8'
s.add_dependency 'metriks' s.add_dependency 'metriks'
s.add_dependency 'opentelemetry-exporter-jaeger', '~> 0.22.0' s.add_dependency 'opentelemetry-exporter-jaeger', '~> 0.22.0'
@@ -44,8 +44,8 @@ Gem::Specification.new do |s|
s.add_development_dependency 'rack-test' s.add_development_dependency 'rack-test'
s.add_development_dependency 'rake' s.add_development_dependency 'rake'
s.add_development_dependency 'rspec' s.add_development_dependency 'rspec'
s.add_development_dependency 'rubocop', '~> 1.81.1' s.add_development_dependency 'rubocop', '~> 1.75.1'
s.add_development_dependency 'rubocop-rake', '~> 0.7.1' s.add_development_dependency 'rubocop-rake', '~> 0.7.1'
s.add_development_dependency 'rubocop-rspec', '~> 3.8.0' s.add_development_dependency 'rubocop-rspec', '~> 3.6.0'
s.add_development_dependency 'solargraph', '~> 0.55.0' s.add_development_dependency 'solargraph', '~> 0.49.0'
end end

View File

@@ -218,22 +218,9 @@ module Dyndnsd
# we can trust this information since user was authorized by middleware # we can trust this information since user was authorized by middleware
user = env['REMOTE_USER'] user = env['REMOTE_USER']
if @users[user].key?('regex') # check for hostnames that the user does not own
pattern = @users[user].fetch('regex') forbidden_hostnames = hostnames - @users[user].fetch('hosts', [])
begin return [422, {'X-DynDNS-Response' => 'host_forbidden'}, []] if forbidden_hostnames.any?
regex = Regexp.new(pattern, Regexp::IGNORECASE | Regexp::EXTENDED)
rescue RegexpError => e
Dyndnsd.logger.warn "Invalid regex pattern '#{pattern}': #{e.message}"
return [422, {'X-DynDNS-Response' => 'host_forbidden'}, []]
end
# check for hostnames that match the regex
matches = hostnames.any? { |str| regex.match?(str) }
return [422, {'X-DynDNS-Response' => 'host_forbidden'}, []] if !matches
else
# check for hostnames that the user does not own
forbidden_hostnames = hostnames - @users[user].fetch('hosts', [])
return [422, {'X-DynDNS-Response' => 'host_forbidden'}, []] if forbidden_hostnames.any?
end
if params['offline'] == 'YES' if params['offline'] == 'YES'
myips = [] myips = []

View File

@@ -89,7 +89,7 @@ module Dyndnsd
# @return [Array{Array{Object}}] # @return [Array{Array{Object}}]
def self.parse_endpoints(endpoint_list) def self.parse_endpoints(endpoint_list)
endpoint_list.map { |addr_string| addr_string.split('@') } endpoint_list.map { |addr_string| addr_string.split('@') }
.map { |addr_parts| [addr_parts[0], addr_parts[1]&.to_i || 53] } .map { |addr_parts| [addr_parts[0], addr_parts[1].to_i || 53] }
.map { |addr| [:tcp, :udp].map { |type| [type] + addr } } .map { |addr| [:tcp, :udp].map { |type| [type] + addr } }
.flatten(1) .flatten(1)
end end

View File

@@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module Dyndnsd module Dyndnsd
VERSION = '3.12.0' VERSION = '3.9.2'
end end

View File

@@ -18,10 +18,6 @@ describe Dyndnsd::Daemon do
}, },
'test2' => { 'test2' => {
'password' => 'ihavenohosts' 'password' => 'ihavenohosts'
},
'test3' => {
'password' => 'superhypermegas3kurepassword1234',
'regex' => '^[a-z0-9]+-test3\.example\.org$'
} }
} }
} }
@@ -78,22 +74,6 @@ describe Dyndnsd::Daemon do
expect(last_response.body).to eq("good 2001:db8::1\ngood 2001:db8::1") expect(last_response.body).to eq("good 2001:db8::1\ngood 2001:db8::1")
end end
it 'supports regex matches for hostnames' do
authorize 'test3', 'superhypermegas3kurepassword1234'
get '/nic/update?hostname=abc123-test3.example.org&myip=1.2.3.4'
expect(last_response).to be_ok
expect(last_response.body).to eq('good 1.2.3.4')
get '/nic/update?hostname=foo-test3.example.org,bar-test3.example.org&myip=2001:db8::1'
expect(last_response).to be_ok
expect(last_response.body).to eq("good 2001:db8::1\ngood 2001:db8::1")
get '/nic/update?hostname=abc123.example.org'
expect(last_response).to be_ok
expect(last_response.body).to eq('nohost')
end
it 'rejects request if one hostname is invalid' do it 'rejects request if one hostname is invalid' do
authorize 'test', 'secret' authorize 'test', 'secret'
@@ -140,10 +120,6 @@ describe Dyndnsd::Daemon do
get '/nic/update?hostname=foo.example.org,notmyhost.example.org' get '/nic/update?hostname=foo.example.org,notmyhost.example.org'
expect(last_response).to be_ok expect(last_response).to be_ok
expect(last_response.body).to eq('nohost') expect(last_response.body).to eq('nohost')
get '/nic/update?hostname=abc123-test3.example.org'
expect(last_response).to be_ok
expect(last_response.body).to eq('nohost')
end end
it 'updates a host on IP change' do it 'updates a host on IP change' do