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

Compare commits

..

2 Commits

Author SHA1 Message Date
depfu[bot]
af967e2edf gems: update rubocop to version 1.63.5 2024-05-16 15:39:06 +00:00
cn
c9caa5ba66 project: disable Depfu for Renovate since PR creation fails 2024-05-16 17:28:30 +02:00
16 changed files with 41 additions and 153 deletions

View File

@@ -1,13 +0,0 @@
---
version: 2
updates:
- package-ecosystem: "bundler"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "gems"
labels: ["dependabot"]
open-pull-requests-limit: 10
pull-request-branch-name:
separator: "-"

View File

@@ -15,18 +15,6 @@
commitMessageTopic: "{{depName}}",
commitMessageExtra: "to {{#if isSingleVersion}}v{{{newVersion}}}{{else}}{{{newValue}}}{{/if}}",
packageRules: [
// Ruby dependencies are managed by depfu
{
matchManagers: ["bundler"],
enabled: false,
},
// Only quarter update since noisy/stable tools
{
matchPackageNames: [
"aquasecurity/trivy",
],
schedule: ["* 0-8 1 */3 *"],
},
// Commit message formats
{
matchDatasources: ["docker"],
@@ -40,7 +28,7 @@
customManagers: [
{
customType: "regex",
managerFilePatterns: ["/.rb$/", "/^Rakefile$/"],
fileMatch: ["\.rb$", "^Rakefile$"],
matchStrings: [
"renovate: datasource=(?<datasource>.*?) depName=(?<depName>.*?)\\s.*_version = '(?<currentValue>.*)'\\s"
]

View File

@@ -11,7 +11,7 @@ jobs:
release-dockerimage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
- name: Extract dyndnsd version from tag name
run: |
@@ -42,7 +42,7 @@ jobs:
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push Docker image for dyndnsd ${{ env.DYNDNSD_VERSION }}
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
context: docker
build-args: |

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
plugins:
require:
- rubocop-rake
- rubocop-rspec

View File

@@ -1,19 +1,6 @@
# Changelog
## 3.12.0 (December 4th, 2025)
IMPROVEMENTS:
- regex instead of hosts list can be used for hostname ownership
## 3.11.0 (October 2nd, 2025)
IMPROVEMENTS:
- 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:

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
dyndnsd.rb is licensed under the Apache License, Version 2.0. See LICENSE for more information.

View File

@@ -3,9 +3,11 @@
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'rubocop/rake_task'
require 'bundler/audit/task'
RSpec::Core::RakeTask.new(:spec)
RuboCop::RakeTask.new
Bundler::Audit::Task.new
desc 'Run experimental solargraph type checker'
task :solargraph do
@@ -13,10 +15,10 @@ task :solargraph do
end
# renovate: datasource=github-tags depName=hadolint/hadolint
hadolint_version = 'v2.14.0'
hadolint_version = 'v2.12.0'
# renovate: datasource=github-tags depName=aquasecurity/trivy
trivy_version = 'v0.67.0'
trivy_version = 'v0.50.4'
namespace :docker do
ci_image = 'cmur2/dyndnsd:ci'
@@ -48,7 +50,7 @@ namespace :docker do
chmod a+w e2e/db.json
SCRIPT
sh "docker run -d --name=dyndnsd-ci -v $(pwd)/e2e:/etc/dyndnsd -p 8080:8080 -p 5353:5353 #{ci_image}"
sh 'sleep 5'
sh 'sleep 1'
puts '----------------------------------------'
# `dig` needs `sudo apt-get install -y -q dnsutils`
sh <<~SCRIPT
@@ -66,14 +68,7 @@ namespace :docker do
end
end
namespace :bundle do
desc 'Check for vulnerabilities with bundler-audit'
task :audit do
sh 'bundler-audit check --ignore GHSA-vvfq-8hwr-qm4m' if !RUBY_VERSION.start_with?('3.0')
end
end
task default: [:rubocop, :spec, 'bundle:audit']
task default: [:rubocop, :spec, 'bundle:audit', :solargraph]
desc 'Run all tasks desired for CI'
task ci: [:default, 'docker:lint', :build, 'docker:build', 'docker:e2e']

View File

@@ -1,11 +1,11 @@
FROM alpine:3.23.0
FROM alpine:3.19.1
EXPOSE 5353 8080
ARG DYNDNSD_VERSION
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 && \
gem install --no-document dyndnsd -v ${DYNDNSD_VERSION} && \
rm -rf /usr/lib/ruby/gems/*/cache/ && \

View File

@@ -1,11 +1,11 @@
FROM alpine:3.23.0
FROM alpine:3.19.1
EXPOSE 5353 8080
COPY pkg/dyndnsd-*.gem /tmp/dyndnsd.gem
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 && \
gem install --no-document /tmp/dyndnsd.gem && \
rm -rf /usr/lib/ruby/gems/*/cache/ && \

View File

@@ -27,25 +27,23 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 3.0'
s.add_dependency 'async', '~> 1.31.0'
s.add_dependency 'async-dns', '~> 1.3.0'
s.add_dependency 'base64', '~> 0.2.0' # needed for async
s.add_dependency 'logger', '>= 1.6', '< 1.8'
s.add_dependency 'metriks'
s.add_dependency 'opentelemetry-exporter-jaeger', '~> 0.22.0'
s.add_dependency 'opentelemetry-instrumentation-rack', '~> 0.22.0'
s.add_dependency 'opentelemetry-sdk', '~> 1.2.0'
s.add_dependency 'rack', '~> 3.0'
s.add_dependency 'rackup', '~> 2'
s.add_dependency 'webrick', '>= 1.6.1'
s.add_runtime_dependency 'async', '~> 1.31.0'
s.add_runtime_dependency 'async-dns', '~> 1.3.0'
s.add_runtime_dependency 'metriks'
s.add_runtime_dependency 'opentelemetry-exporter-jaeger', '~> 0.22.0'
s.add_runtime_dependency 'opentelemetry-instrumentation-rack', '~> 0.22.0'
s.add_runtime_dependency 'opentelemetry-sdk', '~> 1.2.0'
s.add_runtime_dependency 'rack', '~> 3.0'
s.add_runtime_dependency 'rackup', '~> 2'
s.add_runtime_dependency 'webrick', '>= 1.6.1'
s.add_development_dependency 'bundler'
s.add_development_dependency 'bundler-audit', '~> 0.9.0'
s.add_development_dependency 'rack-test'
s.add_development_dependency 'rake'
s.add_development_dependency 'rspec'
s.add_development_dependency 'rubocop', '~> 1.81.1'
s.add_development_dependency 'rubocop-rake', '~> 0.7.1'
s.add_development_dependency 'rubocop-rspec', '~> 3.8.0'
s.add_development_dependency 'solargraph', '~> 0.55.0'
s.add_development_dependency 'rubocop', '~> 1.63.5'
s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
s.add_development_dependency 'rubocop-rspec', '~> 2.26.1'
s.add_development_dependency 'solargraph', '~> 0.50.0'
end

View File

@@ -138,7 +138,7 @@ module Dyndnsd
# @param params [Hash{String => String}]
# @return [Array<String>]
def extract_v4_and_v6_address(params)
return [] if !params['myip']
return [] if !(params['myip'])
begin
IPAddr.new(params['myip'], Socket::AF_INET)
IPAddr.new(params['myip6'], Socket::AF_INET6)
@@ -207,7 +207,7 @@ module Dyndnsd
params = Rack::Utils.parse_query(env['QUERY_STRING'])
# require hostname parameter
return [422, {'X-DynDNS-Response' => 'hostname_missing'}, []] if !params['hostname']
return [422, {'X-DynDNS-Response' => 'hostname_missing'}, []] if !(params['hostname'])
hostnames = params['hostname'].split(',')
@@ -218,22 +218,9 @@ module Dyndnsd
# we can trust this information since user was authorized by middleware
user = env['REMOTE_USER']
if @users[user].key?('regex')
pattern = @users[user].fetch('regex')
begin
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
# 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?
if params['offline'] == 'YES'
myips = []

View File

@@ -89,7 +89,7 @@ module Dyndnsd
# @return [Array{Array{Object}}]
def self.parse_endpoints(endpoint_list)
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 } }
.flatten(1)
end

View File

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

View File

@@ -18,10 +18,6 @@ describe Dyndnsd::Daemon do
},
'test2' => {
'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")
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
authorize 'test', 'secret'
@@ -140,10 +120,6 @@ describe Dyndnsd::Daemon do
get '/nic/update?hostname=foo.example.org,notmyhost.example.org'
expect(last_response).to be_ok
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
it 'updates a host on IP change' do