Compare commits

...

284 commits
alexvm ... main

Author SHA1 Message Date
Quentin 88a7c04cee
media-async-upload must be in the matrix group
note: the group stanza is not mandatory
2021-09-20 09:52:13 +02:00
Quentin 136d176176
Synapse does not use GlusterFS anymore 2021-09-17 18:49:45 +02:00
Quentin 2a0610658d Upgrade synapse+riot web 2021-09-17 18:24:00 +02:00
Quentin 6db8495bbf
Remove fb2nx that never worked 2021-09-17 17:42:16 +02:00
Quentin 4ea2494bd5
Update bottin 2021-09-17 17:41:57 +02:00
Quentin acd46fde80
Remove connection limit dovecot 2021-09-14 17:46:06 +02:00
Quentin 6716687fd7
Finally fix dovecot 2021-09-14 14:02:50 +02:00
Quentin a2a25e2ea4
Use cn instead of mail to store emails 2021-09-14 11:33:29 +02:00
Quentin e74bda617c
Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-09-10 18:33:07 +02:00
Quentin 2dfd006dc5
Upgrade bagage and fix mem leak 2021-09-10 18:32:50 +02:00
Alex 9c4f78619d
Update guichet config: remove useless default groups nextcloud and seafile 2021-09-10 15:32:17 +02:00
Quentin 8fe0a78b0c
Upgrade Bagage 2021-09-03 11:02:22 +02:00
Quentin e66b1c2c54
Upgrade Plume 2021-09-02 15:35:59 +02:00
Quentin d40c41004d Add bagage deployment 2021-08-20 17:39:07 +02:00
Quentin 09269e8497 Merge pull request 'bump diplonat version 2->3' (#39) from bump-diplonat into main
Reviewed-on: Deuxfleurs/infrastructure#39
2021-08-19 11:43:28 +02:00
darkgallium e26f57c8eb bump diplonat version 2->3 2021-08-19 11:33:36 +02:00
Alex d25f4d18aa
update guichet 2021-08-18 14:17:31 +02:00
Alex b8470be123
Update guichet 2021-08-16 16:45:04 +02:00
Alex 9d5b490fd9
add restart with mode "delay" stance to diplonat 2021-07-26 22:58:51 +02:00
Quentin 9304997d84
Upgrade guichet & postgres 2021-07-22 11:03:36 +02:00
Alex 2f37aaaf76
update drone server to 2.0.4 2021-07-08 11:12:05 +02:00
Alex 69f063e406
Update garage to handle ed25519 keys for TLS 2021-07-08 11:07:45 +02:00
Quentin 8302595f65
Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-07-02 17:07:19 +02:00
Quentin 4fdc4a5144
Add pv for psql + upgrade postgres to 13.3 2021-07-02 17:06:58 +02:00
Quentin 2b39a896a7 Postgres can not be run as root 2021-07-02 14:45:59 +02:00
Quentin e97496e09d fix entrypoint 2021-07-02 14:16:33 +02:00
Quentin 2670c8f8f1 libc is needed fos stolon 2021-07-02 14:08:22 +02:00
Quentin 0a6ffcacd2 Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure into main 2021-07-02 13:11:29 +02:00
Quentin 2d61f1449d Upgrade postgresql 2021-07-02 13:10:49 +02:00
Quentin 80c2f1f701
Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-07-01 23:49:08 +02:00
Quentin e640f82eb8
Add 500Mo x3 more RAM to postgres and 2Go less RAM to Matrix 2021-07-01 23:48:11 +02:00
Alex 455e4db784
update guichet 2021-07-01 16:30:21 +02:00
Quentin 576ac2772e
Update config to add more time to pull images 2021-07-01 15:53:41 +02:00
Quentin 1277d94bec
Remove easybridge + increase nomad docker timeout when pulling images 2021-07-01 15:36:54 +02:00
Quentin b9f0f012bd
Update synapse configuration 2021-07-01 14:25:04 +02:00
Quentin 4b68522721
Add locales 2021-07-01 14:23:33 +02:00
Quentin 3c8cd4ca1c
Deactivate guests + expose _synapse api 2021-06-30 16:24:03 +02:00
Quentin 784efbcc9b
Add a restart policy 2021-06-30 12:57:13 +02:00
Quentin 2d30e1a9c7
Log to journald 2021-06-29 13:57:01 +02:00
Quentin 42c020e00b
Fix typo 2021-06-04 21:39:44 +02:00
Quentin 7e82b0d94d Add git 2021-06-04 21:32:45 +02:00
Quentin efcdef7856
Matrix 1.35.1 + S3 backend 2021-06-04 19:48:50 +02:00
Alex 62fa15390b
Update easybridge 2021-06-01 23:44:57 +02:00
Alex a26d41259a
Update garage to v0.3.0 2021-05-28 15:55:52 +02:00
Quentin 73d30b9aa5
Disable syslog as it is not present in the container 2021-05-19 09:44:36 +02:00
Quentin 8c213bc7ba
Update garage 2021-05-19 09:44:17 +02:00
Quentin 1edc5f37a2
Upgrade Matrix configuration 2021-05-19 09:43:45 +02:00
Quentin 4f506422e3 Upgrade matrix 2021-05-18 15:26:41 +02:00
Quentin 3bb2cf9e93 Allow only cipher suites recommended by Mozilla
Check https://ssl-config.mozilla.org/#server=traefik&version=1.7&config=intermediate&guideline=5.6
2021-05-07 20:01:31 +02:00
Alex 1f15d29eab
Update garage to v0.2.1.6 2021-05-04 13:28:04 +02:00
Quentin 6754cfef81 Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure into main 2021-05-03 19:10:16 +02:00
Quentin 3df53eaa94 Upgrade plume build scripts 2021-05-03 19:09:50 +02:00
Quentin 51b5295ba8 Allow Garage to use 800MB of RAM instead of 500MB 2021-05-03 17:27:06 +02:00
Alex 925639b678
update garage 2021-04-28 01:16:35 +02:00
Quentin 68575d2654
Migrate from Plume from v0.6.0 to v0.7.0RC 2021-04-19 10:50:38 +02:00
Quentin 338a8ec7da
Try to migrate to pg_basebackup 2021-04-17 12:21:13 +02:00
Quentin 3135c38505
Upgrade stolon 2021-04-15 13:05:21 +02:00
Quentin 87303033d1
Debug stolon backup 2021-04-15 12:38:31 +02:00
Quentin 9dfff86cd2
Target a replicated server and not the main one 2021-04-14 19:10:46 +02:00
Quentin b851ca0c95
Update matrix HCL + document stolon conf change 2021-04-14 18:15:45 +02:00
Quentin fae36c7ef6 Upgrade synapse+riot images 2021-04-09 14:11:26 +02:00
Alex 4ecda8cc8d
Updated version of Drone 2021-04-07 14:06:02 +02:00
Alex 2ef1a9df5d
Update garage 2021-04-05 20:48:33 +02:00
Alex 1df83c6064
Add iptables rules allowing new IPv6 2021-04-05 18:28:45 +02:00
Quentin 0b4c61dfe1 Try to optimize Consul 2021-04-04 20:04:25 +02:00
Quentin e979434970 Fix Jitsi's IP address 2021-04-04 19:15:29 +02:00
Quentin 474c4575f4 Rename postgres 2021-04-01 19:04:50 +02:00
Alex 5126868e30 update garage to v0.2.1 2021-03-19 14:00:48 +01:00
Quentin 4ad6376aa8 Document how to repair Traefik/ACME 2021-03-18 10:17:05 +01:00
Alex e197429531 Update bottin; remove drone runner 2021-03-16 14:59:10 +01:00
mricher d67a6c363a
Set prometheus node_exporter version to v1.1.2 2021-03-09 00:15:55 +01:00
Alex 573a86b87c Change resource allocation 2021-03-08 23:01:11 +01:00
Alex c586633613 Add node-exporter for metrics collection 2021-03-08 22:55:55 +01:00
Alex e806e24fea Add SSL certificates in ALPS image 2021-03-08 17:49:22 +01:00
Alex a84f4c8f87 Use patched Alps from git.deuxfleurs.fr/Deuxfleurs/alps 2021-03-08 17:32:05 +01:00
Alex b42e42faaa Improve resource allocation 2021-03-08 16:34:41 +01:00
Quentin d6bdfbed5f Expose prometheus metrics on Consul 2021-03-07 21:36:27 +01:00
Quentin 255e3fd2d7 Debug stolon proxy 2021-03-07 18:29:56 +01:00
Quentin eb3f64df41 Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-03-07 17:07:52 +01:00
Quentin 35ddbd9f20 Upgrade Stolon 2021-03-07 17:07:35 +01:00
Quentin 4f296808e8 Refactor stolon Dockerfile 2021-03-07 12:54:03 +01:00
Quentin 4d7470b2fd Draft stolon update 2021-03-07 12:18:08 +01:00
Quentin b608567648 Add a new parameter to stolon 2021-03-07 11:43:46 +01:00
Quentin a69efd9b31 Add gzip compression 2021-03-06 21:43:55 +01:00
Quentin 96f2978a7f Change target image 2021-03-06 20:09:16 +01:00
Quentin 224c0a23a3 Increment image 2021-03-06 20:08:17 +01:00
Quentin c0d86cb0a1 Mount backup directory + export PGPASSWORD 2021-03-06 20:06:57 +01:00
Quentin d1a4ed0f79 Matrix backup draft 2021-03-06 19:52:13 +01:00
Quentin 27963ca089 Upgraded matrix/element to 1.28.0/1.7.22 2021-03-05 17:44:05 +01:00
Quentin 1c5b1f2e5b Upgrade matrix image 2021-03-05 17:40:40 +01:00
Alex fada3f6ed1 Don't always restart stolon keeper if it is failed (let stolon do its job) 2021-02-24 14:54:18 +01:00
Alex 987cefeba0 bump garage 2021-02-24 14:54:10 +01:00
Alex 71971143c4 Fix drone DB (why did it work before???) 2021-02-24 14:53:58 +01:00
Alex 89133ddbea Change l'adresse d'expéditeur pour les invites 2021-02-18 14:02:18 +01:00
Quentin 59623243c8 Deactivate test endpoint 2021-02-11 11:57:23 +01:00
Quentin 2958fbae1b Port nginx's configuration from integration to deployment 2021-02-11 11:56:30 +01:00
Quentin c2d3c543b9 Jitsi add missing mimetypes 2021-02-11 11:54:06 +01:00
Alex 9c2232cebc Add Drone CI 2021-02-08 14:52:13 +01:00
Quentin 9c060b3c28 Add tools 2021-02-01 19:56:16 +01:00
Quentin b6b812c011 Upgrade jitsi nginx conf to make ADRN happy! 2021-02-01 18:19:43 +01:00
Quentin 5fb05f0b7e Add CORS for our load testing frontend 2021-02-01 12:42:29 +01:00
Quentin 5babe6fad1 Fix port binding 2021-02-01 11:22:16 +01:00
Quentin 34c5544ef5 Fix prosody listening 2021-02-01 11:06:45 +01:00
Quentin 847540f7b7 Add trimSpace to secrets to prevent a parsing bug 2021-02-01 10:29:13 +01:00
Quentin 9337129336 Fix typos in the service file 2021-02-01 10:26:26 +01:00
Quentin 088c9df20c Prepare Nomad deployment 2021-02-01 09:50:38 +01:00
Quentin 0a87d26e47 Polish configuration 2021-02-01 08:40:59 +01:00
Quentin cb69a1123c Stabilize build scripts 2021-02-01 07:48:50 +01:00
Quentin c2960f75b7 Add curl to the dockerfile 2021-01-31 18:17:37 +01:00
Quentin 56cf9c1e55 Videobridge doc + debug 2021-01-31 18:03:55 +01:00
Quentin a3f62d1f30 Overide logging + some doc to debug java processes 2021-01-31 15:47:01 +01:00
Quentin 09e1e641a7 Working on meet frontend 2021-01-30 12:06:14 +01:00
Quentin 9ea066d6df Only old configuration can be used for ice4 harvester 2021-01-29 19:22:16 +01:00
Quentin 59ca97e2a9 Migrate JVB to the new packaging 2021-01-29 18:59:19 +01:00
Quentin 83d8668a59 Jicofo might work as intended! 2021-01-29 17:47:09 +01:00
Quentin 952d7c0510 Improve jitsi config 2021-01-29 17:30:43 +01:00
Quentin 7bdea77811 WIP debugging jitsi 2021-01-29 17:17:28 +01:00
Quentin cee95ad061 Merge pull request 'Upgrade Synapse & Element-web, réécriture de l'OP guide, et ajout du secret turn.zinz.dev' (#33) from adrien/infrastructure:master into master
Reviewed-on: Deuxfleurs/infrastructure#33
2021-01-29 15:53:37 +01:00
LUXEY Adrien 24dcc09695 Upgraded Synapse and Element-web on cluster's nomad, and the OP guide 2021-01-29 12:11:43 +01:00
LUXEY Adrien d286da23d8 pushed Synapse and Element-web to latest version, and rewrote the OP guide a bit 2021-01-29 11:53:03 +01:00
LUXEY Adrien 9a263b762b Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-01-29 10:57:42 +01:00
LUXEY Adrien 8f0cb24246 added zinz.dev static auth secret declaration 2021-01-29 10:56:42 +01:00
Quentin 982efd1b49 Still so broken... 2021-01-28 23:02:37 +01:00
Quentin 5b53cf1673 Trying to switch on a development version 2021-01-28 21:47:35 +01:00
Quentin 47bcdaaf0d Rework prosody's configuration 2021-01-28 21:05:10 +01:00
Quentin 0e848bb2d0 Polished prosody 2021-01-28 19:28:15 +01:00
Quentin 4809e27220 WIP integration jitsi 2021-01-28 18:55:56 +01:00
Quentin 7b57ff72a9 Simplify prosody too 2021-01-28 17:52:41 +01:00
Quentin ebb772e5ba Fix ansible inventory + Fix jicofo's hocon conf + fix jicofo's dockerfile 2021-01-28 17:02:10 +01:00
Quentin 07765e8456 Add resources 2021-01-21 10:11:43 +01:00
Quentin 6adb551db4 More info in README 2021-01-20 16:02:58 +01:00
Quentin 3e7dc8b49d Fix conf links 2021-01-20 15:54:17 +01:00
Quentin 031f31e91e WIP modernize jitsi conf 2021-01-20 15:44:42 +01:00
Quentin 5dfca7a713 fix naming 2021-01-20 12:53:23 +01:00
Quentin bd9c854a12 change port due to a strange bug 2021-01-20 11:35:54 +01:00
Quentin d3a3867180 Public IP changed 2021-01-20 10:51:25 +01:00
Quentin b879be2156 Enrichir le postmortem 2021-01-20 10:49:29 +01:00
Quentin 46dce5d917 fix indent postmortem 2021-01-20 10:34:53 +01:00
Quentin 6b91db048d Ajout du postmortem 2021-01-20 10:34:16 +01:00
Quentin 8eaa7914d0 Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-01-20 10:21:42 +01:00
Quentin 2a0e9720b7 React to Free changing my IP address 2021-01-20 10:21:18 +01:00
Alex 2e25e150d4 Merge pull request 'secretmgr retourne une erreur bien formatée face à un fichier vide' (#32) from adrien/infrastructure:master into master
Reviewed-on: Deuxfleurs/infrastructure#32
2021-01-19 18:48:31 +01:00
Alex a2eec38de4 Add a few missing secrets 2021-01-19 18:02:00 +01:00
Alex 1c814f002a Add CMD_ONCE secret type and fill in/change secret definitions 2021-01-19 17:53:53 +01:00
Alex 9560f80852 mention secretmgr.py in create_database 2021-01-19 17:29:37 +01:00
Alex a847a9683f Cleanup op_guide folder 2021-01-19 17:27:32 +01:00
LUXEY Adrien 6e1940061a coturn retourne une erreur bien formatée face à un fichier vide (il pourrait renvoyer autre chose), plus bug nom de variable 2021-01-19 17:16:58 +01:00
Quentin af2b8b06ba Merge pull request 'master' (#30) from adrien/infrastructure:master into master
Reviewed-on: Deuxfleurs/infrastructure#30
2021-01-19 15:49:11 +01:00
LUXEY Adrien 98280c8628 updated READMEs 2021-01-19 15:21:23 +01:00
LUXEY Adrien 2a346f5430 coquille 2021-01-19 14:40:14 +01:00
LUXEY Adrien 65421d947e merge from upstream 2021-01-19 14:33:44 +01:00
Quentin eb925049ac Remove web_static 2021-01-19 13:47:50 +01:00
Quentin 0be20b22a6 Upgrade garage description 2021-01-18 16:51:06 +01:00
Quentin 7e637a070c Add guichet in our readme
Signed-off-by: Quentin Dufour <quentin@deuxfleurs.fr>
2021-01-18 16:49:46 +01:00
Quentin 2c2efdc276 Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-01-18 16:46:21 +01:00
Quentin 6c8c861dd5 Update README 2021-01-18 16:46:08 +01:00
Quentin ad6017eea0 Merge pull request 'Reorganize app/ and add script for secret management' (#29) from test_reorganize into master
Reviewed-on: Deuxfleurs/infrastructure#29
2021-01-18 08:18:21 +01:00
Quentin c642370def Add hierarchy to the README 2021-01-18 08:08:48 +01:00
Quentin cffd902815 Add some documentation + add a requirements file 2021-01-18 08:06:19 +01:00
Quentin 79b7273ff2 Remove my blog 2021-01-18 06:51:19 +01:00
Alex 850ccbf1c7 secretmgr.py does quite a few things! 2021-01-16 20:03:00 +01:00
Alex d4d0b100ad Document secrets and add stub utility to manage them 2021-01-16 17:37:34 +01:00
Alex c74dc92feb Proposal: reorganize app/ folder by modules 2021-01-16 17:07:01 +01:00
Alex 0c4ee40e01 Update garage 2021-01-16 16:21:25 +01:00
Alex a6b23f5713 upgrade garage to 0.1.1 2021-01-15 19:34:33 +01:00
Quentin 52c141e5fc Update Riot+Matrix 2021-01-13 19:17:28 +01:00
Quentin 464b990e19 Upgrade jitsi 2021-01-13 14:42:14 +01:00
Quentin 969ee58b7d WIP nextcloud tests 2021-01-07 21:37:29 +01:00
Quentin 4456fb56c1 Upgrade nomad+consul 2021-01-07 21:36:47 +01:00
Quentin ba3d84a1de Upgrade plume 2021-01-07 11:09:29 +01:00
LUXEY Adrien a5a56b6f70 wrote a redirection to deuxfleurs.fr in Treafik config's comments 2020-12-28 12:04:08 +01:00
Quentin 7508a10a71 WIP redirect regex 2020-12-28 11:55:29 +01:00
Quentin c4c4d6f8a6 Fix URL 2020-12-28 11:05:05 +01:00
Quentin fc518df1c1 Migrate Traefik 2020-12-28 11:02:33 +01:00
Quentin a2f8e11d06 Migrate plume+diagnet+web_static 2020-12-28 10:49:09 +01:00
Quentin 48db0185a4 Migrate postgres 2020-12-25 12:16:18 +01:00
Quentin 4f23adfbb9 Migrated plume 2020-12-25 11:48:52 +01:00
Quentin 1624b348df Migrate platoo 2020-12-25 11:21:41 +01:00
Quentin 8625a9af75 Upgrade seafile + discard unused services 2020-12-25 11:16:11 +01:00
Quentin f75497af11 Fix service addressing 2020-12-24 10:01:42 +01:00
Quentin 6913655316 We do not use pithos 2020-12-23 19:42:30 +01:00
Quentin 80dc6ec803 Migrate jitsi 2020-12-23 15:55:17 +01:00
Quentin 9117616f02 Migrate Synapse + Email hack
Nomad seemed to dislike the 'auth_port' label, replaced by 'zauthentication_port'
2020-12-22 18:24:33 +01:00
Quentin b29028405d Migrate Garage 2020-12-22 17:48:27 +01:00
Quentin 9f6f0fb53c Migrate Nomad job for emails 2020-12-22 16:40:36 +01:00
Quentin a2adaa2101 Migrate directory to new Nomad syntax 2020-12-22 14:52:49 +01:00
Quentin bb5a82b056 Fix seafile 2020-12-22 14:40:04 +01:00
Quentin e628dc44ba Migrate seafile 2020-12-22 14:31:42 +01:00
Quentin 846449b238 Migrate Nextcloud to Nomad 1.0.1 2020-12-22 10:46:26 +01:00
Quentin b6ccf06d8a Set priorities 2020-12-18 10:32:44 +01:00
Quentin 685bc45802 Activate pg_rewind on stolon 2020-12-18 10:23:45 +01:00
Quentin 55f93cc5ad First step to integrate io to the cluster 2020-12-16 19:14:45 +01:00
Quentin 41e33f40ad Merge pull request 'Add traefik v1 prometheus metrics configuration' (#27) from feature/enable-traefik-metrics into master
Reviewed-on: Deuxfleurs/infrastructure#27
2020-12-14 17:08:34 +01:00
mricher 94ee5d3e5c
Remove traefik v2 options and fix endpoint to admin 2020-12-14 17:07:44 +01:00
mricher 91ffdc732c
Add traefik v1 prometheus metrics configuration 2020-12-14 00:19:01 +01:00
Quentin 3ff113ceab Merge pull request 'Upgraded to Synapse v1.24.0' (#26) from adrien/infrastructure:master into master
Reviewed-on: Deuxfleurs/infrastructure#26
2020-12-11 11:00:38 +01:00
LUXEY Adrien bcb3964417 Nomad config for synapse v1.24.0 2020-12-10 09:32:16 +01:00
LUXEY Adrien ad064dddbc Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2020-12-10 09:09:34 +01:00
LUXEY Adrien 2b3df5b6ee upped synapse to v1.24.0 2020-12-10 09:09:17 +01:00
Quentin 9c947a458f Merge branch 'feature/alps' into master 2020-12-04 13:54:02 +01:00
Quentin e370380a3f Alps is now deployed 2020-12-04 13:53:30 +01:00
Quentin d1332a2d42 Add alps container 2020-12-04 13:42:20 +01:00
Quentin 6402119511 Set Jitsi videobridge max memory 2020-12-02 12:28:19 +01:00
Quentin 365849760d Upgrade Nomad and expose telemetry 2020-11-30 08:31:17 +01:00
adrien de3e21101d Merge pull request 'Pushed synapse version to 1.23.0 and riotweb to 1.7.14, incl. nomad deployment' (#25) from adrien/infrastructure:master into master
Reviewed-on: Deuxfleurs/infrastructure#25
2020-11-29 23:19:44 +01:00
LUXEY Adrien da1d381068 pushed synapse to 1.23.0 and riotweb to 1.7.14 and deployed through nomad 2020-11-29 23:13:17 +01:00
LUXEY Adrien fd38cbf744 pushed synapse to 1.23.0 and riotweb to 1.7.14 2020-11-29 22:51:38 +01:00
Quentin d241948034 Add missing dovecot conf files 2020-11-27 14:41:57 +01:00
Quentin e2bb0e1b4e Fix tab again 2020-11-22 13:02:14 +01:00
Quentin cfab2346cf Another another try 2020-11-22 13:01:05 +01:00
Quentin f544c202be Another try? 2020-11-22 13:00:42 +01:00
Quentin 804078b3f4 Try to fix lists 2020-11-22 13:00:15 +01:00
Quentin 9f41d95dcf New line 2020-11-22 12:59:52 +01:00
Quentin 33f769c747 A guide to update Matrix 2020-11-22 12:59:07 +01:00
Quentin c19cadf353 Fix sogo conf to match RAM usage
To do the math:
SoGo SxVMemLimit * SoGo WOWorkersCount < Nomad Memory Limit
Before we had 384 * 10 >>> 1000
Now we have 300 * 3 < 1000
2020-11-22 12:40:51 +01:00
Alex 1bb9c7ce19 Add timestamp to backup 2020-11-15 20:14:19 +01:00
Alex f931dd939c Add cryptography to consul backup 2020-11-15 19:43:33 +01:00
Alex e2a0c40e6b Script to backup Consul KV store 2020-11-15 19:27:57 +01:00
Alex 2051a21662 Bump bottin 2020-11-13 13:02:22 +01:00
Quentin f14777e1b6 Merge pull request 'ansible-users' (#23) from ansible-users into master
Reviewed-on: Deuxfleurs/deuxfleurs.fr#23
2020-11-13 12:37:10 +01:00
Alex 7e111783fe Add LX key3 2020-11-13 12:34:07 +01:00
Alex e1f171e19c use ansible_become instead of ansible_user: root 2020-11-13 12:33:23 +01:00
Quentin 9981ea0286 Fix memory 2020-11-03 21:12:01 +01:00
Quentin 0191926455 Seafile fails with OOM when trying to synchronize a 2GB folder 2020-11-03 19:42:08 +01:00
Quentin 2452e87509 Migrate synapse to 1.22.1 2020-10-30 19:16:23 +01:00
Quentin bf58bd2a2c Some Seafile wizardry to bypass ipv4 only limitations 2020-10-28 22:57:41 +01:00
Quentin ed3ed5e2e4 Add max prefix 2020-10-28 17:55:03 +01:00
Quentin c32bd6df1d Add some doc 2020-10-28 17:07:55 +01:00
Quentin 03680a992b Switch Matrix+Plume to IPv6, Add Trusted Net to ip6tables 2020-10-28 16:55:11 +01:00
Quentin aba3ba723c Nomad now speaks IPv6 2020-10-28 15:53:22 +01:00
Quentin f9013d9ca5 Fix seafdav 2020-10-28 15:14:29 +01:00
Quentin 9fef7ae777 Port seafile 2020-10-28 15:09:51 +01:00
Quentin e74737e6e3 mariadb migrated to host 2020-10-28 14:50:22 +01:00
Quentin 1f53e2061e backport a hack to enable jitsi 2020-10-28 14:41:19 +01:00
Quentin d8d0d74920 rework jitsi service 2020-10-28 14:12:15 +01:00
Quentin 2ef6ab1881 Simplify configuration 2020-10-28 12:08:23 +01:00
Quentin f4a88fa565 Docker does not use IPv6, switching to "network=host" 2020-10-27 23:25:30 +01:00
Quentin 2557793cee switch consul to ipv6 2020-10-27 22:39:00 +01:00
Quentin bf9a9128b8 Disable IPv6 Router Advertisement (RA) as it provision an additional IP address that we do not want to use and breaks things 2020-10-27 21:52:46 +01:00
Quentin 5902805ac9 Reintroduce resolv.conf, it is needed + change DNS from FDN (broken) to Free 2020-10-22 20:22:57 +02:00
Quentin e465d65a27 This file is not needed anymore 2020-10-22 18:57:25 +02:00
Quentin 3b75213d40 We now have IPv6 activated on our network interfaces! 2020-10-22 18:55:29 +02:00
Quentin b53b71f750 Fix some bugs 2020-10-22 18:29:37 +02:00
Quentin 6858f17766 Rework Ansible to support ipv6 2020-10-22 17:57:02 +02:00
Quentin 5c31fbf0b1 Add plume config template 2020-10-19 20:29:15 +02:00
Quentin 3ef7b6775b Plume loves LDAP now 2020-10-19 20:27:54 +02:00
Quentin e4c15e9d71 Plume integration is working 2020-10-19 20:07:15 +02:00
Quentin 6b667af32b Remove unrelated content 2020-10-19 12:02:50 +02:00
Quentin 4af75bd8b8 WIP plume 2020-10-15 21:20:11 +02:00
Quentin 25ec221248 WIP plume container 2020-10-14 21:27:43 +02:00
Quentin fcbb788de6 Readd Florian 2020-10-14 18:27:20 +02:00
Quentin 948e4fb94e Upgrade chat 2020-10-13 11:59:02 +02:00
Alex 8fb283d502 upgrade easybridge 2020-10-10 00:03:51 +02:00
Alex cc57e0b353 Bump easybridge version 2020-10-04 21:31:58 +02:00
Quentin c5eee91b12 WIP plume dockerfile 2020-10-01 15:25:04 +02:00
Quentin 3afe80b158 Upgrade synapse 1.20.0 2020-09-23 11:25:59 +02:00
Quentin 9460862c18 Add guide 2020-09-22 11:50:03 +02:00
Quentin 6467a5ab31 Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/deuxfleurs.fr 2020-09-21 16:30:23 +02:00
Quentin 9e4e2f7b99 Add plume 2020-09-21 16:29:49 +02:00
Quentin f8682668c2 Upgrade Element Web to new config.json
- Display deuxfleurs.fr and not im.deuxfleurs.fr on login screen
  - Remove broken welcome page on login
  - Set our jitsi instance
  - Add more servers in the room discovery page
2020-09-18 19:55:48 +02:00
Quentin 09fc30214d Upgrade synapse as proposed 2020-09-16 15:52:19 +02:00
Quentin e9bc6fe7f1 Merge pull request 'ajout de adrien dans la config de l'os' (#20) from ajout-adrien into master
Reviewed-on: Deuxfleurs/deuxfleurs.fr#20
2020-09-14 23:20:47 +02:00
Adrien 6b1a7127ce ajout de moi-meme dans la config de l'os 2020-09-14 23:12:54 +02:00
Quentin 484c3fe667 Merge branch 'feature/rebase' 2020-09-13 12:03:07 +02:00
Quentin d5bfc38fe8 Final step for jitsi 2020-09-13 12:00:48 +02:00
Quentin d76d82fccb Use jre headless for more leightweight images 2020-09-13 09:48:04 +00:00
Quentin a1be6b31ed Increment once to be sure 2020-09-13 11:47:07 +02:00
Quentin da034dabfc Finally it seems to work 2020-09-13 11:46:14 +02:00
Quentin 744fa8b8c9 Merge branch 'feature/rebase' of git.deuxfleurs.fr:Deuxfleurs/deuxfleurs.fr into feature/rebase 2020-09-12 23:18:20 +02:00
Quentin c40095d02c WIP jitsi 2020-09-12 23:18:02 +02:00
Quentin 7951d35035 WIP jitsi fix 2020-09-12 21:04:25 +00:00
Quentin 1af6eabc81 Fix videobridge 2020-09-12 22:18:30 +02:00
Quentin 51e4af08c0 Reformat markdown 2020-09-12 20:18:41 +02:00
Quentin a23e08ce20 Refactor 2 2020-09-12 20:17:07 +02:00
Quentin fb4ffbc7fa Fix broken Jitsi... 2020-09-12 18:01:34 +00:00
Quentin b00fc0eaf1 Use a more recent npm 2020-09-12 12:21:30 +02:00
Quentin 0c05730a5d Rationalize container building 2020-09-12 11:27:32 +02:00
Quentin 5337be94df Better handle jitsi versions 2020-09-12 11:15:07 +02:00
Quentin c4a6cf1534 Rebase first step 2020-09-12 10:03:48 +02:00
Quentin 0550647b93 Updated natrix 2020-09-07 14:31:05 +02:00
Quentin 30fe6d2e3c Final sogo upgrade 2020-08-20 10:39:10 +02:00
Quentin 72b84fbe18 upgrade matrix + wip sogo 2020-08-20 10:01:44 +02:00
Quentin bdff5571f1 Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/deuxfleurs.fr 2020-07-16 09:04:56 +02:00
Quentin c29d660700 Migrate matrix+riot 2020-07-16 09:04:32 +02:00
354 changed files with 6923 additions and 3822 deletions

2
.gitmodules vendored
View file

@ -1,5 +1,5 @@
[submodule "docker/static/goStatic"]
path = docker/static/goStatic
path = app/build/static/goStatic
url = https://github.com/PierreZ/goStatic
[submodule "docker/blog/quentin.dufour.io"]
path = docker/blog-quentin/quentin.dufour.io

View file

@ -5,42 +5,53 @@ deuxfleurs.fr
## Our abstraction stack
We try to build a generic abstraction stack between our different resources (CPU, RAM, disk, etc.) and our services (Chat, Storage, etc.):
We try to build a generic abstraction stack between our different resources (CPU, RAM, disk, etc.) and our services (Chat, Storage, etc.), we develop our own tools when needed:
* ansible (physical node conf)
* nomad (schedule containers)
* consul (distributed key value store / lock / service discovery)
* glusterfs (file storage)
* stolon + postgresql (distributed relational database)
* docker (container tool)
* bottin (LDAP server, auth)
* **[garage](https://git.deuxfleurs.fr/Deuxfleurs/garage/):** S3-compatible lightweight object store for self-hosted geo-distributed deployments (we also have a legacy glusterfs cluster)
* **[diplonat](https://git.deuxfleurs.fr/Deuxfleurs/diplonat):** network automation (firewalling, upnp igd)
* **[bottin](https://git.deuxfleurs.fr/Deuxfleurs/bottin):** authentication and authorization (LDAP protocol, consul backend)
* **[guichet](https://git.deuxfleurs.fr/Deuxfleurs/guichet):** a dashboard for our users and administrators
* **ansible:** physical node configuration
* **nomad:** schedule containers and handle their lifecycle
* **consul:** distributed key value store + lock + service discovery
* **stolon + postgresql:** distributed relational database
* **docker:** package, distribute and isolate applications
Some services we provide:
* Chat (Matrix/Riot)
* Email (Postfix/Dovecot/Sogo)
* Storage (Seafile)
* **Websites:** garage (static) + fediverse blog (plume)
* **Chat:** Synapse + Element Web (Matrix protocol)
* **Email:** Postfix SMTP + Dovecot IMAP + opendkim DKIM + Sogo webmail (legacy) | Alps webmail (experimental)
* **Storage:** Seafile (legacy) | Nextcloud (experimental)
* **Visio:** Jitsi
As a generic abstraction is provided, deploying new services should be easy.
## I am lost, how this repo works?
To ease the development, we make the choice of a fully integrated environment
1. `os` the base os for the cluster
1. `build`: where you will build our OS image based on Debian that you will install on your server
2. `config`: our Ansible recipes to configure and update your freshly installed server
2. `apps` apps we deploy on the cluster
1. `build`: our Docker files to build immutable images of our applications
2. `integration`: Our Docker compose files to test locally how our built images interact together
3. `config`: Files containing application configurations to be deployed on Consul Key Value Store
4. `deployment`: Files containing application definitions to be deployed on Nomad Scheduler
3. `op_guide`: Guides to explain you operations you can do cluster wide (like configuring postgres)
## Start hacking
### Clone the repository
```
git clone https://gitlab.com/superboum/deuxfleurs.fr.git
git submodule init
git submodule update
```
### Deploying/Updating new services is done from your machine
*The following instructions are provided for ops that already have access to the servers.*
*The following instructions are provided for ops that already have access to the servers (meaning: their SSH public key is known by the cluster).*
Deploy Nomad on your machine:
```bash
export NOMAD_VER=0.9.1
export NOMAD_VER=1.0.1
wget https://releases.hashicorp.com/nomad/${NOMAD_VER}/nomad_${NOMAD_VER}_linux_amd64.zip
unzip nomad_${NOMAD_VER}_linux_amd64.zip
sudo mv nomad /usr/local/bin
@ -50,7 +61,7 @@ rm nomad_${NOMAD_VER}_linux_amd64.zip
Deploy Consul on your machine:
```bash
export CONSUL_VER=1.5.1
export CONSUL_VER=1.9.0
wget https://releases.hashicorp.com/consul/${CONSUL_VER}/consul_${CONSUL_VER}_linux_amd64.zip
unzip consul_${CONSUL_VER}_linux_amd64.zip
sudo mv consul /usr/local/bin
@ -63,14 +74,37 @@ Create an alias (and put it in your `.bashrc`) to bind APIs on your machine:
alias bind_df="ssh \
-p110 \
-N \
-L 1389:bottin2.service.2.cluster.deuxfleurs.fr:389 \
-L 4646:127.0.0.1:4646 \
-L 5432:psql-proxy.service.2.cluster.deuxfleurs.fr:5432 \
-L 8082:traefik-admin.service.2.cluster.deuxfleurs.fr:8082 \
-L 8500:127.0.0.1:8500 \
-L 8082:traefik.service.2.cluster.deuxfleurs.fr:8082 \
<a server from the cluster>"
```
and run:
bind_df
Adrien uses `.ssh/config` configuration instead. I works basically the same. Here it goes:
```
bind_df
# in ~/.ssh/config
Host deuxfleurs
User adrien
Hostname deuxfleurs.fr
# If you don't use the default ~/.ssh/id_rsa to connect to Deuxfleurs
IdentityFile <some_key_path>
PubKeyAuthentication yes
ForwardAgent No
LocalForward 1389 bottin2.service.2.cluster.deuxfleurs.fr:389
LocalForward 4646 127.0.0.1:4646
LocalForward 5432 psql-proxy.service.2.cluster.deuxfleurs.fr:5432
LocalForward 8082 traefik-admin.service.2.cluster.deuxfleurs.fr:8082
LocalForward 8500 127.0.0.1:8500
```
Now, to connect, do the following:
ssh deuxfleurs -N

View file

@ -1,5 +0,0 @@
*.aux
*.fdb_latexmk
*.fls
*.log
*.pdf

View file

@ -1,68 +0,0 @@
\documentclass[a4paper,DIV=12]{scrartcl}
\usepackage[french]{babel}
% On abuse komafont pour réduire la place prise par le titre
\addtokomafont{title}{\vspace*{-3em}}
\addtokomafont{author}{\vspace*{-1em}}
\addtokomafont{date}{\vspace*{-0.5em}}
% On ajoute "Article" devant les sections
\renewcommand\sectionformat{Article\enskip\thesection~:\hspace{1em}}
% On réduit la taille des sections
\addtokomafont{section}{\large}
% On rajoute un peu d'espace entre les paragraphes
\setlength{\parskip}{.8em}
% On enlève de la place après les titres
% (je n'ai pas pu utiliser le paquet dédié titlesec car il cause plein d'erreurs)
%\titlespacing\section{1pt}{*4}{*1.5}
\let\oldsection\section
\renewcommand{\section}[1]{\oldsection{#1}\vspace{-1em}}
\title{Procès-verbal de lassemblée générale constitutive de l'association Deuxfleurs}
\date{13 janvier 2020}
\author{Association Deuxfleurs\\10A Allée de Lanvaux, 35700 Rennes}
\begin{document}
\maketitle
Le 13 janvier 2020 à 19 heures, les fondateurs de lassociation Deuxfleurs se sont réunis en assemblée générale constitutive au 24 rue des Tanneurs à Rennes. Sont présents Adrien, Alex, Anaïs, Axelle, Louison, Maximilien, Quentin, Rémi et Vincent.
Lassemblée générale désigne Adrien Luxey en qualité de président de séance et Quentin Dufour en qualité de secrétaire de séance.
Le président de séance met à la disposition des présents le projet de statuts de lassociation et létat des actes passés pour le compte de lassociation en formation.
Puis il rappelle que lassemblée générale constitutive est appelée à statuer sur lordre du jour suivant :
\begin{itemize}
\item présentation du projet de constitution de lassociation ;
\item présentation du projet de statuts ;
\item adoption des statuts ;
\item désignation des premiers membres du conseil ;
\item pouvoirs en vue des formalités de déclaration et publication.
\end{itemize}
Enfin, le président de séance expose les motifs du projet de création de lassociation et commente le projet de statuts.
Il ouvre la discussion. Un débat sinstaure entre les membres de lassemblée.
Après quoi, personne ne demandant plus la parole, le président met successivement aux voix les délibérations suivantes.
\paragraph{1\iere~délibération} Lassemblée générale adopte les statuts dont le projet lui a été soumis.
Cette délibération est adoptée à lunanimité.
\paragraph{2\ieme~délibération} Lassemblée générale constitutive désigne en qualité de premiers membres du conseil d'administration :
\begin{itemize}
\item Adrien Luxey
\item Alex Auvolat
\item Maximilien Richer
\item Quentin Dufour
\item Vincent Giraud
\end{itemize}
Conformément aux statuts, cette désignation est faite pour une durée expirant lors de lassemblée générale qui sera appelée à statuer sur les comptes de lexercice clos le 13 janvier 2021.
Les membres du conseil ainsi désignés acceptent leurs fonctions
Nom, prénom et signature du président et du secrétaire de séance
\end{document}

View file

@ -1,104 +0,0 @@
\documentclass[a4paper,DIV=12]{scrartcl}
\usepackage[frenchb]{babel}
% On abuse komafont pour réduire la place prise par le titre
\addtokomafont{title}{\vspace*{-3em}}
\addtokomafont{author}{\vspace*{-1em}}
\addtokomafont{date}{\vspace*{-2em}}
% On ajoute "Article" devant les sections
\renewcommand\sectionformat{Article\enskip\thesection~:\hspace{1em}}
% On réduit la taille des sections
\addtokomafont{section}{\large}
% On rajoute un peu d'espace entre les paragraphes
\setlength{\parskip}{.8em}
% On enlève de la place après les titres
% (je n'ai pas pu utiliser le paquet dédié titlesec car il cause plein d'erreurs)
%\titlespacing\section{1pt}{*4}{*1.5}
\let\oldsection\section
\renewcommand{\section}[1]{\oldsection{#1}\vspace{-1em}}
\title{Statuts de l'association Deuxfleurs}
\date{13 janvier 2020}
\begin{document}
\maketitle
\section{Constitution et dénomination}
Il est fondé entre les adhérents aux présents statuts une association régie par la loi 1901, ayant pour titre Deuxfleurs.
\section{Buts}
Cette association a pour but de défendre et promouvoir les libertés individuelles et collectives à travers la mise en place d'infrastuctures numériques libres.
\section{Siège social}
Le siège social est fixé au 10A, Allée de Lanvaux, 35700 Rennes.
Il pourra être transféré suite à un vote par l'assemblée générale.
\section{Durée de l'association}
L'association perdure tant qu'elle possède au moins un membre, ou jusqu'à sa dissolution décidée en assemblée générale.
\section{Admission et adhésion}\label{article:admission}
Pour faire partie de l'association, il faut être coopté par un membre de l'association, adhérer aux présents statuts et s'acquitter de la cotisation annuelle dont le montant est de 10 euros.
\section{Composition de l'association}
L'association se compose exclusivement de membres admis selon les dispositions de l'article~\ref{article:admission} et à jour de leur cotisation.
Tout membre actif possède une voix lors des votes en assemblée générale.
Est considéré actif tout membre présent à l'assemblée générale (physiquement, par visioconférence ou par procuration écrite donnée à un autre membre de l'association).
\section{Perte de la qualité de membre}
La qualité de membre se perd par :
\begin{itemize}
\item la démission,
\item le non-renouvelement de la cotisation dans un délai de deux mois après le 1er Janvier de l'année courante,
\item le décès,
\item la radiation prononcée aux deux tiers des votes exprimés, lors d'un vote extraordinaire ou de l'assemblée générale.
\end{itemize}
\section{L'assemblée générale}\label{article:ag}
L'assemblée générale ordinaire se réunit au moins une fois par an, convoquée par le conseil d'administration.
Lassemblée générale extraordinaire est convoquée par le conseil dadministration, à la demande de celui-ci ou à la demande du quart au moins des membres de l'association.
L'assemblée générale (ordinaire ou extraordinaire) comprend tous les membres de l'association à jour de leur cotisation.
Quinze jours au moins avant la date fixée, les membres de l'association sont convoqués via la liste de diffusion de l'association et l'ordre du jour est inscrit sur les convocations.
Le conseil dadministration anime lassemblée générale.
Lassemblée générale, après avoir délibéré, se prononce sur le rapport moral et/ou d'activités.
Le conseil dadministration rend compte de l'exercice financier clos et soumet le bilan de lexercice clos à lapprobation de lassemblée dans un délai de six mois après la clôture des comptes.
Lassemblée générale délibère sur les orientations à venir et se prononce sur le budget prévisionnel de lannée en cours.
Elle pourvoit, au scrutin secret, à la nomination ou au renouvellement des membres du conseil d'administration via un scrutin de Condorcet Randomisé.
Elle fixe le montant de la cotisation annuelle.
Les décisions de l'assemblée sont prises à la majorité des membres présents ou représentés.
Chaque membre présent ne peut détenir plus d'une procuration.
\section{Membres mineurs}
Les mineurs peuvent adhérer à lassociation sous réserve dun accord tacite ou dune autorisation écrite de leurs parents ou tuteurs légaux.
Ils sont membres à part entière de lassociation.
Seuls les membres âgés de 16 ans au moins au jour dune élection sont autorisés à y voter, notamment au cours d'une assemblée générale.
Pour les autres, leur droit de vote est transmis à leur représentant légal.
\section{Le conseil d'administration}
L'association est administrée par un conseil d'administration composé de 3 à 6 membres, élus pour 1 an dans les conditions fixées à larticle~\ref{article:ag}.
Tous les membres de lassociation à jour de leur cotisation sont éligibles.
En cas de vacance de poste, le conseil d'administration peut pourvoir provisoirement au remplacement de ses membres. Ce remplacement est obligatoire quand le conseil d'administration compte moins de 3 membres.
Il est procédé à leur remplacement définitif à la plus prochaine assemblée générale.
Les pouvoirs des membres ainsi élus prennent fin à l'époque où devrait normalement expirer le mandat des membres remplacés.
Le conseil dadministration met en œuvre les décisions de lassemblée générale, organise et anime la vie de lassociation, dans le cadre fixé par les statuts.
Chacun de ses membres peut être habilité par le conseil à remplir toutes les formalités de déclaration et de publication prescrites par la législation et tout autre acte nécessaire au fonctionnement de lassociation et décidé par le conseil dadministration.
Tous les membres du conseil dadministration sont responsables des engagements contractés par lassociation.
Tout contrat ou convention passé entre lassociation d'une part, et un membre du conseil d'administration, son conjoint ou un proche, d'autre part, est soumis pour autorisation au conseil d'administration et présenté pour information à la plus prochaine assemblée générale.
Le conseil dadministration se réunit au moins 4 fois par an et toutes les fois qu'il est convoqué par le tiers de ses membres.
La présence de la moitié au moins des membres du conseil est nécessaire pour que le conseil d'administration puisse délibérer valablement.
Les décisions sont prises au consensus et, à défaut, à la majorité des voix des présents. Le vote par procuration n'est pas autorisé.
\section{Modification des statuts de l'association}
Sur demande d'un tiers des membres actifs, ou sur demande du conseil d'administration, des amendements aux statuts de l'association peuvent être discutés et soumis au vote lors d'une assemblée générale, selon les modalités de l'article~\ref{article:ag}.
\end{document}

View file

@ -1,3 +0,0 @@
# Documents administatifs
__Statuts__ : Pour compiler les statuts, faites `latexmk -pdf statuts.tex`

View file

@ -1,15 +0,0 @@
# ANSIBLE
## How to proceed
For each machine, **one by one** do:
- Check that cluster is healthy
- `sudo gluster peer status`
- `sudo gluster volume status all` (check Online Col, only `Y` must appear)
- Check that Nomad is healthy
- Check that Consul is healthy
- Check that Postgres is healthy
- Run `ansible-playbook -i production --limit <machine> site.yml`
- Reboot
- Check that cluster is healthy

View file

@ -1,4 +0,0 @@
[cluster_nodes]
veterini ansible_host=fbx-rennes2.machine.deuxfleurs.fr ansible_port=110 ansible_user=root public_ip=192.168.1.2 private_ip=192.168.1.2 interface=eno1 dns_server=80.67.169.40
silicareux ansible_host=fbx-rennes2.machine.deuxfleurs.fr ansible_port=111 ansible_user=root public_ip=192.168.1.3 private_ip=192.168.1.3 interface=eno1 dns_server=80.67.169.40
wonse ansible_host=fbx-rennes2.machine.deuxfleurs.fr ansible_port=112 ansible_user=root public_ip=192.168.1.4 private_ip=192.168.1.4 interface=eno1 dns_server=80.67.169.40

View file

@ -1,2 +0,0 @@
nameserver {{ private_ip }}
nameserver {{ dns_server }}

View file

@ -1,12 +0,0 @@
# WARNING!! When rules.{v4,v6} are changed, the whole iptables configuration is reloaded.
# This creates issues with Docker, which injects its own configuration in iptables when it starts.
# In practice, most (all?) containers will break if rules.{v4,v6} are changed,
# and docker will have to be restared.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

View file

@ -1,11 +0,0 @@
- name: "Deploy iptablesv4 configuration"
template: src=rules.v4.j2 dest=/etc/iptables/rules.v4
- name: "Deploy iptablesv6 configuration"
copy: src=rules.v6 dest=/etc/iptables/rules.v6
- name: "Activate IP forwarding"
sysctl:
name: net.ipv4.ip_forward
value: "1"
sysctl_set: yes

View file

@ -1,34 +0,0 @@
addresses {
http = "0.0.0.0"
rpc = "0.0.0.0"
serf = "0.0.0.0"
}
advertise {
http = "{{ public_ip }}"
rpc = "{{ public_ip }}"
serf = "{{ public_ip }}"
}
data_dir = "/var/lib/nomad"
server {
enabled = true
bootstrap_expect = 3
}
consul {
address="127.0.0.1:8500"
}
client {
enabled = true
#cpu_total_compute = 4000
servers = ["127.0.0.1:4648"]
network_interface = "{{ interface }}"
options {
docker.privileged.enabled = "true"
docker.volumes.enabled = "true"
}
}

2
app/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
env/
__pycache__

66
app/README.md Normal file
View file

@ -0,0 +1,66 @@
# Folder hierarchy
- `<module>/build/<image_name>/`: folders with dockerfiles and other necessary resources for building container images
- `<module>/config/`: folder containing configuration files, referenced by deployment file
- `<module>/secrets/`: folder containing secrets, which can be synchronized with Consul using `secretmgr.py`
- `<module>/deploy/`: folder containing the HCL file(s) necessary for deploying the module
- `<module>/integration/`: folder containing files for integration testing using docker-compose
# Secret Manager `secretmgr.py`
The Secret Manager ensures that all secrets are present where they should in the cluster.
**You need access to the cluster** (SSH port forwarding) for it to find any secret on the cluster. Refer to the previous directory's [README](../README.md), at the bottom of the file.
## How to install `secretmgr.py` dependencies
```bash
### Install system dependencies first:
## On fedora
dnf install -y openldap-devel cyrus-sasl-devel
## On ubuntu
apt-get install -y libldap2-dev libsasl2-dev
### Now install the Python dependencies from requirements.txt:
## Either using a virtual environment
# (requires virtualenv python module)
python3 -m virtualenv env
# Must be done everytime you create a new terminal window in this folder:
. env/bin/activate
# Install the deps
pip install -r requirements.txt
## Either by installing the dependencies for your system user:
pip3 install --user -r requirements.txt
```
## How to use `secretmgr.py`
Check that all secrets are correctly deployed for app `dummy`:
```bash
./secretmgr.py check dummy
```
Generate secrets for app `dummy` if they don't already exist:
```bash
./secretmgr.py gen dummy
```
Rotate secrets for app `dummy`, overwriting existing ones (be careful, this is dangerous!):
```bash
./secretmgr.py regen dummy
```
# Upgrading one of our packaged apps to a new version
1. Edit `docker-compose.yml`
2. Change the `VERSION` variable to the desired version
3. Increment the docker image tag by 1 (eg: superboum/riot:v13 -> superboum/riot:v14)
4. Run `docker-compose build`
5. Run `docker-compose push`
6. Done

View file

@ -0,0 +1,28 @@
FROM golang:buster as builder
WORKDIR /root
RUN git clone https://filippo.io/age && cd age/cmd/age && go build -o age .
FROM amd64/debian:buster
COPY --from=builder /root/age/cmd/age/age /usr/local/bin/age
RUN apt-get update && \
apt-get -qq -y full-upgrade && \
apt-get install -y rsync wget openssh-client unzip && \
apt-get clean && \
rm -f /var/lib/apt/lists/*_*
RUN mkdir -p /root/.ssh
WORKDIR /root
RUN wget https://releases.hashicorp.com/consul/1.8.5/consul_1.8.5_linux_amd64.zip && \
unzip consul_1.8.5_linux_amd64.zip && \
chmod +x consul && \
mv consul /usr/local/bin && \
rm consul_1.8.5_linux_amd64.zip
COPY do_backup.sh /root/do_backup.sh
CMD "/root/do_backup.sh"

View file

@ -0,0 +1,20 @@
#!/bin/sh
set -x -e
cd /root
chmod 0600 .ssh/id_ed25519
cat > .ssh/config <<EOF
Host backuphost
HostName $TARGET_SSH_HOST
Port $TARGET_SSH_PORT
User $TARGET_SSH_USER
EOF
consul kv export | \
gzip | \
age -r "$(cat /root/.ssh/id_ed25519.pub)" | \
ssh backuphost "cat > $TARGET_SSH_DIR/consul/$(date --iso-8601=minute)_consul_kv_export.gz.age"

View file

@ -0,0 +1,22 @@
FROM golang:buster as builder
WORKDIR /root
RUN git clone https://filippo.io/age && cd age/cmd/age && go build -o age .
FROM amd64/debian:buster
COPY --from=builder /root/age/cmd/age/age /usr/local/bin/age
RUN apt-get update && \
apt-get -qq -y full-upgrade && \
apt-get install -y rsync wget openssh-client postgresql-client && \
apt-get clean && \
rm -f /var/lib/apt/lists/*_*
RUN mkdir -p /root/.ssh
WORKDIR /root
COPY do_backup.sh /root/do_backup.sh
CMD "/root/do_backup.sh"

View file

@ -0,0 +1,40 @@
#!/bin/sh
set -x -e
cd /root
chmod 0600 .ssh/id_ed25519
cat > .ssh/config <<EOF
Host backuphost
HostName $TARGET_SSH_HOST
Port $TARGET_SSH_PORT
User $TARGET_SSH_USER
EOF
echo "export sql"
export PGPASSWORD=$REPL_PSQL_PWD
pg_basebackup \
--pgdata=- \
--format=tar \
--max-rate=1M \
--no-slot \
--wal-method=none \
--gzip \
--compress=8 \
--checkpoint=spread \
--progress \
--verbose \
--status-interval=10 \
--username=$REPL_PSQL_USER \
--port=5432 \
--host=psql-proxy.service.2.cluster.deuxfleurs.fr | \
age -r "$(cat /root/.ssh/id_ed25519.pub)" | \
ssh backuphost "cat > $TARGET_SSH_DIR/matrix/db-$(date --iso-8601=minute).gz.age"
MATRIX_MEDIA="/mnt/glusterfs/chat/matrix/synapse/media"
echo "export local_content"
tar -vzcf - ${MATRIX_MEDIA} | \
age -r "$(cat /root/.ssh/id_ed25519.pub)" | \
ssh backuphost "cat > $TARGET_SSH_DIR/matrix/media-$(date --iso-8601=minute).gz.age"

View file

@ -0,0 +1,62 @@
job "backup_manual_matrix" {
datacenters = ["dc1"]
type = "batch"
task "backup-matrix" {
driver = "docker"
config {
image = "superboum/backup_matrix:4"
volumes = [
"secrets/id_ed25519:/root/.ssh/id_ed25519",
"secrets/id_ed25519.pub:/root/.ssh/id_ed25519.pub",
"secrets/known_hosts:/root/.ssh/known_hosts",
"/mnt/glusterfs/chat/matrix/synapse/media:/mnt/glusterfs/chat/matrix/synapse/media"
]
network_mode = "host"
}
env {
CONSUL_HTTP_ADDR = "http://consul.service.2.cluster.deuxfleurs.fr:8500"
}
template {
data = <<EOH
TARGET_SSH_USER={{ key "secrets/backup/target_ssh_user" }}
TARGET_SSH_PORT={{ key "secrets/backup/target_ssh_port" }}
TARGET_SSH_HOST={{ key "secrets/backup/target_ssh_host" }}
TARGET_SSH_DIR={{ key "secrets/backup/target_ssh_dir" }}
REPL_PSQL_USER={{ key "secrets/postgres/keeper/pg_repl_username" }}
REPL_PSQL_PWD={{ key "secrets/postgres/keeper/pg_repl_pwd" }}
EOH
destination = "secrets/env_vars"
env = true
}
template {
data = "{{ key \"secrets/backup/id_ed25519\" }}"
destination = "secrets/id_ed25519"
}
template {
data = "{{ key \"secrets/backup/id_ed25519.pub\" }}"
destination = "secrets/id_ed25519.pub"
}
template {
data = "{{ key \"secrets/backup/target_ssh_fingerprint\" }}"
destination = "secrets/known_hosts"
}
resources {
memory = 200
}
restart {
attempts = 2
interval = "30m"
delay = "15s"
mode = "fail"
}
}
}

View file

@ -0,0 +1,67 @@
job "backup_periodic" {
datacenters = ["dc1"]
type = "batch"
periodic {
// Launch every hour
cron = "0 * * * * *"
// Do not allow overlapping runs.
prohibit_overlap = true
}
task "backup-consul" {
driver = "docker"
config {
image = "lxpz/backup_consul:12"
volumes = [
"secrets/id_ed25519:/root/.ssh/id_ed25519",
"secrets/id_ed25519.pub:/root/.ssh/id_ed25519.pub",
"secrets/known_hosts:/root/.ssh/known_hosts"
]
network_mode = "host"
}
env {
CONSUL_HTTP_ADDR = "http://consul.service.2.cluster.deuxfleurs.fr:8500"
}
template {
data = <<EOH
TARGET_SSH_USER={{ key "secrets/backup/target_ssh_user" }}
TARGET_SSH_PORT={{ key "secrets/backup/target_ssh_port" }}
TARGET_SSH_HOST={{ key "secrets/backup/target_ssh_host" }}
TARGET_SSH_DIR={{ key "secrets/backup/target_ssh_dir" }}
EOH
destination = "secrets/env_vars"
env = true
}
template {
data = "{{ key \"secrets/backup/id_ed25519\" }}"
destination = "secrets/id_ed25519"
}
template {
data = "{{ key \"secrets/backup/id_ed25519.pub\" }}"
destination = "secrets/id_ed25519.pub"
}
template {
data = "{{ key \"secrets/backup/target_ssh_fingerprint\" }}"
destination = "secrets/known_hosts"
}
resources {
memory = 200
}
restart {
attempts = 2
interval = "30m"
delay = "15s"
mode = "fail"
}
}
}

View file

@ -0,0 +1 @@
USER_LONG Private ed25519 key of the container doing the backup

View file

@ -0,0 +1 @@
USER Public ed25519 key of the container doing the backup (this key must be in authorized_keys on the backup target host)

View file

@ -0,0 +1 @@
USER Directory where to store backups on target host

View file

@ -0,0 +1 @@
USER SSH fingerprint of the target machine (format: copy here the corresponding line from your known_hosts file)

View file

@ -0,0 +1 @@
USER Hostname of the backup target host

View file

@ -0,0 +1 @@
USER SSH port number to connect to the target host

View file

@ -0,0 +1 @@
USER SSH username to log in as on the target host

View file

@ -1,6 +1,7 @@
job "webcap" {
job "bagage" {
datacenters = ["dc1"]
type = "service"
priority = 90
constraint {
attribute = "${attr.cpu.arch}"
@ -8,36 +9,38 @@ job "webcap" {
}
group "main" {
task "flask" {
count = 1
network {
port "web_port" { to = 8080 }
}
task "server" {
driver = "docker"
config {
image = "superboum/amd64_webcap:v7"
port_map {
web_port = 3000
}
image = "superboum/amd64_bagage:v8"
readonly_rootfs = true
ports = [ "web_port" ]
}
env {
FLASK_APP = "/usr/local/bin/webcap"
BAGAGE_LDAP_ENDPOINT = "bottin2.service.2.cluster.deuxfleurs.fr:389"
}
resources {
cpu = 1000
memory = 2000
network {
port "web_port" {}
}
memory = 500
}
service {
name = "bagage"
tags = [
"webcap",
"bagage",
"traefik.enable=true",
"traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:webcap.deuxfleurs.fr;PathPrefix:/"
"traefik.frontend.rule=Host:bagage.deuxfleurs.fr",
]
port = "web_port"
address_mode = "host"
name = "webcap"
check {
type = "tcp"
port = "web_port"

51
app/core/deploy/core.hcl Normal file
View file

@ -0,0 +1,51 @@
job "core" {
datacenters = ["dc1"]
type = "system"
priority = 90
constraint {
attribute = "${attr.cpu.arch}"
value = "amd64"
}
update {
max_parallel = 1
stagger = "1m"
}
group "network" {
task "diplonat" {
driver = "docker"
config {
image = "darkgallium/amd64_diplonat:v3"
network_mode = "host"
readonly_rootfs = true
privileged = true
}
restart {
interval = "30m"
attempts = 2
delay = "15s"
mode = "delay"
}
template {
data = <<EOH
DIPLONAT_PRIVATE_IP={{ env "attr.unique.network.ip-address" }}
DIPLONAT_REFRESH_TIME=60
DIPLONAT_EXPIRATION_TIME=300
DIPLONAT_CONSUL_NODE_NAME={{ env "attr.unique.hostname" }}
RUST_LOG=debug
EOH
destination = "secrets/env"
env = true
}
resources {
memory = 40
}
}
}
}

View file

@ -1,6 +1,6 @@
{
"suffix": "dc=deuxfleurs,dc=fr",
"bind": "0.0.0.0:1389",
"bind": "0.0.0.0:389",
"consul_host": "http://consul.service.2.cluster.deuxfleurs.fr:8500",
"log_level": "debug",
"acl": [

View file

@ -12,19 +12,23 @@
"invitation_name_attr": "cn",
"invited_mail_format": "{}@deuxfleurs.fr",
"invited_auto_groups": [
"cn=email,ou=groups,dc=deuxfleurs,dc=fr",
"cn=seafile,ou=groups,dc=deuxfleurs,dc=fr",
"cn=nextcloud,ou=groups,dc=deuxfleurs,dc=fr"
"cn=email,ou=groups,dc=deuxfleurs,dc=fr"
],
"web_address": "https://guichet.deuxfleurs.fr",
"mail_from": "coucou@deuxfleurs.fr",
"mail_from": "deuxfleurs-bienvenue@adnab.me",
"smtp_server": "adnab.me:25",
"smtp_username": "{{ key "secrets/directory/guichet/smtp_user" | trimSpace }}",
"smtp_password": "{{ key "secrets/directory/guichet/smtp_pass" | trimSpace }}",
"admin_account": "cn=admin,dc=deuxfleurs,dc=fr",
"group_can_admin": "cn=admin,ou=groups,dc=deuxfleurs,dc=fr",
"group_can_invite": "cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr"
"group_can_invite": "cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr",
"s3_endpoint": "garage.deuxfleurs.fr",
"s3_access_key": "{{ key "secrets/directory/guichet/s3_access_key" | trimSpace }}",
"s3_secret_key": "{{ key "secrets/directory/guichet/s3_secret_key" | trimSpace }}",
"s3_region": "garage",
"s3_bucket": "bottin-pictures"
}

View file

@ -1,6 +1,7 @@
job "directory2" {
job "directory" {
datacenters = ["dc1"]
type = "service"
priority = 90
constraint {
attribute = "${attr.cpu.arch}"
@ -9,14 +10,21 @@ job "directory2" {
group "bottin" {
count = 1
network {
port "ldap_port" {
static = 389
to = 389
}
}
task "bottin" {
driver = "docker"
config {
image = "lxpz/bottin_amd64:14"
image = "superboum/bottin_amd64:22"
network_mode = "host"
readonly_rootfs = true
port_map {
ldap_port = 1389
}
ports = [ "ldap_port" ]
volumes = [
"secrets/config.json:/config.json"
]
@ -24,15 +32,10 @@ job "directory2" {
resources {
memory = 100
network {
port "ldap_port" {
static = "389"
}
}
}
template {
data = "{{ key \"configuration/directory/bottin/config.json\" }}"
data = file("../config/bottin/config.json")
destination = "secrets/config.json"
}
@ -58,34 +61,29 @@ job "directory2" {
group "guichet" {
count = 1
network {
port "web_port" { to = 9991 }
}
task "guichet" {
driver = "docker"
config {
image = "lxpz/guichet_amd64:10"
image = "superboum/guichet_amd64:15"
readonly_rootfs = true
port_map {
web_port = 9991
}
ports = [ "web_port" ]
volumes = [
"secrets/config.json:/config.json"
]
}
artifact {
source = "http://127.0.0.1:8500/v1/kv/configuration/directory/guichet/config.json.tpl?raw"
destination = "secrets/config.json.tpl"
mode = "file"
}
template {
source = "secrets/config.json.tpl"
data = file("../config/guichet/config.json.tpl")
destination = "secrets/config.json"
}
resources {
memory = 200
network {
port "web_port" {}
}
}
service {

View file

@ -0,0 +1 @@
USER Garage access key for Guichet profile pictures

View file

@ -0,0 +1 @@
USER Garage secret key for Guichet profile pictures

View file

@ -0,0 +1 @@
USER SMTP password

View file

@ -0,0 +1 @@
USER SMTP username

109
app/docker-compose.yml Normal file
View file

@ -0,0 +1,109 @@
version: '3.4'
services:
# Instant Messaging
riot:
build:
context: ./im/build/riotweb
args:
# https://github.com/vector-im/riot-web/releases
VERSION: 1.8.4
image: superboum/amd64_riotweb:v24
synapse:
build:
context: ./im/build/matrix-synapse
args:
# https://github.com/matrix-org/synapse/releases
VERSION: 1.42.0
# https://github.com/matrix-org/synapse-s3-storage-provider/commits/main
S3_VERSION: 3c3fafd6a2624f05fd396d9e003501bf8bef7b2e
image: superboum/amd64_synapse:v47
# Email
sogo:
build:
context: ./email/build/sogo
args:
# fake for now
VERSION: 5.0.0
image: superboum/amd64_sogo:v7
alps:
build:
context: ./email/build/alps
args:
VERSION: 9bafa64b9d
image: superboum/amd64_alps:v1
dovecot:
build:
context: ./email/build/dovecot
image: superboum/amd64_dovecot:v6
# VoIP
jitsi-meet:
build:
context: ./jitsi/build/jitsi-meet
args:
# https://github.com/jitsi/jitsi-meet
MEET_TAG: jitsi-meet_5463
image: superboum/amd64_jitsi_meet:v4
jitsi-conference-focus:
build:
context: ./jitsi/build/jitsi-conference-focus
args:
# https://github.com/jitsi/jicofo
JICOFO_TAG: jitsi-meet_5463
image: superboum/amd64_jitsi_conference_focus:v7
jitsi-videobridge:
build:
context: ./jitsi/build/jitsi-videobridge
args:
# https://github.com/jitsi/jitsi-videobridge
# note: JVB is not tagged with non-stable tags
JVB_TAG: stable/jitsi-meet_5390
image: superboum/amd64_jitsi_videobridge:v17
jitsi-xmpp:
build:
context: ./jitsi/build/jitsi-xmpp
args:
MEET_TAG: jitsi-meet_5463
PROSODY_VERSION: 0.11.7-1~buster4
image: superboum/amd64_jitsi_xmpp:v9
plume:
build:
context: ./plume/build/plume
args:
VERSION: 8c372aa6fcd05083601903d83b0fcb4915585a95
image: superboum/plume:v4
postfix:
build:
context: ./email/build/postfix
args:
# https://packages.debian.org/fr/buster/postfix
VERSION: 3.4.14-0+deb10u1
image: superboum/amd64_postfix:v3
postgres:
build:
args:
# https://github.com/sorintlab/stolon/releases
STOLON_VERSION: 057389f7e484ee1d5c1e1a7020256020e7413c87
context: ./postgres/build/postgres
image: superboum/amd64_postgres:v9
backup-consul:
build:
context: ./backup/build/backup-consul
image: lxpz/backup_consul:12
backup-matrix:
build:
context: ./backup/build/backup-matrix
image: superboum/backup_matrix:4

View file

@ -0,0 +1,125 @@
job "drone-ci" {
datacenters = ["dc1"]
type = "service"
group "server" {
count = 1
network {
port "web_port" {
to = 80
}
}
task "drone_server" {
driver = "docker"
config {
image = "drone/drone:2.0.4"
ports = [ "web_port" ]
}
template {
data = <<EOH
DRONE_GITEA_SERVER=https://git.deuxfleurs.fr
DRONE_GITEA_CLIENT_ID={{ key "secrets/drone-ci/oauth_client_id" }}
DRONE_GITEA_CLIENT_SECRET={{ key "secrets/drone-ci/oauth_client_secret" }}
DRONE_RPC_SECRET={{ key "secrets/drone-ci/rpc_secret" }}
DRONE_SERVER_HOST=drone.deuxfleurs.fr
DRONE_SERVER_PROTO=https
DRONE_DATABASE_SECRET={{ key "secrets/drone-ci/db_enc_secret" }}
DRONE_COOKIE_SECRET={{ key "secrets/drone-ci/cookie_secret" }}
AWS_ACCESS_KEY_ID={{ key "secrets/drone-ci/s3_ak" }}
AWS_SECRET_ACCESS_KEY={{ key "secrets/drone-ci/s3_sk" }}
AWS_DEFAULT_REGION=garage
AWS_REGION=garage
DRONE_S3_BUCKET={{ key "secrets/drone-ci/s3_bucket" }}
DRONE_S3_ENDPOINT=https://garage.deuxfleurs.fr
DRONE_S3_PATH_STYLE=true
DRONE_DATABASE_DRIVER=postgres
DRONE_DATABASE_DATASOURCE=postgres://{{ key "secrets/drone-ci/db_user" }}:{{ key "secrets/drone-ci/db_pass" }}@psql-proxy.service.2.cluster.deuxfleurs.fr:5432/drone?sslmode=disable
DRONE_USER_CREATE=username:lx-admin,admin:true
DRONE_LOGS_TEXT=true
DRONE_LOGS_PRETTY=true
DRONE_LOGS_DEBUG=true
DOCKER_API_VERSION=1.39
EOH
destination = "secrets/env"
env = true
}
resources {
cpu = 100
memory = 100
}
service {
name = "drone"
tags = [
"drone",
"traefik.enable=true",
"traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:drone.deuxfleurs.fr",
]
port = "web_port"
address_mode = "host"
check {
type = "http"
protocol = "http"
port = "web_port"
path = "/"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "600s"
ignore_warnings = false
}
}
}
}
}
/*
group "runner" {
count = 3
constraint {
operator = "distinct_hosts"
value = "true"
}
task "drone_runner" {
driver = "docker"
config {
network_mode = "host"
#image = "drone/drone-runner-nomad:latest"
image = "drone/drone-runner-docker:1.6.3"
volumes = [
"/var/run/docker.sock:/var/run/docker.sock"
]
}
template {
data = <<EOH
DRONE_RPC_SECRET={{ key "secrets/drone-ci/rpc_secret" }}
DRONE_RPC_HOST=drone.deuxfleurs.fr
DRONE_RPC_PROTO=https
DRONE_RUNNER_NAME={{ env "node.unique.name" }}
DRONE_DEBUG=true
NOMAD_ADDR=http://nomad-client.service.2.cluster.deuxfleurs.fr:4646
DOCKER_API_VERSION=1.39
EOH
destination = "secrets/env"
env = true
}
resources {
memory = 40
cpu = 50
}
}
}
*/
}

View file

@ -0,0 +1 @@
CMD openssl rand -hex 16

View file

@ -0,0 +1 @@
CMD_ONCE openssl rand -hex 16

View file

@ -0,0 +1 @@
SERVICE_PASSWORD drone

View file

@ -0,0 +1 @@
CONST drone

View file

@ -0,0 +1 @@
USER OAuth client ID (on Gitea)

View file

@ -0,0 +1 @@
USER OAuth client secret (for gitea)

View file

@ -0,0 +1 @@
CMD openssl rand -hex 16

View file

@ -0,0 +1 @@
USER S3 (garage) access key for Drone

View file

@ -0,0 +1 @@
CONST drone

View file

@ -0,0 +1 @@
USER S3 (garage) secret key for Drone

View file

@ -0,0 +1 @@
CMD head -c 10 /dev/urandom | base64

View file

@ -0,0 +1 @@
CONST this is a constant

View file

@ -0,0 +1,5 @@
CONST_LONG
this is a
constant
on several
lines

View file

@ -0,0 +1 @@
SERVICE_DN dummy Dummy service for testing secretmgr.py

View file

@ -0,0 +1 @@
SERVICE_PASSWORD dummy

View file

@ -0,0 +1 @@
USER Test user value

View file

@ -0,0 +1,19 @@
FROM golang:1.15.6-buster as builder
ARG VERSION
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
WORKDIR /tmp/alps
RUN git init && \
git remote add origin https://git.deuxfleurs.fr/Deuxfleurs/alps.git && \
git fetch --depth 1 origin ${VERSION} && \
git checkout FETCH_HEAD
RUN go build -a -o /usr/local/bin/alps ./cmd/alps
FROM scratch
COPY --from=builder /usr/local/bin/alps /alps
COPY --from=builder /tmp/alps/themes /themes
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
ENTRYPOINT ["/alps"]

View file

@ -1,4 +1,4 @@
FROM amd64/debian:stretch
FROM amd64/debian:bullseye
RUN apt-get update && \
apt-get install -y \
@ -11,7 +11,6 @@ RUN apt-get update && \
dovecot-lmtpd && \
rm -rf /etc/dovecot/*
RUN useradd mailstore
COPY ./conf/* /etc/dovecot/
COPY entrypoint.sh /usr/local/bin/entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint"]

View file

@ -0,0 +1,5 @@
require ["fileinto", "mailbox"];
if header :contains "X-Spam-Flag" "YES" {
fileinto :create "Junk";
}

View file

@ -0,0 +1,8 @@
hosts = ldap.example.com
dn = cn=admin,dc=example,dc=com
dnpass = s3cr3t
base = dc=example,dc=com
scope = subtree
user_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=example,dc=com)))
pass_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=example,dc=com)))
user_attrs = mail=/var/mail/%{ldap:mail}

View file

@ -0,0 +1,17 @@
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables", "vnd.dovecot.debug"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}
if string "${mailbox}" "Trash" {
stop;
}
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-learn" [ "--ham", "-u", "debian-spamd" ];
debug_log "ham reported by ${username}";

View file

@ -0,0 +1,9 @@
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables", "vnd.dovecot.debug"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-learn" [ "--spam", "-u", "debian-spamd"];
debug_log "spam reported by ${username}";

View file

@ -1,8 +1,10 @@
FROM amd64/debian:buster
ARG VERSION
RUN apt-get update && \
apt-get install -y \
postfix \
postfix=$VERSION \
postfix-ldap
COPY entrypoint.sh /usr/local/bin/entrypoint

View file

@ -26,5 +26,6 @@ for file in $(ls /etc/postfix-conf); do
done
echo ${MAILNAME} > /etc/mailname
postmap /etc/postfix/transport
exec "$@"

View file

@ -1,6 +1,6 @@
#FROM amd64/debian:stretch as builder
FROM amd64/debian:stretch
FROM amd64/debian:buster
RUN mkdir ~/.gnupg && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf
@ -8,7 +8,7 @@ RUN apt-get update && \
apt-get install -y apt-transport-https gnupg2 sudo nginx && \
rm -rf /etc/nginx/sites-enabled/* && \
apt-key adv --keyserver keys.gnupg.net --recv-key 0x810273C4 && \
echo "deb https://packages.inverse.ca/SOGo/nightly/4/debian stretch stretch" > /etc/apt/sources.list.d/sogo.list && \
echo "deb http://packages.inverse.ca/SOGo/nightly/5/debian/ buster buster" > /etc/apt/sources.list.d/sogo.list && \
apt-get update && \
apt-get install -y sogo sogo-activesync sope4.9-gdl1-postgresql postgresql-client

View file

@ -0,0 +1,83 @@
server {
listen 8080;
server_name default_server;
root /usr/lib/GNUstep/SOGo/WebServerResources/;
## requirement to create new calendars in Thunderbird ##
proxy_http_version 1.1;
# Message size limit
client_max_body_size 50m;
client_body_buffer_size 128k;
location = / {
rewrite ^ '/SOGo';
allow all;
}
location = /principals/ {
rewrite ^ '/SOGo/dav';
allow all;
}
location ^~/SOGo {
proxy_pass 'http://127.0.0.1:20000';
proxy_redirect 'http://127.0.0.1:20000' default;
# forward user's IP address
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host 127.0.0.1;
proxy_set_header x-webobjects-server-name $server_name;
proxy_set_header x-webobjects-server-url $scheme://$host;
proxy_set_header x-webobjects-server-port $server_port;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
break;
}
location /SOGo.woa/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
allow all;
expires max;
}
location /SOGo/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
allow all;
expires max;
}
location (^/SOGo/so/ControlPanel/Products/([^/]*)/Resources/(.*)$) {
alias /usr/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
expires max;
}
location (^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\.(jpg|png|gif|css|js)$) {
alias /usr/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
expires max;
}
location ^~ /Microsoft-Server-ActiveSync {
access_log /var/log/nginx/activesync.log;
error_log /var/log/nginx/activesync-error.log;
proxy_connect_timeout 75;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_buffers 64 256k;
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_pass http://127.0.0.1:20000/SOGo/Microsoft-Server-ActiveSync;
proxy_redirect http://127.0.0.1:20000/SOGo/Microsoft-Server-ActiveSync /;
}
}

View file

@ -5,4 +5,8 @@ base = dc=deuxfleurs,dc=fr
scope = subtree
user_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=deuxfleurs,dc=fr)))
pass_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=deuxfleurs,dc=fr)))
user_attrs = mail=/var/mail/%{ldap:mail}
user_attrs = \
=user=%{ldap:cn}, \
=mail=maildir:/var/mail/%{ldap:cn}, \
=uid=1000, \
=gid=1000

View file

@ -0,0 +1,87 @@
auth_mechanisms = plain login
auth_username_format = %u
log_timestamp = "%Y-%m-%d %H:%M:%S "
mail_location = maildir:/var/mail/%u
mail_privileged_group = mail
log_path = /dev/stderr
info_log_path = /dev/stdout
debug_log_path = /dev/stdout
protocols = imap sieve lmtp
ssl_cert = < /etc/ssl/certs/dovecot.crt
ssl_key = < /etc/ssl/private/dovecot.key
service auth {
inet_listener {
port = 1337
}
}
service lmtp {
inet_listener lmtp {
address = 0.0.0.0
port = 24
}
}
# https://doc.dovecot.org/configuration_manual/authentication/ldap_authentication/
passdb {
args = /etc/dovecot/dovecot-ldap.conf
driver = ldap
}
userdb {
driver = prefetch
}
userdb {
args = /etc/dovecot/dovecot-ldap.conf
driver = ldap
}
service imap-login {
service_count = 0 # performance mode. set to 1 for secure mode
process_min_avail = 1
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
}
}
protocol imap {
mail_plugins = $mail_plugins imap_sieve
}
protocol lda {
auth_socket_path = /var/run/dovecot/auth-master
info_log_path = /var/log/dovecot-deliver.log
log_path = /var/log/dovecot-deliver-errors.log
postmaster_address = postmaster@deuxfleurs.fr
mail_plugins = $mail_plugins sieve
}
plugin {
sieve = file:~/sieve;active=~/dovecot.sieve
sieve_before = /etc/dovecot/all_before.sieve
# antispam learn
sieve_plugins = sieve_imapsieve sieve_extprograms
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment +vnd.dovecot.debug
sieve_pipe_bin_dir = /usr/bin
imapsieve_mailbox1_name = Junk
imapsieve_mailbox1_causes = COPY FLAG APPEND
imapsieve_mailbox1_before = file:/etc/dovecot/report-spam.sieve
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Spam
imapsieve_mailbox2_causes = COPY APPEND
imapsieve_mailbox2_before = file:/etc/dovecot/report-ham.sieve
}

View file

@ -1,6 +1,7 @@
{
WONoDetach = NO;
WOWorkersCount = 10;
WOWorkersCount = 3;
SxVMemLimit = 300;
WOPort = "127.0.0.1:20000";
SOGoProfileURL = "postgresql://{{ key "secrets/email/sogo/postgre_auth" | trimSpace }}@psql-proxy.service.2.cluster.deuxfleurs.fr:5432/sogo/sogo_user_profile";
OCSFolderInfoURL = "postgresql://{{ key "secrets/email/sogo/postgre_auth" | trimSpace }}@psql-proxy.service.2.cluster.deuxfleurs.fr:5432/sogo/sogo_folder_info";
@ -23,7 +24,7 @@
SOGoSentFolderName = Sent;
SOGoTrashFolderName = Trash;
SOGoDraftsFolderName = Drafts;
SOGoIMAPServer = "imaps://dovecot-imaps.service.2.cluster.deuxfleurs.fr:993/";
SOGoIMAPServer = "imaps://dovecot-imaps.service.2.cluster.deuxfleurs.fr:993/?tlsVerifyMode=none";
SOGoSieveServer = "sieve://sieve.service.2.cluster.deuxfleurs.fr:4190/?tls=YES";
SOGoIMAPAclConformsToIMAPExt = YES;
SOGoVacationEnabled = NO;

View file

@ -1,27 +1,43 @@
job "email" {
datacenters = ["dc1"]
type = "service"
priority = 65
group "dovecot" {
count = 1
network {
port "zauthentication_port" {
static = 1337
to = 1337
}
port "imaps_port" {
static = 993
to = 993
}
port "imap_port" {
static = 143
to = 143
}
port "lmtp_port" {
static = 24
to = 24
}
}
task "server" {
driver = "docker"
config {
image = "superboum/amd64_dovecot:v2"
image = "superboum/amd64_dovecot:v6"
readonly_rootfs = false
port_map {
auth_port = 1337
imaps_port = 993
imap_port = 143
lmtp_port = 24
}
ports = [ "zauthentication_port", "imaps_port", "imap_port", "lmtp_port" ]
command = "dovecot"
args = [ "-F" ]
volumes = [
"secrets/ssl/certs:/etc/ssl/certs",
"secrets/ssl/private:/etc/ssl/private",
"secrets/conf/dovecot-ldap.conf:/etc/dovecot/dovecot-ldap.conf",
"secrets/conf/:/etc/dovecot/",
"/mnt/glusterfs/email/mail:/var/mail/",
]
}
@ -33,47 +49,11 @@ job "email" {
resources {
cpu = 100
memory = 200
network {
mbits = 1
port "auth_port" {
static = "1337"
}
port "imap_port" {
static = "143"
}
port "imaps_port" {
static = "993"
}
port "lmtp_port" {
static = "24"
}
}
}
service {
name = "dovecot-auth"
port = "auth_port"
address_mode = "host"
tags = [
"dovecot",
]
check {
type = "tcp"
port = "auth_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
service {
name = "dovecot-imap"
port = "imap_port"
address_mode = "host"
tags = [
"dovecot"
]
@ -93,7 +73,6 @@ job "email" {
service {
name = "dovecot-imaps"
port = "imaps_port"
address_mode = "host"
tags = [
"dovecot",
"(diplonat (tcp_port 993))"
@ -115,7 +94,6 @@ job "email" {
service {
name = "dovecot-lmtp"
port = "lmtp_port"
address_mode = "host"
tags = [
"dovecot",
]
@ -133,24 +111,44 @@ job "email" {
}
}
artifact {
source = "http://127.0.0.1:8500/v1/kv/configuration/email/dovecot/dovecot-ldap.conf.tpl?raw"
destination = "secrets/conf/dovecot-ldap.conf.tpl"
mode = "file"
}
template {
source = "secrets/conf/dovecot-ldap.conf.tpl"
destination = "secrets/conf/dovecot-ldap.conf"
perms = "400"
service {
name = "dovecot-auth"
port = "zauthentication_port"
tags = [
"dovecot",
]
check {
type = "tcp"
port = "zauthentication_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
template {
data = "{{ key \"configuration/email/dovecot/dovecot.crt\" }}"
data = file("../config/dovecot/dovecot-ldap.conf.tpl")
destination = "secrets/conf/dovecot-ldap.conf"
perms = "400"
}
template {
data = file("../config/dovecot/dovecot.conf")
destination = "secrets/conf/dovecot.conf"
perms = "400"
}
# ----- secrets ------
template {
data = "{{ key \"secrets/email/dovecot/dovecot.crt\" }}"
destination = "secrets/ssl/certs/dovecot.crt"
perms = "400"
}
template {
data = "{{ key \"configuration/email/dovecot/dovecot.key\" }}"
data = "{{ key \"secrets/email/dovecot/dovecot.key\" }}"
destination = "secrets/ssl/private/dovecot.key"
perms = "400"
}
@ -159,15 +157,20 @@ job "email" {
group "opendkim" {
count = 1
network {
port "dkim_port" {
static = 8999
to = 8999
}
}
task "server" {
driver = "docker"
config {
image = "superboum/amd64_opendkim:v1"
readonly_rootfs = false
port_map {
dkim_port = 8999
}
ports = [ "dkim_port" ]
command = "opendkim"
args = [ "-f", "-v", "-x", "/etc/opendkim.conf" ]
volumes = [
@ -179,12 +182,6 @@ job "email" {
resources {
cpu = 100
memory = 50
network {
mbits = 1
port "dkim_port" {
static = "8999"
}
}
}
service {
@ -208,72 +205,69 @@ job "email" {
}
template {
data = "{{ key \"configuration/email/dkim/keytable\" }}"
data = file("../config/dkim/keytable")
destination = "secrets/dkim/keytable"
}
template {
data = "{{ key \"configuration/email/dkim/signingtable\" }}"
data = file("../config/dkim/signingtable")
destination = "secrets/dkim/signingtable"
}
template {
data = "{{ key \"configuration/email/dkim/smtp.private\" }}"
data = file("../config/dkim/trusted")
destination = "secrets/dkim/trusted"
}
# --- secrets ---
template {
data = "{{ key \"secrets/email/dkim/smtp.private\" }}"
destination = "secrets/dkim/smtp.private"
perms = "600"
}
template {
data = "{{ key \"configuration/email/dkim/smtp.txt\" }}"
destination = "secrets/dkim/smtp.txt"
}
template {
data = "{{ key \"configuration/email/dkim/trusted\" }}"
destination = "secrets/dkim/trusted"
}
}
}
group "postfix" {
count = 1
network {
port "smtp_port" {
static = 25
to = 25
}
port "smtps_port" {
static = 465
to = 465
}
port "submission_port" {
static = 587
to = 587
}
}
task "server" {
driver = "docker"
config {
image = "superboum/amd64_postfix:v1"
image = "superboum/amd64_postfix:v3"
readonly_rootfs = false
port_map {
smtp_port = 25
smtps_port = 465
submission_port = 587
}
ports = [ "smtp_port", "smtps_port", "submission_port" ]
command = "postfix"
args = [ "start-fg" ]
volumes = [
"secrets/ssl/certs:/etc/ssl/certs",
"secrets/ssl/private:/etc/ssl/private",
"secrets/postfix:/etc/postfix-conf",
"secrets/postfix:/etc/postfix-conf",
"/dev/log:/dev/log"
]
}
env {
TLSINFO = "/C=FR/ST=Bretagne/L=Rennes/O=Deuxfleurs/CN=smtp.deuxfleurs.fr"
MAILNAME = "smtp.deuxfleurs.fr",
MAILNAME = "smtp.deuxfleurs.fr"
}
resources {
cpu = 100
memory = 200
network {
mbits = 1
port "smtp_port" {
static = "25"
}
port "smtps_port" {
static = "465"
}
port "submission_port" {
static = "587"
}
}
}
service {
@ -339,109 +333,140 @@ job "email" {
}
}
artifact {
source = "http://127.0.0.1:8500/v1/kv/configuration/email/postfix/ldap-account.cf.tpl?raw"
destination = "secrets/postfix/ldap-account.cf.tpl"
mode = "file"
}
template {
source = "secrets/postfix/ldap-account.cf.tpl"
data = file("../config/postfix/ldap-account.cf.tpl")
destination = "secrets/postfix/ldap-account.cf"
}
artifact {
source = "http://127.0.0.1:8500/v1/kv/configuration/email/postfix/ldap-alias.cf.tpl?raw"
destination = "secrets/postfix/ldap-alias.cf.tpl"
mode = "file"
}
template {
source = "secrets/postfix/ldap-alias.cf.tpl"
data = file("../config/postfix/ldap-alias.cf.tpl")
destination = "secrets/postfix/ldap-alias.cf"
}
artifact {
source = "http://127.0.0.1:8500/v1/kv/configuration/email/postfix/ldap-virtual-domains.cf.tpl?raw"
destination = "secrets/postfix/ldap-virtual-domains.cf.tpl"
mode = "file"
}
template {
source = "secrets/postfix/ldap-virtual-domains.cf.tpl"
data = file("../config/postfix/ldap-virtual-domains.cf.tpl")
destination = "secrets/postfix/ldap-virtual-domains.cf"
}
template {
data = file("../config/postfix/dynamicmaps.cf")
destination = "secrets/postfix/dynamicmaps.cf"
}
template {
data = "{{ key \"configuration/email/postfix/postfix.crt\" }}"
data = file("../config/postfix/header_checks")
destination = "secrets/postfix/header_checks"
}
template {
data = file("../config/postfix/main.cf")
destination = "secrets/postfix/main.cf"
}
template {
data = file("../config/postfix/master.cf")
destination = "secrets/postfix/master.cf"
}
template {
data = file("../config/postfix/transport")
destination = "secrets/postfix/transport"
}
# --- secrets ---
template {
data = "{{ key \"secrets/email/postfix/postfix.crt\" }}"
destination = "secrets/ssl/certs/postfix.crt"
perms = "400"
}
template {
data = "{{ key \"configuration/email/postfix/postfix.key\" }}"
data = "{{ key \"secrets/email/postfix/postfix.key\" }}"
destination = "secrets/ssl/private/postfix.key"
perms = "400"
}
template {
data = "{{ key \"configuration/email/postfix/dynamicmaps.cf\" }}"
destination = "secrets/postfix/dynamicmaps.cf"
}
template {
data = "{{ key \"configuration/email/postfix/header_checks\" }}"
destination = "secrets/postfix/header_checks"
}
template {
data = "{{ key \"configuration/email/postfix/main.cf\" }}"
destination = "secrets/postfix/main.cf"
}
template {
data = "{{ key \"configuration/email/postfix/master.cf\" }}"
destination = "secrets/postfix/master.cf"
}
template {
data = "{{ key \"configuration/email/postfix/transport\" }}"
destination = "secrets/postfix/transport"
}
template {
data = "{{ key \"configuration/email/postfix/transport.db\" }}"
destination = "secrets/postfix/transport.db"
}
}
}
group "alps" {
count = 1
network {
port "alps_web_port" { to = 1323 }
}
task "main" {
driver = "docker"
config {
image = "lxpz/alps_amd64:v2"
readonly_rootfs = true
ports = [ "alps_web_port" ]
args = [
"-skiptlsverification",
"-theme",
"alps",
"imaps://imap.deuxfleurs.fr:993",
"smtps://smtp.deuxfleurs.fr:465"
]
}
resources {
cpu = 100
memory = 100
}
service {
name = "alps"
port = "alps_web_port"
address_mode = "host"
tags = [
"alps",
"traefik.enable=true",
"traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:alps.deuxfleurs.fr"
]
check {
type = "tcp"
port = "alps_web_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "5m"
ignore_warnings = false
}
}
}
}
}
group "sogo" {
count = 1
task "bundle" {
driver = "docker"
network {
port "sogo_web_port" { to = 8080 }
}
task "bundle" {
driver = "docker"
config {
image = "superboum/amd64_sogo:v6"
image = "superboum/amd64_sogo:v7"
readonly_rootfs = false
port_map {
sogo_web_port = 8080
}
ports = [ "sogo_web_port" ]
volumes = [
"secrets/sogo.conf:/etc/sogo/sogo.conf",
"secrets/sogo.conf:/etc/sogo/sogo.conf",
]
}
/* Workaround as there is no consul source and no way to template recursively... */
artifact {
source = "http://127.0.0.1:8500/v1/kv/configuration/email/sogo/sogo.conf.tpl?raw"
destination = "secrets/tpl/sogo.conf.tpl"
mode = "file"
}
template {
source = "secrets/tpl/sogo.conf.tpl"
data = file("../config/sogo/sogo.conf.tpl")
destination = "secrets/sogo.conf"
}
resources {
cpu = 200
memory = 1000
network {
mbits = 1
port "sogo_web_port" {}
}
}
service {

View file

@ -0,0 +1 @@
RSA_PRIVATE_KEY dkim

View file

@ -0,0 +1 @@
SSL_CERT dovecot deuxfleurs.fr

View file

@ -0,0 +1 @@
SSL_KEY dovecot

View file

@ -0,0 +1 @@
SERVICE_DN dovecot Dovecot IMAP server

View file

@ -0,0 +1 @@
SERVICE_PASSWORD dovecot

View file

@ -0,0 +1 @@
SSL_CERT postfix deuxfleurs.fr

View file

@ -0,0 +1 @@
SSL_KEY postfix

View file

@ -0,0 +1 @@
SERVICE_DN sogo SoGo email frontend

View file

@ -0,0 +1 @@
SERVICE_PASSWORD sogo

Some files were not shown because too many files have changed in this diff Show more