Projects/Matrix HS: Difference between revisions

From Hackerspace Amersfoort
Jump to navigation Jump to search
(dat limiet was een snafu van mij, niet van smurfnet)
No edit summary
(3 intermediate revisions by the same user not shown)
Line 7: Line 7:
}}
}}


Het bestuur (bij monde van [[Polyfloyd]]) heeft mij gevraagd om bij wijze van proef een Matrix-homeserver op te zetten. Dit om toegang tot de
[[Polyfloyd]] heeft mij gevraagd om bij wijze van proef een Matrix-homeserver op te zetten. Dit om toegang tot de IRC-chat(s) laagdrempeliger te maken. Niet iedereen heeft immers een bouncer/bak om irissi op te draaien, of kennis/tijd/zin om zoiets op te zetten.
IRC-chat(s) laagdrempeliger te maken. Niet iedereen heeft immers een bouncer/bak om irissi op te draaien, of kennis/tijd/zin om zoiets op te zetten.


Op dit moment is de inhoud van de wikipagina alleen nuttig voor het bestuur (of mensen aangewezen daardoor), maar kan op een later moment gewijzigd worden om informatie te geven voor eindgebruikers.
Je kan inloggen met je LDAP-account. Let wel dat de server nog in testfase is, dus geen garanties voor (goede) werking.


De 'realm' van de Matrix-server is matrix.bitlair.nl, dit omdat bitlair.nl gebruiken (en dus op bitlair.nl delegeren dmv SRV-record of .well-known) vereist dat de HS een geldig certificaat voor bitlair.nl heeft. Waar in docs van het ansible-playbook wordt gerefereerd aan DOMAIN is dat dus matrix.bitlair.nl.
De 'realm' van de Matrix-server is bitlair.nl, de homeserver staat op matrix.bitlair.nl


== Gebruik ==
== Gebruik ==
* Log in met Element web (de de-facto web client voor Matrix, wordt by default geinstalleerd met het ansible playbook) op matrix.bitlair.nl
 
* OF gebruik een andere matrix-client en stuur die naar matrix.matrix.bitlair.nl
In beide gevallen is je username op IRC gelijk aan je localpart (@testuser:example.org en @flimpie:bitlair.nl worden respectievelijk testuser en flimpie).
* Join #smurfnet_#bitlair:matrix.bitlair.nl om in de bridge naar #bitlair te komen
 
Dit kan je wijzigen. Nadat je joint krijg je een invite voor een PM met de 'statusbot'. Als je naar de bot '!nick irc.smurfnet.ch je_nieuwe_username' stuurt wordt je username gewijzigd.
 
Als iemand anders (of jijzelf met een andere client) al je username heeft komt daar een suffix achter (bijv test wordt test1). Je krijgt altijd als je verbindt een berichtje van de statusbot met als inhoud "You've been connected to the IRC network 'irc.smurfnet.ch' as JE_USERNAME".
 
=== Zelf inloggen op de server, met LDAP account) ===
 
* Log in met Element web (de de-facto web client voor Matrix, wordt by default geinstalleerd met het ansible playbook) op element.bitlair.nl, log in met je LDAP username en password.
* OF gebruik een andere matrix-client en stuur die naar matrix.bitlair.nl
* Join #bitlair:bitlair.nl [https://matrix.to/#/#bitlair:bitlair.nl] om in de bridge naar #bitlair te komen
 
=== Inloggen vanaf een andere homeserver ===
 
* Join het kanaal. [https://matrix.to/#/#bitlair:bitlair.nl]


== Configuratie ==
== Configuratie ==
Line 28: Line 40:
deze lokaal buiten enige version control.
deze lokaal buiten enige version control.


  <nowiki>matrix_domain: matrix.bitlair.nl
  <nowiki>matrix_domain: bitlair.nl


matrix_ssl_retrieval_method: lets-encrypt
matrix_ssl_retrieval_method: lets-encrypt
# snakeoil tot cname er is
matrix_ssl_retrieval_method: manually-managed


matrix_ssl_lets_encrypt_support_email: bestuur@bitlair.nl
matrix_ssl_lets_encrypt_support_email: bestuur@bitlair.nl
# A shared secret (between Coturn and Synapse) used for authentication.
# A shared secret (between Coturn and Synapse) used for authentication.
# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`).
# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`).
matrix_coturn_turn_static_auth_secret: "GEHEIM"
matrix_coturn_turn_static_auth_secret: "nice try"


# A secret used to protect access keys issued by the server.
# A secret used to protect access keys issued by the server.
# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`).
# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`).
matrix_synapse_macaroon_secret_key: "GEHEIM"
matrix_synapse_macaroon_secret_key: "nice try"


matrix_well_known_matrix_server_enabled: true
matrix_well_known_matrix_server_enabled: true


matrix_postgres_connection_password: 'GEHEIM'
matrix_postgres_connection_password: 'nice try'
matrix_nginx_proxy_worker_connections: 8192
matrix_nginx_proxy_worker_connections: 8192
matrix_nginx_proxy_worker_processes: 8
matrix_nginx_proxy_worker_processes: 8
Line 51: Line 61:
matrix_synapse_workers_enabled: true
matrix_synapse_workers_enabled: true


matrix_common_after_systemd_service_start_wait_for_timeout_seconds: 600
matrix_common_after_systemd_service_start_wait_for_timeout_seconds: 240


matrix_synapse_admin_enabled: true
matrix_synapse_admin_enabled: true
Line 69: Line 79:
       ggIBAPFua0cL9FPbBsZU53eZbYeBDX7aArAzkA68JnSpATX34RvvNyvi7mAzEyzN
       ggIBAPFua0cL9FPbBsZU53eZbYeBDX7aArAzkA68JnSpATX34RvvNyvi7mAzEyzN
       j347N7sN4LmotkGRHnuK7jp8gmuVrH53ecJxrQXaKgEVWe/JcgHIftZHs3fl6iBA
       j347N7sN4LmotkGRHnuK7jp8gmuVrH53ecJxrQXaKgEVWe/JcgHIftZHs3fl6iBA
      za9c4M+d2BtzcyKs6GHkSIPRerdMO5fjbiusWdHpTIvjTwo1BugQoAtszhZ/20cs
       3028VUAVoEvplky+/w1elPTP6VDwHNdYo/a4e5pzf3+WjdUFvuOs7R1g+1KVdxv9
       3028VUAVoEvplky+/w1elPTP6VDwHNdYo/a4e5pzf3+WjdUFvuOs7R1g+1KVdxv9
       lxsOcPwHtiQgwFXhQuqjR7GSCq5j7QsM6DyYU2GbZadmyagE40OVCg12gli8ZWaF
       lxsOcPwHtiQgwFXhQuqjR7GSCq5j7QsM6DyYU2GbZadmyagE40OVCg12gli8ZWaF
Line 116: Line 127:
       federate: true
       federate: true
       aliasTemplate: "#irc_$CHANNEL"
       aliasTemplate: "#irc_$CHANNEL"
    mappings:
      "#bitlair":
        roomIds: ["!qBaVlwurBmrZYdkQLA:bitlair.nl"]
     membershipLists:
     membershipLists:
       enabled: true
       enabled: true
Line 131: Line 145:
       joinAttempts: -1
       joinAttempts: -1
     ircClients:
     ircClients:
       nickTemplate: "$USERID"
       nickTemplate: "$LOCALPART"
       allowNickChanges: true
       allowNickChanges: true
       maxClients: 1
       maxClients: 100
       idleTimeout: 0
       idleTimeout: 0
       reconnectIntervalMs: 5000
       reconnectIntervalMs: 5000
Line 139: Line 153:
       lineLimit: 3
       lineLimit: 3


matrix_prometheus_enabled: true
matrix_prometheus_enabled: false


matrix_prometheus_node_exporter_enabled: true
matrix_prometheus_node_exporter_enabled: false


matrix_grafana_enabled: true
matrix_grafana_enabled: false


matrix_grafana_anonymous_access: true
matrix_grafana_anonymous_access: true
Line 153: Line 167:


# Changing the password subsequently won't work.
# Changing the password subsequently won't work.
matrix_grafana_default_admin_password: "GEHEIM"</nowiki>
matrix_grafana_default_admin_password: "mooi niet"
 
matrix_synapse_ext_password_provider_rest_auth_enabled: true
# matrix-ma1sd is the hostname of the ma1sd Docker container
matrix_synapse_ext_password_provider_rest_auth_endpoint: "http://matrix-ma1sd:8090"
 
matrix_ma1sd_configuration_extension_yaml: |
  ldap:
    enabled: true
    connection:
      host: ldap.bitlair.nl
      tls: true
      port: 636
      baseDNs: ['OU=Members,DC=bitlair,DC=nl']
      bindDn: cn=matrix,ou=System,dc=bitlair,dc=nl
      bindPassword: nice try
    attribute:
      uid:
        type: 'uid'
        value: 'uid'
      name: 'uid'
      threepid:
        email:
          - 'mail'
  logging:
    root: error    # default level for all loggers (apps and thirdparty libraries)
    app: warn      # logt anders realnames (CN) naar journalctl
    requests: false # log request and response</nowiki>


=== iptables ===
=== iptables ===
Line 167: Line 208:
De volgende regels SNATten de bridges die docker maakt:
De volgende regels SNATten de bridges die docker maakt:


  <nowiki>-A POSTROUTING -s 172.19.0.0/16 ! -o br-c21c06bc9787 -j SNAT --to-source 185.205.52.200
  <nowiki>iptables -t nat -I POSTROUTING -s 172.19.0.0/16 ! -o br-634561587f89 -j SNAT --to-source 185.205.52.200
-A POSTROUTING -s 172.18.0.0/16 ! -o br-bcf36440d8a7 -j SNAT --to-source 185.205.52.200
iptables -t nat -I POSTROUTING -s 172.18.0.0/16 ! -o br-5275cf72302f -j SNAT --to-source 185.205.52.200
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j SNAT --to-source 185.205.52.200</nowiki>
iptables -t nat -I POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j SNAT --to-source 185.205.52.200/nowiki>


De br-nnnnnn interfaces veranderen niet van naam, deze zijn gekoppeld aan een docker containernetwerk. (probeer bijv <code>docker network inspect
De br-nnnnnn interfaces veranderen niet van naam (tenzij je het playbook uninstallt vanzelfsprekend), deze zijn gekoppeld aan een docker containernetwerk. (probeer bijv <code>docker network inspect
bcf36440d8a7</code>)
bcf36440d8a7</code>)


Line 198: Line 239:
Alles hieronder is een richtlijn, allemaal at the discretion van het bestuur
Alles hieronder is een richtlijn, allemaal at the discretion van het bestuur


* Nieuwe room maken en die configureren als bridgeroom voor #bitlair. Op dit moment heet de room die #bitlair bridget #smurfnet_#bitlair:matrix.bitlair.nl, dat is op zijn zachtst gezegd een beetje onhandig. Dit zou dus #bitlair:matrix.bitlair.nl kunnen worden.
* Koppelen aan LDAP, zodat members met hun gebruikelijke account kunnen inloggen (maar de rooms zijn gebridged dus iemand kan prima van een andere/zijn eigen HS joinen, de room op Matrix is net zo publiek als op IRC)
* ...
* ...

Revision as of 08:39, 4 December 2021


NoPicture.png
Project Matrix homeserver
Name Matrix homeserver
Start 2021/11/15
End
Contact User:Hillebrand
Website
Information Matrix homeserver tbv Bitlair members
Status Alpha


Polyfloyd heeft mij gevraagd om bij wijze van proef een Matrix-homeserver op te zetten. Dit om toegang tot de IRC-chat(s) laagdrempeliger te maken. Niet iedereen heeft immers een bouncer/bak om irissi op te draaien, of kennis/tijd/zin om zoiets op te zetten.

Je kan inloggen met je LDAP-account. Let wel dat de server nog in testfase is, dus geen garanties voor (goede) werking.

De 'realm' van de Matrix-server is bitlair.nl, de homeserver staat op matrix.bitlair.nl

Gebruik

In beide gevallen is je username op IRC gelijk aan je localpart (@testuser:example.org en @flimpie:bitlair.nl worden respectievelijk testuser en flimpie).

Dit kan je wijzigen. Nadat je joint krijg je een invite voor een PM met de 'statusbot'. Als je naar de bot '!nick irc.smurfnet.ch je_nieuwe_username' stuurt wordt je username gewijzigd.

Als iemand anders (of jijzelf met een andere client) al je username heeft komt daar een suffix achter (bijv test wordt test1). Je krijgt altijd als je verbindt een berichtje van de statusbot met als inhoud "You've been connected to the IRC network 'irc.smurfnet.ch' as JE_USERNAME".

Zelf inloggen op de server, met LDAP account)

  • Log in met Element web (de de-facto web client voor Matrix, wordt by default geinstalleerd met het ansible playbook) op element.bitlair.nl, log in met je LDAP username en password.
  • OF gebruik een andere matrix-client en stuur die naar matrix.bitlair.nl
  • Join #bitlair:bitlair.nl [1] om in de bridge naar #bitlair te komen

Inloggen vanaf een andere homeserver

  • Join het kanaal. [2]

Configuratie

Ansible playbook

De server wordt geconfigureerd met een Ansible-playbook [3]. De configuratie van dit playbook staat in /opt/matrix-ansible-playbook/matrix-docker-ansible-deploy/inventory/host_vars/matrix.bitlair.nl/vars.yml. Dit kan op een later moment in een git-repo geplaatst worden, maar voor het gemak (lees: in deze testsituatie makkelijk wijzingen kunnen doorvoeren) staat deze lokaal buiten enige version control.

matrix_domain: bitlair.nl

matrix_ssl_retrieval_method: lets-encrypt

matrix_ssl_lets_encrypt_support_email: bestuur@bitlair.nl
# A shared secret (between Coturn and Synapse) used for authentication.
# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`).
matrix_coturn_turn_static_auth_secret: "nice try"

# A secret used to protect access keys issued by the server.
# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`).
matrix_synapse_macaroon_secret_key: "nice try"

matrix_well_known_matrix_server_enabled: true

matrix_postgres_connection_password: 'nice try'
matrix_nginx_proxy_worker_connections: 8192
matrix_nginx_proxy_worker_processes: 8

matrix_synapse_workers_enabled: true

matrix_common_after_systemd_service_start_wait_for_timeout_seconds: 240

matrix_synapse_admin_enabled: true

matrix_appservice_irc_enabled: true

matrix_appservice_irc_ircService_servers:
  irc.smurfnet.ch: # WIJZIG NAAR irc.smurfnet.ch
    sslselfsign: true
    ca: |
      -----BEGIN CERTIFICATE-----
      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
      kqrsw8uq38kvNTsxsR6qfSq+A7/D2EjLu00=
      -----END CERTIFICATE-----
    name: "Smurfnet"
    port: 6697 # WIJZIG NAAR 6697
    ssl: true # WIJZIG NAAR TRUE
    sasl: false
    allowExpiredCerts: true
    sendConnectionMessages: true
    botConfig:
      enabled: false
      nick: "flimpie_"
      joinChannelsIfNoUsers: true
    privateMessages:
      enabled: true
      federate: true
    dynamicChannels:
      enabled: true
      createAlias: true
      published: false
      joinRule: public
      groupId: +smurfnet:localhost
      federate: true
      aliasTemplate: "#irc_$CHANNEL"
    mappings:
      "#bitlair":
        roomIds: ["!qBaVlwurBmrZYdkQLA:bitlair.nl"]
    membershipLists:
      enabled: true
      floodDelayMs: 10000
      global:
        ircToMatrix:
          initial: true
          incremental: true
        matrixToIrc:
          initial: true
          incremental: true
    matrixClients:
      userTemplate: "@smurfnet_$NICK"
      displayName: "$NICK"
      joinAttempts: -1
    ircClients:
      nickTemplate: "$LOCALPART"
      allowNickChanges: true
      maxClients: 100
      idleTimeout: 0
      reconnectIntervalMs: 5000
      concurrentReconnectLimit: 50
      lineLimit: 3

matrix_prometheus_enabled: false

matrix_prometheus_node_exporter_enabled: false

matrix_grafana_enabled: false

matrix_grafana_anonymous_access: true
# grafiekjes zijn handig, kan geen kwaad en altijd nog uit...

# This has no relation to your Matrix user id. It can be any username you'd like.
# Changing the username subsequently won't work.
matrix_grafana_default_admin_user: "bitlair"

# Changing the password subsequently won't work.
matrix_grafana_default_admin_password: "mooi niet"

matrix_synapse_ext_password_provider_rest_auth_enabled: true
# matrix-ma1sd is the hostname of the ma1sd Docker container
matrix_synapse_ext_password_provider_rest_auth_endpoint: "http://matrix-ma1sd:8090"

matrix_ma1sd_configuration_extension_yaml: |
  ldap:
    enabled: true
    connection:
      host: ldap.bitlair.nl
      tls: true
      port: 636
      baseDNs: ['OU=Members,DC=bitlair,DC=nl']
      bindDn: cn=matrix,ou=System,dc=bitlair,dc=nl
      bindPassword: nice try
    attribute:
      uid:
        type: 'uid'
        value: 'uid'
      name: 'uid'
      threepid:
        email:
          - 'mail'
  logging:
    root: error     # default level for all loggers (apps and thirdparty libraries)
    app: warn       # logt anders realnames (CN) naar journalctl
    requests: false # log request and response

iptables

Omdat het publieke IPv4 adres over een interface met een RFC6598 (CGNAT) adres wordt gerouteerd moet er voor Docker een SNAT regel worden ingesteld in iptables. Docker stelt automatisch een MASQUERADE in voor alle bridges, maar dit moet dus een SNAT met uiteindelijke source 185.205.52.200 worden.

Dit wordt enigszins hacky gedaan met een service die draait nadat Synapse en Coturn (die hebben beide een eigen netwerk) zijn gestart. Als die zijn gestart zijn de MASQUERADES ingesteld, die worden dan overschreden door de SNATs te -I'en.

Het script staat in /sbin/docker-iptables-rules, de unitfile staat in /etc/systemd/system/docker-iptables.service.

De volgende regels SNATten de bridges die docker maakt:

<nowiki>iptables -t nat -I POSTROUTING -s 172.19.0.0/16 ! -o br-634561587f89 -j SNAT --to-source 185.205.52.200

iptables -t nat -I POSTROUTING -s 172.18.0.0/16 ! -o br-5275cf72302f -j SNAT --to-source 185.205.52.200 iptables -t nat -I POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j SNAT --to-source 185.205.52.200/nowiki>

De br-nnnnnn interfaces veranderen niet van naam (tenzij je het playbook uninstallt vanzelfsprekend), deze zijn gekoppeld aan een docker containernetwerk. (probeer bijv docker network inspect bcf36440d8a7)

Onderhoudstaken

Updaten (of wijzigen van config van) playbook

/opt/matrix-ansible-playbook/update-playbook-and-start-all.sh

Draai dit als root. Pullt playbook, update het (met de lokale ansible install dus) en restart docker-iptables zodat de SNAT regels weer bovenaan staan. Staat als cronjob iedere 2 weken:

0 2 1,14 * * /opt/matrix-ansible-playbook/update-playbook-and-start-all.sh >/dev/null 2>&1

Adminpanel

Ga naar https://matrix.bitlair.nl/synapse-admin en log in met een admin-user.

User toevoegen

# /usr/local/bin/matrix-synapse-register-user <your-username> <your-password> <admin access: 0 or 1>

Graag usernames in testfase prefixen met DEMO_

To-do

Alles hieronder is een richtlijn, allemaal at the discretion van het bestuur

  • ...