Some checks failed
CI / check (push) Has been cancelled
CI / ida (push) Has been cancelled
CI / cpt (push) Has been cancelled
CI / build-nixos (ena) (push) Has been cancelled
CI / build-nixos (hako) (push) Has been cancelled
CI / build-nixos (kazusa) (push) Has been cancelled
CI / build-nixos (mizuki) (push) Has been cancelled
201 lines
5.1 KiB
Nix
201 lines
5.1 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
...
|
|
}:
|
|
|
|
let
|
|
mailSecret = key: {
|
|
sopsFile = ../secrets/mailserver.yaml;
|
|
inherit key;
|
|
owner = "nginx";
|
|
group = "nginx";
|
|
mode = "0440";
|
|
restartUnits = [
|
|
"phpfpm-roundcube.service"
|
|
"dovecot.service"
|
|
];
|
|
};
|
|
|
|
clientIdSecret = config.sops.secrets."mailserver/oauth/client-id".path;
|
|
clientSecret = config.sops.secrets."mailserver/oauth/client-secret".path;
|
|
in
|
|
{
|
|
sops.secrets."mailserver/oauth/client-id" = mailSecret "mailserver/oauth/client-id";
|
|
|
|
sops.secrets."mailserver/oauth/client-secret" = mailSecret "mailserver/oauth/client-secret";
|
|
|
|
imports = [
|
|
(builtins.fetchTarball {
|
|
url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/51726d7b7fd94aa69829fd42749a803914cbf3b7/nixos-mailserver-51726d7b7fd94aa69829fd42749a803914cbf3b7.tar.gz";
|
|
sha256 = "0449ssnpwbgfv0cyddzb8s6g641gy5xh1hd3shg32x8pv0a5qy3a";
|
|
})
|
|
];
|
|
|
|
security.acme.acceptTerms = false;
|
|
|
|
services.roundcube = {
|
|
enable = true;
|
|
hostName = "mail.mizuki.guru";
|
|
|
|
package = pkgs.roundcube.withPlugins (
|
|
plugins: with plugins; [
|
|
persistent_login
|
|
]
|
|
);
|
|
|
|
plugins = [
|
|
"persistent_login"
|
|
"managesieve"
|
|
];
|
|
|
|
dicts = with pkgs.aspellDicts; [
|
|
en
|
|
];
|
|
|
|
maxAttachmentSize = config.mailserver.messageSizeLimit / 1024 / 1024;
|
|
|
|
extraConfig = ''
|
|
$_SERVER['HTTPS'] = 'on';
|
|
$_SERVER['SERVER_PORT'] = 443;
|
|
$_SERVER['HTTP_X_FORWARDED_PORT'] = 443;
|
|
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
|
|
$_SERVER['HTTP_HOST'] = 'mail.mizuki.guru';
|
|
|
|
$config['proxy_ips'] = '127.0.0.1';
|
|
|
|
$config['imap_host'] = "ssl://${config.mailserver.fqdn}";
|
|
$config['smtp_host'] = "ssl://${config.mailserver.fqdn}";
|
|
$config['smtp_user'] = "%u";
|
|
$config['smtp_pass'] = "%p";
|
|
|
|
$config['managesieve_host'] = "tls://${config.mailserver.fqdn}";
|
|
$config['managesieve_port'] = 4190;
|
|
$config['managesieve_usetls'] = true;
|
|
|
|
$config['oauth_provider'] = 'generic';
|
|
$config['oauth_provider_name'] = 'authentik';
|
|
|
|
$config['oauth_client_id'] =
|
|
trim(file_get_contents('${clientIdSecret}'));
|
|
|
|
$config['oauth_client_secret'] =
|
|
trim(file_get_contents('${clientSecret}'));
|
|
|
|
$config['oauth_auth_uri'] =
|
|
'https://auth.mizuki.guru/application/o/authorize/';
|
|
|
|
$config['oauth_token_uri'] =
|
|
'https://auth.mizuki.guru/application/o/token/';
|
|
|
|
$config['oauth_identity_uri'] =
|
|
'https://auth.mizuki.guru/application/o/userinfo/';
|
|
|
|
$config['oauth_scope'] =
|
|
"email openid dovecotprofile offline_access";
|
|
|
|
$config['oauth_auth_parameters'] = [];
|
|
$config['oauth_identity_fields'] = ['email'];
|
|
'';
|
|
};
|
|
|
|
services.nginx.virtualHosts.${config.services.roundcube.hostName} = {
|
|
forceSSL = false;
|
|
enableACME = false;
|
|
|
|
listen = [
|
|
{
|
|
addr = "127.0.0.1";
|
|
port = 5656;
|
|
}
|
|
];
|
|
|
|
extraConfig = ''
|
|
set_real_ip_from 127.0.0.1;
|
|
real_ip_header X-Forwarded-For;
|
|
real_ip_recursive on;
|
|
'';
|
|
};
|
|
|
|
services.caddy = {
|
|
enable = true;
|
|
|
|
virtualHosts."mail.mizuki.guru" = {
|
|
extraConfig = ''
|
|
reverse_proxy localhost:5656
|
|
'';
|
|
};
|
|
};
|
|
|
|
services.dovecot2.settings = {
|
|
auth_mechanisms = lib.mkForce [
|
|
"plain"
|
|
"login"
|
|
"xoauth2"
|
|
"oauthbearer"
|
|
];
|
|
|
|
oauth2_tokeninfo_url = "https://auth.mizuki.guru/application/o/userinfo/?access_token=";
|
|
|
|
# 주의:
|
|
# 여기는 아직 secret '값'이 아니라 secret '경로'가 들어감.
|
|
# Dovecot이 URL 안에서 file_get_contents 같은 처리를 안 하므로
|
|
# 이 방식은 제대로 동작하지 않을 가능성이 큼.
|
|
oauth2_introspection_url = "https://auth.mizuki.guru/application/o/introspect/";
|
|
|
|
oauth2_introspection_mode = "post";
|
|
oauth2_force_introspection = "yes";
|
|
oauth2_active_attribute = "active";
|
|
oauth2_active_value = "true";
|
|
oauth2_username_attribute = "email";
|
|
};
|
|
|
|
users.users.dovecot = {
|
|
isSystemUser = true;
|
|
group = "dovecot";
|
|
extraGroups = [ "caddy" ];
|
|
};
|
|
|
|
users.groups.dovecot = { };
|
|
|
|
users.users.postfix.extraGroups = [ "caddy" ];
|
|
|
|
mailserver = {
|
|
enable = true;
|
|
stateVersion = 4;
|
|
fqdn = "mail.mizuki.guru";
|
|
domains = [ "mizuki.guru" ];
|
|
|
|
x509 = {
|
|
certificateFile = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.mizuki.guru/mail.mizuki.guru.crt";
|
|
|
|
privateKeyFile = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.mizuki.guru/mail.mizuki.guru.key";
|
|
};
|
|
|
|
ldap = {
|
|
enable = true;
|
|
uris = [ "ldap://10.11.8.102" ];
|
|
|
|
bind = {
|
|
dn = "cn=mailserver,ou=users,dc=ldap,dc=goauthentik,dc=io";
|
|
passwordFile = "/var/lib/secrets/authentik-ldap-bind-pw";
|
|
};
|
|
|
|
base = "ou=users,dc=ldap,dc=goauthentik,dc=io";
|
|
scope = "sub";
|
|
|
|
attributes = {
|
|
uuid = "uid";
|
|
username = "mail";
|
|
mail = "mail";
|
|
};
|
|
|
|
dovecot = {
|
|
passFilter = "mail=%{user}\n bind = yes";
|
|
};
|
|
};
|
|
|
|
accounts = { };
|
|
};
|
|
}
|