# How to host a shared gemini server?
2020-12-31T21:07:51Z

Today, I set up a secure multi-user gemini server, because I'd like to support this protocol. I wish more people can do the same, so here how I did it.

=> gemini://gmi.si3t.ch Multi-user gemini server on si3t.ch

## Forewords

We will use an OpenBSD system, SFTP chroot and vger gemini server. ("secure", we said). 
Users capsules will be available at gemini://domain.tld/user/.
I choose "/home/gemini" as chroot because "/home" is my biggest slice. Feel free to use another path.
Only Pubkey authentication will be allowed : easier and more secure. 

Group "gmiusers" is used to identify who must be chrooted.
Before going any further, create this group:
```
# groupadd gmiusers
```

## SFTP configuration
Create chroot. Keep in mind permissions are crucial.

```
# mkdir /home/gemini
# chown root:gmiusers /home/gemini
# chmod 750 /home/gemini
# mkdir /home/gemini/home
```

/home/gemini/home will store users directories.

chmod is 750 because : 
* "7" : owner can read, write and cd in this directory
* "5" : group gmiusers can read in this directory. It is necessary so the gemini server can serve files :)
* "0" : Others can't access this directory at all.


/etc/ssh/sshd_config : 

```
Match Group gmiusers
        ChrootDirectory /home/gemini/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        X11Forwarding no
        PasswordAuthentication no
```

Then reload ssh:

```
# rcctl reload sshd
```

## vger gemini server setup
Download/compile/install vger

=> https://tildegit.org/solene/vger

Create a dedicated user for vger. It must belong to "gmiusers" group to be able to read files to serve:

```
useradd -G gmiusers -s /sbin/nologin _gemini_server
```

Edit /etc/inetd.conf:

```
11965 stream tcp nowait _gemini_server /usr/local/bin/vger vger -d /home/gemini/home
```

Edit /etc/relayd.conf:

```
log connection
ext_ip4 = "xx.xx.xx.xx."
ext_ip6 = "xxxx:xxxx:xxxx:xxx::xxx"


tcp protocol "gemini" {
        tls keypair domain.tld
}

relay "gemini" {
        listen on $ext_ip4 port 1965 tls
        protocol "gemini"
        forward to 127.0.0.1 port 11965
}
relay "gemini6" {
        listen on $ext_ip6 port 1965 tls
        protocol "gemini"
        forward to 127.0.0.1 port 11965
}
```

Notice relayd will look for tls certificates for "domain.tld" with the above configuration. This means /etc/ssl/domain.tld.crt and /etc/ssl/private/domain.tld.key.
gemini requires TLS. To get a certificate, you can use acme-client or generate a self-signed one. This is out of the scope of this page.

=> https://www.romanzolotarev.com/openbsd/acme-client.html
=> https://man.openbsd.org/ssl

Of course, enable and start these daemons:

```
# rcctl enable inetd relayd
# rcctl start inetd relayd
```

## Add an user
You must create the user directory, set permissions, and add ssh pubkey so the user can identify. I do it with the script below. It will ask to paste user pubkey after creating it.

```
#!/bin/sh
# addgmiuser <user>

if [ $# -lt 1 ]; then
	echo "usage: $0 user"
	exit
fi
CHROOT=/home/gemini/
user="$1"
dir="${CHROOT}/home/${user}"
sshkey=""

userinfo "${user}" && (echo "user already exists" || exit 1)

mkdir -p "${CHROOT}"
useradd -G gmiusers -s /sbin/nologin -m "${user}" || exit 1
install -d -o ${user} -g gmiusers -m 750 "${dir}"

while [ -z "${sshkey}" ] ; do
    echo "enter ssh pubkey"
	read -r sshkey
done

echo "${sshkey}" >> /home/${user}/.ssh/authorized_keys

# create an index file so the user see it works
echo "# ${user}'s capsule" > "${dir}/index.gmi"
echo "write here" > "${dir}/index.gmi"
chown "${user}":"${user}" "${dir}/index.gmi"
exit
```

## The end
Now users can start a sftp session, they are locked in the chroot and automatically in their own directory. They just have to upload gmi files and it's done :)

```
$ sftp -i ~/.ssh/sshkey user@domain.tld
Connected to domain.tld.
sftp> pwd
Remote working directory: /home/user
```

## Something to say?

=> mailto:bla@bla.si3t.ch?subject=howto-shared-gemini-host 📧 Send a comment
=> mailto:bla+subscribe@bla.si3t.ch 📫 Subscribe to get answers
=> /log/commentaires/ 📚 Read archives.
=> mailto:bla+subscribe@bla.si3t.ch 💨 Unsubscribe