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> <value>False</value>
</variable> </variable>
<family name="network" description="Réseau"> <family name="network" description="Réseau">
<variable name="zones_list" type="string" multi="True" description="Liste de toutes les zones" hidden="True"/> <variable name="server_name" type="domainname" hidden="True" provider="global:server_name" mandatory="True"/>
<variable name="interfaces_list" type="number" multi="True" description="Liste de tous les numéros d'interfaces" hidden="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"> <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="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" provider="ip"/> <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="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="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>
</family> </family>
</variables> </variables>
<constraints> <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"> <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> <target>ip_eth</target>
</fill> </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"> <fill name="get_zone_name">
<param type="information">zones_name</param> <param type="variable">zones_list</param>
<param name="index" type="suffix"/> <param name="index" type="suffix"/>
<target>zone_name_eth</target> <target>zone_name_eth</target>
</fill> </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 os import makedirs as _makedirs
from risotto.utils import ZONES_SERVER #from risotto.utils import ZONES_SERVER
_HERE = _dirname(_abspath(__main__.__file__)) _HERE = _dirname(_abspath(__main__.__file__))
@ -81,30 +81,8 @@ def _set_password(server_name: str,
return file_content return file_content
def get_range(lst):
return list(range(max(1, len(lst))))
def get_zone_name(zones: list, def get_zone_name(zones: list,
index: str, index: str,
): ):
if zones is not None: if zones is not None:
return zones[int(index)] 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 typing import List
from risotto.utils import load_domains, DOMAINS 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: def get_ip(server_name: str) -> str:
load_domains() if server_name is None:
host_name, domain_name = server_name.split('.', 1) 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] 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"> <variable name="dns_is_only_local" redefine="True">
<value>False</value> <value>False</value>
</variable> </variable>
<variable name="dns_client_address" redefine="True"/> <variable name="dns_client_address" redefine="True" supplier="ExternalDNS"/>
</family> </family>
</variables> </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> </rougail>

View file

@ -10,21 +10,13 @@
<variable name="dns_is_only_local" type="boolean" description="DNS resolve only local address" hidden="True"> <variable name="dns_is_only_local" type="boolean" description="DNS resolve only local address" hidden="True">
<value>True</value> <value>True</value>
</variable> </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"/> <variable name="ip_dns" type="ip" description="Adresse IP du serveur DNS" hidden="True"/>
</family> </family>
</variables> </variables>
<constraints> <constraints>
<fill name="get_provider_name"> <fill name="get_ip">
<param type="variable">zone_name_eth0</param> <param name="server_name" type="variable">dns_client_address</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>
<target>ip_dns</target> <target>ip_dns</target>
</fill> </fill>
</constraints> </constraints>

View file

@ -3,13 +3,13 @@ addresses:
%if %%getVar('dns_client_address', None) %if %%getVar('dns_client_address', None)
- dns_address: '%%dns_client_address' - dns_address: '%%dns_client_address'
dns_ip: '%%ip_dns' 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 %for %%authority in %%unbound_forward_address
- dns_address: %%authority - dns_address: %%authority
dns_ip: %%get_ip(%%str(%%authority)) dns_ip: %%get_ip(%%str(%%authority))
%end for %end for
%else %else
%for %%zone in %%nsd_zones_auto %for %%zone in %%nsd_zones
%set %%suffix = %%normalize_family(%%zone) %set %%suffix = %%normalize_family(%%zone)
%set %%hostnames = %%nsd["nsd_zone_" + %%suffix]["hostname_" + %%suffix]["hostname_" + %%suffix] %set %%hostnames = %%nsd["nsd_zone_" + %%suffix]["hostname_" + %%suffix]["hostname_" + %%suffix]
%for %%nsd in %%hostnames %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 description: Postfix et Dovecot
depends: depends:
- base-fedora-36 - base-fedora-36
- relay-mail-client - relay-lmtp-client
- ldap-client-fedora - ldap-client-fedora
- oauth2-client - oauth2-client
- nginx-https - nginx-https
provider: IMAP

View file

@ -71,9 +71,8 @@
</family> </family>
</family> </family>
<family name="mail" description="Mail domain" leadership="True"> <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" type="domainname" hidden="True"/>
<variable name="mail_domains_calc_autoconfig" type="domainname" hidden="True"/>
<variable name="imap_domainname" type="domainname" mandatory="True"/> <variable name="imap_domainname" type="domainname" mandatory="True"/>
<variable name="submission_domainname" type="domainname" mandatory="True"/> <variable name="submission_domainname" type="domainname" mandatory="True"/>
</family> </family>
@ -81,36 +80,22 @@
<variable name='postfix_pem_files' type="filename" hidden='True' multi='True'/> <variable name='postfix_pem_files' type="filename" hidden='True' multi='True'/>
</family> </family>
<family name="dovecot" description="IMAP mail server"> <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="well_known_filenames" type="filename" hidden='True' multi="True"/>
<variable name='external_imap_crt' 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'/> <variable name='external_imap_key' type="filename" hidden='True' multi='True'/>
</family> </family>
<family name="nginx"> <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"> <variable name="nginx_default_https" redefine="True">
<value>False</value> <value>False</value>
</variable> </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> </family>
</variables> </variables>
<constraints> <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"> <fill name="calc_value">
<param>/etc/pki/tls/certs/imap_</param> <param>/etc/pki/tls/certs/imap_</param>
<param type="variable">imap_domainname</param> <param type="variable">imap_domainname</param>
@ -136,14 +121,12 @@
<target>postfix_pem_files</target> <target>postfix_pem_files</target>
</fill> </fill>
<fill name="calc_value"> <fill name="calc_value">
<param type="variable">mail_domains</param> <param type="variable">domain_name_eth0</param>
<target>mail_domains_calc</target> <target>imap_internal_address</target>
</fill> </fill>
<fill name="calc_value"> <fill name="calc_value">
<param>autoconfig</param>
<param type="variable">mail_domains</param> <param type="variable">mail_domains</param>
<param name="join">.</param> <target>mail_domains_calc</target>
<target>mail_domains_calc_autoconfig</target>
</fill> </fill>
<fill name="calc_value"> <fill name="calc_value">
<param>/var/www/html/mail/</param> <param>/var/www/html/mail/</param>
@ -154,49 +137,20 @@
<param name="multi" type="boolean">True</param> <param name="multi" type="boolean">True</param>
<target>well_known_filenames</target> <target>well_known_filenames</target>
</fill> </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"> <fill name="calc_well_known">
<param type="index"/>
<param type="variable">domain_name_eth0</param> <param type="variable">domain_name_eth0</param>
<param type="variable">mail_domains</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> </fill>
</constraints> </constraints>
</rougail> </rougail>

View file

@ -11,10 +11,29 @@ def sha512_crypt(password):
@_multi_function @_multi_function
def calc_well_known(*args): def calc_domains(domains):
if None in args:
return
ret = [] ret = []
for dom in args[1]: for domain in domains:
ret.append(f'https://{args[0]}/mail/{dom}/autodiscover/autodiscover.xml') ret.append(domain)
ret.append(domain)
ret.append(f'autoconfig.{domain}')
return ret 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. # LDAP base. %variables can be used here.
# For example: dc=mail, dc=example, dc=org # For example: dc=mail, dc=example, dc=org
# GNUNUX base = # GNUNUX base =
base = %%ldapclient_base_dn base = %%ldapclient_search_dn
# Dereference: never, searching, finding, always # Dereference: never, searching, finding, always
#deref = never #deref = never

View file

@ -4,7 +4,7 @@
address: %%ip_eth0 address: %%ip_eth0
dns: %%domain_name_eth0 dns: %%domain_name_eth0
username: %%username 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 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 name_family: %%name_family

View file

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

View file

@ -10,8 +10,8 @@ from smtplib import SMTP, SMTPNotSupportedError, SMTPAuthenticationError
conf_file = f'{environ["MACHINE_TEST_DIR"]}/imap.yml' conf_file = f'{environ["MACHINE_TEST_DIR"]}/imap.yml'
with open(conf_file) as yaml: with open(conf_file) as yaml:
data = load(yaml, Loader=SafeLoader) data = load(yaml, Loader=SafeLoader)
parameters = (('user', data['username'], data['password']), parameters = (('user', data['username'], [data['password']]),
('family', data['username_family'], data['password_family']), ('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' return f'From: {username}\r\nTo: {username}\r\n\r\nSubject: TEST\r\n{msg}\r\n'
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_wrong_password(typ, username, password): def test_imap_wrong_password(typ, username, passwords):
imap = IMAP4_SSL(data['address']) imap = IMAP4_SSL(data['address'])
try: try:
imap.LOGIN(username, 'b') imap.LOGIN(username, 'b')
@ -30,17 +30,33 @@ def test_imap_wrong_password(typ, username, password):
raise Exception('wrong login !') raise Exception('wrong login !')
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_migration(typ, username, password): def test_imap_migration(typ, username, passwords):
msg = get_msg(username, 'MIGRATION') msg = get_msg(username, 'MIGRATION')
if 'FIRST_RUN' in environ: if 'FIRST_RUN' in environ:
smtp = SMTP(data['address'], '587') smtp = SMTP(data['address'], '587')
smtp.starttls() smtp.starttls()
error = None
for password in passwords:
try:
smtp.login(username, password) smtp.login(username, password)
break
except SMTPAuthenticationError as err:
error = err
else:
raise error from error
smtp.sendmail(username, username, msg) smtp.sendmail(username, username, msg)
smtp.quit() smtp.quit()
imap = IMAP4_SSL(data['address']) imap = IMAP4_SSL(data['address'])
error = None
for password in passwords:
try:
imap.LOGIN(username, password) imap.LOGIN(username, password)
break
except Exception as err:
error = err
else:
raise error from error
imap.SELECT(readonly=True) imap.SELECT(readonly=True)
typ, req = imap.SEARCH(None, 'ALL') typ, req = imap.SEARCH(None, 'ALL')
assert typ == 'OK' assert typ == 'OK'
@ -53,49 +69,67 @@ def test_imap_migration(typ, username, password):
imap.LOGOUT() imap.LOGOUT()
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_no_tls(typ, username, password): def test_smtp_no_tls(typ, username, passwords):
smtp = SMTP(data['address'], '587') smtp = SMTP(data['address'], '587')
try: with pytest.raises(SMTPNotSupportedError):
smtp.login(username, password) smtp.login(username, passwords[0])
raise Exception('no tls!')
except SMTPNotSupportedError:
pass
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_wrong_passwd(typ, username, password): def test_smtp_wrong_passwd(typ, username, passwords):
smtp = SMTP(data['address'], '587') smtp = SMTP(data['address'], '587')
smtp.starttls() smtp.starttls()
try: with pytest.raises(SMTPAuthenticationError):
smtp.login(username, 'a') smtp.login(username, 'a')
raise Exception('wrong password!')
except SMTPAuthenticationError:
pass
smtp.quit() smtp.quit()
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_login(typ, username, password): def test_smtp_login(typ, username, passwords):
smtp = SMTP(data['address'], '587') smtp = SMTP(data['address'], '587')
smtp.starttls() smtp.starttls()
error = None
for password in passwords:
try:
smtp.login(username, password) smtp.login(username, password)
break
except SMTPAuthenticationError as err:
error = err
else:
raise error from error
smtp.quit() smtp.quit()
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_smtp_sendmail(typ, username, password): def test_smtp_sendmail(typ, username, passwords):
smtp = SMTP(data['address'], '587') smtp = SMTP(data['address'], '587')
smtp.starttls() smtp.starttls()
error = None
for password in passwords:
try:
smtp.login(username, password) smtp.login(username, password)
break
except SMTPAuthenticationError as err:
error = err
else:
raise error from error
smtp.sendmail(username, username, get_msg(username)) smtp.sendmail(username, username, get_msg(username))
smtp.quit() smtp.quit()
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_read_mail(typ, username, password): def test_imap_read_mail(typ, username, passwords):
imap = IMAP4_SSL(data['address']) imap = IMAP4_SSL(data['address'])
error = None
for password in passwords:
try:
imap.LOGIN(username, password) imap.LOGIN(username, password)
break
except Exception as err:
error = err
else:
raise error from error
imap.SELECT(readonly=True) imap.SELECT(readonly=True)
typ, req = imap.SEARCH(None, 'ALL') typ, req = imap.SEARCH(None, 'ALL')
assert typ == 'OK' assert typ == 'OK'
@ -111,10 +145,18 @@ def test_imap_read_mail(typ, username, password):
imap.LOGOUT() imap.LOGOUT()
@pytest.mark.parametrize('typ, username, password', parameters) @pytest.mark.parametrize('typ, username, passwords', parameters)
def test_imap_delete_mail(typ, username, password): def test_imap_delete_mail(typ, username, passwords):
imap = IMAP4_SSL(data['address']) imap = IMAP4_SSL(data['address'])
error = None
for password in passwords:
try:
imap.LOGIN(username, password) imap.LOGIN(username, password)
break
except Exception as err:
error = err
else:
raise error from error
imap.SELECT() imap.SELECT()
typ, req = imap.SEARCH(None, 'ALL') typ, req = imap.SEARCH(None, 'ALL')
msg_no = req[0].split() 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" 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' format: '0.1'
description: Gitea description: Gitea
depends: depends:
- base-fedora-35 - base-fedora-36
- postgresql-client - postgresql-client
- reverse-proxy-client - reverse-proxy-client
- relay-mail-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="sysuser-gitea.conf">/sysusers.d/0gitea.conf</file>
<file engine="none" source="tmpfile-gitea.conf">/tmpfiles.d/0gitea.conf</file> <file engine="none" source="tmpfile-gitea.conf">/tmpfiles.d/0gitea.conf</file>
<file>/etc/gitea/app.ini</file> <file>/etc/gitea/app.ini</file>
<file>/tests/gitea.yml</file>
</service> </service>
</services> </services>
<variables> <variables>
@ -24,9 +25,11 @@
<variable name="gitea_lfs_jwt_secret" type="password" hidden="True"/> <variable name="gitea_lfs_jwt_secret" type="password" hidden="True"/>
</family> </family>
<family name="nginx"> <family name="nginx">
<family name="revprox_client">
<variable name="revprox_client_local_location" redefine="True"> <variable name="revprox_client_local_location" redefine="True">
<value>/</value> <value>/</value>
</variable> </variable>
</family>
<variable name="revprox_client_port" redefine="True"> <variable name="revprox_client_port" redefine="True">
<value>3000</value> <value>3000</value>
</variable> </variable>

View file

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

View file

@ -16,7 +16,7 @@ User=gitea
Group=gitea Group=gitea
WorkingDirectory=/srv/gitea/lib/ WorkingDirectory=/srv/gitea/lib/
ExecStart=/usr/bin/gitea web --config /etc/gitea/app.ini 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 Restart=always
Environment=USER=gitea HOME=/srv/gitea/home GITEA_WORK_DIR=/srv/gitea/lib 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> <variables>
<variable name="host_install_dir" type="filename" description="Nom du répertoire comprenant les descriptions d'installation" mandatory="True"/> <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_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_zone_filename" type="filename" hidden="True" multi="True"/>
<variable name="systemd_netzone_filename" type="filename" hidden="True" multi="True"/> <variable name="systemd_netzone_filename" type="filename" hidden="True" multi="True"/>
<family name="network"> <family name="network">
@ -64,10 +64,6 @@
<param name="multi" type="boolean">True</param> <param name="multi" type="boolean">True</param>
<target>systemd_netzone_filename</target> <target>systemd_netzone_filename</target>
</fill> </fill>
<fill name="calc_value">
<param type="information">server_name</param>
<target>host_name</target>
</fill>
<fill name="get_internal_zone_information"> <fill name="get_internal_zone_information">
<param type="variable">zone_name</param> <param type="variable">zone_name</param>
<param>cidr</param> <param>cidr</param>

View file

@ -7,14 +7,14 @@
</service> </service>
</services> </services>
<variables> <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"> <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="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="outgoing_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="machine_srv"/> <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="machine_journal"/> <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="machine_config" mandatory="True"/> <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="machine_zones" mandatory="True" multi="True"/> <variable name="zones_" description="Zones for " hidden="True" provider="Host:machine_zones" mandatory="True" multi="True"/>
</family> </family>
<variable name="nspawn_zone_filename" type="filename" hidden="True" multi="True"/> <variable name="nspawn_zone_filename" type="filename" hidden="True" multi="True"/>
<variable name="nspawn_script_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> </services>
<variables> <variables>
<family name="imap" description="Client SMTP"> <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> </family>
</variables> </variables>
<constraints>
<fill name="get_provider_name">
<param type="variable">zone_name_eth0</param>
<param>IMAP</param>
<target>imap_address</target>
</fill>
</constraints>
</rougail> </rougail>

View file

@ -12,16 +12,19 @@
<variables> <variables>
<family name="annuaire" description="Annuaire OpenLDAP"> <family name="annuaire" description="Annuaire OpenLDAP">
<family name="server" description="Serveur"> <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"> <variable name='ldap_port' type='port' description='Port du serveur LDAP' hidden="True">
<value>636</value> <value>636</value>
</variable> </variable>
</family> </family>
<family name="client" description="Client"> <family name="client" description="Client">
<variable name='ldapclient_family' type='unix_user' description="Nom de la famille LDAP"/> <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"/> <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"/> <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 des utilisateurs" mandatory="False"/> <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_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_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"/> <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'> <check name='valid_base_dn'>
<target>ldapclient_base_dn</target> <target>ldapclient_base_dn</target>
</check> </check>
<fill name="get_provider_name"> <fill name='get_default_base_dn'>
<param type="variable">zone_name_eth0</param> <param type="variable">ldap_server_address</param>
<param>LDAP</param> <target>ldapclient_base_dn</target>
<target>ldap_server_address</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>
<fill name="calc_value"> <fill name="calc_value">
<param type="variable">tls_ca_directory</param> <param type="variable">tls_ca_directory</param>
@ -61,16 +77,6 @@
<param name="join">/</param> <param name="join">/</param>
<target>ldap_key_file</target> <target>ldap_key_file</target>
</fill> </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"> <fill name="get_password">
<param name="server_name" type="variable">ldap_server_address</param> <param name="server_name" type="variable">ldap_server_address</param>
<param name="username" type="variable">ldapclient_user</param> <param name="username" type="variable">ldapclient_user</param>
@ -80,13 +86,14 @@
<param name="temporary" type="boolean">True</param> <param name="temporary" type="boolean">True</param>
<target>ldapclient_user_password</target> <target>ldapclient_user_password</target>
</fill> </fill>
<fill name="set_linked_multi_variables"> <fill name="calc_ldapclient_base_dn">
<param type="variable">ldap_server_address</param> <param type="variable">ldapclient_base_dn</param>
<param name="linked_provider_0">client_password</param> <param name="group" type="boolean">True</param>
<param name="linked_value_0" type="variable">ldapclient_user_password</param> <target>ldapclient_group_dn</target>
<param name="linked_returns">base_dn</param> </fill>
<param name="dynamic" type="variable">domain_name_eth0</param> <fill name="calc_ldapclient_base_dn">
<target>ldapclient_base_dn</target> <param type="variable">ldapclient_base_dn</param>
<target>ldapclient_user_dn</target>
</fill> </fill>
</constraints> </constraints>
</rougail> </rougail>

View file

@ -11,6 +11,8 @@ def calc_ldapclient_base_dn(ldap_base_dn: str,
base: bool=False, base: bool=False,
group: bool=False, group: bool=False,
) -> str: ) -> str:
if ldap_base_dn is None:
return
if family_name == 'all': if family_name == 'all':
family_name = None family_name = None
base = True base = True
@ -28,3 +30,23 @@ def calc_ldapclient_base_dn(ldap_base_dn: str,
if family_name != '-': if family_name != '-':
base_name = f'ou={family_name},{base_name}' base_name = f'ou={family_name},{base_name}'
return 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. # This file should be world readable but not world writable.
#BASE dc=example,dc=com #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 ldap://ldap.example.com ldap://ldap-master.example.com:666
URI ldaps://%%ldap_server_address:%%ldap_port URI ldaps://%%ldap_server_address:%%ldap_port

View file

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

View file

@ -28,6 +28,7 @@
<variable name="nginx_default_https" redefine="True"> <variable name="nginx_default_https" redefine="True">
<value>False</value> <value>False</value>
</variable> </variable>
<variable name="oauth2_client_external_domain" type="domainname" hidden="True" supplier="OAuth2Client:external_domain"/>
</family> </family>
<family name="lemonldap" description="LemonLDAP" help="Configuration de la solution d'authentification unique LemonLDAP::NG"> <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"> <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"> <variable name='ldapclient_family' redefine="True">
<value>all</value> <value>all</value>
</variable> </variable>
<variable name='ldapclient_group_dn' type='string' description="Base DN de l'annuaire des groupes" mandatory="False"/>
</family> </family>
</family> </family>
</variables> </variables>
<constraints> <constraints>
<fill name="get_linked_configuration"> <fill name="get_first_value">
<param name="linked_server" type="variable">ldap_server_address</param> <param type="variable">revprox_client_external_domainnames</param>
<param name="linked_provider">ldap_group</param> <target>oauth2_client_external_domain</target>
<target>ldapclient_group_dn</target>
</fill> </fill>
</constraints> </constraints>
</rougail> </rougail>

View file

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

View file

@ -3,5 +3,5 @@ After=nginx.service
[Service] [Service]
ExecStartPre=/usr/bin/timeout 90 bash -c 'while ! 3<> /dev/tcp/%%ldap_server_address/%%ldap_port; do sleep 1; done' 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' 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 internal_address: %%domain_name_eth0
ip: %%ip_eth0 ip: %%ip_eth0

View file

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

View file

@ -48,7 +48,7 @@ server {
# GNUNUX server_name auth.example.com; # GNUNUX server_name auth.example.com;
#>GNUNUX #>GNUNUX
listen 443 ssl; listen 443 ssl;
server_name %%revprox_client_external_domainname; server_name %%{revprox_client_external_domainnames[0]};
ssl_certificate %%revprox_cert_file; ssl_certificate %%revprox_cert_file;
ssl_certificate_key %%revprox_key_file; ssl_certificate_key %%revprox_key_file;
ssl_client_certificate %%revprox_ca_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) ret = _run(cli_args, capture_output=True)
if ret.returncode != 0: if ret.returncode != 0:
raise ValueError(ret.stderr.decode()) print("FIXME")
#raise ValueError(ret.stderr.decode())
print("Done") print("Done")
with open(date_file, 'w') as fh: with open(date_file, 'w') as fh:
fh.write(today) fh.write(today)

View file

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

View file

@ -5,7 +5,7 @@
<variable name="name_" description="Nom des listes" type="unix_user" multi="True" mandatory="True"/> <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"/> <variable name="names_" description="Address names" type="string" multi="True" mandatory="True" hidden="True"/>
</family> </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> </variables>
<constraints> <constraints>
<fill name="mailman_emails"> <fill name="mailman_emails">
@ -17,18 +17,6 @@
<param type="variable">mailman.list_.names_</param> <param type="variable">mailman.list_.names_</param>
<target>mailman.names_</target> <target>mailman.names_</target>
</fill> </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> </constraints>
</rougail> </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'}, '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'] ALLOWED_HOSTS = ['%%{revprox_client_external_domainnames[0]}']
POSTORIUS_TEMPLATE_BASE_URL = 'https://%%revprox_client_external_domainname' POSTORIUS_TEMPLATE_BASE_URL = 'https://%%{revprox_client_external_domainnames[0]}'
CSRF_TRUSTED_ORIGINS = ['%%revprox_client_external_domainname'] CSRF_TRUSTED_ORIGINS = ['%%{revprox_client_external_domainnames[0]}']
USE_X_FORWARDED_HOST = True USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
LANGUAGE_CODE = 'fr' LANGUAGE_CODE = 'fr'

View file

@ -19,7 +19,7 @@ RestrictRealtime=yes
PrivateMounts=yes PrivateMounts=yes
Environment="MAILMAN_WEB_CONFIG=/usr/share/postorius/m_postorius/settings.py" Environment="MAILMAN_WEB_CONFIG=/usr/share/postorius/m_postorius/settings.py"
ExecStartPre=/usr/share/postorius/manage.py migrate 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 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 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 ExecStart=/usr/bin/gunicorn --config /etc/postorius/gunicorn_config.py m_postorius.wsgi

View file

@ -5,33 +5,28 @@
</services> </services>
<variables> <variables>
<family name="mariadb" description="MariaDB"> <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_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"/> <variable name="mariadb_client_database" description="Database name" mandatory="True" hidden="True"/>
</family> </family>
</variables> </variables>
<constraints> <constraints>
<fill name="get_provider_name"> <fill name="normalize_family">
<param type="variable">zone_name_eth0</param> <param type="variable">domain_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>
<target>mariadb_client_username</target> <target>mariadb_client_username</target>
</fill> </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"> <fill name="calc_value">
<param type="variable">mariadb_client_username</param> <param type="variable">mariadb_client_username</param>
<target>mariadb_client_database</target> <target>mariadb_client_database</target>
</fill> </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> </constraints>
</rougail> </rougail>

View file

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

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'; GRANT ALL PRIVILEGES ON %%name.* TO '%%name'@'%%server' IDENTIFIED BY '%%password';
%end for %end for
FLUSH PRIVILEGES; FLUSH PRIVILEGES;

View file

@ -5,7 +5,7 @@
<service name="nextcloudcron" type="timer" engine="none" target="timers"/> <service name="nextcloudcron" type="timer" engine="none" target="timers"/>
<service name="nextcloud" engine="creole" target="multi-user"> <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="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/a-nextcloud-access.conf</file>
<file>/etc/httpd/conf.d/z-nextcloud-access.conf</file> <file>/etc/httpd/conf.d/z-nextcloud-access.conf</file>
<file>/etc/php.d/20-pgsql.ini</file> <file>/etc/php.d/20-pgsql.ini</file>
@ -66,38 +66,12 @@
<param name="hide" type="variable">hide_secret</param> <param name="hide" type="variable">hide_secret</param>
<target>nextcloud_instance_id</target> <target>nextcloud_instance_id</target>
</fill> </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"> <fill name="calc_web_address">
<param type="variable">domain_name_eth0</param> <param type="variable">domain_name_eth0</param>
<param type="variable">revprox_client_port</param> <param type="variable">revprox_client_port</param>
<param>/.well-known/caldav</param> <param>/.well-known/caldav</param>
<target>nextcloud_well_known_caldav</target> <target>nextcloud_well_known_caldav</target>
</fill> </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"> <fill name="calc_web_address">
<param type="variable">domain_name_eth0</param> <param type="variable">domain_name_eth0</param>
<param type="variable">revprox_client_port</param> <param type="variable">revprox_client_port</param>

View file

@ -11,7 +11,7 @@ $CONFIG = array (
'trusted_domains' => 'trusted_domains' =>
array ( array (
0 => 'localhost', 0 => 'localhost',
1 => '%%revprox_client_external_domainname', 1 => '%%revprox_client_external_domainnames[0]',
), ),
'apps_paths' => 'apps_paths' =>
array ( array (
@ -49,7 +49,7 @@ $CONFIG = array (
'memcache.distributed' => '\OC\Memcache\Redis', 'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis', 'memcache.locking' => '\OC\Memcache\Redis',
'trusted_proxies' => '%%revprox_client_server_ip', 'trusted_proxies' => '%%revprox_client_server_ip',
'overwritehost' => '%%revprox_client_external_domainname', 'overwritehost' => '%%revprox_client_external_domainnames[0]',
'filelocking.enabled' => true, 'filelocking.enabled' => true,
'redis' => [ 'redis' => [
'host' => '%%redis_client_server_domainname', '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 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 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 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 ldapBase "%%ldapclient_search_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 ldapBaseUsers "%%ldapclient_user_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 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 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 ldapExpertUUIDUserAttr "cn"
/usr/bin/php /usr/share/nextcloud/occ ldap:set-config s01 ldapLoginFilter "(&(cn=%uid)(ObjectClass=inetOrgPerson))" /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 WorkingDirectory=/usr/share/nextcloud
#FIXME #FIXME
ExecStart=+/usr/bin/chmod +w /etc/nextcloud/config.php 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 ExecStart=+/usr/bin/chmod -w /etc/nextcloud/config.php
User=apache User=apache
Group=apache Group=apache

View file

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

View file

@ -5,8 +5,8 @@
<override engine="creole"/> <override engine="creole"/>
<file source="nginx-options-rp.conf">/etc/nginx/conf.d/options-rp.conf</file> <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="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="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="revprox_domainnames_all">nginx_private_key_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> <file>/tests/reverse-proxy.yml</file>
</service> </service>
</services> </services>
@ -22,34 +22,6 @@
<variable name="nginx_default_http" redefine="True"> <variable name="nginx_default_http" redefine="True">
<value>True</value> <value>True</value>
</variable> </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> </family>
</variables> </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> </rougail>

View file

@ -1,16 +1,40 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10"> <rougail version="0.10">
<variables> <variables>
<family name="reverse_proxy_for_" description="Serveur mandataire inverse pour " dynamic="revprox_domainnames_all"> <variable name="remotes" type="domainname" description="Nom des domaines dans le serveur mandataire inverse" multi="True" provider="ReverseProxy"/>
<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"> <family name="reverse_proxy_for_" description="Serveur mandataire inverse pour " dynamic="nginx.remotes">
<value>False</value>
</variable>
<family name="reverse_proxy_" description="Reverse proxy " help="Paramètrage du proxy inverse" leadership="True"> <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_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_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_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_is_websocket_" type="boolean" description="Le point d'entré est de types websocket pour " mandatory="True" provider="revprox_is_websocket"/> <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_max_body_size_" description="Taille maximum du corps pour " provider="revprox_max_body_size"/> <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>
</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> </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> </rougail>

View file

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

View file

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

View file

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

View file

@ -1,7 +1,4 @@
%for %%idx, %%domainname in %%enumerate(%%revprox_domainnames_all) %for %%idx, %%domainname in %%enumerate(%%nginx.revprox_domainnames)
%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]
# Configuration HTTP %%domainname # Configuration HTTP %%domainname
server { server {
listen 80; listen 80;
@ -12,19 +9,25 @@ server {
# Configuration HTTPS %%domainname # Configuration HTTPS %%domainname
server { server {
listen 443 ssl http2; listen 443 ssl http2;
ssl_certificate %%nginx_certificate_filename[%%idx]; ssl_certificate %%nginx.nginx_certificate_filename[%%idx];
ssl_certificate_key %%nginx_private_key_filename[%%idx]; ssl_certificate_key %%nginx.nginx_private_key_filename[%%idx];
server_name %%domainname; server_name %%domainname;
error_page 403 404 502 503 504 /error.html; error_page 403 404 502 503 504 /error.html;
location = /error.html{ location = /error.html{
root /var/www/html; root /var/www/html;
} }
%for %%location in %%revprox['revprox_location_' + family] %for %%remote in %%nginx.remotes
%set %%location_str = %%str(%%location) %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 { location %%location {
proxy_pass %%location['revprox_url_' + family]; proxy_pass %%rp_domainname['revprox_url_' + %%family];
%if %%location['revprox_is_websocket_' + family] %if %%rp_domainname['revprox_is_websocket_' + %%family][%%loc_idx]
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
@ -42,7 +45,7 @@ server {
proxy_ssl_verify on; proxy_ssl_verify on;
proxy_ssl_verify_depth 2; proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse on; proxy_ssl_session_reuse on;
%set %%maxbody = %%location['revprox_max_body_size_' + family] %set %%maxbody = %%rp_domainname['revprox_max_body_size_' + %%family]
%if %%maxbody %if %%maxbody
client_max_body_size %%maxbody; client_max_body_size %%maxbody;
%end if %end if
@ -51,11 +54,14 @@ server {
root /var/www/html; root /var/www/html;
} }
# If user missing '/' # If user missing '/'
%if %%location_str != '/' and %%location_str.endswith('/') %if %%location != '/' and %%location.endswith('/')
location %%location_str[:-1] { location %%location[:-1] {
rewrite ^(%%location_str[:-1])$ $1/ permanent; rewrite ^(%%location[:-1])$ $1/ permanent;
} }
%end if %end if
%end for %end for
%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]) dns[-1] = (ip, dns[-1][1])
return [dns] return [dns]
socket.getaddrinfo = new_getaddrinfo 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 = get(url, verify=verify)
ret_code = ret.status_code ret_code = ret.status_code
content = ret.content content = ret.content
@ -29,8 +34,6 @@ def test_revprox():
data = load(yaml, Loader=SafeLoader) data = load(yaml, Loader=SafeLoader)
# test unknown domain # test unknown domain
url = 'google.fr' url = 'google.fr'
with warnings.catch_warnings():
warnings.simplefilter("ignore")
ret_code, content = req(f'https://{url}', data['address'], verify=False) 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 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' 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 service: true
depends: depends:
- base-fedora-36 - base-fedora-36
provider: LocalDNS

View file

@ -5,9 +5,9 @@
<override/> <override/>
<ip ip_type="variable">nsd_allowed_all_client</ip> <ip ip_type="variable">nsd_allowed_all_client</ip>
<file>/etc/nsd/conf.d/risotto.conf</file> <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.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 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="sysuser-nsd.conf">/sysusers.d/0nsd.conf</file>
<file engine="none" source="tmpfile-nsd.conf">/tmpfiles.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"/> <variable name="ip_dns" redefine="True" remove_fill="True"/>
</family> </family>
<family name="dns_server" description="Serveur DNS"> <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_allowed_client" type="domainname" description="Clients" multi="True" mandatory="True" hidden="True" provider="LocalDNS"/>
<variable name="nsd_resolver" type="domainname" description="Nom de domaine du résolveur DNS associé"/> <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_resolve_ip" type="ip" hidden="True"/>
<variable name="nsd_allowed_all_client" type="ip" description="All autorised IP" multi="True" hidden="True"/> <variable name="nsd_allowed_all_client" type="ip" description="All autorised IP" multi="True" hidden="True"/>
</family> </family>
<family name="dns_zone" description="Zone DNS"> <family name="dns_zone" description="Zone DNS">
<variable name="nsd_zones" type="domainname" description="Zones DNS" multi="True"/> <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>
<family name="dns_reverses" description="Zone DNS reverse" leadership="True"> <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_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> </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" 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_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" 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"/> <variable name="nsd_reverse_filenames_signed" type="filename" description="Nom des fichiers de zone reverse signé" multi="True" hidden="True"/>
</variables> </variables>
<constraints> <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"> <fill name="calc_value">
<param type="variable">ip_eth0</param> <param type="variable">ip_eth0</param>
<target>ip_dns</target> <target>ip_dns</target>
</fill> </fill>
<fill name="nsd_concat_lists"> <fill name="get_ip">
<param type="variable">ip_eth</param>
<param type="variable">nsd_allowed_client</param> <param type="variable">nsd_allowed_client</param>
<param type="variable">nsd_resolve_ip</param> <target>nsd_allowed_client_ip</target>
<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>
</fill> </fill>
<fill name="nsd_concat_lists"> <fill name="nsd_concat_lists">
<param type="variable">nsd_zones</param> <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> <target>nsd_zones_all</target>
</fill> </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"> <fill name="get_reverse_name">
<param type="variable">nsd_reverse_network</param> <param type="variable">nsd_reverse_network</param>
<target>nsd_reverse_reverse_name</target> <target>nsd_reverse_name</target>
</fill> </fill>
<fill name="calc_value"> <fill name="calc_value">
<param>/etc/nsd/</param> <param>/etc/nsd/</param>
<param type="variable">nsd_zones_all</param> <param type="variable">nsd_zones</param>
<param>.zone</param> <param>.zone</param>
<param name="join"></param> <param name="join"></param>
<param name="multi" type="boolean">True</param> <param name="multi" type="boolean">True</param>
@ -106,7 +87,7 @@
</fill> </fill>
<fill name="calc_value"> <fill name="calc_value">
<param>/etc/nsd/</param> <param>/etc/nsd/</param>
<param type="variable">nsd_reverse_reverse_name</param> <param type="variable">nsd_reverse_name</param>
<param>reverse</param> <param>reverse</param>
<param name="join"></param> <param name="join"></param>
<param name="multi" type="boolean">True</param> <param name="multi" type="boolean">True</param>

View file

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

View file

@ -8,6 +8,8 @@ from shutil import rmtree as _rmtree, copy2 as _copy2
from glob import glob as _glob from glob import glob as _glob
from filecmp import cmp as _cmp from filecmp import cmp as _cmp
from risotto.utils import DOMAINS as _DOMAINS
_PKI_DIR = _abspath('pki/dnssec') _PKI_DIR = _abspath('pki/dnssec')
_ALGO = 'ECDSAP256SHA256' _ALGO = 'ECDSAP256SHA256'
@ -32,9 +34,11 @@ def nsd_concat_lists(list1: _List[str],
list2: _List[str], list2: _List[str],
str1: str=None, str1: str=None,
) -> _List[str]: ) -> _List[str]:
ret = list1 + list2 ret = set(list1 + list2)
if str1: if str1:
ret.append(str1) ret.add(str1)
ret = list(ret)
ret.sort()
return ret return ret
@ -117,3 +121,14 @@ def sign(zone_filename: str,
with open(signed_filename) as fh: with open(signed_filename) as fh:
content = fh.read().strip() content = fh.read().strip()
return content 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 %%name = None
%set %%network = %%ip_network(%%nsd_reverse_network[%%rougail_index]) %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 %%suffix = %%normalize_family(%%zone)
%set %%hostnames = %%nsd["nsd_zone_" + %%suffix]["hostname_" + %%suffix]["hostname_" + %%suffix] %set %%hostnames = %%nsd["nsd_zone_" + %%suffix]["hostname_" + %%suffix]["hostname_" + %%suffix]
%for %%hostname in %%hostnames %for %%hostname in %%hostnames

View file

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

View file

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

View file

@ -2,41 +2,37 @@
<rougail version="0.10"> <rougail version="0.10">
<variables> <variables>
<family name="oauth2_client" description="OAuth2 client"> <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'> <variable name="oauth2_is_client_application" type="boolean" description="OAuth2 client is an application" mandatory='True'>
<value>False</value> <value>False</value>
</variable> </variable>
<variable name="oauth2_client_name" description="OAuth2 client name" mandatory='True'/> <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'/> <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"/> <variable name="oauth2_client_login" type="web_address" description="OAuth2 URL to valid login" supplier="OAuth2:login"/>
<family name="external"> <family name="external">
<variable name="oauth2_client_external" type="web_address" description="OAuth2 client external" mandatory='True' multi="True"/> <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"> <variable name="oauth2_client_family" description="OAuth2 family" supplier="OAuth2:family">
<value>users</value> <value>users</value>
</variable> </variable>
</family> </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> <value>Défaut</value>
</variable> </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> <value>demo.png</value>
</variable> </variable>
<variable name="oauth2_client_id" description="OAuth2 ID" mandatory='True' hidden='True'/> <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_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'> <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> <value>HS512</value>
<choice>HS512</choice> <choice>HS512</choice>
<choice>RS256</choice> <choice>RS256</choice>
</variable> </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> </family>
</variables> </variables>
<constraints> <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"> <fill name="normalize_family">
<param type="variable">domain_name_eth0</param> <param type="variable">domain_name_eth0</param>
<target>oauth2_client_id</target> <target>oauth2_client_id</target>
@ -49,32 +45,6 @@
<param name="hide" type="variable">hide_secret</param> <param name="hide" type="variable">hide_secret</param>
<target>oauth2_client_secret</target> <target>oauth2_client_secret</target>
</fill> </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"> <fill name="calc_oauth2_client_external">
<param type="variable" optional="True">revprox_client_external_domainnames</param> <param type="variable" optional="True">revprox_client_external_domainnames</param>
<param type="variable" optional="True">revprox_client_location</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 @_multi_function
def calc_oauth2_client_external(external, location, *extras): def calc_oauth2_client_external(external, location, *extras):
if not external or not location or None in extras: if not external or not location or None in extras:
if isinstance(external, list):
return []
return return
if isinstance(external, list): if isinstance(external, list):
return [f'https://{exter}{location[0]}' + ''.join(extras) for exter in external] 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: 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 description: OpenLDAP server
depends: depends:
- ldap-client-fedora - ldap-client-fedora
- base-fedora-35 - base-fedora-36
provider: LDAP

View file

@ -76,10 +76,9 @@
<variable name='ldapclient_user' redefine="True"/> <variable name='ldapclient_user' redefine="True"/>
<!--variable name='ldapclient_user_password' redefine="True"/--> <!--variable name='ldapclient_user_password' redefine="True"/-->
<variable name='ldapclient_family' redefine="True" disabled="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_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='ldapclient_search_dn' redefine="True"/>
<variable name='ldap_group_dn' type='string' description="Base DN de l'annuaire des groupes" mandatory="True" provider="ldap_group"/>
</family> </family>
</family> </family>
</variables> </variables>
@ -89,29 +88,20 @@
<param type='variable'>domain_name_eth0</param> <param type='variable'>domain_name_eth0</param>
<target>ldap_server_address</target> <target>ldap_server_address</target>
</fill> </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"> <fill name="calc_ldapclient_base_dn">
<param type="variable">ldapclient_base_dn</param> <param type="variable">ldapclient_base_dn</param>
<param name="base" type="boolean">True</param> <param name="base" type="boolean">True</param>
<target>ldap_account_dn</target> <target>ldap_account_dn</target>
</fill> </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'> <fill name='calc_value'>
<param>cn=admin</param> <param>cn=admin</param>
<param type='variable'>ldapclient_base_dn</param> <param type='variable'>ldapclient_base_dn</param>
<param name="join">,</param> <param name="join">,</param>
<target>ldapclient_user</target> <target>ldapclient_user</target>
</fill> </fill>
<fill name='calc_value'>
<param type="variable">ldapclient_base_dn</param>
<target>ldapclient_search_dn</target>
</fill>
</constraints> </constraints>
</rougail> </rougail>

View file

@ -1,13 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10"> <rougail version="0.10">
<variables> <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"> <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="family_" description="Nom de la familly de " hidden="True" provider="LDAP:family"/>
<variable name="dn_" description="LDAP DN de " hidden="True" provider="dn"/> <variable name="dn_" description="LDAP DN de " hidden="True" provider="LDAP:dn"/>
<variable name="password_" description="Mot de passe de " hidden="True" provider="client_password"/> <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="base_dn"/> <variable name="base_dn_" description="LDAP base DN de " hidden="True" provider="LDAP:base_dn"/>
<variable name="read_only_" description="Le compte est en lecture seule de " type="boolean"/>
</family> </family>
<family name="users" description="Gestion des utilisateurs" leadership="True"> <family name="users" description="Gestion des utilisateurs" leadership="True">
<variable name='ldap_user_mail' type="mail" description="Adresse courriel du compte" multi="True"/> <variable name='ldap_user_mail' type="mail" description="Adresse courriel du compte" multi="True"/>
@ -30,19 +29,6 @@
</family> </family>
</variables> </variables>
<constraints> <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"> <fill name="get_password">
<param name="server_name" type="variable">domain_name_eth0</param> <param name="server_name" type="variable">domain_name_eth0</param>
<param name="username" type='variable'>accounts.users.ldap_user_mail</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: with open(_SSHA_PASSWORD_DIR, 'w') as fh:
_dump(passwords, fh) _dump(passwords, fh)
return ret 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 %%name = %%normalize_family(%%remote)
%set %%family = %%accounts['remote_' + %%name]['family_' + %%name] %set %%family = %%accounts['remote_' + %%name]['family_' + %%name]
%%groups.append(%%accounts['remote_' + %%name]['dn_' + %%name])%slurp %%groups.append(%%accounts['remote_' + %%name]['dn_' + %%name])%slurp
%if %%accounts['remote_' + %%name]['read_only_' + %%name] %set %%right = 'read'
%set %%right = 'read' # %if %%accounts['remote_' + %%name]['read_only_' + %%name]
%else # %set %%right = 'read'
%set %%right = 'write' # %else
%end if # %set %%right = 'write'
# %end if
%%dns.setdefault(%%family, []).append((%%accounts['remote_' + %%name]['dn_' + %%name], %%right))%slurp %%dns.setdefault(%%family, []).append((%%accounts['remote_' + %%name]['dn_' + %%name], %%right))%slurp
%end for %end for
dn: olcDatabase={2}mdb,cn=config dn: olcDatabase={2}mdb,cn=config
@ -25,7 +26,7 @@ olcAccess: {0}to attrs=userPassword
by self write by self write
by anonymous auth by anonymous auth
by * none by * none
olcAccess: {1}to dn.subtree="%%ldap_group_dn" olcAccess: {1}to dn.subtree="%%ldapclient_group_dn"
%for group in %%groups %for group in %%groups
by dn="%%group" read by dn="%%group" read
%end for %end for

View file

@ -1,25 +1,30 @@
%set %%username = "rougail_test@silique.fr" %set %%username = "rougail_test@silique.fr"
%set %%username_family = "rougail_test@gnunux.info" %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 address: %%ip_eth0
admin_dn: %%ldapclient_user admin_dn: %%ldapclient_user
admin_password: %%ldapclient_user_password admin_password: %%ldapclient_user_password
user_dn: cn=%%username,%%ldap_user_dn user_dn: %%userdn
user_password: %%get_password(server_name=%%ldap_server_address, username=%%username, description="ldap user", type="cleartext", hide=%%hide_secret, temporary=True) user_password: %%get_password(server_name='test', username=%%username, description='test', type="cleartext", hide=%%hide_secret, temporary=True)
user_family_dn: cn=%%username_family,%%familydn user_family_dn: %%userfamilydn
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_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_account_dn: %%ldap_account_dn
base_user_dn: %%ldap_user_dn base_user_dn: %%ldapclient_user_dn
base_family_dn: %%familydn base_family_dn: %%familydn
base_group_dn: %%ldap_group_dn base_group_dn: %%ldapclient_group_dn
%for %%idx in %%range(3) %for %%idx in %%range(3)
%set %%name = 'remote_test' + %%str(%%idx) %set %%name = 'remote_test' + %%str(%%idx)
remote%%idx: cn=%%name,%%ldapclient_base_dn 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) remote_password%%idx: %%get_password(server_name=%%domain_name_eth0, username=%%name, description="remote account", type="cleartext", hide=%%hide_secret, temporary=True)
%end for %end for
users: users:
%%username: %%userdn
%%username_family: %%userfamilydn
%for %%user in %%accounts.users.ldap_user_mail %for %%user in %%accounts.users.ldap_user_mail
%%user: cn=%%user,%%ldap_user_dn %%user: cn=%%user,%%ldapclient_user_dn
%end for %end for
%for %%family in %%accounts.families %for %%family in %%accounts.families
%set %%families = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, %%family) %set %%families = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, %%family)
@ -29,11 +34,15 @@ users:
%end for %end for
groups: groups:
users: users:
- %%userdn
%for %%user in %%accounts.users.ldap_user_mail %for %%user in %%accounts.users.ldap_user_mail
- cn=%%user,%%ldap_user_dn - cn=%%user,%%ldapclient_user_dn
%end for %end for
%for %%family in %%accounts.families %for %%family in %%accounts.families
%%family: %%family:
%if %%family == %%name_family
- %%userfamilydn
%end if
%for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family] %for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family]
- cn=%%user,%%families - cn=%%user,%%families
%end for %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 # BaseDN
%set groups = {} %set groups = {}
dn: %%ldapclient_base_dn dn: %%ldapclient_base_dn
@ -38,36 +40,23 @@ objectClass: top
objectClass: organizationalUnit objectClass: organizationalUnit
## Accounts users ## Accounts users
%set %%users = %%ldap_user_dn %set %%users = %%ldapclient_user_dn
dn: %%users dn: %%users
ou: users ou: users
objectClass: top objectClass: top
objectClass: organizationalUnit 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 %for %%user in %%accounts.users.ldap_user_mail
%set %%userdn = "cn=" + %%user + "," + %%users %set %%userdn = "cn=" + %%user + "," + %%users
%%groups.setdefault('users', []).append(%%userdn) %%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
dn: %%userdn %%groups.setdefault('users', []).append(%%userdn)%slurp
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
%end for %end for
## Families ## Families
dn: %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name='-') 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] %for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family]
%set %%userdn = "cn=" + %%user + "," + %%families %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 dn: %%userdn
cn: %%user cn: %%user
mail: %%user mail: %%user
sn: %%user['ldap_user_sn_' + %%family] sn: %%sn
givenName: %%user['ldap_user_gn_' + %%family] givenName: %%gn
uid: %%user['ldap_user_uid_' + %%family] uid: %%uid
userPassword:: %%ssha_encode(%%user['ldap_user_password_' + %%family]) userPassword:: %%ssha_encode(%%password)
%if %%family == 'users'
homeDirectory: /srv/home/users/%%user
%else
homeDirectory: /srv/home/families/%%family/%%user homeDirectory: /srv/home/families/%%family/%%user
%end if
mailLocalAddress: %%user mailLocalAddress: %%user
%if %%user['ldap_user_aliases_' + %%family] %if %%aliases
%for %%alias in %%user['ldap_user_aliases_' + %%family] %for %%alias in %%aliases
mailLocalAddress: %%alias mailLocalAddress: %%alias
%end for %end for
%end if %end if
@ -106,10 +127,9 @@ objectClass: inetOrgPerson
objectClass: posixAccount objectClass: posixAccount
objectClass: inetLocalMailRecipient objectClass: inetLocalMailRecipient
%end for
%end for %end for
## Groups ## Groups
%set %%groupdn = %%ldap_group_dn %set %%groupdn = %%ldapclient_group_dn
dn: %%groupdn dn: %%groupdn
ou: groups ou: groups
objectClass: top 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 # Remote
%set %%acc = [] %set %%acc = []
%for %%idx in %%range(3) %for %%idx in %%range(3)
@ -17,30 +19,29 @@ userPassword:: %%ssha_encode(%%password)
%end for %end for
# Users # 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 %for %%user in %%accounts.users.ldap_user_mail
%set %%userdn = 'cn=' + %%user + ',' + %%users %set %%userdn = 'cn=' + %%user + ',' + %%users
%%groups.setdefault('users', []).append(%%userdn)%slurp %%groups['users'].append(%%userdn)%slurp
dn: %%userdn %%acc.append((%%userdn, %%user, %%user.ldap_user_aliases))%slurp
changetype: modify
#add: objectClass
#objectClass: inetLocalMailRecipient
#-
replace: mailLocalAddress
mailLocalAddress: %%user
%if %%user.ldap_user_aliases
%for %%alias in %%user.ldap_user_aliases
mailLocalAddress: %%alias
%end for
%end if
%end for %end for
# Families
%for %%family in %%accounts.families %for %%family in %%accounts.families
%set %%families = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, %%family) %set %%families = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, %%family)
%for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family] %for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family]
%set %%userdn = 'cn=' + %%user + ',' + %%families %set %%userdn = 'cn=' + %%user + ',' + %%families
%%groups.setdefault(%%family, []).append(%%userdn)%slurp %%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 dn: %%userdn
changetype: modify changetype: modify
#add: objectClass #add: objectClass
@ -48,16 +49,15 @@ changetype: modify
#- #-
replace: mailLocalAddress replace: mailLocalAddress
mailLocalAddress: %%user mailLocalAddress: %%user
%if %%user['ldap_user_aliases_' + %%family] %if %%aliases
%for %%alias in %%user['ldap_user_aliases_' + %%family] %for %%alias in %%aliases
mailLocalAddress: %%alias mailLocalAddress: %%alias
%end for %end for
%end if %end if
%end for
%end for %end for
# Groups # Groups
%set %%groupdn = %%ldap_group_dn %set %%groupdn = %%ldapclient_group_dn
%for %%group, %%members in %%groups.items() %for %%group, %%members in %%groups.items()
dn: cn=%%group,%%groupdn dn: cn=%%group,%%groupdn
changetype: modify changetype: modify

View file

@ -70,13 +70,16 @@ def test_ldap_user():
l.simple_bind_s(data['user_dn'], data['user_password']) 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' conf_file = f'{environ["MACHINE_TEST_DIR"]}/openldap.yml'
with open(conf_file) as yaml: with open(conf_file) as yaml:
data = load(yaml, Loader=SafeLoader) data = load(yaml, Loader=SafeLoader)
set_option(OPT_X_TLS_REQUIRE_CERT, OPT_X_TLS_NEVER) set_option(OPT_X_TLS_REQUIRE_CERT, OPT_X_TLS_NEVER)
l = initialize(f'ldaps://{data["address"]}') 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(): def test_ldap_remote_auth():

View file

@ -68,7 +68,7 @@ server {
location @api { location @api {
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 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 X-Real-IP $remote_addr;
client_max_body_size 100k; # default is 1M client_max_body_size 100k; # default is 1M
@ -119,7 +119,7 @@ server {
location @api_websocket { location @api_websocket {
proxy_http_version 1.1; proxy_http_version 1.1;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 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 X-Real-IP $remote_addr;
# proxy_set_header Upgrade $http_upgrade; # proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "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) # Correspond to your reverse proxy server_name/listen configuration (i.e., your public PeerTube instance URL)
webserver: webserver:
https: true https: true
hostname: '%%revprox_client_external_domainname' hostname: '%%revprox_client_external_domainnames[0]'
port: 443 port: 443
rates_limit: rates_limit:

View file

@ -5,7 +5,7 @@
<file source="tmpfile-piwigo.conf">/tmpfiles.d/0piwigo.conf</file> <file source="tmpfile-piwigo.conf">/tmpfiles.d/0piwigo.conf</file>
<file>/etc/piwigo/config.inc.php</file> <file>/etc/piwigo/config.inc.php</file>
<file>/etc/piwigo/database.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> <file engine="none">/etc/php-fpm.d/piwigo.conf</file>
</service> </service>
</services> </services>

View file

@ -5,7 +5,7 @@ Before=nginx.service php-fpm.service
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart=/usr/local/lib/bin/piwigo.sh ExecStart=/usr/local/lib/sbin/piwigo.sh
User=nginx User=nginx
Group=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"?> <?xml version="1.0" encoding="utf-8"?>
<rougail version="0.10"> <rougail version="0.10">
<variables> <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"> <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> </family>
</variables> </variables>
<constraints> <constraints>

View file

@ -49,3 +49,9 @@ postconf maillog_file=/dev/stdout
https://www.mail-tester.com/ https://www.mail-tester.com/
https://dkimvalidator.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' format: '0.1'
description: Postfix has relay description: Postfix as relay
depends: depends:
- base-fedora-35 - base-fedora-35
- dns-external - dns-external
provider: SMTP - postfix-lmtp-relay

View file

@ -43,10 +43,9 @@
<family name="postfix" description="Postfix mail server"> <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_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_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'> <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="SMTP:password"/>
<variable name="local_authentification_password_" type="secret" auto_save="False" provider="mail_password"/>
</family> </family>
<variable name='postfix_pem_files' type="filename" hidden='True' multi='True'/> <variable name='postfix_pem_files' type="filename" hidden='True' multi='True'/>
</family> </family>
@ -63,14 +62,6 @@
<param name="multi" type="boolean">True</param> <param name="multi" type="boolean">True</param>
<target>opendkim_keys</target> <target>opendkim_keys</target>
</fill> </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"> <fill name="calc_value">
<param>/etc/postfix/certs/</param> <param>/etc/postfix/certs/</param>
<param type="variable">domain_name_eth</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 = 168.100.3.0/28, 127.0.0.0/8
#mynetworks = $config_directory/mynetworks #mynetworks = $config_directory/mynetworks
#mynetworks = hash:/etc/postfix/network_table #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 # The relay_domains parameter restricts what destinations this system will
# relay mail to. See the smtpd_recipient_restrictions description in # 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 %for %%local in %%postfix_relay_authentifications
%set %%user = %%normalize_family(%%local) %set %%user = %%normalize_family(%%local)
%set %%password = %%getVar('local_authentification_password_' + %%user) %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" ExecStartPre=-/usr/bin/bash -c "echo %%password | /usr/sbin/saslpasswd2 -u %%ip %%user -p"
%end for %end for
ExecStartPre=/usr/bin/chown postfix: /etc/sasl2/sasldb2 ExecStartPre=/usr/bin/chown postfix: /etc/sasl2/sasldb2

View file

@ -10,9 +10,9 @@
</services> </services>
<variables> <variables>
<family name="postgresql" description="PostgreSQL"> <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_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_database" description="Client database" mandatory="True" hidden="True"/>
<variable name="pg_client_key_owner" type="unix_user" description="Key owner" mandatory="True"> <variable name="pg_client_key_owner" type="unix_user" description="Key owner" mandatory="True">
<value>apache</value> <value>apache</value>
@ -24,18 +24,17 @@
<param type="variable">domain_name_eth0</param> <param type="variable">domain_name_eth0</param>
<target>pg_client_username</target> <target>pg_client_username</target>
</fill> </fill>
<fill name="get_provider_name"> <!--fill name="get_provider_name">
<param type="variable">zone_name_eth0</param> <param type="variable">zone_name_eth0</param>
<param>Postgresql</param> <param>Postgresql</param>
<target>pg_client_server_domainname</target> <target>pg_client_server_domainname</target>
</fill> </fill-->
<fill name="set_linked_multi_variables"> <fill name="get_password">
<param type="variable">pg_client_server_domainname</param> <param name="server_name" type="variable">pg_client_server_domainname</param>
<param name="linked_value_0" type="variable">domain_name_eth0</param> <param name="username" type="variable">domain_name_eth0</param>
<param name="linked_provider_0">clients</param> <param name="description">remote</param>
<param name="linked_value_1" type="variable">ip_eth0</param> <param name="type">cleartext</param>
<param name="linked_provider_1">client_ip</param> <param name="hide" type="variable">hide_secret</param>
<param name="linked_returns">client_password</param>
<target>pg_client_password</target> <target>pg_client_password</target>
</fill> </fill>
<fill name="calc_value"> <fill name="calc_value">

View file

@ -5,5 +5,5 @@ Before=network.target
[Service] [Service]
Type=oneshot Type=oneshot
Environment=PGPASSFILE=/usr/local/lib/secrets/postgresql.pass 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"' 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' format: '0.1'
description: Postgresql description: Postgresql
depends: depends:
- server - base-fedora-36
- base-fedora-35
provider: Postgresql

View file

@ -2,17 +2,19 @@
<rougail version="0.10"> <rougail version="0.10">
<services> <services>
<service name="postgresql" target="multi-user"> <service name="postgresql" target="multi-user">
<override engine="none"/> <override/>
<ip ip_type='variable'>accounts.remote_.remote_ip_</ip> <ip ip_type='variable'>accounts.remote_.remote_ip_</ip>
<file>/etc/postgresql/postgresql.conf</file> <file>/etc/postgresql/postgresql.conf</file>
<file>/etc/postgresql/pg_hba.conf</file> <file>/etc/postgresql/pg_hba.conf</file>
<file mode="600" owner="postgres" group="postgres">/etc/postgresql/postgresql.sql</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">/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="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/ca-trust/source/anchors/ca_PostgreSQL.crt</file>
<file>/etc/pki/tls/certs/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 owner="root" group="postgres" mode="440">/etc/pki/tls/private/postgresql.key</file>
<file>/tests/postgresql.yml</file>
</service> </service>
</services> </services>
<variables> <variables>

View file

@ -1,20 +1,16 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10"> <rougail version="0.10">
<variables> <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"> <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" mandatory="True"/>
<variable name="remote_ip_" description="Remote IP" type="ip" hidden="True" provider="client_ip"/> <variable name="password_" description="Remote password" auto_save="False" hidden="True" type="password" mandatory="True" provider="Postgresql:password"/>
</family> </family>
</variables> </variables>
<constraints> <constraints>
<fill name="get_password"> <fill name="get_ip">
<param name="server_name" type="variable">domain_name_eth0</param> <param type="suffix"/>
<param name="username" type="suffix"/> <target>accounts.remote_.remote_ip_</target>
<param name="description">remote</param>
<param name="type">cleartext</param>
<param name="hide" type="variable">hide_secret</param>
<target>accounts.remote_.password_</target>
</fill> </fill>
</constraints> </constraints>
</rougail> </rougail>

View file

@ -1 +1,3 @@
PKG="$PKG postgresql-server postgresql-contrib" 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: # IPv4 local connections:
#>GNUNUX #>GNUNUX
# host all all 127.0.0.1/32 ident # host all all 127.0.0.1/32 ident
hostssl rougail_test rougail_test %%gateway_eth0/32 md5
%for %%server in %%accounts.remotes %for %%server in %%accounts.remotes
hostssl %%normalize_family(%%server) %%normalize_family(%%server) %%server md5 hostssl %%normalize_family(%%server) %%normalize_family(%%server) %%server md5
%end for %end for

View file

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

View file

@ -1,11 +1,38 @@
[Service] [Service]
ExecStartPre= Environment=PGDATA=/srv/postgresql/postgresql
ExecStartPre=+/usr/local/lib/bin/postgresql_init
ExecStartPre=/usr/libexec/postgresql-check-db-dir %N
Environment=PGDATA=/srv/postgresql
Environment=PG_CONF=/etc/postgresql/postgresql.conf Environment=PG_CONF=/etc/postgresql/postgresql.conf
Environment=PG_HBA=/etc/postgresql/pg_hba.conf Environment=PG_HBA=/etc/postgresql/pg_hba.conf
Environment=PG_IDENT=/etc/postgresql/pg_ident.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=
ExecStart=/usr/bin/postmaster -D ${PGDATA} -c config_file=${PG_CONF} -c hba_file=${PG_HBA} -c ident_file=${PG_IDENT} 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 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 %for %%server in %%accounts.remotes
%set %%name = %%normalize_family(%%server) %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 DATABASE "%%name";
CREATE ROLE "%%name" WITH LOGIN ENCRYPTED PASSWORD '%%accounts["remote_" + %%name]["password_" + %%name]'; CREATE ROLE "%%name" WITH LOGIN ENCRYPTED PASSWORD '%%password';
ALTER USER "%%name" PASSWORD '%%accounts["remote_" + %%name]["password_" + %%name]'; ALTER USER "%%name" PASSWORD '%%password';
GRANT ALL PRIVILEGES ON DATABASE "%%name" TO "%%name"; GRANT ALL PRIVILEGES ON DATABASE "%%name" TO "%%name";
%end for %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 #!/bin/bash -e
[ -d "/srv/postgresql" ] && exit 0 || true if [ ! -d "/srv/postgresql" ]; then
/bin/mkdir -p /srv/postgresql/postgresql
/bin/mkdir /srv/postgresql /bin/chown -R postgres: /srv/postgresql
/bin/chown postgres: /srv/postgresql /usr/bin/postgresql-setup --initdb
mkdir /var/lib/pgsql #/bin/rm /srv/postgresql/postgresql.conf
/bin/chown postgres: /var/lib/pgsql #/bin/rm /srv/postgresql/pg_hba.conf
/usr/bin/postgresql-setup --initdb #/bin/rm /srv/postgresql/pg_ident.conf
/bin/rm /srv/postgresql/postgresql.conf elif [ ! -d "/srv/postgresql/postgresql" ]; then
/bin/rm /srv/postgresql/pg_hba.conf # migrate /srv/postgresql to /srv/postgresql/postgresql
/bin/rm /srv/postgresql/pg_ident.conf # 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 exit 0

View file

@ -1,3 +1,3 @@
g postgres 26 - 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