Ubuntu 26.04 Resolute Raccoon as a Gateway for Public Access

John C. Rucker

Originally published on 23 June 2026. Last modified on 9 July 2026.
This guide is a quick step-by-step guide to 
how I implement a gateway for public library use
on Ubuntu-type systems. This guide is mostly 
command-line with no hand-holding. For GUI 
systems and more features, see earlier guides.

Introduction

Below are my local install notes for putting together a public access server on Ubuntu 26.04 Resolute Raccoon, providing statistics for wifi users, and a file server for hosting update caches for tools like Ninite.

You'll need to be pretty comfortable with Linux and the command line to replicate this. But it's really nothing too complicated. Basic steps needing no explanation for someone experienced in Linux are omitted. Using this guide, it takes me about 2 hours to set up a new machine from starting installation to full working order. These notes are for my benefit, but I hope you find it useful, too.

Install Ubuntu

Change the hostname if you wish:

$ sudo hostnamectl set-hostname [name-goes-here]

Prep things for basic server tasks:

$ sudo apt-get install -y samba-server^ openssh-server^
$ sudo apt install -y apache2
$ sudo systemctl enable apache2
$ sudo apt install -y mariadb-server mariadb-client
$ sudo systemctl start mariadb
$ sudo systemctl enable mariadb
$ sudo apt install -y php libapache2-mod-php php-mysql php-common php-cli php-common php-json php-readline
$ sudo a2enmod php8.5
$ sudo systemctl restart apache2

Tweak a Few Things

$ sudo apt install -y exfat-fuse
$ echo "set mouse=" >> ~/.vimrc
$ sudo echo "set mouse=" >> /root/.vimrc
*******************************************************************************
                              NOTICE TO USERS

This computer system is the property of the Branch District Library.  It is
for authorized use only.  Users (authorized or unauthorized) have no explicit
or implicit expectation of privacy.

Any or all uses of this system and all files on this system may be intercepted,
monitored, recorded, copied, audited, inspected, and disclosed to authorized
officials of law enforcement and government agencies.

By using this system, the user consents to such interception, monitoring,
recording, auditing, inspection, and disclosure at the discretion of the Branch
District Library or other authorized officials of law enforcement or government
agencies.

Unauthorized or improper use of this system may result in civil and criminal
penalties and administrative or disciplinary action, as appropriate.  By
continuing to use this system you indicate your awareness of and consent to
these terms and conditions of use.  LOG OFF IMMEDIATELY if you do not agree to
the conditions stated in this notice.

*******************************************************************************
network:
  version: 2
  ethernets:
    enp4s0:
      addresses:
        - 192.168.XXX.XXX/24
      dhcp4: false
      routes:
        - to: default
        via: 192.168.XXX.1
      nameservers:
        addresses:
          - IP-OF-NS1
          - IP-OF-NS2
    enp5s0:
      addresses:
        - 192.168.1.1/24
      dhcp4: false
      nameservers:
        addresses:
          - IP-OF-NS1
          - IP-OF-NS2
$ sudo netplan apply
$ ip addr

DHCP Server

$ sudo apt install -y isc-dhcp-server && \
sudo mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak
authoritative;
default-lease-time 3600;
max-lease-time 3600;
ddns-update-style none;
option routers 192.168.1.1;
option domain-name-servers YOUR-DNS-SERVER-1,YOUR-DNS-SERVER-2;

subnet [Subnet of eno1, just ending in .0] netmask 255.255.255.0 
{
}

subnet 192.168.1.0 netmask 255.255.255.0 
{
    range 192.168.1.100 192.168.1.254; # desired public service IP address range
    host HOSTNAME-HERE # host names for static IP assignment
    {
        hardware ethernet MAC-ADDRESS-USING-COLONS;
        fixed-address DESIRED-IP-ADDRESS-FOR-THIS-MACHINE;
    }
}
$ sudo service isc-dhcp-server restart

Shorewall

$ sudo apt-get install -y shorewall shorewall-init && \ 
sudo cp /usr/share/doc/shorewall/examples/two-interfaces/interfaces /etc/shorewall/; \
sudo cp /usr/share/doc/shorewall/examples/two-interfaces/policy /etc/shorewall/; \
sudo cp /usr/share/doc/shorewall/examples/two-interfaces/rules /etc/shorewall/; \
sudo cp /usr/share/doc/shorewall/examples/two-interfaces/snat /etc/shorewall/; \
sudo cp /usr/share/doc/shorewall/examples/two-interfaces/zones /etc/shorewall/
$ sudo ZONE   INTERFACE    OPTIONS

net     NET_IF            dhcp,tcpflags,nosmurfs,routefilter,sourceroute=0,physical=enp4s0
loc     LOC_IF            dhcp,tcpflags,nosmurfs,routefilter,physical=enp5s0
loc             all             ACCEPT
fw              loc             ACCEPT
fw              net             REJECT
net             all             DROP
# THE FOLLOWING POLICY MUST BE LAST
all             all             REJECT
# file sharing
SMB(ACCEPT)  net    fw
SMB(ACCEPT)  fw    net

# Accept SSH connections for administration
ACCEPT      net                     fw      tcp     22

# Accept HTTP for the wifi stats
ACCEPT      net                     fw      tcp     80,443

# let the other servers access apcupsd for shutdown commands
#     after a power failure
ACCEPT      net                     fw      tcp     3551 

# VNC
ACCEPT      net                     fw      tcp     5900

# Allow both sides of the firewall to access the filter
# (as in your staff side can use the filter, too)
ACCEPT      net       fw          tcp    8081

# Route all HTTP traffic from library computers to the filter
# make the IP address range match your needs
REDIRECT    loc:192.168.1.2-192.168.1.255 8081    tcp    80,8000,8001,8080   -

####################################################
# RULES TO LET CERTAIN TRAFFIC OUT OF THE FIREWALL #
####################################################


# ping
ACCEPT      fw      net                     icmp

#DNS
ACCEPT      fw      net                     udp     53
ACCEPT      fw      net                     tcp     53

# HTTP(s)
ACCEPT      fw      net                     tcp     80,8000,8001,8080,443

# NTP
ACCEPT      fw      net                     udp     123

# Security Cams
ACCEPT      fw      net                     tcp     7001,7002

# Allow all traffic out to the local staff and public networks
ACCEPT     fw      net:192.168.0.0/16     all
ACCEPT     fw      loc                    all

########################################################
# END RULES TO LET CERTAIN TRAFFIC OUT OF THE FIREWALL #
########################################################

# This last rule needs to be in place to allow for unfiltered library computers. It needs to be kept last.
ACCEPT      loc     net                     tcp     80 

#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
$ sudo shorewall restart
$ sudo systemctl enable shorewall

Statistics

$ sudo mysql -u root
mysql> CREATE USER 'phpmyadmin'@'localhost' IDENTIFIED BY 'PASSWORD-HERE';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'phpmyadmin'@'localhost';
mysql> FLUSH PRIVILEGES;
$ sudo apt install phpmyadmin php-mbstring php-zip php-gd php-json php-curl -y; sudo phpenmod mbstring
$ sudo  mysql -u root
mysql> CREATE DATABASE IF NOT EXISTS `wifi_stats` DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;quit;
$ sudo mysql -u root wifi_stats < old_exported_wifi_stats.sql
$ sudo  mysql -u root wifi_stats < wifi_stats.sql
$ sudo chmod 755 /usr/lib/cgi-bin/reportdhcp.pl
$ sudo a2enmod cgi
$ sudo systemctl restart apache2
1 *  *   *   *     wget http://localhost/DHCPd-parse.php -O /dev/null > /dev/null 2>&1

Temp Drive for Sharing Files and Ninite Update Cache

$ sudo mkdir /home/temp
$ sudo chown nobody:nogroup /home/temp
$ sudo chmod 777 /home/temp
[temp]
 comment = Public file sharing space
 path = /home/temp
 read only = no
 user mask = nobody
 create mask = 0666
 directory mask = 0777
 browseable = no
 public = yes
 writeable = yes
 guest ok = yes
 guest only = yes
$ sudo systemctl restart smbd

File Backups

$ ssh-keygen -t rsa
# ssh-copy-id -i ~/.ssh/id_rsa.pub username@remote_host
5 0 * * * mysqldump -u root --password=YOUR-PASSWORD wifi_stats > /home/username/wifi_stats_dump.sql; scp -i /home/username/.ssh/id_rsa /home/username/wifi_stats_dump.sql username@remote_host:/path/to/backup/directory/

Uninterrupted Power Supply (UPS)

$ sudo apt-get install apcupsd -y; \
sudo mv /etc/apcupsd/apcupsd.conf /etc/apcupsd/apcupsd.conf.bak

Conclusion

And that is all! Reboot and make sure everything comes back up the way it should. And TEST!


Originally published on 23 June 2026. Last modified on 9 July 2026.
Copyright © John C. Rucker
Verbatim copying and distribution of this entire article is permitted in any medium without royalty provided this notice is preserved.