# 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