nox.im · All Snippets · All in Ubuntu · All in Server
Install Nginx for our reverse proxy setup:
apt-get install -y nginx
Start the service and ensure it starts on reboot:
systemctl start nginx
systemctl enable nginx
We can test this by hitting our box now with a web browser. If it works we’ll
setup basic auth first on the /etc/nginx/sites-available/default
site which is
located under:
root /var/www/html;
Create an htpasswd file with OpenSSL
echo "someuser:$(openssl passwd -crypt somepass)" > /etc/nginx/conf.d/.htpasswd
And reference it in the config:
server {
# ...
location / {
root /var/www/html;
error_page 404 =200 /index.html;
# ...
auth_basic "closed site";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
}
NOTE: The error_page 404 =200 /index.html;
is generally recommended when
*working with single page apps (SPA), “modern web” sites to always serve the
*index on paths that the app will route for us.
Check if the config is good, and if so reload it:
sudo nginx -t
sudo nginx -s reload
Nginx with basic authentication should now be working. We’ll reuse this setup in the reverse proxy section below.
By default our services would be exposed on their native ports, not just through the reverse proxy. For extra security we’ll want to lock down the server to just Nginx. Setup ufw and ensure the SSH port is open BEFORE enabling it.
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
We can view rules:
ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 8080/tcp ALLOW IN Anywhere
[ 4] 22/tcp (v6) ALLOW IN Anywhere (v6)
[ 5] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 8080/tcp (v6) ALLOW IN Anywhere (v6)
and delete a rule with:
sudo ufw delete 6
Create a systemd service file
touch /etc/systemd/system/solana-test-validator.service
chmod 664 /etc/systemd/system/solana-test-validator.service
point the service file to your binary, here it’s the Solana test validator from my Raspberry Pi post:
[Unit]
Description=Solana Test Validator
[Service]
Restart=always
ExecStart=/usr/local/bin/solana-test-validator -q --ledger /var/db/solana/test-ledger
[Install]
WantedBy=multi-user.target
Reload the service files and start our new service
systemctl daemon-reload
systemctl start solana-test-validator
systemctl status solana-test-validator
if ok, enable so it survives a reboot
systemctl enable solana-test-validator
Our service may produce log files. In order to not run out of disk space, we’ll add a logrotate onto the file:
vim /etc/logrotate.d/solana
With zero days retention, running hourly if the file is not empty.
/var/local/solana-test-ledger/validator-*.log {
hourly
missingok
rotate 1
copytruncate
notifempty
}
In this case, the log files look as follows:
ls -lh /var/local/solana-test-ledger/*.log
-rw-r--r-- 1 root staff 550M Mar 10 08:37 /var/local/solana-test-ledger/validator-1646890477927.log
-rw-r--r-- 1 root staff 278M Mar 10 10:51 /var/local/solana-test-ledger/validator-1646903838680.log
-rw-r--r-- 1 root staff 543M Mar 10 14:01 /var/local/solana-test-ledger/validator-1646909768151.log
lrwxrwxrwx 1 root staff 27 Mar 10 10:56 /var/local/solana-test-ledger/validator.log -> validator-1646909768151.log
If we deal with a service that doesn’t close their log files on SIGHUB and
doesn’t rotate the files by itself as it is the case here, we can use the
copytruncate
option.
You can test this by running logrotate manually:
logrotate --force /etc/logrotate.d/solana
Note that usually logrotate is configured to be run by cron daily. To run
logrotate hourly copy the file /etc/cron.daily/logrotate
into the
/etc/cron.hourly/
directory.
As part of systemd, we can setup journald to vaccuum by time and size to only retain 1 day and max 300MB.
journalctl --vacuum-time=1d
journalctl --vacuum-size=300M
Create and enable a new Nginx “site” called “reverse-proxy”:
touch /etc/nginx/sites-available/reverse-proxy
ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/reverse-proxy
vim /etc/nginx/sites-available/reverse-proxy
Link an upstream service, the one we want to expose through the reverse proxy and a server section with the proxy_pass and the basic authentication configuration from above:
upstream myservice {
server 127.0.0.1:8081;
}
server {
listen 8080;
server_name _;
location / {
proxy_pass http://myservice;
auth_basic "closed site";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
}
Note that you can have multiple upstream and multiple server blocks.
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Everything seems to be good, let’s reload nginx:
sudo systemctl reload nginx
We’re done, enjoy!
If you need a service from a web frontend, you may want to look at my follow up on Cross-Origin Resource Sharing (CORS) headers.