diff --git a/how-to/How-To-Setup-Nc-Env-In-Ubuntu-Desktop.md b/how-to/How-To-Setup-Nc-Env-In-Ubuntu-Desktop.md index 0db76b6..2474728 100644 --- a/how-to/How-To-Setup-Nc-Env-In-Ubuntu-Desktop.md +++ b/how-to/How-To-Setup-Nc-Env-In-Ubuntu-Desktop.md @@ -43,6 +43,13 @@ $ sudo apt install vim tree ``` +However, rysnc is needed, so install it: + +``` +$ sudo apt install rsync +``` + + ### LXD Installation Install LXD using snap: @@ -78,7 +85,7 @@ --- -:memo: Go thorugh this section only if you choose option 1 above. +:memo: Go through this section only if you choose option 1 above. --- @@ -104,7 +111,8 @@ ``` -$ wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg +$ wget -O /tmp/hashicorp-gpg https://apt.releases.hashicorp.com/gpg +$ sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg /tmp/hashicorp-gpg $ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list $ sudo apt update @@ -139,13 +147,6 @@ vagrant-lxd (0.6.0, global) ``` -As recommended in the vagrant-lxd documentation ([here](https://gitlab.com/catalyst-it/devtools/vagrant-lxd#synced-folders)), to ensure synced folders work as expected, run the following commands: - -``` -$ echo root:$(id -u):1 | sudo tee -a /etc/subuid -$ echo root:$(id -g):1 | sudo tee -a /etc/subgid -``` - ### Mkcert Installation Install mkcert, an utility that makes it easy to create locally trusted TLS certificates, from APT repositories @@ -172,18 +173,18 @@ --- -:memo: mkcert has browser detection logic, so if one is detected (Chrome, Firefox) the install command will let you know. If the browser is not detected for some reason (ex. Firefox installed via snap) the browser is not detected, you will need to manually import +:memo: mkcert has browser detection logic, so if one is detected (Chrome, Firefox) the install command will let you know. If the browser is not detected for some reason (ex. Firefox installed via snap), you will need to manually import the certificate in the browser. --- ### Nc-env Installation -Pick the latest release of the project from [here](https://codeberg.org/pmarini/nc-env/releases), in this example `v20230421`: +Pick the latest release of the project from [here](https://codeberg.org/pmarini/nc-env/releases), in this example `v20230420`: ``` -$ wget https://codeberg.org/pmarini/nc-env/archive/v20230421.tar.gz -$ tar -xzf v20230421.tar.gz +$ wget https://codeberg.org/pmarini/nc-env/archive/v20230420.tar.gz +$ tar -xzf v20230420.tar.gz $ cd nc-env/ ``` @@ -207,7 +208,7 @@ $ lxd init Would you like to use LXD clustering? (yes/no) [default=no]: no Do you want to configure a new storage pool? (yes/no) [default=yes]: yes -Name of the new storage pool [default=default]: pool01 +Name of the new storage pool [default=default]: lxdpool01 Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]: zfs Create a new ZFS pool? (yes/no) [default=yes]: yes Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: yes @@ -230,11 +231,12 @@ Create a LXD profile for the containers created in nc-env: ``` -$ lxc profile create prf-nc-env -$ lxc profile device add prf-nc-env root disk path=/ pool=pool01 size=5GB -$ lxc profile device add prf-nc-env eth0 nic nictype=bridged name=eth0 parent=lxdbr0 -$ lxc profile set prf-nc-env limits.memory 1GiB -$ lxc profile set prf-nc-env limits.cpu 1 +$ lxc profile create nc-env-prf +$ lxc profile device add nc-env-prf root disk path=/ pool=lxdpool01 size=5GB +$ lxc profile device add nc-env-prf eth0 nic nictype=bridged name=eth0 parent=lxdbr0 +$ lxc profile set nc-env-prf boot.autostart false +$ lxc profile set nc-env-prf limits.memory 1GB +$ lxc profile set nc-env-prf limits.cpu 1 $ lxc profile list +----------------+---------------------+---------+ | NAME | DESCRIPTION | USED BY | diff --git a/templates/template17-mail-server/Readme.md b/templates/template17-mail-server/Readme.md new file mode 100644 index 0000000..345f1f1 --- /dev/null +++ b/templates/template17-mail-server/Readme.md @@ -0,0 +1,25 @@ +### Stand-alone Nextcloud server + +#### Setup + +* Assuming that the copy of the template is called `mail-server`, move to folder `mail-server`. +* Check the content of folder `artifacts` + +|File name | Description| +| `rootCA.pem` | The rootCA previously created in your host machine | +| `rootCA-key.pem` | The rootCA key previously created in your host machine | +| mox | The program binary [here](https://beta.gobuilds.org/github.com/mjl-/mox) | +| domains.conf | Domain configuration file for Mox | +| mox.conf | Main configuration file for Mox | +| mox.service | Systemd service unit file for Mox | +| --- | --- | + + +* Create folder `log` +* Open `Vagrantfile` and change the value of variable `lxd.name`. It makes sense to give the same name as the folder, in this example `mail-server`. +* Open `provision.sh` + * change the value of variable `MACHINE_HOSTNAME`. It makes sense to give the same name as the folder, plus the domain, in this example `mail-server.localenv.com`. + * change the value of variable `MAIL_DOMAIN`. +* Run `vagrant up > log/provisioning.log` +* Make sure your system is able to resolve the domain name that you specified in variable `MACHINE_HOSTNAME`, for example by adding an entry in `/etc/hosts` +* Start using your environment diff --git a/templates/template17-mail-server/Vagrantfile b/templates/template17-mail-server/Vagrantfile new file mode 100644 index 0000000..e39c16d --- /dev/null +++ b/templates/template17-mail-server/Vagrantfile @@ -0,0 +1,34 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + + +Vagrant.configure("2") do |config| + + config.vm.box = "isc/forge-clt-ubuntu-22.04" + + config.vm.box_version = "1" + + config.vm.box_check_update = false + + config.vm.provider 'lxd' do |lxd| + lxd.api_endpoint = 'https://127.0.0.1:8443' + lxd.timeout = 10 + lxd.name = '' + lxd.project = 'default' + lxd.profiles = ['default'] + # lxd.nesting = nil + # lxd.privileged = nil + # lxd.ephemeral = false + # lxd.environment = {} + # lxd.config = {} + end + + config.vm.provision "shell" do |s| + s.env = { + "MACHINE_HOSTNAME" => "", + "MAIL_DOMAIN" => "" + } + s.path = "provision.sh" + end +end + diff --git a/templates/template17-mail-server/artifacts/domains.conf b/templates/template17-mail-server/artifacts/domains.conf new file mode 100644 index 0000000..29f2a70 --- /dev/null +++ b/templates/template17-mail-server/artifacts/domains.conf @@ -0,0 +1,157 @@ + +# Domains for which email is accepted. For internationalized domains, use their +# IDNA names in UTF-8. +Domains: + #MAIL_DOMAIN#: + + # If not empty, only the string before the separator is used to for email delivery + # decisions. For example, if set to "+", you+anything@example.com will be + # delivered to you@example.com. (optional) + LocalpartCatchallSeparator: + + + # With DMARC, a domain publishes, in DNS, a policy on how other mail servers + # should handle incoming messages with the From-header matching this domain and/or + # subdomain (depending on the configured alignment). Receiving mail servers use + # this to build up a reputation of this domain, which can help with mail delivery. + # A domain can also publish an email address to which reports about DMARC + # verification results can be sent by verifying mail servers, useful for + # monitoring. Incoming DMARC reports are automatically parsed, validated, added to + # metrics and stored in the reporting database for later display in the admin web + # pages. (optional) + DMARC: + + # Address-part before the @ that accepts DMARC reports. Must be + # non-internationalized. Recommended value: dmarc-reports. + Localpart: dmarc-reports + + # Account to deliver to. + Account: admin + + # Mailbox to deliver to, e.g. DMARC. + Mailbox: DMARC + + # With MTA-STS a domain publishes, in DNS, presence of a policy for + # using/requiring TLS for SMTP connections. The policy is served over HTTPS. + # (optional) + MTASTS: + + # Policies are versioned. The version must be specified in the DNS record. If you + # change a policy, first change it in mox, then update the DNS record. + PolicyID: 20230623T151905 + + # testing, enforce or none. If set to enforce, a remote SMTP server will not + # deliver email to us if it cannot make a TLS connection. + Mode: enforce + + # How long a remote mail server is allowed to cache a policy. Typically 1 or + # several weeks. + MaxAge: 24h0m0s + + # List of server names allowed for SMTP. If empty, the configured hostname is set. + # Host names can contain a wildcard (*) as a leading label (matching a single + # label, e.g. *.example matches host.example, not sub.host.example). (optional) + MX: + - #MACHINE_HOSTNAME# + + # With TLSRPT a domain specifies in DNS where reports about encountered SMTP TLS + # behaviour should be sent. Useful for monitoring. Incoming TLS reports are + # automatically parsed, validated, added to metrics and stored in the reporting + # database for later display in the admin web pages. (optional) + TLSRPT: + + # Address-part before the @ that accepts TLSRPT reports. Recommended value: + # tls-reports. + Localpart: tls-reports + + # Account to deliver to. + Account: admin + + # Mailbox to deliver to, e.g. TLSRPT. + Mailbox: TLSRPT + +# Accounts to which email can be delivered. An account can accept email for +# multiple domains, for multiple localparts, and deliver to multiple mailboxes. +Accounts: + admin: + + # Default domain for account. Deprecated behaviour: If a destination is not a full + # address but only a localpart, this domain is added to form a full address. + Domain: #MAIL_DOMAIN# + + # Destinations, keys are email addresses (with IDNA domains). If the address is of + # the form '@domain', i.e. with localpart missing, it serves as a catchall for the + # domain, matching all messages that are not explicitly configured. Deprecated + # behaviour: If the address is not a full address but a localpart, it is combined + # with Domain to form a full address. + Destinations: + admin@#MAIL_DOMAIN#: nil + + # If configured, messages classified as weakly spam are rejected with instructions + # to retry delivery, but this time with a signed token added to the subject. + # During the next delivery attempt, the signed token will bypass the spam filter. + # Messages with a clear spam signal, such as a known bad reputation, are + # rejected/delayed without a signed token. (optional) + SubjectPass: + + # How long unique values are accepted after generating, e.g. 12h. + Period: 12h0m0s + + # Mail that looks like spam will be rejected, but a copy can be stored temporarily + # in a mailbox, e.g. Rejects. If mail isn't coming in when you expect, you can + # look there. The mail still isn't accepted, so the remote mail server may retry + # (hopefully, if legitimate), or give up (hopefully, if indeed a spammer). + # Messages are automatically removed from this mailbox, so do not set it to a + # mailbox that has messages you want to keep. (optional) + RejectsMailbox: Rejects + + # Automatically set $Junk and $NotJunk flags based on mailbox messages are + # delivered/moved/copied to. Email clients typically have too limited + # functionality to conveniently set these flags, especially $NonJunk, but they can + # all move messages to a different mailbox, so this helps them. (optional) + AutomaticJunkFlags: + + # If enabled, flags will be set automatically if they match a regular expression + # below. When two of the three mailbox regular expressions are set, the remaining + # one will match all unmatched messages. Messages are matched in the order + # specified and the search stops on the first match. Mailboxes are lowercased + # before matching. + Enabled: true + + # Example: ^(junk|spam). (optional) + JunkMailboxRegexp: ^(junk|spam) + + # Example: ^(inbox|neutral|postmaster|dmarc|tlsrpt|rejects), and you may wish to + # add trash depending on how you use it, or leave this empty. (optional) + NeutralMailboxRegexp: ^(inbox|neutral|postmaster|dmarc|tlsrpt|rejects) + + # Content-based filtering, using the junk-status of individual messages to rank + # words in such messages as spam or ham. It is recommended you always set the + # applicable (non)-junk status on messages, and that you do not empty your Trash + # because those messages contain valuable ham/spam training information. + # (optional) + JunkFilter: + + # Approximate spaminess score between 0 and 1 above which emails are rejected as + # spam. Each delivery attempt adds a little noise to make it slightly harder for + # spammers to identify words that strongly indicate non-spaminess and use it to + # bypass the filter. E.g. 0.95. + Threshold: 0.950000 + Params: + + # Track ham/spam ranking for single words. (optional) + Onegrams: true + + # Maximum power a word (combination) can have. If spaminess is 0.99, and max power + # is 0.1, spaminess of the word will be set to 0.9. Similar for ham words. + MaxPower: 0.010000 + + # Number of most spammy/hammy words to use for calculating probability. E.g. 10. + TopWords: 10 + + # Ignore words that are this much away from 0.5 haminess/spaminess. E.g. 0.1, + # causing word (combinations) of 0.4 to 0.6 to be ignored. (optional) + IgnoreWords: 0.100000 + + # Occurrences in word database until a word is considered rare and its influence + # in calculating probability reduced. E.g. 1 or 2. (optional) + RareWords: 2 diff --git a/templates/template17-mail-server/artifacts/mox.conf b/templates/template17-mail-server/artifacts/mox.conf new file mode 100644 index 0000000..0bbb4c6 --- /dev/null +++ b/templates/template17-mail-server/artifacts/mox.conf @@ -0,0 +1,144 @@ + +# Directory where all data is stored, e.g. queue, accounts and messages, ACME TLS +# certs/keys. If this is a relative path, it is relative to the directory of +# mox.conf. +DataDir: ../data + +# Default log level, one of: error, info, debug, trace, traceauth, tracedata. +# Trace logs SMTP and IMAP protocol transcripts, with traceauth also messages with +# passwords, and tracedata on top of that also the full data exchanges (full +# messages), which can be a large amount of data. +LogLevel: debug + +# User to switch to after binding to all sockets as root. Default: mox. If the +# value is not a known user, it is parsed as integer and used as uid and gid. +# (optional) +User: mox + +# Full hostname of system, e.g. mail. +Hostname: #MACHINE_HOSTNAME# + +# If enabled, a single DNS TXT lookup of _updates.xmox.nl is done every 24h to +# check for a new release. Each time a new release is found, a changelog is +# fetched from https://updates.xmox.nl and delivered to the postmaster mailbox. +# (optional) +# +# RECOMMENDED: please enable to stay up to date +# +#CheckUpdates: true + +# File containing hash of admin password, for authentication in the web admin +# pages (if enabled). (optional) +AdminPasswordFile: adminpasswd + +# Listeners are groups of IP addresses and services enabled on those IP addresses, +# such as SMTP/IMAP or internal endpoints for administration or Prometheus +# metrics. All listeners with SMTP/IMAP services enabled will serve all configured +# domains. If the listener is named 'public', it will get a few helpful additional +# configuration checks, for acme automatic tls certificates and monitoring of ips +# in dnsbls if those are configured. +Listeners: + internal: + + # Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses, but + # it is better to explicitly specify the IPs you want to use for email, as mox + # will make sure outgoing connections will only be made from one of those IPs. + IPs: + - #ip_address_0# + + # If empty, the config global Hostname is used. (optional) + Hostname: localhost + + # Account web interface, for email users wanting to change their accounts, e.g. + # set new password, set new delivery rulesets. Served at /. (optional) + AccountHTTPS: + Enabled: true + Port: 444 + + # Admin web interface, for managing domains, accounts, etc. Served at /admin/. + # Preferably only enable on non-public IPs. Hint: use 'ssh -L 8080:localhost:80 + # you@yourmachine' and open http://localhost:8080/admin/, or set up a tunnel (e.g. + # WireGuard) and add its IP to the mox 'internal' listener. (optional) + AdminHTTPS: + Enabled: true + Port: 444 + + TLS: + KeyCerts: + - + CertFile: /etc/ssl/certs/#MACHINE_HOSTNAME#.pem + KeyFile: /etc/ssl/private/#MACHINE_HOSTNAME#-key.pem + + # Serve prometheus metrics, for monitoring. You should not enable this on a public + # IP. (optional) + MetricsHTTP: + Enabled: false + public: + + # Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses, but + # it is better to explicitly specify the IPs you want to use for email, as mox + # will make sure outgoing connections will only be made from one of those IPs. + IPs: + - #ip_address_0# + + # For SMTP/IMAP STARTTLS, direct TLS and HTTPS connections. (optional) + TLS: + KeyCerts: + - + CertFile: /etc/ssl/certs/#MACHINE_HOSTNAME#.pem + KeyFile: /etc/ssl/private/#MACHINE_HOSTNAME#-key.pem + + # (optional) + SMTP: + Enabled: true + + # Addresses of DNS block lists for incoming messages. Block lists are only + # consulted for connections/messages without enough reputation to make an + # accept/reject decision. This prevents sending IPs of all communications to the + # block list provider. If any of the listed DNSBLs contains a requested IP + # address, the message is rejected as spam. The DNSBLs are checked for healthiness + # before use, at most once per 4 hours. Example DNSBLs: sbl.spamhaus.org, + # bl.spamcop.net (optional) + #DNSBLs: + #- sbl.spamhaus.org + #- bl.spamcop.net + + # SMTP over TLS for submitting email, by email applications. Requires a TLS + # config. (optional) + Submissions: + Enabled: true + + # IMAP over TLS for reading email, by email applications. Requires a TLS config. + # (optional) + IMAPS: + Enabled: true + + # Serve autoconfiguration/autodiscovery to simplify configuring email + # applications, will use port 443. Requires a TLS config. (optional) + AutoconfigHTTPS: + Enabled: true + + # Serve MTA-STS policies describing SMTP TLS requirements. Requires a TLS config. + # (optional) + MTASTSHTTPS: + Enabled: true + + # All configured WebHandlers will serve on an enabled listener. (optional) + WebserverHTTP: + Enabled: false + + # All configured WebHandlers will serve on an enabled listener. Either ACME must + # be configured, or for each WebHandler domain a TLS certificate must be + # configured. (optional) + WebserverHTTPS: + Enabled: true + +# Destination for emails delivered to postmaster addresses: a plain 'postmaster' +# without domain, 'postmaster@' (also for each listener with SMTP +# enabled), and as fallback for each domain without explicitly configured +# postmaster destination. +Postmaster: + Account: admin + + # E.g. Postmaster or Inbox. + Mailbox: Postmaster diff --git a/templates/template17-mail-server/artifacts/mox.service b/templates/template17-mail-server/artifacts/mox.service new file mode 100644 index 0000000..1d870a2 --- /dev/null +++ b/templates/template17-mail-server/artifacts/mox.service @@ -0,0 +1,52 @@ +[Unit] +Description=mox mail server +After=network-online.target +Wants=network-online.target + +[Service] +UMask=007 +LimitNOFILE=65535 +Type=simple +# Mox starts as root, but drops privileges after binding network addresses. +WorkingDirectory=/home/mox +ExecStart=/home/mox/mox serve +RestartSec=5s +Restart=always +ExecStop=/home/mox/mox stop + +# Isolate process, reducing attack surface. +PrivateDevices=yes +PrivateTmp=yes +ProtectSystem=strict +ReadWritePaths=/home/mox/config /home/mox/data +ProtectKernelTunables=yes +ProtectControlGroups=yes +AmbientCapabilities= +CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_NET_BIND_SERVICE CAP_CHOWN CAP_FSETID CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER +NoNewPrivileges=yes +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK +ProtectProc=invisible +RestrictNamespaces=yes +RestrictRealtime=yes +RemoveIPC=yes +ProtectHostname=yes +ProtectClock=yes +ProtectKernelLogs=yes +ProtectKernelModules=yes +MemoryDenyWriteExecute=yes +LockPersonality=yes +DevicePolicy=closed +SystemCallArchitectures=native +SystemCallFilter=@system-service + +# Cannot have RestrictSUIDSGID with setgid directories. +#RestrictSUIDSGID=yes + +# prevents CAP_NET_BIND_SERVICE from working? +#PrivateUsers=yes + +# To check security-related settings: +# sudo systemd-analyze security mox.service + +[Install] +WantedBy=multi-user.target diff --git a/templates/template17-mail-server/provision.sh b/templates/template17-mail-server/provision.sh new file mode 100644 index 0000000..1958c5b --- /dev/null +++ b/templates/template17-mail-server/provision.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +timedatectl set-timezone Europe/Madrid + +start_time=`date` + +echo "provisioning started: ${start_time}" + +hostnamectl set-hostname ${MACHINE_HOSTNAME} + +# Print some information about the container OS +hostnamectl + +# Print some information about the container timezone +timedatectl + +ADMIN_PASSWORD=admin123 + +##################################################################### +## Get the IP address into an environment variable. +##################################################################### +ip_address_list=`hostname -I` + +ip_address_list=($ip_address_list) + +ip_address_0=${ip_address_list[0]} + +echo "ip_address_0=${ip_address_0}" + +apt update + +apt install -y mkcert + +export CAROOT=/vagrant/artifacts/ + +mkcert -install + +mkcert --cert-file /etc/ssl/certs/${MACHINE_HOSTNAME}.pem --key-file /etc/ssl/private/${MACHINE_HOSTNAME}-key.pem "${MACHINE_HOSTNAME}" + +useradd -m -d /home/mox mox + +mkdir /home/mox/config + +cp /vagrant/artifacts/mox.conf /home/mox/config + +sed -i "s|#MACHINE_HOSTNAME#|${MACHINE_HOSTNAME}|g" /home/mox/config/mox.conf + +sed -i "s|#ip_address_0#|${ip_address_0}|g" /home/mox/config/mox.conf + +cp /vagrant/artifacts/domains.conf /home/mox/config + +sed -i "s|#MACHINE_HOSTNAME#|${MACHINE_HOSTNAME}|g" /home/mox/config/domains.conf + +sed -i "s|#MAIL_DOMAIN#|${MAIL_DOMAIN}|g" /home/mox/config/domains.conf + + +mkdir /home/mox/data + +cp /vagrant/artifacts/mox /home/mox/ + +cd /home/mox/ + +echo ${ADMIN_PASSWORD} | /home/mox/mox setadminpassword + +chown -R mox.mox /home/mox + +systemctl enable /vagrant/artifacts/mox.service + +systemctl start mox.service + +end_time=`date` + +echo "This container has the following IP address: ${ip_address_0}" + +echo "The web admin panel can be accessed with user admin@${MAIL_DOMAIN} and password ${ADMIN_PASSWORD}" + +echo "at the following link: https://${MACHINE_HOSTNAME}:444/admin/" + +echo "provisioning started: ${start_time}" + +echo "provisioning ended: ${end_time}"