Merge branch 'develop'

This commit is contained in:
Emmanuel Garette 2022-08-18 10:19:53 +02:00
commit 7cbd9b00fc
128 changed files with 1992 additions and 952 deletions

View file

@ -10,39 +10,25 @@
<value>False</value>
</variable>
<family name="network" description="Réseau">
<variable name="zones_list" type="string" multi="True" description="Liste de toutes les zones" hidden="True"/>
<variable name="interfaces_list" type="number" multi="True" description="Liste de tous les numéros d'interfaces" hidden="True"/>
<variable name="server_name" type="domainname" hidden="True" provider="global:server_name" mandatory="True"/>
<variable name="zones_list" type="string" multi="True" description="Liste de toutes les zones" mandatory="True" hidden="True" provider="global:zones_name"/>
<variable name="interfaces_list" type="number" multi="True" description="Liste de tous les numéros d'interfaces" hidden="True" provider="global:zones_list"/>
<family name="interface_" description="Interface " dynamic="interfaces_list">
<variable name="zone_name_eth" type="string" description="Nom de la zone de l'interface " hidden="True"/>
<variable name="ip_eth" type="ip" description="Adresse IP pour l'interface " hidden="True" provider="ip"/>
<variable name="zone_name_eth" type="string" description="Nom de la zone de l'interface " hidden="True" mandatory="True"/>
<variable name="ip_eth" type="ip" description="Adresse IP pour l'interface " hidden="True" mandatory="True"/>
<variable name="network_eth" type="network_cidr" description="Réseau de l'interface " hidden="True"/>
<variable name="gateway_eth" type="ip" description="La route de l'interface "/>
<variable name="domain_name_eth" type="domainname" description="Nom de domaine pour l'interface " mandatory="True" hidden="True"/>
<variable name="domain_name_eth" type="domainname" description="Nom de domaine pour l'interface " mandatory="True" hidden="True" provider="global:server_names"/>
</family>
</family>
</variables>
<constraints>
<fill name="calc_value">
<param type="information">zones_name</param>
<target>zones_list</target>
</fill>
<fill name="get_range">
<param type="information">zones_name</param>
<target>interfaces_list</target>
</fill>
<fill name="get_ip">
<param name="server_name" type="information">server_name</param>
<param name="server_name" type="variable">domain_name_eth</param>
<target>ip_eth</target>
</fill>
<!-- Return "server_name" only for domain_name_eth0 -->
<fill name="get_domain_name">
<param type="information">server_name</param>
<param type="information">extra_domainnames</param>
<param type="suffix"/>
<target>domain_name_eth</target>
</fill>
<fill name="get_zone_name">
<param type="information">zones_name</param>
<param type="variable">zones_list</param>
<param name="index" type="suffix"/>
<target>zone_name_eth</target>
</fill>

View file

@ -6,7 +6,7 @@ from os.path import dirname as _dirname, abspath as _abspath, join as _join, isf
from os import makedirs as _makedirs
from risotto.utils import ZONES_SERVER
#from risotto.utils import ZONES_SERVER
_HERE = _dirname(_abspath(__main__.__file__))
@ -81,30 +81,8 @@ def _set_password(server_name: str,
return file_content
def get_range(lst):
return list(range(max(1, len(lst))))
def get_zone_name(zones: list,
index: str,
):
if zones is not None:
return zones[int(index)]
def get_domain_name(server_name: str,
extra_domainnames: list,
suffix: str,
) -> str:
index = int(suffix)
if index == 0:
return server_name
return extra_domainnames[index - 1]
def get_provider_name(network_name: str,
provider: str,
) -> str:
if network_name not in ZONES_SERVER['providers'] or provider not in ZONES_SERVER['providers'][network_name]:
return
return ZONES_SERVER['providers'][network_name][provider][0]

View file

@ -1,9 +1,26 @@
from typing import List
from risotto.utils import load_domains, DOMAINS
from risotto.utils import multi_function as _multi_function
@_multi_function
def get_ip(server_name: str) -> str:
load_domains()
host_name, domain_name = server_name.split('.', 1)
if server_name is None:
return
if isinstance(server_name, list):
return_list = True
else:
return_list = False
server_name = [server_name]
lst = []
for s_name in server_name:
host_name, domain_name = s_name.split('.', 1)
if not domain_name in DOMAINS:
raise ValueError(f'cannot find IP in domain name "{domain_name}" (for "{s_name}")')
domain = DOMAINS[domain_name]
return domain[1][domain[0].index(host_name)]
ret = domain[1][domain[0].index(host_name)]
if not return_list:
return ret
if ret not in lst:
lst.append(ret)
return lst

View file

@ -5,14 +5,7 @@
<variable name="dns_is_only_local" redefine="True">
<value>False</value>
</variable>
<variable name="dns_client_address" redefine="True"/>
<variable name="dns_client_address" redefine="True" supplier="ExternalDNS"/>
</family>
</variables>
<constraints>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>ExternalDNS</param>
<target>dns_client_address</target>
</fill>
</constraints>
</rougail>

View file

@ -10,21 +10,13 @@
<variable name="dns_is_only_local" type="boolean" description="DNS resolve only local address" hidden="True">
<value>True</value>
</variable>
<variable name="dns_client_address" type="domainname" description="Nom de domaine du serveur DNS"/>
<variable name="dns_client_address" type="domainname" description="Nom de domaine du serveur DNS" supplier="LocalDNS"/>
<variable name="ip_dns" type="ip" description="Adresse IP du serveur DNS" hidden="True"/>
</family>
</variables>
<constraints>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>LocalDNS</param>
<target>dns_client_address</target>
</fill>
<fill name="set_linked">
<param name="linked_server" type="variable">dns_client_address</param>
<param name="linked_provider">dns</param>
<param name="linked_value" type="variable">ip_eth0</param>
<param name="linked_returns">ip</param>
<fill name="get_ip">
<param name="server_name" type="variable">dns_client_address</param>
<target>ip_dns</target>
</fill>
</constraints>

View file

@ -3,13 +3,13 @@ addresses:
%if %%getVar('dns_client_address', None)
- dns_address: '%%dns_client_address'
dns_ip: '%%ip_dns'
%elif %%getVar('unbound_forward_address', None)
%elif %%getVar('unbound_forward_address', None) is not None
%for %%authority in %%unbound_forward_address
- dns_address: %%authority
dns_ip: %%get_ip(%%str(%%authority))
%end for
%else
%for %%zone in %%nsd_zones_auto
%for %%zone in %%nsd_zones
%set %%suffix = %%normalize_family(%%zone)
%set %%hostnames = %%nsd["nsd_zone_" + %%suffix]["hostname_" + %%suffix]["hostname_" + %%suffix]
%for %%nsd in %%hostnames

View file

@ -0,0 +1,44 @@
import socket
from shutil import copyfile, move
from os import remove
from os.path import isfile
class MookDns:
# Monkey patch to force IPv4 resolution
def __init__(self, ip):
self.ip = ip
def __enter__(self):
self.old_getaddrinfo = socket.getaddrinfo
def new_getaddrinfo(*args, **kwargs):
ret = self.old_getaddrinfo(*args, **kwargs)
dns = list(ret[0])
dns[-1] = (self.ip, dns[-1][1])
return [dns]
socket.getaddrinfo = new_getaddrinfo
return self
def __exit__(self, exc_type, exc, tb):
socket.getaddrinfo = self.old_getaddrinfo
class MookDnsSystem:
# Monkey patch to force IPv4 resolution
def __init__(self, dns, ip):
self.dns = dns
self.ip = ip
def __enter__(self):
if not isfile('/etc/hosts.risotto'):
copyfile('/etc/hosts', '/etc/hosts.risotto')
with open('/etc/hosts.risotto', 'r') as risotto:
with open('/etc/hosts', 'w') as hosts:
for line in risotto.readlines():
if self.dns not in line:
hosts.write(line)
hosts.write(f'{self.ip} {self.dns}')
def __exit__(self, exc_type, exc, tb):
remove('/etc/hosts')
move('/etc/hosts.risotto', '/etc/hosts')

View file

@ -2,8 +2,7 @@ format: '0.1'
description: Postfix et Dovecot
depends:
- base-fedora-36
- relay-mail-client
- relay-lmtp-client
- ldap-client-fedora
- oauth2-client
- nginx-https
provider: IMAP

View file

@ -71,9 +71,8 @@
</family>
</family>
<family name="mail" description="Mail domain" leadership="True">
<variable name="mail_domains" type="domainname" description="Domaine de courriel géré localement" mandatory="True" multi="True"/>
<variable name="mail_domains" type="domainname" description="Domaine de courriel géré localement" mandatory="True" multi="True" supplier="LMTP:criteria"/>
<variable name="mail_domains_calc" type="domainname" hidden="True"/>
<variable name="mail_domains_calc_autoconfig" type="domainname" hidden="True"/>
<variable name="imap_domainname" type="domainname" mandatory="True"/>
<variable name="submission_domainname" type="domainname" mandatory="True"/>
</family>
@ -81,36 +80,22 @@
<variable name='postfix_pem_files' type="filename" hidden='True' multi='True'/>
</family>
<family name="dovecot" description="IMAP mail server">
<variable name="well_knowns" type="web_address" hidden='True' multi="True"/>
<variable name="imap_internal_address" type="domainname" description="Adresse interne du serveur IMAP" mandatory="True" provider="IMAP"/>
<variable name="well_known_filenames" type="filename" hidden='True' multi="True"/>
<variable name='external_imap_crt' type="filename" hidden='True' multi='True'/>
<variable name='external_imap_key' type="filename" hidden='True' multi='True'/>
</family>
<family name="nginx">
<family name="revprox_client">
<variable name="revprox_client_external_domainnames" redefine="True"/>
<variable name="revprox_client_web_address" redefine="True"/>
</family>
<variable name="nginx_default_https" redefine="True">
<value>False</value>
</variable>
<variable name="revprox_client_external_domainnames" redefine="True" mandatory="False"/>
<family name="revprox_client">
<variable name="revprox_client_location" redefine="True" mandatory="False">
<value/>
</variable>
</family>
</family>
</variables>
<constraints>
<check name="set_linked_configuration">
<param name="linked_server" type="variable">smtp_relay_address</param>
<param name="linked_provider">lmtp_server</param>
<param name="linked_value" type="variable">domain_name_eth0</param>
<target>mail_domains</target>
</check>
<check name="set_linked_configuration">
<param name="linked_server" type="variable">smtp_relay_address</param>
<param name="linked_provider">lmtp_criteria</param>
<param name="dynamic" type="variable">domain_name_eth0</param>
<target>mail_domains</target>
</check>
<fill name="calc_value">
<param>/etc/pki/tls/certs/imap_</param>
<param type="variable">imap_domainname</param>
@ -136,14 +121,12 @@
<target>postfix_pem_files</target>
</fill>
<fill name="calc_value">
<param type="variable">mail_domains</param>
<target>mail_domains_calc</target>
<param type="variable">domain_name_eth0</param>
<target>imap_internal_address</target>
</fill>
<fill name="calc_value">
<param>autoconfig</param>
<param type="variable">mail_domains</param>
<param name="join">.</param>
<target>mail_domains_calc_autoconfig</target>
<target>mail_domains_calc</target>
</fill>
<fill name="calc_value">
<param>/var/www/html/mail/</param>
@ -154,49 +137,20 @@
<param name="multi" type="boolean">True</param>
<target>well_known_filenames</target>
</fill>
<check name="set_linked_multi_variables">
<param type="variable">revprox_client_server_domainname</param>
<param name="linked_provider_0">revprox_clients</param>
<param name="linked_provider_1">revprox_location</param>
<param name="linked_value_1">/mail/config-v1.1.xml</param>
<param name="linked_provider_2">revprox_is_websocket</param>
<param name="linked_value_2" type="boolean">False</param>
<param name="linked_provider_3">revprox_url</param>
<param name="linked_value_3" type="variable">well_knowns</param>
<param name="variable_index_3" type="boolean">True</param>
<param name="variable_index" type="index"/>
<target>mail_domains_calc_autoconfig</target>
</check>
<check name="set_linked_multi_variables">
<param type="variable">revprox_client_server_domainname</param>
<param name="linked_provider_0">revprox_clients</param>
<param name="linked_provider_1">revprox_location</param>
<param name="linked_value_1">/.well-known/autoconfig/mail/config-v1.1.xml</param>
<param name="linked_provider_2">revprox_is_websocket</param>
<param name="linked_value_2" type="boolean">False</param>
<param name="linked_provider_3">revprox_url</param>
<param name="linked_value_3" type="variable">well_knowns</param>
<param name="variable_index_3" type="boolean">True</param>
<param name="variable_index" type="index"/>
<target>mail_domains_calc</target>
</check>
<check name="set_linked_multi_variables">
<param type="variable">revprox_client_server_domainname</param>
<param name="linked_provider_0">revprox_clients</param>
<param name="linked_provider_1">revprox_location</param>
<param name="linked_value_1">/autodiscover/autodiscover.xml</param>
<param name="linked_provider_2">revprox_is_websocket</param>
<param name="linked_value_2" type="boolean">False</param>
<param name="linked_provider_3">revprox_url</param>
<param name="linked_value_3" type="variable">well_knowns</param>
<param name="variable_index_3" type="boolean">True</param>
<param name="variable_index" type="index"/>
<target>mail_domains_calc</target>
</check>
<fill name="calc_well_known">
<param type="index"/>
<param type="variable">domain_name_eth0</param>
<param type="variable">mail_domains</param>
<target>well_knowns</target>
<target>revprox_client_web_address</target>
</fill>
<fill name="calc_domains">
<param type="variable">mail_domains</param>
<target>revprox_client_external_domainnames</target>
</fill>
<fill name="calc_locations">
<param type="variable">revprox_client_external_domainnames</param>
<param type="index"/>
<target>revprox_client_location</target>
</fill>
</constraints>
</rougail>

View file

@ -11,10 +11,29 @@ def sha512_crypt(password):
@_multi_function
def calc_well_known(*args):
if None in args:
return
def calc_domains(domains):
ret = []
for dom in args[1]:
ret.append(f'https://{args[0]}/mail/{dom}/autodiscover/autodiscover.xml')
for domain in domains:
ret.append(domain)
ret.append(domain)
ret.append(f'autoconfig.{domain}')
return ret
@_multi_function
def calc_locations(domain, index):
i = index//3
if 3 * i == index:
# divisible by three
return '/autodiscover/autodiscover.xml'
elif 3 * i + 1 == index:
return '/.well-known/autoconfig/mail/config-v1.1.xml'
return '/mail/config-v1.1.xml'
@_multi_function
def calc_well_known(index, dns, doms):
if None in (dns, doms):
return None
i = index//3
return f'https://{dns}/mail/{doms[i]}/autodiscover/autodiscover.xml'

View file

@ -107,7 +107,7 @@ auth_bind = yes
# LDAP base. %variables can be used here.
# For example: dc=mail, dc=example, dc=org
# GNUNUX base =
base = %%ldapclient_base_dn
base = %%ldapclient_search_dn
# Dereference: never, searching, finding, always
#deref = never

View file

@ -4,7 +4,7 @@
address: %%ip_eth0
dns: %%domain_name_eth0
username: %%username
password: %%get_password(server_name=%%ldap_server_address, username=%%username, description="ldap user", type="cleartext", hide=%%hide_secret, temporary=True)
password: %%get_password(server_name='test', username=%%username, description="test", type="cleartext", hide=%%hide_secret, temporary=True)
username_family: %%username_family
password_family: %%get_password(server_name=%%ldap_server_address, username=%%username_family, description="ldap family user", type="cleartext", hide=%%hide_secret, temporary=True)
password_family: %%get_password(server_name='test', username=%%username_family, description='test', type="cleartext", hide=%%hide_secret, temporary=True)
name_family: %%name_family

View file

@ -8,6 +8,6 @@ version = 3
bind = yes
bind_dn = %%ldapclient_user
bind_pw = %%ldapclient_user_password
search_base = %%ldapclient_base_dn
search_base = %%ldapclient_search_dn
query_filter = (mailLocalAddress=%s)
result_attribute = cn

View file

@ -10,8 +10,8 @@ from smtplib import SMTP, SMTPNotSupportedError, SMTPAuthenticationError
conf_file = f'{environ["MACHINE_TEST_DIR"]}/imap.yml'
with open(conf_file) as yaml:
data = load(yaml, Loader=SafeLoader)
parameters = (('user', data['username'], data['password']),
('family', data['username_family'], data['password_family']),
parameters = (('user', data['username'], [data['password']]),
('family', data['username_family'], [data['password_family'], data['password_family'] + "2"]),
)
@ -19,8 +19,8 @@ def get_msg(username, msg='MESSAGE'):
return f'From: {username}\r\nTo: {username}\r\n\r\nSubject: TEST\r\n{msg}\r\n'
@pytest.mark.parametrize('typ, username, password', parameters)
def test_imap_wrong_password(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_wrong_password(typ, username, passwords):
imap = IMAP4_SSL(data['address'])
try:
imap.LOGIN(username, 'b')
@ -30,17 +30,33 @@ def test_imap_wrong_password(typ, username, password):
raise Exception('wrong login !')
@pytest.mark.parametrize('typ, username, password', parameters)
def test_imap_migration(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_migration(typ, username, passwords):
msg = get_msg(username, 'MIGRATION')
if 'FIRST_RUN' in environ:
smtp = SMTP(data['address'], '587')
smtp.starttls()
error = None
for password in passwords:
try:
smtp.login(username, password)
break
except SMTPAuthenticationError as err:
error = err
else:
raise error from error
smtp.sendmail(username, username, msg)
smtp.quit()
imap = IMAP4_SSL(data['address'])
error = None
for password in passwords:
try:
imap.LOGIN(username, password)
break
except Exception as err:
error = err
else:
raise error from error
imap.SELECT(readonly=True)
typ, req = imap.SEARCH(None, 'ALL')
assert typ == 'OK'
@ -53,49 +69,67 @@ def test_imap_migration(typ, username, password):
imap.LOGOUT()
@pytest.mark.parametrize('typ, username, password', parameters)
def test_smtp_no_tls(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_no_tls(typ, username, passwords):
smtp = SMTP(data['address'], '587')
try:
smtp.login(username, password)
raise Exception('no tls!')
except SMTPNotSupportedError:
pass
with pytest.raises(SMTPNotSupportedError):
smtp.login(username, passwords[0])
@pytest.mark.parametrize('typ, username, password', parameters)
def test_smtp_wrong_passwd(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_wrong_passwd(typ, username, passwords):
smtp = SMTP(data['address'], '587')
smtp.starttls()
try:
with pytest.raises(SMTPAuthenticationError):
smtp.login(username, 'a')
raise Exception('wrong password!')
except SMTPAuthenticationError:
pass
smtp.quit()
@pytest.mark.parametrize('typ, username, password', parameters)
def test_smtp_login(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_login(typ, username, passwords):
smtp = SMTP(data['address'], '587')
smtp.starttls()
error = None
for password in passwords:
try:
smtp.login(username, password)
break
except SMTPAuthenticationError as err:
error = err
else:
raise error from error
smtp.quit()
@pytest.mark.parametrize('typ, username, password', parameters)
def test_smtp_sendmail(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_sendmail(typ, username, passwords):
smtp = SMTP(data['address'], '587')
smtp.starttls()
error = None
for password in passwords:
try:
smtp.login(username, password)
break
except SMTPAuthenticationError as err:
error = err
else:
raise error from error
smtp.sendmail(username, username, get_msg(username))
smtp.quit()
@pytest.mark.parametrize('typ, username, password', parameters)
def test_imap_read_mail(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_read_mail(typ, username, passwords):
imap = IMAP4_SSL(data['address'])
error = None
for password in passwords:
try:
imap.LOGIN(username, password)
break
except Exception as err:
error = err
else:
raise error from error
imap.SELECT(readonly=True)
typ, req = imap.SEARCH(None, 'ALL')
assert typ == 'OK'
@ -111,10 +145,18 @@ def test_imap_read_mail(typ, username, password):
imap.LOGOUT()
@pytest.mark.parametrize('typ, username, password', parameters)
def test_imap_delete_mail(typ, username, password):
@pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_delete_mail(typ, username, passwords):
imap = IMAP4_SSL(data['address'])
error = None
for password in passwords:
try:
imap.LOGIN(username, password)
break
except Exception as err:
error = err
else:
raise error from error
imap.SELECT()
typ, req = imap.SEARCH(None, 'ALL')
msg_no = req[0].split()

View file

@ -3,5 +3,8 @@ Créer un utilisateur
su - gitea -s /bin/bash -c "gitea admin user create --username gnunux --password Njw_csh7DeeZtWDxC6WVXDdB-9A --email gnunux@gnunux.info --admin -c /etc/gitea/app.ini"
DEBUG
=====
sed -i 's/info/debug/g' /etc/gitea/app.ini
systemctl restart gitea

View file

@ -1,7 +1,7 @@
format: '0.1'
description: Gitea
depends:
- base-fedora-35
- base-fedora-36
- postgresql-client
- reverse-proxy-client
- relay-mail-client

View file

@ -6,6 +6,7 @@
<file engine="none" source="sysuser-gitea.conf">/sysusers.d/0gitea.conf</file>
<file engine="none" source="tmpfile-gitea.conf">/tmpfiles.d/0gitea.conf</file>
<file>/etc/gitea/app.ini</file>
<file>/tests/gitea.yml</file>
</service>
</services>
<variables>
@ -24,9 +25,11 @@
<variable name="gitea_lfs_jwt_secret" type="password" hidden="True"/>
</family>
<family name="nginx">
<family name="revprox_client">
<variable name="revprox_client_local_location" redefine="True">
<value>/</value>
</variable>
</family>
<variable name="revprox_client_port" redefine="True">
<value>3000</value>
</variable>

View file

@ -19,10 +19,10 @@ ROOT = /srv/gitea/lib/data/gitea-repositories
DEFAULT_BRANCH = main
[server]
SSH_DOMAIN = %%revprox_client_external_domainname
DOMAIN = %%revprox_client_external_domainname
SSH_DOMAIN = %%revprox_client_external_domainnames[0]
DOMAIN = %%revprox_client_external_domainnames[0]
HTTP_PORT = 3000
ROOT_URL = https://%%revprox_client_external_domainname/gitea/
ROOT_URL = https://%%revprox_client_external_domainnames[0]/gitea/
LOCAL_ROOT_URL = https://%%domain_name_eth0:3000/
DISABLE_SSH = false
START_SSH_SERVER = true

View file

@ -16,7 +16,7 @@ User=gitea
Group=gitea
WorkingDirectory=/srv/gitea/lib/
ExecStart=/usr/bin/gitea web --config /etc/gitea/app.ini
ExecStartPost=-/usr/bin/timeout 90 bash -c 'while ! /usr/bin/gitea admin auth list --config /etc/gitea/app.ini | grep "OAuth2"; do echo "TRY TO CONFIGURE"; /usr/bin/gitea admin auth add-oauth --name "%%domain_name_eth0" --provider "openidConnect" --key "%%oauth2_client_id" --secret "%%oauth2_client_secret" --scopes "profile email" --auto-discover-url "https://%%oauth2_client_server_domainname/.well-known/openid-configuration" --config /etc/gitea/app.ini; sleep 2; done; echo "CONFIGURATION DONE"'
ExecStartPre=-/bin/bash -c 'if /usr/bin/gitea admin auth list --config /etc/gitea/app.ini | grep "OAuth2"; then echo "UPDATE";id=$(/usr/bin/gitea --config /etc/gitea/app.ini admin auth list |tail -n 1|awk "{ print \$1}");/usr/bin/gitea admin auth update-oauth --id $id --name "%%domain_name_eth0" --provider "openidConnect" --key "%%oauth2_client_id" --secret "%%oauth2_client_secret" --scopes "profile email" --auto-discover-url "https://%%oauth2_client_server_domainname/.well-known/openid-configuration" --config /etc/gitea/app.ini;else echo "CONFIGURE"; /usr/bin/gitea admin auth add-oauth --name "%%domain_name_eth0" --provider "openidConnect" --key "%%oauth2_client_id" --secret "%%oauth2_client_secret" --scopes "profile email" --auto-discover-url "https://%%oauth2_client_server_domainname/.well-known/openid-configuration" --config /etc/gitea/app.ini;fi;sleep 2; echo "CONFIGURATION DONE"'
Restart=always
Environment=USER=gitea HOME=/srv/gitea/home GITEA_WORK_DIR=/srv/gitea/lib

View file

@ -0,0 +1,10 @@
%set %%username="rougail_test@silique.fr"
ip: %%ip_eth0
revprox_ip: %%revprox_client_server_ip
%set %%domain = %%revprox_client_external_domainnames[0]
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)
gitea_title: "%%gitea_title"

View file

@ -0,0 +1,226 @@
from yaml import load, SafeLoader
from os import environ, makedirs
from os.path import expandvars, isfile, isdir, dirname, join
from re import search
from dulwich.porcelain import init, clone, add, commit, push
from tempfile import TemporaryDirectory
from subprocess import run
from revprox import Authentication
from mookdns import MookDnsSystem
PORT = '3000'
GITEA_USERNAME = 'gitea'
KEY_FILE = expandvars("$HOME/tests/risotto")
AUTHENTICATION = None
DATA = None
def get_data():
global DATA
if not DATA:
conf_file = f'{environ["MACHINE_TEST_DIR"]}/gitea.yml'
with open(conf_file) as yaml:
DATA = load(yaml, Loader=SafeLoader)
return DATA
def get_authentication(data):
global AUTHENTICATION
if not AUTHENTICATION:
AUTHENTICATION = Authentication(data['auth_url'],
data['auth_server'],
data['revprox_ip'],
data['username'],
data['password'],
f'<title>{data["username"]} - Dashboard - {data["gitea_title"]}</title>',
)
return AUTHENTICATION
def get_info(authentication,
url,
with_uid=False,
with_data_id=False,
found_string=None
):
# <input type="hidden" name="_csrf" value="YQbVgdYHX_3VQ-KuZ5cKtr9RzXE6MTY1NzgxMzUzNTA0OTYwODQ0NQ">
pattern_csrf = r'name="_csrf" value="([a-zA-Z0-9\-\_=]+)"'
ret = authentication.get(url)
csrf = search(pattern_csrf, ret)[1]
ret_data = []
if with_uid:
pattern_uid = r'input type="hidden" id="uid" name="uid" value="(\d)+"'
uid = search(pattern_uid, ret)
if uid is None:
ret_data.append(uid)
else:
ret_data.append(uid[1])
if with_data_id:
pattern_uid = r'/user/settings/keys/delete?type=ssh" data-id="(\d)+"'
uid = search(pattern_uid, ret)
if uid is None:
ret_data.append(uid)
else:
ret_data.append(uid[1])
if found_string:
ret_data.append(found_string in ret)
ret_data.append(csrf)
if len(ret_data) == 1:
return ret_data[0]
return ret_data
def add_ssh_key(authentication, data):
# Send key to gitea
url = f'{data["base_url"]}user/settings/keys'
is_already_key, csrf = get_info(authentication, url, found_string='test_key_risotto')
if is_already_key:
return
# Gen SSH key if needed
if not isfile(KEY_FILE):
key_dir = dirname(KEY_FILE)
if not isdir(key_dir):
makedirs(key_dir)
cmd = ['/usr/bin/ssh-keygen', '-N', '', '-f', KEY_FILE]
run(cmd)
with open(f'{KEY_FILE}.pub') as fh:
key = fh.read()
authentication.post(url, {'_csrf': csrf, 'title': 'test_key_risotto', 'content': key, 'type': 'ssh'})
def delete_ssh_key(authentication, data):
url = f'{data["base_url"]}user/settings/keys'
is_already_key, csrf = get_info(authentication, url, found_string='test_key_risotto')
if is_already_key:
uid, csrf = get_info(authentication, url, with_data_id=True)
url = f'{data["base_url"]}user/settings/keys/delete?type=ssh'
authentication.post(url, {'_csrf': csrf, 'id': uid})
is_already_key, csrf = get_info(authentication, url, found_string='test_key_risotto')
def test_gitea():
data = get_data()
get_authentication(data)
def test_gitea_repos():
data = get_data()
authentication = get_authentication(data)
if 'FIRST_RUN' in environ:
url = f'{data["base_url"]}repo/create'
uid, csrf = get_info(authentication, url, with_uid=True)
authentication.post(url, {'_csrf': csrf, 'uid': uid, 'repo_name': 'test_persistent'})
url = f'{data["base_url"]}api/v1/repos/search?sort=updated&order=desc&uid=1&team_id=0&q=&page=1&mode='
json = authentication.get(url, json=True)
assert json['ok']
assert len(json['data']) == 1
username = data['username'].split('@', 1)[0]
assert json['data'][0]['full_name'] == f'{username}/test_persistent'
def test_gitea_create_repo():
data = get_data()
authentication = get_authentication(data)
url = f'{data["base_url"]}repo/create'
uid, csrf = get_info(authentication, url, with_uid=True)
authentication.post(url, {'_csrf': csrf, 'uid': uid, 'repo_name': 'test', 'default_branch': 'main'})
url = f'{data["base_url"]}api/v1/repos/search?sort=updated&order=desc&uid=1&team_id=0&q=&page=1&mode='
json = authentication.get(url, json=True)
assert json['ok']
assert len(json['data']) == 2
username = data['username'].split('@', 1)[0]
assert {dat['full_name'] for dat in json['data']} == set([f'{username}/test_persistent', f'{username}/test'])
def test_repo():
data = get_data()
authentication = get_authentication(data)
if 'FIRST_RUN' in environ:
# delete_ssh_key(authentication, data)
add_ssh_key(authentication, data)
with TemporaryDirectory() as tmpdirname:
username = data['username'].split('@', 1)[0]
dns = data['base_url'].split('/', 3)[2]
ssh_url = f'ssh://{GITEA_USERNAME}@{dns}:2222/{username}/test.git'
with MookDnsSystem(dns, data['ip']):
filename = join(tmpdirname, 'test.txt')
with open(filename, 'w') as fh:
fh.write('test')
repo = init(tmpdirname)
add(repo, filename)
commit(repo, message=b'test commit')
push(repo=repo,
remote_location=ssh_url,
refspecs='master',
)
lst = list(repo.get_walker())
assert len(lst) == 1
assert lst[0].commit.message == b'test commit'
def test_clone_http():
data = get_data()
authentication = get_authentication(data)
if 'FIRST_RUN' in environ:
# delete_ssh_key(authentication, data)
add_ssh_key(authentication, data)
with TemporaryDirectory() as tmpdirname:
username = data['username'].split('@', 1)[0]
dns = data['base_url'].split('/', 3)[2]
http_url = f'{data["base_url"]}{username}/test.git'
with MookDnsSystem(dns, data['revprox_ip']):
repo = clone(http_url, tmpdirname)
lst = list(repo.get_walker())
assert len(lst) == 1
assert lst[0].commit.message == b'test commit'
def test_gitea_delete_repo():
repo_name = 'test'
data = get_data()
authentication = get_authentication(data)
username = data['username'].split('@', 1)[0]
url = f'{data["base_url"]}{username}/{repo_name}/settings'
csrf = get_info(authentication, url)
authentication.post(url, {'_csrf': csrf, 'action': 'delete', 'repo_name': repo_name})
url = f'{data["base_url"]}api/v1/repos/search?sort=updated&order=desc&uid=1&team_id=0&q=&page=1&mode='
json = authentication.get(url, json=True)
assert json['ok']
assert len(json['data']) == 1
username = data['username'].split('@', 1)[0]
assert json['data'][0]['full_name'] == f'{username}/test_persistent'
def test_repo_persistent():
data = get_data()
authentication = get_authentication(data)
if 'FIRST_RUN' in environ:
# delete_ssh_key(authentication, data)
add_ssh_key(authentication, data)
with TemporaryDirectory() as tmpdirname:
username = data['username'].split('@', 1)[0]
dns = data['base_url'].split('/', 3)[2]
ssh_url = f'ssh://{GITEA_USERNAME}@{dns}:2222/{username}/test_persistent.git'
with MookDnsSystem(dns, data['ip']):
if 'FIRST_RUN' in environ:
filename = join(tmpdirname, 'test.txt')
with open(filename, 'w') as fh:
fh.write('test')
repo = init(tmpdirname)
add(repo, filename)
commit(repo, message=b'test commit')
push(repo=repo,
remote_location=ssh_url,
refspecs='master',
)
else:
repo = clone(ssh_url, tmpdirname)
lst = list(repo.get_walker())
assert len(lst) == 1
assert lst[0].commit.message == b'test commit'

View file

@ -24,7 +24,7 @@
<variables>
<variable name="host_install_dir" type="filename" description="Nom du répertoire comprenant les descriptions d'installation" mandatory="True"/>
<variable name="host_dhcp_filename" type="filename" hidden="True" multi="True"/>
<variable name="host_name" type="domainname" hidden="True"/>
<variable name="host_name" type="domainname" hidden="True" provider="global:server_name" mandatory="True"/>
<variable name="systemd_zone_filename" type="filename" hidden="True" multi="True"/>
<variable name="systemd_netzone_filename" type="filename" hidden="True" multi="True"/>
<family name="network">
@ -64,10 +64,6 @@
<param name="multi" type="boolean">True</param>
<target>systemd_netzone_filename</target>
</fill>
<fill name="calc_value">
<param type="information">server_name</param>
<target>host_name</target>
</fill>
<fill name="get_internal_zone_information">
<param type="variable">zone_name</param>
<param>cidr</param>

View file

@ -7,14 +7,14 @@
</service>
</services>
<variables>
<variable name="machines" description="Machines started in this host" type="domainname" multi="True" provider="machines"/>
<variable name="machines" description="Machines started in this host" type="domainname" multi="True" provider="Host"/>
<family name="machine_" description="Machine " dynamic="machined.machines">
<variable name="incoming_ports_" description="Incomming external ports for " hidden="True" type="port" multi="True" provider="incoming_ports"/>
<variable name="outgoing_ports_" description="Outcoming external ports for " hidden="True" type="port" multi="True" provider="outgoing_ports"/>
<variable name="srv_dir_" description="Directory with srv volume for " hidden="True" type="filename" provider="machine_srv"/>
<variable name="journal_dir_" description="Directory with journal volume for " hidden="True" type="filename" provider="machine_journal"/>
<variable name="config_dir_" description="Directory with configuration volume for " hidden="True" type="filename" provider="machine_config" mandatory="True"/>
<variable name="zones_" description="Zones for " hidden="True" provider="machine_zones" mandatory="True" multi="True"/>
<variable name="incoming_ports_" description="Incomming external ports for " hidden="True" type="port" multi="True" provider="Host:incoming_ports"/>
<variable name="outgoing_ports_" description="Outcoming external ports for " hidden="True" type="port" multi="True" provider="Host:outgoing_ports"/>
<variable name="srv_dir_" description="Directory with srv volume for " hidden="True" type="filename" provider="Host:machine_srv"/>
<variable name="journal_dir_" description="Directory with journal volume for " hidden="True" type="filename" provider="Host:machine_journal"/>
<variable name="config_dir_" description="Directory with configuration volume for " hidden="True" type="filename" provider="Host:config_dir" mandatory="True"/>
<variable name="zones_" description="Zones for " hidden="True" provider="Host:machine_zones" mandatory="True" multi="True"/>
</family>
<variable name="nspawn_zone_filename" type="filename" hidden="True" multi="True"/>
<variable name="nspawn_script_filename" type="filename" hidden="True" multi="True"/>

View file

@ -7,14 +7,7 @@
</services>
<variables>
<family name="imap" description="Client SMTP">
<variable name="imap_address" type="domainname" description="Nom de domaine du serveur IMAP" mandatory="True"/>
<variable name="imap_address" type="domainname" description="Nom de domaine du serveur IMAP" mandatory="True" supplier="IMAP"/>
</family>
</variables>
<constraints>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>IMAP</param>
<target>imap_address</target>
</fill>
</constraints>
</rougail>

View file

@ -12,16 +12,19 @@
<variables>
<family name="annuaire" description="Annuaire OpenLDAP">
<family name="server" description="Serveur">
<variable name='ldap_server_address' type='domainname' description="Nom DNS du serveur LDAP" mandatory='True'/>
<variable name='ldap_server_address' type='domainname' description="Nom DNS du serveur LDAP" mandatory='True' supplier="LDAP"/>
<variable name='ldap_port' type='port' description='Port du serveur LDAP' hidden="True">
<value>636</value>
</variable>
</family>
<family name="client" description="Client">
<variable name='ldapclient_family' type='unix_user' description="Nom de la famille LDAP"/>
<variable name='ldapclient_user' type='string' description="DN de l'utilisateur LDAP" mandatory='False' hidden="True"/>
<variable name='ldapclient_user_password' type='password' description="Mot de passe de l'utilisateur LDAP" mandatory='True' hidden="True"/>
<variable name='ldapclient_base_dn' type='string' description="Base DN de l'annuaire des utilisateurs" mandatory="False"/>
<variable name='ldapclient_family' type='unix_user' description="Nom de la famille LDAP" supplier="LDAP:family"/>
<variable name='ldapclient_user' type='string' description="DN de l'utilisateur LDAP" mandatory='False' hidden="True" supplier="LDAP:dn"/>
<variable name='ldapclient_user_password' type='password' description="Mot de passe de l'utilisateur LDAP" mandatory='True' hidden="True" supplier="LDAP:password"/>
<variable name='ldapclient_base_dn' type='string' description="Base DN de l'annuaire" mandatory="True" supplier="LDAP:base_dn"/>
<variable name='ldapclient_search_dn' type='string' description="Base DN de l'annuaire des utilisateurs" mandatory="True"/>
<variable name='ldapclient_group_dn' type='string' description="Base DN de l'annuaire des groupes" mandatory="True"/>
<variable name='ldapclient_user_dn' type='string' description="Base DN de l'annuaire des utilisateurs n'appartenant à une famille" mandatory="True"/>
<variable name="ldap_ca_file" type="filename" description="Fichier de l'autorité de certification LDAP" hidden="True"/>
<variable name="ldap_cert_file" type="filename" description="Fichier du certificate LDAP" hidden="True"/>
<variable name="ldap_key_file" type="filename" description="Fichier de la clef privée LDAP" hidden="True"/>
@ -38,10 +41,23 @@
<check name='valid_base_dn'>
<target>ldapclient_base_dn</target>
</check>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>LDAP</param>
<target>ldap_server_address</target>
<fill name='get_default_base_dn'>
<param type="variable">ldap_server_address</param>
<target>ldapclient_base_dn</target>
</fill>
<fill name='calc_value'>
<param>ou=accounts</param>
<param type="variable">ldapclient_base_dn</param>
<param name="join">,</param>
<target>ldapclient_search_dn</target>
</fill>
<fill name='calc_value'>
<param>cn=</param>
<param type='variable'>domain_name_eth0</param>
<param>,</param>
<param type='variable'>ldapclient_base_dn</param>
<param name="join"></param>
<target>ldapclient_user</target>
</fill>
<fill name="calc_value">
<param type="variable">tls_ca_directory</param>
@ -61,16 +77,6 @@
<param name="join">/</param>
<target>ldap_key_file</target>
</fill>
<fill name="set_linked_multi_variables">
<param type="variable">ldap_server_address</param>
<param name="linked_provider_0">clients</param>
<param name="linked_value_0" type="variable">domain_name_eth0</param>
<param name="linked_provider_1">client_family</param>
<param name="linked_value_1" type="variable">ldapclient_family</param>
<param name="allow_none_1" type="boolean">True</param>
<param name="linked_returns">dn</param>
<target>ldapclient_user</target>
</fill>
<fill name="get_password">
<param name="server_name" type="variable">ldap_server_address</param>
<param name="username" type="variable">ldapclient_user</param>
@ -80,13 +86,14 @@
<param name="temporary" type="boolean">True</param>
<target>ldapclient_user_password</target>
</fill>
<fill name="set_linked_multi_variables">
<param type="variable">ldap_server_address</param>
<param name="linked_provider_0">client_password</param>
<param name="linked_value_0" type="variable">ldapclient_user_password</param>
<param name="linked_returns">base_dn</param>
<param name="dynamic" type="variable">domain_name_eth0</param>
<target>ldapclient_base_dn</target>
<fill name="calc_ldapclient_base_dn">
<param type="variable">ldapclient_base_dn</param>
<param name="group" type="boolean">True</param>
<target>ldapclient_group_dn</target>
</fill>
<fill name="calc_ldapclient_base_dn">
<param type="variable">ldapclient_base_dn</param>
<target>ldapclient_user_dn</target>
</fill>
</constraints>
</rougail>

View file

@ -11,6 +11,8 @@ def calc_ldapclient_base_dn(ldap_base_dn: str,
base: bool=False,
group: bool=False,
) -> str:
if ldap_base_dn is None:
return
if family_name == 'all':
family_name = None
base = True
@ -28,3 +30,23 @@ def calc_ldapclient_base_dn(ldap_base_dn: str,
if family_name != '-':
base_name = f'ou={family_name},{base_name}'
return base_name
class _Undefined:
pass
_undefined = _Undefined()
def get_default_base_dn(server_name: str) -> str:
if not server_name or '.' not in server_name:
return None
values = server_name.split('.')
# cannot calculated base dn should be server.domain.tld
# remove 'server' in dn
if len(values) < 3:
return None
domain = ['ou=' + domain for domain in values[1:-2]]
domain.append(f'o={values[-2]},o={values[-1]}')
return ','.join(domain)

View file

@ -6,7 +6,7 @@
# This file should be world readable but not world writable.
#BASE dc=example,dc=com
BASE %%ldapclient_base_dn
BASE %%ldapclient_search_dn
#URI ldap://ldap.example.com ldap://ldap-master.example.com:666
URI ldaps://%%ldap_server_address:%%ldap_port

View file

@ -6,4 +6,3 @@ depends:
- reverse-proxy-client
- relay-mail-client
- nginx-common
provider: OAuth2

View file

@ -28,6 +28,7 @@
<variable name="nginx_default_https" redefine="True">
<value>False</value>
</variable>
<variable name="oauth2_client_external_domain" type="domainname" hidden="True" supplier="OAuth2Client:external_domain"/>
</family>
<family name="lemonldap" description="LemonLDAP" help="Configuration de la solution d'authentification unique LemonLDAP::NG">
<variable name="lemon_proc" type="number" description="Nombre de processus dédié à LemonLdap (équivalent au nombre de processeurs)" mandatory="True">
@ -40,15 +41,13 @@
<variable name='ldapclient_family' redefine="True">
<value>all</value>
</variable>
<variable name='ldapclient_group_dn' type='string' description="Base DN de l'annuaire des groupes" mandatory="False"/>
</family>
</family>
</variables>
<constraints>
<fill name="get_linked_configuration">
<param name="linked_server" type="variable">ldap_server_address</param>
<param name="linked_provider">ldap_group</param>
<target>ldapclient_group_dn</target>
<fill name="get_first_value">
<param type="variable">revprox_client_external_domainnames</param>
<target>oauth2_client_external_domain</target>
</fill>
</constraints>
</rougail>

View file

@ -1,23 +1,30 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10">
<variables>
<variable name="remotes" description="Remote clients needing to verify OAuth2 account" type="domainname" multi="True" provider="oauth2"/>
<variable name="remotes" description="Remote clients needing to verify OAuth2 account" type="domainname" multi="True" provider="OAuth2"/>
<family name="oauth2_" description="OAuth2 for " dynamic="oauth2.remotes">
<variable name="secret_" description="Remote secret for " type="password" mandatory="True" hidden="True" provider="oauth2_secret"/>
<variable name="name_" description="Remote name for " hidden="True" provider="oauth2_name"/>
<variable name="description_" description="Remote description for " hidden="True" provider="oauth2_description"/>
<variable name="category_" hidden="True" provider="oauth2_category"/>
<variable name="login_" description="Remote URL to login" hidden="True" provider="oauth2_login"/>
<variable name="secret_" description="Remote secret for " type="password" mandatory="True" hidden="True" provider="OAuth2:secret"/>
<variable name="name_" description="Remote name for " hidden="True" provider="OAuth2:name"/>
<variable name="description_" description="Remote description for " hidden="True" provider="OAuth2:description"/>
<variable name="category_" hidden="True" provider="OAuth2:category"/>
<variable name="login_" description="Remote URL to login" hidden="True" provider="OAuth2:login"/>
<family name="external_" leadership="True">
<variable name="hosts_" description="Remote external for " provider="oauth2_external" multi="True"/>
<variable name="family_" hidden="True" provider="oauth2_family"/>
<variable name="hosts_" description="Remote external for " provider="OAuth2:external" multi="True"/>
<variable name="family_" hidden="True" provider="OAuth2:family"/>
</family>
<variable name="logo_" hidden="True" provider="oauth2_logo"/>
<variable name="token_signature_algo_" type="choice" description="OAuth2 token signature algorithm" mandatory='True' hidden="True" provider="oauth2_token_signature_algo">
<variable name="logo_" hidden="True" provider="OAuth2:logo"/>
<variable name="token_signature_algo_" type="choice" description="OAuth2 token signature algorithm" mandatory='True' hidden="True" provider="OAuth2:token_signature_algo">
<choice>HS512</choice>
<choice>RS256</choice>
</variable>
</family>
<variable name="clients" description="Remote clients" type="domainname" multi="True" supplier="OAuth2Client"/>
</variables>
<constraints>
<fill name="calc_value">
<param type="variable">oauth2.remotes</param>
<target>oauth2.clients</target>
</fill>
</constraints>
</rougail>

View file

@ -3,5 +3,5 @@ After=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 5; 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'

View file

@ -1,3 +1,3 @@
address: %%revprox_client_external_domainname
address: %%revprox_client_external_domainnames[0]
internal_address: %%domain_name_eth0
ip: %%ip_eth0

View file

@ -13,7 +13,7 @@ commentStartToken = §
"ldapPpolicyControl" : 1,
"ldapAllowResetExpiredPassword" : 1,
"ldapChangePasswordAsUser" : 1,
"ldapBase" : "%%ldapclient_base_dn",
"ldapBase" : "%%ldapclient_search_dn",
"ldapExportedVars" : {
"uid" : "uid",
"cn" : "cn",
@ -41,7 +41,7 @@ commentStartToken = §
"mail" : "mail",
"uid" : "uid"
},
"domain" : "%%revprox_client_external_domainname",
"domain" : "%%revprox_client_external_domainnames[0]",
"exportedVars" : {
"UA" : "HTTP_USER_AGENT",
"cn" : "cn",
@ -60,7 +60,7 @@ commentStartToken = §
"namespace" : "lemonldap-ng-sessions"
},
"locationRules" : {
"%%revprox_client_external_domainname" : {
"%%revprox_client_external_domainnames[0]" : {
"default" : "accept"
%set %%domains = []
%for %%app in %%oauth2.remotes
@ -84,7 +84,7 @@ commentStartToken = §
"UA" : "$ENV{HTTP_USER_AGENT}",
"_whatToTrace" : "$_auth eq 'SAML' ? lc($_user.'@'.$_idpConfKey) : $_auth eq 'OpenIDConnect' ? lc($_user.'@'.$_oidc_OP) : lc($_user)"
},
"mailUrl" : "https://%%revprox_client_external_domainname/resetpwd",
"mailUrl" : "https://%%revprox_client_external_domainnames[0]/resetpwd",
"mySessionAuthorizedRWKeys" : [
"_appsListOrder",
"_oidcConnectedRP",
@ -161,12 +161,13 @@ commentStartToken = §
"Directory": "/srv/lemonldap-ng/psessions",
"LockDirectory": "/srv/lemonldap-ng/psessions/lock"
},
"portal" : "https://%%revprox_client_external_domainname/",
"portal" : "https://%%revprox_client_external_domainnames[0]/",
"portalCheckLogins": 0,
"portalDisplayRegister": 0,
"portalDisplayResetPassword": 0,
"portalMainLogo": "risotto/logo.png",
"showLanguages": 0,
"requireToken": "$env->{REMOTE_ADDR} ne '%%gateway_eth0'",
"whatToTrace" : "_whatToTrace",
%set %%remotes = {}
%for %%index, %%app in %%enumerate(%%oauth2.remotes)

View file

@ -48,7 +48,7 @@ server {
# GNUNUX server_name auth.example.com;
#>GNUNUX
listen 443 ssl;
server_name %%revprox_client_external_domainname;
server_name %%{revprox_client_external_domainnames[0]};
ssl_certificate %%revprox_cert_file;
ssl_certificate_key %%revprox_key_file;
ssl_client_certificate %%revprox_ca_file;

View file

@ -56,7 +56,8 @@ def letsencrypt_certif(domain: str,
]
ret = _run(cli_args, capture_output=True)
if ret.returncode != 0:
raise ValueError(ret.stderr.decode())
print("FIXME")
#raise ValueError(ret.stderr.decode())
print("Done")
with open(date_file, 'w') as fh:
fh.write(today)

View file

@ -3,7 +3,7 @@ description: Gestionnaire de liste de diffusion Mailman
depends:
- base-fedora-35
- postgresql-client
- relay-mail-client
- relay-lmtp-client
- reverse-proxy-client
- nginx-common
- oauth2-client

View file

@ -5,7 +5,7 @@
<variable name="name_" description="Nom des listes" type="unix_user" multi="True" mandatory="True"/>
<variable name="names_" description="Address names" type="string" multi="True" mandatory="True" hidden="True"/>
</family>
<variable name="names_" description="Address names" type="string" multi="True" mandatory="True" hidden="True"/>
<variable name="names_" description="Address names" type="string" multi="True" mandatory="True" hidden="True" supplier="LMTP:criteria"/>
</variables>
<constraints>
<fill name="mailman_emails">
@ -17,18 +17,6 @@
<param type="variable">mailman.list_.names_</param>
<target>mailman.names_</target>
</fill>
<check name="set_linked_configuration">
<param name="linked_server" type="variable">smtp_relay_address</param>
<param name="linked_provider">lmtp_server</param>
<param name="linked_value" type="variable">domain_name_eth0</param>
<target>mailman.names_</target>
</check>
<check name="set_linked_configuration">
<param name="linked_server" type="variable">smtp_relay_address</param>
<param name="linked_provider">lmtp_criteria</param>
<param name="dynamic" type="variable">domain_name_eth0</param>
<target>mailman.names_</target>
</check>
</constraints>
</rougail>

View file

@ -13,9 +13,9 @@ DATABASES = {
'OPTIONS': {'sslmode': 'verify-full', 'sslcert': '/etc/pki/tls/certs/postgresql.crt', 'sslkey': '/etc/pki/tls/private/postgresql_postorius.key', 'sslrootcert': '/etc/pki/ca-trust/source/anchors/ca_PostgreSQL.crt'},
}
}
ALLOWED_HOSTS = ['%%revprox_client_external_domainname']
POSTORIUS_TEMPLATE_BASE_URL = 'https://%%revprox_client_external_domainname'
CSRF_TRUSTED_ORIGINS = ['%%revprox_client_external_domainname']
ALLOWED_HOSTS = ['%%{revprox_client_external_domainnames[0]}']
POSTORIUS_TEMPLATE_BASE_URL = 'https://%%{revprox_client_external_domainnames[0]}'
CSRF_TRUSTED_ORIGINS = ['%%{revprox_client_external_domainnames[0]}']
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
LANGUAGE_CODE = 'fr'

View file

@ -19,7 +19,7 @@ RestrictRealtime=yes
PrivateMounts=yes
Environment="MAILMAN_WEB_CONFIG=/usr/share/postorius/m_postorius/settings.py"
ExecStartPre=/usr/share/postorius/manage.py migrate
ExecStartPre=/usr/share/postorius/manage.py shell -c 'from django.contrib.sites.models import Site; site=Site.objects.first(); site.name="%%revprox_client_external_domainname"; site.domain="%%revprox_client_external_domainname"; site.save()'
ExecStartPre=/usr/share/postorius/manage.py shell -c 'from django.contrib.sites.models import Site; site=Site.objects.first(); site.name="%%{revprox_client_external_domainnames[0]}"; site.domain="%%{revprox_client_external_domainnames[0]}"; site.save()'
ExecStartPre=/usr/share/postorius/manage.py shell -c 'from allauth.socialaccount.models import SocialApp; SocialApp.objects.create() if SocialApp.objects.count() == 0 else print("social app already exists"); a=SocialApp.objects.first(); a.name = "%%domain_name_eth0"; a.provider = "risotto"; a.client_id = "%%oauth2_client_id"; a.secret = "%%oauth2_client_secret"; a.sites.set([1]); a.save()'
ExecStartPre=-/usr/share/postorius/manage.py createsuperuser --username "%%mailman_mail_owner" --email "%%mailman_mail_owner" --noinput
ExecStart=/usr/bin/gunicorn --config /etc/postorius/gunicorn_config.py m_postorius.wsgi

View file

@ -5,33 +5,28 @@
</services>
<variables>
<family name="mariadb" description="MariaDB">
<variable name="mariadb_client_server_domainname" type="domainname" description="Nom de domaine du serveur MariaDB" mandatory="True"/>
<variable name="mariadb_client_server_domainname" type="domainname" description="Nom de domaine du serveur MariaDB" mandatory="True" supplier="MariaDB"/>
<variable name="mariadb_client_username" description="Database username" mandatory="True" hidden="True"/>
<variable name="mariadb_client_password" type="secret" description="Database password" mandatory="True" hidden="True"/>
<variable name="mariadb_client_password" type="secret" description="Database password" mandatory="True" hidden="True" supplier="MariaDB:password"/>
<variable name="mariadb_client_database" description="Database name" mandatory="True" hidden="True"/>
</family>
</variables>
<constraints>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>MariaDB</param>
<target>mariadb_client_server_domainname</target>
</fill>
<fill name="set_linked">
<param name="linked_server" type="variable">mariadb_client_server_domainname</param>
<param name="linked_provider">clients</param>
<param name="linked_value" type="variable">domain_name_eth0</param>
<fill name="normalize_family">
<param type="variable">domain_name_eth0</param>
<target>mariadb_client_username</target>
</fill>
<fill name="get_linked_configuration">
<param name="linked_server" type="variable">mariadb_client_server_domainname</param>
<param name="linked_provider">client_password</param>
<param name="dynamic" type="variable">mariadb_client_username</param>
<target>mariadb_client_password</target>
</fill>
<fill name="calc_value">
<param type="variable">mariadb_client_username</param>
<target>mariadb_client_database</target>
</fill>
<fill name="get_password">
<param name="server_name" type="variable">mariadb_client_server_domainname</param>
<param name="username" type="variable">domain_name_eth0</param>
<param name="description">remote</param>
<param name="type">cleartext</param>
<param name="hide" type="variable">hide_secret</param>
<target>mariadb_client_password</target>
</fill>
</constraints>
</rougail>

View file

@ -1,6 +1,4 @@
format: '0.1'
description: Mariadb
depends:
- server
- base-fedora-35
provider: MariaDB
- base-fedora-36

View file

@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10">
<variables>
<variable name="remotes" description="Remote clients needing an account" type="domainname" multi="True" provider="MariaDB"/>
<family name="remote_" description="Account for " dynamic="accounts.remotes">
<variable name="password_" description="Remote password" auto_save="False" hidden="True" type="password" mandatory="True" provider="MariaDB:password"/>
</family>
</variables>
</rougail>

View file

@ -10,4 +10,3 @@ CREATE DATABASE IF NOT EXISTS %%name CHARACTER SET utf8;
GRANT ALL PRIVILEGES ON %%name.* TO '%%name'@'%%server' IDENTIFIED BY '%%password';
%end for
FLUSH PRIVILEGES;

View file

@ -5,7 +5,7 @@
<service name="nextcloudcron" type="timer" engine="none" target="timers"/>
<service name="nextcloud" engine="creole" target="multi-user">
<file owner="apache" group="apache" mode="440" source="nextcloud-config.php">/etc/nextcloud/config.php</file>
<file owner="root" group="apache" mode="750">/etc/nextcloud/nextcloud.init</file>
<file owner="root" group="root" mode="755">/sbin/nextcloud.init</file>
<file>/etc/httpd/conf.d/a-nextcloud-access.conf</file>
<file>/etc/httpd/conf.d/z-nextcloud-access.conf</file>
<file>/etc/php.d/20-pgsql.ini</file>
@ -66,38 +66,12 @@
<param name="hide" type="variable">hide_secret</param>
<target>nextcloud_instance_id</target>
</fill>
<fill name="calc_value">
<param type="variable">revprox_client_external_domainnames</param>
<target>nextcloud_well_known_server</target>
</fill>
<!-- FIXME : check name="set_linked_multi_variables">
<param name="linked_provider_0">revprox_clients</param>
<param name="linked_value_0" type="variable">nextcloud_well_known_server</param>
<param name="linked_provider_1">revprox_location</param>
<param name="linked_value_1">/.well-known/caldav</param>
<param name="linked_provider_2">revprox_is_websocket</param>
<param name="linked_value_2" type="boolean">False</param>
<param name="linked_provider_3">revprox_url</param>
<param name="linked_value_3" type="variable">nextcloud_well_known_caldav</param>
<target>revprox_client_server_domainname</target>
</check-->
<fill name="calc_web_address">
<param type="variable">domain_name_eth0</param>
<param type="variable">revprox_client_port</param>
<param>/.well-known/caldav</param>
<target>nextcloud_well_known_caldav</target>
</fill>
<!-- FIXME : check name="set_linked_multi_variables">
<param name="linked_provider_0">revprox_clients</param>
<param name="linked_value_0" type="variable">nextcloud_well_known_server</param>
<param name="linked_provider_1">revprox_location</param>
<param name="linked_value_1">/.well-known/carddav</param>
<param name="linked_provider_2">revprox_is_websocket</param>
<param name="linked_value_2" type="boolean">False</param>
<param name="linked_provider_3">revprox_url</param>
<param name="linked_value_3" type="variable">nextcloud_well_known_carddav</param>
<target>revprox_client_server_domainname</target>
</check-->
<fill name="calc_web_address">
<param type="variable">domain_name_eth0</param>
<param type="variable">revprox_client_port</param>

View file

@ -11,7 +11,7 @@ $CONFIG = array (
'trusted_domains' =>
array (
0 => 'localhost',
1 => '%%revprox_client_external_domainname',
1 => '%%revprox_client_external_domainnames[0]',
),
'apps_paths' =>
array (
@ -49,7 +49,7 @@ $CONFIG = array (
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'trusted_proxies' => '%%revprox_client_server_ip',
'overwritehost' => '%%revprox_client_external_domainname',
'overwritehost' => '%%revprox_client_external_domainnames[0]',
'filelocking.enabled' => true,
'redis' => [
'host' => '%%redis_client_server_domainname',

View file

@ -29,9 +29,9 @@ fi
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapPort "%%ldap_port"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapAgentName "%%ldapclient_user"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapAgentPassword "%%ldapclient_user_password"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapBase "%%ldapclient_base_dn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapBaseUsers "%%ldapclient_base_dn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapBaseGroups "%%ldapclient_base_dn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapBase "%%ldapclient_search_dn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapBaseUsers "%%ldapclient_user_dn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapBaseGroups "%%ldapclient_group_dn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapExperiencedAdmin "0"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapExpertUUIDUserAttr "cn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapLoginFilter "(&(cn=%uid)(ObjectClass=inetOrgPerson))"

View file

@ -8,7 +8,7 @@ Type=oneshot
WorkingDirectory=/usr/share/nextcloud
#FIXME
ExecStart=+/usr/bin/chmod +w /etc/nextcloud/config.php
ExecStart=/etc/nextcloud/nextcloud.init
ExecStart=/usr/local/lib/sbin/nextcloud.init
ExecStart=+/usr/bin/chmod -w /etc/nextcloud/config.php
User=apache
Group=apache

View file

@ -3,4 +3,3 @@ description: Nginx as reverse proxy
depends:
- base-fedora-36
- nginx-common
provider: ReverseProxy

View file

@ -5,8 +5,8 @@
<override engine="creole"/>
<file source="nginx-options-rp.conf">/etc/nginx/conf.d/options-rp.conf</file>
<file source="revprox-nginx.conf">/etc/nginx/conf.d/risotto.conf</file>
<file source="certificate.crt" file_type="variable" mode="600" variable="revprox_domainnames_all">nginx_certificate_filename</file>
<file source="private.key" file_type="variable" mode="600" variable="revprox_domainnames_all">nginx_private_key_filename</file>
<file source="certificate.crt" file_type="variable" mode="600" variable="nginx.revprox_domainnames">nginx.nginx_certificate_filename</file>
<file source="private.key" file_type="variable" mode="600" variable="nginx.revprox_domainnames">nginx.nginx_private_key_filename</file>
<file>/tests/reverse-proxy.yml</file>
</service>
</services>
@ -22,34 +22,6 @@
<variable name="nginx_default_http" redefine="True">
<value>True</value>
</variable>
<variable name="revprox_domainnames" type="domainname" description="Nom des domaines à configurer dans le serveur mandataire inverse" help="Liste des domaines gérés par le serveur mandataire inverse" multi="True"/>
<variable name="revprox_domainnames_auto" type="domainname" description="Nom des domaines auto-configurés dans le serveur mandataire inverse" multi="True" provider="revprox_clients" hidden="True"/>
<variable name="revprox_domainnames_all" type="domainname" description="Tous les noms de domaines" multi="True" hidden="True"/>
<variable name='nginx_private_key_filename' type="filename" description="Private key filename" hidden='True' multi='True'/>
<variable name='nginx_certificate_filename' type="filename" description="Certificate filename" hidden='True' multi='True'/>
</family>
</variables>
<constraints>
<fill name="nginx_concat_lists">
<param type="variable">revprox_domainnames</param>
<param type="variable">revprox_domainnames_auto</param>
<target>revprox_domainnames_all</target>
</fill>
<fill name="calc_value">
<param>/etc/pki/tls/certs/</param>
<param type="variable">revprox_domainnames_all</param>
<param>.crt</param>
<param name="join"></param>
<param name="multi" type="boolean">True</param>
<target>nginx_certificate_filename</target>
</fill>
<fill name="calc_value">
<param>/etc/pki/tls/private/</param>
<param type="variable">revprox_domainnames_all</param>
<param>.key</param>
<param name="join"></param>
<param name="multi" type="boolean">True</param>
<target>nginx_private_key_filename</target>
</fill>
</constraints>
</rougail>

View file

@ -1,16 +1,40 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10">
<variables>
<family name="reverse_proxy_for_" description="Serveur mandataire inverse pour " dynamic="revprox_domainnames_all">
<variable name="revprox_domain_wildcard_" description="Activer la redirection pour tous les sous-domaines" help="Exemple pour &quot;domaine&quot; : tous les sous-domaines de &quot;domaine&quot; seront redirigés" type="boolean">
<value>False</value>
</variable>
<variable name="remotes" type="domainname" description="Nom des domaines dans le serveur mandataire inverse" multi="True" provider="ReverseProxy"/>
<family name="reverse_proxy_for_" description="Serveur mandataire inverse pour " dynamic="nginx.remotes">
<family name="reverse_proxy_" description="Reverse proxy " help="Paramètrage du proxy inverse" leadership="True">
<variable name="revprox_location_" type="filename" description="Répertoire ou nom de la page à rediriger pour " help="URL relative (sans le nom de domaine) redirigée pour l'adresse définie dans la variable ci-dessus (exemple &quot;/mail&quot;)" mandatory="True" multi="True" provider="revprox_location"/>
<variable name="revprox_url_" type="web_address" description="Domaine de destination ou URI complète pour " mandatory="True" help="Nom de domaine ou IP de destination, par exemple &quot;http://domainelocal&quot; ou URI, par exemple &quot;http://domainelocal/dir/&quot;" provider="revprox_url"/>
<variable name="revprox_is_websocket_" type="boolean" description="Le point d'entré est de types websocket pour " mandatory="True" provider="revprox_is_websocket"/>
<variable name="revprox_max_body_size_" description="Taille maximum du corps pour " provider="revprox_max_body_size"/>
<variable name="revprox_domainnames_" type="domainname" description="Nom des domaines auto-configurés dans le serveur mandataire inverse" multi="True" provider="ReverseProxy:external" hidden="True"/>
<variable name="revprox_location_" type="filename" description="Répertoire ou nom de la page à rediriger pour " help="URL relative (sans le nom de domaine) redirigée pour l'adresse définie dans la variable ci-dessus (exemple &quot;/mail&quot;)" mandatory="True" multi="True" provider="ReverseProxy:location"/>
<variable name="revprox_url_" type="web_address" description="Domaine de destination ou URI complète pour " mandatory="True" help="Nom de domaine ou IP de destination, par exemple &quot;http://domainelocal&quot; ou URI, par exemple &quot;http://domainelocal/dir/&quot;" provider="ReverseProxy:url"/>
<variable name="revprox_is_websocket_" type="boolean" description="Le point d'entré est de types websocket pour " mandatory="True" multi="True" provider="ReverseProxy:websocket"/>
<variable name="revprox_max_body_size_" description="Taille maximum du corps pour " provider="ReverseProxy:max_body_size"/>
</family>
</family>
<variable name="revprox_domainnames" type="domainname" description="Nom des domaines auto-configurés dans le serveur mandataire inverse" multi="True" hidden="True"/>
<variable name='nginx_private_key_filename' type="filename" description="Private key filename" hidden='True' multi='True'/>
<variable name='nginx_certificate_filename' type="filename" description="Certificate filename" hidden='True' multi='True'/>
</variables>
<constraints>
<fill name="nginx_list">
<param type="variable">nginx.reverse_proxy_for_.reverse_proxy_.revprox_domainnames_</param>
<target>nginx.revprox_domainnames</target>
</fill>
<fill name="calc_value">
<param>/etc/pki/tls/certs/</param>
<param type="variable">nginx.revprox_domainnames</param>
<param>.crt</param>
<param name="join"></param>
<param name="multi" type="boolean">True</param>
<target>nginx.nginx_certificate_filename</target>
</fill>
<fill name="calc_value">
<param>/etc/pki/tls/private/</param>
<param type="variable">nginx.revprox_domainnames</param>
<param>.key</param>
<param name="join"></param>
<param name="multi" type="boolean">True</param>
<target>nginx.nginx_private_key_filename</target>
</fill>
</constraints>
</rougail>

View file

@ -1,9 +1,11 @@
from typing import List as _List
from risotto.utils import multi_function
from risotto.utils import multi_function as _multi_function
@multi_function
def nginx_concat_lists(list1: _List[str],
list2: _List[str],
) -> _List[str]:
return list1 + list2
@_multi_function
def nginx_list(lst):
ret = []
for l in lst:
ret.extend(l)
ret = list(set(ret))
ret.sort()
return ret

View file

@ -1,9 +1,9 @@
%set %%domains = set()
%for %%domainname in %%revprox_domainnames_all
%for %%domainname in %%nginx.remotes
%set %%family = %%normalize_family(%%domainname)
%set %%revprox = %%nginx['reverse_proxy_for_' + family]['reverse_proxy_' + family]
%for %%location in %%revprox['revprox_location_' + family]
%set %%domain = %%location['revprox_url_' + family].split('/', 3)[2].split(':')[0]
%for %%domain in %%revprox['revprox_domainnames_' + family]
%set %%domain = %%domain['revprox_url_' + family].split('/', 3)[2].split(':')[0]
%%domains.add(%%domain)%slurp
%end for
%end for

View file

@ -1,10 +1,12 @@
address: %%ip_eth0
urls:
%for %%domain in %%revprox_domainnames_all
%for %%domain in %%nginx.remotes
%set %%suffix = %%normalize_family(%%domain)
%for %%location in %%nginx['reverse_proxy_for_' + %%suffix]['reverse_proxy_' + %%suffix]['revprox_location_' + %%suffix]
%if not %%location['revprox_is_websocket_' + %%suffix]
- %%domain%%location
%for %%revprox in %%nginx['reverse_proxy_for_' + %%suffix]['reverse_proxy_' + %%suffix]['revprox_domainnames_' + %%suffix]
%for %%loc_idx, %%location in %%enumerate(%%revprox['revprox_location_' + %%suffix])
%if not %%revprox['revprox_is_websocket_' + %%suffix][%%loc_idx]
- %%revprox%%location
%end if
%end for
%end for
%end for

View file

@ -1,7 +1,4 @@
%for %%idx, %%domainname in %%enumerate(%%revprox_domainnames_all)
%set %%family = %%normalize_family(%%domainname)
%set %%revprox = %%nginx['reverse_proxy_for_' + family]['reverse_proxy_' + family]
%set %%wildcard = %%nginx['reverse_proxy_for_' + family]['revprox_domain_wildcard_' + family]
%for %%idx, %%domainname in %%enumerate(%%nginx.revprox_domainnames)
# Configuration HTTP %%domainname
server {
listen 80;
@ -12,19 +9,25 @@ server {
# Configuration HTTPS %%domainname
server {
listen 443 ssl http2;
ssl_certificate %%nginx_certificate_filename[%%idx];
ssl_certificate_key %%nginx_private_key_filename[%%idx];
ssl_certificate %%nginx.nginx_certificate_filename[%%idx];
ssl_certificate_key %%nginx.nginx_private_key_filename[%%idx];
server_name %%domainname;
error_page 403 404 502 503 504 /error.html;
location = /error.html{
root /var/www/html;
}
%for %%location in %%revprox['revprox_location_' + family]
%set %%location_str = %%str(%%location)
%for %%remote in %%nginx.remotes
%set %%family = %%normalize_family(%%remote)
%set %%revprox = %%nginx['reverse_proxy_for_' + %%family]['reverse_proxy_' + %%family]
%for %%rp_domainname in %%revprox['revprox_domainnames_' + %%family]
%if %%domainname != %%str(%%rp_domainname)
%continue
%end if
%for %%loc_idx, %%location in %%enumerate(%%rp_domainname['revprox_location_' + %%family])
location %%location {
proxy_pass %%location['revprox_url_' + family];
%if %%location['revprox_is_websocket_' + family]
proxy_pass %%rp_domainname['revprox_url_' + %%family];
%if %%rp_domainname['revprox_is_websocket_' + %%family][%%loc_idx]
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
@ -42,7 +45,7 @@ server {
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse on;
%set %%maxbody = %%location['revprox_max_body_size_' + family]
%set %%maxbody = %%rp_domainname['revprox_max_body_size_' + %%family]
%if %%maxbody
client_max_body_size %%maxbody;
%end if
@ -51,11 +54,14 @@ server {
root /var/www/html;
}
# If user missing '/'
%if %%location_str != '/' and %%location_str.endswith('/')
location %%location_str[:-1] {
rewrite ^(%%location_str[:-1])$ $1/ permanent;
%if %%location != '/' and %%location.endswith('/')
location %%location[:-1] {
rewrite ^(%%location[:-1])$ $1/ permanent;
}
%end if
%end for
}
%end for
%end for
}
%end for

View file

@ -16,6 +16,11 @@ def req(url, ip, verify=True):
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
@ -29,8 +34,6 @@ def test_revprox():
data = load(yaml, Loader=SafeLoader)
# test unknown domain
url = 'google.fr'
with warnings.catch_warnings():
warnings.simplefilter("ignore")
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 "<title>Test Page for the HTTP Server on Fedora</title>" in content, f'https://{url} returns default fedora page'

View file

@ -3,4 +3,3 @@ description: Configuration du serveur faisant autorité NSD
service: true
depends:
- base-fedora-36
provider: LocalDNS

View file

@ -5,9 +5,9 @@
<override/>
<ip ip_type="variable">nsd_allowed_all_client</ip>
<file>/etc/nsd/conf.d/risotto.conf</file>
<file file_type="variable" source="nsd.zone" variable="nsd_zones_all" included="content">nsd_zone_filenames</file>
<file file_type="variable" source="nsd.zone" variable="nsd_zones" included="content">nsd_zone_filenames</file>
<file file_type="variable" source="nsd.signed" variable="nsd_zone_filenames">nsd_zone_filenames_signed</file>
<file file_type="variable" source="nsd.reverse" variable="nsd_reverse_reverse_name" included="content">nsd_reverse_filenames</file>
<file file_type="variable" source="nsd.reverse" variable="nsd_reverse_name" included="content">nsd_reverse_filenames</file>
<file file_type="variable" source="nsd.signed" variable="nsd_reverse_filenames">nsd_reverse_filenames_signed</file>
<file engine="none" source="sysuser-nsd.conf">/sysusers.d/0nsd.conf</file>
<file engine="none" source="tmpfile-nsd.conf">/tmpfiles.d/0nsd.conf</file>
@ -20,78 +20,59 @@
<variable name="ip_dns" redefine="True" remove_fill="True"/>
</family>
<family name="dns_server" description="Serveur DNS">
<variable name="nsd_allowed_client" type="ip" description="Clients" multi="True" mandatory="True" hidden="True" provider="dns"/>
<variable name="nsd_resolver" type="domainname" description="Nom de domaine du résolveur DNS associé"/>
<variable name="nsd_allowed_client" type="domainname" description="Clients" multi="True" mandatory="True" hidden="True" provider="LocalDNS"/>
<variable name="nsd_allowed_client_ip" type="ip" description="Clients" multi="True" mandatory="True" hidden="True"/>
<variable name="nsd_resolver" type="domainname" description="Nom de domaine du résolveur DNS associé" supplier="ExternalDNS"/>
<variable name="nsd_resolve_ip" type="ip" hidden="True"/>
<variable name="nsd_allowed_all_client" type="ip" description="All autorised IP" multi="True" hidden="True"/>
</family>
<family name="dns_zone" description="Zone DNS">
<variable name="nsd_zones" type="domainname" description="Zones DNS" multi="True"/>
<variable name="nsd_zones_auto" type="domainname" description="Zones DNS automatique" multi="True" hidden="True"/>
<variable name="nsd_zones_all" type="domainname" description="Toutes les zones DNS" multi="True" hidden="True" mandatory="True"/>
</family>
<family name="dns_reverses" description="Zone DNS reverse" leadership="True">
<variable name="nsd_reverse_network" description="Réseau pour la résolution reverse" type="network_cidr" multi="True"/>
<variable name="nsd_reverse_reverse_name" description="Nom de la zone" hidden="True"/>
<variable name="nsd_reverse_name" description="Nom de la zone" hidden="True"/>
</family>
<variable name="nsd_zones_all" type="domainname" multi="True" supplier="ExternalDNS:authority_zones" hidden="True"/>
<variable name="nsd_zone_filenames" type="filename" description="Nom des fichiers de zone" multi="True" hidden="True"/>
<variable name="nsd_zone_filenames_signed" type="filename" description="Nom des fichiers de zone signé" multi="True" hidden="True"/>
<variable name="nsd_reverse_filenames" type="filename" description="Nom des fichiers de zone reverse" multi="True" hidden="True"/>
<variable name="nsd_reverse_filenames_signed" type="filename" description="Nom des fichiers de zone reverse signé" multi="True" hidden="True"/>
</variables>
<constraints>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>ExternalDNS</param>
<target>nsd_resolver</target>
</fill>
<fill name="calc_value">
<param type="variable">ip_eth0</param>
<target>ip_dns</target>
</fill>
<fill name="nsd_concat_lists">
<param type="variable">ip_eth</param>
<fill name="get_ip">
<param type="variable">nsd_allowed_client</param>
<param type="variable">nsd_resolve_ip</param>
<target>nsd_allowed_all_client</target>
</fill>
<fill name="set_linked">
<param name="linked_server" type="variable">nsd_resolver</param>
<param name="linked_provider">authorities</param>
<param name="linked_value" type="variable">domain_name_eth0</param>
<param name="linked_returns">ip</param>
<param name="dynamic">0</param>
<target>nsd_resolve_ip</target>
</fill>
<check name="set_linked_configuration">
<param name="linked_server" type="variable">nsd_resolver</param>
<param name="leader_provider">authorities</param>
<param name="leader_value" type="variable">domain_name_eth0</param>
<param name="linked_provider">authority_zones</param>
<target>nsd_zones_all</target>
</check>
<check name="set_linked_configuration">
<param name="linked_server" type="variable">nsd_resolver</param>
<param name="leader_provider">authorities</param>
<param name="leader_value" type="variable">domain_name_eth0</param>
<param name="linked_provider">authority_zones</param>
<target>nsd_reverse_reverse_name</target>
</check>
<fill name="get_internal_zones">
<target>nsd_zones_auto</target>
<target>nsd_allowed_client_ip</target>
</fill>
<fill name="nsd_concat_lists">
<param type="variable">nsd_zones</param>
<param type="variable">nsd_zones_auto</param>
<param type="variable">nsd_reverse_name</param>
<target>nsd_zones_all</target>
</fill>
<fill name="nsd_concat_lists">
<param type="variable">ip_eth</param>
<param type="variable">nsd_allowed_client_ip</param>
<param type="variable">nsd_resolve_ip</param>
<target>nsd_allowed_all_client</target>
</fill>
<fill name="get_ip">
<param type="variable">nsd_resolver</param>
<target>nsd_resolve_ip</target>
</fill>
<fill name="get_internal_zones">
<target>nsd_zones</target>
</fill>
<fill name="get_reverse_name">
<param type="variable">nsd_reverse_network</param>
<target>nsd_reverse_reverse_name</target>
<target>nsd_reverse_name</target>
</fill>
<fill name="calc_value">
<param>/etc/nsd/</param>
<param type="variable">nsd_zones_all</param>
<param type="variable">nsd_zones</param>
<param>.zone</param>
<param name="join"></param>
<param name="multi" type="boolean">True</param>
@ -106,7 +87,7 @@
</fill>
<fill name="calc_value">
<param>/etc/nsd/</param>
<param type="variable">nsd_reverse_reverse_name</param>
<param type="variable">nsd_reverse_name</param>
<param>reverse</param>
<param name="join"></param>
<param name="multi" type="boolean">True</param>

View file

@ -1,8 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10">
<variables>
<family name="nsd_zone_" description="Zone " dynamic="nsd_zones_all">
<variable name="is_auto_" description="Le domaine est automatique " type="boolean" hidden="True"/>
<family name="nsd_zone_" description="Zone " dynamic="nsd_zones" hidden="True">
<family name="hostname_" description="Nom d'hôte pour " leadership="True">
<variable name="hostname_" description="Nom d'hôte pour " type="hostname" multi="True" mandatory="True"/>
<variable name="type_" description="Type pour " type="choice">
@ -16,20 +15,13 @@
</family>
</variables>
<constraints>
<fill name="value_in">
<param type="suffix"/>
<param type="variable">nsd_zones_auto</param>
<target>nsd.nsd_zone_.is_auto_</target>
</fill>
<fill name="get_internal_info_in_zone">
<param type="suffix"/>
<param type="variable">nsd.nsd_zone_.is_auto_</param>
<param>host</param>
<target>nsd.nsd_zone_.hostname_.hostname_</target>
</fill>
<fill name="get_internal_info_in_zone">
<param type="suffix"/>
<param type="variable">nsd.nsd_zone_.is_auto_</param>
<param>ip</param>
<param type="index"/>
<target>nsd.nsd_zone_.hostname_.ip_</target>
@ -42,9 +34,5 @@
<param>CNAME</param>
<target type="variable">nsd.nsd_zone_.hostname_.ip_</target>
</condition>
<condition name="hidden_if_in" source="nsd.nsd_zone_.is_auto_">
<param type="boolean">True</param>
<target type="family">nsd.nsd_zone_.hostname_</target>
</condition>
</constraints>
</rougail>

View file

@ -8,6 +8,8 @@ from shutil import rmtree as _rmtree, copy2 as _copy2
from glob import glob as _glob
from filecmp import cmp as _cmp
from risotto.utils import DOMAINS as _DOMAINS
_PKI_DIR = _abspath('pki/dnssec')
_ALGO = 'ECDSAP256SHA256'
@ -32,9 +34,11 @@ def nsd_concat_lists(list1: _List[str],
list2: _List[str],
str1: str=None,
) -> _List[str]:
ret = list1 + list2
ret = set(list1 + list2)
if str1:
ret.append(str1)
ret.add(str1)
ret = list(ret)
ret.sort()
return ret
@ -117,3 +121,14 @@ def sign(zone_filename: str,
with open(signed_filename) as fh:
content = fh.read().strip()
return content
def get_internal_info_in_zone(zone: str,
type: str,
index: int=None,
) -> _List[str]:
if zone not in _DOMAINS:
return []
if type == 'host':
return list(_DOMAINS[zone][0])
return _DOMAINS[zone][1][index]

View file

@ -1,6 +1,6 @@
%set %%name = None
%set %%network = %%ip_network(%%nsd_reverse_network[%%rougail_index])
%for %%zone in %%nsd_zones_all
%for %%zone in %%nsd_zones
%set %%suffix = %%normalize_family(%%zone)
%set %%hostnames = %%nsd["nsd_zone_" + %%suffix]["hostname_" + %%suffix]["hostname_" + %%suffix]
%for %%hostname in %%hostnames

View file

@ -1,6 +1,6 @@
address: '%%ip_eth0'
records:
%for %%domain in %%nsd_zones_all
%for %%domain in %%nsd_zones
%set %%suffix = %%normalize_family(%%domain)
%set %%hostnames = %%nsd["nsd_zone_" + %%suffix]["hostname_" + %%suffix]["hostname_" + %%suffix]
%for %%nsd in %%hostnames

View file

@ -10,7 +10,7 @@ server:
remote-control:
control-enable: no
%for %%zone in %%nsd_zones_all
%for %%zone in %%nsd_zones
zone:
name: "%%zone"
@ -19,6 +19,6 @@ zone:
%for %%reverse in %%nsd_reverse_network
zone:
name: "%%reverse.nsd_reverse_reverse_name"
zonefile: "%%{reverse.nsd_reverse_reverse_name}reverse.signed"
name: "%%reverse.nsd_reverse_name"
zonefile: "%%{reverse.nsd_reverse_name}reverse.signed"
%end for

View file

@ -2,41 +2,37 @@
<rougail version="0.10">
<variables>
<family name="oauth2_client" description="OAuth2 client">
<variable name="oauth2_client_server_domainname" type="domainname" description="OAuth2 server domain name" mandatory='True'/>
<variable name="oauth2_client_server_domainname" type="domainname" description="OAuth2 server domain name" mandatory='True' supplier="OAuth2"/>
<variable name="oauth2_is_client_application" type="boolean" description="OAuth2 client is an application" mandatory='True'>
<value>False</value>
</variable>
<variable name="oauth2_client_name" description="OAuth2 client name" mandatory='True'/>
<variable name="oauth2_client_description" description="OAuth2 client description" mandatory='True'/>
<variable name="oauth2_client_login" type="web_address" description="OAuth2 URL to valid login"/>
<variable name="oauth2_client_name" description="OAuth2 client name" mandatory='True' supplier="OAuth2:name"/>
<variable name="oauth2_client_description" description="OAuth2 client description" mandatory='True' supplier="OAuth2:description"/>
<variable name="oauth2_client_login" type="web_address" description="OAuth2 URL to valid login" supplier="OAuth2:login"/>
<family name="external">
<variable name="oauth2_client_external" type="web_address" description="OAuth2 client external" mandatory='True' multi="True"/>
<variable name="oauth2_client_family" description="OAuth2 family">
<variable name="oauth2_client_external" type="web_address" description="OAuth2 client external" mandatory='True' multi="True" supplier="OAuth2:external"/>
<variable name="oauth2_client_family" description="OAuth2 family" supplier="OAuth2:family">
<value>users</value>
</variable>
</family>
<variable name="oauth2_client_category" description="OAuth2 category" mandatory='True'>
<variable name="oauth2_client_category" description="OAuth2 category" mandatory='True' supplier="OAuth2:category">
<value>Défaut</value>
</variable>
<variable name="oauth2_client_logo" description="OAuth2 logo" mandatory='True'>
<variable name="oauth2_client_logo" description="OAuth2 logo" mandatory='True' supplier="OAuth2:logo">
<value>demo.png</value>
</variable>
<variable name="oauth2_client_id" description="OAuth2 ID" mandatory='True' hidden='True'/>
<variable name="oauth2_client_secret" type="password" description="OAuth2 secret" mandatory='True' hidden='True'/>
<variable name="oauth2_client_token_signature_algo" type="choice" description="OAuth2 token signature algorithm" mandatory='True' hidden='True'>
<variable name="oauth2_client_secret" type="password" description="OAuth2 secret" mandatory='True' hidden='True' supplier="OAuth2:secret"/>
<variable name="oauth2_client_token_signature_algo" type="choice" description="OAuth2 token signature algorithm" mandatory='True' hidden='True' supplier="OAuth2:token_signature_algo">
<value>HS512</value>
<choice>HS512</choice>
<choice>RS256</choice>
</variable>
<variable name="oauth2_server_domainname" type="domainname" description="OAuth2 server domain name" mandatory='True' hidden='True'/>
<variable name="oauth2_clients" description="Remote clients" type="domainname" multi="True" provider="OAuth2Client"/>
<variable name="oauth2_server_domainname" type="domainname" description="OAuth2 server domain name" mandatory='True' provider="OAuth2Client:external_domain"/>
</family>
</variables>
<constraints>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>OAuth2</param>
<target>oauth2_client_server_domainname</target>
</fill>
<fill name="normalize_family">
<param type="variable">domain_name_eth0</param>
<target>oauth2_client_id</target>
@ -49,32 +45,6 @@
<param name="hide" type="variable">hide_secret</param>
<target>oauth2_client_secret</target>
</fill>
<fill name="set_linked_multi_variables">
<param type="variable">oauth2_client_server_domainname</param>
<param name="linked_value_0" type="variable">domain_name_eth0</param>
<param name="linked_provider_0">oauth2</param>
<param name="linked_value_1" type="variable">oauth2_client_secret</param>
<param name="linked_provider_1">oauth2_secret</param>
<param name="linked_value_2" type="variable" propertyerror="False">oauth2_client_name</param>
<param name="linked_provider_2">oauth2_name</param>
<param name="linked_value_3" type="variable" propertyerror="False">oauth2_client_description</param>
<param name="linked_provider_3">oauth2_description</param>
<param name="linked_value_4" type="variable" propertyerror="False">oauth2_client_external</param>
<param name="linked_provider_4">oauth2_external</param>
<param name="linked_value_5" type="variable" propertyerror="False">oauth2_client_family</param>
<param name="linked_provider_5">oauth2_family</param>
<param name="linked_value_6" type="variable">oauth2_client_category</param>
<param name="linked_provider_6">oauth2_category</param>
<param name="linked_value_7" type="variable">oauth2_client_logo</param>
<param name="linked_provider_7">oauth2_logo</param>
<param name="linked_value_8" type="variable">oauth2_client_login</param>
<param name="linked_provider_8">oauth2_login</param>
<param name="allow_none_8" type="boolean">True</param>
<param name="linked_value_9" type="variable">oauth2_client_token_signature_algo</param>
<param name="linked_provider_9">oauth2_token_signature_algo</param>
<param name="linked_returns">external_domainname</param>
<target>oauth2_server_domainname</target>
</fill>
<fill name="calc_oauth2_client_external">
<param type="variable" optional="True">revprox_client_external_domainnames</param>
<param type="variable" optional="True">revprox_client_location</param>

View file

@ -4,6 +4,8 @@ from risotto.utils import multi_function as _multi_function
@_multi_function
def calc_oauth2_client_external(external, location, *extras):
if not external or not location or None in extras:
if isinstance(external, list):
return []
return
if isinstance(external, list):
return [f'https://{exter}{location[0]}' + ''.join(extras) for exter in external]

View file

@ -27,4 +27,8 @@ grep ldapAgentPassword /etc/nextcloud/nextcloud.init
Search information with standard user:
ldapsearch -D cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info -w "1vCE09NRW2kxHIpf1PkehOS9bSLZual82saHSBj9RPM" -b cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info
ldapsearch -D cn=admin,ou=in,o=gnunux,o=info -w "1vCE09NRW2kxHIpf1PkehOS9bSLZual82saHSBj9RPM" -b cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info
# Delete User
ldapdelete -D cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info -y /usr/local/lib/secrets/admin_ldap.pwd cn=rougail_test@gnunux.info,ou=in,o=gnunux,o=info

View file

@ -2,5 +2,4 @@ format: '0.1'
description: OpenLDAP server
depends:
- ldap-client-fedora
- base-fedora-35
provider: LDAP
- base-fedora-36

View file

@ -76,10 +76,9 @@
<variable name='ldapclient_user' redefine="True"/>
<!--variable name='ldapclient_user_password' redefine="True"/-->
<variable name='ldapclient_family' redefine="True" disabled="True"/>
<variable name='ldapclient_base_dn' redefine="True" mandatory="True" provider="ldap_dn" description="Base DN"/>
<variable name='ldapclient_base_dn' redefine="True" mandatory="True" description="Base DN"/>
<variable name='ldap_account_dn' type='string' description="Base DN de l'annuaire des utilisateurs" mandatory="True"/>
<variable name='ldap_user_dn' type='string' description="Base DN de l'annuaire des utilisateurs n'appartenant à une famille" mandatory="True"/>
<variable name='ldap_group_dn' type='string' description="Base DN de l'annuaire des groupes" mandatory="True" provider="ldap_group"/>
<variable name='ldapclient_search_dn' redefine="True"/>
</family>
</family>
</variables>
@ -89,29 +88,20 @@
<param type='variable'>domain_name_eth0</param>
<target>ldap_server_address</target>
</fill>
<fill name='get_default_base_dn'>
<param type="variable">domain_name_eth0</param>
<target>ldapclient_base_dn</target>
</fill>
<fill name="calc_ldapclient_base_dn">
<param type="variable">ldapclient_base_dn</param>
<param name="base" type="boolean">True</param>
<target>ldap_account_dn</target>
</fill>
<fill name="calc_ldapclient_base_dn">
<param type="variable">ldapclient_base_dn</param>
<param name="group" type="boolean">True</param>
<target>ldap_group_dn</target>
</fill>
<fill name="calc_ldapclient_base_dn">
<param type="variable">ldapclient_base_dn</param>
<target>ldap_user_dn</target>
</fill>
<fill name='calc_value'>
<param>cn=admin</param>
<param type='variable'>ldapclient_base_dn</param>
<param name="join">,</param>
<target>ldapclient_user</target>
</fill>
<fill name='calc_value'>
<param type="variable">ldapclient_base_dn</param>
<target>ldapclient_search_dn</target>
</fill>
</constraints>
</rougail>

View file

@ -1,13 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10">
<variables>
<variable name="remotes" description="Serveurs distant ayant un compte" type="domainname" multi="True" provider="clients"/>
<variable name="remotes" description="Serveurs distant ayant un compte" type="domainname" multi="True" provider="LDAP"/>
<family name="remote_" description="Compte LDAP pour " dynamic="accounts.remotes">
<variable name="family_" description="Nom de la familly de " hidden="True" provider="client_family"/>
<variable name="dn_" description="LDAP DN de " hidden="True" provider="dn"/>
<variable name="password_" description="Mot de passe de " hidden="True" provider="client_password"/>
<variable name="base_dn_" description="LDAP base DN de " hidden="True" provider="base_dn"/>
<variable name="read_only_" description="Le compte est en lecture seule de " type="boolean"/>
<variable name="family_" description="Nom de la familly de " hidden="True" provider="LDAP:family"/>
<variable name="dn_" description="LDAP DN de " hidden="True" provider="LDAP:dn"/>
<variable name="password_" description="Mot de passe de " hidden="True" provider="LDAP:password"/>
<variable name="base_dn_" description="LDAP base DN de " hidden="True" provider="LDAP:base_dn"/>
</family>
<family name="users" description="Gestion des utilisateurs" leadership="True">
<variable name='ldap_user_mail' type="mail" description="Adresse courriel du compte" multi="True"/>
@ -30,19 +29,6 @@
</family>
</variables>
<constraints>
<fill name="calc_ldapclient_base_dn">
<param type="variable">ldapclient_base_dn</param>
<param type="variable">accounts.remote_.family_</param>
<target>accounts.remote_.base_dn_</target>
</fill>
<fill name='calc_value'>
<param>cn=</param>
<param type='suffix'></param>
<param>,</param>
<param type='variable'>ldapclient_base_dn</param>
<param name="join"></param>
<target>accounts.remote_.dn_</target>
</fill>
<fill name="get_password">
<param name="server_name" type="variable">domain_name_eth0</param>
<param name="username" type='variable'>accounts.users.ldap_user_mail</param>

View file

@ -29,16 +29,3 @@ def ssha_encode(password):
with open(_SSHA_PASSWORD_DIR, 'w') as fh:
_dump(passwords, fh)
return ret
def get_default_base_dn(server_name: str) -> str:
if not server_name or '.' not in server_name:
return None
values = server_name.split('.')
# cannot calculated base dn should be server.domain.tld
# remove 'server' in dn
if len(values) < 3:
return None
domain = ['ou=' + domain for domain in values[1:-2]]
domain.append(f'o={values[-2]},o={values[-1]}')
return ','.join(domain)

View file

@ -11,11 +11,12 @@
%set %%name = %%normalize_family(%%remote)
%set %%family = %%accounts['remote_' + %%name]['family_' + %%name]
%%groups.append(%%accounts['remote_' + %%name]['dn_' + %%name])%slurp
%if %%accounts['remote_' + %%name]['read_only_' + %%name]
%set %%right = 'read'
%else
%set %%right = 'write'
%end if
# %if %%accounts['remote_' + %%name]['read_only_' + %%name]
# %set %%right = 'read'
# %else
# %set %%right = 'write'
# %end if
%%dns.setdefault(%%family, []).append((%%accounts['remote_' + %%name]['dn_' + %%name], %%right))%slurp
%end for
dn: olcDatabase={2}mdb,cn=config
@ -25,7 +26,7 @@ olcAccess: {0}to attrs=userPassword
by self write
by anonymous auth
by * none
olcAccess: {1}to dn.subtree="%%ldap_group_dn"
olcAccess: {1}to dn.subtree="%%ldapclient_group_dn"
%for group in %%groups
by dn="%%group" read
%end for

View file

@ -1,25 +1,30 @@
%set %%username = "rougail_test@silique.fr"
%set %%username_family = "rougail_test@gnunux.info"
%set %%familydn = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name='gnunux')
%set %%name_family = 'gnunux'
%set %%familydn = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name=%%name_family)
%set %%userdn = 'cn=' + %%username + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn)
%set %%userfamilydn = 'cn=' + %%username_family + ',' + %%familydn
address: %%ip_eth0
admin_dn: %%ldapclient_user
admin_password: %%ldapclient_user_password
user_dn: cn=%%username,%%ldap_user_dn
user_password: %%get_password(server_name=%%ldap_server_address, username=%%username, description="ldap user", type="cleartext", hide=%%hide_secret, temporary=True)
user_family_dn: cn=%%username_family,%%familydn
user_family_password: %%get_password(server_name=%%ldap_server_address, username=%%username_family, description="ldap family user", type="cleartext", hide=%%hide_secret, temporary=True)
user_dn: %%userdn
user_password: %%get_password(server_name='test', username=%%username, description='test', type="cleartext", hide=%%hide_secret, temporary=True)
user_family_dn: %%userfamilydn
user_family_password: %%get_password(server_name='test', username=%%username_family, description="test", type="cleartext", hide=%%hide_secret, temporary=True)
base_account_dn: %%ldap_account_dn
base_user_dn: %%ldap_user_dn
base_user_dn: %%ldapclient_user_dn
base_family_dn: %%familydn
base_group_dn: %%ldap_group_dn
base_group_dn: %%ldapclient_group_dn
%for %%idx in %%range(3)
%set %%name = 'remote_test' + %%str(%%idx)
remote%%idx: cn=%%name,%%ldapclient_base_dn
remote_password%%idx: %%get_password(server_name=%%domain_name_eth0, username=%%name, description="remote account", type="cleartext", hide=%%hide_secret, temporary=True)
%end for
users:
%%username: %%userdn
%%username_family: %%userfamilydn
%for %%user in %%accounts.users.ldap_user_mail
%%user: cn=%%user,%%ldap_user_dn
%%user: cn=%%user,%%ldapclient_user_dn
%end for
%for %%family in %%accounts.families
%set %%families = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, %%family)
@ -29,11 +34,15 @@ users:
%end for
groups:
users:
- %%userdn
%for %%user in %%accounts.users.ldap_user_mail
- cn=%%user,%%ldap_user_dn
- cn=%%user,%%ldapclient_user_dn
%end for
%for %%family in %%accounts.families
%%family:
%if %%family == %%name_family
- %%userfamilydn
%end if
%for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family]
- cn=%%user,%%families
%end for

View file

@ -1,4 +1,6 @@
%set name_family = 'gnunux'
%set %%username="rougail_test@silique.fr"
%set %%username_family="rougail_test@gnunux.info"
%set %%name_family="gnunux"
# BaseDN
%set groups = {}
dn: %%ldapclient_base_dn
@ -38,36 +40,23 @@ objectClass: top
objectClass: organizationalUnit
## Accounts users
%set %%users = %%ldap_user_dn
%set %%users = %%ldapclient_user_dn
dn: %%users
ou: users
objectClass: top
objectClass: organizationalUnit
%set %%userdn = 'cn=' + %%username + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn)
%set %%userfamilydn = 'cn=' + %%username_family + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name=%%name_family)
%set %%acc = [(%%userdn, %%username, %%get_password(server_name='test', username=%%username, description="test", type="cleartext", hide=%%hide_secret, temporary=True), 'Rougail', 'Test', 'rougail_test', [], 'users'),
(%%userfamilydn, %%username_family, %%get_password(server_name='test', username=%%username_family, description='test', type="cleartext", hide=%%hide_secret, temporary=True), 'Rougail', 'Test', 'rougail_test_gnunux', [], %%name_family),
]
%set %%groups['users'] = [%%userdn]
%set %%groups[%%name_family] = [%%userfamilydn]
%for %%user in %%accounts.users.ldap_user_mail
%set %%userdn = "cn=" + %%user + "," + %%users
%%groups.setdefault('users', []).append(%%userdn)
dn: %%userdn
cn: %%user
mail: %%user
sn: %%user.ldap_user_sn
givenName: %%user.ldap_user_gn
uid: %%user.ldap_user_uid
userPassword:: %%ssha_encode(%%user.ldap_user_password)
homeDirectory: /srv/home/users/%%user
mailLocalAddress: %%user
%if %%user.ldap_user_aliases
%for %%alias in %%user.ldap_user_aliases
mailLocalAddress: %%alias
%end for
%end if
uidNumber: 0
gidNumber: 0
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: inetLocalMailRecipient
%%acc.append((%%userdn, %%user, %%user.ldap_user_password, %%user.ldap_user_sn, %%user.ldap_user_gn, %%user.ldap_user_uid, %%user.ldap_user_aliases, 'users'))%slurp
%%groups.setdefault('users', []).append(%%userdn)%slurp
%end for
## Families
dn: %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name='-')
@ -84,18 +73,50 @@ objectClass: organizationalUnit
%for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family]
%set %%userdn = "cn=" + %%user + "," + %%families
%%groups.setdefault(%%family, []).append(%%userdn)
%%groups.setdefault(%%family, []).append(%%userdn)%slurp
%%acc.append((%%userdn, %%user, %%user['ldap_user_password_' + %%family], %%user['ldap_user_sn_' + %%family], %%user['ldap_user_gn_' + %%family], %%user['ldap_user_uid_' + %%family], %%user['ldap_user_aliases_' + %%family], %%family))%slurp
#pouet
#dn: %%userdn
#cn: %%user
#mail: %%user
#sn:
#givenName:
#uid:
#userPassword:: %%ssha_encode()
#homeDirectory: /srv/home/families/%%family/%%user
#mailLocalAddress: %%user
# %if %%user['ldap_user_aliases_' + %%family]
# %for %%alias in
#mailLocalAddress: %%alias
# %end for
# %end if
#uidNumber: 0
#gidNumber: 0
#objectClass: top
#objectClass: inetOrgPerson
#objectClass: posixAccount
#objectClass: inetLocalMailRecipient
#
# %end for
#%end for
%end for
%end for
%for %%userdn, %%user, %%password, %%sn, %%gn, %%uid, %%aliases, %%family in %%acc
dn: %%userdn
cn: %%user
mail: %%user
sn: %%user['ldap_user_sn_' + %%family]
givenName: %%user['ldap_user_gn_' + %%family]
uid: %%user['ldap_user_uid_' + %%family]
userPassword:: %%ssha_encode(%%user['ldap_user_password_' + %%family])
sn: %%sn
givenName: %%gn
uid: %%uid
userPassword:: %%ssha_encode(%%password)
%if %%family == 'users'
homeDirectory: /srv/home/users/%%user
%else
homeDirectory: /srv/home/families/%%family/%%user
%end if
mailLocalAddress: %%user
%if %%user['ldap_user_aliases_' + %%family]
%for %%alias in %%user['ldap_user_aliases_' + %%family]
%if %%aliases
%for %%alias in %%aliases
mailLocalAddress: %%alias
%end for
%end if
@ -107,9 +128,8 @@ objectClass: posixAccount
objectClass: inetLocalMailRecipient
%end for
%end for
## Groups
%set %%groupdn = %%ldap_group_dn
%set %%groupdn = %%ldapclient_group_dn
dn: %%groupdn
ou: groups
objectClass: top

View file

@ -1,4 +1,6 @@
%set groups = {}
%set %%username="rougail_test@silique.fr"
%set %%username_family="rougail_test@gnunux.info"
%set %%name_family="gnunux"
# Remote
%set %%acc = []
%for %%idx in %%range(3)
@ -17,30 +19,29 @@ userPassword:: %%ssha_encode(%%password)
%end for
# Users
%set %%users = %%ldap_user_dn
%set %%userdn = 'cn=' + %%username + ',' + %%ldapclient_base_dn
%set %%userfamilydn = 'cn=' + %%username_family + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name=%%name_family)
%set %%acc = [(%%userdn, %%username, ['alias_' + %%username]),
(%%userfamilydn, %%username_family, ['alias_' + %%username_family]),
]
%set groups = {'users': [%%userdn],
%%name_family: [%%userfamilydn],
}
%set %%users = %%ldapclient_user_dn
%for %%user in %%accounts.users.ldap_user_mail
%set %%userdn = 'cn=' + %%user + ',' + %%users
%%groups.setdefault('users', []).append(%%userdn)%slurp
dn: %%userdn
changetype: modify
#add: objectClass
#objectClass: inetLocalMailRecipient
#-
replace: mailLocalAddress
mailLocalAddress: %%user
%if %%user.ldap_user_aliases
%for %%alias in %%user.ldap_user_aliases
mailLocalAddress: %%alias
%%groups['users'].append(%%userdn)%slurp
%%acc.append((%%userdn, %%user, %%user.ldap_user_aliases))%slurp
%end for
%end if
%end for
# Families
%for %%family in %%accounts.families
%set %%families = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, %%family)
%for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family]
%set %%userdn = 'cn=' + %%user + ',' + %%families
%%groups.setdefault(%%family, []).append(%%userdn)%slurp
%%acc.append((%%userdn, %%user, %%user['ldap_user_aliases_' + %%family]))%slurp
%end for
%end for
%for %%userdn, %%user, %%aliases in %%acc
dn: %%userdn
changetype: modify
#add: objectClass
@ -48,16 +49,15 @@ changetype: modify
#-
replace: mailLocalAddress
mailLocalAddress: %%user
%if %%user['ldap_user_aliases_' + %%family]
%for %%alias in %%user['ldap_user_aliases_' + %%family]
%if %%aliases
%for %%alias in %%aliases
mailLocalAddress: %%alias
%end for
%end if
%end for
%end for
# Groups
%set %%groupdn = %%ldap_group_dn
%set %%groupdn = %%ldapclient_group_dn
%for %%group, %%members in %%groups.items()
dn: cn=%%group,%%groupdn
changetype: modify

View file

@ -70,13 +70,16 @@ def test_ldap_user():
l.simple_bind_s(data['user_dn'], data['user_password'])
def test_ldap_user_family():
def test_ldap_migration():
conf_file = f'{environ["MACHINE_TEST_DIR"]}/openldap.yml'
with open(conf_file) as yaml:
data = load(yaml, Loader=SafeLoader)
set_option(OPT_X_TLS_REQUIRE_CERT, OPT_X_TLS_NEVER)
l = initialize(f'ldaps://{data["address"]}')
l.simple_bind_s(data['user_family_dn'], data['user_family_password'])
if 'FIRST_RUN' in environ:
l.simple_bind_s(data['admin_dn'], data['admin_password'])
l.passwd_s(data['user_family_dn'], data['user_family_password'], data['user_family_password'] + "2")
l.simple_bind_s(data['user_family_dn'], data['user_family_password'] + "2")
def test_ldap_remote_auth():

View file

@ -68,7 +68,7 @@ server {
location @api {
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host %%revprox_client_external_domainname;
proxy_set_header Host %%revprox_client_external_domainnames[0];
# proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 100k; # default is 1M
@ -119,7 +119,7 @@ server {
location @api_websocket {
proxy_http_version 1.1;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host %%revprox_client_external_domainname;
proxy_set_header Host %%revprox_client_external_domainnames[0];
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";

View file

@ -8,7 +8,7 @@ listen:
# Correspond to your reverse proxy server_name/listen configuration (i.e., your public PeerTube instance URL)
webserver:
https: true
hostname: '%%revprox_client_external_domainname'
hostname: '%%revprox_client_external_domainnames[0]'
port: 443
rates_limit:

View file

@ -5,7 +5,7 @@
<file source="tmpfile-piwigo.conf">/tmpfiles.d/0piwigo.conf</file>
<file>/etc/piwigo/config.inc.php</file>
<file>/etc/piwigo/database.inc.php</file>
<file mode="755">/bin/piwigo.sh</file>
<file mode="755">/sbin/piwigo.sh</file>
<file engine="none">/etc/php-fpm.d/piwigo.conf</file>
</service>
</services>

View file

@ -5,7 +5,7 @@ Before=nginx.service php-fpm.service
[Service]
Type=oneshot
ExecStart=/usr/local/lib/bin/piwigo.sh
ExecStart=/usr/local/lib/sbin/piwigo.sh
User=nginx
Group=nginx

View file

@ -0,0 +1,2 @@
format: '0.1'
description: Postfix as LMTP relay

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<rougail version="0.10">
<variables>
<variable name="server_lmtp" description="LMTP remote server" type="domainname" provider="lmtp_server" multi="True"/>
<variable name="server_lmtp" description="LMTP remote server" type="domainname" provider="LMTP" multi="True"/>
<family name="lmtp_" description="LMTP " dynamic="lmtp.server_lmtp">
<variable name="criteria_" description="transport criteria" type="string" multi="True" mandatory="True" hidden="True" provider="lmtp_criteria"/>
<variable name="criteria_" description="transport criteria" type="string" multi="True" mandatory="True" hidden="True" provider="LMTP:criteria"/>
</family>
</variables>
<constraints>

View file

@ -49,3 +49,9 @@ postconf maillog_file=/dev/stdout
https://www.mail-tester.com/
https://dkimvalidator.com/
# debug mail :
journalctl -m -u postfix -g address mail
# get date
journalctl -m -u postfix --since "2022-07-31 23:14:04"

View file

@ -1,6 +1,6 @@
format: '0.1'
description: Postfix has relay
description: Postfix as relay
depends:
- base-fedora-35
- dns-external
provider: SMTP
- postfix-lmtp-relay

View file

@ -43,10 +43,9 @@
<family name="postfix" description="Postfix mail server">
<variable name="postfix_mail_hostname" type="domainname" description="Nom de domaine extérieur du serveur de courriel" mandatory="True"/>
<variable name="postfix_relay_domains" type="domainname" description="Domaine de courriel généré localement" multi="True" mandatory="True" hidden="True"/>
<variable name='postfix_relay_authentifications' description="CA certificate" hidden='True' multi="True" provider="mail"/>
<variable name='postfix_relay_authentifications' description="Authentification sur le relai SMTP" multi="True" provider="SMTP"/>
<family name="local_authentification_" description="Local server authentification" dynamic='postfix_relay_authentifications'>
<variable name="local_authentification_ip_" type="ip" provider="mail_ip"/>
<variable name="local_authentification_password_" type="secret" auto_save="False" provider="mail_password"/>
<variable name="local_authentification_password_" type="secret" auto_save="False" provider="SMTP:password"/>
</family>
<variable name='postfix_pem_files' type="filename" hidden='True' multi='True'/>
</family>
@ -63,14 +62,6 @@
<param name="multi" type="boolean">True</param>
<target>opendkim_keys</target>
</fill>
<fill name="get_password">
<param name="server_name" type="variable">domain_name_eth0</param>
<param name="username" type="suffix"/>
<param name="description">local authentification</param>
<param name="type">cleartext</param>
<param name="hide" type="variable">hide_secret</param>
<target>local_authentification_password_</target>
</fill>
<fill name="calc_value">
<param>/etc/postfix/certs/</param>
<param type="variable">domain_name_eth</param>

View file

@ -318,7 +318,7 @@ smtpd_recipient_restrictions =
#mynetworks = 168.100.3.0/28, 127.0.0.0/8
#mynetworks = $config_directory/mynetworks
#mynetworks = hash:/etc/postfix/network_table
mynetworks = 172.0.0.0/8
mynetworks = 127.0.0.0/8
# The relay_domains parameter restricts what destinations this system will
# relay mail to. See the smtpd_recipient_restrictions description in

View file

@ -4,7 +4,7 @@ ExecStartPre=/usr/sbin/postmap -F /etc/postfix/sni
%for %%local in %%postfix_relay_authentifications
%set %%user = %%normalize_family(%%local)
%set %%password = %%getVar('local_authentification_password_' + %%user)
%set %%ip = %%getVar('local_authentification_ip_' + %%user)
%set %%ip = %%get_ip(%%local)
ExecStartPre=-/usr/bin/bash -c "echo %%password | /usr/sbin/saslpasswd2 -u %%ip %%user -p"
%end for
ExecStartPre=/usr/bin/chown postfix: /etc/sasl2/sasldb2

View file

@ -10,9 +10,9 @@
</services>
<variables>
<family name="postgresql" description="PostgreSQL">
<variable name="pg_client_server_domainname" type="domainname" description="Nom de domaine du serveur PostgreSQL" mandatory="True"/>
<variable name="pg_client_server_domainname" type="domainname" description="Nom de domaine du serveur PostgreSQL" mandatory="True" supplier="Postgresql"/>
<variable name="pg_client_username" description="Client username" mandatory="True" hidden="True"/>
<variable name="pg_client_password" type="password" description="Client password" mandatory="True" hidden="True"/>
<variable name="pg_client_password" type="password" description="Client password" mandatory="True" hidden="True" supplier="Postgresql:password"/>
<variable name="pg_client_database" description="Client database" mandatory="True" hidden="True"/>
<variable name="pg_client_key_owner" type="unix_user" description="Key owner" mandatory="True">
<value>apache</value>
@ -24,18 +24,17 @@
<param type="variable">domain_name_eth0</param>
<target>pg_client_username</target>
</fill>
<fill name="get_provider_name">
<!--fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>Postgresql</param>
<target>pg_client_server_domainname</target>
</fill>
<fill name="set_linked_multi_variables">
<param type="variable">pg_client_server_domainname</param>
<param name="linked_value_0" type="variable">domain_name_eth0</param>
<param name="linked_provider_0">clients</param>
<param name="linked_value_1" type="variable">ip_eth0</param>
<param name="linked_provider_1">client_ip</param>
<param name="linked_returns">client_password</param>
</fill-->
<fill name="get_password">
<param name="server_name" type="variable">pg_client_server_domainname</param>
<param name="username" type="variable">domain_name_eth0</param>
<param name="description">remote</param>
<param name="type">cleartext</param>
<param name="hide" type="variable">hide_secret</param>
<target>pg_client_password</target>
</fill>
<fill name="calc_value">

View file

@ -5,5 +5,5 @@ Before=network.target
[Service]
Type=oneshot
Environment=PGPASSFILE=/usr/local/lib/secrets/postgresql.pass
ExecStart=/usr/bin/timeout 90 bash -c 'while ! 3<> /dev/tcp/%%pg_client_server_domainname/5432; do sleep 1; done; echo "POSTGRESQL STARTED"'
ExecStart=/usr/bin/timeout 300 bash -c 'while ! 3<> /dev/tcp/%%pg_client_server_domainname/5432; do sleep 1; done; echo "POSTGRESQL STARTED"'
ExecStart=/usr/bin/timeout 90 bash -c 'while ! /usr/bin/psql --set=sslmode=verify-full -h %%pg_client_server_domainname -U %%pg_client_username %%pg_client_database -c "\l"; do sleep 1; done; echo "POSTGRESQL READY"'

View file

@ -1,6 +1,4 @@
format: '0.1'
description: Postgresql
depends:
- server
- base-fedora-35
provider: Postgresql
- base-fedora-36

View file

@ -2,17 +2,19 @@
<rougail version="0.10">
<services>
<service name="postgresql" target="multi-user">
<override engine="none"/>
<override/>
<ip ip_type='variable'>accounts.remote_.remote_ip_</ip>
<file>/etc/postgresql/postgresql.conf</file>
<file>/etc/postgresql/pg_hba.conf</file>
<file mode="600" owner="postgres" group="postgres">/etc/postgresql/postgresql.sql</file>
<file engine="none">/etc/postgresql/pg_ident.conf</file>
<file engine="none" mode="755">/bin/postgresql_init</file>
<file engine="none" mode="755">/sbin/postgresql_init</file>
<file engine="none" source="sysuser-postgresql.conf">/sysusers.d/0postgresql.conf</file>
<file engine="none" source="tmpfiles.postgresql.conf">/tmpfiles.d/0postgresql.conf</file>
<file>/etc/pki/ca-trust/source/anchors/ca_PostgreSQL.crt</file>
<file>/etc/pki/tls/certs/postgresql.crt</file>
<file owner="root" group="postgres" mode="440">/etc/pki/tls/private/postgresql.key</file>
<file>/tests/postgresql.yml</file>
</service>
</services>
<variables>

View file

@ -1,20 +1,16 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10">
<variables>
<variable name="remotes" description="Remote clients needing an account" type="domainname" multi="True" provider="clients"/>
<variable name="remotes" description="Remote clients needing an account" type="domainname" multi="True" provider="Postgresql"/>
<family name="remote_" description="Account for " dynamic="accounts.remotes">
<variable name="password_" description="Remote password" auto_save="False" hidden="True" type="password" mandatory="True" provider="client_password"/>
<variable name="remote_ip_" description="Remote IP" type="ip" hidden="True" provider="client_ip"/>
<variable name="remote_ip_" description="Remote IP" type="ip" mandatory="True"/>
<variable name="password_" description="Remote password" auto_save="False" hidden="True" type="password" mandatory="True" provider="Postgresql:password"/>
</family>
</variables>
<constraints>
<fill name="get_password">
<param name="server_name" type="variable">domain_name_eth0</param>
<param name="username" type="suffix"/>
<param name="description">remote</param>
<param name="type">cleartext</param>
<param name="hide" type="variable">hide_secret</param>
<target>accounts.remote_.password_</target>
<fill name="get_ip">
<param type="suffix"/>
<target>accounts.remote_.remote_ip_</target>
</fill>
</constraints>
</rougail>

View file

@ -1 +1,3 @@
PKG="$PKG postgresql-server postgresql-contrib"
# for postgresql-setup
PKG="$PKG util-linux postgresql-upgrade"

View file

@ -88,6 +88,7 @@ local all postgres ident map=pg_map
# IPv4 local connections:
#>GNUNUX
# host all all 127.0.0.1/32 ident
hostssl rougail_test rougail_test %%gateway_eth0/32 md5
%for %%server in %%accounts.remotes
hostssl %%normalize_family(%%server) %%normalize_family(%%server) %%server md5
%end for

View file

@ -47,9 +47,6 @@ directiveStartToken = §
#data_directory = 'ConfigDir' # use data in another directory
# (change requires restart)
#>GNUNUX
data_directory = '/srv/postgresql'
#<GNUNUX
#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file
# (change requires restart)
#>GNUNUX
@ -116,7 +113,7 @@ unix_socket_directories = '/var/run/postgresql'
#>GNUNUX
authentication_timeout = §§{pg_authentication_timeout}s
#<GNUNUX
#password_encryption = md5 # md5 or scram-sha-256
#password_encryption = scram-sha-256 # scram-sha-256 or md5
#db_user_namespace = off
# GSSAPI using Kerberos
@ -129,6 +126,7 @@ authentication_timeout = §§{pg_authentication_timeout}s
#ssl_ca_file = ''
#ssl_cert_file = 'server.crt'
#ssl_crl_file = ''
##ssl_crl_dir = ''
#ssl_key_file = 'server.key'
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
#ssl_prefer_server_ciphers = on
@ -156,6 +154,8 @@ shared_buffers = 128MB # min 128kB
shared_buffers = §§{pg_shared_buffers}§§pg_shared_buffers_unit
#huge_pages = try # on, off, or try
# (change requires restart)
#huge_page_size = 0 # zero for system default
# (change requires restart)
#temp_buffers = 8MB # min 800kB
#max_prepared_transactions = 0 # zero disables the feature
# (change requires restart)
@ -184,6 +184,7 @@ dynamic_shared_memory_type = posix # the default is the first option
# windows
# mmap
# (change requires restart)
#min_dynamic_shared_memory = 0MB # (change requires restart)
# - Disk -
@ -199,7 +200,7 @@ dynamic_shared_memory_type = posix # the default is the first option
#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables)
#vacuum_cost_page_hit = 1 # 0-10000 credits
#vacuum_cost_page_miss = 10 # 0-10000 credits
#vacuum_cost_page_miss = 2 # 0-10000 credits
#vacuum_cost_page_dirty = 20 # 0-10000 credits
#vacuum_cost_limit = 200 # 1-10000 credits
@ -212,17 +213,17 @@ dynamic_shared_memory_type = posix # the default is the first option
# - Asynchronous Behavior -
#backend_flush_after = 0 # measured in pages, 0 disables
#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching
#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching
#max_worker_processes = 8 # (change requires restart)
#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers
#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers
#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers
#parallel_leader_participation = on
#max_parallel_workers = 8 # maximum number of max_worker_processes that
# can be used in parallel operations
#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate
# (change requires restart)
#backend_flush_after = 0 # measured in pages, 0 disables
#------------------------------------------------------------------------------
@ -246,13 +247,15 @@ dynamic_shared_memory_type = posix # the default is the first option
# fsync_writethrough
# open_sync
#full_page_writes = on # recover from partial page writes
#wal_compression = off # enable compression of full-page writes
#wal_log_hints = off # also do full page writes of non-critical updates
# (change requires restart)
#wal_compression = off # enable compression of full-page writes
#wal_init_zero = on # zero-fill new WAL files
#wal_recycle = on # recycle WAL files
#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
#>GNUNUX
wal_buffers = §§pg_wal_buffers
#<GNUNUX
# (change requires restart)
#wal_writer_delay = 200ms # 1-10000 milliseconds
#wal_writer_flush_after = 1MB # measured in pages, 0 disables
@ -264,14 +267,14 @@ wal_buffers = §§pg_wal_buffers
# - Checkpoints -
#checkpoint_timeout = 5min # range 30s-1d
#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 256kB # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables
#>GNUNUX
#max_wal_size = 1GB
max_wal_size = §§{pg_max_wal_size}§§pg_max_wal_size_unit
#<GNUNUX
min_wal_size = 80MB
#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 256kB # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables
# - Archiving -
@ -292,7 +295,6 @@ min_wal_size = 80MB
# placeholders: %p = path of file to restore
# %f = file name only
# e.g. 'cp /mnt/server/archivedir/%f %p'
# (change requires restart)
#archive_cleanup_command = '' # command to execute at every restartpoint
#recovery_end_command = '' # command to execute at completion of recovery
@ -327,20 +329,19 @@ min_wal_size = 80MB
# - Sending Servers -
# Set these on the master and on any standby that will send replication data.
# Set these on the primary and on any standby that will send replication data.
#max_wal_senders = 10 # max number of walsender processes
# (change requires restart)
#max_replication_slots = 10 # max number of replication slots
# (change requires restart)
#wal_keep_size = 0 # in megabytes; 0 disables
#max_slot_wal_keep_size = -1 # in megabytes; -1 disables
#wal_sender_timeout = 60s # in milliseconds; 0 disables
#max_replication_slots = 10 # max number of replication slots
# (change requires restart)
#track_commit_timestamp = off # collect timestamp of transaction commit
# (change requires restart)
# - Master Server -
# - Primary Server -
# These settings are ignored on a standby server.
@ -352,7 +353,7 @@ min_wal_size = 80MB
# - Standby Servers -
# These settings are ignored on a master server.
# These settings are ignored on a primary server.
#primary_conninfo = '' # connection string to sending server
#primary_slot_name = '' # replication slot on sending server
@ -372,7 +373,7 @@ min_wal_size = 80MB
#hot_standby_feedback = off # send info from standby to prevent
# query conflicts
#wal_receiver_timeout = 60s # time that receiver waits for
# communication from master
# communication from primary
# in milliseconds; 0 disables
#wal_retrieve_retry_interval = 5s # time to wait before retrying to
# retrieve WAL after a failed attempt
@ -393,23 +394,26 @@ min_wal_size = 80MB
# - Planner Method Configuration -
#enable_async_append = on
#enable_bitmapscan = on
#enable_gathermerge = on
#enable_hashagg = on
#enable_hashjoin = on
#enable_incremental_sort = on
#enable_indexscan = on
#enable_indexonlyscan = on
#enable_material = on
#enable_memoize = on
#enable_mergejoin = on
#enable_nestloop = on
#enable_parallel_append = on
#enable_seqscan = on
#enable_sort = on
#enable_incremental_sort = on
#enable_tidscan = on
#enable_partitionwise_join = off
#enable_partitionwise_aggregate = off
#enable_parallel_hash = on
#enable_partition_pruning = on
#enable_partitionwise_join = off
#enable_partitionwise_aggregate = off
#enable_seqscan = on
#enable_sort = on
#enable_tidscan = on
# - Planner Cost Constants -
@ -420,6 +424,12 @@ min_wal_size = 80MB
#cpu_operator_cost = 0.0025 # same scale as above
#parallel_tuple_cost = 0.1 # same scale as above
#parallel_setup_cost = 1000.0 # same scale as above
#min_parallel_table_scan_size = 8MB
#min_parallel_index_scan_size = 512kB
#effective_cache_size = 4GB
#>GNUNUX
effective_cache_size = §§{pg_effective_cache_size}§§pg_effective_cache_size_unit
#<GNUNUX
#jit_above_cost = 100000 # perform JIT compilation if available
# and query more expensive than this;
@ -430,10 +440,6 @@ min_wal_size = 80MB
# query is more expensive than this;
# -1 disables
#min_parallel_table_scan_size = 8MB
#min_parallel_index_scan_size = 512kB
#effective_cache_size = 4GB
effective_cache_size = §§{pg_effective_cache_size}§§pg_effective_cache_size_unit
# - Genetic Query Optimizer -
@ -451,10 +457,9 @@ effective_cache_size = §§{pg_effective_cache_size}§§pg_effective_cache_size_
#constraint_exclusion = partition # on, off, or partition
#cursor_tuple_fraction = 0.1 # range 0.0-1.0
#from_collapse_limit = 8
#jit = on # allow JIT compilation
#join_collapse_limit = 8 # 1 disables collapsing of explicit
# JOIN clauses
#force_parallel_mode = off
#jit = on # allow JIT compilation
#plan_cache_mode = auto # auto, force_generic_plan or
# force_custom_plan
@ -465,27 +470,24 @@ effective_cache_size = §§{pg_effective_cache_size}§§pg_effective_cache_size_
# - Where to Log -
#>GNUNUX
#log_destination = 'stderr' # Valid values are combinations of
# stderr, csvlog, syslog, and eventlog,
# depending on platform. csvlog
# requires logging_collector to be on.
log_destination = 'syslog'
#<GNUNUX
# This is used when logging to stderr:
#logging_collector = off # Enable capturing of stderr and csvlog
#GNUNUX: logging_collector = on # Enable capturing of stderr and csvlog
# into log files. Required to be on for
# csvlogs.
# (change requires restart)
# These are only used if logging_collector is on:
#log_directory = 'pg_log' # directory where log files are written,
#log_directory = 'log' # directory where log files are written,
# can be absolute or relative to PGDATA
#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern,
#GNUNUX: log_filename = 'postgresql-%a.log' # log file name pattern,
# can include strftime() escapes
#log_file_mode = 0600 # creation mode for log files,
# begin with 0 to use octal notation
#log_truncate_on_rotation = off # If on, an existing log file with the
#GNUNUX: log_truncate_on_rotation = on # If on, an existing log file with the
# same name as the new log file will be
# truncated rather than appended to.
# But such truncation only occurs on
@ -493,11 +495,14 @@ log_destination = 'syslog'
# or size-driven rotation. Default is
# off, meaning append to existing files
# in all cases.
#log_rotation_age = 1d # Automatic rotation of logfiles will
#GNUNUX: log_rotation_age = 1d # Automatic rotation of logfiles will
# happen after that time. 0 disables.
#log_rotation_size = 10MB # Automatic rotation of logfiles will
#GNUNUX: log_rotation_size = 0 # Automatic rotation of logfiles will
# happen after that much log output.
# 0 disables.
#>GNUNUX
log_destination = 'syslog'
#<GNUNUX
# These are relevant when logging to syslog:
#syslog_facility = 'LOCAL0'
@ -505,7 +510,7 @@ log_destination = 'syslog'
#syslog_sequence_numbers = on
#syslog_split_messages = on
# This is only relevant when logging to eventlog (win32):
# This is only relevant when logging to eventlog (Windows):
# (change requires restart)
#event_source = 'PostgreSQL'
@ -565,6 +570,11 @@ log_destination = 'syslog'
#debug_print_rewritten = off
#debug_print_plan = off
#debug_pretty_print = on
#log_autovacuum_min_duration = -1 # log autovacuum activity;
# -1 disables, 0 logs all actions and
# their durations, > 0 logs only
# actions running at least this number
# of milliseconds.
#log_checkpoints = off
#log_connections = off
#log_disconnections = off
@ -579,9 +589,11 @@ log_destination = 'syslog'
# %h = remote host
# %b = backend type
# %p = process ID
# %P = process ID of parallel group leader
# %t = timestamp without milliseconds
# %m = timestamp with milliseconds
# %n = timestamp with milliseconds (as a Unix epoch)
# %Q = query ID (0 if none or not computed)
# %i = command tag
# %e = SQL state
# %c = session ID
@ -594,6 +606,8 @@ log_destination = 'syslog'
# %% = '%'
# e.g. '<%u%%%d> '
#log_lock_waits = off # log lock waits >= deadlock_timeout
#log_recovery_conflict_waits = off # log standby recovery conflict waits
# >= deadlock_timeout
#log_parameter_max_length = -1 # when logging statements, limit logged
# bind-parameter values to N bytes;
# -1 means print in full, 0 disables
@ -608,6 +622,7 @@ log_destination = 'syslog'
#FIXME en dure ?
log_timezone = 'Europe/Paris'
#------------------------------------------------------------------------------
# PROCESS TITLE
#------------------------------------------------------------------------------
@ -624,19 +639,21 @@ log_timezone = 'Europe/Paris'
# - Query and Index Statistics Collector -
#track_activities = on
#track_activity_query_size = 1024 # (change requires restart)
#track_counts = on
#track_io_timing = off
#track_wal_io_timing = off
#track_functions = none # none, pl, all
#track_activity_query_size = 1024 # (change requires restart)
#stats_temp_directory = 'pg_stat_tmp'
# - Monitoring -
#compute_query_id = auto
#log_statement_stats = off
#log_parser_stats = off
#log_planner_stats = off
#log_executor_stats = off
#log_statement_stats = off
#------------------------------------------------------------------------------
@ -652,10 +669,6 @@ autovacuum = on
autovacuum = off
§end if
#<GNUNUX
#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
# their durations, > 0 logs only
# actions running at least this number
# of milliseconds.
#autovacuum_max_workers = 3 # max number of autovacuum subprocesses
# (change requires restart)
#autovacuum_naptime = 1min # time between autovacuum runs
@ -701,10 +714,11 @@ autovacuum = off
# error
#search_path = '"$user", public' # schema names
#row_security = on
#default_table_access_method = 'heap'
#default_tablespace = '' # a tablespace name, '' uses the default
#default_toast_compression = 'pglz' # 'pglz' or 'lz4'
#temp_tablespaces = '' # a list of tablespace names, '' uses
# only default tablespace
#default_table_access_method = 'heap'
#check_function_bodies = on
#default_transaction_isolation = 'read committed'
#default_transaction_read_only = off
@ -713,17 +727,16 @@ autovacuum = off
#statement_timeout = 0 # in milliseconds, 0 is disabled
#lock_timeout = 0 # in milliseconds, 0 is disabled
#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled
#vacuum_freeze_min_age = 50000000
#idle_session_timeout = 0 # in milliseconds, 0 is disabled
#vacuum_freeze_table_age = 150000000
#vacuum_multixact_freeze_min_age = 5000000
#vacuum_freeze_min_age = 50000000
#vacuum_failsafe_age = 1600000000
#vacuum_multixact_freeze_table_age = 150000000
#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples
# before index cleanup, 0 always performs
# index cleanup
#vacuum_multixact_freeze_min_age = 5000000
#vacuum_multixact_failsafe_age = 1600000000
#bytea_output = 'hex' # hex, escape
#xmlbinary = 'base64'
#xmloption = 'content'
#gin_fuzzy_search_limit = 0
#gin_pending_list_limit = 4MB
# - Locale and Formatting -
@ -757,14 +770,15 @@ default_text_search_config = 'pg_catalog.french'
# - Shared Library Preloading -
#shared_preload_libraries = '' # (change requires restart)
#local_preload_libraries = ''
#session_preload_libraries = ''
#shared_preload_libraries = '' # (change requires restart)
#jit_provider = 'llvmjit' # JIT library to use
# - Other Defaults -
#dynamic_library_path = '$libdir'
#gin_fuzzy_search_limit = 0
#------------------------------------------------------------------------------
@ -792,7 +806,6 @@ default_text_search_config = 'pg_catalog.french'
#backslash_quote = safe_encoding # on, off, or safe_encoding
#escape_string_warning = on
#lo_compat_privileges = off
#operator_precedence_warning = off
#quote_all_identifiers = off
#standard_conforming_strings = on
#synchronize_seqscans = on
@ -811,6 +824,7 @@ default_text_search_config = 'pg_catalog.french'
#data_sync_retry = off # retry or panic on failure to fsync
# data?
# (change requires restart)
#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+)
#------------------------------------------------------------------------------

View file

@ -1,11 +1,38 @@
[Service]
ExecStartPre=
ExecStartPre=+/usr/local/lib/bin/postgresql_init
ExecStartPre=/usr/libexec/postgresql-check-db-dir %N
Environment=PGDATA=/srv/postgresql
Environment=PGDATA=/srv/postgresql/postgresql
Environment=PG_CONF=/etc/postgresql/postgresql.conf
Environment=PG_HBA=/etc/postgresql/pg_hba.conf
Environment=PG_IDENT=/etc/postgresql/pg_ident.conf
Environment=LC_ALL=fr_FR.UTF-8
ExecStartPre=
ExecStartPre=+/usr/local/lib/sbin/postgresql_init
# if upgrade needed, do it
ExecStartPre=/bin/bash -c '%slurp
/usr/libexec/postgresql-check-db-dir %N || (%slurp
echo "UPGRADE" &&%slurp
# directory creation must have 700 rights
umask 0077 &&%slurp
# pg_upgrade do not like ssl activation
/bin/grep -v "ssl " ${PG_CONF} > /tmp/postgresql.conf &&%slurp
mv -f /tmp/postgresql.conf ${PGDATA}/postgresql.conf &&%slurp
# pg_upgrade modify pg_hba.conf so copy it
/bin/rm ${PGDATA}/pg_hba.conf &&%slurp
/bin/cp -af ${PG_HBA} ${PGDATA} &&%slurp
# do upgrade
/usr/bin/postgresql-setup --upgrade &&%slurp
# re do link
ln -sf ${PG_HBA} ${PGDATA}/ &&%slurp
ln -sf ${PG_CONF} ${PGDATA}/ &&%slurp
# remove old cluster
/srv/postgresql/postgresql/delete_old_cluster.sh &&%slurp
rm -f /srv/postgresql/postgresql/delete_old_cluster.sh &&%slurp
# force index (see later)
touch /srv/postgresql/risotto_upgrade.lock%slurp
)'
# recheck db
ExecStartPre=/usr/libexec/postgresql-check-db-dir %N
ExecStart=
ExecStart=/usr/bin/postmaster -D ${PGDATA} -c config_file=${PG_CONF} -c hba_file=${PG_HBA} -c ident_file=${PG_IDENT}
ExecStartPost=-/usr/bin/psql -f /etc/postgresql/postgresql.sql
# if lock do reindex
ExecStartPost=/bin/bash -c 'if [ -f /srv/postgresql/risotto_upgrade.lock ];then echo REINDEX; /usr/bin/reindexdb && rm -f /srv/postgresql/risotto_upgrade.lock; fi'

View file

@ -1,7 +1,12 @@
%set %%new_accounts = [('rougail_test', %%get_password(server_name=%%domain_name_eth0, username='rougail_test', description="remote", type="cleartext", hide=%%hide_secret, temporary=True))]
%for %%server in %%accounts.remotes
%set %%name = %%normalize_family(%%server)
%set %%password = %%accounts["remote_" + %%name]["password_" + %%name]
%%new_accounts.append((%%name, %%password))%slurp
%end for
%for %%name, %%password in %%new_accounts
CREATE DATABASE "%%name";
CREATE ROLE "%%name" WITH LOGIN ENCRYPTED PASSWORD '%%accounts["remote_" + %%name]["password_" + %%name]';
ALTER USER "%%name" PASSWORD '%%accounts["remote_" + %%name]["password_" + %%name]';
CREATE ROLE "%%name" WITH LOGIN ENCRYPTED PASSWORD '%%password';
ALTER USER "%%name" PASSWORD '%%password';
GRANT ALL PRIVILEGES ON DATABASE "%%name" TO "%%name";
%end for

View file

@ -0,0 +1,4 @@
address: %%ip_eth0
user: rougail_test
password: %%get_password(server_name=%%domain_name_eth0, username='rougail_test', description="remote", type="cleartext", hide=%%hide_secret, temporary=True)
dbname: rougail_test

View file

@ -1,14 +1,22 @@
#!/bin/bash -e
[ -d "/srv/postgresql" ] && exit 0 || true
/bin/mkdir /srv/postgresql
/bin/chown postgres: /srv/postgresql
mkdir /var/lib/pgsql
/bin/chown postgres: /var/lib/pgsql
if [ ! -d "/srv/postgresql" ]; then
/bin/mkdir -p /srv/postgresql/postgresql
/bin/chown -R postgres: /srv/postgresql
/usr/bin/postgresql-setup --initdb
/bin/rm /srv/postgresql/postgresql.conf
/bin/rm /srv/postgresql/pg_hba.conf
/bin/rm /srv/postgresql/pg_ident.conf
#/bin/rm /srv/postgresql/postgresql.conf
#/bin/rm /srv/postgresql/pg_hba.conf
#/bin/rm /srv/postgresql/pg_ident.conf
elif [ ! -d "/srv/postgresql/postgresql" ]; then
# migrate /srv/postgresql to /srv/postgresql/postgresql
# needed for upgrade...
mkdir /srv/postgresql/postgresql
mv /srv/postgresql/* /srv/postgresql/postgresql || true
chown postgres: /srv/postgresql/postgresql
chmod 700 /srv/postgresql/postgresql
fi
# for postgresql-setup...
/bin/ln -sf /etc/postgresql/postgresql.conf /srv/postgresql/postgresql/postgresql.conf
/bin/ln -sf /etc/postgresql/pg_hba.conf /srv/postgresql/postgresql/pg_hba.conf
/bin/ln -sf /etc/postgresql/pg_ident.conf /srv/postgresql/postgresql/pg_ident.conf
exit 0

View file

@ -1,3 +1,3 @@
g postgres 26 -
u postgres 26:26 "PostgreSQL Server" /srv/postgresql /bin/bash
u postgres 26:26 "PostgreSQL Server" /srv/postgresql/postgresql /bin/bash

View file

@ -0,0 +1,2 @@
# for postgresql-setup only...
d /var/lib/pgsql/ 0750 postgres postgres -

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