These are my notes for installing jackal on a server where I already have PostgreSQL and Caddy set up to host a Mattermost instance. Some of the roadblocks I hit are most likely due to the idiosyncracies of however I set up postgres for mattermost, which is my only experience with postgres.
Tested with go 1.11.5 (current version available in Debian testing/buster repo)
First, get the code and build:
go get -d github.com/ortuman/jackal
cd $GOPATH/src/github.com/ortuman/jackal
make install
Make a user to run jackal (all commands from here on are run as root):
adduser jackal
As db admin user, make jackal database and user. On my system, the db admin is 'postgres'.
sudo --login --user postgres
psql
# in the postgres console:
CREATE ROLE jackal WITH LOGIN PASSWORD 'passwordstring';
CREATE DATABASE jackal;
GRANT ALL PRIVILEGES ON DATABASE jackal TO jackal;
Next, import the database schema:
psql --user jackal --password -f sql/postgres.up.psql
But on my system, that returned the error psql: FATAL: no pg_hba.conf entry for host "[local]", user "jackal", database "jackal", SSL off
.
This suggests you should add a line like hostnossl jackal jackal 127.0.0.1/32 md5
to pg_hba.conf.
But on my system, that didn't work, while the following line to set up connection through a unix socket did.
local jackal jackal peer
Then importing the schema as the jackal user worked fine:
su jackal
psql --user jackal --password -f sql/postgres.up.psql
However, currently jackal is set up to connect to postgres through ipv4, and that line will need to be switched to the following before running jackal.
hostnossl jackal jackal 127.0.0.1/32 md5
A more permissive pg_hba.conf (for example, with host all all 127.0.0.1/32 md5
) would have probably avoided having to jump through all those hoops.
Remember to reload postgres after editing the config file.
vi /etc/postgresql/9.6/main/pg_hba.conf
systemctl reload postgresql
To set jackal up on anything but localhost, it seems to expect the path to a TLS certificate and key file. Which is great! Since Let's Encrypt there's no reason to not encrypt your chat server connections. My system already has a website for which Caddy is managing a Let's Encrypt certificate. I don't have another domain name to use, and I don't feel like using a subdomain for jackal, so I'm going to share the cert between caddy and jackal. (Can you even get two Let's Encrypt certs for the same domain? Something I just assumed "no" to but didn't do any research.) It would have been less convoluted if I wasn't sharing the cert and could point the jackal config at it's own personal certificate files.
First, find the files! Who are they owned by? Let's put the jackal user in that group.
ls -l /etc/ssl/caddy/acme/acme-v01.api.letsencrypt.org/sites/mydomain.com/
usermod -a -G www-data jackal
Next, I make a directory to point jackal to, and hardlink the files into it. Hardlinking lets the jackal user see the cert/key without loosening restrictions on the original path, and in theory means jackal will see the new certs whenever caddy automatically bugs Let's Encrypt for them. This avoids the issue of certificate expiration I would have if I simply copied the certs to a new directory and changed the ownership of the copies to the jackal user. (Although I'm not sure whether or not the renewed certs will still be group readable, I'll find out in three months!)
mkdir /etc/ssl/jackal
cp -l /etc/ssl/caddy/acme/acme-v01.api.letsencrypt.org/sites/mydomain.com/* /etc/ssl/jackal/
chmod 700 /etc/ssl/jackal
chown jackal:jackal /etc/ssl/jackal
cd /etc/ssl/caddy/acme/acme-v01.api.letsencrypt.org/sites/mydomain.com/
chmod g+r /etc/ssl/jackal/*
mkdir /etc/jackal
cd /etc/jackal
wget https://raw.githubusercontent.com/ortuman/jackal/master/example.jackal.yml
cp /etc/jackal/example.jackal.yml /etc/jackal/jackal.yml
# putting the db password in here, so restricting the permissions
chown -R root:jackal /etc/jackal
chmod -R 750 /etc/jackal
Include the following in 'jackal.yml' for the hostname set up above, and to use postgres.
router:
hosts:
- name: mydomain.com
tls:
privkey_path: "/etc/ssl/jackal/mydomain.com.key"
cert_path: "/etc/ssl/jackal/mydomain.com.crt"
storage:
type: pgsql
pgsql:
host: 127.0.0.1:5432
user: jackal
password: passwordstring
database: jackal
ssl_mode: disable
For using ssl to connect to postgres, the 'ssl_mode' line above can be changed. The options accepted by postgres are require
, verify-full
, verify-ca
, and disable
.
Note that the jackal line of the postgres 'pg_hba.conf' file will need to be changed to reflect whatever setting is chosen. For example, host jackal jackal 127.0.0.1/32 md5
will allow SSL connections from localhost, and passwords will be hashed with md5.
I keep manually built applications in their own path:
mkdir /opt/jackal
mv /home/user/go/bin/jackal /opt/jackal/
chown -R jackal:jackal /opt/jackal/
chmod 500 /opt/jackal/jackal
chmod 700 /opt/jackal
Systemd service file: '/etc/systemd/system/jackal.service'
[Unit]
Description=jackal
After=network.target
After=postgresql.service
Requires=postgresql.service
[Service]
Type=simple
PIDFile=/opt/jackal/jackal.pid
ExecStart=/opt/jackal/jackal
Restart=always
RestartSec=10
WorkingDirectory=/opt/jackal
User=jackal
Group=jackal
[Install]
WantedBy=multi-user.target
Start the service, make sure it's running well, and enable it so it starts automatically on boot.
systemctl start jackal.service
systemctl status jackal
systemctl enable jackal.service
Disable jackal user log in: vipw
, change the jackal line to jackal:x:1001:1001::/home/jackal:/usr/sbin/nologin
Disable jackal user password: vipw -s
, change jackal line to jackal:!:17965::::::
(note: 3rd value is unimportant, it's a timestamp for when password was last changed. The important part is '!' in the second slot.)