forked from stove/dataset
Compare commits
3 commits
69c3a1c375
...
4d98ec14f1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d98ec14f1 | ||
|
|
7be018a275 | ||
|
|
4cbbedac89 |
8 changed files with 213 additions and 24 deletions
42
seed/base-machine/manual/install/backup
Executable file
42
seed/base-machine/manual/install/backup
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
HOST_NAME=$1
|
||||
START=$2
|
||||
if [ -z "$HOST_NAME" ]; then
|
||||
echo "usage: $0 host name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. config.sh
|
||||
|
||||
MACHINES=""
|
||||
for image in *; do
|
||||
if [ -d "$image" ]; then
|
||||
for os in $image/configurations/*; do
|
||||
if [ -d "$os" ]; then
|
||||
machine="$(basename $os)"
|
||||
if [ -d "/var/lib/risotto/srv/$machine" ]; then
|
||||
MACHINES="$MACHINES$machine "
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
cd /var/lib/risotto/srv/
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
for machine in $MACHINES; do
|
||||
machinectl stop $machine || true
|
||||
while true; do
|
||||
machinectl status "$machine" > /dev/null 2>&1 || break
|
||||
sleep 1
|
||||
done
|
||||
BACKUP_FILE="$BACKUP_DIR/backup_$machine.tar.bz2"
|
||||
rm -f "$BACKUP_FILE"
|
||||
tar -cvjf $BACKUP_FILE $machine
|
||||
done
|
||||
|
||||
if [ -z "$START" ]; then
|
||||
machinectl start $MACHINES
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
@ -4,6 +4,7 @@ RISOTTO_IMAGE_DIR="$RISOTTO_DIR/images"
|
|||
RISOTTO_SRV_DIR="$RISOTTO_DIR/srv"
|
||||
RISOTTO_CONFIG_DIR="$RISOTTO_DIR/configurations"
|
||||
MACHINES_DIR="/var/lib/machines"
|
||||
BACKUP_DIR="/root/backup"
|
||||
# image configuration
|
||||
IMAGE_BASE_RISOTTO_BASE_DIR="$RISOTTO_IMAGE_DIR/image_bases"
|
||||
IMAGE_NAME_RISOTTO_IMAGE_DIR="$RISOTTO_IMAGE_DIR/$IMAGE_NAME"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
format: '0.1'
|
||||
description: Postfix et Dovecot
|
||||
depends:
|
||||
- base-fedora-35
|
||||
- base-fedora-36
|
||||
- relay-mail-client
|
||||
- ldap-client-fedora
|
||||
- oauth2-client
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
<file owner="root" group="dovecot" mode="440">/etc/pki/tls/private/dovecot.key</file>
|
||||
<file source="external_imap.crt" file_type="variable" variable="imap_domainname">external_imap_crt</file>
|
||||
<file owner="root" group="dovecot" mode="440" source="external_imap.key" file_type="variable" variable="imap_domainname">external_imap_key</file>
|
||||
<file>/tests/imap.yml</file>
|
||||
</service>
|
||||
</services>
|
||||
<variables>
|
||||
|
|
|
|||
10
seed/dovecot/templates/imap.yml
Normal file
10
seed/dovecot/templates/imap.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
%set %%username="rougail_test@silique.fr"
|
||||
%set %%username_family="rougail_test@gnunux.info"
|
||||
%set %%name_family="gnunux"
|
||||
address: %%ip_eth0
|
||||
dns: %%domain_name_eth0
|
||||
username: %%username
|
||||
password: %%get_password(server_name=%%ldap_server_address, username=%%username, description="ldap user", type="cleartext", hide=%%hide_secret, temporary=True)
|
||||
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)
|
||||
name_family: %%name_family
|
||||
131
seed/dovecot/tests/test_imap.py
Normal file
131
seed/dovecot/tests/test_imap.py
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
from yaml import load, SafeLoader
|
||||
from os import environ
|
||||
from os.path import isdir
|
||||
import pytest
|
||||
|
||||
from imaplib2 import IMAP4_SSL
|
||||
from smtplib import SMTP, SMTPNotSupportedError, SMTPAuthenticationError
|
||||
|
||||
|
||||
|
||||
conf_file = f'{environ["MACHINE_TEST_DIR"]}/imap.yml'
|
||||
with open(conf_file) as yaml:
|
||||
data = load(yaml, Loader=SafeLoader)
|
||||
parameters = (('user', data['username'], data['password']),
|
||||
('family', data['username_family'], data['password_family']),
|
||||
)
|
||||
|
||||
|
||||
def get_msg(username, msg='MESSAGE'):
|
||||
return f'From: {username}\r\nTo: {username}\r\n\r\nSubject: TEST\r\n{msg}\r\n'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_imap_wrong_password(typ, username, password):
|
||||
imap = IMAP4_SSL(data['address'])
|
||||
try:
|
||||
imap.LOGIN(username, 'b')
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
raise Exception('wrong login !')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_imap_migration(typ, username, password):
|
||||
if typ == 'family':
|
||||
dirname = f'/var/lib/risotto/srv/{data["dns"]}/home/families/{data["name_family"]}/{username}'
|
||||
else:
|
||||
dirname = f'/var/lib/risotto/srv/{data["dns"]}/home/users/{username}'
|
||||
msg = get_msg(username, 'MIGRATION')
|
||||
if not isdir(dirname):
|
||||
smtp = SMTP(data['address'], '587')
|
||||
smtp.starttls()
|
||||
smtp.login(username, password)
|
||||
smtp.sendmail(username, username, msg)
|
||||
smtp.quit()
|
||||
imap = IMAP4_SSL(data['address'])
|
||||
imap.LOGIN(username, password)
|
||||
imap.SELECT(readonly=True)
|
||||
typ, req = imap.SEARCH(None, 'ALL')
|
||||
assert typ == 'OK'
|
||||
assert len(req) == 1
|
||||
assert req[0] == b'1'
|
||||
field = imap.FETCH('1', '(RFC822)')
|
||||
assert field[0] == 'OK'
|
||||
assert field[1][-2][-1].decode().endswith(msg)
|
||||
imap.CLOSE()
|
||||
imap.LOGOUT()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_smtp_no_tls(typ, username, password):
|
||||
smtp = SMTP(data['address'], '587')
|
||||
try:
|
||||
smtp.login(username, password)
|
||||
raise Exception('no tls!')
|
||||
except SMTPNotSupportedError:
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_smtp_wrong_passwd(typ, username, password):
|
||||
smtp = SMTP(data['address'], '587')
|
||||
smtp.starttls()
|
||||
try:
|
||||
smtp.login(username, 'a')
|
||||
raise Exception('wrong password!')
|
||||
except SMTPAuthenticationError:
|
||||
pass
|
||||
smtp.quit()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_smtp_login(typ, username, password):
|
||||
smtp = SMTP(data['address'], '587')
|
||||
smtp.starttls()
|
||||
smtp.login(username, password)
|
||||
smtp.quit()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_smtp_sendmail(typ, username, password):
|
||||
smtp = SMTP(data['address'], '587')
|
||||
smtp.starttls()
|
||||
smtp.login(username, password)
|
||||
smtp.sendmail(username, username, get_msg(username))
|
||||
smtp.quit()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_imap_read_mail(typ, username, password):
|
||||
imap = IMAP4_SSL(data['address'])
|
||||
imap.LOGIN(username, password)
|
||||
imap.SELECT(readonly=True)
|
||||
typ, req = imap.SEARCH(None, 'ALL')
|
||||
assert typ == 'OK'
|
||||
assert len(req) == 1
|
||||
msg = get_msg(username)
|
||||
msg_no = req[0].split()
|
||||
assert len(msg_no) == 2
|
||||
for num in msg_no[1:]:
|
||||
field = imap.FETCH(num, '(RFC822)')
|
||||
assert field[0] == 'OK'
|
||||
assert field[1][-2][-1].decode().endswith(msg)
|
||||
imap.CLOSE()
|
||||
imap.LOGOUT()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('typ, username, password', parameters)
|
||||
def test_imap_delete_mail(typ, username, password):
|
||||
imap = IMAP4_SSL(data['address'])
|
||||
imap.LOGIN(username, password)
|
||||
imap.SELECT()
|
||||
typ, req = imap.SEARCH(None, 'ALL')
|
||||
msg_no = req[0].split()
|
||||
for num in msg_no[1:]:
|
||||
ret = imap.store(num, '+FLAGS', '\\Deleted')
|
||||
assert ret[0] == 'OK', f'error when deleting mail: {ret}'
|
||||
imap.expunge()
|
||||
imap.CLOSE()
|
||||
imap.LOGOUT()
|
||||
|
|
@ -6,6 +6,7 @@ After=network.target local-fs.target systemd-logind.service
|
|||
Type=oneshot
|
||||
WorkingDirectory=%%host_install_dir
|
||||
ExecStart=%%host_install_dir/install_images %%host_name
|
||||
ExecStart=%%host_install_dir/backup %%host_name no
|
||||
ExecStart=%%host_install_dir/install_machines %%host_name
|
||||
|
||||
[Install]
|
||||
|
|
|
|||
|
|
@ -98,14 +98,14 @@ server:
|
|||
# num-queries-per-thread, or, use as many as the OS will allow you.
|
||||
# outgoing-range: 4096
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# permit Unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Only ephemeral ports are allowed by SElinux
|
||||
outgoing-port-permit: 32768-60999
|
||||
|
||||
# deny unbound the use this of port number or port range for
|
||||
# deny Unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# Use this to make sure Unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# If multiple outgoing-port-permit and outgoing-port-avoid options
|
||||
|
|
@ -238,7 +238,7 @@ server:
|
|||
# do-ip6: yes
|
||||
|
||||
# Enable UDP, "yes" or "no".
|
||||
# NOTE: if setting up an unbound on tls443 for public use, you might want to
|
||||
# NOTE: if setting up an Unbound on tls443 for public use, you might want to
|
||||
# disable UDP to avoid being used in DNS amplification attacks.
|
||||
# do-udp: yes
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ server:
|
|||
# use-systemd: no
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
# Set the value to "no" when unbound runs as systemd service.
|
||||
# Set the value to "no" when Unbound runs as systemd service.
|
||||
# do-daemonize: yes
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
|
|
@ -328,7 +328,7 @@ server:
|
|||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/urandom (for entropy).
|
||||
# Additionally, Unbound may need to access /dev/urandom (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
|
|
@ -542,7 +542,7 @@ server:
|
|||
# Use several entries, one per domain name, to track multiple zones.
|
||||
#
|
||||
# If you want to perform DNSSEC validation, run unbound-anchor before
|
||||
# you start unbound (i.e. in the system boot scripts). And enable:
|
||||
# you start Unbound (i.e. in the system boot scripts). And enable:
|
||||
# Please note usage of unbound-anchor root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see that file in the source).
|
||||
# auto-trust-anchor-file: "/var/lib/unbound/root.key"
|
||||
|
|
@ -620,7 +620,7 @@ server:
|
|||
val-permissive-mode: no
|
||||
|
||||
# Ignore the CD flag in incoming queries and refuse them bogus data.
|
||||
# Enable it if the only clients of unbound are legacy servers (w2008)
|
||||
# Enable it if the only clients of Unbound are legacy servers (w2008)
|
||||
# that set CD but cannot validate themselves.
|
||||
# ignore-cd-flag: no
|
||||
|
||||
|
|
@ -650,7 +650,7 @@ server:
|
|||
|
||||
# Return the original TTL as received from the upstream name server rather
|
||||
# than the decrementing TTL as stored in the cache. Enabling this feature
|
||||
# does not impact cache expiry, it only changes the TTL unbound embeds in
|
||||
# does not impact cache expiry, it only changes the TTL Unbound embeds in
|
||||
# responses to queries. Note that enabling this feature implicitly disables
|
||||
# enforcement of the configured minimum and maximum TTL.
|
||||
# serve-original-ttl: no
|
||||
|
|
@ -743,9 +743,9 @@ server:
|
|||
# Add example.com into ipset
|
||||
# local-zone: "example.com" ipset
|
||||
|
||||
# If unbound is running service for the local host then it is useful
|
||||
# If Unbound is running service for the local host then it is useful
|
||||
# to perform lan-wide lookups to the upstream, and unblock the
|
||||
# long list of local-zones above. If this unbound is a dns server
|
||||
# long list of local-zones above. If this Unbound is a dns server
|
||||
# for a network of computers, disabled is better and stops information
|
||||
# leakage of local lan information.
|
||||
# unblock-lan-zones: no
|
||||
|
|
@ -929,7 +929,7 @@ server:
|
|||
# the number of servers that will be used in the fast server selection.
|
||||
# fast-server-num: 3
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# Specific options for ipsecmod. Unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
#
|
||||
# Enable or disable ipsecmod (it still needs to be defined in
|
||||
|
|
@ -943,7 +943,7 @@ server:
|
|||
# ipsecmod-hook: "./my_executable"
|
||||
ipsecmod-hook:/usr/libexec/ipsec/_unbound-hook
|
||||
|
||||
# When enabled unbound will reply with SERVFAIL if the return value of
|
||||
# When enabled Unbound will reply with SERVFAIL if the return value of
|
||||
# the ipsecmod-hook is not 0.
|
||||
# ipsecmod-strict: no
|
||||
#
|
||||
|
|
@ -992,7 +992,7 @@ remote-control:
|
|||
# Enable remote control with unbound-control(8) here.
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# Note: required for unbound-munin package
|
||||
control-enable: yes
|
||||
control-enable: yes
|
||||
|
||||
# Set to no and use an absolute path as control-interface to use
|
||||
# a unix local named pipe for unbound-control.
|
||||
|
|
@ -1012,10 +1012,10 @@ remote-control:
|
|||
# For local sockets this option is ignored, and TLS is not used.
|
||||
control-use-cert: "no"
|
||||
|
||||
# unbound server key file.
|
||||
# Unbound server key file.
|
||||
# GNUNUX server-key-file: "/etc/unbound/unbound_server.key"
|
||||
|
||||
# unbound server certificate file.
|
||||
# Unbound server certificate file.
|
||||
# GNUNUX server-cert-file: "/etc/unbound/unbound_server.pem"
|
||||
|
||||
# unbound-control key file.
|
||||
|
|
@ -1132,7 +1132,7 @@ auth-zone:
|
|||
#
|
||||
# DNSCrypt
|
||||
# Caveats:
|
||||
# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper
|
||||
# 1. the keys/certs cannot be produced by Unbound. You can use dnscrypt-wrapper
|
||||
# for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
|
||||
# 2. dnscrypt channel attaches to an interface. you MUST set interfaces to
|
||||
# listen on `dnscrypt-port` with the follo0wing snippet:
|
||||
|
|
@ -1172,7 +1172,7 @@ auth-zone:
|
|||
|
||||
# IPSet
|
||||
# Add specify domain into set via ipset.
|
||||
# Note: To enable ipset unbound needs to run as root user.
|
||||
# Note: To enable ipset Unbound needs to run as root user.
|
||||
# ipset:
|
||||
# # set name for ip v4 addresses
|
||||
# name-v4: "list-v4"
|
||||
|
|
@ -1195,7 +1195,7 @@ auth-zone:
|
|||
# dnstap-tls: yes
|
||||
# # name for authenticating the upstream server. or "" disabled.
|
||||
# dnstap-tls-server-name: ""
|
||||
# # if "", it uses the cert bundle from the main unbound config.
|
||||
# # if "", it uses the cert bundle from the main Unbound config.
|
||||
# dnstap-tls-cert-bundle: ""
|
||||
# # key file for client authentication, or "" disabled.
|
||||
# dnstap-tls-client-key-file: ""
|
||||
|
|
@ -1215,10 +1215,11 @@ auth-zone:
|
|||
# dnstap-log-forwarder-response-messages: no
|
||||
|
||||
# Response Policy Zones
|
||||
# RPZ policies. Applied in order of configuration. QNAME and Response IP
|
||||
# Address trigger are the only supported triggers. Supported actions are:
|
||||
# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Policies can be loaded from
|
||||
# file, using zone transfer, or using HTTP. The respip module needs to be added
|
||||
# RPZ policies. Applied in order of configuration. QNAME, Response IP
|
||||
# Address, nsdname, nsip and clientip triggers are supported. Supported
|
||||
# actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
|
||||
# and drop. Policies can be loaded from a file, or using zone
|
||||
# transfer, or using HTTP. The respip module needs to be added
|
||||
# to the module-config, e.g.: module-config: "respip validator iterator".
|
||||
# rpz:
|
||||
# name: "rpz.example.com"
|
||||
|
|
@ -1230,4 +1231,6 @@ auth-zone:
|
|||
# rpz-cname-override: www.example.org
|
||||
# rpz-log: yes
|
||||
# rpz-log-name: "example policy"
|
||||
# rpz-signal-nxdomain-ra: no
|
||||
# for-downstream: no
|
||||
# tags: "example"
|
||||
|
|
|
|||
Loading…
Reference in a new issue