diff --git a/seed/base-machine/manual/install/diff.py b/seed/base-machine/manual/install/diff.py
index 510dcc5d..b2030863 100755
--- a/seed/base-machine/manual/install/diff.py
+++ b/seed/base-machine/manual/install/diff.py
@@ -1,12 +1,11 @@
#!/usr/bin/env python3
-from os.path import join
from filecmp import dircmp
from difflib import unified_diff
from sys import stdout, argv
from os import walk
-from os.path import join
+from os.path import join, islink
from datetime import datetime, timezone
@@ -87,10 +86,13 @@ for filename in old - new:
for filename in new - old:
- print(f'\n- fichier {filename} ajouté :\n')
- with open(join(NEW_DIR, filename), 'r') as fh:
- if WEBSITE:
- print('```')
- print(fh.read())
- if WEBSITE:
- print('```')
+ if islink(join(NEW_DIR, filename)):
+ print(f'\n- lien {filename} ajouté\n')
+ else:
+ print(f'\n- fichier {filename} ajouté :\n')
+ with open(join(NEW_DIR, filename), 'r') as fh:
+ if WEBSITE:
+ print('```')
+ print(fh.read())
+ if WEBSITE:
+ print('```')
diff --git a/seed/base-machine/manual/install/install_machines b/seed/base-machine/manual/install/install_machines
index f053a5f4..82388f32 100755
--- a/seed/base-machine/manual/install/install_machines
+++ b/seed/base-machine/manual/install/install_machines
@@ -14,7 +14,7 @@ for image in *; do
if [ -f "host/configurations/$HOST_NAME/etc/systemd/nspawn/$osname.nspawn" ]; then
MACHINES="$MACHINES$osname "
fi
- echo
+ echo
echo "Install machine $image"
./install_machine "$HOST_NAME" "$image" "$osname"
fi
@@ -23,5 +23,39 @@ for image in *; do
done
machinectl enable $MACHINES
machinectl start $MACHINES
+STARTED=""
+DEGRADED=""
+found=true
+idx=0
+while [ $found = true ]; do
+ found=false
+ echo "tentative $idx"
+ for machine in $MACHINES; do
+ if ! echo $STARTED | grep -q " $machine "; then
+ status=$(machinectl -q shell $machine /usr/bin/systemctl is-system-running || true)
+ if echo "$status" | grep -q degraded; then
+ STARTED="$STARTED $machine "
+ DEGRADED="$DEGRADED $machine"
+ elif echo "$status" | grep -q running; then
+ STARTED="$STARTED $machine "
+ else
+ found=true
+ echo "status actuel de $machine : $status"
+ fi
+ fi
+ done
+ sleep 2
+ idx=$((idx+1))
+ if [ $idx = 60 ]; then
+ break
+ fi
+done
+retcode=0
+for machine in $DEGRADED; do
+ echo
+ echo "========= $machine"
+ machinectl -q shell $machine /usr/bin/systemctl --state=failed --no-legend --no-pager
+ retcode=1
+done
-exit 0
+exit $retcode
diff --git a/seed/base-machine/tests/execute.py b/seed/base-machine/tests/execute.py
index 7b9cb08b..76747d75 100644
--- a/seed/base-machine/tests/execute.py
+++ b/seed/base-machine/tests/execute.py
@@ -2,12 +2,14 @@ from os import fdopen
from dbus import SystemBus, Array
-def run(host, cmd):
+def run(host, cmd, user=None):
bus = SystemBus()
remote_object = bus.get_object('org.freedesktop.machine1',
'/org/freedesktop/machine1',
False,
)
+ if user is not None:
+ cmd = ['/bin/su', '-', user, '-s', '/bin/bash', '-c', ' '.join(cmd)]
res = remote_object.OpenMachineShell(host,
'',
cmd[0],
diff --git a/seed/dovecot/dictionaries/26_dovecot.xml b/seed/dovecot/dictionaries/26_dovecot.xml
index 05e555eb..89a55027 100644
--- a/seed/dovecot/dictionaries/26_dovecot.xml
+++ b/seed/dovecot/dictionaries/26_dovecot.xml
@@ -18,7 +18,7 @@
- /etc/nginx/conf.d/autoconfig.conf
+ /etc/nginx/default.d/autoconfig.conf
well_known_filenames
@@ -90,8 +90,8 @@
-
- False
+
+ /var/www/html
diff --git a/seed/dovecot/templates/autoconfig.conf b/seed/dovecot/templates/autoconfig.conf
index 8be4082e..c4faeebb 100644
--- a/seed/dovecot/templates/autoconfig.conf
+++ b/seed/dovecot/templates/autoconfig.conf
@@ -1,12 +1,2 @@
-server {
- listen 443 ssl;
- server_name %%domain_name_eth0;
-
- ssl_client_certificate %%revprox_ca_file;
- ssl_certificate %%revprox_cert_file;
- ssl_certificate_key %%revprox_key_file;
-
- root /var/www/html/;
- # To allow POST on static pages
- error_page 405 =200 $uri;
-}
+# To allow POST on static pages
+error_page 405 =200 $uri;
diff --git a/seed/dovecot/templates/dovecot-init.service b/seed/dovecot/templates/dovecot-init.service
index b4f9cecd..1df2ef4f 100644
--- a/seed/dovecot/templates/dovecot-init.service
+++ b/seed/dovecot/templates/dovecot-init.service
@@ -1,5 +1,5 @@
[Unit]
-After=network.target
+After=risotto.target
[Service]
ExecStart=
diff --git a/seed/gitea/templates/gitea.service b/seed/gitea/templates/gitea.service
index 9f19bf7b..abb4929c 100644
--- a/seed/gitea/templates/gitea.service
+++ b/seed/gitea/templates/gitea.service
@@ -1,7 +1,7 @@
#ORIGIN https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/systemd/gitea.service
[Unit]
Description=Gitea (Git with a cup of tea)
-After=network.target postgresqlclient.service
+After=risotto.target
[Service]
# Modify these two values and uncomment them if you have
diff --git a/seed/ldap-client/dictionaries/21_ldap-client.xml b/seed/ldap-client/dictionaries/21_ldap-client.xml
index ac1ce2f4..b0835e48 100644
--- a/seed/ldap-client/dictionaries/21_ldap-client.xml
+++ b/seed/ldap-client/dictionaries/21_ldap-client.xml
@@ -2,7 +2,7 @@
-
+
ldap_client_file
ldap_ca_file
ldap_cert_file
diff --git a/seed/ldap-client/templates/ldap-client.service b/seed/ldap-client/templates/ldap-client.service
new file mode 100644
index 00000000..6cbf68c8
--- /dev/null
+++ b/seed/ldap-client/templates/ldap-client.service
@@ -0,0 +1,8 @@
+[Unit]
+After=network-online.target
+Before=risotto.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/timeout 90 bash -c 'while ! 3<> /dev/tcp/%%ldap_server_address/%%ldap_port; do sleep 1; done'
+
diff --git a/seed/lemonldap/dictionaries/70_lemonldap_ng.xml b/seed/lemonldap/dictionaries/70_lemonldap_ng.xml
index 37b7de86..d5b9eea9 100644
--- a/seed/lemonldap/dictionaries/70_lemonldap_ng.xml
+++ b/seed/lemonldap/dictionaries/70_lemonldap_ng.xml
@@ -25,10 +25,10 @@
+
False
-
diff --git a/seed/lemonldap/templates/lemonldap-ng-fastcgi-server.service b/seed/lemonldap/templates/lemonldap-ng-fastcgi-server.service
index f61277e7..adbfcf36 100644
--- a/seed/lemonldap/templates/lemonldap-ng-fastcgi-server.service
+++ b/seed/lemonldap/templates/lemonldap-ng-fastcgi-server.service
@@ -1,7 +1,6 @@
[Unit]
-After=nginx.service
+After=risotto.target nginx.service
[Service]
-ExecStartPre=/usr/bin/timeout 90 bash -c 'while ! 3<> /dev/tcp/%%ldap_server_address/%%ldap_port; do sleep 1; done'
ExecStartPost=-/usr/bin/timeout 10 bash -c 'while ! /usr/local/lib/sbin/interne_well_known.pl > /var/www/html/.well-known/openid-configuration/int; do sleep 1; done'
ExecStartPost=-/bin/bash -c '/usr/local/lib/sbin/interne_well_known.pl no > /var/www/html/.well-known/openid-configuration/ext'
diff --git a/seed/lemonldap/templates/wget.pl b/seed/lemonldap/templates/wget.pl
index b46dc4b7..ca4eda78 100644
--- a/seed/lemonldap/templates/wget.pl
+++ b/seed/lemonldap/templates/wget.pl
@@ -1,7 +1,6 @@
%echo "#!/usr/bin/env perl"
use HTTP::Tiny;
-use JSON qw(from_json to_json);
my $response = HTTP::Tiny->new->get('https://%%domain_name_eth0/.well-known/openid-configuration');
diff --git a/seed/mailman/applicationservice.yml b/seed/mailman/applicationservice.yml
index 769c5867..17e1ec58 100644
--- a/seed/mailman/applicationservice.yml
+++ b/seed/mailman/applicationservice.yml
@@ -5,5 +5,5 @@ depends:
- postgresql-client
- relay-lmtp-client
- reverse-proxy-client
- - nginx-common
+ - nginx-https
- oauth2-client
diff --git a/seed/mailman/dictionaries/31_mailman.xml b/seed/mailman/dictionaries/31_mailman.xml
index b7055029..575e133e 100644
--- a/seed/mailman/dictionaries/31_mailman.xml
+++ b/seed/mailman/dictionaries/31_mailman.xml
@@ -11,8 +11,9 @@
/etc/postorius/gunicorn_config.py
/sysusers.d/0postorius.conf
- /etc/nginx/conf.d/postorius.conf
+ /etc/nginx/default.d/postorius.conf
/etc/mailman3.d/postorius.py
+ /tests/mailman.yml
/etc/pki/tls/private/postgresql_postorius.key
@@ -47,6 +48,11 @@
+
+
+ /usr/share/webapps/postorius
+
+
mailman
diff --git a/seed/mailman/extras/mailman/20_mailman.xml b/seed/mailman/extras/mailman/20_mailman.xml
index 97066c77..37e46c9a 100644
--- a/seed/mailman/extras/mailman/20_mailman.xml
+++ b/seed/mailman/extras/mailman/20_mailman.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/seed/mailman/funcs/mailman.py b/seed/mailman/funcs/mailman.py
index 07372bc5..66b633d4 100644
--- a/seed/mailman/funcs/mailman.py
+++ b/seed/mailman/funcs/mailman.py
@@ -1,20 +1,18 @@
from risotto.utils import multi_function as _multi_function
-from itertools import chain
-@_multi_function
def mailman_emails(lists, domain):
- ret = []
- for lst in lists:
- for suffix in [None, 'bounces(\+.*)?', 'confirm(\+.*)?', 'join', 'leave', 'owner', 'request', 'subscribe', 'unsubscribe']:
- if suffix:
- lst_name = lst + '-' + suffix
- else:
- lst_name = lst
- ret.append(lst_name + '@' + domain)
- return ret
+ return '.*@' + domain
+# ret = []
+# for lst in lists:
+# for suffix in [None, 'bounces(\+.*)?', 'confirm(\+.*)?', 'join', 'leave', 'owner', 'request', 'subscribe', 'unsubscribe']:
+# if suffix:
+# lst_name = lst + '-' + suffix
+# else:
+# lst_name = lst
+# ret.append(lst_name + '@' + domain)
+# return ret
@_multi_function
def mailman_concat(lists):
- # list of lists to a single list
- return list(chain(*lists))
+ return lists
diff --git a/seed/mailman/templates/config-nginx.conf b/seed/mailman/templates/config-nginx.conf
index 5c928d74..56b07475 100644
--- a/seed/mailman/templates/config-nginx.conf
+++ b/seed/mailman/templates/config-nginx.conf
@@ -1,42 +1,31 @@
-server {
- listen 443 ssl;
- server_name %%domain_name_eth0;
-
- ssl_client_certificate %%revprox_ca_file;
- ssl_certificate %%revprox_cert_file;
- ssl_certificate_key %%revprox_key_file;
-
- charset utf-8;
- client_max_body_size 75M;
- root /usr/share/webapps/postorius;
-
- location /mailman/postorius_static {
- alias /usr/lib/python3.10/site-packages/postorius/static;
- }
- #FIXME user-profile seems to be in hyperkitty redirect in existing page
- location /mailman/user-profile {
- proxy_pass http://127.0.0.1:8002/postorius/users;
- proxy_set_header Host $http_host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Forwarded-Port $server_port;
- proxy_set_header X-Forwarded-Server $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
-%for %%location in ['accounts', 'admin', 'postorius']
- location /mailman/%%location {
- proxy_pass http://127.0.0.1:8002/%%location;
- proxy_set_header Host $http_host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Forwarded-Port $server_port;
- proxy_set_header X-Forwarded-Server $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
-%end for
- location /mailman {
- rewrite ^(/mailman/.*)$ /mailman/postorius/ permanent;
- }
+charset utf-8;
+client_max_body_size 75M;
+location /mailman/postorius_static {
+ alias /usr/lib/python3.10/site-packages/postorius/static;
+}
+#FIXME user-profile seems to be in hyperkitty redirect in existing page
+location /mailman/user-profile {
+ proxy_pass http://127.0.0.1:8002/postorius/users;
+ proxy_set_header Host $http_host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header X-Forwarded-Port $server_port;
+ proxy_set_header X-Forwarded-Server $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+}
+%for %%location in ['accounts', 'admin', 'postorius']
+location /mailman/%%location {
+ proxy_pass http://127.0.0.1:8002/%%location;
+ proxy_set_header Host $http_host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header X-Forwarded-Port $server_port;
+ proxy_set_header X-Forwarded-Server $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+}
+%end for
+location /mailman {
+ rewrite ^(/mailman/.*)$ /mailman/postorius/ permanent;
}
diff --git a/seed/mailman/templates/mailman.yml b/seed/mailman/templates/mailman.yml
new file mode 100644
index 00000000..2c96daf1
--- /dev/null
+++ b/seed/mailman/templates/mailman.yml
@@ -0,0 +1,12 @@
+%set %%username="rougail_test@silique.fr"
+ip: %%ip_eth0
+revprox_ip: %%revprox_client_server_ip
+%set %%domain = %%revprox_client_external_domainnames[0]
+domain_name: %%domain
+base_url: https://%%domain%%domain.revprox_client_location
+auth_url: %%oauth2_client_external[0]
+auth_server: %%oauth2_server_domainname
+username: %%username
+password: %%get_password(server_name='test', username=%%username, description='test', type="cleartext", hide=%%hide_secret, temporary=True)
+mailman_domain: %%mailman_domains[0]
+internal_address: %%domain_name_eth0
diff --git a/seed/mailman/templates/mailman3.service b/seed/mailman/templates/mailman3.service
index 58932c6c..5727c469 100644
--- a/seed/mailman/templates/mailman3.service
+++ b/seed/mailman/templates/mailman3.service
@@ -1,6 +1,6 @@
[Unit]
Description=Postorius WSGI Service
-After=postgresqlclient.service
+After=risotto.target
[Service]
%for %%domain in %%mailman_domains
diff --git a/seed/mailman/templates/postorius.service b/seed/mailman/templates/postorius.service
index 1f29c6c4..83374d6d 100644
--- a/seed/mailman/templates/postorius.service
+++ b/seed/mailman/templates/postorius.service
@@ -1,6 +1,6 @@
[Unit]
Description=Postorius WSGI Service
-After=network.target postgresqlclient.service
+After=risotto.target
[Service]
Type=notify
diff --git a/seed/mailman/tests/test_mailman.py b/seed/mailman/tests/test_mailman.py
new file mode 100644
index 00000000..2b7e899d
--- /dev/null
+++ b/seed/mailman/tests/test_mailman.py
@@ -0,0 +1,396 @@
+from yaml import load, SafeLoader
+from os import environ
+from os.path import join, isdir
+from revprox import Authentication
+from execute import run
+from re import search
+from time import sleep
+from imaplib2 import IMAP4_SSL
+from smtplib import SMTP
+from email import message_from_bytes
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+
+DATA = None
+DATA_IMAP = None
+IMAP = None
+IMAP_FAMILY = None
+
+
+def get_data():
+ global DATA
+ if not DATA:
+ conf_file = f'{environ["MACHINE_TEST_DIR"]}/mailman.yml'
+ with open(conf_file) as yaml:
+ DATA = load(yaml, Loader=SafeLoader)
+ return DATA
+
+
+def get_imap_data():
+ global DATA_IMAP
+ if not DATA_IMAP:
+ machine_test_dir = environ['MACHINE_TEST_DIR']
+ print("FIXME")
+ machine_test_dir = machine_test_dir.replace('mailman', 'dovecot')
+ if not isdir(machine_test_dir):
+ print('!!! No local IMAP server found !!!')
+ return
+ conf_file = f'{machine_test_dir}/imap.yml'
+ with open(conf_file) as yaml:
+ DATA_IMAP = load(yaml, Loader=SafeLoader)
+ return DATA_IMAP
+
+
+def get_authentication(data, family=False):
+ if family:
+ username = data['username_family']
+ password = data['password_family']
+ else:
+ username = data['username']
+ password = data['password']
+ return Authentication(data['auth_url'],
+ data['auth_server'],
+ data['revprox_ip'],
+ username,
+ password,
+ f"""
+Listes - {data["domain_name"]}
+""",
+ )
+
+
+def check_mail(subject, family=False, reply=False):
+ global IMAP, IMAP_FAMILY
+ data = get_imap_data()
+ if data is None:
+ return
+ if family:
+ if IMAP_FAMILY is None:
+ IMAP_FAMILY = IMAP4_SSL(data['address'])
+ IMAP_FAMILY.LOGIN(data['username_family'], data['password_family'] + '2')
+ imap = IMAP_FAMILY
+ else:
+ if IMAP is None:
+ IMAP = IMAP4_SSL(data['address'])
+ IMAP.LOGIN(data['username'], data['password'])
+ imap = IMAP
+ imap.SELECT(readonly=False)
+ typ, req = imap.SEARCH(None, 'ALL')
+ assert typ == 'OK'
+ if not req[0].decode():
+ raise Exception('pas de mail')
+ num = req[0].decode().split()[-1]
+ field = imap.FETCH(num, '(RFC822)')
+ assert field[0] == 'OK'
+ msg = message_from_bytes(field[1][-2][-1])
+ #if msg.is_multipart():
+ # for part in msg.walk():
+ # # extract content type of email
+ # try:
+ # print(part.get_payload(decode=True).decode())
+ # except:
+ # pass
+ #else:
+ # print(msg.get_payload(decode=True).decode())
+ if subject is not None:
+ assert subject == msg['Subject']
+ if reply:
+ reply_message(msg)
+ ret = imap.store(num, '+FLAGS', '\\Deleted')
+ assert ret[0] == 'OK', f'error when deleting mail: {ret}'
+ imap.expunge()
+# imap.CLOSE()
+# imap.LOGOUT()
+
+
+def reply_message(msg):
+ data = get_imap_data()
+ body = MIMEText('resend')
+ message = MIMEMultipart()
+ message["to"] = msg["From"]
+ message['from'] = msg["To"]
+ message['subject'] = f'Re: {msg["Subject"]}'
+ message.add_header('reply-to', msg["From"])
+ message.attach(body)
+ #
+ smtp = SMTP(data['address'], '587')
+ smtp.starttls()
+ smtp.login(data['username_family'], data['password_family'] + '2')
+ smtp.sendmail(msg["To"],
+ msg["From"],
+ message.as_string(),
+ )
+ smtp.quit()
+
+
+def send_mail(subject, data, data_mm, family=False, add_mail=''):
+ list_name = 'test'
+ smtp = SMTP(data['address'], '587')
+ smtp.starttls()
+ if not family:
+ sender = data['username']
+ smtp.login(sender, data['password'])
+ else:
+ sender = data['username_family']
+ smtp.login(sender, data['password_family'] + '2')
+ list_addr = f'{list_name}{add_mail}@{data_mm["mailman_domain"]}'
+ msg = f"""From: {sender}\r\n\
+To: {list_addr}\r\n\
+Subject: {subject}\r\n\
+\r\n\
+MESSAGE"""
+ smtp.sendmail(sender,
+ list_addr,
+ msg,
+ )
+ smtp.quit()
+
+
+def test_mailman():
+ data = get_data()
+ get_authentication(data)
+
+
+def test_mailman_login():
+ data = get_data()
+ authentication = get_authentication(data)
+ content = authentication.get(data['auth_url'])
+ login = data['username'].split('@')[0]
+ assert f'Successfully signed in as {login}.' in content
+
+
+def test_mailman_list():
+ data = get_data()
+ authentication = get_authentication(data)
+ list_name = 'test'
+ search_list = f'href="/mailman/postorius/lists/{list_name}.{data["mailman_domain"]}/"'
+ if 'FIRST_RUN' in environ:
+ content = authentication.get(data['auth_url'])
+ assert search_list not in content
+ result = run(data['internal_address'],
+ ['/usr/bin/mailman3', 'create', '--language', 'fr', '-o', data['username'], '-N', '-d', f'{list_name}@{data["mailman_domain"]}'],
+ 'mailman',
+ )
+ assert list(result) == [f'Liste de diffusion créée : {list_name}@{data["mailman_domain"]}']
+ content = authentication.get(data['auth_url'])
+ assert search_list in content
+
+
+def test_mailman_inscription():
+ data = get_data()
+ authentication = get_authentication(data)
+ list_name = 'test'
+ search_inscription = f'Adresse principale ({data["username"]}) | '
+ url = join(data['base_url'], f'postorius/lists/{list_name}.{data["mailman_domain"]}/')
+ if 'FIRST_RUN' in environ:
+ content = authentication.get(url)
+ assert search_inscription not in content
+ pattern_csrf = r'name="csrfmiddlewaretoken" value="([a-zA-Z0-9\-\_=]+)"'
+ pattern_sub = r'
diff --git a/seed/nginx-common/templates/nginx-common.yml b/seed/nginx-common/templates/nginx-common.yml
new file mode 100644
index 00000000..4680042f
--- /dev/null
+++ b/seed/nginx-common/templates/nginx-common.yml
@@ -0,0 +1,13 @@
+address: %%ip_eth0
+nginx_default_http: %slurp
+%if %%getVar('nginx_default_http', False) and not %%getVar('revprox_client_external_domainnames', None)
+true
+%else
+false
+%end if
+nginx_default_https: %slurp
+%if %%getVar('nginx_default_https', False) and not %%getVar('revprox_client_external_domainnames', None)
+true
+%else
+false
+%end if
diff --git a/seed/nginx-common/templates/nginx.conf b/seed/nginx-common/templates/nginx.conf
index 758cb4de..b8cf4220 100644
--- a/seed/nginx-common/templates/nginx.conf
+++ b/seed/nginx-common/templates/nginx.conf
@@ -76,14 +76,24 @@ http {
%if %%nginx_default_https
server {
listen 443 ssl http2;
- server_name %%domain_name_eth0;
+ %if %%getVar('revprox_client_external_domainnames', None)
+ %for %%domain in %%revprox_client_external_domainnames
+ server_name %%domain;
+ %end for
+ %else
+ server_name _;
+ %end if
root %%nginx_root;
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
ssl_certificate /etc/pki/tls/certs/nginx.crt;
ssl_certificate_key /etc/pki/tls/private/nginx.key;
- ssl_client_certificate /etc/pki/ca-trust/source/anchors/ca_InternalReverseProxy.crt;
+ %if %%getVar('revprox_client_external_domainnames', None)
+ ssl_client_certificate %%revprox_ca_file;
+ %else
+ ssl_client_certificate /etc/pki/ca-trust/source/anchors/ca_HTTP.crt;
+ %end if
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
@@ -105,5 +115,7 @@ http {
%else
include /etc/nginx/sites-enabled/*;
%end if
-
+%if not %%getVar('revprox_client_external_domainnames', None)
+ include /etc/nginx/sites-enabled/*;
+%end if
}
diff --git a/seed/nginx-common/tests/test_nginx_commmon.py b/seed/nginx-common/tests/test_nginx_commmon.py
new file mode 100644
index 00000000..efbfc866
--- /dev/null
+++ b/seed/nginx-common/tests/test_nginx_commmon.py
@@ -0,0 +1,50 @@
+from yaml import load, SafeLoader
+from os import environ
+from pytest import raises
+
+import warnings
+import socket
+from requests import get
+from requests.exceptions import SSLError
+
+
+def req(url, ip, verify=True):
+ # Monkey patch to force IPv4 resolution
+ old_getaddrinfo = socket.getaddrinfo
+ def new_getaddrinfo(*args, **kwargs):
+ ret = old_getaddrinfo(*args, **kwargs)
+ dns = list(ret[0])
+ dns[-1] = (ip, dns[-1][1])
+ return [dns]
+ socket.getaddrinfo = new_getaddrinfo
+ if not verify:
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore")
+ ret = get(url, verify=verify)
+ else:
+ ret = get(url, verify=verify)
+ ret_code = ret.status_code
+ content = ret.content
+ socket.getaddrinfo = old_getaddrinfo
+ return ret_code, content.decode()
+
+
+def test_revprox():
+ conf_file = f'{environ["MACHINE_TEST_DIR"]}/nginx-common.yml'
+ with open(conf_file) as yaml:
+ data = load(yaml, Loader=SafeLoader)
+ # test unknown domain
+ url = 'google.fr'
+ protocols = []
+ if data['nginx_default_http']:
+ protocols.append('http')
+ if data['nginx_default_https']:
+ protocols.append('https')
+ # test certificate
+ with raises(SSLError):
+ # not certificat problem for https://{url}
+ req(f'https://{url}', data['address'])
+ for protocol in protocols:
+ ret_code, content = req(f'{protocol}://{url}', data['address'], verify=False)
+ assert ret_code == 200, f'{protocol}://{url} do not returns code 200 but {ret_code}'
+ assert "Test Page for the HTTP Server on Fedora" in content, f'{protocol}://{url} do not returns default fedora page'
diff --git a/seed/nginx-https/dictionaries/25_nginx.xml b/seed/nginx-https/dictionaries/25_nginx.xml
index f908f0b5..1f24bfaf 100644
--- a/seed/nginx-https/dictionaries/25_nginx.xml
+++ b/seed/nginx-https/dictionaries/25_nginx.xml
@@ -1,22 +1,16 @@
-
-
- /etc/nginx/default.d/risotto.conf
-
-
-
+
+ False
+
+
True
nginx
-
-
- /
-
@@ -29,11 +23,4 @@
-
-
-
- nginx_default_risotto
- nginx_locations
-
-
diff --git a/seed/nginx-reverse-proxy/dictionaries/20_nginx.xml b/seed/nginx-reverse-proxy/dictionaries/20_nginx.xml
new file mode 100644
index 00000000..85ac9c5a
--- /dev/null
+++ b/seed/nginx-reverse-proxy/dictionaries/20_nginx.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ /etc/pki/ca-trust/source/anchors/ca_HTTP.crt
+
+
+
diff --git a/seed/nginx-reverse-proxy/dictionaries/25_nginx.xml b/seed/nginx-reverse-proxy/dictionaries/25_nginx.xml
index 3ed3d35b..e4aa3699 100644
--- a/seed/nginx-reverse-proxy/dictionaries/25_nginx.xml
+++ b/seed/nginx-reverse-proxy/dictionaries/25_nginx.xml
@@ -4,7 +4,7 @@
/etc/nginx/conf.d/options-rp.conf
- /etc/nginx/conf.d/risotto.conf
+ /etc/nginx/sites-enabled/risotto.conf
nginx.nginx_certificate_filename
nginx.nginx_private_key_filename
/tests/reverse-proxy.yml
@@ -22,6 +22,9 @@
True
+
+ True
+
diff --git a/seed/nginx-reverse-proxy/templates/ca_HTTP.crt b/seed/nginx-reverse-proxy/templates/ca_HTTP.crt
new file mode 100644
index 00000000..dcbc3aa3
--- /dev/null
+++ b/seed/nginx-reverse-proxy/templates/ca_HTTP.crt
@@ -0,0 +1,3 @@
+%for %%idx in %%range(%%len(%%zones_list))
+%%get_chain(authority_cn=%%getVar('domain_name_eth' + %%str(%%idx)), authority_name="HTTP", hide=%%hide_secret)
+%end for
diff --git a/seed/nginx-reverse-proxy/templates/nginx.crt b/seed/nginx-reverse-proxy/templates/nginx.crt
new file mode 100644
index 00000000..de2a8a1d
--- /dev/null
+++ b/seed/nginx-reverse-proxy/templates/nginx.crt
@@ -0,0 +1,2 @@
+%%get_certificate(%%nginx_default, authority_cn=%%domain_name_eth0, authority_name='HTTP', type="server", hide=%%hide_secret)
+%%get_chain(%%nginx_default, 'HTTP', hide=%%hide_secret)
diff --git a/seed/nginx-reverse-proxy/templates/nginx.key b/seed/nginx-reverse-proxy/templates/nginx.key
new file mode 100644
index 00000000..4d393c67
--- /dev/null
+++ b/seed/nginx-reverse-proxy/templates/nginx.key
@@ -0,0 +1 @@
+%%get_private_key(%%nginx_default, authority_cn=%%domain_name_eth0, authority_name='HTTP', type='server', hide=%%hide_secret)
diff --git a/seed/nginx-reverse-proxy/templates/revprox-nginx.conf b/seed/nginx-reverse-proxy/templates/revprox-nginx.conf
index c1c7ff68..0f48e774 100644
--- a/seed/nginx-reverse-proxy/templates/revprox-nginx.conf
+++ b/seed/nginx-reverse-proxy/templates/revprox-nginx.conf
@@ -41,7 +41,7 @@ server {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Destination $dest;
%end if
- proxy_ssl_trusted_certificate /etc/pki/ca-trust/source/anchors/ca_InternalReverseProxy.crt;
+ proxy_ssl_trusted_certificate %%revprox_ca_file;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse on;
diff --git a/seed/nginx-reverse-proxy/tests/test_revprox.py b/seed/nginx-reverse-proxy/tests/test_revprox.py
index d48cc788..592807d8 100644
--- a/seed/nginx-reverse-proxy/tests/test_revprox.py
+++ b/seed/nginx-reverse-proxy/tests/test_revprox.py
@@ -32,19 +32,8 @@ def test_revprox():
conf_file = f'{environ["MACHINE_TEST_DIR"]}/reverse-proxy.yml'
with open(conf_file) as yaml:
data = load(yaml, Loader=SafeLoader)
- # test unknown domain
- url = 'google.fr'
- ret_code, content = req(f'https://{url}', data['address'], verify=False)
- assert ret_code == 200, f'https://{url} do not returns code 200 but {ret_code}'
- assert "
Test Page for the HTTP Server on Fedora" in content, f'https://{url} returns default fedora page'
- # test certificate
- try:
- req(f'https://{url}', data['address'])
- raise Exception(f'not certificat problem for https://{url}')
- except SSLError:
- pass
# test known domains
for url in data['urls']:
ret_code, content = req(f'https://{url}', data['address'])
assert ret_code == 200, f'https://{url} do not returns code 200 but {ret_code}'
- assert "Test Page for the HTTP Server on Fedora" not in content, f'https://{url} returns default fedora page'
+ assert "Test Page for the HTTP Server on Fedora" not in content, f'https://{url} do returns default fedora page'
diff --git a/seed/nsd/templates/nsd.service b/seed/nsd/templates/nsd.service
index 6f45f4ef..f48cf183 100644
--- a/seed/nsd/templates/nsd.service
+++ b/seed/nsd/templates/nsd.service
@@ -1,2 +1,2 @@
[Unit]
-After=network.target
+After=risotto.target
diff --git a/seed/oauth2-client/dictionaries/30_oauth2_client.xml b/seed/oauth2-client/dictionaries/30_oauth2_client.xml
index cc6e415c..80a28a6c 100644
--- a/seed/oauth2-client/dictionaries/30_oauth2_client.xml
+++ b/seed/oauth2-client/dictionaries/30_oauth2_client.xml
@@ -1,5 +1,8 @@
+
+
+
diff --git a/seed/oauth2-client/manual/image/preinstall/oauth2-client.sh b/seed/oauth2-client/manual/image/preinstall/oauth2-client.sh
new file mode 100644
index 00000000..c6335d96
--- /dev/null
+++ b/seed/oauth2-client/manual/image/preinstall/oauth2-client.sh
@@ -0,0 +1 @@
+PKG="$PKG curl"
diff --git a/seed/oauth2-client/templates/oauth2-client.service b/seed/oauth2-client/templates/oauth2-client.service
new file mode 100644
index 00000000..c2bb7768
--- /dev/null
+++ b/seed/oauth2-client/templates/oauth2-client.service
@@ -0,0 +1,7 @@
+[Unit]
+After=network-online.target
+Before=risotto.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/timeout 90 bash -c 'while ! [ "$(/usr/bin/curl --write-out '%{http_code}' --silent --output /dev/null https://%%oauth2_client_server_domainname/.well-known/openid-configuration)" = 200 ]; do sleep 1; done;'
diff --git a/seed/peertube/applicationservice.yml b/seed/peertube/applicationservice.yml
index 6ae8b4b7..1aa97aba 100644
--- a/seed/peertube/applicationservice.yml
+++ b/seed/peertube/applicationservice.yml
@@ -7,5 +7,5 @@ depends:
- relay-mail-client
- reverse-proxy-client
- redis-client
- - nginx-common
+ - nginx-https
- oauth2-client
diff --git a/seed/peertube/dictionaries/30_peertube.xml b/seed/peertube/dictionaries/30_peertube.xml
index 47aa5482..6e627f15 100644
--- a/seed/peertube/dictionaries/30_peertube.xml
+++ b/seed/peertube/dictionaries/30_peertube.xml
@@ -6,7 +6,8 @@
/sysusers.d/0peertube.conf
/tmpfiles.d/0peertube.conf
/etc/peertube/production.yaml
- /etc/nginx/conf.d/peertube.conf
+ /etc/nginx/default.d/peertube.conf
+ /etc/nginx/conf.d/peertube.conf
@@ -45,6 +46,9 @@
+
+ /usr/share/peertube
+
/
diff --git a/seed/peertube/templates/nginx.peertube.conf b/seed/peertube/templates/nginx.peertube.conf
index 145eee6f..0f1fcf99 100644
--- a/seed/peertube/templates/nginx.peertube.conf
+++ b/seed/peertube/templates/nginx.peertube.conf
@@ -16,15 +16,14 @@
# GNUNUX location / { return 301 https://$host$request_uri; }
# GNUNUX }
-upstream %%domain_name_eth0 {
-# GNUNUX server ${PEERTUBE_HOST};
- server localhost:9000;
-}
+# GNUNUX upstream %%domain_name_eth0 {
+# GNUNUX server ${PEERTUBE_HOST};
+# GNUNUX }
-server {
- listen 443 ssl http2;
- listen [::]:443 ssl http2;
- server_name %%domain_name_eth0;
+# GNUNUX server {
+# GNUNUX listen 443 ssl http2;
+# GNUNUX listen [::]:443 ssl http2;
+# GNUNUX server_name %%domain_name_eth0;
# GNUNUX access_log /var/log/nginx/peertube.access.log; # reduce I/0 with buffer=10m flush=5m
# GNUNUX error_log /var/log/nginx/peertube.error.log;
@@ -35,11 +34,6 @@ server {
##
# GNUNUX ssl_certificate /etc/letsencrypt/live/${WEBSERVER_HOST}/fullchain.pem;
# GNUNUX ssl_certificate_key /etc/letsencrypt/live/${WEBSERVER_HOST}/privkey.pem;
-#>GNUNUX
- ssl_client_certificate %%revprox_ca_file;
- ssl_certificate %%revprox_cert_file;
- ssl_certificate_key %%revprox_key_file;
-#/etc/piwigo/database.inc.php
/sbin/piwigo.sh
/etc/php-fpm.d/piwigo.conf
+ /etc/nginx/default.d/piwigo.conf
-
-
- /usr/local/share/piwigo
-
-
+
Album photographique
@@ -53,7 +50,7 @@
piwigo_users
- nginx_locations
+ piwigo_locations
diff --git a/seed/nginx-https/templates/risotto.conf b/seed/piwigo/templates/piwigo.nginx.conf
similarity index 82%
rename from seed/nginx-https/templates/risotto.conf
rename to seed/piwigo/templates/piwigo.nginx.conf
index e7d34a48..1ba02a33 100644
--- a/seed/nginx-https/templates/risotto.conf
+++ b/seed/piwigo/templates/piwigo.nginx.conf
@@ -1,3 +1,5 @@
+# To allow POST on static pages
+error_page 405 =200 $uri;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
@@ -6,18 +8,15 @@ add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;';
add_header Referrer-Policy no-referrer always;
-
-%for %%location in %%nginx_locations
+
+%for %%location in %%piwigo_locations
location %%location {
-%if %%location == '/'
+ %if %%location == '/'
root %slurp
-%else
+ %else
alias %slurp
-%end if
-%%nginx_root_directory;
-%if not %%getVar('php_fpm_installed', False)
- index index.html;
-%else
+ %end if
+ /usr/local/share/piwigo;
index index.php;
location ~ ^(?.+?\.php)(?/.*)?$ {
fastcgi_pass php-fpm;
@@ -25,6 +24,5 @@ location %%location {
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
-%end if
}
%end for
diff --git a/seed/piwigo/templates/piwigo.service b/seed/piwigo/templates/piwigo.service
index e75c1c11..16b5b987 100644
--- a/seed/piwigo/templates/piwigo.service
+++ b/seed/piwigo/templates/piwigo.service
@@ -1,6 +1,6 @@
[Unit]
Description=Piwigo management
-After=mariadbclient.service
+After=risotto.target
Before=nginx.service php-fpm.service
[Service]
diff --git a/seed/pleroma/dictionaries/30_pleroma.xml b/seed/pleroma/dictionaries/30_pleroma.xml
index b457600c..6a6cc7ed 100644
--- a/seed/pleroma/dictionaries/30_pleroma.xml
+++ b/seed/pleroma/dictionaries/30_pleroma.xml
@@ -7,7 +7,7 @@
/tmpfiles.d/0peertube.conf
/etc/peertube/production.yaml
/etc/pam.d/login
- /etc/nginx/conf.d/peertube.conf
+ /etc/nginx/sites-enabled/peertube.conf
diff --git a/seed/postgresql-client/dictionaries/23_postgresql.xml b/seed/postgresql-client/dictionaries/23_postgresql.xml
index 138f7d3f..9afde856 100644
--- a/seed/postgresql-client/dictionaries/23_postgresql.xml
+++ b/seed/postgresql-client/dictionaries/23_postgresql.xml
@@ -1,7 +1,7 @@
-
+
/secrets/postgresql.pass
/etc/pki/ca-trust/source/anchors/ca_PostgreSQL.crt
/etc/pki/tls/certs/postgresql.crt
diff --git a/seed/postgresql-client/templates/postgresqlclient.service b/seed/postgresql-client/templates/postgresqlclient.service
index 7addde19..fd8b647a 100644
--- a/seed/postgresql-client/templates/postgresqlclient.service
+++ b/seed/postgresql-client/templates/postgresqlclient.service
@@ -1,6 +1,7 @@
[Unit]
Description=Waiting for postgresql server
-Before=network.target
+After=network-online.target
+Before=risotto.target
[Service]
Type=oneshot
diff --git a/seed/postgresql/DEBUG.md b/seed/postgresql/DEBUG.md
new file mode 100644
index 00000000..c835ba01
--- /dev/null
+++ b/seed/postgresql/DEBUG.md
@@ -0,0 +1 @@
+pg_dumpall --clean > /srv/database.sql
diff --git a/seed/reverse-proxy-client/tests/revprox.py b/seed/reverse-proxy-client/tests/revprox.py
index bb9ab177..134fb4f2 100644
--- a/seed/reverse-proxy-client/tests/revprox.py
+++ b/seed/reverse-proxy-client/tests/revprox.py
@@ -33,7 +33,7 @@ class Authentication:
ret = req.get(url)
code = ret.status_code
content = ret.content
- assert code == 200
+ assert code == 200, f"cannot access to lemonldap; {content}"
assert b'Authentication portal' in content, f'cannot find LemonLdap title: {content}'
def auth_lemonldap(self,
@@ -62,7 +62,8 @@ class Authentication:
authorize_url = f'{portal_url}authorize'
ret = req.get(authorize_url)
assert ret.status_code == 200
- assert title in ret.content.decode()
+ content = ret.content.decode()
+ assert title in content, f'cannot find {title} in {content}'
def get(self,
url,
@@ -78,7 +79,8 @@ class Authentication:
def post(self,
url,
data,
+ headers=None,
):
with MookDns(self.ip):
- ret = post(url, cookies=self.cookies, data=data)
+ ret = post(url, cookies=self.cookies, data=data, headers=headers)
assert ret.status_code == 200, f'return code is {ret.status_code}'
diff --git a/seed/roundcube/templates/roundcube.service b/seed/roundcube/templates/roundcube.service
index 92913e35..19b462b2 100644
--- a/seed/roundcube/templates/roundcube.service
+++ b/seed/roundcube/templates/roundcube.service
@@ -1,6 +1,6 @@
[Unit]
Description=Roundcube database init
-After=postgresqlclient.service
+After=risotto.target
Before=nginx.service php-fpm.service
[Service]
diff --git a/seed/systemd/dictionaries/15-systemd.xml b/seed/systemd/dictionaries/15-systemd.xml
index 6819b861..deaf2e74 100644
--- a/seed/systemd/dictionaries/15-systemd.xml
+++ b/seed/systemd/dictionaries/15-systemd.xml
@@ -29,6 +29,7 @@
/secrets/root.pwd
/tmpfiles.d/risotto-volatile.conf
+
diff --git a/seed/systemd/templates/risotto.target b/seed/systemd/templates/risotto.target
new file mode 100644
index 00000000..8f4c5e63
--- /dev/null
+++ b/seed/systemd/templates/risotto.target
@@ -0,0 +1,5 @@
+[Unit]
+Description=Waiting for all dependencies
+Before=multi-user.target
+After=network-online.target
+Wants=network-online.target