commit af0dd903527555d0eeabe621365f725de0e8a4b5 Author: surtur Date: Mon Jul 3 14:01:38 2023 +0200 initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..07ea92a --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +source_env ${XDG_RUNTIME_DIR}/secrets/infra-vars diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a24153f --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Created by https://www.toptal.com/developers/gitignore/api/terraform +# Edit at https://www.toptal.com/developers/gitignore?templates=terraform + +### Terraform ### +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# End of https://www.toptal.com/developers/gitignore/api/terraform + diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl new file mode 100644 index 0000000..8fe4ac7 --- /dev/null +++ b/.terraform.lock.hcl @@ -0,0 +1,23 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/linode/linode" { + version = "2.5.0" + hashes = [ + "h1:EzUubjT9XxUhTt8bCKISIF1KC9HpmyqTrkmQqAsZIRE=", + "zh:00c3391c1d10ff0421ea6629f842fc4b36dd3c38fa01ea8a76b57687b2087e89", + "zh:660051ad5e081b6789c995cbf1ee8ac8940e74cef0f0301c4e4493e40fc6cec2", + "zh:6772f8dbbbc6fef4af13b59cedb9ce8d50fd6380ddcb8a78d9e6d63998a59b43", + "zh:689c3c37a3eee3750fc032111c4589861c976231e2f776c093de52663c6286bc", + "zh:724a4b25c00f00d3f6495bd8984385e4d6adf42fdd4d9410ae3721dddafbba1e", + "zh:849240355fcab00c206b424c7a26b5f596caf0bf0723326cd9e1d88402db3650", + "zh:97b0633a1d5c3229222807a97767c75d3b729d31a72d5e5854acd3c77526a900", + "zh:9b85fcb432fe6bad7e542c1adef44ffa4f2a3fb0ac50361d7840c0ec6b001bee", + "zh:c5fd629bfadadb41e593115082b5c8f7bb1a67b8799a1c8d591e501b86ef5eaf", + "zh:d394c005dd3185bd3e8ef38698b175f0dc3961385bf6b584eeb1c2951edfe471", + "zh:e74c24a4d58e104a7e25c9b2fac293f12effaaa7bbf68bad603a320830b1f9d8", + "zh:f1a11f3dc4a9d9da9a2245ce4a9ce75be583a9dbe10b729a54c295cc0239cc0a", + "zh:f2127af74eadfa592f426499af7957451033c752e8e526047d337d3aaaaf3bee", + "zh:f3f5d1c072702c52df6c0d8952058d335c580298bff3bae131ad20104ed1d1ee", + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..94ad701 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# [`infra`][infra] + +this repo holds the code describing my very own infra (machines I use/manage) +and is very much a WIP. + +should contain zero secrets, except encrypted either with [`age`][age] or +[`ansible-vault`][ansible-vault]. + +[`terraform`][tf] secrets are supplied as ENV vars at runtime by sourcing the +decrypted `infra-vars` file using [`direnv`][direnv], which is in turn +stationed in its place using [`home-manager`][hm]. + +[infra]: https://git.dotya.ml/wanderer/infra +[age]: https://github.com/FiloSottile/age +[ansible-vault]: https://docs.ansible.com/ansible/latest/cli/ansible-vault.html +[tf]: https://www.terraform.io/ +[direnv]: https://direnv.net/ +[hm]: https://github.com/nix-community/home-manager diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000..a1b9478 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,14 @@ +[defaults] +inventory = hosts +remote_tmp = $HOME/.ansible/tmp +remote_user = root +nocows = 1 +roles_path = roles +vault_identity_list = default@misc/vault-keyring-client.sh +vault_id_match = True +retry_files_enabled = False + +[ssh_connection] +pipelining = True +scp_if_ssh = True +retries = 5 diff --git a/ansible/group_vars/all/root_access.yml b/ansible/group_vars/all/root_access.yml new file mode 100644 index 0000000..2ffd2dd --- /dev/null +++ b/ansible/group_vars/all/root_access.yml @@ -0,0 +1,15 @@ +--- +keys: &default_agekeys + - age1rw65fywnja3kdgw9tsnhaa7xzf3c5zd7y2fggn0emhcxsfltxdlsh3pe95 # the + - 'ssh-ed25519\ AAAAC3NzaC1lZDI1NTE5AAAAIGzJL8/M+tTejrAPoomHKtlYk8lINBLHaH+p4SLt3sBG' # theEd + - age15959gprm59azjflvpj97yt0lj6dj4d2yv0nd6u9jp32lzwp3de7qzhf85y # BACKUPKEY + + +# run 'playbooks/tasks/reencrypt-default-key.yml' when this changes +vault_default_agekeys: + - *default_agekeys + - 'ssh-ed25519\ AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL' + +# run 'playbooks/tasks/reencrypt-super-key.yml' when this changes +vault_super_agekeys: + - 'ssh-ed25519\ AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL' diff --git a/ansible/group_vars/common.yml b/ansible/group_vars/common.yml new file mode 100644 index 0000000..4ca060c --- /dev/null +++ b/ansible/group_vars/common.yml @@ -0,0 +1,48 @@ +$ANSIBLE_VAULT;1.1;AES256 +38643739306165633963663564333036336438323532393165663064386563386666383135646539 +3639656262393039666332623164626337333633353737370a383664323431383530356237663330 +63353331623130363365623062363162363037383763633532363162376665353462376465326238 +3530613630646431620a343033363639643632326634336165393036643130323430313631383236 +64613165646239313832343334616633363866376332356165616637366236306363636630663530 +35393830613830303530323866663232633561376435636337363266656537353066336663313633 +65663833376464653030343337323563343833383031353234356136313663393338366364306334 +66623936363539343038663731366366343265363131653537303666303533663865336265643132 +39346630393634323538303466613731663964646530663234623362303836396435326133663966 +33333633363937656466326533383839633437666363326332623263666164353461643433346234 +63333035646563396135306336303630613337373132383230326433353066336464393239346234 +63636232313166333661666439326339376134303731333039663563363631306533386234383466 +63366635623836613233383961353266303535313634633430643262323366343165353030616231 +32383936613239336237363234663438366639313433306236636237636661626466626466313934 +34363135383030386631626134653936356535363161613837643662353130646335393930666135 +33333138613666633462623665356162653032303231303433656265336135363538653937623739 +35323961393266343763666436616530616465663766356430633031346166313566333662373937 +34613663383230343034373535363638386339313966386264663566656139616233393532333466 +66336634336361656330333765363066613737313962313466316431323664356534653063623530 +65353131613939653061323464633337343836653532323433386264336266363466666661616164 +65343735373863633432326438316564386230383236633261336463373032636131353362623263 +31393634336432313032363264633438376263333962613635613864383034363762616137303561 +64616563356264353164643131393436383137343966623965303436343831366263393035313733 +61643335363933653936316565396634383763323966326330616136326533343333373231306135 +30323633646363316365643932616336313939383132663738393566633763366462303335633034 +37356463393937616238313730326234656262663836643139343837333430316434396661646664 +32663031376265623264393439383636396630663461646337346662363138366537623664336337 +62666662636130313030376137663834633461363637643465386337616665383130333961633936 +63663834373230396263653833353465363830343539376565343961313131613535613466346537 +64346434633833623264393434323765343238356539356537356539353432636637363063643433 +63373964323734396165346262626639313666313637663536336566363434376532656332636164 +35386236396333643163646639353762363234353231316230323965353365653431393465376461 +61636230363761336334373663396233363630653239363365333634346633353934386461643332 +32316561306235663031336239353163623063323931663565323561613666343436393361663730 +64383237643436666231323961646239396239353164613765313762353531633763356137316634 +35646131343862666435353063633230313561376566316432343365633030623931386139343461 +32396665643531623937643163646633393730393435646566316434653864316534616635666133 +63633833643965366366653038393663366461316162356661393662346136396534303731343135 +36663230303137396137306630646231616663623632316438306430363632303863373865326264 +38643236393064383136303865383839303261333665303764343239616364646535316432633730 +38383261343830323234393634383266636336633932633965366134383336366236656537633561 +36616363376332343261656430383430363566386534353239373335666532336130346534373835 +63623562346631666265333661303539636339343835663563643434643634383064356130356466 +34313965376536303065373731636535646230323663346337333365613336303733313536653261 +31383839653263316531646464323537313238386661326164303038383230383432336164373332 +36393138633366343666613636363162373263333139363130623131363832353530343239363633 +373761373265643139353733653433333931 diff --git a/ansible/group_vars/surtur/vault_surtur.yml b/ansible/group_vars/surtur/vault_surtur.yml new file mode 100644 index 0000000..565b41b --- /dev/null +++ b/ansible/group_vars/surtur/vault_surtur.yml @@ -0,0 +1,11 @@ +$ANSIBLE_VAULT;1.1;AES256 +63643462623661313666616639623037636264356162383339643639656537363732626131353534 +3236363862313161653030663338663138326636643765360a303166623033626439386264653564 +38653264643361613239633836373361313133316665353331306362613563613162333534353133 +6364323061363165390a306464613938323831366634663134353562636131393338346161656663 +39616338386232356337326162393637653937373661366138346437336230316633383536333766 +61323264626234336233383433633136643333333039396163656336353937633338373737636265 +36656138633230336663343066346664313537353165393861303732623639633263626631303263 +39663466363961386531616639376330663365643536373162353030653338396533313839326461 +37393938376664336266323736316530343464393233376430316335656132656332643233393663 +3732393361333939636537633732363434613037353234663531 diff --git a/ansible/host_vars/nbgw.yml b/ansible/host_vars/nbgw.yml new file mode 100644 index 0000000..47d55ad --- /dev/null +++ b/ansible/host_vars/nbgw.yml @@ -0,0 +1,12 @@ +$ANSIBLE_VAULT;1.1;AES256 +62306632323964353465643930303138363139656130623532356362653834396264376663376161 +3833363761613730393065613732373231363131613564350a373739313364653738333839653363 +37313430663466646534386436663930653932653862663530383636303139626563633530653561 +6266316361666433310a396635663935656565356135356230616535616264646433656465343633 +65663430633862656134383530616437353033383164303461613363356465323139303831663036 +35353633373636643565636165636137306636393939323836323633313035316365663263323838 +36316166376132653937353831343332383866383337383862373061646534646664386231316234 +34383863333231386339633739633335313236373638393031316533643666643835373734633239 +66383333646365636263656638373765333361343466313338353832363232656261613563646534 +61646332616437306532336331623034316630643762393535663364343837393436333835653138 +336363636661646366343339306331353033 diff --git a/ansible/hosts b/ansible/hosts new file mode 100644 index 0000000..600f947 --- /dev/null +++ b/ansible/hosts @@ -0,0 +1,6 @@ +[surtur] +surtur.local + +[nbgw] +nbgw +# 172.105.66.99 diff --git a/ansible/misc/vault-default-password.age b/ansible/misc/vault-default-password.age new file mode 100644 index 0000000..c34f969 --- /dev/null +++ b/ansible/misc/vault-default-password.age @@ -0,0 +1,24 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvTHpIZVFnY1hSaVNmVkcx +VGttQXRpVGRHdHJXdHJxcmlyRWhrSzd6L0JBCnJzUDM5ZDIzZE9kUitnaFJrVUxV +anZySy9vWklJUFF4V0NueDlQdzBrY0UKLT4gc3NoLWVkMjU1MTkgNlR6L1RRIGtm +K21vSzNOTGtzK3F1R296ZFlneHI3ZUwrYko1cCtwbEgzeFZKeDRWV3MKeEREQ2d4 +dlh2VW81eElTd0Q4a0JvUGJRbXNWWHJHK3h6M1FzcHppUkNZWQotPiBYMjU1MTkg +ejdBeC9NTHdsaFhiUkNtaGp6ZzJPMERtNnMxNWRkRDNjRjVIYmU4aUp6TQowT2Rt +T3FSL1ZZNHRSNkVyUXpmNC8wbHdsWmUybGlIaVFuQmlWb25nYjNjCi0+IHNzaC1l +ZDI1NTE5IE1kQ1p5QSBsd1Z4UC93OWdIc3RrWi9VOGFINnNvRnBHY2oxcmZQMm41 +KzE0YzhUZmlrClRWRjQ5R2s3L2ZpUU1KaG9kMlZzRHhJWUx2a0tiZHZzUGpRamVl +YmUyQVkKLS0tIGw4anVuWUdFVHVaZktvdG9JSDYvRS9YWVJaOFUyN1gyV0QzdnM2 +ZUhuZDgKs9QSQRCkCN2p1fQKQYliJ5tfZ1PWfCqImWZibGbnCYPawFxcyKdbPsC4 +3ns2JEjcv65eo5gflJQT7JdDV/kn/wppA3BFtTKvyVwfhUflPfcj5M1oRBNC+Eip +41ia0c4Re+JWOBqMZhItbugiwvoS95/9U8pFp38LQ2NTld24yKYmBms5nP4ppJhJ +fEnd7auiC2PMvSlvR1fxajEEu7yug1UcDRd6s1nYFoBztvPzbci7wV9/e92v6byP +tL4jqtBUv76quDWMxfcJa0LkF3Lz8643jxhcIGFL/6B3XjCrr5fU4uYDTCIs+WmL +/wv58hLB0NgeTWq2BmQctY0nMDptd11meLYRZA974kwEaj2kmzMV1AY66CihRcZA +GA6G4Vbl2stLu7t0A4rVfM5WKBFptGEbocLtDlObkRhJ+Ft41uGmEHp+g3BTOOjR +FeIU3UmJPBaV87Lc3Kch/ZDUZx73Opn8NgI9GvXLYIxUNFQcAKRJiA5XuvVUjF/M +tZZqx5P04C6W2IbVoG/WJpnEtP03XQ20Cg9VqW+ZgTXSastOKO/hqmAZk7n7biWj +gKBVfEB9rNwVpi9kAnZ2OX5iqW5mC9BwvtdkdrIcmKBK2oov8zqzA0cxiWEKAKjM +o9jiSlPF47lT8Nc9OMboDFujnqjUaSLLu0VgLf4IhkSE920LB70DkHmwKW14P+lO +LRmVq+KCHtNeZbWgjBm0w7gRkyGCYOk= +-----END AGE ENCRYPTED FILE----- diff --git a/ansible/misc/vault-keyring-client.sh b/ansible/misc/vault-keyring-client.sh new file mode 100755 index 0000000..6dc82dd --- /dev/null +++ b/ansible/misc/vault-keyring-client.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +readonly vault_password_file_encrypted="$(dirname $0)/vault-$2-password.age" + +flock "$vault_password_file_encrypted" \ + age -i ~/.age/ansible-vault-pw --decrypt "$vault_password_file_encrypted" diff --git a/ansible/misc/vault-super-password.age b/ansible/misc/vault-super-password.age new file mode 100644 index 0000000..28d694d Binary files /dev/null and b/ansible/misc/vault-super-password.age differ diff --git a/ansible/playbooks/nbgw.yml b/ansible/playbooks/nbgw.yml new file mode 100644 index 0000000..c74899b --- /dev/null +++ b/ansible/playbooks/nbgw.yml @@ -0,0 +1,9 @@ +--- +- hosts: nbgw + vars_files: + - ../group_vars/common.yml + - ../host_vars/nbgw.yml + roles: + - common + - netbird +... diff --git a/ansible/playbooks/nothingatall b/ansible/playbooks/nothingatall new file mode 100644 index 0000000..eef03a8 --- /dev/null +++ b/ansible/playbooks/nothingatall @@ -0,0 +1,11 @@ +$ANSIBLE_VAULT;1.1;AES256 +32353865333038386130343731373633383636633935326264636563636330336261623762343332 +3136383331376664633135313938633936633236393166360a326337653034383039643663653136 +30616139383339663661393834323638643362613761636366643466353539336263383035306338 +3037623262656162340a626633386132316563613333343761663431323065393530376335643433 +62353161316636353066343830646133386630643738336165613731633239313534346262643536 +63356333613265323039356161653432656461313035303039396465643361376261663036313665 +33383837356366393932636438666362383234656536356530643862363831383061636263623265 +66623465643531336236336133353363343533373035643062663739366430386434333038356131 +62303063666637363863663363386635356536356534343930343730306534623565643262393235 +6530396564353963393938383435656236613533643331393931 diff --git a/ansible/playbooks/reencrypt.yml b/ansible/playbooks/reencrypt.yml new file mode 100644 index 0000000..5363fd7 --- /dev/null +++ b/ansible/playbooks/reencrypt.yml @@ -0,0 +1,15 @@ +--- +- hosts: surtur + connection: local + vars_files: + - nothingatall + # - ../group_vars/surtur/vault_surtur.yml + roles: + # include_role: + - tasks + # - rand + # - configs + # tasks: + # include_role: + # name: tasks + # tasks_from: reencrypt-vault-default-key diff --git a/ansible/playbooks/surtur.yml b/ansible/playbooks/surtur.yml new file mode 100644 index 0000000..c26d29b --- /dev/null +++ b/ansible/playbooks/surtur.yml @@ -0,0 +1,9 @@ +--- +- hosts: surtur + # connection: local + vars_files: + - nothingatall + - ../group_vars/surtur/vault_surtur.yml + roles: + # - rand + - configs diff --git a/ansible/playbooks/tasks/include/reencrypt-vault-key.yml b/ansible/playbooks/tasks/include/reencrypt-vault-key.yml new file mode 100644 index 0000000..1dc0578 --- /dev/null +++ b/ansible/playbooks/tasks/include/reencrypt-vault-key.yml @@ -0,0 +1,22 @@ +--- +- name: Check if moreutils is installed + become: true + dnf5: name=moreutils state=present + when: ansible_distribution == "Fedora" + +- name: Check if moreutils is installed + become: false + pacman: name=moreutils state=present + when: ansible_distribution == "Archlinux" + +- name: Reencrypt vault {{ vault_id }} key + shell: | + set -eo pipefail + age \ + -i ~/.age/ansible-vault-pw \ + --decrypt "{{ playbook_dir }}/../../misc/vault-{{ vault_id }}-password.age" \ + | age --armor --encrypt \ + {% for userid in vault_agekeys | flatten %}--recipient {{ userid }} {% endfor %} \ + - \ + | sponge "{{ playbook_dir }}/../../misc/vault-{{ vault_id }}-password.age" + changed_when: false diff --git a/ansible/playbooks/tasks/reencrypt-vault-default-key.yml b/ansible/playbooks/tasks/reencrypt-vault-default-key.yml new file mode 100644 index 0000000..60083e6 --- /dev/null +++ b/ansible/playbooks/tasks/reencrypt-vault-default-key.yml @@ -0,0 +1,11 @@ +--- +- name: Reencrypt vault default key + hosts: localhost + # vars_files: + # - nothingatall + tasks: + - name: Reencrypt vault default key + include_tasks: include/reencrypt-vault-key.yml + vars: + vault_id: default + vault_agekeys: "{{ vault_default_agekeys }}" diff --git a/ansible/playbooks/tasks/reencrypt-vault-super-key.yml b/ansible/playbooks/tasks/reencrypt-vault-super-key.yml new file mode 100644 index 0000000..c07de15 --- /dev/null +++ b/ansible/playbooks/tasks/reencrypt-vault-super-key.yml @@ -0,0 +1,10 @@ +--- +- name: Reencrypt vault super key + hosts: localhost + tasks: + - name: Reencrypt vault super key + include_tasks: include/reencrypt-vault-key.yml + vars: + vault_id: super + vault_agekeys: "{{ vault_super_agekeys }}" + diff --git a/ansible/roles/common/tasks/dnscrypt.yml b/ansible/roles/common/tasks/dnscrypt.yml new file mode 100644 index 0000000..0cdc65f --- /dev/null +++ b/ansible/roles/common/tasks/dnscrypt.yml @@ -0,0 +1,8 @@ +--- +- name: dnscrypt-proxy-test.toml + ansible.builtin.template: + src: ../templates/dnscrypt-proxy.toml + dest: /etc/dnscrypt-proxy/dnscrypt-proxy-test.toml + # owner: dnscrypt-proxy + # group: dnscrypt-proxy + mode: '0644' diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml new file mode 100644 index 0000000..09982db --- /dev/null +++ b/ansible/roles/common/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Stop and disable systemd-resolved + become: true + ansible.builtin.systemd: + name: systemd-resolved + state: stopped + enabled: false + when: ansible_hostname == "surtur" + +- name: Enable systemd-timesyncd + become: true + systemd: + name: systemd-timesyncd + state: started + enabled: true + +- include_tasks: pkg.yml +- include_tasks: dnscrypt.yml diff --git a/ansible/roles/common/tasks/pkg.yml b/ansible/roles/common/tasks/pkg.yml new file mode 100644 index 0000000..faf295c --- /dev/null +++ b/ansible/roles/common/tasks/pkg.yml @@ -0,0 +1,21 @@ +--- +- name: Common pkgs + become: true + ansible.builtin.package: + state: present + name: "{{ item }}" + loop: "{{ pkgs_common }}" + +- name: Arch pkgs + community.general.pacman: + state: present + name: "{{ item }}" + loop: "{{ pkgs_arch }}" + when: ansible_distribution == "Archlinux" + +- name: F38 pkgs + ansible.builtin.dnf: + state: present + name: "{{ item }}" + loop: "{{ pkgs_fedora38 }}" + when: ansible_distribution == "Fedora" diff --git a/ansible/roles/common/templates/dnscrypt-proxy.toml b/ansible/roles/common/templates/dnscrypt-proxy.toml new file mode 100644 index 0000000..75d34b7 --- /dev/null +++ b/ansible/roles/common/templates/dnscrypt-proxy.toml @@ -0,0 +1,905 @@ + +############################################## +# # +# dnscrypt-proxy configuration # +# # +############################################## + +## This is an example configuration file. +## You should adjust it to your needs, and save it as "dnscrypt-proxy.toml" +## +## Online documentation is available here: https://dnscrypt.info/doc + + + +################################## +# Global settings # +################################## + +## List of servers to use +## +## Servers from the "public-resolvers" source (see down below) can +## be viewed here: https://dnscrypt.info/public-servers +## +## The proxy will automatically pick working servers from this list. +## Note that the require_* filters do NOT apply when using this setting. +## +## By default, this list is empty and all registered servers matching the +## require_* filters will be used instead. +## +## Remove the leading # first to enable this; lines starting with # are ignored. + +# server_names = ['scaleway-fr', 'google', 'yandex', 'cloudflare'] +#server_names = ['dotya.ml'] + + +## List of local addresses and ports to listen to. Can be IPv4 and/or IPv6. +## Example with both IPv4 and IPv6: +## listen_addresses = ['127.0.0.1:53', '[::1]:53'] +## +## To listen to all IPv4 addresses, use `listen_addresses = ['0.0.0.0:53']` +## To listen to all IPv4+IPv6 addresses, use `listen_addresses = ['[::]:53']` + +listen_addresses = [ {{ dnscrypt_listen_addresses }} ] + + +## Maximum number of simultaneous client connections to accept + +#max_clients = 250 +max_clients = 4096 + + +## Switch to a different system user after listening sockets have been created. +## Note (1): this feature is currently unsupported on Windows. +## Note (2): this feature is not compatible with systemd socket activation. +## Note (3): when using -pidfile, the PID file directory must be writable by the new user + +# user_name = 'nobody' + + +## Require servers (from remote sources) to satisfy specific properties + +# Use servers reachable over IPv4 +ipv4_servers = true + +# Use servers reachable over IPv6 -- Do not enable if you don't have IPv6 connectivity +ipv6_servers = {{ dnscrypt_ipv6 }} + +# Use servers implementing the DNSCrypt protocol +dnscrypt_servers = true + +# Use servers implementing the DNS-over-HTTPS protocol +doh_servers = true + +# Use servers implementing the Oblivious DoH protocol +odoh_servers = {{ dnscrypt_odoh }} + + +## Require servers defined by remote sources to satisfy specific properties + +# Server must support DNS security extensions (DNSSEC) +require_dnssec = true + +# Server must not log user queries (declarative) +require_nolog = true + +# Server must not enforce its own blocklist (for parental control, ads blocking...) +require_nofilter = true + +# Server names to avoid even if they match all criteria +#disabled_server_names = ['yandex', 'google', 'cloudflare', 'apple', 'cisco'] +disabled_server_names = [ +{{ dnscrypt_disabled_names }} +] +# disabled_server_names = ['google-ipv6', + # 'cloudflare', + # 'cloudflare-ipv6', + # 'cisco', + # 'cisco-ipv6', + # 'cisco-familyshield', + # 'cisco-familyshield-ipv6', + # 'yandex', + # 'apple', + # 'doh.dns.apple.com', + # 'ffmuc.net', + # 'dnswarden-uncensor-dc', + # 'dnswarden-uncensor-dc-swiss', + # 'techsaviours.org-dnscrypt', + # 'dns.watch', + # 'dct-at1', + # 'pryv8boi', + # 'dct-ru1', + # 'controld-uncensored', + # 'controld-unfiltered', + # 'doh.appliedprivacy.net', + # 'nextdns', + # 'mullvad-doh', + # 'nextdns-ultralow', + # 'dns.digitalsize.net' +# ] + + +## Always use TCP to connect to upstream servers. +## This can be useful if you need to route everything through Tor. +## Otherwise, leave this to `false`, as it doesn't improve security +## (dnscrypt-proxy will always encrypt everything even using UDP), and can +## only increase latency. + +force_tcp = false + + +## Enable support for HTTP/3 (DoH3, HTTP over QUIC) +## Note that, like DNSCrypt but unlike other HTTP versions, this uses +## UDP and (usually) port 443 instead of TCP. + +http3 = {{ dnscrypt_http3 }} + + +## SOCKS proxy +## Uncomment the following line to route all TCP connections to a local Tor node +## Tor doesn't support UDP, so set `force_tcp` to `true` as well. + +# proxy = 'socks5://127.0.0.1:9050' + + +## HTTP/HTTPS proxy +## Only for DoH servers + +# http_proxy = 'http://127.0.0.1:8888' + + +## How long a DNS query will wait for a response, in milliseconds. +## If you have a network with *a lot* of latency, you may need to +## increase this. Startup may be slower if you do so. +## Don't increase it too much. 10000 is the highest reasonable value. + +timeout = 5000 +#timeout = 500 + + +## Keepalive for HTTP (HTTPS, HTTP/2) queries, in seconds + +keepalive = 30 + + +## Add EDNS-client-subnet information to outgoing queries +## +## Multiple networks can be listed; they will be randomly chosen. +## These networks don't have to match your actual networks. + +# edns_client_subnet = ['0.0.0.0/0', '2001:db8::/32'] + + +## Response for blocked queries. Options are `refused`, `hinfo` (default) or +## an IP response. To give an IP response, use the format `a:,aaaa:`. +## Using the `hinfo` option means that some responses will be lies. +## Unfortunately, the `hinfo` option appears to be required for Android 8+ + +# blocked_query_response = 'refused' + + +## Load-balancing strategy: 'p2' (default), 'ph', 'p', 'first' or 'random' +## Randomly choose 1 of the fastest 2, half, n, 1 or all live servers by latency. +## The response quality still depends on the server itself. + +# lb_strategy = 'p2' +lb_strategy = 'p7' + +## Set to `true` to constantly try to estimate the latency of all the resolvers +## and adjust the load-balancing parameters accordingly, or to `false` to disable. +## Default is `true` that makes 'p2' `lb_strategy` work well. + +lb_estimator = true + + +## Log level (0-6, default: 2 - 0 is very verbose, 6 only contains fatal errors) + +log_level = 2 + + +## Log file for the application, as an alternative to sending logs to +## the standard system logging service (syslog/Windows event log). +## +## This file is different from other log files, and will not be +## automatically rotated by the application. + +log_file = '/var/log/dnscrypt-proxy/dnscrypt-proxy.log' + + +## When using a log file, only keep logs from the most recent launch. + +# log_file_latest = true + + +## Use the system logger (syslog on Unix, Event Log on Windows) + +use_syslog = true + + +## Delay, in minutes, after which certificates are reloaded + +cert_refresh_delay = 240 + + +## DNSCrypt: Create a new, unique key for every single DNS query +## This may improve privacy but can also have a significant impact on CPU usage +## Only enable if you don't have a lot of network load + +# dnscrypt_ephemeral_keys = false + + +## DoH: Disable TLS session tickets - increases privacy but also latency + +# tls_disable_session_tickets = false + + +## DoH: Use a specific cipher suite instead of the server preference +## 49199 = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +## 49195 = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +## 52392 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 +## 52393 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 +## 4865 = TLS_AES_128_GCM_SHA256 +## 4867 = TLS_CHACHA20_POLY1305_SHA256 +## +## On non-Intel CPUs such as MIPS routers and ARM systems (Android, Raspberry Pi...), +## the following suite improves performance. +## This may also help on Intel CPUs running 32-bit operating systems. +## +## Keep tls_cipher_suite empty if you have issues fetching sources or +## connecting to some DoH servers. Google and Cloudflare are fine with it. + +# tls_cipher_suite = [52392, 49199] +tls_cipher_suite = [4867, 49195, 52392, 49199] + + +## Bootstrap resolvers +## +## These are normal, non-encrypted DNS resolvers, that will be only used +## for one-shot queries when retrieving the initial resolvers list and if +## the system DNS configuration doesn't work. +## +## No user queries will ever be leaked through these resolvers, and they will +## not be used after IP addresses of DoH resolvers have been found (if you are +## using DoH). +## +## They will never be used if lists have already been cached, and if the stamps +## of the configured servers already include IP addresses (which is the case for +## most of DoH servers, and for all DNSCrypt servers and relays). +## +## They will not be used if the configured system DNS works, or after the +## proxy already has at least one usable secure resolver. +## +## Resolvers supporting DNSSEC are recommended, and, if you are using +## DoH, bootstrap resolvers should ideally be operated by a different entity +## than the DoH servers you will be using, especially if you have IPv6 enabled. +## +## People in China may want to use 114.114.114.114:53 here. +## Other popular options include 8.8.8.8, 9.9.9.9 and 1.1.1.1. +## +## If more than one resolver is specified, they will be tried in sequence. +## +## TL;DR: put valid standard resolver addresses here. Your actual queries will +## not be sent there. If you're using DNSCrypt or Anonymized DNS and your +## lists are up to date, these resolvers will not even be used. + +#bootstrap_resolvers = ['9.9.9.11:53', '8.8.8.8:53'] +bootstrap_resolvers = ['144.91.70.62:53', '[2a02:c207:2030:396::1]:53','9.9.9.11:53','84.200.69.80:53', '84.200.70.40:53', '8.8.8.8:53'] + + +## Always use the bootstrap resolver before the system DNS settings. + +ignore_system_dns = true + + +## Maximum time (in seconds) to wait for network connectivity before +## initializing the proxy. +## Useful if the proxy is automatically started at boot, and network +## connectivity is not guaranteed to be immediately available. +## Use 0 to not test for connectivity at all (not recommended), +## and -1 to wait as much as possible. + +netprobe_timeout = 60 + +## Address and port to try initializing a connection to, just to check +## if the network is up. It can be any address and any port, even if +## there is nothing answering these on the other side. Just don't use +## a local address, as the goal is to check for Internet connectivity. +## On Windows, a datagram with a single, nul byte will be sent, only +## when the system starts. +## On other operating systems, the connection will be initialized +## but nothing will be sent at all. + +netprobe_address = '9.9.9.9:53' + + +## Offline mode - Do not use any remote encrypted servers. +## The proxy will remain fully functional to respond to queries that +## plugins can handle directly (forwarding, cloaking, ...) + +# offline_mode = false + + +## Additional data to attach to outgoing queries. +## These strings will be added as TXT records to queries. +## Do not use, except on servers explicitly asking for extra data +## to be present. +## encrypted-dns-server can be configured to use this for access control +## in the [access_control] section + +# query_meta = ['key1:value1', 'key2:value2', 'token:MySecretToken'] + + +## Automatic log files rotation + +# Maximum log files size in MB - Set to 0 for unlimited. +log_files_max_size = 10 + +# How long to keep backup files, in days +log_files_max_age = 7 + +# Maximum log files backups to keep (or 0 to keep all backups) +log_files_max_backups = 1 + + + +######################### +# Filters # +######################### + +## Note: if you are using dnsmasq, disable the `dnssec` option in dnsmasq if you +## configure dnscrypt-proxy to do any kind of filtering (including the filters +## below and blocklists). +## You can still choose resolvers that do DNSSEC validation. + + +## Immediately respond to IPv6-related queries with an empty response +## This makes things faster when there is no IPv6 connectivity, but can +## also cause reliability issues with some stub resolvers. + +block_ipv6 = false + + +## Immediately respond to A and AAAA queries for host names without a domain name + +block_unqualified = true + + +## Immediately respond to queries for local zones instead of leaking them to +## upstream resolvers (always causing errors or timeouts). + +block_undelegated = true + + +## TTL for synthetic responses sent when a request has been blocked (due to +## IPv6 or blocklists). + +reject_ttl = 10 + + + +################################################################################## +# Route queries for specific domains to a dedicated set of servers # +################################################################################## + +## See the `example-forwarding-rules.txt` file for an example + +# forwarding_rules = '/etc/dnscrypt-proxy/forwarding-rules.txt' + + + +############################### +# Cloaking rules # +############################### + +## Cloaking returns a predefined address for a specific name. +## In addition to acting as a HOSTS file, it can also return the IP address +## of a different name. It will also do CNAME flattening. +## If 'cloak_ptr' is set, then PTR (reverse lookups) are enabled +## for cloaking rules that do not contain wild cards. +## +## See the `example-cloaking-rules.txt` file for an example + +# cloaking_rules = '/etc/dnscrypt-proxy/cloaking-rules.txt' + +## TTL used when serving entries in cloaking-rules.txt + +# cloak_ttl = 600 +# cloak_ptr = false + + + +########################### +# DNS cache # +########################### + +## Enable a DNS cache to reduce latency and outgoing traffic + +cache = true + + +## Cache size + +cache_size = 10000 + + +## Minimum TTL for cached entries + +cache_min_ttl = 2400 + + +## Maximum TTL for cached entries + +cache_max_ttl = 86400 + + +## Minimum TTL for negatively cached entries + +# cache_neg_min_ttl = 60 +cache_neg_min_ttl = 30 + + +## Maximum TTL for negatively cached entries + +#cache_neg_max_ttl = 600 +cache_neg_max_ttl = 300 + + + +######################################## +# Captive portal handling # +######################################## + +[captive_portals] + +## A file that contains a set of names used by operating systems to +## check for connectivity and captive portals, along with hard-coded +## IP addresses to return. + +# map_file = '/etc/dnscrypt-proxy/captive-portals.txt' + + + +################################## +# Local DoH server # +################################## + +[local_doh] + +## dnscrypt-proxy can act as a local DoH server. By doing so, web browsers +## requiring a direct connection to a DoH server in order to enable some +## features will enable these, without bypassing your DNS proxy. + +## Addresses that the local DoH server should listen to + +# listen_addresses = ['127.0.0.1:3000'] + + +## Path of the DoH URL. This is not a file, but the part after the hostname +## in the URL. By convention, `/dns-query` is frequently chosen. +## For each `listen_address` the complete URL to access the server will be: +## `https://` (ex: `https://127.0.0.1/dns-query`) + +# path = '/dns-query' + + +## Certificate file and key - Note that the certificate has to be trusted. +## See the documentation (wiki) for more information. + +# cert_file = "/var/lib/dnscrypt-proxy/localhost.pem" +# cert_key_file = "/var/lib/dnscrypt-proxy/localhost.pem" + + + +############################### +# Query logging # +############################### + +## Log client queries to a file + +[query_log] + +## Path to the query log file (absolute, or relative to the same directory as the config file) +## Can be set to /dev/stdout in order to log to the standard output. + +# file = '/var/log/dnscrypt-proxy/query.log' + + +## Query log format (currently supported: tsv and ltsv) + +format = 'tsv' + + +## Do not log these query types, to reduce verbosity. Keep empty to log everything. + +# ignored_qtypes = ['DNSKEY', 'NS'] + + + +############################################ +# Suspicious queries logging # +############################################ + +## Log queries for nonexistent zones +## These queries can reveal the presence of malware, broken/obsolete applications, +## and devices signaling their presence to 3rd parties. + +[nx_log] + +## Path to the query log file (absolute, or relative to the same directory as the config file) + +# file = '/var/log/dnscrypt-proxy/nx.log' + + +## Query log format (currently supported: tsv and ltsv) + +format = 'tsv' + + + +###################################################### +# Pattern-based blocking (blocklists) # +###################################################### + +## Blocklists are made of one pattern per line. Example of valid patterns: +## +## example.com +## =example.com +## *sex* +## ads.* +## ads*.example.* +## ads*.example[0-9]*.com +## +## Example blocklist files can be found at https://download.dnscrypt.info/blocklists/ +## A script to build blocklists from public feeds can be found in the +## `utils/generate-domains-blocklists` directory of the dnscrypt-proxy source code. + +[blocked_names] + +## Path to the file of blocking rules (absolute, or relative to the same directory as the config file) + +# blocked_names_file = '/etc/dnscrypt-proxy/blocked-names.txt' + + +## Optional path to a file logging blocked queries + +# log_file = '/var/log/dnscrypt-proxy/blocked-names.log' + + +## Optional log format: tsv or ltsv (default: tsv) + +# log_format = 'tsv' + + + +########################################################### +# Pattern-based IP blocking (IP blocklists) # +########################################################### + +## IP blocklists are made of one pattern per line. Example of valid patterns: +## +## 127.* +## fe80:abcd:* +## 192.168.1.4 + +[blocked_ips] + +## Path to the file of blocking rules (absolute, or relative to the same directory as the config file) + +# blocked_ips_file = '/etc/dnscrypt-proxy/blocked-ips.txt' + + +## Optional path to a file logging blocked queries + +# log_file = '/var/log/dnscrypt-proxy/blocked-ips.log' + + +## Optional log format: tsv or ltsv (default: tsv) + +# log_format = 'tsv' + + + +###################################################### +# Pattern-based allow lists (blocklists bypass) # +###################################################### + +## Allowlists support the same patterns as blocklists +## If a name matches an allowlist entry, the corresponding session +## will bypass names and IP filters. +## +## Time-based rules are also supported to make some websites only accessible at specific times of the day. + +[allowed_names] + +## Path to the file of allow list rules (absolute, or relative to the same directory as the config file) + +# allowed_names_file = '/etc/dnscrypt-proxy/allowed-names.txt' + + +## Optional path to a file logging allowed queries + +# log_file = '/var/log/dnscrypt-proxy/allowed-names.log' + + +## Optional log format: tsv or ltsv (default: tsv) + +# log_format = 'tsv' + + + +######################################################### +# Pattern-based allowed IPs lists (blocklists bypass) # +######################################################### + +## Allowed IP lists support the same patterns as IP blocklists +## If an IP response matches an allowed entry, the corresponding session +## will bypass IP filters. +## +## Time-based rules are also supported to make some websites only accessible at specific times of the day. + +[allowed_ips] + +## Path to the file of allowed ip rules (absolute, or relative to the same directory as the config file) + +# allowed_ips_file = '/etc/dnscrypt-proxy/allowed-ips.txt' + + +## Optional path to a file logging allowed queries + +# log_file = '/var/log/dnscrypt-proxy/allowed-ips.log' + +## Optional log format: tsv or ltsv (default: tsv) + +# log_format = 'tsv' + + + +########################################## +# Time access restrictions # +########################################## + +## One or more weekly schedules can be defined here. +## Patterns in the name-based blocked_names file can optionally be followed with @schedule_name +## to apply the pattern 'schedule_name' only when it matches a time range of that schedule. +## +## For example, the following rule in a blocklist file: +## *.youtube.* @time-to-sleep +## would block access to YouTube during the times defined by the 'time-to-sleep' schedule. +## +## {after='21:00', before= '7:00'} matches 0:00-7:00 and 21:00-0:00 +## {after= '9:00', before='18:00'} matches 9:00-18:00 + +[schedules] + + # [schedules.time-to-sleep] + # mon = [{after='21:00', before='7:00'}] + # tue = [{after='21:00', before='7:00'}] + # wed = [{after='21:00', before='7:00'}] + # thu = [{after='21:00', before='7:00'}] + # fri = [{after='23:00', before='7:00'}] + # sat = [{after='23:00', before='7:00'}] + # sun = [{after='21:00', before='7:00'}] + + # [schedules.work] + # mon = [{after='9:00', before='18:00'}] + # tue = [{after='9:00', before='18:00'}] + # wed = [{after='9:00', before='18:00'}] + # thu = [{after='9:00', before='18:00'}] + # fri = [{after='9:00', before='17:00'}] + + + +######################### +# Servers # +######################### + +## Remote lists of available servers +## Multiple sources can be used simultaneously, but every source +## requires a dedicated cache file. +## +## Refer to the documentation for URLs of public sources. +## +## A prefix can be prepended to server names in order to +## avoid collisions if different sources share the same for +## different servers. In that case, names listed in `server_names` +## must include the prefixes. +## +## If the `urls` property is missing, cache files and valid signatures +## must already be present. This doesn't prevent these cache files from +## expiring after `refresh_delay` hours. +## Cache freshness is checked every 24 hours, so values for 'refresh_delay' +## of less than 24 hours will have no effect. +## A maximum delay of 168 hours (1 week) is imposed to ensure cache freshness. + +[sources] + + ### An example of a remote source from https://github.com/DNSCrypt/dnscrypt-resolvers + + [sources.public-resolvers] + urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/public-resolvers.md'] + cache_file = '/var/cache/dnscrypt-proxy/public-resolvers.md' + minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' + refresh_delay = 72 + prefix = '' + + ### Anonymized DNS relays + + [sources.relays] + urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/relays.md', 'https://download.dnscrypt.info/resolvers-list/v3/relays.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/relays.md'] + cache_file = '/var/cache/dnscrypt-proxy/relays.md' + minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' + refresh_delay = 72 + prefix = '' + + ### ODoH (Oblivious DoH) servers and relays + + # [sources.odoh-servers] + # urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-servers.md', 'https://download.dnscrypt.info/resolvers-list/v3/odoh-servers.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/odoh-servers.md'] + # cache_file = 'odoh-servers.md' + # minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' + # refresh_delay = 24 + # prefix = '' + # [sources.odoh-relays] + # urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-relays.md', 'https://download.dnscrypt.info/resolvers-list/v3/odoh-relays.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/odoh-relays.md'] + # cache_file = 'odoh-relays.md' + # minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' + # refresh_delay = 24 + # prefix = '' + + ### Quad9 + + # [sources.quad9-resolvers] + # urls = ['https://www.quad9.net/quad9-resolvers.md'] + # minisign_key = 'RWQBphd2+f6eiAqBsvDZEBXBGHQBJfeG6G+wJPPKxCZMoEQYpmoysKUN' + # cache_file = '/var/cache/dnscrypt-proxy/quad9-resolvers.md' + # prefix = 'quad9-' + + ### Another example source, with resolvers censoring some websites not appropriate for children + ### This is a subset of the `public-resolvers` list, so enabling both is useless. + + # [sources.parental-control] + # urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/parental-control.md', 'https://download.dnscrypt.info/resolvers-list/v3/parental-control.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/parental-control.md'] + # cache_file = '/var/cache/dnscrypt-proxy/parental-control.md' + # minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' + + + +######################################### +# Servers with known bugs # +######################################### + +[broken_implementations] + +## Cisco servers currently cannot handle queries larger than 1472 bytes, and don't +## truncate responses larger than questions as expected by the DNSCrypt protocol. +## This prevents large responses from being received over UDP and over relays. +## +## Older versions of the `dnsdist` server software had a bug with queries larger +## than 1500 bytes. This is fixed since `dnsdist` version 1.5.0, but +## some server may still run an outdated version. +## +## The list below enables workarounds to make non-relayed usage more reliable +## until the servers are fixed. + +fragments_blocked = ['cisco', 'cisco-ipv6', 'cisco-familyshield', 'cisco-familyshield-ipv6', 'cleanbrowsing-adult', 'cleanbrowsing-adult-ipv6', 'cleanbrowsing-family', 'cleanbrowsing-family-ipv6', 'cleanbrowsing-security', 'cleanbrowsing-security-ipv6'] + + + +################################################################# +# Certificate-based client authentication for DoH # +################################################################# + +## Use a X509 certificate to authenticate yourself when connecting to DoH servers. +## This is only useful if you are operating your own, private DoH server(s). +## 'creds' maps servers to certificates, and supports multiple entries. +## If you are not using the standard root CA, an optional "root_ca" +## property set to the path to a root CRT file can be added to a server entry. + +[doh_client_x509_auth] + +# creds = [ +# { server_name='*', client_cert='client.crt', client_key='client.key' } +# ] + + + +################################ +# Anonymized DNS # +################################ + +[anonymized_dns] + +## Routes are indirect ways to reach DNSCrypt servers. +## +## A route maps a server name ("server_name") to one or more relays that will be +## used to connect to that server. +## +## A relay can be specified as a DNS Stamp (either a relay stamp, or a +## DNSCrypt stamp) or a server name. +## +## The following example routes "example-server-1" via `anon-example-1` or `anon-example-2`, +## and "example-server-2" via the relay whose relay DNS stamp is +## "sdns://gRIxMzcuNzQuMjIzLjIzNDo0NDM". +## +## !!! THESE ARE JUST EXAMPLES !!! +## +## Review the list of available relays from the "relays.md" file, and, for each +## server you want to use, define the relays you want connections to go through. +## +## Carefully choose relays and servers so that they are run by different entities. +## +## "server_name" can also be set to "*" to define a default route, for all servers: +## { server_name='*', via=['anon-example-1', 'anon-example-2'] } +## +## If a route is ["*"], the proxy automatically picks a relay on a distinct network. +## { server_name='*', via=['*'] } is also an option, but is likely to be suboptimal. +## +## Manual selection is always recommended over automatic selection, so that you can +## select (relay,server) pairs that work well and fit your own criteria (close by or +## in different countries, operated by different entities, on distinct ISPs...) + +# routes = [ +# { server_name='example-server-1', via=['anon-example-1', 'anon-example-2'] }, +# { server_name='example-server-2', via=['sdns://gRIxMzcuNzQuMjIzLjIzNDo0NDM'] } +# ] + + +## Skip resolvers incompatible with anonymization instead of using them directly + +skip_incompatible = false + + +## If public server certificates for a non-conformant server cannot be +## retrieved via a relay, try getting them directly. Actual queries +## will then always go through relays. + +direct_cert_fallback = false + + + +############################### +# DNS64 # +############################### + +## DNS64 is a mechanism for synthesizing AAAA records from A records. +## It is used with an IPv6/IPv4 translator to enable client-server +## communication between an IPv6-only client and an IPv4-only server, +## without requiring any changes to either the IPv6 or the IPv4 node, +## for the class of applications that work through NATs. +## +## There are two options to synthesize such records: +## Option 1: Using a set of static IPv6 prefixes; +## Option 2: By discovering the IPv6 prefix from DNS64-enabled resolver. +## +## If both options are configured - only static prefixes are used. +## (Ref. RFC6147, RFC6052, RFC7050) +## +## Do not enable unless you know what DNS64 is and why you need it, or else +## you won't be able to connect to anything at all. + +[dns64] + +## Static prefix(es) as Pref64::/n CIDRs + +# prefix = ['64:ff9b::/96'] + +## DNS64-enabled resolver(s) to discover Pref64::/n CIDRs +## These resolvers are used to query for Well-Known IPv4-only Name (WKN) "ipv4only.arpa." to discover only. +## Set with your ISP's resolvers in case of custom prefixes (other than Well-Known Prefix 64:ff9b::/96). +## IMPORTANT: Default resolvers listed below support Well-Known Prefix 64:ff9b::/96 only. + +# resolver = ['[2606:4700:4700::64]:53', '[2001:4860:4860::64]:53'] + + + +######################################## +# Static entries # +######################################## + +## Optional, local, static list of additional servers +## Mostly useful for testing your own servers. + +[static] + # IPv4 (144.91.70.62, port 5443) + [static. 'dnscrypt.dotya.ml-ipv4'] + stamp = 'sdns://AQcAAAAAAAAAETE0NC45MS43MC42Mjo1NDQzIHF-JiN46cNwFXJleEVWGWgrhe2QeysUtZoo9HwzYCMzITIuZG5zY3J5cHQtY2VydC5kbnNjcnlwdC5kb3R5YS5tbA' diff --git a/ansible/roles/configs/files/dnf.conf b/ansible/roles/configs/files/dnf.conf new file mode 100644 index 0000000..676cc93 --- /dev/null +++ b/ansible/roles/configs/files/dnf.conf @@ -0,0 +1,14 @@ +[main] +gpgcheck=1 +# if installing multiple kernels this applies to each flavour +# installonly_limit=3 +installonly_limit=2 +clean_requirements_on_remove=True +fastestmirror=False +best=False +skip_if_unavailable=True +keepcache=1 +max_parallel_downloads=10 +deltarpm=True +#exclude=alacritty +# debuglevel=7 diff --git a/ansible/roles/configs/files/resolv.conf b/ansible/roles/configs/files/resolv.conf new file mode 100644 index 0000000..8649490 --- /dev/null +++ b/ansible/roles/configs/files/resolv.conf @@ -0,0 +1,12 @@ +nameserver 127.0.0.1 +nameserver ::1 + +# nameserver 84.200.69.80 +# nameserver 130.225.244.166 +# https://blog.uncensoreddns.org/dns-servers/ +##nameserver 130.225.244.166 +#nameserver 2001:878:0:e000:82:e1:f4:a6 + +# options edns0 single-request-reopen rotate attempts:9 timeout:1 +options edns0 rotate attempts:10 timeout:1 +# options edns0 single-request-reopen attempts:7 timeout:5 diff --git a/ansible/roles/configs/tasks/dnf.yml b/ansible/roles/configs/tasks/dnf.yml new file mode 100644 index 0000000..203cadc --- /dev/null +++ b/ansible/roles/configs/tasks/dnf.yml @@ -0,0 +1,9 @@ +--- +- name: Install dnf config + become: true + ansible.builtin.copy: + src: dnf.conf + dest: /etc/dnf/dnf.conf + owner: root + group: root + mode: '0644' diff --git a/ansible/roles/configs/tasks/main.yml b/ansible/roles/configs/tasks/main.yml new file mode 100644 index 0000000..7db7ce7 --- /dev/null +++ b/ansible/roles/configs/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- include_tasks: dnf.yml +- include_tasks: resolvconf.yml diff --git a/ansible/roles/configs/tasks/resolvconf.yml b/ansible/roles/configs/tasks/resolvconf.yml new file mode 100644 index 0000000..0f5234c --- /dev/null +++ b/ansible/roles/configs/tasks/resolvconf.yml @@ -0,0 +1,18 @@ +--- +- name: stop+disable systemd-resolved + become: true + systemd: + name: systemd-resolved + state: stopped + enabled: false + +#- name: unlink resolv.conf +# file: +# path: /etc/resolv.conf +# state: absent + +- name: write resolv.conf + become: true + copy: + src: resolv.conf + dest: /etc/resolvconftest diff --git a/ansible/roles/netbird/tasks/main.yml b/ansible/roles/netbird/tasks/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/ansible/roles/netbird/tasks/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible/roles/rand/tasks/main.yml b/ansible/roles/rand/tasks/main.yml new file mode 100644 index 0000000..19affa6 --- /dev/null +++ b/ansible/roles/rand/tasks/main.yml @@ -0,0 +1,4 @@ +--- +# - include_tasks: ../../../playbooks/tasks/reencrypt-vault-default-key.yml +# - include_tasks: reencrypt.yml +- include_tasks: pkgs.yml diff --git a/ansible/roles/rand/tasks/pkgs.yml b/ansible/roles/rand/tasks/pkgs.yml new file mode 100644 index 0000000..c3b6d7e --- /dev/null +++ b/ansible/roles/rand/tasks/pkgs.yml @@ -0,0 +1,25 @@ +--- +#- name: Upgrade all packages +# become: true +# ansible.builtin.dnf: +# name: "*" +# state: latest +# +- name: Install core packages + become: true + dnf: + name: "{{ packages }}" + state: present + vars: + packages: + - zsh + - zsh-syntax-highlighting + - zsh-autosuggestions + - gcc + - binutils + - go + - sway + - curl + - wget + retries: 5 + delay: 3 diff --git a/ansible/roles/rand/tasks/reencrypt.yml b/ansible/roles/rand/tasks/reencrypt.yml new file mode 100644 index 0000000..12f3bef --- /dev/null +++ b/ansible/roles/rand/tasks/reencrypt.yml @@ -0,0 +1,6 @@ +--- +- name: reencrypt default vault + include: + - ../../../playbooks/tasks/reencrypt-vault-default-key.yml + # name: adsa + tags: reencrypt diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..d47ac35 --- /dev/null +++ b/main.tf @@ -0,0 +1,55 @@ +# https://www.tweag.io/blog/2019-04-03-terraform-provider-secret/ +# resource "secret_resource" "" {} + +# https://www.linode.com/docs/guides/secrets-management-with-terraform/ +provider "linode" { + token = var.linode_token +} + +resource "linode_sshkey" "surtur" { + label = "nbgw" + ssh_key = chomp(file("~/.ssh/surtur.pub")) +} + +resource "linode_sshkey" "leo" { + label = "nbgw" + ssh_key = chomp(file("~/.ssh/leo.pub")) +} + +resource "linode_instance" "nbgw" { + booted = true + region = var.linode_region + image = "linode/fedora38" + type = "g6-standard-1" + label = "nbgw" + group = "Terraform" + root_pass = var.linode_rootpasswd + authorized_keys = [ + linode_sshkey.surtur.ssh_key, + linode_sshkey.leo.ssh_key + ] + + connection { + type = "ssh" + user = "root" + password = var.linode_rootpasswd + host = self.ip_address + } + + # remote-exec waits for the instance setup, so local-exec below will not fail immediatelly + provisioner "remote-exec" { + inline = ["/bin/true"] + } + + provisioner "local-exec" { + command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -e 'wheel_login=${var.linode_wheel_login} hostname=${self.label}' -u root -i '${self.ip_address},' ./ansible/playbooks/common.yml" + } +} + +output "nbgw-ipv4" { + value = linode_instance.nbgw.ipv4 +} + +output "nbgw-ipv6" { + value = linode_instance.nbgw.ipv6 +} diff --git a/terraform.tf b/terraform.tf new file mode 100644 index 0000000..f6a630b --- /dev/null +++ b/terraform.tf @@ -0,0 +1,22 @@ +# https://thegeeklab.de/posts/2022/09/store-terraform-state-on-backblaze-s3/ +terraform { + required_providers { + linode = { + source = "linode/linode" + } + } + + backend "s3" { + bucket = "tfinfra" + key = "tf-infra.tfstate" + skip_credentials_validation = true + skip_region_validation = true + # endpoint = var.b2_endpoint + # region = var.b2_region + # access_key = var.b2_access_key + # secret_key = var.b2_secret_key + # encrypt = true + # openssl rand -base64 32 + # sse_customer_key = "fsRb1SXBjiUqBM0rw/YqvDixScWnDCZsK7BhnPTc93Y=" + } +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..d848503 --- /dev/null +++ b/variables.tf @@ -0,0 +1,22 @@ +variable "linode_token" { + description = "Linode API token" +} + +variable "linode_rootpasswd" { + description = "Linode root passwd" + type = string +} + +variable "linode_region" { + description = "Linode region" +} + +variable "linode_nbgw_hostname" { + description = "nbgw hostname" + type = string +} + +variable "linode_wheel_login" { + type = string + description = "username of the admin user" +}