1
0
mirror of https://github.com/cmur2/dyndnsd.git synced 2024-12-21 14:54:22 +01:00

Add "myip6" URL parameter to provide an IPv6 address in addition to an IPv4 one as "myip"

This commit is contained in:
cn 2016-12-07 14:16:57 +01:00
parent ae095c22b7
commit 4894015325
6 changed files with 71 additions and 22 deletions

View File

@ -120,6 +120,8 @@ The following rules apply:
* use any IP address provided via the X-Real-IP header e.g. when used behind HTTP reverse proxy such as nginx, or
* use any IP address used by the connecting HTTP client
If you want to provide an additional IPv6 address as myip6 parameter the myip parameter containing an IPv4 address has to be present, too! No automatism is applied then.
### SSL, multiple listen ports
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.

View File

@ -78,6 +78,21 @@ module Dyndnsd
return @responder.response_for_error(:host_forbidden) if not @users[user]['hosts'].include? hostname
end
myip = nil
if params.has_key?("myip6")
# require presence of myip parameter as valid IPAddr (v4) and valid myip6
return @responder.response_for_error(:host_forbidden) if not params["myip"]
begin
IPAddr.new(params["myip"], Socket::AF_INET)
IPAddr.new(params["myip6"], Socket::AF_INET6)
# myip will be an array
myip = [params["myip"], params["myip6"]]
rescue ArgumentError
return @responder.response_for_error(:host_forbidden)
end
else
# fallback value, always present
myip = env["REMOTE_ADDR"]
@ -98,6 +113,7 @@ module Dyndnsd
rescue ArgumentError
end
end
end
Metriks.meter('requests.valid').mark
Dyndnsd.logger.info "Request to update #{hostnames} to #{myip} for user #{user}"

View File

@ -18,12 +18,14 @@ module Dyndnsd
out << "@ IN SOA #{@dns} #{@email_addr} ( #{zone['serial']} 3h 5m 1w 1h )"
out << "@ IN NS #{@dns}"
out << ""
zone['hosts'].each do |hostname,ip|
zone['hosts'].each do |hostname,ips|
(ips.is_a?(Array) ? ips : [ips]).each do |ip|
ip = IPAddr.new(ip).native
type = ip.ipv6? ? "AAAA" : "A"
name = hostname.chomp('.' + @domain)
out << "#{name} IN #{type} #{ip}"
end
end
out << ""
out << @additional_zone_content
out << ""

View File

@ -13,7 +13,7 @@ module Dyndnsd
end
def response_for_changes(states, ip)
body = states.map { |state| "#{state} #{ip}" }.join("\n")
body = states.map { |state| "#{state} #{ip.is_a?(Array) ? ip.join(' ') : ip}" }.join("\n")
return [200, {"Content-Type" => "text/plain"}, [body]]
end
end

View File

@ -13,7 +13,7 @@ module Dyndnsd
end
def response_for_changes(states, ip)
body = states.map { |state| state == :good ? "Changed to #{ip}" : "No change needed for #{ip}" }.join("\n")
body = states.map { |state| state == :good ? "Changed to #{ip.is_a?(Array) ? ip.join(' ') : ip}" : "No change needed for #{ip.is_a?(Array) ? ip.join(' ') : ip}" }.join("\n")
return [200, {"Content-Type" => "text/plain"}, [body]]
end
end

View File

@ -170,8 +170,37 @@ describe Dyndnsd::Daemon do
it 'uses clients remote IP address from X-Real-IP header if behind proxy' do
authorize 'test', 'secret'
get '/nic/update?hostname=foo.example.org', '', 'HTTP_X_REAL_IP' => '10.0.0.1'
expect(last_response).to be_ok
expect(last_response.body).to eq('good 10.0.0.1')
get '/nic/update?hostname=foo.example.org', '', 'HTTP_X_REAL_IP' => '2001:db8::1'
expect(last_response).to be_ok
expect(last_response.body).to eq('good 2001:db8::1')
end
it 'supports an IPv4 and an IPv6 address in one request' do
authorize 'test', 'secret'
get '/nic/update?hostname=foo.example.org&myip=1.2.3.4&myip6=2001:db8::1'
expect(last_response).to be_ok
expect(last_response.body).to eq("good 1.2.3.4 2001:db8::1")
get '/nic/update?hostname=foo.example.org&myip=BROKENIP&myip6=2001:db8::1'
expect(last_response).to be_ok
expect(last_response.body).to eq('nohost')
get '/nic/update?hostname=foo.example.org&myip=1.2.3.4&myip6=BROKENIP'
expect(last_response).to be_ok
expect(last_response.body).to eq('nohost')
get '/nic/update?hostname=foo.example.org&myip6=2001:db8::10'
expect(last_response).to be_ok
expect(last_response.body).to eq('nohost')
get '/nic/update?hostname=foo.example.org&myip=1.2.3.40'
expect(last_response).to be_ok
expect(last_response.body).to eq('good 1.2.3.40')
end
end