From 741690baca90ae043f7128f5bd387a521d7aeeda Mon Sep 17 00:00:00 2001 From: Arne Schauf Date: Sun, 29 Sep 2013 22:07:33 +0200 Subject: [PATCH 1/4] how to configure your router --- .../main/templates/main/generate_secret.html | 22 ++++--- .../includes/tabbed_router_configuration.html | 61 +++++++++++++++++++ 2 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 nsupdate/main/templates/main/includes/tabbed_router_configuration.html diff --git a/nsupdate/main/templates/main/generate_secret.html b/nsupdate/main/templates/main/generate_secret.html index 876f272..4d0e65f 100644 --- a/nsupdate/main/templates/main/generate_secret.html +++ b/nsupdate/main/templates/main/generate_secret.html @@ -2,12 +2,20 @@ {% load bootstrap %} {% block content %} - -
-

Host Secret Generated back to overview

-

New secret generated for you. We store it hashed, so save it now, or you have to generate a new one again.

-

secret: {{ update_secret }}

+
+
+
+

Host Secret Generated
+ back to overview

+

New secret generated for you. We store it hashed, so save it now, or you have to generate a new one again. Everytime you visit this page a new secret will be generated and the old one becomes invalid.

+

Secret: {{ update_secret }}

+
- - +
+
+

How to configure your router?

+ {% include "main/includes/tabbed_router_configuration.html" with host=object %} +
+
+
{% endblock %} diff --git a/nsupdate/main/templates/main/includes/tabbed_router_configuration.html b/nsupdate/main/templates/main/includes/tabbed_router_configuration.html new file mode 100644 index 0000000..851072b --- /dev/null +++ b/nsupdate/main/templates/main/includes/tabbed_router_configuration.html @@ -0,0 +1,61 @@ + + +
+
+

Generic configuration hints

+
+ Your router/script needs to call the following url for IPv4-Updates: +
+ http://{{ host.get_fqdn|default:"<your fqdn>" }}:{{ update_secret|default:"<your secret>" }}@nsupdate.info/nic/update +
+ for IPv6-Updates: +
+ http://{{ host.get_fqdn|default:"<your fqdn>" }}:{{ update_secret|default:"<your secret>" }}@ipv6.nsupdate.info/nic/update +
+ The IPs will be determined automatically. +
+ Briefly your router/script has to do the following steps: +
    +
  • visit http://(ipv6.)nsupdate.info/nic/update
  • +
  • Do HTTP BasicAuth with: +
      +
    • Username: {{ host.get_fqdn|default:"<your fqdn>" }}
    • +
    • Password: {{ update_secret|default:"<your secret>" }}
    • +
    +
  • +
  • The response will look like this: +
      +
    • "good <your fqdn>" (new IP accepted)
    • +
    • "nochg <your fqdn>" (IP accepted, but did not change since last update)
    • +
    • redirect (Code 401) (Incorrect or no authentication data)
    • +
    +
+
+
+

Fritz!Box 7390 (and maybe others):

+
+
Go to:
+
+ Internet + Permit Access + Dynamic DNS +
+
Enter the following data
+ + + + + + + +
SettingValue
Dynamic DNS providerCustom
Update-URLhttp://nsupdate.info/nic/update
Domain Name{{ host.get_fqdn|default:"<your fqdn>" }}
User name{{ host.get_fqdn|default:"<your fqdn>" }}
Password{{ update_secret|default:"<your secret>" }}
+
For IPv6
+ Set Update-URL to the following (two links, separated by space) +
+ http://nsupdate.info/nic/update http://ipv6.nsupdate.info/nic/update +
+
+
From 77d82c68e3d393cd8eb784500116c9b4f046c761 Mon Sep 17 00:00:00 2001 From: Arne Schauf Date: Sun, 29 Sep 2013 22:32:29 +0200 Subject: [PATCH 2/4] more help --- .../includes/tabbed_router_configuration.html | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/nsupdate/main/templates/main/includes/tabbed_router_configuration.html b/nsupdate/main/templates/main/includes/tabbed_router_configuration.html index 851072b..a3c2520 100644 --- a/nsupdate/main/templates/main/includes/tabbed_router_configuration.html +++ b/nsupdate/main/templates/main/includes/tabbed_router_configuration.html @@ -9,17 +9,18 @@
Your router/script needs to call the following url for IPv4-Updates:
- http://{{ host.get_fqdn|default:"<your fqdn>" }}:{{ update_secret|default:"<your secret>" }}@nsupdate.info/nic/update + http://{{ host.get_fqdn|default:"<your fqdn>" }}:{{ update_secret|default:"<your secret>" }}@ipv4.nsupdate.info/nic/update
- for IPv6-Updates: + For IPv6-Updates:
- http://{{ host.get_fqdn|default:"<your fqdn>" }}:{{ update_secret|default:"<your secret>" }}@ipv6.nsupdate.info/nic/update + http://{{ host.get_fqdn|default:'<your fqdn>' }}:{{ update_secret|default:'<your secret>' }}@ipv6.nsupdate.info/nic/update
The IPs will be determined automatically.
Briefly your router/script has to do the following steps:
    -
  • visit http://(ipv6.)nsupdate.info/nic/update
  • +
  • visit http://ipv4.nsupdate.info/nic/update (to update A (IPv4) record)
  • +
  • visit http://ipv6.nsupdate.info/nic/update (to update AAAA (IPv6) record)
  • Do HTTP BasicAuth with:
    • Username: {{ host.get_fqdn|default:"<your fqdn>" }}
    • @@ -28,9 +29,9 @@
    • The response will look like this:
        -
      • "good <your fqdn>" (new IP accepted)
      • -
      • "nochg <your fqdn>" (IP accepted, but did not change since last update)
      • -
      • redirect (Code 401) (Incorrect or no authentication data)
      • +
      • "good <your fqdn>" new IP accepted
      • +
      • "nochg <your fqdn>" IP accepted, but did not change since last update
      • +
      • Code 401: Authorization Required Incorrect or no authentication data
@@ -52,10 +53,10 @@ User name{{ host.get_fqdn|default:"<your fqdn>" }} Password{{ update_secret|default:"<your secret>" }} -
For IPv6
+
If you also have IPv6 (Dual Stack)
Set Update-URL to the following (two links, separated by space)
- http://nsupdate.info/nic/update http://ipv6.nsupdate.info/nic/update + http://ipv4.nsupdate.info/nic/update http://ipv6.nsupdate.info/nic/update
From df971fe8e9a9122935fa3c66be966010cdf198c5 Mon Sep 17 00:00:00 2001 From: Arne Schauf Date: Sun, 29 Sep 2013 22:48:09 +0200 Subject: [PATCH 3/4] more fields --- ...er_ip__add_field_domain_nameserver_upda.py | 99 +++++++++++++++++++ nsupdate/main/models.py | 3 + 2 files changed, 102 insertions(+) create mode 100644 nsupdate/main/migrations/0010_auto__add_field_domain_nameserver_ip__add_field_domain_nameserver_upda.py diff --git a/nsupdate/main/migrations/0010_auto__add_field_domain_nameserver_ip__add_field_domain_nameserver_upda.py b/nsupdate/main/migrations/0010_auto__add_field_domain_nameserver_ip__add_field_domain_nameserver_upda.py new file mode 100644 index 0000000..72e63dd --- /dev/null +++ b/nsupdate/main/migrations/0010_auto__add_field_domain_nameserver_ip__add_field_domain_nameserver_upda.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Domain.nameserver_ip' + db.add_column(u'main_domain', 'nameserver_ip', + self.gf('django.db.models.fields.IPAddressField')(default='85.10.192.104', max_length=15), + keep_default=False) + + # Adding field 'Domain.nameserver_update_key' + db.add_column(u'main_domain', 'nameserver_update_key', + self.gf('django.db.models.fields.CharField')(default='YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYQ==', max_length=256), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Domain.nameserver_ip' + db.delete_column(u'main_domain', 'nameserver_ip') + + # Deleting field 'Domain.nameserver_update_key' + db.delete_column(u'main_domain', 'nameserver_update_key') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'main.blacklisteddomain': { + 'Meta': {'object_name': 'BlacklistedDomain'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'domain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + u'main.domain': { + 'Meta': {'object_name': 'Domain'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'domain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'nameserver_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}), + 'nameserver_update_key': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + u'main.host': { + 'Meta': {'unique_together': "(('subdomain', 'domain'),)", 'object_name': 'Host'}, + 'comment': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts'", 'to': u"orm['auth.User']"}), + 'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['main.Domain']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_api_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'subdomain': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'update_secret': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + } + } + + complete_apps = ['main'] \ No newline at end of file diff --git a/nsupdate/main/models.py b/nsupdate/main/models.py index 25e80b9..ab24c7a 100644 --- a/nsupdate/main/models.py +++ b/nsupdate/main/models.py @@ -34,6 +34,9 @@ def domain_blacklist_validator(value): class Domain(models.Model): domain = models.CharField(max_length=256, unique=True) + nameserver_ip = models.IPAddressField(max_length=256, + help_text="An IP where the nsupdates for this domain will be sent to") + nameserver_update_key = models.CharField(max_length=256) last_update = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) From fc278a28ddd500d0497ea7e357e352c29ee2aef6 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 29 Sep 2013 22:50:04 +0200 Subject: [PATCH 4/4] host view: fix typos, improve/clarify wording --- nsupdate/main/templates/main/host.html | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/nsupdate/main/templates/main/host.html b/nsupdate/main/templates/main/host.html index 7ec1891..fcb00d3 100644 --- a/nsupdate/main/templates/main/host.html +++ b/nsupdate/main/templates/main/host.html @@ -6,8 +6,8 @@
-

Edit Horst back to overview

-

You can only change the comment. If you want to have another domain name, you have to delete this host and create a new one.

+

Edit Host back to overview

+

You can only change the comment. If you want to have another host name, you have to delete this host and create a new one.

{% csrf_token %} {{ form|bootstrap }} @@ -16,15 +16,14 @@

Generate new secret

-

We store your update secret hashed, so if you forgot or lost it you have to create a new one.

+

We store your update secret salted and hashed, so if you forget or lose it you will have to create a new one.

Update Nameserver Entry

-

Usually you configure your router to follow the dyndns protocol. But if you know what you are doing, and you want to update it by hand, you can do it here.

- +

Usually you configure your router to follow the dyndns2 protocol. But if you know what you are doing, and you want to update it by hand, you can do it here.

@@ -41,17 +40,17 @@

General Information

-

We try to get your IP addresses through a trick. We host two fake images on a IPv4 and IPv6 domain and we can associate those with your session. If we find an IP address, we will update this information accordingly. This allows us to get your IPv4 address even when you are using your IPv6 and vice versa.

- your IPv4: {{ request.session.ipv4 }}
- your IPv6: {{ request.session.ipv6 }} +

We try to get your IP addresses through a trick. We host two fake images on a IPv4-only and a IPv6-only host and we can associate those with your session. + If we find an IP address, we will update this information accordingly. This allows us to get your IPv4 address even when you are using IPv6 and vice versa.

+ Your IPv4: {{ request.session.ipv4 }}
+ Your IPv6: {{ request.session.ipv6 }}

Host Information

-

This information comes directly from the name server and shows the current IPs set for your domain.

+

This information comes directly from the name server and shows the current IPs set for your host.

Host IPv4: {{ host.getIPv4 }}
Host IPv6: {{ host.getIPv6 }}
- {% endblock %}