├── .dockerignore ├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ └── check.yml ├── .gitignore ├── Dockerfile ├── Makefile ├── README.md ├── bin ├── mkcountries ├── mkgdns ├── mkgeo ├── mksshfp ├── sumlogs └── update ├── dnsconfig.js ├── gdns └── .gitkeep ├── include └── .gitkeep ├── json └── .gitkeep ├── lib └── countries.xml ├── origins └── .gitkeep ├── requests └── nominatim.openstreetmap.yml └── src ├── ideditor.js ├── ipv4.json ├── ipv6.json ├── nominatim.openstreetmap.yml ├── opengeodata.js ├── openstreetmap-mg.js ├── openstreetmap-nz.js ├── openstreetmap-town.js ├── openstreetmap-uk.js ├── openstreetmap-za.js ├── openstreetmap.js ├── osm-li.js ├── osm-wiki.js ├── osm2pgsql.js ├── osmfoundation.js ├── ptr_equinix_ams_ipv4.js ├── ptr_equinix_ams_ipv6.js ├── ptr_equinix_dub_ipv4.js ├── ptr_equinix_dub_ipv6.js ├── ptr_he_ams_ipv4.js ├── ptr_he_ams_ipv6.js ├── ptr_he_dub_ipv4.js ├── ptr_he_dub_ipv6.js ├── stateofthemap-eu.js ├── stateofthemap.js └── switch2osm.js /.dockerignore: -------------------------------------------------------------------------------- 1 | data/* 2 | json/* 3 | kml/* 4 | origins/* 5 | pingdom.yml 6 | statuscake.yml 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_trailing_newline = true 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | # Check for updates to GitHub Actions every weekday 7 | interval: "daily" 8 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: dnscontrol check 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | # concurrency: 8 | # group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} 9 | # cancel-in-progress: true 10 | 11 | jobs: 12 | check: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | 19 | - name: Install dependencies 20 | run: | 21 | sudo apt-get update 22 | sudo apt-get install -y --no-install-recommends \ 23 | make \ 24 | libxml-treebuilder-perl \ 25 | libyaml-libyaml-perl \ 26 | libyaml-perl \ 27 | libjson-xs-perl \ 28 | gh 29 | 30 | - name: Install dnscontrol 31 | env: 32 | GH_TOKEN: ${{ github.token }} 33 | run: | 34 | arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \ 35 | && gh release download --repo https://github.com/StackExchange/dnscontrol --pattern "dnscontrol-*.${arch}.deb" --output /tmp/dnscontrol.deb \ 36 | && sudo apt install /tmp/dnscontrol.deb -y 37 | 38 | - name: Run Check 39 | run: | 40 | make check -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | creds.json 2 | gdns/ 3 | include/ 4 | json/ 5 | kml/ 6 | origins/ 7 | pingdom.yml 8 | statuscake.yml 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stable 2 | 3 | RUN apt-get update && apt-get install -y --no-install-recommends \ 4 | make \ 5 | libxml-treebuilder-perl \ 6 | libyaml-libyaml-perl \ 7 | libyaml-perl \ 8 | libjson-xs-perl \ 9 | jq \ 10 | less \ 11 | curl \ 12 | ca-certificates 13 | 14 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 15 | 16 | RUN arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \ 17 | && curl -fsSL https://github.com/StackExchange/dnscontrol/releases/download/v4.1.0/dnscontrol-4.1.0.${arch}.deb -o /tmp/dnscontrol.deb \ 18 | && apt install /tmp/dnscontrol.deb -y 19 | 20 | WORKDIR /dns 21 | ADD . . 22 | 23 | VOLUME ["/dns/data"] 24 | 25 | CMD ["make", "check"] 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | preview: check preview_dnscontrol 2 | 3 | preview_dnscontrol: check_dnscontrol sshfp gdns 4 | dnscontrol preview 5 | 6 | check: check_dnscontrol 7 | 8 | check_dnscontrol: sshfp gdns 9 | dnscontrol check 10 | 11 | update: update_dnscontrol update_geodns 12 | 13 | update_primary: update_dnscontrol_primary update_geodns 14 | 15 | update_dnscontrol: sshfp gdns 16 | dnscontrol push 17 | 18 | update_dnscontrol_primary: sshfp gdns 19 | dnscontrol push --domains openstreetmap.org 20 | 21 | update_geodns: gdns 22 | parallel --will-cite rsync --quiet --recursive --checksum gdns/ {}::geodns ::: ${GEODNS_SERVERS} 23 | 24 | sshfp: 25 | bin/mksshfp 26 | 27 | gdns: gdns_nominatim 28 | 29 | gdns_nominatim: lib/countries.xml origins/nominatim.openstreetmap.yml 30 | bin/mkgeo origins/nominatim.openstreetmap.yml src/nominatim.openstreetmap.yml nominatim origins/nominatim-total.openstreetmap.yml nominatim 31 | 32 | clean: 33 | rm -f includes/* json/* origins/* gdns/* 34 | 35 | lib/countries.xml: 36 | curl -s -o $@ http://api.geonames.org/countryInfo?username=demo 37 | 38 | origins/nominatim.openstreetmap.yml: bin/mkcountries lib/countries.xml requests/nominatim.openstreetmap.yml 39 | bin/mkcountries requests/nominatim.openstreetmap.yml origins/nominatim.openstreetmap.yml 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OpenStreetMap DNS 2 | ====================================== 3 | 4 | This repository contains the DNS zone templates and related code for managing OpenStreetMap.org and other domain names. The full list of domains managed by this repo are in the [dnsconfig.js](dnsconfig.js) file. 5 | 6 | ## Standard DNS Zone Files 7 | 8 | We use [dnscontrol](https://dnscontrol.org/) to manage OpenStreetMap DNS. A set of wrapper scripts are used, which are called from the [Makefile](Makefile) 9 | 10 | Merges to the master branch trigger a git [post-receive](https://github.com/openstreetmap/chef/blob/master/cookbooks/dns/files/default/post-receive) which runs `make update` via a [script](https://github.com/openstreetmap/chef/blob/master/cookbooks/dns/templates/default/dns-update.erb), the DNS is then updated by dnscontrol. 11 | 12 | ## GeoDNS Zones 13 | 14 | For GeoDNS zones we use [gdnsd](https://gdnsd.org/) with gdnsd config files generated by scripts called from the [Makefile](Makefile) file. 15 | -------------------------------------------------------------------------------- /bin/mkcountries: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use XML::TreeBuilder; 7 | use YAML; 8 | 9 | # Get arguments 10 | my $requestsfile = shift @ARGV; 11 | my $originsfile = shift @ARGV; 12 | 13 | # Initialise origins 14 | my $origins = {}; 15 | 16 | # Create a parser for the country database 17 | my $countries = XML::TreeBuilder->new; 18 | 19 | # Parse the country database 20 | $countries->parsefile("lib/countries.xml"); 21 | 22 | # Load the per-country requests details 23 | my $requests = YAML::LoadFile($requestsfile); 24 | 25 | # Fill in country table and work out which clusters each can use 26 | foreach my $country ($countries->look_down("_tag" => "country")) 27 | { 28 | my $code = $country->look_down("_tag" => "countryCode")->as_text; 29 | my $name = $country->look_down("_tag" => "countryName")->as_text; 30 | my $population = $country->look_down("_tag" => "population")->as_text; 31 | my $requests = $requests->{$code} || 0; 32 | my $continent = $country->look_down("_tag" => "continent")->as_text; 33 | my $west = $country->look_down("_tag" => "west")->as_text; 34 | my $north = $country->look_down("_tag" => "north")->as_text; 35 | my $east = $country->look_down("_tag" => "east")->as_text; 36 | my $south = $country->look_down("_tag" => "south")->as_text; 37 | my $lat = centre_lat($south, $north); 38 | my $lon = centre_lon($west, $east); 39 | 40 | $origins->{$code} = { 41 | code => $code, name => $name, 42 | country => $code, continent => $continent, 43 | requests => $requests, lat => $lat, lon => $lon 44 | }; 45 | } 46 | 47 | # Save the origins 48 | YAML::DumpFile($originsfile, $origins); 49 | 50 | exit 0; 51 | 52 | # 53 | # Find the centre value between two latitudes 54 | # 55 | sub centre_lat 56 | { 57 | my $south = shift; 58 | my $north = shift; 59 | 60 | return ( $south + $north ) / 2; 61 | } 62 | 63 | # 64 | # Find the centre value between two longitudes 65 | # 66 | sub centre_lon 67 | { 68 | my $west = shift; 69 | my $east = shift; 70 | my $lon; 71 | 72 | if ($west < $east) 73 | { 74 | $lon = ( $west + $east ) / 2; 75 | } 76 | else 77 | { 78 | $lon = ( $west + $east + 360 ) / 2; 79 | } 80 | 81 | $lon = $lon - 360 if $lon > 180; 82 | 83 | return $lon 84 | } 85 | -------------------------------------------------------------------------------- /bin/mkgdns: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use XML::TreeBuilder; 7 | 8 | # Initialise continent and country tables 9 | my %continents; 10 | my @countries; 11 | 12 | # Create a parser for the country database 13 | my $countries = XML::TreeBuilder->new; 14 | 15 | # Parse the country database 16 | $countries->parsefile("lib/countries.xml"); 17 | 18 | # Build continent and country tables 19 | foreach my $country ($countries->look_down("_tag" => "country")) 20 | { 21 | my $continent = $country->look_down("_tag" => "continent")->as_text; 22 | my $code = $country->look_down("_tag" => "countryCode")->as_text; 23 | 24 | next if $code eq "SS" or $code eq "XK"; 25 | 26 | $continents{$continent} ||= []; 27 | 28 | push @countries, $code; 29 | push @{$continents{$continent}}, $code; 30 | } 31 | 32 | # Add unknown country 33 | push @countries, "XX"; 34 | 35 | print "plugins => {\n"; 36 | print " geoip => {\n"; 37 | print " maps => {\n"; 38 | print " country => {\n"; 39 | print " geoip_db => /usr/share/GeoIP/GeoIPv6.dat\n"; 40 | print " datacenters => ["; 41 | 42 | print join(",", map { lc($_) } sort @countries); 43 | 44 | print "]\n"; 45 | print " map => {\n"; 46 | print " default => [xx]\n"; 47 | 48 | foreach my $continent (sort keys %continents) 49 | { 50 | print " ${continent} => {\n"; 51 | 52 | foreach my $country (sort @{$continents{$continent}}) 53 | { 54 | print " ${country} => [\L${country}\E]\n"; 55 | } 56 | 57 | print " }\n"; 58 | } 59 | 60 | print " }\n"; 61 | print " }\n"; 62 | print " }\n"; 63 | print " resources => {\n"; 64 | print " tile => {\n"; 65 | print " map => country\n"; 66 | print " dcmap => {\n"; 67 | 68 | foreach my $country (sort @countries) 69 | { 70 | print " \L${country}\E => \L${country}\E.tile.openstreetmap.org.\n"; 71 | } 72 | 73 | print " }\n"; 74 | print " }\n"; 75 | print " }\n"; 76 | print " }\n"; 77 | print "}\n"; 78 | 79 | exit 0; 80 | -------------------------------------------------------------------------------- /bin/mkgeo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use v5.12; 4 | 5 | use strict; 6 | use warnings; 7 | 8 | use IO::File; 9 | use Math::Trig qw(deg2rad pip2 great_circle_distance); 10 | use JSON::XS; 11 | use LWP::UserAgent; 12 | use YAML::XS qw(LoadFile DumpFile); 13 | 14 | my $originfile = shift @ARGV; 15 | my $clusterfile = shift @ARGV; 16 | my $zone = shift @ARGV; 17 | my $targetoriginfile = shift @ARGV; 18 | my $origins = LoadFile($originfile); 19 | my $clusters = LoadFile($clusterfile); 20 | my $gdnsname = shift @ARGV; 21 | my @servers; 22 | 23 | # Initialise cluster details 24 | while (my($name,$cluster) = each %$clusters) 25 | { 26 | if ($cluster->{servers}) 27 | { 28 | $cluster->{requests} = 0; 29 | 30 | foreach my $server (@{$cluster->{servers}}) 31 | { 32 | $server->{cluster} = $cluster; 33 | $cluster->{requests} = $cluster->{requests} + $server->{requests}; 34 | 35 | push @servers, $server; 36 | } 37 | } 38 | elsif ($cluster->{requests} > 0) 39 | { 40 | my $server = { 41 | cluster => $cluster, 42 | statuscake => $cluster->{statuscake}, 43 | requests => $cluster->{requests}, 44 | cname => $cluster->{cname}, 45 | ipv4 => $cluster->{ipv4}, 46 | ipv6 => $cluster->{ipv6} 47 | }; 48 | 49 | $cluster->{servers} = [ $server ]; 50 | 51 | push @servers, $server; 52 | } 53 | else 54 | { 55 | $cluster->{servers} = []; 56 | } 57 | 58 | $cluster->{name} = $name; 59 | $cluster->{status} = "down"; 60 | } 61 | 62 | # Initialise server details 63 | foreach my $server (@servers) 64 | { 65 | $server->{status} = "up"; 66 | } 67 | 68 | # If statuscake support is enabled then check which servers are up 69 | if ($ENV{STATUSCAKE_APIKEY}) 70 | { 71 | my $ua = LWP::UserAgent->new; 72 | my $cache; 73 | 74 | $ua->agent("mkgeo/1.0"); 75 | $ua->default_header("Authorization", "Bearer $ENV{STATUSCAKE_APIKEY}"); 76 | 77 | if (-f "statuscake.yml") 78 | { 79 | $cache = LoadFile("statuscake.yml"); 80 | } 81 | else 82 | { 83 | $cache = {}; 84 | } 85 | 86 | my $page = 1; 87 | my $pages = 1; 88 | 89 | while ($page <= $pages) 90 | { 91 | my $response = $ua->get("https://api.statuscake.com/v1/uptime?nouptime=true&limit=100&page=${page}"); 92 | 93 | if ($response->is_success) 94 | { 95 | my $uptime = decode_json($response->content); 96 | 97 | foreach my $test (@{$uptime->{data}}) 98 | { 99 | my $testid = $test->{id}; 100 | 101 | if ($test->{status} eq "up" && !$test->{paused}) 102 | { 103 | $cache->{$testid} = "up"; 104 | } 105 | else 106 | { 107 | $cache->{$testid} = "down"; 108 | } 109 | } 110 | 111 | $page = $page + 1; 112 | $pages = $uptime->{metadata}->{page_count}; 113 | } 114 | } 115 | 116 | foreach my $server (@servers) 117 | { 118 | if (my $testids = $server->{statuscake}) 119 | { 120 | $server->{status} = "up"; 121 | 122 | for my $testid (@$testids) 123 | { 124 | my $testresult = $cache->{$testid} || "down"; 125 | 126 | $server->{status} = "down" if $testresult eq "down"; 127 | } 128 | } 129 | else 130 | { 131 | $server->{status} = "down"; 132 | } 133 | } 134 | 135 | DumpFile("statuscake-$$.yml", $cache); 136 | rename("statuscake-$$.yml", "statuscake.yml"); 137 | } 138 | 139 | # Mark a cluster as up if any servers are up 140 | foreach my $server (@servers) 141 | { 142 | if ($server->{status} eq "up") 143 | { 144 | $server->{cluster}->{status} = "up"; 145 | } 146 | else 147 | { 148 | $server->{cluster}->{requests} = $server->{cluster}->{requests} - $server->{requests}; 149 | } 150 | } 151 | 152 | # Abort if no servers at all are up 153 | exit 0 unless grep { $_->{status} eq "up" } values(%$clusters); 154 | 155 | # Create target origins object 156 | my $targetorigins = {}; 157 | 158 | # Initialise cluster details 159 | while (my($name,$cluster) = each %$clusters) 160 | { 161 | $cluster->{requests_limit} = $cluster->{requests}; 162 | $cluster->{requests_used} = 0; 163 | 164 | next if $cluster->{global}; 165 | 166 | $targetorigins->{$cluster->{name}} = { 167 | code => $cluster->{name}, 168 | name => $cluster->{name}, 169 | lat => $cluster->{lat}, 170 | lon => $cluster->{lon}, 171 | requests => 0 172 | }; 173 | } 174 | 175 | my @mappings = (); 176 | 177 | # Scan origins and work out which clusters each can use 178 | foreach my $origin (values %$origins) 179 | { 180 | foreach my $cluster (values %$clusters) 181 | { 182 | my $match = match_origin($cluster, $origin); 183 | 184 | if ($cluster->{status} eq "up" && $match ne "denied") 185 | { 186 | my $priority = $match eq "preferred" ? 20 : 10; 187 | my $distance; 188 | 189 | if ($cluster->{global}) 190 | { 191 | $distance = 0; 192 | } 193 | else 194 | { 195 | $distance = distance($origin->{lat}, $origin->{lon}, $cluster->{lat}, $cluster->{lon}); 196 | } 197 | 198 | push @mappings, { 199 | origin => $origin, cluster => $cluster, 200 | priority => $priority, distance => $distance 201 | }; 202 | } 203 | } 204 | } 205 | 206 | # Allocate each country to a cluster 207 | allocate_clusters(@mappings); 208 | 209 | # If we failed to allocate every origin then loop, increasing 210 | # the requests for each cluster by a little and retrying until 211 | # we manage to allocate everything 212 | while (grep { !exists($_->{cluster}) } values %$origins) 213 | { 214 | # Clear any existing mappings of countries to clusters 215 | foreach my $origin (values %$origins) 216 | { 217 | delete $origin->{cluster}; 218 | } 219 | 220 | # Reset requests usage for clusters and increase limits by 10% 221 | foreach my $cluster (values %$clusters) 222 | { 223 | $cluster->{requests_used} = 0; 224 | $cluster->{requests_limit} = $cluster->{requests_limit} * 1.1; 225 | } 226 | 227 | # Try the allocate again 228 | allocate_clusters(@mappings); 229 | } 230 | 231 | # Report on allocation results 232 | foreach my $name (sort keys %$clusters) 233 | { 234 | my $cluster = $clusters->{$name}; 235 | my $used = int($cluster->{requests_used} + 0.5); 236 | my $limit = $cluster->{requests_limit}; 237 | 238 | if ($limit > 0) 239 | { 240 | my $proportion = int($used / $limit * 100 + 0.5); 241 | 242 | print "${name}: used ${used} of ${limit} (${proportion}%)\n"; 243 | } 244 | else 245 | { 246 | print "${name}: used ${used} of ${limit}\n"; 247 | } 248 | } 249 | 250 | # Create JSON collection object 251 | my @json; 252 | 253 | # Open output files 254 | my $zonefile = IO::File->new("> include/${zone}.js") || die "$!"; 255 | my $jsonfile = IO::File->new("> json/${zone}.openstreetmap.org.json") || die "$!"; 256 | 257 | # Output headers 258 | $zonefile->print("var \U${zone}\E_RECORDS = [\n"); 259 | 260 | # Output details for each country 261 | foreach my $origin (sort { $a->{name} cmp $b->{name} } values %$origins) 262 | { 263 | my $cluster = $origin->{cluster}; 264 | 265 | if (!defined($gdnsname)) 266 | { 267 | $zonefile->print(" CNAME(\"\L$origin->{code}\E.${zone}\", \"$cluster->{name}.${zone}.openstreetmap.org.\", TTL(\"10m\")),\n"); 268 | } 269 | 270 | if ($cluster->{lon} && $cluster->{lat}) 271 | { 272 | my $clon = $origin->{lon}; 273 | my $clat = $origin->{lat}; 274 | my $slon = $cluster->{lon}; 275 | my $slat = $cluster->{lat}; 276 | 277 | if ($clon > 0 && $slon < 0 && 360 + $slon - $clon < $clon - $slon) 278 | { 279 | $slon = $slon + 360; 280 | } 281 | elsif ($slon > 0 && $clon < 0 && 360 + $clon - $slon < $slon - $clon) 282 | { 283 | $clon = $clon + 360; 284 | } 285 | 286 | push @json, { 287 | type => "Feature", 288 | geometry => { 289 | type => "LineString", 290 | coordinates => [ [ $clon, $clat ], [ $slon, $slat ] ] 291 | }, 292 | properties => { 293 | origin => $origin->{name}, 294 | server => $cluster->{name}, 295 | colour => $cluster->{colour} 296 | } 297 | }; 298 | } 299 | 300 | next if $cluster->{global}; 301 | 302 | $targetorigins->{$cluster->{name}}->{requests} += $origin->{requests}; 303 | } 304 | 305 | # Skip default records if we don't need them 306 | if (!defined($gdnsname)) 307 | { 308 | # Output default records for IPs that can't be mapped to a country 309 | foreach my $cluster (sort { $a->{name} cmp $b->{name} } values %$clusters) 310 | { 311 | my $name = $cluster->{name}; 312 | 313 | if (my $default = $cluster->{default}) 314 | { 315 | output_server($zonefile, "${default}.${zone}", $cluster, 0); 316 | } 317 | elsif (exists($cluster->{default})) 318 | { 319 | output_server($zonefile, "${zone}", $cluster, 0); 320 | } 321 | } 322 | } 323 | 324 | # Output A records for each cluster 325 | foreach my $cluster (sort { $a->{name} cmp $b->{name} } values %$clusters) 326 | { 327 | my $name = $cluster->{name}; 328 | 329 | if (@{$cluster->{servers}} > 1) 330 | { 331 | output_server($zonefile, "${name}-%02d.${zone}", $cluster, 1); 332 | } 333 | else 334 | { 335 | output_server($zonefile, "${name}.${zone}", $cluster, 1); 336 | } 337 | } 338 | 339 | # Output the GeoJSON text 340 | $jsonfile->print(encode_json(\@json)); 341 | 342 | # Output footers 343 | $zonefile->print("];\n"); 344 | 345 | # Close the output files 346 | $zonefile->close(); 347 | $zonefile->close(); 348 | 349 | # Output gdnsd configuration 350 | if (defined($gdnsname)) 351 | { 352 | my $gdnsmapfile = IO::File->new("> gdns/${gdnsname}.map") || die "$!"; 353 | my $gdnsresourcefile = IO::File->new("> gdns/${gdnsname}.resource") || die "$!"; 354 | my $gdnsweightedfile = IO::File->new("> gdns/${gdnsname}.weighted") || die "$!"; 355 | my $continent = ""; 356 | 357 | $gdnsmapfile->print("${gdnsname} => {\n"); 358 | $gdnsmapfile->print(" geoip2_db => /etc/gdnsd/geoip/GeoLite2-Country.mmdb\n"); 359 | $gdnsmapfile->print(" datacenters => [" . join(",", sort(keys(%$clusters))) . "]\n"); 360 | $gdnsmapfile->print(" map => {\n"); 361 | $gdnsmapfile->print(" default => [" . join(",", sort(map { $_->{name} } grep { $_->{default} } values(%$clusters))) . "]\n"); 362 | 363 | foreach my $origin (sort { $a->{continent} cmp $b->{continent} || $a->{code} cmp $b->{code} } values %$origins) 364 | { 365 | my $code = $origin->{code}; 366 | my $cluster = $origin->{cluster}->{name}; 367 | 368 | next if $code eq "XK"; 369 | 370 | if ($continent ne $origin->{continent}) 371 | { 372 | $gdnsmapfile->print(" }\n") if $continent; 373 | 374 | $continent = $origin->{continent}; 375 | 376 | $gdnsmapfile->print(" ${continent} => {\n"); 377 | } 378 | 379 | $gdnsmapfile->print(" ${code} => [${cluster}]\n"); 380 | } 381 | 382 | $gdnsmapfile->print(" }\n") if $continent; 383 | 384 | $gdnsmapfile->print(" }\n"); 385 | $gdnsmapfile->print("}\n"); 386 | 387 | $gdnsresourcefile->print("${gdnsname} => {\n"); 388 | $gdnsresourcefile->print(" map => ${gdnsname}\n"); 389 | $gdnsresourcefile->print(" dcmap => {\n"); 390 | 391 | foreach my $cluster (sort { $a->{name} cmp $b->{name} } values %$clusters) 392 | { 393 | my $name = $cluster->{name}; 394 | 395 | if (@{$cluster->{servers}} > 1 && grep { $_->{status} eq "up" } @{$cluster->{servers}}) 396 | { 397 | $gdnsweightedfile->print("${name} => {\n"); 398 | 399 | while (my($index,$server) = each @{$cluster->{servers}}) 400 | { 401 | if ($server->{status} eq "up") 402 | { 403 | my $number = sprintf("%02d", $index + 1); 404 | my $requests = $server->{requests}; 405 | 406 | if (my $cname = $server->{cname}) 407 | { 408 | $gdnsweightedfile->print(" ${name}-${number} = [ ${cname}., ${requests} ]\n"); 409 | } 410 | else 411 | { 412 | $gdnsweightedfile->print(" ${name}-${number} = [ ${name}-${number}.${zone}.openstreetmap.org., ${requests} ]\n"); 413 | } 414 | } 415 | } 416 | 417 | $gdnsweightedfile->print("}\n"); 418 | 419 | $gdnsresourcefile->print(" ${name} => %weighted!${name}\n"); 420 | } 421 | elsif (my $cname = $cluster->{cname}) 422 | { 423 | $gdnsresourcefile->print(" ${name} => ${cname}.\n"); 424 | } 425 | else 426 | { 427 | $gdnsresourcefile->print(" ${name} => ${name}.${zone}.openstreetmap.org.\n"); 428 | } 429 | } 430 | 431 | $gdnsresourcefile->print(" }\n"); 432 | $gdnsresourcefile->print("}\n"); 433 | 434 | $gdnsweightedfile->close(); 435 | $gdnsresourcefile->close(); 436 | $gdnsmapfile->close(); 437 | } 438 | 439 | # Output the target details in origin format if required 440 | DumpFile($targetoriginfile, $targetorigins) if $targetoriginfile; 441 | 442 | exit 0; 443 | 444 | # 445 | # Match an origin against a cluster 446 | # 447 | sub match_origin 448 | { 449 | my $cluster = shift; 450 | my $origin = shift; 451 | my $match; 452 | 453 | if ($cluster->{preferred} && 454 | $cluster->{preferred}->{origins} && 455 | grep { $_ eq $origin->{name} } @{$cluster->{preferred}->{origins}}) 456 | { 457 | $match = "preferred"; 458 | } 459 | elsif ($cluster->{allowed} && 460 | $cluster->{allowed}->{origins} && 461 | grep { $_ eq $origin->{name} } @{$cluster->{allowed}->{origins}}) 462 | { 463 | $match = "allowed"; 464 | } 465 | elsif ($cluster->{preferred} && 466 | $cluster->{preferred}->{countries} && 467 | grep { $_ eq $origin->{country} } @{$cluster->{preferred}->{countries}}) 468 | { 469 | $match = "preferred"; 470 | } 471 | elsif ($cluster->{allowed} && 472 | $cluster->{allowed}->{countries} && 473 | grep { $_ eq $origin->{country} } @{$cluster->{allowed}->{countries}}) 474 | { 475 | $match = "allowed"; 476 | } 477 | elsif ($cluster->{denied} && 478 | $cluster->{denied}->{countries} && 479 | grep { $_ eq $origin->{country} } @{$cluster->{denied}->{countries}}) 480 | { 481 | $match = "denied"; 482 | } 483 | elsif ($cluster->{preferred} && 484 | $cluster->{preferred}->{continents} && 485 | grep { $_ eq $origin->{continent} } @{$cluster->{preferred}->{continents}}) 486 | { 487 | $match = "preferred"; 488 | } 489 | elsif ($cluster->{allowed} && 490 | $cluster->{allowed}->{continents} && 491 | grep { $_ eq $origin->{continent} } @{$cluster->{allowed}->{continents}}) 492 | { 493 | $match = "allowed"; 494 | } 495 | elsif ($cluster->{denied} && 496 | $cluster->{denied}->{continents} && 497 | grep { $_ eq $origin->{continent} } @{$cluster->{denied}->{continents}}) 498 | { 499 | $match = "denied"; 500 | } 501 | elsif ($cluster->{allowed}) 502 | { 503 | $match = "denied"; 504 | } 505 | else 506 | { 507 | $match = "allowed"; 508 | } 509 | 510 | return $match; 511 | } 512 | 513 | # 514 | # Compute the great circle distance between two points 515 | # 516 | sub distance 517 | { 518 | my $lat1 = deg2rad(shift); 519 | my $lon1 = deg2rad(shift); 520 | my $lat2 = deg2rad(shift); 521 | my $lon2 = deg2rad(shift); 522 | 523 | return great_circle_distance($lon1, pip2 - $lat1, $lon2, pip2 - $lat2); 524 | } 525 | 526 | # 527 | # Allocate each origin to a cluster 528 | # 529 | sub allocate_clusters 530 | { 531 | my @mappings = sort { compare_mappings($a, $b) } @_; 532 | 533 | # Loop over the mappings, trying to assign each origin to the 534 | # nearest cluster, but subject to the request limits 535 | while (my $mapping = shift @mappings) 536 | { 537 | my @group; 538 | 539 | push @group, $mapping; 540 | 541 | while (@mappings && compare_mappings($mapping, $mappings[0]) == 0) 542 | { 543 | push @group, shift @mappings; 544 | } 545 | 546 | for my $mapping (sort compare_requests @group) 547 | { 548 | my $origin = $mapping->{origin}; 549 | my $cluster = $mapping->{cluster}; 550 | 551 | if (!exists($origin->{cluster}) && 552 | $cluster->{requests_used} + $origin->{requests} <= $cluster->{requests_limit}) 553 | { 554 | $origin->{cluster} = $cluster; 555 | $cluster->{requests_used} = $cluster->{requests_used} + $origin->{requests}; 556 | } 557 | } 558 | } 559 | 560 | return; 561 | } 562 | 563 | # 564 | # Compare two mappings to decide which to use 565 | # 566 | sub compare_mappings 567 | { 568 | my $a = shift; 569 | my $b = shift; 570 | 571 | return $b->{priority} <=> $a->{priority} || 572 | $a->{distance} <=> $b->{distance}; 573 | } 574 | 575 | # 576 | # Compare two mappings to decide which to try first 577 | # 578 | sub compare_requests 579 | { 580 | my $a_used = ( $a->{cluster}->{requests_used} * 100.0 ) / ( $a->{cluster}->{requests_limit} * 1.0 ); 581 | my $b_used = ( $b->{cluster}->{requests_used} * 100.0 ) / ( $b->{cluster}->{requests_limit} * 1.0 ); 582 | 583 | return $a_used <=> $b_used; 584 | } 585 | 586 | # 587 | # Output DNS records for a server 588 | # 589 | sub output_server 590 | { 591 | my $zonefile = shift; 592 | my $name = shift; 593 | my $cluster = shift; 594 | my $all = shift; 595 | 596 | while (my($index,$server) = each @{$cluster->{servers}}) 597 | { 598 | if ($all || $server->{status} eq "up") 599 | { 600 | if ($server->{ipv4}) 601 | { 602 | $zonefile->printf(" A(\"${name}\", \"$server->{ipv4}\", TTL(\"10m\")),\n", $index + 1); 603 | } 604 | 605 | if ($server->{ipv6}) 606 | { 607 | $zonefile->printf(" AAAA(\"${name}\", \"$server->{ipv6}\", TTL(\"10m\")),\n", $index + 1); 608 | } 609 | } 610 | } 611 | 612 | return; 613 | } 614 | -------------------------------------------------------------------------------- /bin/mksshfp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Digest::SHA qw(sha256_hex); 7 | use MIME::Base64; 8 | 9 | my %hosts; 10 | 11 | if (-f "/etc/ssh/ssh_known_hosts") 12 | { 13 | open(HOSTS, "<", "/etc/ssh/ssh_known_hosts") || die $!; 14 | 15 | while (my $line = ) 16 | { 17 | last if $line =~ /^# Manually maintained records$/; 18 | 19 | if ($line =~ /^([^, ]+)\S* (\S+) (\S+)$/) 20 | { 21 | my $host = $1; 22 | my $algorithm = $2; 23 | my $value = uc(sha256_hex(decode_base64($3))); 24 | 25 | $host =~ s/\.openstreetmap\.org$//; 26 | 27 | if ($algorithm ne "2") 28 | { 29 | $hosts{$host} ||= {}; 30 | 31 | $hosts{$host}->{$algorithm} = $value; 32 | } 33 | } 34 | } 35 | 36 | close(HOSTS); 37 | } 38 | 39 | open(SSHFP_JS, ">", "include/sshfp.js") || die $!; 40 | 41 | print SSHFP_JS qq|var SSHFP_RECORDS = [\n|; 42 | 43 | foreach my $host (sort keys %hosts) 44 | { 45 | if ($hosts{$host}->{"ecdsa-sha2-nistp256"} || $hosts{$host}->{"ssh-ed25519"}) 46 | { 47 | if ($hosts{$host}->{"ecdsa-sha2-nistp256"}) 48 | { 49 | print SSHFP_JS sshfp_record($host, "3", $hosts{$host}->{"ecdsa-sha2-nistp256"}); 50 | } 51 | 52 | if ($hosts{$host}->{"ssh-ed25519"}) 53 | { 54 | print SSHFP_JS sshfp_record($host, "4", $hosts{$host}->{"ssh-ed25519"}); 55 | } 56 | } 57 | elsif ($hosts{$host}->{"ssh-rsa"}) 58 | { 59 | print SSHFP_JS sshfp_record($host, "1", $hosts{$host}->{"ssh-rsa"}); 60 | } 61 | } 62 | 63 | print SSHFP_JS qq|];\n|; 64 | 65 | close(SSHFP_JS); 66 | 67 | exit 0; 68 | 69 | sub sshfp_record 70 | { 71 | my $host = shift; 72 | my $algorithm = shift; 73 | my $value = shift; 74 | 75 | return qq| SSHFP("${host}", ${algorithm}, 2, "${value}"),\n|; 76 | } 77 | -------------------------------------------------------------------------------- /bin/sumlogs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Geo::IP; 7 | use YAML; 8 | 9 | my $gi = Geo::IP->open("/usr/share/GeoIP/GeoIP.dat", GEOIP_MEMORY_CACHE); 10 | my $total_bandwidth = 560 * 1024 * 1024; 11 | my $total_bytes = 0; 12 | my %country_bytes; 13 | 14 | while (my $record = <>) 15 | { 16 | if ($record =~ /^\d+\.\d+\s+\S+\s+".*"\s+(\d+\.\d+\.\d+\.\d+)\s+".*"\s+(\d+)$/) 17 | { 18 | my $ip = $1; 19 | my $bytes = $2; 20 | my $country = $gi->country_code_by_addr($ip); 21 | 22 | if (defined($country) && 23 | $country ne "A1" && $country ne "A2" && 24 | $country ne "01" && $country ne "--") 25 | { 26 | $country_bytes{$country} += $bytes; 27 | } 28 | 29 | $total_bytes += $bytes; 30 | } 31 | else 32 | { 33 | warn $record; 34 | } 35 | } 36 | 37 | my %country_bandwidth; 38 | 39 | while (my($country,$bytes) = each %country_bytes) 40 | { 41 | $country_bandwidth{$country} = $bytes * $total_bandwidth / $total_bytes; 42 | } 43 | 44 | print Dump(\%country_bandwidth); 45 | 46 | exit 0; 47 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Upload data to Bytemark Hosting's content DNS servers 4 | # 5 | 6 | RSYNC=/usr/bin/rsync 7 | USER=openstreetmap 8 | 9 | if [ ! -f $RSYNC ] ; then 10 | echo "You need rsync installed to use this script" 11 | if [ -f /etc/debian_version ] ; then 12 | echo "I'll try to install it automatically." 13 | apt-get install rsync 14 | fi 15 | fi 16 | 17 | for SERVER in upload ; do 18 | echo -n "Server $SERVER.ns.bytemark.co.uk..." 19 | if ping -c 1 $SERVER.ns.bytemark.co.uk >/dev/null 2>&1 ; then 20 | echo -n "alive, sending updates..." 21 | if $RSYNC -C -r --delete data/ dns@$SERVER.ns.bytemark.co.uk::$USER; then 22 | echo "sent." 23 | else 24 | echo "failed :-(" 25 | fi 26 | else 27 | echo "not responding." 28 | fi 29 | done 30 | -------------------------------------------------------------------------------- /dnsconfig.js: -------------------------------------------------------------------------------- 1 | var REG_NONE = NewRegistrar("none"); 2 | var REG_GANDI = NewRegistrar("gandi_v5"); 3 | var PROVIDER = NewDnsProvider("cloudflare"); 4 | 5 | var DOMAIN; 6 | var REGISTRAR; 7 | var DYNAMIC_RECORDS; 8 | 9 | var QUALIFY = function (name) { 10 | return name + "." + DOMAIN + "."; 11 | }; 12 | 13 | function loadTemplate(template) { 14 | return function (domain, registrar) { 15 | DOMAIN = domain; 16 | REGISTRAR = registrar; 17 | 18 | require("src/" + template + ".js"); 19 | }; 20 | } 21 | 22 | /** 23 | * Create A, optional AAAA, and optional HTTPS (SVCB) records for an OSM web service, 24 | * with optional Cloudflare proxy support. 25 | * 26 | * @param {string} name - Hostname (e.g. "www"). 27 | * @param {string[]} servers - Required array of servers. 28 | * @param {Object} [options] - Optional settings for HTTPS and Cloudflare. 29 | * @param {boolean} [options.h1=false] - If true, sets HTTPS apn=http1.1 30 | * @param {boolean} [options.h2=true] - If true, sets HTTPS apn=h2 31 | * @param {boolean} [options.h3=false] - If true, sets HTTPS apn=h3 32 | * @param {boolean} [options.cfproxy=false] - If true, enables Cloudflare proxy on A/AAAA. 33 | * 34 | */ 35 | function osm_web_service( 36 | name, 37 | servers, 38 | options 39 | ) { 40 | 41 | // If servers is a string, convert to a single-element array 42 | if (typeof servers === "string") { 43 | servers = [servers]; 44 | } 45 | 46 | if (options === undefined) { 47 | options = {}; 48 | } 49 | 50 | // Set default values for options.h1, options.h2, and options.h3 51 | options.h1 = options.h1 !== undefined ? options.h1 : false; 52 | options.h2 = options.h2 !== undefined ? options.h2 : true; 53 | options.h3 = options.h3 !== undefined ? options.h3 : false; 54 | 55 | var records = []; 56 | var ipv4s = []; 57 | var ipv6s = []; 58 | 59 | servers.forEach(function(serverName) { 60 | if (IPV4[serverName]) { 61 | ipv4s.push(IPV4[serverName]); 62 | if (!options.cfproxy) { 63 | records.push(A(name, IPV4[serverName])); 64 | } else { 65 | records.push(A(name, IPV4[serverName], CF_PROXY_ON)); 66 | } 67 | } 68 | if (IPV6[serverName]) { 69 | ipv6s.push(IPV6[serverName]); 70 | if (!options.cfproxy) { 71 | records.push(AAAA(name, IPV6[serverName])); 72 | } else { 73 | records.push(AAAA(name, IPV6[serverName], CF_PROXY_ON)); 74 | } 75 | } 76 | }); 77 | 78 | if (ipv4s.length === 0 && ipv6s.length === 0) { 79 | throw new Error("An IPv4 or IPv6 address is required for " + name + " service"); 80 | } 81 | 82 | // 83 | // Build a parameter string for DNSControl HTTPS() syntax. 84 | // Example: "ipv4hint=1.2.3.4,1.2.3.5 ipv6hint=2001:db8::1,2001:db8::2 alpn=h2" 85 | // 86 | var paramParts = []; 87 | if (ipv4s.length > 0) { 88 | // Join IPv4 addresses with comma+space 89 | paramParts.push("ipv4hint=" + ipv4s.join(",")); 90 | } 91 | if (ipv6s.length > 0) { 92 | // Join IPv6 addresses with comma+space 93 | paramParts.push("ipv6hint=" + ipv6s.join(",")); 94 | } 95 | 96 | if (options.h1 || options.h2 || options.h3) { 97 | var paramPartsALPN = []; 98 | if (options.h3) { 99 | paramPartsALPN.push("h3"); 100 | } 101 | if (options.h2) { 102 | paramPartsALPN.push("h2"); 103 | } 104 | if (options.h1) { 105 | paramPartsALPN.push("http/1.1"); 106 | } 107 | paramParts.push("alpn=" + paramPartsALPN.join(",")); 108 | } 109 | 110 | // Join the parts with a space 111 | var paramString = paramParts.join(" "); 112 | 113 | // Create the HTTPS record with 4 arguments 114 | records.push(HTTPS(name, 1, ".", paramString)); 115 | 116 | 117 | return records; 118 | } 119 | 120 | // Ensure that the reverse DNS records are in RFC 4183 notation 121 | REVCOMPAT("rfc4183"); 122 | 123 | var IPV4 = require("src/ipv4.json"); 124 | var IPV6 = require("src/ipv6.json"); 125 | 126 | var HOST_RECORDS = []; 127 | 128 | for (var name in IPV4) { 129 | HOST_RECORDS.push(A(name, IPV4[name])); 130 | } 131 | 132 | for (var name in IPV6) { 133 | HOST_RECORDS.push(AAAA(name, IPV6[name])); 134 | } 135 | 136 | var OPENSTREETMAP = loadTemplate("openstreetmap"); 137 | 138 | require("include/sshfp.js"); 139 | require("include/nominatim.js"); 140 | 141 | try { 142 | require("include/geo.js"); 143 | } catch (e) { 144 | var GEO_NS_RECORDS = []; 145 | } 146 | 147 | OPENSTREETMAP("openstreetmap.org", REG_GANDI); 148 | OPENSTREETMAP("openstreetmap.com", REG_GANDI); 149 | OPENSTREETMAP("openstreetmap.net", REG_GANDI); 150 | OPENSTREETMAP("openstreetmap.ca", REG_GANDI); 151 | OPENSTREETMAP("openstreetmap.eu", REG_NONE); 152 | OPENSTREETMAP("openstreetmap.pro", REG_GANDI); 153 | OPENSTREETMAP("openstreetmap.gay", REG_GANDI); 154 | OPENSTREETMAP("openstreetmaps.org", REG_GANDI); 155 | OPENSTREETMAP("osm.org", REG_GANDI); 156 | OPENSTREETMAP("openmaps.org", REG_GANDI); 157 | OPENSTREETMAP("openstreetmap.io", REG_GANDI); 158 | OPENSTREETMAP("osm.io", REG_GANDI); 159 | OPENSTREETMAP("openstreetmap.li", REG_GANDI); 160 | OPENSTREETMAP("openworldmap.org", REG_GANDI); 161 | OPENSTREETMAP("freeosm.org", REG_GANDI); 162 | OPENSTREETMAP("open-maps.org", REG_GANDI); 163 | OPENSTREETMAP("open-maps.com", REG_GANDI); 164 | OPENSTREETMAP("osmbugs.org", REG_GANDI); 165 | OPENSTREETMAP("openstreetmap.ai", REG_GANDI); 166 | OPENSTREETMAP("openstreetmap.am", REG_GANDI); 167 | OPENSTREETMAP("openstreetmap.fi", REG_GANDI); 168 | OPENSTREETMAP("openstreetmap.gr", REG_GANDI); 169 | OPENSTREETMAP("openstreetmap.me", REG_GANDI); 170 | OPENSTREETMAP("openstreetmap.mx", REG_GANDI); 171 | OPENSTREETMAP("openstreetmap.pe", REG_GANDI); 172 | OPENSTREETMAP("openstreetmap.ph", REG_GANDI); 173 | OPENSTREETMAP("openstreetmap.sg", REG_GANDI); 174 | OPENSTREETMAP("openstreetmap.tv", REG_GANDI); 175 | OPENSTREETMAP("openstreetmap.wales", REG_GANDI); 176 | OPENSTREETMAP("openstreetmapdata.org", REG_GANDI); 177 | 178 | // Disable due to registration issue 179 | // OPENSTREETMAP("openstreetmap.al", REG_NONE); 180 | 181 | D_EXTEND("openstreetmap.org", 182 | CNAME("_acme-challenge.tile", "bxve5ryiwwv7woiraq.fastly-validations.com.", TTL("10m")), 183 | 184 | // Uptime site at StatusCake 185 | CNAME("uptime", "uptimessl-new.statuscake.com."), 186 | 187 | HOST_RECORDS, 188 | SSHFP_RECORDS, 189 | GEO_NS_RECORDS, 190 | NOMINATIM_RECORDS 191 | ); 192 | 193 | D_EXTEND("osm.org", 194 | CNAME("_acme-challenge.tile", "21gvdfyyxjoc4lmsem.fastly-validations.com.", TTL("10m")), 195 | 196 | HOST_RECORDS, 197 | SSHFP_RECORDS 198 | ); 199 | 200 | // Mastodon redirects to en.osm.town 201 | var OPENSTREETMAP_TOWN = loadTemplate("openstreetmap-town"); 202 | OPENSTREETMAP_TOWN("openstreetmap.town", REG_GANDI); 203 | 204 | // Domain owned by Amanda McCann 205 | // osm.town 206 | 207 | // Managed independently by Guillaume Rischard 208 | // openstreetmap.lu 209 | // osm.lu 210 | 211 | var OSM_LI = loadTemplate("osm-li"); 212 | 213 | OSM_LI("osm.li", REG_GANDI); 214 | 215 | var OPENSTREETMAP_NZ = loadTemplate("openstreetmap-nz"); 216 | 217 | OPENSTREETMAP_NZ("openstreetmap.nz", REG_GANDI); 218 | OPENSTREETMAP_NZ("openstreetmap.org.nz", REG_GANDI); 219 | 220 | var OPENSTREETMAP_UK = loadTemplate("openstreetmap-uk"); 221 | 222 | OPENSTREETMAP_UK("openstreetmap.uk", REG_GANDI); 223 | OPENSTREETMAP_UK("openstreetmap.org.uk", REG_GANDI); 224 | OPENSTREETMAP_UK("openstreetmap.co.uk", REG_GANDI); 225 | 226 | var OPENSTREETMAP_ZA = loadTemplate("openstreetmap-za"); 227 | 228 | OPENSTREETMAP_ZA("openstreetmap.org.za", REG_NONE); 229 | OPENSTREETMAP_ZA("osm.org.za", REG_NONE); 230 | 231 | var OSMFOUNDATION = loadTemplate("osmfoundation"); 232 | 233 | OSMFOUNDATION("osmfoundation.org", REG_GANDI); 234 | 235 | var STATEOFTHEMAP = loadTemplate("stateofthemap"); 236 | 237 | STATEOFTHEMAP("stateofthemap.org", REG_GANDI); 238 | STATEOFTHEMAP("stateofthemap.com", REG_GANDI); 239 | STATEOFTHEMAP("sotm.org", REG_GANDI); 240 | 241 | // The domain is registation is managed by FOSSGIS.de 242 | var STATEOFTHEMAP_EU = loadTemplate("stateofthemap-eu"); 243 | STATEOFTHEMAP_EU("stateofthemap.eu", REG_NONE); 244 | 245 | // State of the Map Madagascar 246 | var OPENSTREETMAP_MG = loadTemplate("openstreetmap-mg"); 247 | OPENSTREETMAP_MG("openstreetmap.mg", REG_GANDI); 248 | 249 | var OPENGEODATA = loadTemplate("opengeodata"); 250 | OPENGEODATA("opengeodata.org", REG_GANDI); 251 | 252 | var SWITCH2OSM = loadTemplate("switch2osm"); 253 | 254 | SWITCH2OSM("switch2osm.org", REG_GANDI); 255 | SWITCH2OSM("switch2osm.com", REG_GANDI); 256 | 257 | var OSM2PGSQL = loadTemplate("osm2pgsql"); 258 | 259 | OSM2PGSQL("osm2pgsql.org", REG_GANDI); 260 | OSM2PGSQL("osm2pgsql.com", REG_GANDI); 261 | 262 | var IDEDITOR = loadTemplate("ideditor"); 263 | 264 | IDEDITOR("ideditor.com", REG_GANDI); 265 | 266 | var OSMWIKI = loadTemplate("osm-wiki"); 267 | OSMWIKI("osm.wiki", REG_GANDI); 268 | 269 | var PTR_HE_AMS_IPV4 = loadTemplate("ptr_he_ams_ipv4"); 270 | 271 | PTR_HE_AMS_IPV4(REV("184.104.179.128/27"), REG_NONE); 272 | 273 | var PTR_HE_AMS_IPV6 = loadTemplate("ptr_he_ams_ipv6"); 274 | 275 | PTR_HE_AMS_IPV6(REV("2001:470:1:fa1::/64"), REG_NONE); 276 | 277 | var PTR_HE_DUB_IPV4 = loadTemplate("ptr_he_dub_ipv4"); 278 | 279 | PTR_HE_DUB_IPV4(REV("184.104.226.96/27"), REG_NONE); 280 | 281 | var PTR_HE_DUB_IPV6 = loadTemplate("ptr_he_dub_ipv6"); 282 | 283 | PTR_HE_DUB_IPV6(REV("2001:470:1:b3b::/64"), REG_NONE); 284 | 285 | var PTR_EQUINIX_AMS_IPV4 = loadTemplate("ptr_equinix_ams_ipv4"); 286 | 287 | PTR_EQUINIX_AMS_IPV4(REV("82.199.86.96/27"), REG_NONE); 288 | 289 | var PTR_EQUINIX_AMS_IPV6 = loadTemplate("ptr_equinix_ams_ipv6"); 290 | 291 | PTR_EQUINIX_AMS_IPV6(REV("2001:4d78:500:5e3::/64"), REG_NONE); 292 | 293 | var PTR_EQUINIX_DUB_IPV4 = loadTemplate("ptr_equinix_dub_ipv4"); 294 | 295 | PTR_EQUINIX_DUB_IPV4(REV("87.252.214.96/27"), REG_NONE); 296 | 297 | var PTR_EQUINIX_DUB_IPV6 = loadTemplate("ptr_equinix_dub_ipv6"); 298 | 299 | PTR_EQUINIX_DUB_IPV6(REV("2001:4d78:fe03:1c::/64"), REG_NONE); 300 | 301 | // No immediate plans 302 | // External DNS and hosting still up 303 | // freethepostcode.org 304 | 305 | // External DNS and hosting 306 | // openstreetmap.cymru 307 | -------------------------------------------------------------------------------- /gdns/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstreetmap/dns/8207197e226602ce5368828df55185b9b8620437/gdns/.gitkeep -------------------------------------------------------------------------------- /include/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstreetmap/dns/8207197e226602ce5368828df55185b9b8620437/include/.gitkeep -------------------------------------------------------------------------------- /json/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstreetmap/dns/8207197e226602ce5368828df55185b9b8620437/json/.gitkeep -------------------------------------------------------------------------------- /origins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstreetmap/dns/8207197e226602ce5368828df55185b9b8620437/origins/.gitkeep -------------------------------------------------------------------------------- /requests/nominatim.openstreetmap.yml: -------------------------------------------------------------------------------- 1 | --- 2 | AD: 0.0302777777778 3 | AE: 1.98777777778 4 | AF: 0.0408333333333 5 | AG: 0.00222222222222 6 | AI: 0.249166666667 7 | AL: 2.22527777778 8 | AM: 1.59555555556 9 | AO: 0.583055555556 10 | AQ: 0.0025 11 | AR: 10.4358333333 12 | AS: 0.000555555555556 13 | AT: 15.6136111111 14 | AU: 18.2058333333 15 | AW: 0.0358333333333 16 | AX: 0.0152777777778 17 | AZ: 1.45888888889 18 | BA: 0.412222222222 19 | BB: 0.0313888888889 20 | BD: 2.07638888889 21 | BE: 5.54 22 | BF: 0.0527777777778 23 | BG: 2.63083333333 24 | BH: 0.121944444444 25 | BI: 0.0691666666667 26 | BJ: 0.257777777778 27 | BL: 0.00666666666667 28 | BM: 0.0594444444444 29 | BN: 0.106388888889 30 | BO: 2.04444444444 31 | BQ: 0.00416666666667 32 | BR: 64.7872222222 33 | BS: 0.0113888888889 34 | BT: 0.0211111111111 35 | BW: 0.0675 36 | BY: 3.45055555556 37 | BZ: 0.015 38 | CA: 18.0144444444 39 | CD: 0.364722222222 40 | CF: 0.005 41 | CG: 0.0661111111111 42 | CH: 11.8022222222 43 | CI: 0.66 44 | CK: 0.000555555555556 45 | CL: 5.82055555556 46 | CM: 1.11805555556 47 | CN: 24.0813888889 48 | CO: 29.0861111111 49 | CR: 0.450555555556 50 | CU: 0.0975 51 | CV: 0.0138888888889 52 | CW: 0.0155555555556 53 | CY: 0.251944444444 54 | CZ: 6.90222222222 55 | DE: 229.34 56 | DJ: 0.0125 57 | DK: 3.63361111111 58 | DM: 0.00194444444444 59 | DO: 3.98111111111 60 | DZ: 0.991666666667 61 | EC: 3.18333333333 62 | EE: 3.37527777778 63 | EG: 4.04583333333 64 | ES: 23.5105555556 65 | ET: 0.326666666667 66 | FI: 4.62611111111 67 | FJ: 0.0161111111111 68 | FK: 0.000833333333333 69 | FM: 0.000833333333333 70 | FO: 0.613333333333 71 | FR: 49.7969444444 72 | GA: 0.0636111111111 73 | GB: 30.8966666667 74 | GD: 0.00138888888889 75 | GE: 0.204166666667 76 | GF: 0.0297222222222 77 | GG: 0.00527777777778 78 | GH: 1.145 79 | GI: 0.00888888888889 80 | GL: 0.0880555555556 81 | GM: 0.0172222222222 82 | GN: 0.0661111111111 83 | GP: 0.0627777777778 84 | GQ: 0.000833333333333 85 | GR: 21.7488888889 86 | GT: 15.895 87 | GU: 0.0144444444444 88 | GW: 0.000833333333333 89 | GY: 0.0122222222222 90 | HK: 1.82722222222 91 | HN: 0.228333333333 92 | HR: 8.52138888889 93 | HT: 0.00666666666667 94 | HU: 4.32694444444 95 | ID: 38.6758333333 96 | IE: 30.0491666667 97 | IL: 6.955 98 | IM: 0.142777777778 99 | IN: 45.3866666667 100 | IO: 0.000555555555556 101 | IQ: 0.7525 102 | IR: 4.71722222222 103 | IS: 0.1725 104 | IT: 31.4088888889 105 | JE: 0.0513888888889 106 | JM: 0.130833333333 107 | JO: 0.599166666667 108 | JP: 11.1275 109 | KE: 4.11861111111 110 | KG: 0.218055555556 111 | KH: 0.379722222222 112 | KI: 0.000277777777778 113 | KM: 0.00388888888889 114 | KN: 0.000555555555556 115 | KR: 3.85888888889 116 | KW: 0.819166666667 117 | KY: 0.00416666666667 118 | KZ: 2.39666666667 119 | LA: 0.366944444444 120 | LB: 0.231944444444 121 | LC: 0.01 122 | LI: 0.0236111111111 123 | LK: 1.51722222222 124 | LR: 0.0355555555556 125 | LS: 0.00305555555556 126 | LT: 6.14444444444 127 | LU: 2.09 128 | LV: 2.19222222222 129 | LY: 0.0883333333333 130 | MA: 5.09111111111 131 | MC: 0.0163888888889 132 | MD: 3.43583333333 133 | ME: 0.145833333333 134 | MF: 0.00361111111111 135 | MG: 0.525277777778 136 | MH: 0.00305555555556 137 | MK: 0.112222222222 138 | ML: 0.0725 139 | MM: 0.0772222222222 140 | MN: 1.35861111111 141 | MO: 0.0475 142 | MP: 0.00194444444444 143 | MQ: 0.0322222222222 144 | MR: 0.0458333333333 145 | MS: 0.0025 146 | MT: 0.314166666667 147 | MU: 0.234166666667 148 | MV: 0.0244444444444 149 | MW: 0.0447222222222 150 | MX: 30.385 151 | MY: 6.13722222222 152 | MZ: 0.246666666667 153 | NA: 0.486666666667 154 | NC: 0.0458333333333 155 | NE: 0.173611111111 156 | NF: 0.000277777777778 157 | NG: 6.42138888889 158 | NI: 0.0344444444444 159 | NL: 30.8016666667 160 | NO: 4.5425 161 | NP: 1.77666666667 162 | NZ: 2.23888888889 163 | OM: 0.176388888889 164 | PA: 0.261111111111 165 | PE: 1.65388888889 166 | PF: 0.285555555556 167 | PG: 0.055 168 | PH: 4.54111111111 169 | PK: 1.99972222222 170 | PL: 53.8841666667 171 | PM: 0.000833333333333 172 | PR: 0.4075 173 | PS: 1.21805555556 174 | PT: 2.37777777778 175 | PW: 0.000277777777778 176 | PY: 4.65277777778 177 | QA: 0.277777777778 178 | RE: 0.497222222222 179 | RO: 4.84888888889 180 | RS: 1.51027777778 181 | RU: 79.0533333333 182 | RW: 0.0455555555556 183 | SA: 3.76305555556 184 | SB: 0.194444444444 185 | SC: 1.6425 186 | SD: 0.899722222222 187 | SE: 6.68861111111 188 | SG: 13.1025 189 | SI: 0.849166666667 190 | SK: 2.11944444444 191 | SL: 0.163333333333 192 | SM: 0.0205555555556 193 | SN: 0.185277777778 194 | SO: 0.146944444444 195 | SR: 0.0136111111111 196 | SS: 0.00777777777778 197 | ST: 0.00138888888889 198 | SV: 0.171666666667 199 | SX: 0.00444444444444 200 | SY: 0.728888888889 201 | SZ: 0.0116666666667 202 | TC: 0.0025 203 | TD: 0.00388888888889 204 | TG: 0.0719444444444 205 | TH: 5.42694444444 206 | TJ: 0.534444444444 207 | TL: 0.0172222222222 208 | TM: 0.0577777777778 209 | TN: 1.01861111111 210 | TO: 0.000277777777778 211 | TR: 14.9716666667 212 | TT: 1.00166666667 213 | TV: 0.00583333333333 214 | TW: 5.9775 215 | TZ: 0.296944444444 216 | UA: 37.3986111111 217 | UG: 0.272222222222 218 | UM: 0.000833333333333 219 | US: 324.626944444 220 | UY: 0.799166666667 221 | UZ: 7.335 222 | VA: 0.00555555555556 223 | VC: 0.000833333333333 224 | VE: 4.03694444444 225 | VG: 0.00111111111111 226 | VI: 0.00944444444444 227 | VN: 15.1244444444 228 | VU: 0.00277777777778 229 | WF: 0.0183333333333 230 | WS: 0.00111111111111 231 | XK: 0.00166666666667 232 | YE: 0.0991666666667 233 | YT: 0.00527777777778 234 | ZA: 8.20611111111 235 | ZM: 0.110277777778 236 | ZW: 0.420277777778 237 | -------------------------------------------------------------------------------- /src/ideditor.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Delegate SPF policy to the main domain 17 | 18 | SPF_BUILDER({ 19 | label: "@", 20 | parts: [ 21 | "v=spf1", 22 | "include:openstreetmap.org", // main openstreetmap.org spf record 23 | "-all" 24 | ] 25 | }), 26 | 27 | // site hosted on github pages 28 | 29 | ALIAS("@", "openstreetmap.github.io."), 30 | CNAME("www", "openstreetmap.github.io."), 31 | A("preview", IPV4["naga"]), 32 | AAAA("preview", IPV6["naga"]) 33 | 34 | ); 35 | -------------------------------------------------------------------------------- /src/ipv4.json: -------------------------------------------------------------------------------- 1 | { 2 | "albi": "51.159.53.238", 3 | "angor": "196.10.54.165", 4 | "ats1.ams": "10.0.48.103", 5 | "cmok": "64.225.143.127", 6 | "culebre": "87.252.214.105", 7 | "culebre.he": "184.104.226.105", 8 | "culebre.dub": "10.0.64.9", 9 | "culebre.oob": "10.0.65.9", 10 | "dribble": "82.199.86.100", 11 | "dribble.he": "184.104.179.132", 12 | "dribble.ams": "10.0.48.4", 13 | "dribble.oob": "10.0.49.4", 14 | "dulcy": "82.199.86.105", 15 | "dulcy.he": "184.104.179.137", 16 | "dulcy.ams": "10.0.48.9", 17 | "dulcy.oob": "10.0.49.9", 18 | "eddie.ucl": "10.0.0.10", 19 | "eddie.oob": "10.0.1.10", 20 | "equinix-gw.ams": "82.199.86.73", 21 | "equinix-gw-1.ams": "82.199.86.74", 22 | "equinix-gw-2.ams": "82.199.86.75", 23 | "equinix-osm.ams": "82.199.86.76", 24 | "equinix-gw.dub": "87.252.218.105", 25 | "equinix-gw-1.dub": "87.252.218.106", 26 | "equinix-gw-2.dub": "87.252.218.107", 27 | "equinix-osm.dub": "87.252.218.108", 28 | "faffy": "82.199.86.99", 29 | "faffy.he": "184.104.179.131", 30 | "faffy.ams": "10.0.48.3", 31 | "faffy.oob": "10.0.49.3", 32 | "fafnir": "87.252.214.98", 33 | "fafnir.he": "184.104.226.98", 34 | "fafnir.dub": "10.0.64.2", 35 | "fafnir.oob": "10.0.65.2", 36 | "fume": "87.252.214.112", 37 | "fume.he": "184.104.226.112", 38 | "fume.dub": "10.0.64.16", 39 | "fume.oob": "10.0.65.16", 40 | "grisu": "87.252.214.113", 41 | "grisu.he": "184.104.226.113", 42 | "grisu.dub": "10.0.64.17", 43 | "grisu.oob": "10.0.65.17", 44 | "horntail": "87.252.214.106", 45 | "horntail.he": "184.104.226.106", 46 | "horntail.dub": "10.0.64.10", 47 | "horntail.oob": "10.0.65.10", 48 | "idris": "87.252.214.102", 49 | "idris.he": "184.104.226.102", 50 | "idris.dub": "10.0.64.6", 51 | "idris.oob": "10.0.65.6", 52 | "karm.ams": "10.0.48.50", 53 | "karm.oob": "10.0.49.50", 54 | "konqi": "87.252.214.103", 55 | "konqi.he": "184.104.226.103", 56 | "konqi.dub": "10.0.64.7", 57 | "konqi.oob": "10.0.65.7", 58 | "ladon": "83.212.2.116", 59 | "lockheed": "82.199.86.112", 60 | "lockheed.he": "184.104.179.144", 61 | "lockheed.ams": "10.0.48.16", 62 | "lockheed.oob": "10.0.49.16", 63 | "longma": "87.252.214.109", 64 | "longma.he": "184.104.226.109", 65 | "longma.dub": "10.0.64.13", 66 | "longma.oob": "10.0.65.13", 67 | "meraxes": "51.15.185.90", 68 | "muirdris": "87.252.214.111", 69 | "muirdris.he": "184.104.226.111", 70 | "muirdris.dub": "10.0.64.15", 71 | "muirdris.oob": "10.0.65.15", 72 | "naga": "87.252.214.104", 73 | "naga.he": "184.104.226.104", 74 | "naga.dub": "10.0.64.8", 75 | "naga.oob": "10.0.65.8", 76 | "neak": "89.234.177.142", 77 | "nidhogg": "194.71.11.111", 78 | "nidhogg.oob": "130.239.18.115", 79 | "norbert": "82.199.86.113", 80 | "norbert.he": "184.104.179.145", 81 | "norbert.ams": "10.0.48.17", 82 | "norbert.oob": "10.0.49.17", 83 | "odin": "82.199.86.111", 84 | "odin.he": "184.104.179.143", 85 | "odin.ams": "10.0.48.15", 86 | "odin.oob": "10.0.49.15", 87 | "oob1.ams": "10.0.48.102", 88 | "oob1.dub": "10.0.64.102", 89 | "palulukon": "3.144.0.72", 90 | "piasa": "140.211.167.101", 91 | "piasa.oob": "10.0.0.198", 92 | "pdu1.ams": "10.0.48.100", 93 | "pdu2.ams": "10.0.48.101", 94 | "pdu1.dub": "10.0.64.100", 95 | "pdu2.dub": "10.0.64.101", 96 | "rhaegal": "193.198.233.218", 97 | "ridgeback": "31.169.50.10", 98 | "ridgeback.oob": "31.169.50.14", 99 | "ridley": "193.60.236.19", 100 | "ridley.ucl": "10.0.0.3", 101 | "ridley.oob": "10.0.1.3", 102 | "shenron": "212.110.172.32", 103 | "smaug": "87.252.214.110", 104 | "smaug.he": "184.104.226.110", 105 | "smaug.dub": "10.0.64.14", 106 | "smaug.oob": "10.0.65.14", 107 | "snap-01.ams": "10.0.48.49", 108 | "snap-01.oob": "10.0.49.49", 109 | "snap-02.ucl": "10.0.0.4", 110 | "snap-02.oob": "10.0.1.4", 111 | "snap-03.dub": "10.0.64.50", 112 | "snap-03.oob": "10.0.65.50", 113 | "spike-01": "87.252.214.99", 114 | "spike-01.he": "184.104.226.99", 115 | "spike-01.dub": "10.0.64.3", 116 | "spike-01.oob": "10.0.65.3", 117 | "spike-02": "87.252.214.100", 118 | "spike-02.he": "184.104.226.100", 119 | "spike-02.dub": "10.0.64.4", 120 | "spike-02.oob": "10.0.65.4", 121 | "spike-03": "87.252.214.101", 122 | "spike-03.he": "184.104.226.101", 123 | "spike-03.dub": "10.0.64.5", 124 | "spike-03.oob": "10.0.65.5", 125 | "spike-06": "82.199.86.102", 126 | "spike-06.he": "184.104.179.134", 127 | "spike-06.ams": "10.0.48.6", 128 | "spike-06.oob": "10.0.49.6", 129 | "spike-07": "82.199.86.103", 130 | "spike-07.he": "184.104.179.135", 131 | "spike-07.ams": "10.0.48.7", 132 | "spike-07.oob": "10.0.49.7", 133 | "spike-08": "82.199.86.104", 134 | "spike-08.he": "184.104.179.136", 135 | "spike-08.ams": "10.0.48.8", 136 | "spike-08.oob": "10.0.49.8", 137 | "stormfly-03": "140.211.167.99", 138 | "stormfly-03.oob": "10.0.0.2", 139 | "stormfly-04": "140.211.167.100", 140 | "stormfly-04.oob": "10.0.0.3", 141 | "switch1.ams": "82.199.86.97", 142 | "switch1.he.ams": "184.104.179.129", 143 | "switch1.dub": "87.252.214.97", 144 | "switch1.he.dub": "184.104.226.97", 145 | "tabaluga": "82.199.86.110", 146 | "tabaluga.he": "184.104.179.142", 147 | "tabaluga.ams": "10.0.48.14", 148 | "tabaluga.oob": "10.0.49.14", 149 | "vhagar": "82.199.86.101", 150 | "vhagar.he": "184.104.179.133", 151 | "vhagar.ams": "10.0.48.5", 152 | "vhagar.oob": "10.0.49.5", 153 | "wawel": "64.225.136.96", 154 | "ysera": "193.60.236.22", 155 | "ysera.ucl": "10.0.0.15", 156 | "ysera.oob": "10.0.1.15" 157 | } 158 | -------------------------------------------------------------------------------- /src/ipv6.json: -------------------------------------------------------------------------------- 1 | { 2 | "albi": "2001:0bc8:1200:0004:dac4:97ff:fe8a:9cfc", 3 | "angor": "2001:43f8:1f4:b00:b283:feff:fed8:dd45", 4 | "culebre": "2001:4d78:fe03:1c::9", 5 | "culebre.he": "2001:470:1:b3b::9", 6 | "dribble": "2001:4d78:500:5e3::4", 7 | "dribble.he": "2001:470:1:fa1::4", 8 | "dulcy": "2001:4d78:500:5e3::9", 9 | "dulcy.he": "2001:470:1:fa1::9", 10 | "equinix-gw.ams": "2001:4d78:500:5e2::1", 11 | "equinix-gw-1.ams": "2001:4d78:500:5e2::2", 12 | "equinix-gw-2.ams": "2001:4d78:500:5e2::3", 13 | "equinix-osm.ams": "2001:4d78:500:5e2::4", 14 | "equinix-gw.dub": "2001:4d78:fe03:1b::1", 15 | "equinix-gw-1.dub": "2001:4d78:fe03:1b::2", 16 | "equinix-gw-2.dub": "2001:4d78:fe03:1b::3", 17 | "equinix-osm.dub": "2001:4d78:fe03:1b::4", 18 | "faffy": "2001:4d78:500:5e3::3", 19 | "faffy.he": "2001:470:1:fa1::3", 20 | "fafnir": "2001:4d78:fe03:1c::2", 21 | "fafnir.he": "2001:470:1:b3b::2", 22 | "fume": "2001:4d78:fe03:1c::10", 23 | "fume.he": "2001:470:1:b3b::10", 24 | "grisu": "2001:4d78:fe03:1c::11", 25 | "grisu.he": "2001:470:1:b3b::11", 26 | "horntail": "2001:4d78:fe03:1c::a", 27 | "horntail.he": "2001:470:1:b3b::a", 28 | "idris": "2001:4d78:fe03:1c::6", 29 | "idris.he": "2001:470:1:b3b::6", 30 | "konqi": "2001:4d78:fe03:1c::7", 31 | "konqi.he": "2001:470:1:b3b::7", 32 | "ladon": "2001:648:2ffe:4::116", 33 | "lockheed": "2001:4d78:500:5e3::10", 34 | "lockheed.he": "2001:470:1:fa1::10", 35 | "longma": "2001:4d78:fe03:1c::d", 36 | "longma.he": "2001:470:1:b3b::d", 37 | "meraxes": "2001:bc8:2d57:100:aa1e:84ff:fe72:e660", 38 | "muirdris": "2001:4d78:fe03:1c::f", 39 | "muirdris.he": "2001:470:1:b3b::f", 40 | "naga": "2001:4d78:fe03:1c::8", 41 | "naga.he": "2001:470:1:b3b::8", 42 | "nidhogg": "2001:6b0:19:2::111", 43 | "norbert": "2001:4d78:500:5e3::11", 44 | "norbert.he": "2001:470:1:fa1::11", 45 | "odin": "2001:4d78:500:5e3::f", 46 | "odin.he": "2001:470:1:fa1::f", 47 | "piasa": "2605:bc80:3010:700::8cd3:a765", 48 | "rhaegal": "2001:b68:40ff:3::2", 49 | "shenron": "2001:41c9:1:400::32", 50 | "smaug": "2001:4d78:fe03:1c::e", 51 | "smaug.he": "2001:470:1:b3b::e", 52 | "spike-01": "2001:4d78:fe03:1c::3", 53 | "spike-01.he": "2001:470:1:b3b::3", 54 | "spike-02": "2001:4d78:fe03:1c::4", 55 | "spike-02.he": "2001:470:1:b3b::4", 56 | "spike-03": "2001:4d78:fe03:1c::5", 57 | "spike-03.he": "2001:470:1:b3b::5", 58 | "spike-06": "2001:4d78:500:5e3::6", 59 | "spike-06.he": "2001:470:1:fa1::6", 60 | "spike-07": "2001:4d78:500:5e3::7", 61 | "spike-07.he": "2001:470:1:fa1::7", 62 | "spike-08": "2001:4d78:500:5e3::8", 63 | "spike-08.he": "2001:470:1:fa1::8", 64 | "stormfly-03": "2605:bc80:3010:700::8cd3:a763", 65 | "stormfly-04": "2605:bc80:3010:700::8cd3:a764", 66 | "switch1.he.ams": "2001:470:1:fa1::1", 67 | "switch1.ams": "2001:4d78:500:5e3::1", 68 | "switch1.dub": "2001:4d78:fe03:1c::1", 69 | "switch1.he.dub": "2001:470:1:b3b::1", 70 | "tabaluga": "2001:4d78:500:5e3::e", 71 | "tabaluga.he": "2001:470:1:fa1::e", 72 | "vhagar": "2001:4d78:500:5e3::5", 73 | "vhagar.he": "2001:470:1:fa1::5" 74 | } 75 | -------------------------------------------------------------------------------- /src/nominatim.openstreetmap.yml: -------------------------------------------------------------------------------- 1 | europe: 2 | lat: 52.8746661 3 | lon: -0.7088728262458915 4 | colour: "#7fc97f" 5 | servers: 6 | - statuscake: 7 | - 2217359 8 | - 2217360 9 | requests: 300 10 | name: dulcy 11 | ipv4: 82.199.86.105 12 | ipv6: 2001:4d78:500:5e3::9 13 | - statuscake: 14 | - 6224536 15 | - 6224537 16 | requests: 700 17 | name: longma 18 | ipv4: 184.104.226.109 19 | ipv6: 2001:470:1:b3b::d 20 | - statuscake: 21 | - 6726828 22 | - 6726827 23 | requests: 500 24 | name: vhagar 25 | ipv4: 82.199.86.101 26 | ipv6: 2001:4d78:500:5e3::5 27 | default: "xx" 28 | 29 | stormfly-04: 30 | lat: 44.5639267 31 | lon: -123.274707837676 32 | statuscake: 33 | - 5769055 34 | - 5769056 35 | colour: "#fdc086" 36 | requests: 400 37 | ipv4: 140.211.167.100 38 | ipv6: 2605:bc80:3010:700::8cd3:a764 39 | default: "xx" 40 | -------------------------------------------------------------------------------- /src/opengeodata.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Delegate SPF policy to the main domain 17 | 18 | SPF_BUILDER({ 19 | label: "@", 20 | parts: [ 21 | "v=spf1", 22 | "include:openstreetmap.org", // main openstreetmap.org spf record 23 | "-all" 24 | ] 25 | }), 26 | 27 | // Main web server and it's aliases 28 | 29 | osm_web_service("@", "ridley"), 30 | osm_web_service("old", "ridley"), // Legacy URL support https://blog.openstreetmap.org/2010/02/25/old-opengeodata-posts-now-up-at-old-opengeodata-org/ 31 | osm_web_service("www", "ridley"), 32 | 33 | ); 34 | -------------------------------------------------------------------------------- /src/openstreetmap-mg.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Block email delivery 17 | 18 | TXT("_dmarc", "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s;"), 19 | TXT("*._domainkey", "v=DKIM1; p="), 20 | TXT("@", "v=spf1 -all"), 21 | 22 | // Site hosted on github pages 23 | 24 | ALIAS("@", "openstreetmap-madagascar.github.io."), 25 | CNAME("www", "openstreetmap-madagascar.github.io."), 26 | 27 | CNAME("sotm2024", "openstreetmap-madagascar.github.io."), 28 | 29 | ); -------------------------------------------------------------------------------- /src/openstreetmap-nz.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Let the main domain handle the email 17 | 18 | MX("@", 10, "a.mx.openstreetmap.org."), 19 | 20 | // Delegate SPF policy to the main domain 21 | 22 | SPF_BUILDER({ 23 | label: "@", 24 | parts: [ 25 | "v=spf1", 26 | "include:openstreetmap.org", // main openstreetmap.org spf record 27 | "-all" 28 | ] 29 | }), 30 | 31 | // Delegate MTA-STS policy to the main domain 32 | 33 | CNAME("_mta-sts", "_mta-sts.openstreetmap.org."), 34 | 35 | // Main web site 36 | 37 | ALIAS("@", "www.openstreetmap.org."), 38 | CNAME("www", "www.openstreetmap.org."), 39 | CNAME("api", "api.openstreetmap.org."), 40 | 41 | ); 42 | -------------------------------------------------------------------------------- /src/openstreetmap-town.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Let the main domain handle the email 17 | 18 | MX("@", 10, "a.mx.openstreetmap.org."), 19 | 20 | // Delegate SPF policy to the main domain 21 | 22 | SPF_BUILDER({ 23 | label: "@", 24 | parts: [ 25 | "v=spf1", 26 | "include:openstreetmap.org", // main openstreetmap.org spf record 27 | "-all" 28 | ] 29 | }), 30 | 31 | // Delegate MTA-STS policy to the main domain 32 | 33 | CNAME("_mta-sts", "_mta-sts.openstreetmap.org."), 34 | 35 | // Redirect en.openstreetmap.town to en.osm.town 36 | 37 | osm_web_service("en", "naga"), 38 | 39 | ); 40 | -------------------------------------------------------------------------------- /src/openstreetmap-uk.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Let the main domain handle the email 17 | 18 | MX("@", 10, "a.mx.openstreetmap.org."), 19 | 20 | // Delegate SPF policy to the main domain 21 | 22 | SPF_BUILDER({ 23 | label: "@", 24 | parts: [ 25 | "v=spf1", 26 | "include:openstreetmap.org", // main openstreetmap.org spf record 27 | "-all" 28 | ] 29 | }), 30 | 31 | // Delegate MTA-STS policy to the main domain 32 | 33 | CNAME("_mta-sts", "_mta-sts.openstreetmap.org."), 34 | 35 | // Main web site 36 | 37 | ALIAS("@", "www.openstreetmap.org."), 38 | CNAME("www", "www.openstreetmap.org."), 39 | CNAME("api", "api.openstreetmap.org."), 40 | 41 | // Shaun McDonald's taginfo instance 42 | 43 | CNAME("taginfo", "proxy.mythic-beasts.com."), 44 | 45 | // Aerial imagery sites 46 | 47 | osm_web_service("hampshire.aerial", "lockheed"), 48 | osm_web_service("a.hampshire.aerial", "lockheed"), 49 | osm_web_service("b.hampshire.aerial", "lockheed"), 50 | osm_web_service("c.hampshire.aerial", "lockheed"), 51 | 52 | osm_web_service("surrey.aerial", "lockheed"), 53 | osm_web_service("a.surrey.aerial", "lockheed"), 54 | osm_web_service("b.surrey.aerial", "lockheed"), 55 | osm_web_service("c.surrey.aerial", "lockheed"), 56 | 57 | osm_web_service("os", "lockheed"), 58 | osm_web_service("a.os", "lockheed"), 59 | osm_web_service("b.os", "lockheed"), 60 | osm_web_service("c.os", "lockheed"), 61 | 62 | osm_web_service("ea", "lockheed"), 63 | osm_web_service("a.ea", "lockheed"), 64 | osm_web_service("b.ea", "lockheed"), 65 | osm_web_service("c.ea", "lockheed"), 66 | 67 | ); 68 | -------------------------------------------------------------------------------- /src/openstreetmap-za.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Let the main domain handle the email 17 | 18 | MX("@", 10, "a.mx.openstreetmap.org."), 19 | 20 | // Delegate SPF policy to the main domain 21 | 22 | SPF_BUILDER({ 23 | label: "@", 24 | parts: [ 25 | "v=spf1", 26 | "include:openstreetmap.org", // main openstreetmap.org spf record 27 | "-all" 28 | ] 29 | }), 30 | 31 | // Delegate MTA-STS policy to the main domain 32 | 33 | CNAME("_mta-sts", "_mta-sts.openstreetmap.org."), 34 | 35 | // Main web site 36 | 37 | ALIAS("@", "www.openstreetmap.org."), 38 | CNAME("www", "www.openstreetmap.org."), 39 | CNAME("api", "api.openstreetmap.org."), 40 | 41 | // Aerial imagery sites 42 | 43 | osm_web_service("aerial", "lockheed"), 44 | osm_web_service("a.aerial", "lockheed"), 45 | osm_web_service("b.aerial", "lockheed"), 46 | osm_web_service("c.aerial", "lockheed"), 47 | 48 | osm_web_service("coct.aerial", "lockheed"), 49 | osm_web_service("a.coct.aerial", "lockheed"), 50 | osm_web_service("b.coct.aerial", "lockheed"), 51 | osm_web_service("c.coct.aerial", "lockheed"), 52 | 53 | osm_web_service("topo", "lockheed"), 54 | osm_web_service("a.topo", "lockheed"), 55 | osm_web_service("b.topo", "lockheed"), 56 | osm_web_service("c.topo", "lockheed"), 57 | 58 | osm_web_service("namibia-topo", "lockheed"), 59 | osm_web_service("a.namibia-topo", "lockheed"), 60 | osm_web_service("b.namibia-topo", "lockheed"), 61 | osm_web_service("c.namibia-topo", "lockheed"), 62 | 63 | ); 64 | -------------------------------------------------------------------------------- /src/openstreetmap.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt and globalsign (Fastly) should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | ttl: "1h", 8 | iodef: "mailto:hostmaster@openstreetmap.org", 9 | issue: [ 10 | "letsencrypt.org", 11 | "globalsign.com", // Used by Fastly for CDN certificates 12 | ], 13 | issuewild: [ 14 | "letsencrypt.org", 15 | "globalsign.com", // Used by Fastly for CDN certificates 16 | ], 17 | }), 18 | 19 | // Mail service 20 | 21 | MX("@", 10, QUALIFY("a.mx")), 22 | MX("messages", 10, QUALIFY("a.mx")), 23 | MX("noreply", 10, QUALIFY("a.mx")), 24 | MX("otrs", 10, QUALIFY("a.mx")), 25 | MX("community", 10, QUALIFY("a.mx")), 26 | MX("supporting", 10, QUALIFY("a.mx")), 27 | 28 | A("a.mx", IPV4["fafnir"]), 29 | AAAA("a.mx", IPV6["fafnir"]), 30 | A("mail", IPV4["fafnir"]), 31 | AAAA("mail", IPV6["fafnir"]), 32 | A("mta-sts", IPV4["fafnir"]), 33 | AAAA("mta-sts", IPV6["fafnir"]), 34 | 35 | // Publish SPF records indicating that only shenron sends mail 36 | 37 | SPF_BUILDER({ 38 | label: "@", 39 | parts: [ 40 | "v=spf1", 41 | "ip4:184.104.226.98", // fafnir ipv4 (he.net) 42 | "ip6:2001:470:1:b3b::2", // fafnir ipv6 (he.net) 43 | "ip4:87.252.214.98", // fafnir ipv4 (equinix) 44 | "ip6:2001:4d78:fe03:1c::2", // fafnir ipv6 (equinix) 45 | "ip4:193.60.236.0/24", // ucl external 46 | "ip4:82.199.86.96/27", // amsterdam external (equinix) 47 | "ip6:2001:4d78:500:5e3::/64", // amsterdam external (equinix) 48 | "ip4:87.252.214.96/27", // dublin external (equinix) 49 | "ip6:2001:4d78:fe03:1c::/64", // dublin external (equinix) 50 | "ip4:184.104.179.128/27", // amsterdam external (he.net) 51 | "ip6:2001:470:1:fa1::/64", // amsterdam external (he.net) 52 | "ip4:184.104.226.96/27", // dublin external (he.net) 53 | "ip6:2001:470:1:b3b::/64", // dublin external (he.net) 54 | "mx", // safety net if we change mx 55 | "-all" 56 | ] 57 | }), 58 | 59 | SPF_BUILDER({ 60 | label: "messages", 61 | parts: [ 62 | "v=spf1", 63 | "include:openstreetmap.org", // main openstreetmap.org spf record 64 | "-all" 65 | ] 66 | }), 67 | 68 | SPF_BUILDER({ 69 | label: "noreply", 70 | parts: [ 71 | "v=spf1", 72 | "include:openstreetmap.org", // main openstreetmap.org spf record 73 | "-all" 74 | ] 75 | }), 76 | 77 | SPF_BUILDER({ 78 | label: "otrs", 79 | parts: [ 80 | "v=spf1", 81 | "include:openstreetmap.org", // main openstreetmap.org spf record 82 | "-all" 83 | ] 84 | }), 85 | 86 | SPF_BUILDER({ 87 | label: "community", 88 | parts: [ 89 | "v=spf1", 90 | "include:openstreetmap.org", // main openstreetmap.org spf record 91 | "-all" 92 | ] 93 | }), 94 | 95 | SPF_BUILDER({ 96 | label: "supporting", 97 | parts: [ 98 | "v=spf1", 99 | "include:openstreetmap.org", // main openstreetmap.org spf record 100 | "-all" 101 | ] 102 | }), 103 | 104 | // Publish DKIM public key 105 | 106 | TXT("20200301._domainkey", "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzvoNZVOGfw1V4A171hxHMhzVTAnIUQVJ8iX3wbqCld8A5iIaXeTGYvBmewymax/cYJS4QqzbpUzkgrrTA9avuZhd+QGJDgjADgx4VyMOaOS6FwAxS0uXtLrt+lsixRDx/feKyZHaxjzJAQy46ok77xXL4UXIaaovw6G6eZpIScMzZQ2zkKNJxTICzzSOduIilHhMWte4XP+/2PdRmD7Ge9jb0U4bZjswX0AqKSGzDKYw+yxVna9l53adeCnklqg2ofoXu+ResiH+kt05aCUOMo8en3em6yBnRCMalgi1E3Tt7I5BWcYFRkT/8agUGW4gGC6XMV9IskOsYL0emG0kGwIDAQAB", AUTOSPLIT), 107 | 108 | // Publish DMARC report-only policy 109 | 110 | DMARC_BUILDER({ 111 | policy: "none", 112 | rua: [ 113 | "mailto:openstreetmap-d@dmarc.report-uri.com" 114 | ], 115 | failureOptions: 1 116 | }), 117 | 118 | // Announce MTA-STS policy and TLSRPT policy for error reports 119 | 120 | TXT("_mta-sts", "v=STSv1; id=202001291805Z"), 121 | TXT("_smtp._tls", "v=TLSRPTv1; rua=mailto:openstreetmap-d@tlsrpt.report-uri.com"), 122 | 123 | // Fastly cert domain ownership confirmation 124 | 125 | TXT("@", "_globalsign-domain-verification=ps00GlW1BzY9c2_cwH_pFqRkvzZyaCVZ-3RLssRG6S"), 126 | TXT("@", "_globalsign-domain-verification=W0buKB5ZmL-VwwHw2oQyQImk3I1q3hSemf2qmB1hjP"), 127 | 128 | // Facebook Business domain verification 129 | 130 | TXT("@", "facebook-domain-verification=j5hix5i8r0kortfugqf2p9wx9x9by0"), 131 | 132 | // Bluesky domain verification 133 | 134 | TXT("_atproto", "did=did:plc:i6llv7iwybeipknl57v4dalb"), 135 | 136 | // Delegate MTA-STS policy for subdomains 137 | 138 | CNAME("_mta-sts.messages", QUALIFY("_mta-sts")), 139 | CNAME("_mta-sts.noreply", QUALIFY("_mta-sts")), 140 | CNAME("_mta-sts.otrs", QUALIFY("_mta-sts")), 141 | CNAME("_mta-sts.community", QUALIFY("_mta-sts")), 142 | CNAME("_mta-sts.supporting", QUALIFY("_mta-sts")), 143 | 144 | // Google postmaster tools verification 145 | 146 | CNAME("af323lytato5", "gv-o4v3qh5pfayqex.dv.googlehosted.com."), 147 | CNAME("irzdddnmh465", "gv-cwr6bvt7xsgact.dv.googlehosted.com."), 148 | 149 | // Main web servers and their aliases 150 | 151 | osm_web_service("@", [ "spike-06", 152 | "spike-07", 153 | "spike-08" 154 | ], { cfproxy: true }), 155 | 156 | osm_web_service("www", [ "spike-06", 157 | "spike-07", 158 | "spike-08" 159 | ], { cfproxy: true }), 160 | 161 | osm_web_service("api", [ "spike-06", 162 | "spike-07", 163 | "spike-08" 164 | ], { cfproxy: true }), 165 | 166 | osm_web_service("maps", [ "spike-06", 167 | "spike-07", 168 | "spike-08" 169 | ], { cfproxy: true }), 170 | 171 | osm_web_service("mapz", [ "spike-06", 172 | "spike-07", 173 | "spike-08" 174 | ], { cfproxy: true }), 175 | 176 | // Nominatim servers 177 | 178 | CNAME("nominatim", "nominatim.geo.openstreetmap.org."), 179 | CNAME("qgis.nominatim", "nominatim.geo.openstreetmap.org."), 180 | CNAME("qa-tile.nominatim", "longma.openstreetmap.org."), 181 | 182 | // Tile servers 183 | 184 | CNAME("tile", "dualstack.n.sni.global.fastly.net."), 185 | CNAME("a.tile", "dualstack.n.sni.global.fastly.net."), 186 | CNAME("b.tile", "dualstack.n.sni.global.fastly.net."), 187 | CNAME("c.tile", "dualstack.n.sni.global.fastly.net."), 188 | 189 | osm_web_service("render", [ "culebre", 190 | "nidhogg" 191 | ]), 192 | 193 | // Vector tile servers 194 | 195 | CNAME("vector", "dualstack.n.sni.global.fastly.net."), 196 | 197 | // Planet servers 198 | 199 | A("backup", IPV4["norbert"]), 200 | AAAA("backup", IPV6["norbert"]), 201 | // A("backup", IPV4["horntail"]), 202 | // AAAA("backup", IPV6["horntail"]), 203 | 204 | osm_web_service("planet", "norbert"), 205 | // osm_web_service("planet", "horntail"), 206 | 207 | // Development server with wildcard alias for user sites 208 | 209 | osm_web_service("dev", "faffy"), 210 | osm_web_service("*.dev", "faffy"), 211 | 212 | osm_web_service("ooc", "faffy"), 213 | osm_web_service("a.ooc", "faffy"), 214 | osm_web_service("b.ooc", "faffy"), 215 | osm_web_service("c.ooc", "faffy"), 216 | 217 | osm_web_service("npe", "faffy"), 218 | 219 | // Foundation server 220 | 221 | osm_web_service("blog", "ridley"), 222 | osm_web_service("foundation", "ridley"), 223 | 224 | // Matomo server 225 | 226 | osm_web_service("matomo", "smaug"), 227 | osm_web_service("piwik", "smaug"), 228 | 229 | // Imagery servers 230 | 231 | osm_web_service("agri", "lockheed"), 232 | osm_web_service("a.agri", "lockheed"), 233 | osm_web_service("b.agri", "lockheed"), 234 | osm_web_service("c.agri", "lockheed"), 235 | 236 | osm_web_service("act-imagery", "lockheed"), 237 | osm_web_service("a.act-imagery", "lockheed"), 238 | osm_web_service("b.act-imagery", "lockheed"), 239 | osm_web_service("c.act-imagery", "lockheed"), 240 | 241 | osm_web_service("au-vic-melbourne-imagery", "lockheed"), 242 | osm_web_service("a.au-vic-melbourne-imagery", "lockheed"), 243 | osm_web_service("b.au-vic-melbourne-imagery", "lockheed"), 244 | osm_web_service("c.au-vic-melbourne-imagery", "lockheed"), 245 | 246 | osm_web_service("os", "lockheed"), 247 | osm_web_service("a.os", "lockheed"), 248 | osm_web_service("b.os", "lockheed"), 249 | osm_web_service("c.os", "lockheed"), 250 | 251 | osm_web_service("tiler", "lockheed"), 252 | 253 | osm_web_service("us-imagery", "lockheed"), 254 | osm_web_service("a.us-imagery", "lockheed"), 255 | osm_web_service("b.us-imagery", "lockheed"), 256 | osm_web_service("c.us-imagery", "lockheed"), 257 | 258 | // Prometheus server and munin redirect 259 | 260 | osm_web_service("prometheus", "stormfly-03"), 261 | osm_web_service("munin", "stormfly-03"), 262 | 263 | // Management server 264 | 265 | osm_web_service("acme", "idris"), 266 | osm_web_service("apt", "idris"), 267 | osm_web_service("chef", "idris"), 268 | osm_web_service("dns", "idris"), 269 | osm_web_service("git", "idris"), 270 | osm_web_service("hardware", "idris"), 271 | 272 | // Bytemark machine, and the services which operate from it 273 | 274 | osm_web_service("lists", "shenron"), 275 | osm_web_service("help", "shenron"), 276 | 277 | // Naga services 278 | 279 | osm_web_service("svn", "naga"), 280 | osm_web_service("trac", "naga"), 281 | osm_web_service("irc", "naga"), 282 | osm_web_service("blogs", "naga"), 283 | osm_web_service("welcome", "naga"), 284 | osm_web_service("operations", "naga"), 285 | osm_web_service("hot", "naga"), 286 | osm_web_service("dmca", "naga"), 287 | osm_web_service("otrs", "naga", { h1: true, h2: false }), // OTRS is not available using HTTPS/2 288 | osm_web_service("birthday20", "naga"), 289 | 290 | // Wiki servers 291 | 292 | osm_web_service("wiki", "konqi"), 293 | osm_web_service("test.wiki", "muirdris"), 294 | 295 | // Overpass server 296 | 297 | osm_web_service("query", "grisu"), 298 | 299 | // GPS tile server 300 | 301 | osm_web_service("gps-tile", "muirdris"), 302 | osm_web_service("a.gps-tile", "muirdris"), 303 | osm_web_service("b.gps-tile", "muirdris"), 304 | osm_web_service("c.gps-tile", "muirdris"), 305 | osm_web_service("gps.tile", "muirdris"), 306 | osm_web_service("gps-a.tile", "muirdris"), 307 | osm_web_service("gps-b.tile", "muirdris"), 308 | osm_web_service("gps-c.tile", "muirdris"), 309 | 310 | // Donation site and new OSMF crm site 311 | 312 | osm_web_service("donate", "ridley"), 313 | osm_web_service("support", "ridley"), 314 | osm_web_service("supporting", "ridley"), 315 | 316 | osm_web_service("test.civicrm", "muirdris"), 317 | 318 | // Discourse server ("community") 319 | 320 | osm_web_service("community", "fume"), 321 | osm_web_service("communities", "fume"), 322 | osm_web_service("c", "fume"), 323 | osm_web_service("forum", "fume"), 324 | 325 | CNAME("community-cdn", "dualstack.n.sni.global.fastly.net."), 326 | TXT("community", "google-site-verification=hQ8GZyj4KwnPqAX2oAzpbLrh6I5dfR08PSdL3icVkfg"), 327 | 328 | // Taginfo and Staging Blog Server 329 | 330 | osm_web_service("taginfo", "tabaluga"), 331 | 332 | // Staging Blog Server 333 | 334 | osm_web_service("staging.blog", "tabaluga"), 335 | 336 | ); 337 | -------------------------------------------------------------------------------- /src/osm-li.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, 2 | 3 | NAMESERVER("nalps.sosm.ch."), 4 | NAMESERVER("palpuogna.sosm.ch."), 5 | NAMESERVER("ns.poole.ch."), 6 | NAMESERVER("he.poole.ch."), 7 | NAMESERVER("ns3.spreng.ch."), 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /src/osm-wiki.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt and globalsign (Fastly) should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | ttl: "1h", 8 | iodef: "mailto:hostmaster@openstreetmap.org", 9 | issue: [ 10 | "letsencrypt.org", 11 | "globalsign.com", // Used by Fastly for CDN certificates 12 | ], 13 | issuewild: [ 14 | "letsencrypt.org", 15 | "globalsign.com", // Used by Fastly for CDN certificates 16 | ], 17 | }), 18 | 19 | // Mail service 20 | 21 | MX("@", 10, QUALIFY("a.mx")), 22 | 23 | A("a.mx", IPV4["fafnir"]), 24 | AAAA("a.mx", IPV6["fafnir"]), 25 | A("mail", IPV4["fafnir"]), 26 | AAAA("mail", IPV6["fafnir"]), 27 | A("mta-sts", IPV4["fafnir"]), 28 | AAAA("mta-sts", IPV6["fafnir"]), 29 | 30 | // Delegate SPF policy to the main domain 31 | 32 | SPF_BUILDER({ 33 | label: "@", 34 | parts: [ 35 | "v=spf1", 36 | "include:openstreetmap.org", // main openstreetmap.org spf record 37 | "-all" 38 | ] 39 | }), 40 | 41 | // Publish DMARC report-only policy 42 | 43 | DMARC_BUILDER({ 44 | policy: "none", 45 | rua: [ 46 | "mailto:openstreetmap-d@dmarc.report-uri.com" 47 | ], 48 | failureOptions: 1 49 | }), 50 | 51 | // Announce MTA-STS policy and TLSRPT policy for error reports 52 | 53 | TXT("_mta-sts", "v=STSv1; id=202001291805Z"), 54 | TXT("_smtp._tls", "v=TLSRPTv1; rua=mailto:openstreetmap-d@tlsrpt.report-uri.com"), 55 | 56 | // Fastly cert domain ownership confirmation 57 | 58 | TXT("@", "_globalsign-domain-verification=ps00GlW1BzY9c2_cwH_pFqRkvzZyaCVZ-3RLssRG6S"), 59 | TXT("@", "_globalsign-domain-verification=W0buKB5ZmL-VwwHw2oQyQImk3I1q3hSemf2qmB1hjP"), 60 | 61 | osm_web_service("wiki", "konqi"), 62 | osm_web_service("www", "konqi"), 63 | osm_web_service("@", "konqi"), 64 | 65 | ); 66 | -------------------------------------------------------------------------------- /src/osm2pgsql.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Main web server and it's aliases 17 | 18 | A("@", "138.201.190.130"), 19 | AAAA("@", "2a01:4f8:1c17:6433::2"), 20 | A("www", "138.201.190.130"), 21 | AAAA("www", "2a01:4f8:1c17:6433::2"), 22 | 23 | // Test server for osm2pgsql development 24 | A("test", "135.181.221.216"), 25 | 26 | ); 27 | -------------------------------------------------------------------------------- /src/osmfoundation.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Let mailbox.org handle email 17 | 18 | MX("@", 10, "mxext1.mailbox.org."), 19 | MX("@", 10, "mxext2.mailbox.org."), 20 | MX("@", 20, "mxext3.mailbox.org."), 21 | 22 | // Handle mail for the join subdomain ourselves 23 | 24 | MX("join", 10, "a.mx.openstreetmap.org."), 25 | 26 | // SPF policy 27 | 28 | SPF_BUILDER({ 29 | label: "@", 30 | parts: [ 31 | "v=spf1", 32 | "include:mailbox.org", // mailbox.org 33 | "include:_spf.google.com", // Google GSuite 34 | "include:openstreetmap.org", // main openstreetmap.org spf record 35 | "-all" 36 | ] 37 | }), 38 | 39 | SPF_BUILDER({ 40 | label: "wiki", 41 | parts: [ 42 | "v=spf1", 43 | "include:openstreetmap.org", // main openstreetmap.org spf record 44 | "-all" 45 | ] 46 | }), 47 | 48 | // Apple Business Manager verification 49 | TXT("@", "apple-domain-verification=ZzBG2msRtUDehTMW"), 50 | 51 | // Mailbox.org registration verification 52 | TXT("d00f46a3fde45d06c53f3cd5b21f213ea384e7f5", "4a229bebe41606a1f7d909507846729a73998c31"), 53 | 54 | // Publish DMARC report-only policy 55 | 56 | DMARC_BUILDER({ 57 | policy: "none", 58 | rua: [ 59 | "mailto:openstreetmap-d@dmarc.report-uri.com" 60 | ], 61 | failureOptions: 1 62 | }), 63 | 64 | // DKIM keys 65 | 66 | TXT("google._domainkey", "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJmTBAkYRCocCCNtVsdRNMlQel8kNfjPYJpjEm7woEgZh9yZeDzxImtz+u73oUF4+7bXzrNYbP946WNQIwAba1J69he8L1qfPBJLd3Z/fgmuaGdWcxpDno2EY4cQ8PrzvI6Vfm+6YAFANl8w09CIg41ykdlzH4iUJXD35k3SIl3wIDAQAB"), 67 | TXT("20201112._domainkey", "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz4OyJc77mpW5djxVfZm18HcmJHQLpo7B2Z8Og8byICjDiG91Tpkv5ws3xIbMsi/tVA6p5L76uL0TGKlo4ayewYvJUTC22+hBWARUuWA0DgeMwBpW/dNUOJHBABCTouolvXLKRTPTefA177Y5jYbD7ZeJAR4ZnFbZX6spimXCT66AyhqCBSrOCXYXFm3ons5ANkkQBNZ/jMYczYs9T1ijNEbBNTJmLO+whOrYLyGd3iZ9X9iOmuNFBCgXp0tsN//FBsOyTl559/XY25r3GZhiKXMbrZ1IJewqJlG0+hN1y9qwWGgq5YpZPt5YJ1KGjIrcFX59/PhNQX4khPOaD5g7ZQIDAQAB", AUTOSPLIT), 68 | 69 | // https://kb.mailbox.org/en/private/custom-domains/spf-dkim-and-dmarc-how-to-improve-spam-reputation-and-avoid-bounces 70 | CNAME("MBO0001._domainkey", "MBO0001._domainkey.mailbox.org."), 71 | CNAME("MBO0002._domainkey", "MBO0002._domainkey.mailbox.org."), 72 | CNAME("MBO0003._domainkey", "MBO0003._domainkey.mailbox.org."), 73 | CNAME("MBO0004._domainkey", "MBO0004._domainkey.mailbox.org."), 74 | 75 | // Google postmaster tools verification 76 | 77 | CNAME("uaqn4jv2xaoe", "gv-jun5dginqysxph.dv.googlehosted.com."), 78 | 79 | // Aliases for google services 80 | 81 | CNAME("login", "ghs.googlehosted.com."), 82 | CNAME("docs", "ghs.googlehosted.com."), 83 | CNAME("mail", "ghs.googlehosted.com."), 84 | CNAME("calendar", "ghs.googlehosted.com."), 85 | CNAME("sites", "ghs.googlehosted.com."), 86 | 87 | // Aliases for mailbox.org services 88 | 89 | CNAME("autoconfig", "mailbox.org."), 90 | SRV("_hkps._tcp", 1, 1, 443, "pgp.mailbox.org."), 91 | 92 | // Main web server and it's aliases 93 | 94 | osm_web_service("@", "ridley"), 95 | osm_web_service("www", "ridley"), 96 | osm_web_service("wiki", "ridley"), 97 | osm_web_service("blog", "ridley"), 98 | osm_web_service("crm", "ridley"), 99 | osm_web_service("join", "ridley"), 100 | osm_web_service("support", "ridley"), 101 | osm_web_service("supporting", "ridley"), 102 | osm_web_service("donate", "ridley"), 103 | osm_web_service("board", "ridley"), 104 | osm_web_service("dwg", "ridley"), 105 | osm_web_service("mwg", "ridley"), 106 | osm_web_service("operations", "naga"), 107 | 108 | // Nextcloud instance 109 | 110 | CNAME("files", "nextcloud-openstreetmapfoundation.cloud68.systems."), 111 | 112 | // Staging Blog 113 | osm_web_service("staging.blog", "tabaluga"), 114 | 115 | osm_web_service("hardware", "idris"), 116 | 117 | ); 118 | -------------------------------------------------------------------------------- /src/ptr_equinix_ams_ipv4.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | PTR(IPV4["dribble"], "dribble.openstreetmap.org."), 3 | PTR(IPV4["dulcy"], "dulcy.openstreetmap.org."), 4 | PTR(IPV4["faffy"], "faffy.openstreetmap.org."), 5 | PTR(IPV4["lockheed"], "lockheed.openstreetmap.org."), 6 | PTR(IPV4["norbert"], "norbert.openstreetmap.org."), 7 | PTR(IPV4["odin"], "odin.openstreetmap.org."), 8 | PTR(IPV4["spike-06"], "spike-06.openstreetmap.org."), 9 | PTR(IPV4["spike-07"], "spike-07.openstreetmap.org."), 10 | PTR(IPV4["spike-08"], "spike-08.openstreetmap.org."), 11 | PTR(IPV4["tabaluga"], "tabaluga.openstreetmap.org."), 12 | PTR(IPV4["vhagar"], "vhagar.openstreetmap.org."), 13 | PTR(IPV4["switch1.ams"], "switch1.ams.openstreetmap.org."), 14 | ); 15 | -------------------------------------------------------------------------------- /src/ptr_equinix_ams_ipv6.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | PTR(IPV6["dribble"], "dribble.openstreetmap.org."), 3 | PTR(IPV6["dulcy"], "dulcy.openstreetmap.org."), 4 | PTR(IPV6["faffy"], "faffy.openstreetmap.org."), 5 | PTR(IPV6["lockheed"], "lockheed.openstreetmap.org."), 6 | PTR(IPV6["norbert"], "norbert.openstreetmap.org."), 7 | PTR(IPV6["odin"], "odin.openstreetmap.org."), 8 | PTR(IPV6["spike-06"], "spike-06.openstreetmap.org."), 9 | PTR(IPV6["spike-07"], "spike-07.openstreetmap.org."), 10 | PTR(IPV6["spike-08"], "spike-08.openstreetmap.org."), 11 | PTR(IPV6["tabaluga"], "tabaluga.openstreetmap.org."), 12 | PTR(IPV6["vhagar"], "vhagar.openstreetmap.org."), 13 | PTR(IPV6["switch1.ams"], "switch1.ams.openstreetmap.org."), 14 | ); 15 | -------------------------------------------------------------------------------- /src/ptr_equinix_dub_ipv4.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | PTR(IPV4["culebre"], "culebre.openstreetmap.org."), 3 | PTR(IPV4["fafnir"], "fafnir.openstreetmap.org."), 4 | PTR(IPV4["fume"], "fume.openstreetmap.org."), 5 | PTR(IPV4["grisu"], "grisu.openstreetmap.org."), 6 | PTR(IPV4["horntail"], "horntail.openstreetmap.org."), 7 | PTR(IPV4["idris"], "idris.openstreetmap.org."), 8 | PTR(IPV4["konqi"], "konqi.openstreetmap.org."), 9 | PTR(IPV4["longma"], "longma.openstreetmap.org."), 10 | PTR(IPV4["muirdris"], "muirdris.openstreetmap.org."), 11 | PTR(IPV4["naga"], "naga.openstreetmap.org."), 12 | PTR(IPV4["smaug"], "smaug.openstreetmap.org."), 13 | PTR(IPV4["spike-01"], "spike-01.openstreetmap.org."), 14 | PTR(IPV4["spike-02"], "spike-02.openstreetmap.org."), 15 | PTR(IPV4["spike-03"], "spike-03.openstreetmap.org."), 16 | PTR(IPV4["switch1.dub"], "switch1.dub.openstreetmap.org."), 17 | ); 18 | -------------------------------------------------------------------------------- /src/ptr_equinix_dub_ipv6.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | PTR(IPV6["culebre"], "culebre.openstreetmap.org."), 3 | PTR(IPV6["fafnir"], "fafnir.openstreetmap.org."), 4 | PTR(IPV6["fume"], "fume.openstreetmap.org."), 5 | PTR(IPV6["grisu"], "grisu.openstreetmap.org."), 6 | PTR(IPV6["horntail"], "horntail.openstreetmap.org."), 7 | PTR(IPV6["idris"], "idris.openstreetmap.org."), 8 | PTR(IPV6["konqi"], "konqi.openstreetmap.org."), 9 | PTR(IPV6["longma"], "longma.openstreetmap.org."), 10 | PTR(IPV6["muirdris"], "muirdris.openstreetmap.org."), 11 | PTR(IPV6["naga"], "naga.openstreetmap.org."), 12 | PTR(IPV6["smaug"], "smaug.openstreetmap.org."), 13 | PTR(IPV6["spike-01"], "spike-01.openstreetmap.org."), 14 | PTR(IPV6["spike-02"], "spike-02.openstreetmap.org."), 15 | PTR(IPV6["spike-03"], "spike-03.openstreetmap.org."), 16 | PTR(IPV6["switch1.dub"], "switch1.dub.openstreetmap.org."), 17 | ); 18 | -------------------------------------------------------------------------------- /src/ptr_he_ams_ipv4.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | PTR(IPV4["dribble.he"], "dribble.he.openstreetmap.org."), 3 | PTR(IPV4["dulcy.he"], "dulcy.he.openstreetmap.org."), 4 | PTR(IPV4["faffy.he"], "faffy.he.openstreetmap.org."), 5 | PTR(IPV4["lockheed.he"], "lockheed.he.openstreetmap.org."), 6 | PTR(IPV4["norbert.he"], "norbert.he.openstreetmap.org."), 7 | PTR(IPV4["odin.he"], "odin.he.openstreetmap.org."), 8 | PTR(IPV4["spike-06.he"], "spike-06.he.openstreetmap.org."), 9 | PTR(IPV4["spike-07.he"], "spike-07.he.openstreetmap.org."), 10 | PTR(IPV4["spike-08.he"], "spike-08.he.openstreetmap.org."), 11 | PTR(IPV4["tabaluga.he"], "tabaluga.he.openstreetmap.org."), 12 | PTR(IPV4["vhagar.he"], "vhagar.he.openstreetmap.org."), 13 | PTR(IPV4["switch1.he.ams"], "switch1.he.ams.openstreetmap.org."), 14 | ); 15 | -------------------------------------------------------------------------------- /src/ptr_he_ams_ipv6.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | PTR(IPV6["dribble.he"], "dribble.he.openstreetmap.org."), 3 | PTR(IPV6["dulcy.he"], "dulcy.he.openstreetmap.org."), 4 | PTR(IPV6["faffy.he"], "faffy.he.openstreetmap.org."), 5 | PTR(IPV6["lockheed.he"], "lockheed.he.openstreetmap.org."), 6 | PTR(IPV6["norbert.he"], "norbert.he.openstreetmap.org."), 7 | PTR(IPV6["odin.he"], "odin.he.openstreetmap.org."), 8 | PTR(IPV6["spike-06.he"], "spike-06.he.openstreetmap.org."), 9 | PTR(IPV6["spike-07.he"], "spike-07.he.openstreetmap.org."), 10 | PTR(IPV6["spike-08.he"], "spike-08.he.openstreetmap.org."), 11 | PTR(IPV6["tabaluga.he"], "tabaluga.he.openstreetmap.org."), 12 | PTR(IPV6["vhagar.he"], "vhagar.he.openstreetmap.org."), 13 | PTR(IPV6["switch1.he.ams"], "switch1.he.ams.openstreetmap.org."), 14 | ); 15 | -------------------------------------------------------------------------------- /src/ptr_he_dub_ipv4.js: -------------------------------------------------------------------------------- 1 | // http://www.he.net/adm/reverse.dns.html (RFC4183 notation) 2 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 3 | PTR(IPV4["culebre.he"], "culebre.he.openstreetmap.org."), 4 | PTR(IPV4["fafnir.he"], "fafnir.he.openstreetmap.org."), 5 | PTR(IPV4["fume.he"], "fume.he.openstreetmap.org."), 6 | PTR(IPV4["grisu.he"], "grisu.he.openstreetmap.org."), 7 | PTR(IPV4["horntail.he"], "horntail.he.openstreetmap.org."), 8 | PTR(IPV4["idris.he"], "idris.he.openstreetmap.org."), 9 | PTR(IPV4["konqi.he"], "konqi.he.openstreetmap.org."), 10 | PTR(IPV4["longma.he"], "longma.he.openstreetmap.org."), 11 | PTR(IPV4["muirdris.he"], "muirdris.he.openstreetmap.org."), 12 | PTR(IPV4["naga.he"], "naga.he.openstreetmap.org."), 13 | PTR(IPV4["smaug.he"], "smaug.he.openstreetmap.org."), 14 | PTR(IPV4["spike-01.he"], "spike-01.he.openstreetmap.org."), 15 | PTR(IPV4["spike-02.he"], "spike-02.he.openstreetmap.org."), 16 | PTR(IPV4["spike-03.he"], "spike-03.he.openstreetmap.org."), 17 | PTR(IPV4["switch1.he.dub"], "switch1.he.dub.openstreetmap.org."), 18 | ); 19 | -------------------------------------------------------------------------------- /src/ptr_he_dub_ipv6.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | PTR(IPV6["culebre.he"], "culebre.he.openstreetmap.org."), 3 | PTR(IPV6["fafnir.he"], "fafnir.he.openstreetmap.org."), 4 | PTR(IPV6["fume.he"], "fume.he.openstreetmap.org."), 5 | PTR(IPV6["grisu.he"], "grisu.he.openstreetmap.org."), 6 | PTR(IPV6["horntail.he"], "horntail.he.openstreetmap.org."), 7 | PTR(IPV6["idris.he"], "idris.he.openstreetmap.org."), 8 | PTR(IPV6["konqi.he"], "konqi.he.openstreetmap.org."), 9 | PTR(IPV6["longma.he"], "longma.he.openstreetmap.org."), 10 | PTR(IPV6["muirdris.he"], "muirdris.he.openstreetmap.org."), 11 | PTR(IPV6["naga.he"], "naga.he.openstreetmap.org."), 12 | PTR(IPV6["smaug.he"], "smaug.he.openstreetmap.org."), 13 | PTR(IPV6["spike-01.he"], "spike-01.he.openstreetmap.org."), 14 | PTR(IPV6["spike-02.he"], "spike-02.he.openstreetmap.org."), 15 | PTR(IPV6["spike-03.he"], "spike-03.he.openstreetmap.org."), 16 | PTR(IPV6["switch1.he.dub"], "switch1.he.dub.openstreetmap.org."), 17 | ); 18 | -------------------------------------------------------------------------------- /src/stateofthemap-eu.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Email delivery 17 | SPF_BUILDER({ 18 | label: "@", 19 | parts: [ 20 | "v=spf1", 21 | "include:secureserver.net", 22 | "-all" 23 | ] 24 | }), 25 | 26 | TXT("_dmarc", "v=DMARC1; p=none;"), 27 | 28 | CNAME("k2._domainkey", "dkim2.mcsv.net."), 29 | CNAME("k3._domainkey", "dkim3.mcsv.net."), 30 | A("mail", "92.205.4.228"), 31 | 32 | MX("@", 10, "mail"), 33 | 34 | // Web service for stateofthemap.eu index site 35 | osm_web_service("@", "naga"), 36 | osm_web_service("www", "naga"), 37 | 38 | // 2025 SoTM site 39 | CNAME("2025", "osm-uk.github.io."), 40 | 41 | // Previous editions 42 | 43 | A("2014", "49.12.5.171"), 44 | CNAME("2023", "osmbe.github.io."), 45 | CNAME("2024", "openstreetmap-polska.github.io."), 46 | 47 | ); 48 | -------------------------------------------------------------------------------- /src/stateofthemap.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // SPF policy 17 | 18 | SPF_BUILDER({ 19 | label: "@", 20 | parts: [ 21 | "v=spf1", 22 | "include:_spf.google.com", // Google GSuite 23 | "ip4:212.110.172.32", // shenron ipv4 24 | "ip6:2001:41c9:1:400::32", // shenron ipv6 25 | "ip4:184.104.226.98", // fafnir ipv4 26 | "ip6:2001:470:1:b3b::2", // fafnir ipv6 27 | "-all" 28 | ] 29 | }), 30 | 31 | // Let google handle email 32 | 33 | MX("@", 1, "aspmx.l.google.com."), 34 | MX("@", 5, "alt1.aspmx.l.google.com."), 35 | MX("@", 5, "alt2.aspmx.l.google.com."), 36 | MX("@", 10, "alt3.aspmx.l.google.com."), 37 | MX("@", 10, "alt4.aspmx.l.google.com."), 38 | 39 | // Aliases for google services 40 | 41 | CNAME("login", "ghs.googlehosted.com."), 42 | CNAME("docs", "ghs.googlehosted.com."), 43 | CNAME("mail", "ghs.googlehosted.com."), 44 | CNAME("calendar", "ghs.googlehosted.com."), 45 | CNAME("sites", "ghs.googlehosted.com."), 46 | 47 | // Main web server and it's aliases 48 | 49 | osm_web_service("@", "naga"), 50 | osm_web_service("www", "naga"), 51 | osm_web_service("2025", "naga"), 52 | osm_web_service("2024", "naga"), 53 | osm_web_service("2022", "naga"), 54 | osm_web_service("2021", "naga"), 55 | osm_web_service("2020", "naga"), 56 | osm_web_service("2019", "naga"), 57 | osm_web_service("2018", "naga"), 58 | osm_web_service("2017", "naga"), 59 | osm_web_service("2016", "naga"), 60 | osm_web_service("2013", "naga"), 61 | osm_web_service("2012", "ridley"), 62 | osm_web_service("2011", "ridley"), 63 | osm_web_service("2010", "ridley"), 64 | osm_web_service("2009", "naga"), 65 | osm_web_service("2008", "naga"), 66 | osm_web_service("2007", "naga"), 67 | 68 | // Google Site Verification - Grant 69 | TXT("2022", "google-site-verification=wT1dJzSYM_2By372lJ_v9IU1crF21qOySEAPABxUcyo"), 70 | TXT("@", "google-site-verification=pqJHZHtrC4UhevQdPlR_2gVDPml6UCwmyHq75bfWLRQ"), 71 | 72 | ); 73 | -------------------------------------------------------------------------------- /src/switch2osm.js: -------------------------------------------------------------------------------- 1 | D(DOMAIN, REGISTRAR, DnsProvider(PROVIDER), 2 | 3 | // Publish CAA records indicating that only letsencrypt should issue certificates 4 | 5 | CAA_BUILDER({ 6 | label: "@", 7 | iodef: "mailto:hostmaster@openstreetmap.org", 8 | issue: [ 9 | "letsencrypt.org", 10 | ], 11 | issuewild: [ 12 | "letsencrypt.org", 13 | ], 14 | }), 15 | 16 | // Delegate SPF policy to the main domain 17 | 18 | SPF_BUILDER({ 19 | label: "@", 20 | parts: [ 21 | "v=spf1", 22 | "include:openstreetmap.org", // main openstreetmap.org spf record 23 | "-all" 24 | ] 25 | }), 26 | 27 | // Main web server and it's aliases 28 | 29 | osm_web_service("@", "naga"), 30 | osm_web_service("www", "naga"), 31 | 32 | ); 33 | --------------------------------------------------------------------------------