mod_geoip2
The mod_geoip2
module uses the GeoIP library from MaxMind to
look up various geographic information for a connecting client:
https://github.com/maxmind/libmaxminddbThis information can be used to set access controls for the server.
This module is contained in the mod_geoip2.c
file for
ProFTPD 1.3.x, and is not compiled by default. Installation
instructions are discussed here.
The most current version of mod_geoip2
can be found at:
https://github.com/Castaglia/proftpd-mod_geoip2.git
This product includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com/.
Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.
<VirtualHost>
, <Global>
The GeoIPAllowFilter
directive is used to configure ACLs based
on the geographic data provided by the GeoIP library.
Multiple GeoIPAllowFilter
directives in the configuration are
supported; if any filter matches the connecting client, the connection
will be allowed.
The filter parameter specifies the GeoIP value to which to apply the configured pattern for matching. The possible filter values are:
ASN
City
Continent
CountryCode
CountryName
Latitude
Longitude
Organization
PostalCode
RegionCode
RegionName
Timezone
The pattern parameter is case-insensitive regular expression that will be applied to the specified filter value, if available.
Note that as of proftpd-1.3.6rc3
and later, the
GeoIPAllowFilter
directive can also take a single
parameter which specifies a SQL query (via mod_sql
's
SQLNamedQuery
), which
will be used to retrieve the filter and pattern values to use.
Examples:
# Allow clients from Ireland GeoIPAllowFilter CountryCode IE # Reject clients connecting from North America or South America GeoIPDenyFilter Continent (NA|SA)The following more complex configuration demonstrates what can be done using SQL querires:
<IfModule mod_sql.c> ... SQLNamedQuery get-geo-allowed SELECT "filter_name, pattern FROM allowed_user_geo WHERE user_name = '%u'" SQLNamedQuery get-geo-denied SELECT "filter_name, pattern FROM denied_user_geo WHERE user_name = '%u'" </IfModule> <IfModule mod_geoip2.c> GeoIPEngine on GeoIPAllowFilter sql:/get-geo-allowed GeoIPDenyFilter sql:/get-geo-denied </IfModule>The above assumes SQL tables with schema similar to the following (expressed using SQLite syntax):
CREATE TABLE allowed_user_geo ( user_name TEXT, filter_name TEXT, pattern TEXT ); CREATE TABLE denied_user_geo ( user_name TEXT, filter_name TEXT, pattern TEXT ); # Note that we create separate indexes, to allow for multiple rows per user CREATE INDEX allowed_user_geo_name_idx ON allowed_user_geo (user_name); CREATE INDEX denied_user_geo_name_idx ON denied_user_geo (user_name);
<VirtualHost>
, <Global>
The GeoIPDenyFilter
directive is used to configure ACLs based
on the geographic data provided by the GeoIP library.
Multiple GeoIPDenyFilter
directives in the configuration are
supported; if any filter matches the connecting client, the connection
will be rejected.
Note that as of proftpd-1.3.6rc3
and later, the
GeoIPDenyFilter
directive can also take a single
parameter which specifies a SQL query (via mod_sql
's
SQLNamedQuery
), which
will be used to retrieve the filter and pattern values to use.
See GeoIPAllowFilter
for
a description of the directive syntax and parameters.
<VirtualHost>
, <Global>
The GeoIPEngine
directive enables or disables the module's
lookup of geographic information for a connecting client, and subsequent
enforcement of any configured ACLs.
<VirtualHost>
, <Global>
The GeoIPLog
directive is used to specify a log file for
mod_geoip2
's reporting on a per-server basis. The file
parameter given must be the full path to the file to use for logging.
Note that this path must not be to a world-writable directory and,
unless AllowLogSymlinks
is explicitly set to on
(generally a bad idea), the path must not be a symbolic link.
<VirtualHost>
, <Global>
The GeoIPPolicy
directive determines whether the
mod_geoip2
module will allow a connection by default or not.
If GeoIPPolicy
is configured using "allow,deny" (which
is the default setting), then the mod_geoip2
module will allow the
connection, unless the connecting client is rejected by any
GeoIPDenyFilter
rules.
If GeoIPPolicy
is configured using "deny,allow", then
the mod_geoip2
module will reject any connection,
unless the connecting client matches any configured
GeoIPAllowFilter
rules.
<VirtualHost>
, <Global>
The GeoIPTable
directive is used to a GeoIP database file
for use by the GeoIP library. The path parameter given must be the
full path to the database file.
If no GeoIPTable
directive is configured, then
mod_geoip2
will not perform any geographical lookups.
Multiple GeoIPTable
directives can be used to configure
multiple different GeoIP database files for use at the same time.
Note that the flags parameter is currently supported for
backward compatibility with mod_geoip
, but is
currently ignored.
Examples:
GeoIPTable /path/to/GeoLite2-City.mmdb GeoIPTable /path/to/GeoLite2-Country.mmdb GeoIPTable /path/to/GeoLite2-ASN.mmdb
mod_geoip2
module requires that the MaxMindDB library be
installed. For including mod_geoip2
as a statically linked module:
$ ./configure --with-modules=mod_geoip2Alternatively,
mod_geoip2
could be built as a DSO module:
$ ./configure --with-shared=mod_geoip2Then follow the usual steps:
$ make $ make installYou may need to specify the location of the MaxMindDB header and library files in your
configure
command, e.g.:
$ ./configure --with-modules=mod_geoip2 \ --with-includes=/usr/local/maxminddb/include \ --with-libraries=/usr/local/maxminddb/lib
Alternatively, if your proftpd
was compiled with DSO support, you
can use the prxs
tool to build mod_geoip2
as a shared
module:
$ prxs -c -i -d mod_geoip2.c
mod_geoip
Interactions
The mod_geoip2
module is meant to be, roughly, a drop-in
replacement for the legacy mod_geoip
module; it implements the
same configuration directive, provides the same environment variables,
etc. Thus mod_geoip2
will fail to start if it
detects that the mod_geoip
module is also being used. You
must use only one of either mod_geoip
or
mod_geoip2
in ProFTPD, but not both.
Access Controls
If any GeoIPAllowFilter
or GeoIPDenyFilter
directives are configured, the mod_geoip2
module applies them
against the geographic information retrieved from the GeoIP library. First
any GeoIPAllowFilter
s are checked. If any of these
filters matches the connecting client's information, the connection is allowed.
Next, any GeoIPDenyFilter
s are checked. If any of these
filters matches the connecting client's information, the connection is closed.
Otherwise, the connection is allowed.
This means that if you wanted to reject connections from the US except for connections from California, you might use something like this:
# Deny all connections from the US GeoIPDenyFilter CountryCode US # But allow connections from California GeoIPAllowFilter RegionCode CA
Environment Variables
The mod_geoip2
module will set the following environment
variables whenever a client connects, assuming that the appropriate
GeoIP tables have been configured and the values are known for the connecting
client:
GEOIP_ASN
GEOIP_CITY
GEOIP_CONTINENT_CODE
GEOIP_COUNTRY_CODE
(two-letter country code)
GEOIP_COUNTRY_NAME
GEOIP_LATITUDE
GEOIP_LONGITUDE
GEOIP_ORGANIZATION
GEOIP_POSTAL_CODE
GEOIP_REGION
GEOIP_REGION_NAME
GEOIP_TIMEZONE
session.notes
table,
under keys of the names above.
Example Configuration
<IfModule mod_geoip2.c> GeoIPEngine on GeoIPLog /path/to/ftpd/geoip.log GeoIPTable /path/to/GeoLite2-City.mmdb # Add your GeoIPAllowFilter/GeoIPDenyFilter rules here </IfModule>
Logging
The mod_geoip2
module supports different forms of logging. The
main module logging is done via the GeoIPLog
directive.
For debugging purposes, the module also uses trace logging, via the module-specific log channels:
proftpd.conf
:
TraceLog /path/to/ftpd/trace.log Trace geoip2:20The geographic information retrieved from the GeoIP library for the connecting client is logged using this "geoip2" trace log channel. This trace logging can generate large files; it is intended for debugging use only, and should be removed from any production configuration.
Suggested Future Features
The following lists the features I hope to add to mod_geoip2
,
according to need, demand, inclination, and time:
GeoIPAllowFilter
/GeoIPDenyFilter
to apply, in addition to any
Frequently Asked Questions
Question: What is the difference between
Question: How I can whitelist specific clients from
mod_geoip2
and mod_geoip
?
Answer: The mod_geoip
module uses
the "legacy" GeoIP API from MaxMind, which was discontinued in early 2019.
This mod_geoip2
module uses the newer MaxMindDB library from
MaxMind.
mod_geoip2
's checking?
Answer: You should be able to easily do this using
classes and the
mod_ifsession
module. For example:
<Class geoip-whitelist>
From 1.2.3.4
</Class>
<IfModule mod_geoip2.c>
# Add the normal mod_geoip2 directives here except
GeoIPEngine
</IfModule>
<IfClass geoip-whitelist>
# Disable mod_geoip2 for the whitelisted clients
GeoIPEngine off
</IfClass>
<IfClass !geoip-whitelist>
# Enable mod_geoip2 for all non-whitelisted clients
GeoIPEngine on
</IfClass>