Zero to Geoserver

How to setup geoserver on AWS

  1. EC2 considerations
  2. Install geoserver
    1. Adapting to Java 17
    2. Startup
    3. Autostart / Run as Service
    4. Performance settings
    5. Open Firewall
    6. Wipe the demo data
  3. Reverse Proxy, SSL/HTTPS
    1. Install nginx
    2. Get SSL certificate
    3. Configure nginx
    4. Enable site and reload
  4. Geoserver Settings
    1. Allow cross-site referencing
  5. Security/Production settings
  6. Not allowing unauthorized requests to geoserver
  7. Plugins
    1. PGraster geoserver plugin
    2. Install COG geoserver plugin
    3. Install authkey plugin
  8. Allow CORS

EC2 considerations

We generally seem to be able run the geoserver on a t.micro instance, but run into crashes under load. Either the geoserver java container runs out of memory, or the whole machine. t2.medium runs the geoserver very stable. But we might get away with t2.small.

Install geoserver

sudo apt install openjdk-17-jre unzip

VERSION=2.23.2
USERNAME=griessbaum

wget https://sourceforge.net/projects/geoserver/files/GeoServer/$VERSION/geoserver-$VERSION-bin.zip

sudo mkdir /usr/share/geoserver
sudo mv geoserver-$VERSION-bin.zip /usr/share/geoserver/
cd /usr/share/geoserver/
sudo unzip geoserver-$VERSION-bin.zip 
sudo rm geoserver-$VERSION-bin.zip 
echo "export GEOSERVER_HOME=/usr/share/geoserver" >> ~/.profile
. ~/.profile
sudo chown -R $USERNAME /usr/share/geoserver/

Adapting to Java 17

https://docs.geoserver.org/latest/en/user/production/java.html#running-on-java-17

rm /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/marlin-0.9.3.jar

Startup

/usr/share/geoserver/bin/startup.sh
/usr/share/geoserver/bin/shutdown.sh

By default, starts up at localhost:8080 with http://localhost:8080/geoserver/

  • user: admin
  • pwd: geoserver

Autostart / Run as Service

https://docs.geoserver.org/latest/en/user/production/linuxscript.html

wget https://docs.geoserver.org/latest/en/user/_downloads/5c56ec58bc153d3a7dd6ef198f9eeaf7/geoserver_deb
mv geoserver_deb geoserver
sudo mv geoserver /etc/init.d/
chmod +x /etc/init.d/geoserver

Now we should be able to e.g.:

sudo /etc/init.d/geoserver start
sudo service geoserver status

We can either edit the /etc/init.d/geoserver, or create /etc/default/geoserver.

sudo nano /etc/init.d/geoserver
  • GEOSERVER_HOME=/usr/share/geoserver
  • GEOSERVER_DATA_DIR=/usr/share/geoserver/data_dir
  • USER=griessbaum (that’s probably not a good idea)
  • JAVA_HOME='' (this is the prefix; keeping it empty will point it to /bin/java)
sudo systemctl daemon-reload
sudo service geoserver restart

To make the service start at startup:

sudo systemctl enable geoserver

Performance settings

We might also want to consider changing some performance parameters in /etc/init.d/geoserver as described in container considerations, e.g. set the min and max heap size with -Xmx1024M and -Xms128m. GisExchange discussion on the topic.

  • -XX:+UseParallelGC
  • -Xmx256M
  • -Xmx384M

Then reload the units and restart the server

sudo systemctl daemon-reload
sudo service geoserver restart

Open Firewall

If we are in production, we probably only need 80, 443 and 22.

sudo ufw enable
sudo ufw allow 443
sudo ufw allow 22
sudo ufw status

Edit security group on AWS

Wipe the demo data

  • data_dir/workspaces : wipe the dir
rm -rf /usr/share/geoserver/data_dir/workspaces && mkdir /usr/share/geoserver/data_dir/workspaces
sudo chown ubuntu /usr/share/geoserver/data_dir/workspaces/
  • data_dir/layergroups : wipe the dir
rm -rf /usr/share/geoserver/data_dir/layergroups/*
  • while not stritcly necessary, wipe the data directory too:
rm -rf /usr/share/geoserver/data_dir/data/*

Reverse Proxy, SSL/HTTPS

Install nginx

ADDRESS='geoserver.co.ck'
sudo apt install nginx

Get SSL certificate

sudo apt install python3-certbot-nginx
sudo certbot --nginx certonly
  • Certificate is saved at: /etc/letsencrypt/live/$ADDRESS/fullchain.pem
  • Key is saved at: /etc/letsencrypt/live/$ADDRESS.duckdns.org/privkey.pem

Have the cert renewed once a week.

sudo crontab -e
17 7 * * * certbot renew --post-hook "systemctl reload nginx"

Configure nginx

Create a config file:

sudo nano /etc/nginx/sites-available/geoserver
server {
        listen 80;
        server_name geoserver.co.ck www.geoserver.co.ck;

        # Redirect http requests to https
        return 301 https://geoserver.co.ck$request_uri;
}

server {        
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        ssl_certificate /etc/letsencrypt/live/geoserver.co.ck/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/geoserver.co.ck/privkey.pem;

        server_name geoserver.co.ck;

        location /geoserver/ {
                proxy_pass http://127.0.0.1:8080/geoserver/;
                proxy_pass_header Set-Cookie;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Enable site and reload

sudo ln -s /etc/nginx/sites-available/geoserver /etc/nginx/sites-enabled
sudo nginx -t
sudo service nginx reload
sudo service nginx restart

Site should now be available at https://geoserver.co.ck/ and you should either get to the geoserver (if it is running), or get a 502 bad gateway if it is off.

Geoserver Settings

settings are in /usr/share/geoserver/data_dir/global.xml

Set proxy settings

We won’t be able to log in via port 443. We have to change the server’s proxy settings first. Kind of a hen-and-egg problem ..

Two solutions. Either:

  • temporarily open port 8080 (aws and local firewall). Not very elegant.
  • port forwarding; e.g.
ssh -N -L 1234:127.0.0.1:8080 geoserver.co.ck

Then navigate to localhost:1234.

Once logged into the webinterface (admin/geoserver), go to Global (under Settings)

  • Set Proxy Base URL to your address (geoserver.co.ck). In previous versions, this might have been called admin site.
  • Tick/set Use headers for Proxy URL = True.

Allow cross-site referencing

sudo nano /usr/share/geoserver/webapps/geoserver/WEB-INF/web.xml

Add the following

<context-param>
        <param-name>GEOSERVER_CSRF_WHITELIST</param-name>
        <param-value>geoserver.co.ck</param-value>
</context-param> 

and edit the following

<context-param>  
        <param-name>PROXY_BASE_URL</param-name>  
        <param-value>https://geoserver.co.ck/geoserver</param-value>
</context-param>

Note: If you screw this up, you can try to get back to the webinterface through port 8080

Security/Production settings

https://docs.geoserver.org/latest/en/user/production/config.html

Now that SSL is running, we can tighten up security

  • Block Port 8080
    • in security group
    • firewall: sudo ufw deny 8080
  • Update admin password (Security > Users)
  • Update master pwd (Security > Passwords)
  • We don’t care about service limits since we won’t allow unauthorized access
  • We might want to disable the web admin IF

Not allowing unauthorized requests to geoserver

  • Do not remove anonymous from Authentication settings
  • Create new user (e.g. arconline)
  • Change layer security;
    • by default nothing is ticked meaning everyone can do everything
    • tick “read” for ROLE_AUTHENTICATED. That should only allow authenticated users to access

Plugins

PGraster geoserver plugin

https://docs.geoserver.org/stable/en/user/community/pgraster/pgraster.html

VERSION=2.23
sudo apt install libpostgresql-jdbc-java
wget https://build.geoserver.org/geoserver/$VERSION.x/community-latest/geoserver-$VERSION-SNAPSHOT-pgraster-plugin.zip
mv geoserver-$VERSION-SNAPSHOT-pgraster-plugin.zip /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/
cd /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/
unzip geoserver-$VERSION-SNAPSHOT-pgraster-plugin.zip
rm geoserver-$VERSION-SNAPSHOT-pgraster-plugin.zip

This does not work out-of-the-box for me. We have to do something with imagemosaic first. I never figured it out.

java -Xbootclasspath/a:<location of jdbc.jar> -jar <your_geoserver_install_dir>/webapps/geoserver/WEB-INF/lib/gt-imagemosaic-jdbc-{version}.jar import -config <your geoserver data dir>/coverages/osm.postgis.xml -spatialTNPrefix tileosm -tileTNPrefix tileosm -dir tiles -ext png

Remove:

rm /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/gs-pgraster-2.23-SNAPSHOT.jar

Install COG geoserver plugin

VERSION=2.23
wget https://build.geoserver.org/geoserver/$VERSION.x/community-latest/geoserver-$VERSION-SNAPSHOT-cog-plugin.zip
mv geoserver-$VERSION-SNAPSHOT-cog-plugin.zip /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/
cd /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/
unzip geoserver-$VERSION-SNAPSHOT-cog-plugin.zip 
rm geoserver-$VERSION-SNAPSHOT-cog-plugin.zip 

Restart. Verify by heading to stores > add store > Geotiff; you now should have “Cloud Optimized GeoTIFF (COG)” Checkbox

Install authkey plugin

The authkey module for GeoServer allows for a very simple authentication protocol designed for OGC clients that cannot handle any kind of security protocol, not even the HTTP basic authentication … like ArcOnline!

VERSION=2.23.2
wget https://sourceforge.net/projects/geoserver/files/GeoServer/$VERSION/extensions/geoserver-$VERSION-authkey-plugin.zip
mv geoserver-$VERSION-authkey-plugin.zip /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/
cd /usr/share/geoserver/webapps/geoserver/WEB-INF/lib/
unzip geoserver-$VERSION-authkey-plugin.zip
rm geoserver-$VERSION-authkey-plugin.zip

Then follow https://docs.geoserver.org/latest/en/user/extensions/authkey/index.html#configuration

Now add a new authentication filter

  1. Go to Security > Authentication > Under Authentication Filters, click Add new
  2. Click Authkey up top
  3. set:
    1. Name: whatever
    2. name of url parameter: authkey
    3. Auth key to user mapper: user property
    4. User/group service: default
  4. Sync the user/group services
  5. save

After configuring the filter, it is necessary to put this filter on the authentication filter chain(s). i.e. add a filter chain.

  1. Go to Security > Authentication > Under Filters Chains, click Add service chain.
  2. Set:
    • Name: key_pwd
    • Comma delimited list of ANT patterns (with optional query string): /wms/**,/ows/**
    • Add both the authkey and basic chain filter
  3. Make it second to the last (bottom); before default

i

Allow CORS

We might want to allow CORS for acronline to use user/pwd login

sudo nano /usr/share/geoserver/webapps/geoserver/WEB-INF/web.xml