pkmn.ai runs on virtual machine imaged with the current Ubuntu LTS release and the stack is built on nginx proxying to Node behind Cloudflare.
Set up a pkmn.ai website in the Cloudflare dashboard and configure
your hosting provider's DNS settings to use the custom nameservers Cloudflare provides. The DNS
records should look like:
| Type | Name | Content | Proxy status | TTL |
|---|---|---|---|---|
A |
* |
123.45.67.89 |
Proxied |
Auto |
A |
pkmn.ai |
123.45.67.89 |
Proxied |
Auto |
A |
www |
123.45.67.89 |
Proxied |
Auto |
In the SSL/TLS section of the dashboard, set SSL/TLS encryption mode to "Full". If
certbot encounters error on renewal follow the troubleshooting
steps.
Cloudflare doesn't proxy SSH connections so to get ssh pkmn@pkmn.ai to work, set up a local DNS
record in /etc/hosts:
+123.45.67.89 pkmn.aiIf this doesn't work, update ~/.ssh/config instead:
+Host pkmn.ai
+ HostName 123.45.67.89
+ ForwardAgent yesAs root, create a pkmn user and set up the authorized SSH keys for passwordless remote login:
adduser pkmn
mkdir ~pkmn/.ssh
chmod 700 ~pkmn/.ssh
cat ~/.ssh/authorized_keys > ~pkmn/.ssh/authorized_keys
chmod 600 ~pkmn/.ssh/authorized_keysIf unable to login as pkmn after the preceding steps, edit /etc/ssh/sshd_config and restart the SSH
daemon:
vim /etc/ssh/sshd_config
/usr/sbin/sshd –t
service ssh restartMake sure the following fields are set in /etc/ssh/sshd_config:
+PasswordAuthentication no
+PubkeyAuthentication yes
+AuthorizedKeysFile .ssh/authorized_keysAllow SSH traffic through the firewall and then enable the firewall:
ufw allow OpenSSH
ufw enable
ufw statusUpgrade/clean up the system packages:
apt-get update
apt-get update upgrade -y
reboot
apt --purge autoremoveIf not already, update to the latest LTS release, verifying through inspection of cat /etc/lsb-release that the update was successful:
cat /etc/lsb-release
apt install update-manager-core -y
do-release-upgrade -d
cat /etc/lsb-releaseInstall general packages required to set up the server:
apt-get install -y git curl build-essentialAs root, install n to manage Node versions via
n-install:
curl -sL https://git.io/n-install | N_PREFIX=/opt/n bash -s -- -y
for binary in node npm npx; do ln -s /opt/n/bin/$binary /usr/bin/$binary; doneRemove the aliases n sets up in the root user's .bashrc:
vim ~/.bashrcSwitch to the pkmn user (su pkmn) and set up the repository in the /home/pkmn directory:
cd /home/pkmn
git clone https://github.com/pkmn/ai.gitAs the root user, select an editor for visudo and then edit /etc/sudoers.d/pkmn to give the
pkmn user the necessary permissions:
update-alternatives --config editor
visudo -f /etc/sudoers.d/pkmnAllow pkmn to reload nginx, reload the systemd unit files and to manager any pkmn.* service.
+pkmn ALL=(ALL) NOPASSWD: /usr/sbin/service nginx reload,/usr/bin/systemctl daemon-reload,/usr/sbin/service pkmn.* *Configure and enable all of the systemd services and timers:
for config in config/*.{service,timer}; do
name=$(basename $config)
if [ $name != "pkmn.ai-controller.service" ]; then
systemctl enable /home/pkmn/ai/$config
systemctl start $name
fi
doneThe following commands can be used to troubleshoot issues with the units:
systemctl list-units
systemctl daemon-reload
systemctl reset-failedLogs for the pkmn.ai services can be viewed through journalctl:
journalctl -xeu pkmn.ai*Install nginx, add www-data to the pkmn group so that nginx can serve the static files in
/home/pkmn/ai/public, and then link the nginx.conf:
apt-get install nginx
usermod -a -G pkmn www-data
ln -s /home/pkmn/ai/config/nginx.conf /etc/nginx/sites-available/pkmn.ai
ln -s /etc/nginx/sites-{available,enabled}/pkmn.aiAllow nginx traffic through the firewall:
ufw allow 'nginx Full'
ufw delete allow 'nginx HTTP'
ufw statusUse snap to install certbot and get certificates for the domains
(you may need to remove the relevant SSL sections from the nginx.conf to bootstrap):
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
certbot --nginx -d pkmn.ai -d www.pkmn.aiRestart the nginx server:
service nginx restartLogs for the nginx service can be viewed via journalctl, and the logrotate-d access logs can be
found in /var/log/nginx:
journalctl -xeu nginx
tail -f /var/log/nginx/access.logBy default the IPs in these logs are going to be coming from Cloudflare, the
following needs to be added to the http block of /etc/nginx/nginx.conf and then nginx needs to
be restarted to get the actual client IPs:
##
# Cloudflare IPs
# https://www.cloudflare.com/ips/
##
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header X-Forwarded-For;This list needs to be kept up to date to reflect changes to Cloudflare's service.