aboutsummaryrefslogtreecommitdiff
path: root/docker
diff options
context:
space:
mode:
Diffstat (limited to 'docker')
-rwxr-xr-xdocker/blog-quentin/.dockerenv0
-rw-r--r--docker/blog-quentin/Dockerfile16
-rw-r--r--docker/blog-quentin/README.md1
-rw-r--r--docker/coturn/Dockerfile8
-rw-r--r--docker/coturn/README.md17
-rw-r--r--docker/dovecot/.gitignore1
-rw-r--r--docker/dovecot/Dockerfile17
-rw-r--r--docker/dovecot/README.md18
-rwxr-xr-xdocker/dovecot/entrypoint.sh27
-rw-r--r--docker/landing/Dockerfile3
-rw-r--r--docker/landing/README.md3
-rw-r--r--docker/landing/html/.well-known/matrix/client9
-rw-r--r--docker/landing/html/.well-known/matrix/server0
-rw-r--r--docker/landing/html/index.html116
-rw-r--r--docker/landing/html/robots.txt2
-rw-r--r--docker/mariadb/60-disable-dialog.cnf3
-rw-r--r--docker/mariadb/60-ldap.cnf3
-rw-r--r--docker/mariadb/60-remote.cnf2
-rw-r--r--docker/mariadb/Dockerfile14
-rw-r--r--docker/mariadb/README.md19
-rwxr-xr-xdocker/mariadb/entrypoint.sh50
-rw-r--r--docker/mariadb/nsswitch.conf21
-rw-r--r--docker/mariadb/pam-mariadb2
-rw-r--r--docker/matrix-synapse/Dockerfile47
-rw-r--r--docker/matrix-synapse/README.md3
-rwxr-xr-xdocker/matrix-synapse/entrypoint.sh3
-rw-r--r--docker/opendkim/Dockerfile8
-rw-r--r--docker/opendkim/README.md12
-rw-r--r--docker/opendkim/opendkim.conf12
-rw-r--r--docker/postfix/Dockerfile11
-rw-r--r--docker/postfix/README.md18
-rwxr-xr-xdocker/postfix/entrypoint.sh30
-rw-r--r--docker/postgres/Dockerfile19
-rw-r--r--docker/postgres/README.md4
-rw-r--r--docker/postgres/postgresql.conf25
-rwxr-xr-xdocker/postgres/start.sh22
-rw-r--r--docker/riotweb/Dockerfile13
-rw-r--r--docker/riotweb/README.md4
-rw-r--r--docker/riotweb/config.json24
-rw-r--r--docker/seafile/Dockerfile45
-rw-r--r--docker/seafile/README.md11
-rwxr-xr-xdocker/seafile/seadocker4
-rwxr-xr-xdocker/seafile/seaenv7
-rw-r--r--docker/sogo/Dockerfile17
-rw-r--r--docker/sogo/README.md20
-rwxr-xr-xdocker/sogo/entrypoint13
-rw-r--r--docker/static/Dockerfile9
-rw-r--r--docker/static/README.md5
m---------docker/static/goStatic0
-rw-r--r--docker/tag-config/.gitignore1
-rw-r--r--docker/tag-config/README.md22
-rw-r--r--docker/tag-config/index.mjs56
-rw-r--r--docker/tag-config/package-lock.json74
-rw-r--r--docker/tag-config/package.json18
-rw-r--r--docker/tag-config/src/catalog/consul.mjs30
-rw-r--r--docker/tag-config/src/injector/iptables.mjs53
-rw-r--r--docker/tag-config/src/injector/upnp.mjs0
-rw-r--r--docker/tag-config/src/io/files.mjs8
-rw-r--r--docker/tag-config/src/io/run.mjs9
-rw-r--r--docker/tag-config/static.iptables10
-rw-r--r--docker/tag-config/test/io.mjs10
-rw-r--r--docker/tag-config/test/iptables.mjs28
-rw-r--r--docker/tag-config/test/runner.mjs28
63 files changed, 1085 insertions, 0 deletions
diff --git a/docker/blog-quentin/.dockerenv b/docker/blog-quentin/.dockerenv
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/docker/blog-quentin/.dockerenv
diff --git a/docker/blog-quentin/Dockerfile b/docker/blog-quentin/Dockerfile
new file mode 100644
index 0000000..61f5c40
--- /dev/null
+++ b/docker/blog-quentin/Dockerfile
@@ -0,0 +1,16 @@
+FROM amd64/debian:stretch as builder
+
+COPY ./quentin.dufour.io/Gemfile /root/quentin.dufour.io/Gemfile
+
+WORKDIR /root/quentin.dufour.io
+
+RUN apt-get update && \
+ apt-get install -y ruby-dev gem build-essential bundler zlib1g-dev libxml2-dev && \
+ bundle install
+
+COPY ./quentin.dufour.io/ /root/quentin.dufour.io/
+RUN bundle exec jekyll build
+
+FROM superboum/amd64_webserver:v2
+COPY --from=builder /root/quentin.dufour.io/_site /srv/http
+
diff --git a/docker/blog-quentin/README.md b/docker/blog-quentin/README.md
new file mode 100644
index 0000000..7e1bb53
--- /dev/null
+++ b/docker/blog-quentin/README.md
@@ -0,0 +1 @@
+sudo docker build -t superboum/amd64_blog:v18 .
diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile
new file mode 100644
index 0000000..0d23161
--- /dev/null
+++ b/docker/coturn/Dockerfile
@@ -0,0 +1,8 @@
+FROM amd64/debian:buster
+
+RUN apt-get update && \
+ apt-get dist-upgrade -y && \
+ apt-get install -y \
+ coturn
+
+CMD ["/usr/bin/turnserver"]
diff --git a/docker/coturn/README.md b/docker/coturn/README.md
new file mode 100644
index 0000000..e882146
--- /dev/null
+++ b/docker/coturn/README.md
@@ -0,0 +1,17 @@
+
+## Génère l'image
+```
+sudo docker build -t registry.gitlab.com/superboum/ankh-morpork/amd64_coturn:v1 .
+```
+
+## Run bash dans le container
+```
+sudo docker run --rm -t -i registry.gitlab.com/superboum/ankh-morpork/amd64_coturn:v1 bash
+sudo docker run --rm -t -i -p 3478:3478/udp -p 3479:3479/udp -p 3478:3478/tcp -p 3479:3479/tcp registry.gitlab.com/superboum/ankh-morpork/amd64_coturn:v1
+```
+
+## Used ports
+- udp/tcp 3478 3479
+
+## Publish
+sudo docker push registry.gitlab.com/superboum/ankh-morpork/amd64_coturn:v1
diff --git a/docker/dovecot/.gitignore b/docker/dovecot/.gitignore
new file mode 100644
index 0000000..71a04e2
--- /dev/null
+++ b/docker/dovecot/.gitignore
@@ -0,0 +1 @@
+dovecot-ldap.conf
diff --git a/docker/dovecot/Dockerfile b/docker/dovecot/Dockerfile
new file mode 100644
index 0000000..9b87627
--- /dev/null
+++ b/docker/dovecot/Dockerfile
@@ -0,0 +1,17 @@
+FROM amd64/debian:stretch
+
+RUN apt-get update && \
+ apt-get install -y \
+ dovecot-antispam \
+ dovecot-core \
+ dovecot-imapd \
+ dovecot-ldap \
+ dovecot-managesieved \
+ dovecot-sieve \
+ 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"]
diff --git a/docker/dovecot/README.md b/docker/dovecot/README.md
new file mode 100644
index 0000000..8c9f372
--- /dev/null
+++ b/docker/dovecot/README.md
@@ -0,0 +1,18 @@
+```
+sudo docker build -t superboum/amd64_dovecot:v2 .
+```
+
+
+```
+sudo docker run -t -i \
+ -e TLSINFO="/C=FR/ST=Bretagne/L=Rennes/O=Deuxfleurs/CN=www.deuxfleurs.fr" \
+ -p 993:993 \
+ -p 143:143 \
+ -p 24:24 \
+ -p 1337:1337 \
+ -v /mnt/glusterfs/email/ssl:/etc/ssl/ \
+ -v /mnt/glusterfs/email/mail:/var/mail \
+ -v `pwd`/dovecot-ldap.conf:/etc/dovecot/dovecot-ldap.conf \
+ superboum/amd64_dovecot:v1 \
+ dovecot -F
+```
diff --git a/docker/dovecot/entrypoint.sh b/docker/dovecot/entrypoint.sh
new file mode 100755
index 0000000..2165d8f
--- /dev/null
+++ b/docker/dovecot/entrypoint.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+if [[ ! -f /etc/ssl/certs/dovecot.crt || ! -f /etc/ssl/private/dovecot.key ]]; then
+ cd /root
+ openssl req \
+ -new \
+ -newkey rsa:4096 \
+ -days 3650 \
+ -nodes \
+ -x509 \
+ -subj ${TLSINFO} \
+ -keyout dovecot.key \
+ -out dovecot.crt
+
+ mkdir -p /etc/ssl/{certs,private}/
+
+ cp dovecot.crt /etc/ssl/certs/dovecot.crt
+ cp dovecot.key /etc/ssl/private/dovecot.key
+ chmod 400 /etc/ssl/certs/dovecot.crt
+ chmod 400 /etc/ssl/private/dovecot.key
+fi
+
+if [[ $(stat -c '%U' /var/mail/) != "mailstore" ]]; then
+ chown -R mailstore /var/mail
+fi
+
+exec "$@"
diff --git a/docker/landing/Dockerfile b/docker/landing/Dockerfile
new file mode 100644
index 0000000..b4cbbce
--- /dev/null
+++ b/docker/landing/Dockerfile
@@ -0,0 +1,3 @@
+FROM superboum/amd64_webserver:v2
+COPY ./html /srv/http
+
diff --git a/docker/landing/README.md b/docker/landing/README.md
new file mode 100644
index 0000000..fffdbce
--- /dev/null
+++ b/docker/landing/README.md
@@ -0,0 +1,3 @@
+```
+docker build -t superboum/amd64_landing:v5 .
+```
diff --git a/docker/landing/html/.well-known/matrix/client b/docker/landing/html/.well-known/matrix/client
new file mode 100644
index 0000000..d34a03a
--- /dev/null
+++ b/docker/landing/html/.well-known/matrix/client
@@ -0,0 +1,9 @@
+{
+ "m.homeserver": {
+ "base_url": "https://im.deuxfleurs.fr"
+ },
+ "m.identity_server": {
+ "base_url": "https://vector.im"
+ }
+}
+
diff --git a/docker/landing/html/.well-known/matrix/server b/docker/landing/html/.well-known/matrix/server
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docker/landing/html/.well-known/matrix/server
diff --git a/docker/landing/html/index.html b/docker/landing/html/index.html
new file mode 100644
index 0000000..7804d62
--- /dev/null
+++ b/docker/landing/html/index.html
@@ -0,0 +1,116 @@
+<!doctype html>
+<html lang="fr">
+ <head>
+ <title>💮💮 deuxfleurs.fr</title>
+ <meta charset="utf-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="Description" content="deuxfleurs.fr, communiquer en préservant nos libertés">
+<style>
+* {
+ background-color: #fafafa;
+ color: #111;
+ font-family: Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
+ font-weight: normal;
+ font-size: 20px;
+ line-height: 1.4em;
+}
+
+header > h1, header > h2 {
+ display: inline;
+ font-size: 28px;
+}
+
+article > h2::before {
+ content: "# ";
+}
+
+article > h2 {
+ font-size: 34px;
+}
+
+article > h3 {
+ font-size: 28px;
+}
+
+samp {
+ font-family: "Courier";
+}
+
+.container {
+ display: flex;
+ justify-content: center;
+}
+.main.content {
+ width: 100%;
+ max-width: 1200px;
+}
+</style>
+ </head>
+
+ <body>
+ <div class="container">
+ <div class="content main">
+ <header>
+ <h1>💮💮 deuxfleurs.fr</h1>
+ <h2> - préservons nos libertés</h2>
+ <hr/>
+ </header>
+ <article>
+ <h2>Notre raison d'être</h2>
+ <p>
+ Aujourd'hui, de grandes entreprises conçoivent des services numériques qui ont pour objectif de <a href="https://fr.wikipedia.org/wiki/%C3%89conomie_de_l%27attention">maximiser le temps</a> que nous passons dessus, de <a href="https://fr.wikipedia.org/wiki/%C3%89conomie_de_la_surveillance">collecter et recouper des données</a> à notre insu pour nous influencer, de <a href="https://www.april.org/le-parlement-europeen-valide-la-generalisation-de-la-censure-automatisee">limiter nos possibilités d'expression</a> au delà du cadre légal et de <a href="https://fr.wikipedia.org/wiki/Embrace,_extend_and_extinguish">créer de nouveaux monopôles</a>. Ces effets nous montrent que la technologie n'est pas neutre et a un réel impact sur nos vies. En choisissant et en hébergeant nos propres outils de communication, sans but lucratif ni hégémonique, nous espérons nous affranchir de ces nuisances et préserver nos libertés.
+ </p>
+
+ <p>Pour en savoir plus, rendez-vous sur <a href="https://www.laquadrature.net/">La Quadrature du Net</a> et allez lire le manifeste <a href="https://chatons.org/fr/manifeste">des CHATONS</a>.
+ </p>
+
+ <h2> Nos services </h2>
+ <h3>💬 Communications instantanées</h3>
+ <p>Riot est une application de communication instantanée libre, moderne et facile d'utilisation.
+ Elle utilise un protocole standard nommé Matrix vous permettant de discuter avec des personnes qui ont des comptes ailleurs que sur deuxfleurs.fr.
+ En activant le chiffrement de bout en bout, vos conversations ne seront lisible par aucun tiers (ni les administrateurs de ce service, ni votre fournisseur d'accès).
+ L'application propose aussi de la visioconférence, des discussions à plusieurs, une gestion des communautés, etc.
+ </p>
+ <p>
+ Pour vous connecter sur l'application mobile, choisissez paramètres avancés et dans serveur d'accueil changez la valeur par <samp>https://im.deuxfleurs.fr</samp>.
+ Ensuite, utilisez votre nom d'utilisateur et votre mot de passe pour vous connecter.
+ </p>
+ <p>
+ <a href="https://riot.deuxfleurs.fr">Accéder à Riot Web</a> -
+ <a href="https://play.google.com/store/apps/details?id=im.vector.app">Télécharger Riot pour Android</a> -
+ <a href="https://itunes.apple.com/gb/app/vector.im/id1083446067?mt=8">Télecharger Riot pour iOS</a>
+ </p>
+ <h3>📨 Email, Contacts, Calendrier </h3>
+ <p>
+ Nous fournissons des adresses email en <samp>@deuxfleurs.fr</samp>. Sans publicité et sans lire vos emails. Mais aussi un carnet de contact et un calendrier. Le tout synchronisable entre vos différents terminaux (ordinateur, téléphone, tablette...).
+ </p>
+ <p>
+ Pour vous connecter depuis une application email (sur mobile ou ordinateur), définissez les valeurs suivantes pour le serveur de réception. Protocole : <samp>IMAP</samp>, hôte : <samp>imap.deuxfleurs.fr</samp>, chiffrement : <samp>SSL/TLS</samp>, port : <samp>993</samp>, votre identifiant est votre adresse email, utilisez votre mot de passe normal. Pour le serveur d'envoi, utilisez les valeurs suivantes. Protocole : <samp>SMTP</samp>, hôte : <samp>smtp.deuxfleurs.fr</samp>, chiffrement : <samp>SSL/TLS</samp>, port <samp>465</samp>, votre identifiant et mot de passe sont les mêmes que pour le serveur de réception.
+ </p>
+ <p>
+ Si votre application le supporte, vous pouvez également vous connecter avec le protocole Exchange/Active-Sync qui synchronisera vos emails, votre calendrier et vos contacts. Dans ce cas, le serveur est <samp>sogo.deuxfleurs.fr</samp>. Utilisez votre email et votre mot de passe normal pour vous identifier.
+ </p>
+ <p>
+ <a href="https://sogo.deuxfleurs.fr">Accéder à Sogo Web</a> -
+ <a href="https://www.thunderbird.net/fr/">Télécharger Thunderbird pour ordinateur</a> -
+ <a href="https://play.google.com/store/apps/details?id=com.fsck.k9&hl=fr">Télécharger K9 Mail pour Android</a>
+ </p>
+ <h3>📄 Stockage de fichiers</h3>
+ <p>Seafile vous permet de créer une sauvegarde de vos fichiers sur nos machines, de les synchroniser entre vos différents terminaux (ordinateur, téléphone, tablette...) et de partager des dossiers à plusieurs pour collaborer.
+ </p>
+ <p>
+ Pour vous connecter sur l'application (mobile ou ordinateur), vous devez renseigner votre email et votre mot de passe ainsi que l'URL de l'instance : <samp>https://cloud.deuxfleurs.fr</samp>.
+ </p>
+ <p>
+ <a href="https://cloud.deuxfleurs.fr">Accéder à Seafile Web</a> -
+ <a href="https://www.seafile.com/en/download/">Télécharger Seafile pour ordinateur et mobile</a>
+ </p>
+
+ <h2>Comment nous rejoindre ?</h2>
+ <p>Si vous connaissez un utilisateur du service, contactez-le directement.<br/>
+Sinon, vous pouvez envoyer un email à <samp>*coucou</samp><img src="arobase.png" alt="arobase"><samp>deuxfleurs.fr</samp>.</p>
+ </article>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/docker/landing/html/robots.txt b/docker/landing/html/robots.txt
new file mode 100644
index 0000000..c2a49f4
--- /dev/null
+++ b/docker/landing/html/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Allow: /
diff --git a/docker/mariadb/60-disable-dialog.cnf b/docker/mariadb/60-disable-dialog.cnf
new file mode 100644
index 0000000..d41731a
--- /dev/null
+++ b/docker/mariadb/60-disable-dialog.cnf
@@ -0,0 +1,3 @@
+[mariadb]
+pam_use_cleartext_plugin
+bind-address = 0.0.0.0
diff --git a/docker/mariadb/60-ldap.cnf b/docker/mariadb/60-ldap.cnf
new file mode 100644
index 0000000..72ffb9f
--- /dev/null
+++ b/docker/mariadb/60-ldap.cnf
@@ -0,0 +1,3 @@
+[mariadb]
+plugin-load=auth_pam.so
+
diff --git a/docker/mariadb/60-remote.cnf b/docker/mariadb/60-remote.cnf
new file mode 100644
index 0000000..f759a49
--- /dev/null
+++ b/docker/mariadb/60-remote.cnf
@@ -0,0 +1,2 @@
+[mysqld]
+bind-address = 0.0.0.0
diff --git a/docker/mariadb/Dockerfile b/docker/mariadb/Dockerfile
new file mode 100644
index 0000000..15ef954
--- /dev/null
+++ b/docker/mariadb/Dockerfile
@@ -0,0 +1,14 @@
+FROM debian:stretch
+
+RUN apt-get update && \
+ apt-get dist-upgrade -y && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-client libnss-ldapd
+
+COPY 60-ldap.cnf /etc/mysql/mariadb.conf.d/60-ldap.cnf
+COPY 60-remote.cnf /etc/mysql/mariadb.conf.d/60-remote.cnf
+COPY 60-disable-dialog.cnf /etc/mysql/mariadb.conf.d/60-disable-dialog.cnf
+COPY pam-mariadb /etc/pam.d/mariadb
+COPY nsswitch.conf /etc/nsswitch.conf
+COPY entrypoint.sh /usr/local/bin/entrypoint
+
+ENTRYPOINT ["/usr/local/bin/entrypoint"]
diff --git a/docker/mariadb/README.md b/docker/mariadb/README.md
new file mode 100644
index 0000000..f20a59f
--- /dev/null
+++ b/docker/mariadb/README.md
@@ -0,0 +1,19 @@
+```
+sudo docker build -t superboum/amd64_mariadb:v2 .
+
+sudo docker run \
+ -t -i \
+ -p 3306:3306 \
+ -v /tmp/mysql:/var/lib/mysql \
+ -e LDAP_URI='ldap://bottin.service.2.cluster.deuxfleurs.fr' \
+ -e LDAP_BASE='ou=users,dc=deuxfleurs,dc=fr' \
+ -e LDAP_VERSION=3 \
+ -e LDAP_BIND_DN='cn=admin,dc=deuxfleurs,dc=fr' \
+ -e LDAP_BIND_PW='xxxx' \
+ -e MYSQL_PASSWORD='xxxx' \
+ superboum/amd64_mariadb:v1 \
+ tail -f /var/log/mysql/error.log
+
+CREATE USER quentin@localhost IDENTIFIED VIA pam USING 'mariadb';
+
+```
diff --git a/docker/mariadb/entrypoint.sh b/docker/mariadb/entrypoint.sh
new file mode 100755
index 0000000..7ebf049
--- /dev/null
+++ b/docker/mariadb/entrypoint.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+set -e
+
+cat > /etc/nslcd.conf <<EOF
+# /etc/nslcd.conf
+# nslcd configuration file. See nslcd.conf(5)
+# for details.
+
+# The user and group nslcd should run as.
+uid nslcd
+gid nslcd
+
+# The location at which the LDAP server(s) should be reachable.
+uri ${LDAP_URI}
+
+# The search base that will be used for all queries.
+base ${LDAP_BASE}
+
+# The LDAP protocol version to use.
+ldap_version ${LDAP_VERSION}
+
+# The DN to bind with for normal lookups.
+binddn ${LDAP_BIND_DN}
+bindpw ${LDAP_BIND_PW}
+
+# The DN used for password modifications by root.
+#rootpwmoddn cn=admin,dc=example,dc=com
+
+# SSL options
+#ssl off
+#tls_reqcert never
+tls_cacertfile /etc/ssl/certs/ca-certificates.crt
+
+# The search scope.
+#scope sub
+EOF
+
+/usr/sbin/nslcd
+
+chown mysql:mysql /var/lib/mysql
+[ -z "$(ls -A /var/lib/mysql)" ] && mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
+
+/usr/bin/mysqld_safe &
+
+until ls /var/run/mysqld/mysqld.sock; do sleep 1; done
+/usr/bin/mysqladmin -u root password ${MYSQL_PASSWORD} || true
+
+exec "$@"
+
diff --git a/docker/mariadb/nsswitch.conf b/docker/mariadb/nsswitch.conf
new file mode 100644
index 0000000..853348e
--- /dev/null
+++ b/docker/mariadb/nsswitch.conf
@@ -0,0 +1,21 @@
+# /etc/nsswitch.conf
+#
+# Example configuration of GNU Name Service Switch functionality.
+# If you have the `glibc-doc-reference' and `info' packages installed, try:
+# `info libc "Name Service Switch"' for information about this file.
+
+passwd: files ldap
+group: files ldap
+shadow: files ldap
+gshadow: files
+
+hosts: files dns
+networks: files
+
+protocols: db files
+services: db files
+ethers: db files
+rpc: db files
+
+netgroup: nis
+
diff --git a/docker/mariadb/pam-mariadb b/docker/mariadb/pam-mariadb
new file mode 100644
index 0000000..e1bb814
--- /dev/null
+++ b/docker/mariadb/pam-mariadb
@@ -0,0 +1,2 @@
+auth required pam_ldap.so
+account required pam_ldap.so
diff --git a/docker/matrix-synapse/Dockerfile b/docker/matrix-synapse/Dockerfile
new file mode 100644
index 0000000..459adc4
--- /dev/null
+++ b/docker/matrix-synapse/Dockerfile
@@ -0,0 +1,47 @@
+FROM amd64/debian:stretch as builder
+
+ENV VERSION 1.0.0
+
+RUN apt-get update && \
+ apt-get -qq -y full-upgrade && \
+ apt-get install -y \
+ python3 \
+ python3-pip \
+ python3-dev \
+ python3-setuptools \
+ libffi-dev \
+ build-essential \
+ libssl-dev \
+ libjpeg-dev \
+ libjpeg62-turbo-dev \
+ libxml2-dev \
+ zlib1g-dev \
+ # postgresql-dev \
+ libpq-dev \
+ virtualenv \
+ libxslt1-dev && \
+ virtualenv /root/matrix-env -p /usr/bin/python3 && \
+ . /root/matrix-env/bin/activate && \
+ pip3 install \
+ https://github.com/matrix-org/synapse/archive/v${VERSION}.tar.gz#egg=matrix-synapse[email.enable_notifs,matrix-synapse-ldap3,postgres,resources.consent,saml2,url_preview]
+
+FROM amd64/debian:stretch
+
+RUN apt-get update && \
+ apt-get -qq -y full-upgrade && \
+ apt-get install -y \
+ python3 \
+ libffi6 \
+ libjpeg62-turbo \
+ libssl1.1 \
+ libxslt1.1 \
+ libpq5 \
+ zlib1g \
+ libjemalloc1 \
+ ca-certificates
+
+ENV LD_PRELOAD /usr/lib/x86_64-linux-gnu/libjemalloc.so.1
+COPY --from=builder /root/matrix-env /root/matrix-env
+COPY entrypoint.sh /usr/local/bin/entrypoint
+
+ENTRYPOINT ["/usr/local/bin/entrypoint"]
diff --git a/docker/matrix-synapse/README.md b/docker/matrix-synapse/README.md
new file mode 100644
index 0000000..d0be64e
--- /dev/null
+++ b/docker/matrix-synapse/README.md
@@ -0,0 +1,3 @@
+```
+docker build -t superboum/amd64_synapse:v20 .
+```
diff --git a/docker/matrix-synapse/entrypoint.sh b/docker/matrix-synapse/entrypoint.sh
new file mode 100755
index 0000000..b93a702
--- /dev/null
+++ b/docker/matrix-synapse/entrypoint.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+. /root/matrix-env/bin/activate
+exec "$@"
diff --git a/docker/opendkim/Dockerfile b/docker/opendkim/Dockerfile
new file mode 100644
index 0000000..70a39e4
--- /dev/null
+++ b/docker/opendkim/Dockerfile
@@ -0,0 +1,8 @@
+FROM amd64/debian:buster
+
+RUN apt-get update && \
+ apt-get dist-upgrade -y && \
+ apt-get install -y opendkim opendkim-tools
+
+COPY ./opendkim.conf /etc/opendkim.conf
+CMD opendkim -f -v -x /etc/opendkim.conf
diff --git a/docker/opendkim/README.md b/docker/opendkim/README.md
new file mode 100644
index 0000000..e146125
--- /dev/null
+++ b/docker/opendkim/README.md
@@ -0,0 +1,12 @@
+```
+sudo docker build -t superboum/amd64_opendkim:v1 .
+```
+
+```
+sudo docker run -t -i \
+ -v `pwd`/conf:/etc/dkim \
+ -v /dev/log:/dev/log \
+ -p 8999:8999
+ superboum/amd64_opendkim:v1
+ opendkim -f -v -x /etc/opendkim.conf
+```
diff --git a/docker/opendkim/opendkim.conf b/docker/opendkim/opendkim.conf
new file mode 100644
index 0000000..0d6465f
--- /dev/null
+++ b/docker/opendkim/opendkim.conf
@@ -0,0 +1,12 @@
+Syslog yes
+SyslogSuccess yes
+LogWhy yes
+UMask 007
+Mode sv
+OversignHeaders From
+TrustAnchorFile /usr/share/dns/root.key
+KeyTable refile:/etc/dkim/keytable
+SigningTable refile:/etc/dkim/signingtable
+ExternalIgnoreList refile:/etc/dkim/trusted
+InternalHosts refile:/etc/dkim/trusted
+Socket inet:8999
diff --git a/docker/postfix/Dockerfile b/docker/postfix/Dockerfile
new file mode 100644
index 0000000..9e4c067
--- /dev/null
+++ b/docker/postfix/Dockerfile
@@ -0,0 +1,11 @@
+FROM amd64/debian:buster
+
+RUN apt-get update && \
+ apt-get install -y \
+ postfix \
+ postfix-ldap
+
+COPY entrypoint.sh /usr/local/bin/entrypoint
+
+ENTRYPOINT ["/usr/local/bin/entrypoint"]
+CMD ["postfix", "start-fg"]
diff --git a/docker/postfix/README.md b/docker/postfix/README.md
new file mode 100644
index 0000000..ac44fc0
--- /dev/null
+++ b/docker/postfix/README.md
@@ -0,0 +1,18 @@
+```
+sudo docker build -t superboum/amd64_postfix:v1 .
+```
+
+```
+sudo docker run -t -i \
+ -e TLSINFO="/C=FR/ST=Bretagne/L=Rennes/O=Deuxfleurs/CN=smtp.deuxfleurs.fr" \
+ -e MAILNAME="smtp.deuxfleurs.fr" \
+ -p 25:25 \
+ -p 465:465 \
+ -p 587:587 \
+ -v `pwd`/../../ansible/roles/container_conf/files/email/postfix-conf:/etc/postfix-conf \
+ -v /mnt/glusterfs/email/postfix-ssl/private:/etc/ssl/private \
+ -v /mnt/glusterfs/email/postfix-ssl/certs:/etc/ssl/certs \
+ superboum/amd64_postfix:v1 \
+ bash
+```
+
diff --git a/docker/postfix/entrypoint.sh b/docker/postfix/entrypoint.sh
new file mode 100755
index 0000000..c7ace3d
--- /dev/null
+++ b/docker/postfix/entrypoint.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+if [[ ! -f /etc/ssl/certs/postfix.crt || ! -f /etc/ssl/private/postfix.key ]]; then
+ cd /root
+ openssl req \
+ -new \
+ -newkey rsa:4096 \
+ -days 3650 \
+ -nodes \
+ -x509 \
+ -subj ${TLSINFO} \
+ -keyout postfix.key \
+ -out postfix.crt
+
+ mkdir -p /etc/ssl/{certs,private}/
+
+ cp postfix.crt /etc/ssl/certs/postfix.crt
+ cp postfix.key /etc/ssl/private/postfix.key
+ chmod 400 /etc/ssl/certs/postfix.crt
+ chmod 400 /etc/ssl/private/postfix.key
+fi
+
+# A way to map files inside the postfix folder :s
+for file in $(ls /etc/postfix-conf); do
+ cp /etc/postfix-conf/${file} /etc/postfix/${file}
+done
+
+echo ${MAILNAME} > /etc/mailname
+
+exec "$@"
diff --git a/docker/postgres/Dockerfile b/docker/postgres/Dockerfile
new file mode 100644
index 0000000..bb018b8
--- /dev/null
+++ b/docker/postgres/Dockerfile
@@ -0,0 +1,19 @@
+FROM amd64/debian:stretch
+
+RUN echo "deb http://deb.debian.org/debian stretch-backports main contrib non-free # available after stretch release" > /etc/apt/sources.list.d/stretch-backports.list && \
+ apt-get update && \
+ apt-get -qq -y full-upgrade && \
+ apt-get install -y postgresql-all golang-1.11 git && \
+ export GOPATH=/usr/local/go && \
+ mkdir -p /usr/local/go/src/github.com/sorintlab && \
+ cd /usr/local/go/src/github.com/sorintlab && \
+ git clone --depth=1 https://github.com/sorintlab/stolon && \
+ ln -s /usr/lib/go-1.11/bin/go /usr/bin/go && \
+ ln -s /usr/lib/go-1.11/bin/gofmt /usr/bin/gofmt && \
+ cd ./stolon && \
+ ./build && \
+ mv /usr/local/go/src/github.com/sorintlab/stolon/bin/* /usr/local/bin/ && \
+ rm -rf /usr/local/go
+
+USER postgres
+
diff --git a/docker/postgres/README.md b/docker/postgres/README.md
new file mode 100644
index 0000000..d2f7a12
--- /dev/null
+++ b/docker/postgres/README.md
@@ -0,0 +1,4 @@
+```
+docker build -t superboum/arm32v7_postgres .
+docker build -t superboum/amd64_postgres:v2 .
+```
diff --git a/docker/postgres/postgresql.conf b/docker/postgres/postgresql.conf
new file mode 100644
index 0000000..8e0af2b
--- /dev/null
+++ b/docker/postgres/postgresql.conf
@@ -0,0 +1,25 @@
+data_directory = '/var/lib/postgresql/9.6/main' # use data in another directory
+hba_file = '/etc/postgresql/9.6/main/pg_hba.conf' # host-based authentication file
+ident_file = '/etc/postgresql/9.6/main/pg_ident.conf' # ident configuration file
+external_pid_file = '/var/run/postgresql/9.6-main.pid' # write an extra PID file
+listen_addresses = '*' #listen on every ip / interfaces
+port = 5432 # (change requires restart)
+max_connections = 100 # (change requires restart)
+unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories
+ssl = true # (change requires restart)
+ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' # (change requires restart)
+ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' # (change requires restart)
+shared_buffers = 128MB # min 128kB
+dynamic_shared_memory_type = posix # the default is the first option
+log_line_prefix = '%m [%p] %q%u@%d ' # special values:
+log_timezone = 'UTC'
+cluster_name = '9.6/main' # added to process titles if nonempty
+stats_temp_directory = '/var/run/postgresql/9.6-main.pg_stat_tmp'
+datestyle = 'iso, mdy'
+timezone = 'UTC'
+lc_messages = 'C.UTF-8' # locale for system error message
+lc_monetary = 'C.UTF-8' # locale for monetary formatting
+lc_numeric = 'C.UTF-8' # locale for number formatting
+lc_time = 'C.UTF-8' # locale for time formatting
+default_text_search_config = 'pg_catalog.english'
+
diff --git a/docker/postgres/start.sh b/docker/postgres/start.sh
new file mode 100755
index 0000000..f1d493f
--- /dev/null
+++ b/docker/postgres/start.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+if [ -f /local/pg_hba.conf ]; then
+ echo "Copying Nomad configuration..."
+ cp /local/pg_hba.conf /etc/postgresql/9.6/main/
+ echo "Done"
+fi
+
+
+if [ -z "$(ls -A /var/lib/postgresql/9.6/main)" ]; then
+ echo "Copying base"
+ cp -r /var/lib/postgresql/9.6/base/* /var/lib/postgresql/9.6/main
+ echo "Done"
+fi
+
+chmod -R 700 /var/lib/postgresql/9.6/main
+chown -R postgres /var/lib/postgresql/9.6/main
+
+echo "Starting postgres..."
+. /usr/share/postgresql-common/init.d-functions
+start 9.6
+tail -f /var/log/postgresql/postgresql-9.6-main.log
diff --git a/docker/riotweb/Dockerfile b/docker/riotweb/Dockerfile
new file mode 100644
index 0000000..f3528a1
--- /dev/null
+++ b/docker/riotweb/Dockerfile
@@ -0,0 +1,13 @@
+FROM amd64/debian:stretch as builder
+
+WORKDIR /root
+ENV VERSION v1.1.2
+
+RUN apt-get update && \
+ apt-get install -y wget && \
+ wget https://github.com/vector-im/riot-web/releases/download/${VERSION}/riot-${VERSION}.tar.gz && \
+ tar xf riot-${VERSION}.tar.gz && \
+ mv riot-${VERSION}/ riot/
+
+FROM superboum/amd64_webserver:v3
+COPY --from=builder /root/riot /srv/http
diff --git a/docker/riotweb/README.md b/docker/riotweb/README.md
new file mode 100644
index 0000000..4949dd2
--- /dev/null
+++ b/docker/riotweb/README.md
@@ -0,0 +1,4 @@
+```
+sudo docker build -t superboum/amd64_riotweb:v4 .
+sudo docker push superboum/amd64_riotweb:v4
+```
diff --git a/docker/riotweb/config.json b/docker/riotweb/config.json
new file mode 100644
index 0000000..8ce8e4c
--- /dev/null
+++ b/docker/riotweb/config.json
@@ -0,0 +1,24 @@
+{
+ "default_hs_url": "https://im.deuxfleurs.fr",
+ "default_is_url": "https://vector.im",
+ "disable_custom_urls": false,
+ "disable_guests": false,
+ "disable_login_language_selector": false,
+ "disable_3pid_login": false,
+ "brand": "Deuxfleurs",
+ "integrations_ui_url": "https://scalar.vector.im/",
+ "integrations_rest_url": "https://scalar.vector.im/api",
+ "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
+ "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
+ "features": {
+ "feature_groups": "labs",
+ "feature_pinning": "labs"
+ },
+ "default_federate": true,
+ "welcomePageUrl": "home.html",
+ "default_theme": "light",
+ "roomDirectory": {
+ "servers": [ "im.deuxfleurs.fr", "matrix.org" ]
+ }
+}
+
diff --git a/docker/seafile/Dockerfile b/docker/seafile/Dockerfile
new file mode 100644
index 0000000..b2b5849
--- /dev/null
+++ b/docker/seafile/Dockerfile
@@ -0,0 +1,45 @@
+FROM amd64/debian:stretch as builder
+
+ENV VERSION 6.3.4
+
+RUN apt-get update && \
+ apt-get dist-upgrade -y && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y wget tar && \
+ wget https://download.seadrive.org/seafile-server_${VERSION}_x86-64.tar.gz -O ./seafile.tar.gz && \
+ tar xf ./seafile.tar.gz && \
+ mv seafile-server-${VERSION} seafile-server
+
+FROM debian:buster
+
+COPY --from=builder ./seafile-server /srv/webstore/seafile-server
+
+RUN apt-get update && \
+ apt-get dist-upgrade -y && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y \
+ python \
+ mariadb-client \
+ python2.7 \
+ libpython2.7 \
+ python-setuptools \
+ python-ldap \
+ python-urllib3 \
+ ffmpeg \
+ python-pip \
+ python-mysqldb \
+ python-memcache \
+ procps \
+ python-requests && \
+ pip install Pillow==4.3.0 && \
+ pip install moviepy && \
+ useradd -u 1000 -d /srv/webstore seauser && \
+ chown -R seauser:1000 /srv/webstore/ && \
+ mkdir -p /usr/lib64/mysql/plugin/ && \
+ ln -s /usr/lib/x86_64-linux-gnu/mariadb*/plugin/mysql_clear_password.so /usr/lib64/mysql/plugin/ && \
+ ln -s /usr/lib/x86_64-linux-gnu/mariadb*/plugin/dialog.so /usr/lib64/mysql/plugin/
+
+WORKDIR /srv/webstore/seafile-server
+COPY seadocker /usr/local/bin/seadocker
+COPY seaenv /usr/local/bin/seaenv
+
+ENTRYPOINT ["/usr/local/bin/seaenv"]
+CMD ["/usr/local/bin/seadocker"]
diff --git a/docker/seafile/README.md b/docker/seafile/README.md
new file mode 100644
index 0000000..d92c531
--- /dev/null
+++ b/docker/seafile/README.md
@@ -0,0 +1,11 @@
+
+```
+sudo docker build -t superboum/amd64_seafile:v4 .
+
+sudo docker run -t -i \
+ -v /mnt/glusterfs/seafile:/mnt/seafile-data \
+ -v /mnt/glusterfs/seaconf/conf:/srv/webstore/conf \
+ -v /mnt/glusterfs/seaconf/ccnet:/srv/webstore/ccnet \
+ superboum/amd64_seafile:v4
+```
+
diff --git a/docker/seafile/seadocker b/docker/seafile/seadocker
new file mode 100755
index 0000000..5b5982b
--- /dev/null
+++ b/docker/seafile/seadocker
@@ -0,0 +1,4 @@
+#!/bin/bash
+/srv/webstore/seafile-server/seafile.sh start
+/srv/webstore/seafile-server/seahub.sh start
+tail -f /srv/webstore/logs/*
diff --git a/docker/seafile/seaenv b/docker/seafile/seaenv
new file mode 100755
index 0000000..3b0e0bb
--- /dev/null
+++ b/docker/seafile/seaenv
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+chown seauser /srv/webstore
+chown seauser -R /srv/webstore/ccnet
+chown seauser -R /srv/webstore/conf
+
+runuser -u seauser -- "$@"
diff --git a/docker/sogo/Dockerfile b/docker/sogo/Dockerfile
new file mode 100644
index 0000000..57965c4
--- /dev/null
+++ b/docker/sogo/Dockerfile
@@ -0,0 +1,17 @@
+#FROM amd64/debian:stretch as builder
+
+FROM amd64/debian:stretch
+
+RUN mkdir ~/.gnupg && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf
+
+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 && \
+ apt-get update && \
+ apt-get install -y sogo sogo-activesync sope4.9-gdl1-postgresql postgresql-client
+
+COPY sogo.nginx.conf /etc/nginx/sites-enabled/sogo.conf
+COPY entrypoint /usr/sbin/entrypoint
+ENTRYPOINT ["/usr/sbin/entrypoint"]
diff --git a/docker/sogo/README.md b/docker/sogo/README.md
new file mode 100644
index 0000000..ea12245
--- /dev/null
+++ b/docker/sogo/README.md
@@ -0,0 +1,20 @@
+```
+docker build -t superboum/amd64_sogo:v6 .
+
+# privileged is only for debug
+docker run --rm -ti \
+ --privileged \
+ -p 8080:8080 \
+ -v /tmp/sogo/log:/var/log/sogo \
+ -v /tmp/sogo/run:/var/run/sogo \
+ -v /tmp/sogo/spool:/var/spool/sogo \
+ -v /tmp/sogo/tmp:/tmp \
+ -v `pwd`/sogo:/etc/sogo:ro \
+ superboum/amd64_sogo:v1
+```
+
+Password must be url encoded in sogo.conf for postgres
+Will need a nginx instance: http://wiki.sogo.nu/nginxSettings
+
+Might (or might not) be needed:
+traefik.frontend.headers.customRequestHeaders=x-webobjects-server-port:443||x-webobjects-server-name=sogo.deuxfleurs.fr||x-webobjects-server-url:https://sogo.deuxfleurs.fr
diff --git a/docker/sogo/entrypoint b/docker/sogo/entrypoint
new file mode 100755
index 0000000..8b39def
--- /dev/null
+++ b/docker/sogo/entrypoint
@@ -0,0 +1,13 @@
+#!/bin/bash
+mkdir -p /var/log/sogo
+mkdir -p /var/run/sogo
+mkdir -p /var/spool/sogo
+chown sogo /var/log/sogo
+chown sogo /var/run/sogo
+chown sogo /var/spool/sogo
+
+nginx -g 'daemon on; master_process on;'
+sudo -u sogo memcached -d
+sudo -u sogo sogod
+sleep 10
+tail -n200 -f /var/log/sogo/sogo.log
diff --git a/docker/static/Dockerfile b/docker/static/Dockerfile
new file mode 100644
index 0000000..cdba59a
--- /dev/null
+++ b/docker/static/Dockerfile
@@ -0,0 +1,9 @@
+FROM golang:1.11.1-stretch as builder
+
+COPY ./goStatic /goStatic
+WORKDIR /goStatic
+RUN CGO_ENABLED=0 go build -a -o web-server .
+
+FROM scratch
+COPY --from=builder /goStatic/web-server /
+ENTRYPOINT ["/web-server"]
diff --git a/docker/static/README.md b/docker/static/README.md
new file mode 100644
index 0000000..d50390c
--- /dev/null
+++ b/docker/static/README.md
@@ -0,0 +1,5 @@
+
+```
+sudo docker build -t superboum/amd64_webserver:v3 .
+sudo docker push superboum/amd64_webserver:v3
+```
diff --git a/docker/static/goStatic b/docker/static/goStatic
new file mode 160000
+Subproject 3f97f57aaee09a142afe3ca0f1a5d51acd85643
diff --git a/docker/tag-config/.gitignore b/docker/tag-config/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/docker/tag-config/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/docker/tag-config/README.md b/docker/tag-config/README.md
new file mode 100644
index 0000000..0746388
--- /dev/null
+++ b/docker/tag-config/README.md
@@ -0,0 +1,22 @@
+```
+npm install
+npm test
+```
+
+You will probably need to run consul in parallel:
+
+```
+consul agent -dev
+```
+
+You can register services like that:
+
+```
+consul services register -name=toto -tag="public_port=4848"
+```
+
+You will need some arguments to run the software:
+
+```
+sudo npm start node=rincevent ipt_base=./static.iptables
+```
diff --git a/docker/tag-config/index.mjs b/docker/tag-config/index.mjs
new file mode 100644
index 0000000..a5b51fc
--- /dev/null
+++ b/docker/tag-config/index.mjs
@@ -0,0 +1,56 @@
+'use strict'
+import consul from 'consul'
+import { exec } from './src/io/run.mjs'
+import { readFile } from './src/io/files.mjs'
+
+import ctlg_consul from './src/catalog/consul.mjs'
+import inj_iptables from './src/injector/iptables.mjs'
+
+const get_args = () => process
+ .argv
+ .slice(2)
+ .map(a => a.split('='))
+ .reduce((dict, tuple) => {
+ dict[tuple[0]] = tuple.length > 1 ? tuple[1] : null
+ return dict
+ }, {})
+
+/**
+ * If we have multiple catalogs
+ * we cache the results of the other ones
+ */
+function* notifications_aggregator(injectors) {
+ const states = []
+ for(let idx = 0; true; idx++) {
+ yield async (tag_list) => {
+ states[idx] = tag_list
+ await Promise.all(
+ injectors.map(notify =>
+ notify(states.reduce((acc, tag) => [...acc, ...tag], []))))
+ }
+ }
+}
+
+const main = async () => {
+ try {
+ const args = get_args()
+
+ // Initialize all injectors
+ const injectors = [
+ await inj_iptables(args.ipt_base, readFile, exec, console.log)
+ ]
+
+ // Initialize all catalogs and map them to the injectors
+ const aggr = notifications_aggregator(injectors)
+ const catalogs = [
+ await ctlg_consul(args.node, consul(), console.log, aggr.next().value)
+ ]
+
+ console.log("[main] initialized")
+ } catch(e) {
+ console.error("initialization failed", e)
+ process.exit(1)
+ }
+}
+
+main()
diff --git a/docker/tag-config/package-lock.json b/docker/tag-config/package-lock.json
new file mode 100644
index 0000000..a4d30b9
--- /dev/null
+++ b/docker/tag-config/package-lock.json
@@ -0,0 +1,74 @@
+{
+ "name": "consul-to-igd",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "dev": true
+ },
+ "chai": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+ "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+ "dev": true,
+ "requires": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.2",
+ "deep-eql": "^3.0.1",
+ "get-func-name": "^2.0.0",
+ "pathval": "^1.1.0",
+ "type-detect": "^4.0.5"
+ }
+ },
+ "check-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+ "dev": true
+ },
+ "consul": {
+ "version": "0.34.1",
+ "resolved": "https://registry.npmjs.org/consul/-/consul-0.34.1.tgz",
+ "integrity": "sha512-xCLBzPQBgnDgC2LdYnrT/Fc6PglRU6u7EBkpW0ExAx3Am/CdtKcP5o/3jfwOy7PBAwBqnJk3AYdwwGg+arriiQ==",
+ "requires": {
+ "papi": "^0.29.0"
+ }
+ },
+ "deep-eql": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "^4.0.0"
+ }
+ },
+ "get-func-name": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+ "dev": true
+ },
+ "papi": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/papi/-/papi-0.29.1.tgz",
+ "integrity": "sha512-Y9ipSMfWuuVFO3zY9PlxOmEg+bQ7CeJ28sa9/a0veYNynLf9fwjR3+3fld5otEy7okUaEOUuCHVH62MyTmACXQ=="
+ },
+ "pathval": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+ "dev": true
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ }
+ }
+}
diff --git a/docker/tag-config/package.json b/docker/tag-config/package.json
new file mode 100644
index 0000000..892fb87
--- /dev/null
+++ b/docker/tag-config/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "consul-to-igd",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.mjs",
+ "dependencies": {
+ "consul": "^0.34.1"
+ },
+ "devDependencies": {
+ "chai": "^4.2.0"
+ },
+ "scripts": {
+ "start": "node --experimental-modules ./index.mjs",
+ "test": "node --experimental-modules ./test/runner.mjs"
+ },
+ "author": "Quentin",
+ "license": "AGPL-3.0-or-later"
+}
diff --git a/docker/tag-config/src/catalog/consul.mjs b/docker/tag-config/src/catalog/consul.mjs
new file mode 100644
index 0000000..655c61f
--- /dev/null
+++ b/docker/tag-config/src/catalog/consul.mjs
@@ -0,0 +1,30 @@
+'use strict'
+
+let l
+export default l = async (node, consul, log, notify) => {
+ const watch = consul.watch({ method: consul.catalog.node.services, options: {node: node}})
+
+ const extract_tags = data =>
+ data ?
+ Object
+ .keys(data.Services)
+ .map(k => data.Services[k].Tags)
+ .reduce((acc, v) => [...acc, ...v], []) :
+ []
+
+ watch.on('error', err => {
+ console.error('error', err)
+ })
+
+ watch.on('change', async (data, res) => {
+ try {
+ const tags = extract_tags(data)
+ log(`[consul] new update, detected ${tags.length} tags`)
+ await notify(tags)
+ } catch(e) {
+ console.error('failed to notify target', e)
+ }
+ })
+
+ log('[consul] initialized')
+}
diff --git a/docker/tag-config/src/injector/iptables.mjs b/docker/tag-config/src/injector/iptables.mjs
new file mode 100644
index 0000000..584b560
--- /dev/null
+++ b/docker/tag-config/src/injector/iptables.mjs
@@ -0,0 +1,53 @@
+'use strict'
+
+let l;
+export default l = async (path, readFile, exec, log) => {
+
+ const load_static_rules = async path =>
+ (await readFile(path, 'utf-8'))
+ .split('\n')
+ .filter(e => e)
+
+ const get_current_rules = async () =>
+ (await exec('iptables -S INPUT'))
+ .stdout
+ .split('\n')
+ .filter(e => e.match(/^-A INPUT/g))
+
+ const compute_rules_to_add = (current, target) =>
+ target.filter(r => !current.includes(r))
+
+ const compute_rules_to_del = (current, target) =>
+ current
+ .filter(r => !target.includes(r))
+ .map(r => r.replace(/^-A INPUT/g, '-D INPUT'))
+
+ const update_rules = async (current, target) =>
+ await Promise.all([
+ ...compute_rules_to_del(current, target),
+ ...compute_rules_to_add(current, target)
+ ].map(r => exec(`iptables ${r}`)))
+
+ const build_target_rules = (tag_list) =>
+ tag_list
+ .map(t => /^public_port=(\d+)(-(\d+))?\/(udp|tcp)/g.exec(t))
+ .filter(t => t)
+ .map(t => new Object({ start: t[1], stop: t[3], protocol: t[4] }))
+ .map(t => t.stop
+ ? `-A INPUT -p ${t.protocol} --match multiport --dports ${t.start}:${t.stop} -j ACCEPT`
+ : `-A INPUT -p ${t.protocol} --dport ${t.start} -j ACCEPT`)
+
+ const do_log = (tag_list, r) => {
+ //log('[iptables]', tag_list)
+ log(`[iptables] ran ${r.length} commands`)
+ }
+
+ const static_rules = path ? await load_static_rules(path) : []
+ log(`[iptables] initialized with ${static_rules.length} static rules`)
+ return async tag_list =>
+ do_log(
+ tag_list,
+ await update_rules(
+ await get_current_rules(),
+ [...static_rules, ...build_target_rules(tag_list)]))
+}
diff --git a/docker/tag-config/src/injector/upnp.mjs b/docker/tag-config/src/injector/upnp.mjs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docker/tag-config/src/injector/upnp.mjs
diff --git a/docker/tag-config/src/io/files.mjs b/docker/tag-config/src/io/files.mjs
new file mode 100644
index 0000000..c3eca1b
--- /dev/null
+++ b/docker/tag-config/src/io/files.mjs
@@ -0,0 +1,8 @@
+'use strict'
+
+import fs from 'fs'
+
+export const readFile = (file, opts) =>
+ new Promise((resolve, reject) =>
+ fs.readFile(file, opts, (err, data) =>
+ err ? reject(err) : resolve(data)))
diff --git a/docker/tag-config/src/io/run.mjs b/docker/tag-config/src/io/run.mjs
new file mode 100644
index 0000000..8774043
--- /dev/null
+++ b/docker/tag-config/src/io/run.mjs
@@ -0,0 +1,9 @@
+'use strict'
+
+import child_process from 'child_process'
+
+export const exec = (cmd, opts) =>
+ new Promise((resolve, reject) =>
+ child_process.exec(cmd, opts, (error, stdout, stderr) =>
+ error ? reject({err: error, stdout: stdout, stderr: stderr}) : resolve({stdout: stdout, stderr: stderr})))
+
diff --git a/docker/tag-config/static.iptables b/docker/tag-config/static.iptables
new file mode 100644
index 0000000..d9e7d38
--- /dev/null
+++ b/docker/tag-config/static.iptables
@@ -0,0 +1,10 @@
+-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+-A INPUT -i docker0 -j ACCEPT
+-A INPUT -s 127.0.0.0/8 -j ACCEPT
+-A INPUT -s 192.168.1.2/32 -j ACCEPT
+-A INPUT -s 192.168.1.3/32 -j ACCEPT
+-A INPUT -s 192.168.1.4/32 -j ACCEPT
+-A INPUT -p udp -m udp --dport 53 -j ACCEPT
+-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
+-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
+-A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
diff --git a/docker/tag-config/test/io.mjs b/docker/tag-config/test/io.mjs
new file mode 100644
index 0000000..d88ad15
--- /dev/null
+++ b/docker/tag-config/test/io.mjs
@@ -0,0 +1,10 @@
+import chai from 'chai'
+import { readFile } from '../src/io/files.mjs'
+const expect = chai.expect
+
+export default [
+ (async () => {
+ const dirname = import.meta.url.replace(/^file:\/\//g, '').replace(/io.mjs$/g, '')
+ expect(await readFile(`${dirname}/../package.json`, 'utf-8')).to.include('Quentin')
+ })
+]
diff --git a/docker/tag-config/test/iptables.mjs b/docker/tag-config/test/iptables.mjs
new file mode 100644
index 0000000..1ae1cb0
--- /dev/null
+++ b/docker/tag-config/test/iptables.mjs
@@ -0,0 +1,28 @@
+'use strict'
+
+import chai from 'chai'
+import iptables from '../src/injector/iptables.mjs'
+const expect = chai.expect
+
+export default [
+ (async () => {
+ const effective_actions = []
+ const expected_actions = [
+ 'iptables -A INPUT -p tcp --dport 56 -j ACCEPT',
+ 'iptables -A INPUT -p tcp --dport 53 -j ACCEPT',
+ 'iptables -A INPUT -p udp --match multiport --dports 25630:25999 -j ACCEPT',
+ 'iptables -D INPUT -p tcp --dport 54 -j ACCEPT'
+ ]
+
+ const mockLog = () => {}
+ const mockReadFile = (file, opt) => '-A INPUT -p tcp --dport 53 -j ACCEPT'
+ const mockExecCommand = (cmd, opts) => {
+ if (cmd.match(/^iptables -S/g)) return { stdout: '-A INPUT -p tcp --dport 54 -j ACCEPT' }
+ else effective_actions.push(cmd)
+ return { stdout: '' } }
+
+ const fw = await iptables('static', mockReadFile, mockExecCommand, mockLog)
+ await fw(['public_port=56/tcp', 'public_port=25630-25999/udp', 'public_port=13', 'traefik.entrypoints=Host:im.deuxfleurs.fr;PathPrefix:/_matrix'])
+ expect(effective_actions).to.have.members(expected_actions)
+ })
+]
diff --git a/docker/tag-config/test/runner.mjs b/docker/tag-config/test/runner.mjs
new file mode 100644
index 0000000..b4da1de
--- /dev/null
+++ b/docker/tag-config/test/runner.mjs
@@ -0,0 +1,28 @@
+'use strict'
+
+import io from './io.mjs'
+import iptables from './iptables.mjs'
+
+(async () => {
+ const res = await [
+ ...io,
+ ...iptables
+ ].map(async f => {
+ try {
+ await f()
+ return 'passed'
+ }
+ catch(e) {
+ console.error(e)
+ return 'failed'
+ }
+ }).reduce(async (acc, r) => {
+ const accumulator = await acc
+ const result = await r
+ accumulator.total++
+ accumulator[result]++
+ return accumulator
+ }, {total: 0, passed: 0, failed: 0})
+
+ console.log(`Done. passed: ${res.passed}, failed: ${res.failed}, total: ${res.total}`)
+})()