stalwartlabs/website

Wish: Describe _manual install_

Opened this issue · 20 comments

Currently at https://stalw.art/docs/install/linux/

Please note that root access is required to perform the installation, if you don't feel comfortable running the install script as root you may also download the stalwart-install binary and perform a manual installation.

But how to perform the manual install of "stallwart"?

(I will use this issue to document my install journey.)

Picked possible best fit from https://github.com/stalwartlabs/mail-server/releases

stappers@hop:~
$ wget https://github.com/stalwartlabs/mail-server/releases/download/v0.4.2/stalwart-install-x86_64-unknown-linux-gnu.tar.gz
wget output
stappers@hop:~
$ tar tf stalwart-install-x86_64-unknown-linux-gnu.tar.gz 
stalwart-install
stappers@hop:~
$ tar xf stalwart-install-x86_64-unknown-linux-gnu.tar.gz 
stappers@hop:~
$ file stalwart-install
stalwart-install: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fb2af9b60f6f025668dc4f49fd3f0c3ab7a7344f, for GNU/Linux 3.2.0, with debug_info, not stripped
stappers@hop:~
$ 

What is in stallwart-install? Where to finds its source??

What is in stallwart-install? Where to finds its source??

Currently less important (to me).

Now building mail-server. It is what I thinking that I need for my use case, it is the binary I hoped to find in the .tar.gz.

Add after cargo build --release of mail-server:

stappers@messer:/usr/src/stallwart/mail-server
$ ls target/release/
build               libimap.rlib         libnlp.d       libutils.rlib
deps                libjmap.d            libnlp.rlib    stalwart-cli
examples            libjmap_proto.d      libsmtp.d      stalwart-cli.d
incremental         libjmap_proto.rlib   libsmtp.rlib   stalwart-install
libdirectory.d      libjmap.rlib         libstore.d     stalwart-install.d
libdirectory.rlib   libmanagesieve.d     libstore.rlib  stalwart-mail
libimap.d           libmanagesieve.rlib  libtests.d     stalwart-mail.d
libimap_proto.d     libmaybe_async.d     libtests.rlib
libimap_proto.rlib  libmaybe_async.so    libutils.d
stappers@messer:/usr/src/stallwart/mail-server
$ file target/release/stalwart-{cli,install,mail}
target/release/stalwart-cli:     ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=061d3b50f2eb5adee7b4c1f0cef554bebbd35db8, for GNU/Linux 3.2.0, with debug_info, not stripped
target/release/stalwart-install: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=226f532ac62ba4761a16e2a5407f7d1116a5de65, for GNU/Linux 3.2.0, with debug_info, not stripped
target/release/stalwart-mail:    ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3d713e2620467266c3cf41367c96fc87b068dcbc, for GNU/Linux 3.2.0, with debug_info, not stripped
stappers@messer:/usr/src/stallwart/mail-server
$ 

So I have found the source of stallwart-install and can now start exploring stallwart-mail ...

Ah,

stappers@hop:~
$ ./stalwart-mail 
Missing parameter --config=<path-to-config>.
stappers@hop:~
$ ./stalwart-mail --config=/dev/null
Invalid configuration: No server directives found in config file.
stappers@hop:~
$ 

So next step seems to be assembling a configuration file.

Intermediate report:

Manual install:

  • Have stallwart-mail executable
  • Have a configuration file
  • /path/to/stallwart-mail --config=/path/to/configuration_file

Ah, in stallwart git repository mail-server are directories crates/install and resources/config. ( And I have the warm feeling that I'm closer to a "manual install" :- )

Made the greek horse less dangerous:

--- a/crates/install/src/main.rs
+++ b/crates/install/src/main.rs
@@ -118,14 +118,6 @@ pub struct Arguments {
 fn main() -> std::io::Result<()> {
     let args = Arguments::parse();
 
-    #[cfg(not(target_env = "msvc"))]
-    unsafe {
-        if libc::getuid() != 0 {
-            eprintln!("This program must be run as root.");
-            std::process::exit(1);
-        }
-    }
-
     println!("\nWelcome to the Stalwart Mail Server installer\n");
 
     // Obtain component to install

Then I did ride that horse, did choose ./hier ( not /opt/stallwart-... ) for Installation directory and more YOLO.

Some screenshot:

stappers@messer:/usr/src/stallwart/mail-server
$ target/release/stalwart-install

Welcome to the Stalwart Mail Server installer

✔ Which components would you like to install? · SMTP server
✔ Installation directory · ./hier
✔ How should your local accounts be validated? · LMTP server
📦 Downloading components...
✔ What is your main domain name? (you can add others later) · stappers.nl
✔ What is your server hostname? · hop.stappers.nl
? Where is the TLS certificate for 'hop.stappers.nl' located? (/etc/letsencrypt/live/hop.sta✘ File /etc/letsencrypt/live/hop.stappers.nl/fullchain.pem does not exist
✘ File /dev/null does not exist
✔ Where is the TLS certificate for 'hop.stappers.nl' located? · /etc/resolv.conf
? Where is the TLS private key for 'hop.stappers.nl' located? (/etc/letsencrypt/live/hop.sta✔ Where is the TLS private key for 'hop.stappers.nl' located? · /etc/resolv.conf
chown: ongeldige gebruiker: ‘stalwart-mail:stalwart-mail’
Warning: Failed to write service file: Permission denied (os error 13)

🎉 Installation completed!

✅ Add the following DNS records to your domain in order to enable DKIM, SPF and DMARC:

stalwart._domainkey.stappers.nl. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlm35mYbOThjc4Nijh09kdVQV+F9D0gEoUCDHBmyUz8ZRD9aDX7yVMxrXf02J81ZmiwPqCJx0Nmgb+UGG5diGEbGWxy0kYcQGfuD8QHqIenGSq7Df+6I6iE6/yrHNPWraZ0hVURXq27AyoIg1/jD6L35TBJBn9LqAQ1gXu1OIe9kMRAmdG76WoBf4NImnbhRwiY0DXP/ZCgJCjfwGO23m5a/FgAN2ON7L4zu9H5s/q8plrE55A61RBhtqEeyLt+nN+09L773CIMlE1waElmWxuEaozEIixZ/vQhnKPJn/jhKUP1epCfJiv5NcF8QZOjGSru7t4p/xcoLhm4mJWuIY+QIDAQAB"
stappers.nl. IN TXT "v=spf1 a:hop.stappers.nl mx -all ra=postmaster"
hop.stappers.nl. IN TXT "v=spf1 a -all ra=postmaster"
_dmarc.stappers.nl. IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@stappers.nl; ruf=mailto:postmaster@stappers.nl"


🔑 The administrator account is 'admin' with password 'reDACted'.

stappers@messer:/usr/src/stallwart/mail-server
$

For what it is worth, I compiled on host messer and will need the configuration on host hop.

Some verification:

stappers@messer:/usr/src/stallwart/mail-server
$ file hier/etc/dkim/stappers.nl.cert
hier/etc/dkim/stappers.nl.cert: ASCII text, with very long lines (392), with no line terminators
stappers@messer:/usr/src/stallwart/mail-server
$ cat hier/etc/dkim/stappers.nl.cert
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlm35mYbOThjc4Nijh09kdVQV+F9D0gEoUCDHBmyUz8ZRD9aDX7yVMxrXf02J81ZmiwPqCJx0Nmgb+UGG5diGEbGWxy0kYcQGfuD8QHqIenGSq7Df+6I6iE6/yrHNPWraZ0hVURXq27AyoIg1/jD6L35TBJBn9LqAQ1gXu1OIe9kMRAmdG76WoBf4NImnbhRwiY0DXP/ZCgJCjfwGO23m5a/FgAN2ON7L4zu9H5s/q8plrE55A61RBhtqEeyLt+nN+09L773CIMlE1waElmWxuEaozEIixZ/vQhnKPJn/jhKUP1epCfJiv5NcF8QZOjGSru7t4p/xcoLhm4mJWuIY+QIDAQABstappers@messer:/usr/src/stallwart/mail-server
$ grep MIIBI saved 
stalwart._domainkey.stappers.nl. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlm35mYbOThjc4Nijh09kdVQV+F9D0gEoUCDHBmyUz8ZRD9aDX7yVMxrXf02J81ZmiwPqCJx0Nmgb+UGG5diGEbGWxy0kYcQGfuD8QHqIenGSq7Df+6I6iE6/yrHNPWraZ0hVURXq27AyoIg1/jD6L35TBJBn9LqAQ1gXu1OIe9kMRAmdG76WoBf4NImnbhRwiY0DXP/ZCgJCjfwGO23m5a/FgAN2ON7L4zu9H5s/q8plrE55A61RBhtqEeyLt+nN+09L773CIMlE1waElmWxuEaozEIixZ/vQhnKPJn/jhKUP1epCfJiv5NcF8QZOjGSru7t4p/xcoLhm4mJWuIY+QIDAQAB"
stappers@messer:/usr/src/stallwart/mail-server
$

Verification result: the etc/dkim/stappers.nl.cert is what is supposed to be in DKIM record.

stappers@hop:~
$ sudo adduser --system --no-create-home stalwart-mail
info: Selecting UID from range 100 to 999 ...

info: Adding system user `stalwart-mail' (UID 110) ...
info: Adding new user `stalwart-mail' (UID 110) with group `nogroup' ...
info: Not creating `/nonexistent'.
stappers@hop:~
$ 
stappers@hop:~/stalwart
$ sudo stalwart-mail --config /home/stappers/stalwart/config.toml 
Invalid configuration file: Failed to read file "/home/stappers/stalwart/dkim/stappers.nl.key" for property "signature.rsa.private-key": Permission denied (os error 13)
stappers@hop:~/stalwart
$ ls -l /home/stappers/stalwart/dkim/stappers.nl.key
-rwxr-x--- 1 stappers stappers 1679 Dec 10 16:59 /home/stappers/stalwart/dkim/stappers.nl.key
stappers@hop:~/stalwart
$ 

So make config readable for stalwart-mail user.

stappers@hop:~/stalwart
$ sudo stalwart-mail --config /home/stappers/stalwart/config.toml 
Invalid configuration file: Directory ./hier/queue does not exist.
stappers@hop:~/stalwart
$ git grep queue
config.toml:          "/home/stappers/stalwart/smtp/queue.toml",
smtp/queue.toml:# SMTP server queue configuration
smtp/queue.toml:[queue]
smtp/queue.toml:path = "%{BASE_PATH}%/queue"
smtp/queue.toml:[queue.schedule]
smtp/queue.toml:[queue.outbound]
smtp/queue.toml:[queue.outbound.tls]
smtp/queue.toml:#[queue.outbound.source-ip]
smtp/queue.toml:[queue.outbound.limits]
smtp/queue.toml:[queue.outbound.timeouts]
smtp/queue.toml:[[queue.quota]]
smtp/queue.toml:[[queue.throttle]]
stappers@hop:~/stalwart
$ 
stappers@hop:~/stalwart
$ sudo mkdir /var/spool/stalwart-mail
stappers@hop:~/stalwart
$ sudo mkdir /var/spool/stalwart-mail/queue
stappers@hop:~/stalwart
$ sudo chown stalwart-mail /var/spool/stalwart-mail/queue
stappers@hop:~/stalwart
$ vi smtp/queue.toml 
stappers@hop:~/stalwart
$ git diff smtp/queue.toml
diff --git a/smtp/queue.toml b/smtp/queue.toml
index bcf9b7c..53c0e05 100755
--- a/smtp/queue.toml
+++ b/smtp/queue.toml
@@ -3,7 +3,7 @@
 #############################################
 
 [queue]
-path = "%{BASE_PATH}%/queue"
+path = "/var/spool/stalwart-mail/queue"
 hash = 64
 
 [queue.schedule]
stappers@hop:~/stalwart
$ 
stappers@hop:~/stalwart
$ sudo stalwart-mail --config /home/stappers/stalwart/config.toml 
Invalid configuration file: Directory ./hier/reports does not exist.
stappers@hop:~/stalwart
$ sudo mkdir /var/spool/stalwart-mail/reports
stappers@hop:~/stalwart
$ sudo chown stalwart-mail /var/spool/stalwart-mail/reports
stappers@hop:~/stalwart
$ vi smtp/report.toml 
stappers@hop:~/stalwart
$ git diff
diff --git a/smtp/report.toml b/smtp/report.toml
index 39fea89..fb3b062 100755
--- a/smtp/report.toml
+++ b/smtp/report.toml
@@ -3,7 +3,7 @@
 #############################################
 
 [report]
-path = "%{BASE_PATH}%/reports"
+path = "/var/spool/stalwart-mail/reports"
 hash = 64
 #submitter = "%{HOST}%"
 
stappers@hop:~/stalwart
$
stappers@hop:~/stalwart
$ sudo stalwart-mail --config /home/stappers/stalwart/config.toml
Unable to open database: Internal Error: Connection pool error: timed out waiting for connection: unable to open database file: ./hier/data/index.sqlite3
stappers@hop:~/stalwart
$ git grep index.sqlite3
jmap/store.toml:path = "%{BASE_PATH}%/data/index.sqlite3"
stappers@hop:~/stalwart
$ sudo mkdir -p /var/lib/stalwart-mail/data
stappers@hop:~/stalwart
$ sudo chown stalwart-mail /var/lib/stalwart-mail/data
stappers@hop:~/stalwart
$ vi jmap/store.toml 
stappers@hop:~/stalwart
$ sudo mkdir -p /var/lib/stalwart-mail/blobs
stappers@hop:~/stalwart
$ sudo chown stalwart-mail /var/lib/stalwart-mail/blobs
stappers@hop:~/stalwart
$ git diff
diff --git a/jmap/store.toml b/jmap/store.toml
index 0e436e6..2c4cf23 100755
--- a/jmap/store.toml
+++ b/jmap/store.toml
@@ -3,7 +3,7 @@
 #############################################
 
 [store.db]
-path = "%{BASE_PATH}%/data/index.sqlite3"
+path = "/var/lib/stalwart-mail/data/index.sqlite3"
 
 [store.db.pool]
 max-connections = 10
@@ -16,7 +16,7 @@ size = 1000
 type = "local"
 
 [store.blob.local]
-path = "%{BASE_PATH}%/data/blobs"
+path = "/var/lib/stalwart-mail/data/blobs"
 
 [store.blob.s3]
 bucket = "stalwart"
$ 

OK, so far, so good

stappers@hop:~/stalwart
$ sudo stalwart-mail --config /home/stappers/stalwart/config.toml
^Z
[1]+  Stopped                 sudo stalwart-mail --config /home/stappers/stalwart/config.toml
stappers@hop:~/stalwart
$ bg
[1]+ sudo stalwart-mail --config /home/stappers/stalwart/config.toml &
stappers@hop:~/stalwart
$ tail /var/log/stalwart/stalwart.log.2023-12-10 
2023-12-10T21:45:47.827696Z  INFO utils: Starting Stalwart Mail Server v0.4.2...
2023-12-10T21:56:23.691378Z  INFO utils: Starting Stalwart Mail Server v0.4.2...
2023-12-10T21:57:33.267188Z  INFO utils: Starting Stalwart Mail Server v0.4.2...
2023-12-10T21:57:33.351728Z  INFO utils::listener::listen: Starting listener id="imap" protocol=Imap bind.ip="::" bind.port=143 tls=false
2023-12-10T21:57:33.352067Z  INFO utils::listener::listen: Starting listener id="imaptls" protocol=Imap bind.ip="::" bind.port=993 tls=true
2023-12-10T21:57:33.352179Z  INFO utils::listener::listen: Starting listener id="jmap" protocol=Jmap bind.ip="::" bind.port=8080 tls=false
2023-12-10T21:57:33.352370Z  INFO utils::listener::listen: Starting listener id="sieve" protocol=ManageSieve bind.ip="::" bind.port=4190 tls=true
2023-12-10T21:57:33.352506Z  INFO utils::listener::listen: Starting listener id="smtp" protocol=Smtp bind.ip="::" bind.port=252 tls=false
2023-12-10T21:57:33.352623Z  INFO utils::listener::listen: Starting listener id="submission" protocol=Smtp bind.ip="::" bind.port=587 tls=false
2023-12-10T21:57:33.352725Z  INFO utils::listener::listen: Starting listener id="submissions" protocol=Smtp bind.ip="::" bind.port=465 tls=true
stappers@hop:~/stalwart
$ 

OK, so far, so good

Way too optimistic.

I started over.

stappers@hop:~/stalwart
$ ~/bin/stalwart-alogo 

Welcome to the Stalwart Mail Server installer

✔ Which components would you like to install? · SMTP server
✔ Installation directory · /srv/stalwart
✔ How should your local accounts be validated? · LMTP server
📦 Downloading components...
❌ Failed to download http://mywebserver/stalwart/smtp-server/releases/latest/download/stalwart-smtp-x86_64-unknown-linux-gnu.tar.gz, make sure your platform is supported: 404 Not Found
stappers@hop:~/stalwart
$ ~/bin/stalwart-alogo 

Welcome to the Stalwart Mail Server installer

✔ Which components would you like to install? · SMTP server
✔ Installation directory · /srv/stalwart
✔ How should your local accounts be validated? · LMTP server
📦 Downloading components...
❌ Failed to download http://mywebserver/stalwart/mail-server/releases/latest/download/stalwart-cli-x86_64-unknown-linux-gnu.tar.gz, make sure your platform is supported: 404 Not Found
stappers@hop:~/stalwart
$ ~/bin/stalwart-alogo 

Welcome to the Stalwart Mail Server installer

✔ Which components would you like to install? · SMTP server
✔ Installation directory · /srv/stalwart
✔ How should your local accounts be validated? · LMTP server
📦 Downloading components...
✔ What is your main domain name? (you can add others later) · stappers.nl
✔ What is your server hostname? · hop.stappers.nl
? Where is the TLS certificate for 'hop.stappers.nl' located? (/etc/letsencrypt/live/hop.stappers.nl/ful✔ Where is the TLS certificate for 'hop.stappers.nl' located? · /home/stappers/cert/domain.crt
? Where is the TLS private key for 'hop.stappers.nl' located? (/etc/letsencrypt/live/hop.stappers.nl/pri✔ Where is the TLS private key for 'hop.stappers.nl' located? · /home/stappers/cert/domain.key
chown: invalid group: ‘stalwart-mail:stalwart-mail’
Warning: Failed to write service file: Permission denied (os error 13)

🎉 Installation completed!

✅ Add the following DNS records to your domain in order to enable DKIM, SPF and DMARC:

stalwart._domainkey.stappers.nl. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/pIW76LAupveb0pXmXzAP+E8c93U77VoUxrRQ5dnOZfIuCqsTR+SOycjv+6oPpX96aMzYuDufmuoon4ul+koaxojQEleV25H1XXoSSFo9RHoEyQwJY8Rzux/PXzc66TkIJINUSugnYdDjYiIpQvr9nj+vFcK4o+pQM8C+QwOJQV2+5oNNvEUZ8VNf58xS0LtmUq2PTzZ2uknlA0JP19sHdqqhKFkZxlDGJDAiU/vTjIwNlhmPQvTyZNbzENJcm5Vq/CkyBbDyK1koxchG494Rbq8oPcI3MibfgM7tKN1Q1FGV19XCjBUfEhY2FkOmHlgWj3oQCia1YQCUSOnIOwpwIDAQAB"
stappers.nl. IN TXT "v=spf1 a:hop.stappers.nl mx -all ra=postmaster"
hop.stappers.nl. IN TXT "v=spf1 a -all ra=postmaster"
_dmarc.stappers.nl. IN TXT "v=DMARC1; p=none; rua=mailto:postmaster@stappers.nl; ruf=mailto:postmaster@stappers.nl"


🔑 The administrator account is 'admin' with password 'redacted'.

stappers@hop:~/stalwart
$

chown: invalid group: ‘stalwart-mail:stalwart-mail’

stalwartlabs/mail-server#168

Using mail as common group.

stappers@hop:/srv/stalwart
$ id stalwart-mail
uid=110(stalwart-mail) gid=65534(nogroup) groups=65534(nogroup)
stappers@hop:/srv/stalwart
$ id stappers
uid=1000(stappers) gid=1000(stappers) groups=1000(stappers),4(adm)
stappers@hop:/srv/stalwart
$ sudo vi /etc/group /etc/passwd
2 files to edit
stappers@hop:/srv/stalwart
$ id stalwart-mail
uid=110(stalwart-mail) gid=8(mail) groups=8(mail)
stappers@hop:/srv/stalwart
$ id stappers
uid=1000(stappers) gid=1000(stappers) groups=1000(stappers),4(adm),8(mail)
stappers@hop:/srv/stalwart
$ 

Some sudo stuff

stappers@hop:/srv/stalwart
$ sudo chown -R stalwart-mail:mail .
stappers@hop:/srv/stalwart
$ sudo chmod -R ug+rwx,o-rwx .
stappers@hop:/srv/stalwart
$ 
cd etc/
git init --shared=group -b main .
git config --global --add safe.directory /srv/stalwart/etc
git add .
git commit -m "Untuned config from \"installer\""

Tune the configuration to your preferences ...

Even more sudo stuff

stappers@hop:/srv/stalwart
$ sudo cp stalwart-smtp.service /etc/systemd/system
stappers@hop:/srv/stalwart
$ sudo systemctl enable stalwart-smtp
Created symlink /etc/systemd/system/multi-user.target.wants/stalwart-smtp.service → /etc/systemd/system/stalwart-smtp.service.
stappers@hop:/srv/stalwart
$ sudo systemctl start stalwart-smtp
stappers@hop:/srv/stalwart
$