From 3124cfd933d25913ae49b9d98115570b7dce4427 Mon Sep 17 00:00:00 2001 From: Jelle van der Waa <jelle@archlinux.org> Date: Thu, 28 Jan 2021 21:48:59 +0100 Subject: [PATCH] Add hedgedoc as new service This adds a collaborative markdown editor as newly offered service which is available via login for all Arch Linux Staff with an option to allow anonymous edits by users (not default). Users are managed via keycloak and require the Staff role to be allowed in, non staff keycloak users currently will receive an internal server error due to an upstream issue. --- docs/servers.md | 6 +++ docs/ssh-hostkeys.txt | 11 +++++ docs/ssh-known_hosts.txt | 5 ++ group_vars/all/vault_hedgedoc.yml | 12 +++++ group_vars/all/vault_postgres.yml | 32 +++++++------ host_vars/md.archlinux.org | 2 + hosts | 2 + playbooks/md.archlinux.org.yml | 22 +++++++++ roles/hedgedoc/defaults/main.yml | 2 + roles/hedgedoc/tasks/main.yml | 39 +++++++++++++++ roles/hedgedoc/templates/config.json.j2 | 37 +++++++++++++++ .../hedgedoc/templates/hedgedoc.service.d.j2 | 16 +++++++ roles/hedgedoc/templates/nginx.d.conf.j2 | 47 +++++++++++++++++++ roles/hedgedoc/templates/sequelizerc.j2 | 8 ++++ tf-stage1/archlinux.tf | 5 +- tf-stage2/keycloak.tf | 32 +++++++++++++ 16 files changed, 262 insertions(+), 16 deletions(-) create mode 100644 group_vars/all/vault_hedgedoc.yml create mode 100644 host_vars/md.archlinux.org create mode 100644 playbooks/md.archlinux.org.yml create mode 100644 roles/hedgedoc/defaults/main.yml create mode 100644 roles/hedgedoc/tasks/main.yml create mode 100644 roles/hedgedoc/templates/config.json.j2 create mode 100644 roles/hedgedoc/templates/hedgedoc.service.d.j2 create mode 100644 roles/hedgedoc/templates/nginx.d.conf.j2 create mode 100644 roles/hedgedoc/templates/sequelizerc.j2 diff --git a/docs/servers.md b/docs/servers.md index 82fdeb397..b47dc3df7 100644 --- a/docs/servers.md +++ b/docs/servers.md @@ -138,6 +138,12 @@ Medium-fast-ish packet.net Arch Linux box. ### Services - archwiki +## md.archlinux.org + + Online collborative markdwown editor for Arch Linux Staff. + +### Services + - [hedgedoc](https://hedgedoc.org/) ## Archive Mirrors diff --git a/docs/ssh-hostkeys.txt b/docs/ssh-hostkeys.txt index 0e38926ca..6a45f5684 100644 --- a/docs/ssh-hostkeys.txt +++ b/docs/ssh-hostkeys.txt @@ -207,6 +207,17 @@ 256 MD5:f6:40:bf:89:89:1a:dc:50:86:d6:0d:cc:d4:ae:15:a1 root@archlinux-packer (ED25519) 3072 MD5:db:7c:b7:7b:d6:4a:d9:9f:aa:84:ba:17:e1:a1:d8:b0 root@archlinux-packer (RSA) +# md.archlinux.org +1024 SHA256:BR7Kn7TsXpaszgByF227yoLlI8OpQ5aGHqptYsUwWgE root@archlinux-packer (DSA) +256 SHA256:vYhOL93Q0MSdaSD7PoW30twqhW6JwhO/5ylyQ9sYzhU root@archlinux-packer (ECDSA) +256 SHA256:x/WWvtqZx4HZtxyWmXihvcFRAvZTlWAUbeHxyYzxEZU root@archlinux-packer (ED25519) +3072 SHA256:d3PQVarjHA2iuopomsGtK26hMG5h6JN4+Lt+X8WdMis root@archlinux-packer (RSA) + +1024 MD5:23:3a:a6:c6:81:ab:bd:22:80:83:cd:91:4b:3d:16:a0 root@archlinux-packer (DSA) +256 MD5:29:95:e6:56:59:36:d6:f9:05:ca:3b:13:38:79:70:48 root@archlinux-packer (ECDSA) +256 MD5:35:57:8e:de:29:d4:76:7a:3b:b6:57:ff:c3:2f:9d:e0 root@archlinux-packer (ED25519) +3072 MD5:0d:cb:e7:c6:38:c1:c9:bd:6f:74:9e:bf:f1:3f:9c:f5 root@archlinux-packer (RSA) + # mirror.pkgbuild.com 1024 SHA256:O7TKGcsfAsOiY8YFNEGX8Tma5kvQFe/lGd6+StnpmAM root@archlinux-packer (DSA) 256 SHA256:6hikXsqiWU9Oqf7FSsi2iBgeeiL8/hifuaFpotiGz4U root@archlinux-packer (ECDSA) diff --git a/docs/ssh-known_hosts.txt b/docs/ssh-known_hosts.txt index 4759959c9..40f964d94 100644 --- a/docs/ssh-known_hosts.txt +++ b/docs/ssh-known_hosts.txt @@ -93,6 +93,11 @@ matrix.archlinux.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbml matrix.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPm0Ing8aSqaw/FGvPD5NqmqZjCo99xKMq1lBdfY4NdX matrix.archlinux.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCbcTp/+cwo7sKcgDjxJ1sUDQwU4xAWajOna1hC5Vnie4Kpo13hStIWmBUMHn0PkS9XbJC5hFEfE87l8ciemIiWZbxwCx93iVD2+M2S1Arso+0xvKJKEkmLdwx7Lr8bnqOnpyCt3fPCHaPoKVXWnYYvNSqkLh2QgtPv7QXnTZhhFmFmzf8dbQqJXFPpPN28y/SQ0w4iFpfuVAbVwK9UmYmjdK8FyN6V1S+8U6zZXYqaAI6wBNsa5zkczfmSM3AUy71T6DE7uceWx2hARaytf8yPyj/E6B0II7jvwa9CbcrQxvm2MStwIhuULG0ILcNfdOgYc5ddqy+m8XKN4b7WKgClfZc53FeFzBrsFrK9fRNp6mjZesj+MthKChF5M6sTpYt5Qn8c3dfhA5SmulD23K/zLxGPpluDReoEfXPZDqaNQh9JoemrBuBMCkN5MKgJBFGgkO/YnUVPpwLZAELg4zw7ON2q9Bw2CUPXMsi6CxUG0pb0dpGn+VK66YHyCyT4vbc= +# md.archlinux.org +md.archlinux.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHsMS3c+QGKLT7/rcnOrx5kI7J6zxf5djtgKYEWnqaK5LZi52KalVo2ID68xYBEtuPFKRQ8dRN+7QNQqWQWCIPU= +md.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqqsOIUGWwIz1OqclbHeREBrujf43B28MEeuEWVvgc2 +md.archlinux.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4r5WR6WQ9WjIx1bbRkygM7jQvZB2kM/D7GiEWIhyvK9g2va39MKHWEaZ9xVtkxPN4ob1/5MYDlEb6MoXLktFQwTGhi0mBSvBqjRaotsiqgdxCDjM3gaOznKDafBBE5a2pu5uQ3Nt2pwX6inNWUK9AWZjmHqcTkjdQZoPsKsu/zBuiGOC2rjhMBq2AfIJDJvYLXEbNVWx6hn7cstSPPX+4aa6miu1buJrbVQxF7aq5/vhR2dANdicerl+rnhneMKRfxmFQ2UEa5mKCW4eVYFXGxCjdIj6OEzjvcCSK+9cOaLqsF9//70qfq//jai8PrI4SAsdPyNKkouHgJ04kpE3zfu1WZ2zzWnFZBC11YccIPOAEJYeg641VxMa4gWa+t4H1P+CTNpuPZ4bxktPYCIFkgj4qzz4v5XvVpP9mOj23lm3tXLjai2NXm80MraJ95WDd2Ozf0tZn7fWZ3T0lNVqMoU522ImRrUrOIsPhjZhgowWK06/wU3FZZOA49GFnYwk= + # mirror.pkgbuild.com mirror.pkgbuild.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCBew2WqfyvxwKSnfnVrZiwnwogBFmYMMejOFP7aVT7qMXP6xT1qZ6daJEgXKI81j54TEVoGIU1lZIuvhi7hqT0= mirror.pkgbuild.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBkcn0PYBn4cqwQDhyiel4kx0EkNp//usdKVbcfT9GO+ diff --git a/group_vars/all/vault_hedgedoc.yml b/group_vars/all/vault_hedgedoc.yml new file mode 100644 index 000000000..1360262c2 --- /dev/null +++ b/group_vars/all/vault_hedgedoc.yml @@ -0,0 +1,12 @@ +$ANSIBLE_VAULT;1.1;AES256 +63373465656232323265643638376633383230643139323535656565396362636330396130663263 +6233666233646537363536323032366337613765336530350a336130303663383337643737323665 +66393863666135616430643931376239616266616664623034653134303563306239653736616464 +3666386534306434640a386261383039643937316564303561666133643536353839346262353833 +63313264363162336166666361366533336265386433376136623435666661363861663239303236 +32623930393838323964646166393037633564343262336565383331636633666230313434326635 +35366433313636646466303565356138386436323266316534343231303861336462343637383065 +66643663356363356466613933376331656432306434393432643163326663343161636333303134 +62383362393933636164363666613230316439396235383636346530343536636432343330623330 +33373135343033623437613836393564376366613366636662383337623534386161623663386631 +356435336630613834356535646239616139 diff --git a/group_vars/all/vault_postgres.yml b/group_vars/all/vault_postgres.yml index 07b43d6af..6439cef7f 100644 --- a/group_vars/all/vault_postgres.yml +++ b/group_vars/all/vault_postgres.yml @@ -1,16 +1,18 @@ $ANSIBLE_VAULT;1.1;AES256 -63366165396562363135333830643834663532353865653138636334343664343138313365336436 -6436383535623062656466646461303365373533363430610a373930366237326137613362336164 -34633732376464646437356137343631353434396432623633353036663738343538303966353464 -6535383735323763330a633436646331623131633564393130376139363061663139626366666634 -66643763376463386231663832303664633632613530633266313431646333316534326237373137 -36663233303561313965633333313738643331396465666263663034336163303339383437353332 -64626462393336623130316535303531623634656235313939636232653930303432636364386330 -61613736356239613935323430396233323335363862353039343936653631656562656231323237 -65336663666166326630663565353032303461613431343662326535363761333665336137316161 -62366561383736326338346362333939386332356137653866383334333262663839313438363631 -31663062373366383133343063313931366637346131626338656538613166656664393930373733 -62336639356361663962373039366362343966616363653838313538623039666665633565323765 -62346337636336663333613766396436313238346565633133383030633931613965396261333766 -31326337646438623631616639383764636332336336353830616633396336333536623861356637 -333839656139326135636238643561356366 +33396466383935313930366561313862626233306538393832646563343039313536306464363534 +6233653830383738333733666230396233626132303532310a313864373236346464353233653337 +66646461356531373033393031396464663965373036663266366463333735633061646138316138 +3538663833656636370a316430636238326631363937393865373836616633303564646530356530 +33626639303738343137353161633735356161353839616236313565663938663539653166656262 +62623565626239363766653733663361643737386239613838323537636631333431336165613639 +62306166383735663732313438313234306637393237623930383561346233363064316664366234 +62383166346534373863303866646562386330313932343238306232366466383165663339306633 +35613534386663633034313032363765343864366634663733393666643435383064643133653630 +39346563396661353666313732663538663334616166316163643536616535306336653639656431 +64333532616636376661663465323763346566623830643533663533363161646234333365643134 +32663437613831366339646531366234386665626231653864363138356638346139646134393865 +39616535656665363434633338646334356562323432346562613562616361646262616237376632 +39393264356137326335333433643266343639366630356366646165333165613331623034653462 +64383930376664393938363835373131636437396330366532616262656565306161663239383566 +37326164343637303764343833373764316232303039303762633861336465323864383934323538 +3165 diff --git a/host_vars/md.archlinux.org b/host_vars/md.archlinux.org new file mode 100644 index 000000000..ca1d97558 --- /dev/null +++ b/host_vars/md.archlinux.org @@ -0,0 +1,2 @@ +--- +filesystem: btrfs diff --git a/hosts b/hosts index 253602d96..59c4b9adb 100644 --- a/hosts +++ b/hosts @@ -45,6 +45,7 @@ mail.archlinux.org wiki.archlinux.org patchwork.archlinux.org security.archlinux.org +md.archlinux.org [borg_hosts] prio.ch-s012.rsync.net @@ -139,6 +140,7 @@ america.mirror.pkgbuild.com europe.mirror.pkgbuild.com repro2.pkgbuild.com runner1.archlinux.org +md.archlinux.org [kape_servers] asia.mirror.pkgbuild.com diff --git a/playbooks/md.archlinux.org.yml b/playbooks/md.archlinux.org.yml new file mode 100644 index 000000000..aba370277 --- /dev/null +++ b/playbooks/md.archlinux.org.yml @@ -0,0 +1,22 @@ +--- + +- name: setup hedgedoc server + hosts: md.archlinux.org + remote_user: root + roles: + - { role: common } + - { role: tools } + - { role: firewalld } + - { role: sshd } + - { role: unbound } + - { role: root_ssh } + - { role: borg_client, tags: ["borg"] } + - { role: nginx } + - { role: certbot } + - role: postgres + postgres_max_connections: 100 + postgres_ssl: 'off' + postgres_shared_buffers: 512MB + postgres_effective_cache_size: 1GB + - { role: hedgedoc, hedgedoc_domain: "md.archlinux.org" } + - { role: prometheus_exporters } diff --git a/roles/hedgedoc/defaults/main.yml b/roles/hedgedoc/defaults/main.yml new file mode 100644 index 000000000..e41478b40 --- /dev/null +++ b/roles/hedgedoc/defaults/main.yml @@ -0,0 +1,2 @@ +hedgedoc_nginx_conf: /etc/nginx/nginx.d/hedgedoc.conf +hedgedoc_domain: md.archlinux.org diff --git a/roles/hedgedoc/tasks/main.yml b/roles/hedgedoc/tasks/main.yml new file mode 100644 index 000000000..5643369cd --- /dev/null +++ b/roles/hedgedoc/tasks/main.yml @@ -0,0 +1,39 @@ +--- + +- name: install hedgedoc + pacman: name=hedgedoc state=present + +- name: add hedgedoc postgres db + postgresql_db: db=hedgedoc + become: yes + become_user: postgres + become_method: su + +- name: add hedgedoc postgres user + postgresql_user: db=hedgedoc name=hedgedoc password={{ vault_postgres_users.hedgedoc }} encrypted=true + become: yes + become_user: postgres + become_method: su + +- name: make nginx log dir + file: path=/var/log/nginx/{{ hedgedoc_domain }} state=directory owner=root group=root mode=0755 + +- name: set up nginx + template: src=nginx.d.conf.j2 dest={{ hedgedoc_nginx_conf }} owner=root group=root mode=644 + notify: reload nginx + tags: ['nginx'] + +- name: add hedgedoc.service.d dir + file: state=directory path=/etc/systemd/system/hedgedoc.service.d owner=root group=root mode=0755 + +- name: install hedgedoc.service snippet for configuration + template: src=hedgedoc.service.d.j2 dest=/etc/systemd/system/hedgedoc.service.d/local.conf owner=root group=root mode=0644 + +- name: install hedgedoc config file + template: src=config.json.j2 dest=/etc/webapps/hedgedoc/config.json owner=root group=root mode=0644 + +- name: install hedgedoc sequelizerc file + template: src=sequelizerc.j2 dest=/etc/webapps/hedgedoc/sequelizerc owner=root group=root mode=0644 + +- name: start and enable hedgedoc + service: name=hedgedoc.service enabled=yes state=started diff --git a/roles/hedgedoc/templates/config.json.j2 b/roles/hedgedoc/templates/config.json.j2 new file mode 100644 index 000000000..607b5a664 --- /dev/null +++ b/roles/hedgedoc/templates/config.json.j2 @@ -0,0 +1,37 @@ +{ + "production": { + "sessionSecret": "{{ vault_hedgedoc_session_secret }}", + "email": false, + "domain": "{{ hedgedoc_domain }}", + "loglevel": "info", + "protocolUseSSL": true, + "allowAnonymous": false, + "allowAnonymousEdits": true, + "defaultPermission": "limited", + "hsts": { + "enable": true, + "maxAgeSeconds": 31536000, + "includeSubdomains": true, + "preload": true + }, + "csp": { + "enable": true, + "directives": {}, + "upgradeInsecureRequests": "true", + "addDefaults": true, + "addDisqus": false, + "addGoogleAnalytics": false + }, + "cookiePolicy": "lax", + "db": { + "dialect": "postgres", + "username": "hedgedoc", + "password": "{{ vault_postgres_users.hedgedoc }}", + "database": "hedgedoc", + "host": "localhost", + "port": "5432", + "dialect": "postgres" + }, + "linkifyHeaderStyle": "gfm" + } +} diff --git a/roles/hedgedoc/templates/hedgedoc.service.d.j2 b/roles/hedgedoc/templates/hedgedoc.service.d.j2 new file mode 100644 index 000000000..36810b009 --- /dev/null +++ b/roles/hedgedoc/templates/hedgedoc.service.d.j2 @@ -0,0 +1,16 @@ +[Service] +Environment=CMD_OAUTH2_USER_PROFILE_URL=https://accounts.archlinux.org/auth/realms/archlinux/protocol/openid-connect/userinfo +Environment=CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username +Environment=CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name +Environment=CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=email +Environment=CMD_OAUTH2_TOKEN_URL=https://accounts.archlinux.org/auth/realms/archlinux/protocol/openid-connect/token +Environment=CMD_OAUTH2_AUTHORIZATION_URL=https://accounts.archlinux.org/auth/realms/archlinux/protocol/openid-connect/auth +Environment=CMD_OAUTH2_CLIENT_ID=openid_hedgedoc +Environment=CMD_OAUTH2_CLIENT_SECRET={{ vault_hedgedoc_client_secret }} +Environment=CMD_OAUTH2_SCOPE="openid email profile roles" +Environment=CMD_OAUTH2_ROLES_CLAIM=roles +Environment=CMD_OAUTH2_ACCESS_ROLE=Staff +Environment=CMD_OAUTH2_PROVIDERNAME=Keycloak +Environment=CMD_DOMAIN=md.archlinux.org +Environment=CMD_PROTOCOL_USESSL=true +Environment=CMD_URL_ADDPORT=false diff --git a/roles/hedgedoc/templates/nginx.d.conf.j2 b/roles/hedgedoc/templates/nginx.d.conf.j2 new file mode 100644 index 000000000..293486c68 --- /dev/null +++ b/roles/hedgedoc/templates/nginx.d.conf.j2 @@ -0,0 +1,47 @@ +upstream hedgedoc { + server localhost:3000; +} + +server { + listen 80; + listen [::]:80; + server_name {{ hedgedoc_domain }}; + + access_log /var/log/nginx/{{ hedgedoc_domain }}/access.log main; + error_log /var/log/nginx/{{ hedgedoc_domain }}/error.log; + + include snippets/letsencrypt.conf; + + location / { + rewrite ^(.*) https://{{ hedgedoc_domain }}$1 permanent; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name {{ hedgedoc_domain }}; + + access_log /var/log/nginx/{{ hedgedoc_domain }}/access.log main; + error_log /var/log/nginx/{{ hedgedoc_domain }}/error.log; + + ssl_certificate /etc/letsencrypt/live/{{ hedgedoc_domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ hedgedoc_domain }}/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/{{ hedgedoc_domain }}/chain.pem; + + location / { + proxy_pass http://hedgedoc; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /socket.io/ { + proxy_pass http://hedgedoc; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} diff --git a/roles/hedgedoc/templates/sequelizerc.j2 b/roles/hedgedoc/templates/sequelizerc.j2 new file mode 100644 index 000000000..8b657b7e2 --- /dev/null +++ b/roles/hedgedoc/templates/sequelizerc.j2 @@ -0,0 +1,8 @@ +var path = require('path'); + +module.exports = { + 'config': path.resolve('config.json'), + 'migrations-path': path.resolve('lib', 'migrations'), + 'models-path': path.resolve('lib', 'models'), + 'url': 'postgres://hedgedoc:{{ vault_postgres_users.hedgedoc }}@localhost:5432/hedgedoc' +} diff --git a/tf-stage1/archlinux.tf b/tf-stage1/archlinux.tf index 9a7dfb9ef..6413c2485 100644 --- a/tf-stage1/archlinux.tf +++ b/tf-stage1/archlinux.tf @@ -139,6 +139,10 @@ locals { domain = "mirror" zone = hetznerdns_zone.pkgbuild.id } + "md.archlinux.org" = { + server_type = "cx11" + domain = "md" + } } # This creates gitlab pages varification entries. @@ -489,4 +493,3 @@ resource "hcloud_volume" "homedir" { size = 100 server_id = hcloud_server.machine["homedir.archlinux.org"].id } - diff --git a/tf-stage2/keycloak.tf b/tf-stage2/keycloak.tf index 775af5861..b68461178 100644 --- a/tf-stage2/keycloak.tf +++ b/tf-stage2/keycloak.tf @@ -33,6 +33,12 @@ data "external" "vault_monitoring" { "--format", "json"] } +data "external" "vault_hedgedoc" { + program = ["${path.module}/../misc/get_key.py", "group_vars/all/vault_hedgedoc.yml", + "vault_hedgedoc_client_secret", + "--format", "json"] +} + provider "keycloak" { client_id = "admin-cli" username = data.external.vault_keycloak.result.vault_keycloak_admin_user @@ -785,3 +791,29 @@ resource "keycloak_openid_client_scope" "email" { include_in_token_scope = true consent_screen_text = "$${emailScopeConsentText}" } + +resource "keycloak_openid_client" "hedgedoc_openid_client" { + realm_id = "archlinux" + client_id = "openid_hedgedoc" + client_secret = data.external.vault_hedgedoc.result.vault_hedgedoc_client_secret + + name = "Hedgedoc" + enabled = true + + access_type = "CONFIDENTIAL" + standard_flow_enabled = true + valid_redirect_uris = [ + "https://md.archlinux.org/*", + ] +} + +resource "keycloak_openid_user_realm_role_protocol_mapper" "hedgedoc_user_realm_role_mapper" { + realm_id = "archlinux" + client_id = keycloak_openid_client.hedgedoc_openid_client.id + name = "user realms" + + claim_name = "roles" + multivalued = true + add_to_id_token = false + add_to_access_token = false +} -- GitLab