**Purpose**: Self-Hosted Open-Source email server that can be setup in minutes, and is enterprise-grade if upgraded with an iRedAdmin-Pro license. !!! note "Assumptions" It is assumed you are running at least Rocky Linux 9.3. While you can use CentOS Stream, Alma, Debian, Ubuntu, FreeBSD, and OpenBSD, the more enterprise-level sections of my homelab are built on Rocky Linux. ## Overview The instructions below are specific to my homelab environment, but can be easily ported depending on your needs. This guide also assumes you want to operate a PostgreSQL-based iRedMail installation. You can follow along with the official documentation on [Installation](https://docs.iredmail.org/install.iredmail.on.rhel.html) as well as [DNS Record Configuration](https://docs.iredmail.org/setup.dns.html) if you want more detailed explanations throughout the installation process. ## Configure FQDN Ensure the FQDN of the server is correctly set. You can find the hostname configured in two locations: `/etc/hostname` and `/etc/hosts`. ## Disable SELinux iRedMail doesn't work with SELinux, so please disable it by setting below value in its config file /etc/selinux/config. After server reboot, SELinux will be completely disabled. ``` sh # Elevate to Root User sudo su # Disable SELinux sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # (1) setenforce 0 ``` 1. If you prefer to let SELinux prints warnings instead of enforcing, you can set this value instead: `SELINUX=permissive` ## Set Domain and iRedMail Version Start by connecting to the server / VM via SSH, then set silent deployment variables below. ``` sh # Define some deployment variables. VERSION="1.6.8" # (1) MAIL_DOMAIN="bunny-lab.io" # (2) ``` 1. This is the version of iRedMail you are deploying. You can find the newest version on the [iRedMail Download Page](https://www.iredmail.org/download.html). 2. This is the domain suffix that appears after mailbox names. e.g. `first.last@bunny-lab.io` would use a domain value of `bunny-lab.io`. You will then proceed to bootstrap a silent unattended installation of iRedMail. (I've automated as much as I can to make this as turn-key as possible). Just copy/paste this whole thing into your terminal and hit ENTER. !!! danger "Storage Space Requirements" You absolutely need to ensure that `/var/vmail` has a lot of space. At least 16GB. This is where all of your emails / mailboxes / a lot of settings will be. If possible, create a second physical/virtual disk specifically for the `/var` partition, or specifically for `/var/vmail` at minimum, so you can expand it over time if necessary. LVM-based provisioning is recommended but not required. ``` sh # Check for Updates in the Package Manager yum update -y # Install Extra Packages for Enterprise Linux dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm # Download the iRedMail binaries and extract them cd /root curl https://codeload.github.com/iredmail/iRedMail/tar.gz/refs/tags/$VERSION -o iRedMail-$VERSION.tar.gz tar zxf iRedMail-$VERSION.tar.gz # Create the unattend config file for silent deployment. This will automatically generate random 32-character passwords for all of the databases. (echo "export STORAGE_BASE_DIR='/var/vmail'"; echo "export WEB_SERVER='NGINX'"; echo "export BACKEND_ORIG='PGSQL'"; echo "export BACKEND='PGSQL'"; for var in VMAIL_DB_BIND_PASSWD VMAIL_DB_ADMIN_PASSWD MLMMJADMIN_API_AUTH_TOKEN NETDATA_DB_PASSWD AMAVISD_DB_PASSWD IREDADMIN_DB_PASSWD RCM_DB_PASSWD SOGO_DB_PASSWD SOGO_SIEVE_MASTER_PASSWD IREDAPD_DB_PASSWD FAIL2BAN_DB_PASSWD PGSQL_ROOT_PASSWD DOMAIN_ADMIN_PASSWD_PLAIN; do echo "export $var='$(openssl rand -base64 48 | tr -d '+/=' | head -c 32)'"; done; echo "export FIRST_DOMAIN='$MAIL_DOMAIN'"; echo "export USE_IREDADMIN='YES'"; echo "export USE_SOGO='YES'"; echo "export USE_NETDATA='YES'"; echo "export USE_FAIL2BAN='YES'") > /root/iRedMail-$VERSION/config # Set Environment Variables for Silent Deployment AUTO_USE_EXISTING_CONFIG_FILE=y # (1) AUTO_INSTALL_WITHOUT_CONFIRM=y # (2) AUTO_CLEANUP_REMOVE_SENDMAIL=y # (3) AUTO_CLEANUP_REPLACE_FIREWALL_RULES=y # (4) AUTO_CLEANUP_RESTART_FIREWALL=n # (5) AUTO_CLEANUP_REPLACE_MYSQL_CONFIG=y # (6) # Deploy iRedMail via the Install Script cd /root/iRedMail-1.6.8 bash iRedMail.sh ``` 1. Use existing `config` file without asking for confirmation. 2. Start the installation without asking for confirmation. 3. Remove `sendmail` package without asking for confirmation. 4. Copy and use the firewall rules shipped in iRedMail installer. 5. Restart firewall service without asking for confirmation. 6. Copy and use the MySQL (server) config file shipped in iRedMail installer. When the installation is completed, take note of any output it gives you for future reference. Then reboot the server to finalize the server installation. ``` reboot ``` !!! warning "Automatically-Generated Postmaster Password" When you deploy iRedMail, it will give you a username and password for the postmaster account. If you accidentally forget to document this, you can log back into the server via SSH and see the credentials at `/root/iRedMail-$VERSION/iRedMail.tips`. This file is critical and contains passwords and DNS information such as DKIM record information as well. ## Nested Reverse Proxy Configuration In my homelab environment, I run Traefik reverse proxy in front of everything, which includes the NGINX reverse proxy that iRedMail creates. In my scenario, I have to make some custom adjustments to the reverse proxy dynamic configuration data to ensure it will allow self-signed certificates from iRedMail to communicate with the Traefik reverse proxy successfully. You will see an example Traefik configuration file below. ``` sh # ROUTER http: routers: mail: entryPoints: - websecure rule: "Host(`mail.bunny-lab.io`)" service: mail middlewares: - add-real-ip-header - add-host-header tls: certResolver: myresolver # MIDDLEWARE (May not actually be necessary) middlewares: add-real-ip-header: headers: customRequestHeaders: X-Real-IP: "" add-host-header: headers: customRequestHeaders: Host: "mail.bunny-lab.io" # SERVICE mail: loadBalancer: serversTransport: insecureTransport servers: - url: "https://192.168.3.13:443" passHostHeader: true # TRANSPORT serversTransports: insecureTransport: insecureSkipVerify: true ```