diff --git a/docs/servers.md b/docs/servers.md index 8c97d456bb119d866e599095c3f205ea611bf012..f72f11d190e61c8c1af21af776391a6101412748 100644 --- a/docs/servers.md +++ b/docs/servers.md @@ -85,7 +85,6 @@ So to set up this server from scratch, run: ### Services - Regular mirror. - - Running a authoritative DNS server (PowerDNS) for our GeoIP mirror ## reproducible.archlinux.org @@ -135,6 +134,7 @@ Prometheus, and Grafana server which receives selected performance/metrics from ### Services - Redirects (nginx redirects) + - Authoritative DNS server (PowerDNS) for ACME DNS challenges - ping ## security.archlinux.org diff --git a/group_vars/all/geo.yml b/group_vars/all/geo.yml new file mode 100644 index 0000000000000000000000000000000000000000..a70e3a1585d452338535079b5f80eb1f20a76ff2 --- /dev/null +++ b/group_vars/all/geo.yml @@ -0,0 +1,5 @@ +geo_acme_dns_challenge_ns: redirect.archlinux.org +geo_domains: + - geo.mirror.pkgbuild.com +geo_health_check_paths: + geo.mirror.pkgbuild.com: /lastupdate diff --git a/group_vars/geo_mirrors.yml b/group_vars/geo_mirrors.yml deleted file mode 100644 index f1babee47d019f34d554d97653ec80ebdc1d5677..0000000000000000000000000000000000000000 --- a/group_vars/geo_mirrors.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -certbot_dns_support: true diff --git a/group_vars/geo_mirrors/misc.yml b/group_vars/geo_mirrors/misc.yml new file mode 100644 index 0000000000000000000000000000000000000000..e560d4eb51c572d53a8835f02774a3a42958a954 --- /dev/null +++ b/group_vars/geo_mirrors/misc.yml @@ -0,0 +1,3 @@ +--- +certbot_dns_support: true +geo_mirror_domain: "geo.mirror.pkgbuild.com" diff --git a/group_vars/geo_mirrors/vault_certbot.yml b/group_vars/geo_mirrors/vault_certbot.yml new file mode 120000 index 0000000000000000000000000000000000000000..760d5f94f435cbe9cc884917061dc28dbcb1445b --- /dev/null +++ b/group_vars/geo_mirrors/vault_certbot.yml @@ -0,0 +1 @@ +../../host_vars/redirect.archlinux.org/vault_certbot.yml \ No newline at end of file diff --git a/group_vars/mirrors/misc.yml b/group_vars/mirrors/misc.yml index 10bf4901525592e4a86268de31b084c3ce35326d..a424fa109db74921a3edd248d707887f9d081e3d 100644 --- a/group_vars/mirrors/misc.yml +++ b/group_vars/mirrors/misc.yml @@ -1,6 +1,5 @@ --- archweb_db_host: "{{ hostvars['archlinux.org']['wireguard_address'] }}" -geo_mirror_domain: "geo.mirror.pkgbuild.com" # raise tcp window limits to 32MiB tcp_rmem: "10240 87380 33554432" diff --git a/group_vars/mirrors/vault_certbot.yml b/group_vars/mirrors/vault_certbot.yml deleted file mode 100644 index 9a7c83b1e5f8c02ad4226b33ab0449c2cb1437ea..0000000000000000000000000000000000000000 --- a/group_vars/mirrors/vault_certbot.yml +++ /dev/null @@ -1,18 +0,0 @@ -$ANSIBLE_VAULT;1.1;AES256 -33353333666434623961613663633633383731373033316562663738626365613338376533353063 -6630303162373830353863393932363365666130346235340a653238636534636266633137313435 -38386562313930373762386635346264363839623239616662663733636262326331656365643732 -3861396531336463320a623339333461316132666333326136326561633966636136346636303662 -31353932303931666361333038356363633234343130633831636632383063313135616633343263 -38383562326464363061633031636263313534363035656230323137303663653966346231336535 -36653835626632393232633538616365383532643830636633666635393335336538356631353039 -66363836653935316664353161363038376562333764613062316536643034623436303337396639 -64316234623830613739303866653139316362663461376132616464613432303734373761373434 -65323965623431376665353338316531346363303338613863633030656136643933363331396539 -66663362346530643332386436653663336564623664303838386637353061376561626364383433 -37616133643861646536363535613133366664643764356665343162623439333462323634386134 -66343335656334356466636430613634393235613462666362656632316665663235346233363435 -64343031376230393735333761376561393838633734646434626333306666373231353461343561 -38666266666230383330306566653438633566613565386565383565356532653438376234356233 -62373434656634343061333535663135396432383039306566626636666163356534306665623765 -33363030356637376462323934313731326236623765613666356165336165313366 diff --git a/host_vars/mirror.pkgbuild.com/misc b/host_vars/mirror.pkgbuild.com/misc index 8759253d8d08ac13fe643bead1f1bdea8052e143..1663410dd031d63e5835868ca0f72dbc108bc897 100644 --- a/host_vars/mirror.pkgbuild.com/misc +++ b/host_vars/mirror.pkgbuild.com/misc @@ -1,7 +1,6 @@ --- mirror_domain: mirror.pkgbuild.com mirror_debug_packages: false -geomirror_acme_challenge: true archweb_mirrorcheck_locations: [20, 21] filesystem: btrfs diff --git a/host_vars/redirect.archlinux.org/misc b/host_vars/redirect.archlinux.org/misc index 8a6ff0110f457e0236813ad1b51f935a466b6fa3..ce24a877c423ca713852a3e505bbc6615e547cdc 100644 --- a/host_vars/redirect.archlinux.org/misc +++ b/host_vars/redirect.archlinux.org/misc @@ -2,3 +2,6 @@ filesystem: btrfs wireguard_address: 10.0.0.25 wireguard_public_key: n11Ps2sc0Cxsi1sLaYFq7dkhlDtTnOZCGovRYbzDGR8= + +ipv4_address: "95.216.195.133" +ipv6_address: "2a01:4f9:c010:2636::1" diff --git a/host_vars/redirect.archlinux.org/vault_certbot.yml b/host_vars/redirect.archlinux.org/vault_certbot.yml new file mode 100644 index 0000000000000000000000000000000000000000..224f5bbcdba4860643ce2a9b8f0ee6d27833e3ac --- /dev/null +++ b/host_vars/redirect.archlinux.org/vault_certbot.yml @@ -0,0 +1,18 @@ +$ANSIBLE_VAULT;1.1;AES256 +39626637376631343762626362663831313061353261646164316339663936363938396561363864 +3761623339613362373235326161303736303634333564350a393861623461316661646239393935 +64333234383435313865653463616139393562633735616331343964623032326534393138616161 +6462616265666633380a393862646464373438633835383239623435373636613964623839663939 +39373638356461383331393732626665373436653137373666303465666632383133333237386564 +61353965333432323432383365313263336234366163363330663234656530326265373530663238 +37353561663035363239653763383731313062646538383839383831306562336335363236373036 +33613562623661343965626164386332306164373861316561383239666261393464656536373062 +35646637303036333138643966383239666564323539653866373738346565346238323266376434 +39383064343164373537353866363834663066363333343035373832653261353966653662333736 +32626662636330313261643636663233353536396136353263666461616630393164316435613264 +64643563333337396439643036623739303766313661316266343962386630316366346432376537 +66333863343362323362356333613064613333653161663564616234363263373863663530353038 +37316661376435373239643035343664653133363862323536613164386136376164663763316362 +63646363326333663637613761373032383135393331663361363462386631653266336532663938 +36363135316634383062613562306332663363383630323762333334346339346161393536353466 +30656162633164376635313839646633663133343736386630383439666636613963 diff --git a/playbooks/mirrors.yml b/playbooks/mirrors.yml index 75184d5663166501f4c0581989ff8ab3af302852..f135ab5d05f7184d8766ae1612c0ba5c040f7485 100644 --- a/playbooks/mirrors.yml +++ b/playbooks/mirrors.yml @@ -15,4 +15,4 @@ - { role: promtail } - { role: fail2ban } - { role: wireguard } - - { role: geomirror, when: "inventory_hostname == 'mirror.pkgbuild.com' or 'geo_mirrors' in group_names" } + - { role: geomirror, when: "'geo_mirrors' in group_names" } diff --git a/playbooks/redirect.archlinux.org.yml b/playbooks/redirect.archlinux.org.yml index f2d15df759f53c65a5674998d05a6effbef97b95..53fbc6ba2c14ced53970fccbb860d5e2db750ae6 100644 --- a/playbooks/redirect.archlinux.org.yml +++ b/playbooks/redirect.archlinux.org.yml @@ -14,3 +14,4 @@ - { role: promtail } - { role: hardening } - { role: ping } + - { role: acme_dns_challenge } diff --git a/roles/acme_dns_challenge/handlers/main.yml b/roles/acme_dns_challenge/handlers/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..ee953235084233b13220d92752900f740d077485 --- /dev/null +++ b/roles/acme_dns_challenge/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart powerdns + service: name=pdns state=restarted diff --git a/roles/acme_dns_challenge/tasks/main.yml b/roles/acme_dns_challenge/tasks/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..77e21e66f38235b8b83515860ae507ac01687c18 --- /dev/null +++ b/roles/acme_dns_challenge/tasks/main.yml @@ -0,0 +1,45 @@ +--- +- name: install powerdns + pacman: name=powerdns state=present + +- name: install PowerDNS configuration + template: src={{ item.src }} dest=/etc/powerdns/{{ item.dest }} owner=root group=root mode=0644 + loop: + - {src: pdns.conf.j2, dest: pdns.conf} + - {src: dnsupdate-policy.lua.j2, dest: dnsupdate-policy.lua} + notify: restart powerdns + +- name: create directory for sqlite3 dbs + file: path=/var/lib/powerdns state=directory owner=powerdns group=powerdns mode=0755 + +- name: initialize sqlite3 database for _acme-challenge zones + command: sqlite3 -init /usr/share/doc/powerdns/schema.sqlite3.sql /var/lib/powerdns/pdns.sqlite3 "" + become: true + become_user: powerdns + args: + creates: /var/lib/powerdns/pdns.sqlite3 + +- name: create _acme-challenge zones + shell: | + pdnsutil create-zone _acme-challenge.{{ item }} {{ inventory_hostname }} + pdnsutil replace-rrset _acme-challenge.{{ item }} @ SOA "{{ inventory_hostname }}. root.archlinux.org. 0 10800 3600 604800 3600" + loop: "{{ geo_domains }}" + become: true + become_user: powerdns + changed_when: false + +- name: import TSIG key (for certbot) + command: pdnsutil import-tsig-key {{ certbot_rfc2136_key }} {{ certbot_rfc2136_algorithm }} {{ certbot_rfc2136_secret }} + changed_when: false + +- name: open powerdns ipv4 port for monitoring.archlinux.org + ansible.posix.firewalld: zone=wireguard state=enabled permanent=true immediate=yes + rich_rule="rule family=ipv4 source address={{ hostvars['monitoring.archlinux.org']['wireguard_address'] }} port protocol=tcp port=8081 accept" + tags: + - firewall + +- name: open firewall hole + ansible.posix.firewalld: service=dns permanent=true state=enabled immediate=yes + +- name: start and enable powerdns + systemd: name=pdns.service enabled=yes daemon_reload=yes state=started diff --git a/roles/geomirror/templates/dnsupdate-policy.lua.j2 b/roles/acme_dns_challenge/templates/dnsupdate-policy.lua.j2 similarity index 81% rename from roles/geomirror/templates/dnsupdate-policy.lua.j2 rename to roles/acme_dns_challenge/templates/dnsupdate-policy.lua.j2 index b9185cc5a8746921f0223f34e44c4b40e533ebd1..50fc8a2223780aedcdd8a6618e25d9afd50358f2 100644 --- a/roles/geomirror/templates/dnsupdate-policy.lua.j2 +++ b/roles/acme_dns_challenge/templates/dnsupdate-policy.lua.j2 @@ -1,6 +1,11 @@ +#jinja2: lstrip_blocks: True -- Based on https://github.com/PowerDNS/pdns/wiki/Lua-Examples-(Authoritative)#updatepolicy-access-control-for-rfc2136-dynamic-updates function updatepolicy(input) - acme_challenge_rrname = "_acme-challenge.{{ geo_mirror_domain }}." + valid_rrnames = { + {% for domain in geo_domains %} + ["_acme-challenge.{{ domain }}."]=true, + {% endfor %} + } -- only allow updates from our servers mynetworks = newNMG() @@ -26,7 +31,7 @@ function updatepolicy(input) end -- only accept TXT record updates for _acme_challenge - if input:getQType() == pdns.TXT and input:getQName():toString() == acme_challenge_rrname + if input:getQType() == pdns.TXT and valid_rrnames[input:getQName():toString()] then pdnslog("updatepolicy: query checks successful", pdns.loglevels.Info) return true diff --git a/roles/acme_dns_challenge/templates/pdns.conf.j2 b/roles/acme_dns_challenge/templates/pdns.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..49b1264784f201ed751aea70f970eba05b62f7fc --- /dev/null +++ b/roles/acme_dns_challenge/templates/pdns.conf.j2 @@ -0,0 +1,10 @@ +setgid=powerdns +setuid=powerdns +local-address={{ ipv4_address }},{{ ipv6_address }} +webserver=yes +webserver-address=0.0.0.0 +webserver-allow-from=127.0.0.1,::1,{{ hostvars['monitoring.archlinux.org']['wireguard_address'] }} +launch=gsqlite3 +gsqlite3-database=/var/lib/powerdns/pdns.sqlite3 +dnsupdate=yes +lua-dnsupdate-policy-script=/etc/powerdns/dnsupdate-policy.lua diff --git a/roles/geomirror/defaults/main.yml b/roles/geomirror/defaults/main.yml deleted file mode 100644 index b82cec9d855633a7dac50735bf4f953c5e12d1e3..0000000000000000000000000000000000000000 --- a/roles/geomirror/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -geomirror_acme_challenge: false diff --git a/roles/geomirror/tasks/main.yml b/roles/geomirror/tasks/main.yml index 55c15d03ab13cb32cd6309f8934f24c67ebbefdd..c7a251f13e6803efb8130c02bc4fe9a832074656 100644 --- a/roles/geomirror/tasks/main.yml +++ b/roles/geomirror/tasks/main.yml @@ -7,36 +7,8 @@ loop: - {src: pdns.conf.j2, dest: pdns.conf} - {src: geo.yml.j2, dest: geo.yml} - - {src: dnsupdate-policy.lua.j2, dest: dnsupdate-policy.lua} notify: restart powerdns -- name: create directory for sqlite3 dbs - file: path=/var/lib/powerdns state=directory owner=powerdns group=powerdns mode=0755 - when: geomirror_acme_challenge - -- name: initialize sqlite3 database for _acme-challenge zone - command: sqlite3 -init /usr/share/doc/powerdns/schema.sqlite3.sql /var/lib/powerdns/pdns.sqlite3 "" - become: true - become_user: powerdns - args: - creates: /var/lib/powerdns/pdns.sqlite3 - register: init - when: geomirror_acme_challenge - -- name: create _acme-challenge zone - command: "{{ item }}" - loop: - - pdnsutil create-zone _acme-challenge.{{ geo_mirror_domain }} mirror.pkgbuild.com - - pdnsutil replace-rrset _acme-challenge.{{ geo_mirror_domain }} @ SOA "mirror.pkgbuild.com. root.archlinux.org. 0 10800 3600 604800 3600" - become: true - become_user: powerdns - when: init.changed - -- name: import TSIG key (for certbot) - command: pdnsutil import-tsig-key {{ certbot_rfc2136_key }} {{ certbot_rfc2136_algorithm }} {{ certbot_rfc2136_secret }} - changed_when: false - when: geomirror_acme_challenge - - name: open powerdns ipv4 port for monitoring.archlinux.org ansible.posix.firewalld: zone=wireguard state=enabled permanent=true immediate=yes rich_rule="rule family=ipv4 source address={{ hostvars['monitoring.archlinux.org']['wireguard_address'] }} port protocol=tcp port=8081 accept" diff --git a/roles/geomirror/templates/geo.yml.j2 b/roles/geomirror/templates/geo.yml.j2 index 82533fff92f513f639729dd921112194263339c0..485f62b27754910b79bdb082ef9778475c53a8ec 100644 --- a/roles/geomirror/templates/geo.yml.j2 +++ b/roles/geomirror/templates/geo.yml.j2 @@ -1,12 +1,13 @@ #jinja2:lstrip_blocks: True --- domains: - - domain: {{ geo_mirror_domain }} + {% for domain in geo_domains %} + - domain: {{ domain }} ttl: 3600 records: - {{ geo_mirror_domain }}: - - soa: mirror.pkgbuild.com. root.archlinux.org. 2022042701 3600 1800 604800 3600 - {% for host in groups['geo_mirrors'] + ['mirror.pkgbuild.com'] %} + {{ domain }}: + - soa: {{ groups['geo_mirrors'] | first }}. root.archlinux.org. 2022042701 3600 1800 604800 3600 + {% for host in groups['geo_mirrors'] %} - ns: ttl: 86400 content: {{ host }} @@ -14,16 +15,15 @@ domains: - lua: ttl: 300 content: > - A "ifurlup('https://{{ geo_mirror_domain }}/lastupdate', + A "ifurlup('https://{{ domain }}{{ geo_health_check_paths[domain] | default('/') }}', {'{{ groups['geo_mirrors'] | map('extract', hostvars, ['ipv4_address']) | join("', '") }}'}, {selector='pickclosest', useragent='pdns on {{ inventory_hostname }}'})" - lua: ttl: 300 content: > - AAAA "ifurlup('https://{{ geo_mirror_domain }}/lastupdate', + AAAA "ifurlup('https://{{ domain }}{{ geo_health_check_paths[domain] | default('/') }}', {'{{ groups['geo_mirrors'] | map('extract', hostvars, ['ipv6_address']) | join("', '") }}'}, {selector='pickclosest', useragent='pdns on {{ inventory_hostname }}'})" - {% if not geomirror_acme_challenge %} - _acme-challenge.{{ geo_mirror_domain }}: - - ns: mirror.pkgbuild.com - {% endif %} + _acme-challenge.{{ domain }}: + - ns: {{ geo_acme_dns_challenge_ns }} + {% endfor %} diff --git a/roles/geomirror/templates/pdns.conf.j2 b/roles/geomirror/templates/pdns.conf.j2 index 6539ab25d0565583c5e0e69d2207d7236a473a4b..6b1d467c5f9cde1364e0b7ba101acd1b6dd7df80 100644 --- a/roles/geomirror/templates/pdns.conf.j2 +++ b/roles/geomirror/templates/pdns.conf.j2 @@ -4,14 +4,7 @@ local-address={{ ipv4_address }},{{ ipv6_address }} webserver=yes webserver-address=0.0.0.0 webserver-allow-from=127.0.0.1,::1,{{ hostvars['monitoring.archlinux.org']['wireguard_address'] }} -{% if geomirror_acme_challenge %} -launch=geoip,gsqlite3 -gsqlite3-database=/var/lib/powerdns/pdns.sqlite3 -dnsupdate=yes -lua-dnsupdate-policy-script=/etc/powerdns/dnsupdate-policy.lua -{% else %} launch=geoip -{% endif %} geoip-database-files=/var/lib/GeoIP/GeoLite2-City.mmdb geoip-zones-file=/etc/powerdns/geo.yml enable-lua-records diff --git a/roles/prometheus/defaults/main.yml b/roles/prometheus/defaults/main.yml index 203b1101cf26e499637f56220221202a1cf422e7..4f53dc492ced11a89aa96ca4473d54850f54106d 100644 --- a/roles/prometheus/defaults/main.yml +++ b/roles/prometheus/defaults/main.yml @@ -75,8 +75,8 @@ blackbox_targets: smtp_starttls: - mail.archlinux.org:25 - lists.archlinux.org:25 - dns_geomirror_a: "{{ groups['geo_mirrors'] + ['mirror.pkgbuild.com'] }}" - dns_geomirror_aaaa: "{{ groups['geo_mirrors'] + ['mirror.pkgbuild.com'] }}" + dns_geomirror_a: "{{ groups['geo_mirrors'] }}" + dns_geomirror_aaaa: "{{ groups['geo_mirrors'] }}" matrix_metrics_endpoints: - homeserver - appservice diff --git a/roles/prometheus/templates/prometheus.yml.j2 b/roles/prometheus/templates/prometheus.yml.j2 index 96a38e31851fa6eebfef451b0b1485bc7641adb3..e700cb6373674905425f0eea07954ca23b98a53f 100644 --- a/roles/prometheus/templates/prometheus.yml.j2 +++ b/roles/prometheus/templates/prometheus.yml.j2 @@ -74,7 +74,7 @@ scrape_configs: - job_name: 'powerdns' static_configs: - {% for host in groups['geo_mirrors'] + ['mirror.pkgbuild.com'] %} + {% for host in groups['geo_mirrors'] + [geo_acme_dns_challenge_ns] %} - targets: ['{{ hostvars[host]['wireguard_address'] }}:8081'] labels: instance: "{{ host }}" diff --git a/tf-stage1/templates.tf b/tf-stage1/templates.tf index 9b97dd3b8d70ab44936fc9dc847a2baaedbd3f4b..24df546277ab610aab1bebb9c3498207f217f6ac 100644 --- a/tf-stage1/templates.tf +++ b/tf-stage1/templates.tf @@ -146,16 +146,6 @@ resource "hetznerdns_record" "machine_aaaa" { resource "hetznerdns_record" "geo_ns1" { for_each = local.geo_domains - zone_id = each.value.zone_id - name = each.value.name - value = "mirror.pkgbuild.com." - type = "NS" - ttl = 86400 -} - -resource "hetznerdns_record" "geo_ns2" { - for_each = local.geo_domains - zone_id = each.value.zone_id name = each.value.name value = "asia.mirror.pkgbuild.com." @@ -163,7 +153,7 @@ resource "hetznerdns_record" "geo_ns2" { ttl = 86400 } -resource "hetznerdns_record" "geo_ns3" { +resource "hetznerdns_record" "geo_ns2" { for_each = local.geo_domains zone_id = each.value.zone_id @@ -173,7 +163,7 @@ resource "hetznerdns_record" "geo_ns3" { ttl = 86400 } -resource "hetznerdns_record" "geo_ns4" { +resource "hetznerdns_record" "geo_ns3" { for_each = local.geo_domains zone_id = each.value.zone_id