Skip to main content

How to Set Up Geo-IP Country Based Stream Viewing

IP to Geolocation

IP-to-geolocation allows you to estimate where a user connecting to your server is located. For precise results, you’ll need a paid database or service specializing in geolocation. Free options, such as MaxMind's GeoLite2, offer reasonable accuracy for identifying countries but may lack precision for city-level details. MaxMind's tools are widely available and easy to use, making them a great starting point for Geo-IP functionality.

Requirements

  • Linux (Ubuntu 24.04 is used in this guide)
  • Basic Bash knowledge

Steps in this guide

  1. Install geoiplookup
  2. Set up the script for USER_NEW
  3. Configure the USER_NEW trigger in MistServer
  4. Test and troubleshoot the script

1. Install geoiplookup

We’ll use the free GeoLite2 database from MaxMind, available through most Linux package managers. Keep in mind that the free version has limited accuracy. Should better precision be required you might want to look into the MaxMind developer documentation and integrate with their available services.

Installation on Ubuntu 24.04

Run the following command to install GeoIP tools:

apt install geoip-bin geoip-database

This installs the country-based GeoIP database and provides the geoiplookup tool. You can use this tool to identify the location of an IP address:

geoiplookup ADDRESS

Image of using geoiplookup in the terminal

With geoiplookup installed, you’re ready to set up your script.

2. Set up the script for USER_NEW

We’ll create two script versions:

geoipAllow: Allow viewers from specified countries. geoipDeny: Deny viewers from specified countries.

You can choose one depending on your needs. Don’t activate both scripts on the same stream, as this could create conflicting behavior.

Both scripts use ISO 3166-1 Alpha-2 country codes for identification. Update the country codes and logging settings as needed.

geoIPAllow

The geoIPAllow script allows viewers from specific countries and denies all others.

#!/bin/sh

#This trigger is meant to work with minimum bash. Dependencies are:
# cat , date, geoiplookup

# Usage: Any countries in the CLIST will be checked and if the viewer is from a country in the list playback is ALLOWED.

#Countries to match against matching list as ISO_3166-1_alpha-2 for example: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
# Countries should be space separated and between ", example: CLIST=("NL" "US" "DE" )
CLIST=( )


#Acceslog will keep track of useful reject/accept messages. Feel free to uncomment the lines with $ACCESSLOG in them to remove spam
LOGGING=true
ACCESSLOG=/path/to/accesslog


#Collect the trigger payload
DATA=`cat`
NOW=`date`


#Stream name attempted from 1st line
STREAM=`echo "$DATA" | sed -n 1p`
#IP address requester logged from 2nd line
IP=`echo -n "$DATA" | sed -n 2p`


#Master address is allowed to view everything and skips the check.
MASTER="127.0.0.1"

if [ "$IP" = "$MASTER" ];then
echo -n true
if [ $LOGGING = true ] ; then
echo "$NOW - $IP has all access, allowing for $STREAM" >> $ACCESSLOG
fi
exit 0
fi

#Add any view attempt to accesslog
if [ $LOGGING = true ] ; then
echo "$NOW - checking $IP $STREAM " >> $ACCESSLOG
fi

COUNTRYFULL=`geoiplookup $IP`
COUNTRYSHORT=`echo ${COUNTRYFULL#*:}`

# Check if "IP Address not found" is the result & exit by checking for the word Address, potentially a problem if a Country ever decides that the word "Address" should be in their name.
if [[ $COUNTRYSHORT =~ 'Address' ]]; then
echo -n false
if [ $LOGGING = true ]; then
echo "Viewer from $IP for $STREAM address not found, rejecting" >> $ACCESSLOG
fi
exit 0
fi

COUNTRYCODE=`echo ${COUNTRYSHORT:0:2}`

#Full debugging information, only uncomment if you want full visibility on what is happening.
#echo "$DATA" >> $ACCESSLOG

if [[ ${CLIST[@]} =~ $COUNTRYCODE ]]; then
echo -n true
if [ $LOGGING = true ] ; then
echo "Viewer from $IP for $STREAM is from White-listed $COUNTRYCODE, allowing playback" >> $ACCESSLOG
fi
else
echo -n false
if [ $LOGGING = true ] ; then
echo "VIEWER from $IP for $STREAM is from $COUNTRYCODE, rejecting" >> $ACCESSLOG
fi
fi


Save the script to a memorable location and make it executable.

tip

Don't forget to:

  • Fill in the country codes
  • Fill in logfile location or set off logging
  • Make the script executable through chmod +x
  • Optionally set the master IP to always allow yourself in

3. Configure the USER_NEW trigger in MistServer

Once your scripts are ready, integrate them with MistServer using the USER_NEW trigger:

  1. Navigate to the Triggers page in MistServer.
  2. Create a new trigger and select USER_NEW.
  3. Fill in the fields as shown below:

Image of setting up a USER_NEW trigger

Applies to: Select specific streams for the script. If left blank, the script applies to all streams.

Handler: Provide the path to your script. For example: /path/to/script/geoIPAllow or geoIPAllow if available in path.

Blocking: Yes Blocking should be set for the script to work.

Default response: false The default response is what happens should the script fail, you will want this to false in order to block any unchecked viewers.

4. Test and troubleshoot the script

To test or troubleshoot the script, simulate a USER_NEW trigger by passing a stream name and address manually.

You can do so by using echo:

echo -e "anything\nADDRESS" | /path/to/geoIPAllow
tip

The value stream name is not actually checked, it is only passed to the script as it's a required field for the trigger to work. Whether a stream is checked is determined by which streams are ticked in the applies to field of the USER_NEW trigger.

warning

Make sure to keep the newline \n in there or it will not work!

Example:

echo -e "anything\n149.210.147.206" | geoIPAllow

picture of the command above in use

You’ll see a true or false response in the terminal, indicating whether the viewer is allowed. If logging is enabled, check the log for detailed information:

picture of log captured

Common issues

Script is not responding

Most likely you forgot to make the script executable. Please do so with: chmod +x

Script is giving errors about a file not existing

You've forgotten to set the accesslog. Please do so or turn off logging by setting LOGGING to false.

geoiplookup gives an error

Most likely you do not have geoiplookup installed. Please verify if it's in the package you have installed previously