+14
-8
README.md
+14
-8
README.md
···-Eilean enables you to host your own digital 'island', where you control your own online infrastructure.-Eilean uses [NixOS](https://nixos.org/) to enable reproducible deployments of services such as webservers, mailservers, federated communication servers, Virtual Private Network servers, and more.-However, they still require a lot of manual configuration for domain names, DNS records, user accounts, databases, HTTP proxies, TLS certificates, and more.+Eilean enables you to host your own digital island where you control your own online infrastructure.+Through the use of open standards and federated protocols Eilean allows you to interoperate with other providers.+[NixOS](https://nixos.org/) is used to enable reproducible deployments of services such as webservers, mailservers, federated communication servers, Virtual Private Network servers, and more.+However, such services still require a lot of manual configuration for domain names, DNS records, user accounts, databases, HTTP proxies, TLS certificates, and more.Eilean aims to be a optioned framework to allow the simple deployment of these services on a single machine, and a library of documentation for common issues in managing runtime state like secrets, databases, and upgrades.-By using Nix, Eilean modules are extensive to other configurations outside this deployment scenario, such as offloading a particularly resource heavy service to a dedicated machine.+By using Nix, Eilean modules are extensible to other configurations outside this deployment scenario, such as offloading a particularly resource heavy service to a dedicated machine.
+7
-6
docs/getting_started.md
+7
-6
docs/getting_started.md
···Note you'll need a static IPv4[^1] address for reliable hosting[^2]. If you're behind Network Address Translation (NAT) you'll need to set up port forwarding for every service you want to run.The resource requirements depend on the number of services you want to run, and the load they'll be under.-With no services 10GiB of disk space and 1GiB of RAM is plenty, though you may want to enable swap if you have low memory.-With all services enabled and fairly populated databases 40GiB of disk space and 2GiB of RAM is appropriate.+With no services 10ย GiB of disk space and 1ย GiB of RAM is plenty, though you may want to enable swap if you have low memory.+With all services enabled and fairly populated databases 40ย GiB of disk space and 2ย GiB of RAM is appropriate.[^1]: You could just use an IPv6 address, but much of the Internet is still [IPv4-only](https://stats.labs.apnic.net/ipv6).[^2]: If you don't have a static address, Dynamic DNS is possible but takes some time to propagate. Email reputation is tied to your IP address; using a residential address assigned by your ISP may get your mail blocked.-Resource requirements depends how many service you want to run and how much load they'll be under, but 2 GB RAM and 20 GB disk should be a good starting point.+Resource requirements depend on how many services you want to run and how much load they'll be under, but 2 GiB RAM and 20 GiB disk should be a good starting point.···-By default DHCP will be enabled so your machine will discovery it's IP address, however some providers don't enable DHCPv6 or SLAAC so you need to manually configure the IP address.+By default, DHCP will be enabled, so your machine will discover its IP address, however some providers don't enable DHCPv6 or SLAAC, so you need to manually configure the IP address.···-Once your domain is setup, replace these default values of Eilean with your IPv4 and IPv6 network addresses, and your public network interface:+Once your domain is set up, replace these default values of Eilean with your IPv4 and IPv6 network addresses, and your public network interface:···
docs/gitea.md
docs/gitea.md
This is a binary file and will not be displayed.
docs/vpn.md
docs/vpn.md
This is a binary file and will not be displayed.
eilean-donan.jpg
eilean-donan.jpg
This is a binary file and will not be displayed.
+282
-4
flake.lock
+282
-4
flake.lock
···
+32
-3
flake.nix
+32
-3
flake.nix
···
+35
man/default.nix
+35
man/default.nix
···
+17
man/eilean-configuration-nix-header.5
+17
man/eilean-configuration-nix-header.5
···
+16
modules/acme-eon.nix
+16
modules/acme-eon.nix
···
+21
-20
modules/default.nix
+21
-20
modules/default.nix
···
+22
-33
modules/dns.nix
+22
-33
modules/dns.nix
···
+42
modules/fail2ban.nix
+42
modules/fail2ban.nix
···
+55
-42
modules/gitea.nix
+55
-42
modules/gitea.nix
···-proxyPass = "http://localhost:${builtins.toString config.services.gitea.settings.server.HTTP_PORT}/";············-iptables -A PREROUTING -t nat -i ${config.eilean.publicInterface} -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort}-ip6tables -A PREROUTING -t nat -i ${config.eilean.publicInterface} -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort}+iptables -A PREROUTING -t nat -i ${config.eilean.publicInterface} -p tcp --dport 22 -j REDIRECT --to-port ${+ip6tables -A PREROUTING -t nat -i ${config.eilean.publicInterface} -p tcp --dport 22 -j REDIRECT --to-port ${-iptables -A OUTPUT -d ${config.eilean.serverIpv4} -t nat -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort}-ip6tables -A OUTPUT -d ${config.eilean.serverIpv6} -t nat -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort}+iptables -A OUTPUT -d ${config.eilean.serverIpv4} -t nat -p tcp --dport 22 -j REDIRECT --to-port ${+ip6tables -A OUTPUT -d ${config.eilean.serverIpv6} -t nat -p tcp --dport 22 -j REDIRECT --to-port ${
+22
-25
modules/headscale.nix
+22
-25
modules/headscale.nix
······
-78
modules/mailserver/borgbackup.nix
-78
modules/mailserver/borgbackup.nix
···-compressionFragment = lib.concatStringsSep "," (lib.flatten [autoFragment methodFragment levelFragment]);-compression = lib.optionalString (compressionFragment != "") "--compression ${compressionFragment}";-(if cfg.encryption.passphraseFile != null then ''env BORG_PASSPHRASE="$(cat ${passphraseFile})"''-${passphraseFragment} ${pkgs.borgbackup}/bin/borg init ${extraInitArgs} --encryption ${encryptionFragment} || true-${passphraseFragment} ${pkgs.borgbackup}/bin/borg create ${extraCreateArgs} ${compression} ::${name} ${locations}
-30
modules/mailserver/clamav.nix
-30
modules/mailserver/clamav.nix
···
-48
modules/mailserver/common.nix
-48
modules/mailserver/common.nix
···-mkHashFile = name: hash: pkgs.writeText "${builtins.hashString "sha256" name}-password-hash" hash;
-4
modules/mailserver/debug.nix
-4
modules/mailserver/debug.nix
-1043
modules/mailserver/default.nix
-1043
modules/mailserver/default.nix
···-description = "Secondary domains and subdomains for which it is necessary to generate a certificate.";-example = "$6$evQJs5CFQyPAW09S$Cn99Y8.QjZ2IBnSu4qf1vBxDRWkaIZWOtmu1Ddsm3.H3CFpeVc0JU4llIq8HQXgeatvYhh5O33eWG3TSpjzu6/";-hashedPassword = "$6$evQJs5CFQyPAW09S$Cn99Y8.QjZ2IBnSu4qf1vBxDRWkaIZWOtmu1Ddsm3.H3CFpeVc0JU4llIq8HQXgeatvYhh5O33eWG3TSpjzu6/";-hashedPassword = "$6$oE0ZNv2n7Vk9gOf$9xcZWCCLGdMflIfuA0vR1Q1Xblw6RZqPrP94mEit2/81/7AKj2bqUai5yPyWE.QYPyv6wLMHZvjw3Rlg7yTCD/";-enable = lib.mkEnableOption "Full text search indexing with xapian. This has significant performance and disk space cost.";-description = "Memory limit for the indexer process, in MiB. If null, leaves the default (which is rather low), and if 0, no limit.";-description = "When to run the maintenance job. See systemd.time(7) for more information about the format.";-description = "Run the maintenance job not exactly at the time specified with <literal>onCalendar</literal>, but plus or minus this many seconds.";-For instance when using "." then in a sieve script "example.com" would refer to the mailbox "com" in the parent mailbox "example".-Runs a local DNS resolver (kresd) as recommended when running rspamd. This prevents your log file from filling up with rspamd_monitored_dns_mon entries.-defaultText = lib.literalDocBook "computed from <option>config.services.redis.servers.rspamd.bind</option>";-if failed host ${cfg.fqdn} port 993 type tcpssl sslauto protocol imap for 5 cycles then restart-description = "When or how often the backup should run. Must be in the format described in systemd.time 7.";-description = "Leaves it to borg to determine whether an individual file should be compressed.";-This is called prior to borg init in the same script that runs borg init and create and cmdPostexec.-It is recommended to use the default value because the quicker kexec reboot has a number of problems.-Also if your server is running in a virtual machine the regular reboot will already be very quick.-The command to be executed before each backup operation. This is wrapped in a shell script to be called by rsnapshot.-description = "The command to be executed after each backup operation. This is wrapped in a shell script to be called by rsnapshot.";
-15
modules/mailserver/dovecot/imap_sieve/report-ham.sieve
-15
modules/mailserver/dovecot/imap_sieve/report-ham.sieve
···
-7
modules/mailserver/dovecot/imap_sieve/report-spam.sieve
-7
modules/mailserver/dovecot/imap_sieve/report-spam.sieve
-3
modules/mailserver/dovecot/pipe_bin/sa-learn-ham.sh
-3
modules/mailserver/dovecot/pipe_bin/sa-learn-ham.sh
-3
modules/mailserver/dovecot/pipe_bin/sa-learn-spam.sh
-3
modules/mailserver/dovecot/pipe_bin/sa-learn-spam.sh
-324
modules/mailserver/dovecot.nix
-324
modules/mailserver/dovecot.nix
···-for f in ${builtins.toString (lib.mapAttrsToList (name: value: passwordFiles."${name}") cfg.loginAccounts)}; do-"${name}:${"$(head -n 1 ${passwordFiles."${name}"})"}:${builtins.toString cfg.vmailUID}:${builtins.toString cfg.vmailUID}::${cfg.mailDirectory}:/run/current-system/sw/bin/nologin:"-junkMailboxes = builtins.attrNames (lib.filterAttrs (n: v: v ? "specialUse" && v.specialUse == "Junk") cfg.mailboxes);-message = "nixos-mailserver requires exactly one dovecot mailbox with the 'special use' flag set to 'Junk' (${builtins.toString junkMailboxNumber} have been found)";-modules = [ pkgs.dovecot_pigeonhole ] ++ (lib.optional cfg.fullTextSearch.enable pkgs.dovecot_fts_xapian );-fts_xapian = partial=${toString cfg.fullTextSearch.minSize} full=${toString cfg.fullTextSearch.maxSize} attachments=${bool2int cfg.fullTextSearch.indexAttachments} verbose=${bool2int cfg.debug}-${lib.strings.concatImapStringsSep "\n" (n: x: "fts_autoindex_exclude${if n==1 then "" else toString n} = ${x}") cfg.fullTextSearch.autoIndexExclude}-systemd.services.dovecot-fts-xapian-optimize = lib.mkIf (cfg.fullTextSearch.enable && cfg.fullTextSearch.maintenance.enable) {-systemd.timers.dovecot-fts-xapian-optimize = lib.mkIf (cfg.fullTextSearch.enable && cfg.fullTextSearch.maintenance.enable && cfg.fullTextSearch.maintenance.randomizedDelaySec != 0) {
-28
modules/mailserver/environment.nix
-28
modules/mailserver/environment.nix
···
-27
modules/mailserver/kresd.nix
-27
modules/mailserver/kresd.nix
···
-32
modules/mailserver/monit.nix
-32
modules/mailserver/monit.nix
···
-37
modules/mailserver/networking.nix
-37
modules/mailserver/networking.nix
···
-44
modules/mailserver/nginx.nix
-44
modules/mailserver/nginx.nix
···
-88
modules/mailserver/opendkim.nix
-88
modules/mailserver/opendkim.nix
···-(dom: "${dom} ${dom}:${cfg.dkimSelector}:${cfg.dkimKeyDirectory}/${dom}.${cfg.dkimSelector}.key")));
-46
modules/mailserver/post-upgrade-check.nix
-46
modules/mailserver/post-upgrade-check.nix
···-systemd.services.nixos-upgrade.serviceConfig.ExecStartPost = pkgs.writeScript "post-upgrade-check" ''-# This is just an educated guess. If the links do not differ the kernels might still be different, according to spacefrogg in #nixos.-echo "kernel version seems unchanged, skipping reboot" | systemd-cat --priority 4 --identifier "post-upgrade-check";-echo "kernel path changed, possibly a new version" | systemd-cat --priority 2 --identifier "post-upgrade-check"
-269
modules/mailserver/postfix.nix
-269
modules/mailserver/postfix.nix
···-in lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${valueToString value}") attrs);-denied_recipients_file = builtins.toFile "denied_recipients" (lib.concatStringsSep "\n" denied_recipients_postfix);-reject_senders_file = builtins.toFile "reject_senders" (lib.concatStringsSep "\n" (reject_senders_postfix)) ;-reject_recipients_file = builtins.toFile "reject_recipients" (lib.concatStringsSep "\n" (reject_recipients_postfix)) ;-smtpd_recipient_restrictions = "reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject";-virtual = lookupTableToString (mergeLookupTables [all_valiases_postfix catchAllPostfix forwards]);-milter_mail_macros = "i {mail_addr} {client_addr} {client_name} {auth_type} {auth_authen} {auth_author} {mail_addr} {mail_host} {mail_mailer}";
-59
modules/mailserver/rsnapshot.nix
-59
modules/mailserver/rsnapshot.nix
···
-119
modules/mailserver/rspamd.nix
-119
modules/mailserver/rspamd.nix
···-scan_mime_parts = false; # scan mail as a whole unit, not parts. seems to be needed to work at all-requires = [ "redis-rspamd.service" ] ++ (lib.optional cfg.virusScanning "clamav-daemon.service");-after = [ "redis-rspamd.service" ] ++ (lib.optional cfg.virusScanning "clamav-daemon.service");
-83
modules/mailserver/systemd.nix
-83
modules/mailserver/systemd.nix
···
-101
modules/mailserver/users.nix
-101
modules/mailserver/users.nix
···
+56
-34
modules/mailserver.nix
+56
-34
modules/mailserver.nix
······-data = "\"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6YmYYvoFF7VqtGcozpVQa78aaGgZdvc5ZIHqzmkKdCBEyDF2FRbCEK4s2AlC8hhc8O4mSSe3S4AzEhlRgHXbU22GBaUZ3s2WHS8JJwZvWeTjsbXQwjN/U7xpkqXPHLH9IVfOJbHlp4HQmCAXw4NaypgkkxIGK0jaZHm2j6/1izQIDAQAB\"";
+35
-31
modules/mastodon.nix
+35
-31
modules/mastodon.nix
······
+188
modules/matrix/mautrix-instagram.nix
+188
modules/matrix/mautrix-instagram.nix
···
+188
modules/matrix/mautrix-messenger.nix
+188
modules/matrix/mautrix-messenger.nix
···
+249
modules/matrix/synapse.nix
+249
modules/matrix/synapse.nix
···+# set other headers due to https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md+add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; frame-src 'self'; frame-ancestors 'self'; form-action 'self';" always;+echo "turn_shared_secret: $(cat '${config.services.coturn.static-auth-secret-file}')" > '${turnSharedSecretFile}'+chown ${config.systemd.services.matrix-synapse.serviceConfig.User}:${config.systemd.services.matrix-synapse.serviceConfig.Group} '${turnSharedSecretFile}'
-134
modules/matrix.nix
-134
modules/matrix.nix
···
+81
modules/radicale.nix
+81
modules/radicale.nix
···
+35
-13
modules/services/dns/bind.nix
+35
-13
modules/services/dns/bind.nix
···
+17
-29
modules/services/dns/default.nix
+17
-29
modules/services/dns/default.nix
·········
+42
modules/services/dns/eon.nix
+42
modules/services/dns/eon.nix
···+${config.services.eon.package}/bin/capc update /var/lib/eon/caps/domain/''${domain}.cap -u "add|''${record_name}.''${domain}|''${record_type}|''${record_value}|''${ttl}" || exit 0
+4
-12
modules/services/dns/zonefile.nix
+4
-12
modules/services/dns/zonefile.nix
······-(builtins.map (rr: "${rr.name} IN ${builtins.toString rr.ttl} ${rr.type} ${rr.data}") zone.records)
+62
-30
modules/turn.nix
+62
-30
modules/turn.nix
···+chown -R ${config.systemd.services.coturn.serviceConfig.User}:${config.systemd.services.coturn.serviceConfig.Group} "$DIR"···
+82
-53
modules/wireguard/default.nix
+82
-53
modules/wireguard/default.nix
······
-39
modules/wireguard/server.nix
-39
modules/wireguard/server.nix
···
+31
pkgs/mautrix-meta.nix
+31
pkgs/mautrix-meta.nix
···
+4
-7
template/configuration.nix
+4
-7
template/configuration.nix
············
+24
-10
template/flake.lock
+24
-10
template/flake.lock
·········
+19
-20
template/flake.nix
+19
-20
template/flake.nix
···