Ubuntu 22.04 Jammy Jellyfish as a Gateway for Public Access

John C. Rucker

Originally published on 3 June 2023. Last modified on 23 February 2024.
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 22.04 Jammy Jellyfish, 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 apache2
$ sudo systemctl enable apache2
$ sudo apt install mariadb-server mariadb-client
$ sudo systemctl start mariadb
$ sudo systemctl enable mariadb
$ sudo mysql_secure_installation
$ sudo apt install php libapache2-mod-php php-mysql php-common php-cli php-common php-json php-opcache php-readline
$ sudo a2enmod php8.1
$ sudo systemctl restart apache2

Tweak a Few Things

$ sudo apt install -y exfat-fuse

Set the timezone:

sudo timedatectl set-timezone America/New_York

Edit /etc/systemd/timesyncd.conf to include:

NTP=us.pool.ntp.org
FallbackNTP=ntp.ubuntu.com

Restart the time service and check:

$ sudo systemctl restart systemd-timesyncd.service
$ sudo systemctl status systemd-timesyncd.service
$ timedatectl

Edit /etc/ssh/sshd_config. Add the line Banner /etc/issue.net.

Edit /etc/issue.net to give whatever notice your lawyers say is appropriate to people trying to log into your server:

*******************************************************************************
                              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:
    ethernets:
        enp4s0:
            addresses:
            - 192.168.XX.XXX/24
            dhcp4: no
            routes:
                - to: default
                via: 192.168.XX.1
            nameservers:
                addresses:
                    - IP-OF-NS1
                    - IP-OF-NS2
        enp5s0:
            addresses:
                - 192.168.1.1/24
            dhcp4: no
            nameservers:
                addresses:
                    - IP-OF-NS1
                    - IP-OF-NS2
    version: 2

To apply the changes, execute:

$ sudo netplan apply

Verify the changes:

$ ip addr

DHCP Server

Install the DHCP server and back up the original config file:

$ sudo apt install -y isc-dhcp-server && \
sudo mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak

Edit /etc/dhcp/dhcpd.conf as needed, adding static address assignments for your library-provided public computers. If you are using this DHCP server to give addresses to all your public and staff computers, make sure all library computers are defined in this file. The file should look something like this:

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;
    }
}

Restart DHCP server:

$ sudo service isc-dhcp-server restart

Shorewall

We'll use Shorewall to make it easier to maintain rules for public Internet access. Note: I highly recommend that you have this gateway behind another firewall, limiting access from the public Internet. In this case, think of "net" in all the examples below to mean your staff network and "loc" is your public access network.

Install shorewall and copy configuration files:

$ 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

Edit /etc/shorewall/policy:

loc             all             ACCEPT
fw              loc             ACCEPT
fw              net             REJECT
net             all             DROP
# THE FOLLOWING POLICY MUST BE LAST
all             all             REJECT
Edit /etc/shorewall/rules. At minimum, append the following rules to the end of the existing file and edit per your situation.

# 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

Set Shorewall to start automatically on boot:

$ sudo systemctl enable shorewall

Statistics

$ sudo mysql -u root
mysql> CREATE USER 'phpmyadmin'@'localhost' IDENTIFIED WITH mysql_native_password 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; 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
This program isn't actually used for any of the stats collection, but it can be useful for troubleshooting. Access it from http://YOUR-SERVER-IP-ADDRESS-OR-URL/cgi-bin/reportdhcp.pl.
  • Set a cron job to collect the stats every hour, and to preemptively restart the services hourly (for stability reasons):
  • 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

    Bluecherry Video Surveillance Server

    $ sudo bash -c "$(curl -s https://raw.githubusercontent.com/bluecherrydvr/bluecherry-docker/master/scripts/install.sh)"

    Log into the Bluecherry web admin at https://192.168.1.1:7001/ and activate with your license key. Set up the system as desired. The default login is a username of admin and password of bluecherry. Change these immediately and setup user account(s) for those who will be watching the video streams.

    Install the Bluecherry client program or web client views as needed.

    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; \
    mv /etc/apcupsd/apcupsd.conf /etc/apcupsd/apcupsd.conf.bak