Configuration guide¶
A single config file is the only thing you need to modify in order to have almost full control over your DHCP server’s behaviour.
The file is intended to be largely forwards-compatible, meaning that, when a new version of staticDHCPd is released, you shouldn’t have to change anything: the new engine will massage and inject data as needed to make sure that gaps in your configuration will be filled with sane defaults, and that old scripting logic will still work. (Within reason, of course; always check the changelog)
The default file is very minimal in nature. To extend it, simply place the parameters, described below, that you want to modify into that file and restart your server.
conf.py
¶
conf.py is, as you may have surmised, a real Python file. It is executed by the interpreter before staticDHCPd is fully online and you can do, with it, everything that you’d normally expect a Python script to do, including importing other modules. More information on that is provided in the scripting guide – the important thing to note for basic configurations is that you need to conform to Python syntax when specifying values:
None
, written capitalised and without quotation, indicates that a value is explicitly null.Text values must be strings, “like this” or ‘like this’, with quotation marks.
Numbers are written naturally, like 6 or 7.32.
Boolean values are written as
True
orFalse
, capitalised, without quotation.1
and0
are NOT suitable substitutes.Lists are written like
[1, 2, 'hello']
, and may contain mixed data-types.Concatenations of strings may be done using the + operator:
'hello' + 'goodbye' # = 'hellogoodbye' #Non-string data, like numbers, must be converted 'hello' + str(5) # = 'hello5'
Any value defined in the file may be referenced on any later line, like this:
_HELLO = 'hello' GREETING = _HELLO + 'goodbye'
Everything is case-sensitive.
You may define non-config-parameter values in this file, but it would be a good idea to prefix their names with an underscore, to avoid potential conflicts with future upstream changes.
Parameters¶
The various settings that may be defined within conf.py
. These should always
be specified before any custom code you might add, like functions.
General¶
DEBUG : boolean : default=False¶
- Adds additional information to everything that gets logged
- Does not modify the logging severity levels of individual loggers
SYSTEM_NAME : text : default=’staticDHCPd’¶
- The name the system will use to self-identify
DAEMON : boolean : default=True¶
- Causes the server to daemonise during startup
- Not a good thing to have enabled when doing initial setup because you lose ^C and console logs
PID_FILE : text, None : default=None¶
- The path to which a pidfile should be written
'/var/run/staticDHCPd.pid'
is a good choice
Server¶
UID : integer : MUST BE SPECIFIED¶
- The UID under which the server will run, after everything is bound
- This should normally be your system’s “nobody”
GID : integer : MUST BE SPECIFIED¶
- The GID under which the server will run, after everything is bound
- This should normally be your system’s “nobody”
DHCP_SERVER_IP : text : MUST BE SPECIFIED¶
- The IP of the interface to use for DHCP traffic
- This value must be a specific IP address:
'0.0.0.0'
is invalid
DHCP_RESPONSE_INTERFACE : text : default=’-‘¶
- The value is the lexical name of the interface from which responses
should be sent, like
'eth0'
- A special value of
'-'
may be used to automatically resolve the interface based on DHCP_SERVER_IP - If set, response-packets will be crafted from layer 2, allowing for unicast OFFERs in response to DISCOVERs, if the client set the broadcast bit
- For the vast majority of environments where staticDHCPd is likely to be used,
it is perfectly fine, and recommended, to disable this feature with
None
- This feature was historically not enabled by default because it incurs a slight performance penalty (calculating IP and UDP checksums in Python) and some additional overhead (interfacing with libpcap from Python if Linux’s AF_PACKET (which has its own syscalls) is not available) on all broadcast-scope exchanges, whether they use unicast MAC-broadcasts or not, plus a persistent filehandle and some memory, and complications with VLANs if the server is expected to handle them
- Unfortunately, some Windows firewalling configurations require it
- Surprisingly, the Linux kernel’s DHCP autoconfiguration mechanism does, too
DHCP_RESPONSE_INTERFACE_QTAGS : list : default=None¶
If DHCP_RESPONSE_INTERFACE is set and qtags are required on that interface, they may be supplied in order of appearance (head to tail) as TCI blocks
Format:
(Priority Control Point (0-7), Drop Eligible Indicator (True/False), VLAN Identifier (1-4094),)
Example:
[(3, True, 42), (1, False, 77)]
-> VLAN 42 with nested VLAN 77
DHCP_SERVER_PORT : integer : default=67¶
- The port on which to listen for DHCP queries
DHCP_CLIENT_PORT : integer : default=68¶
- The port on which to respond to DHCP clients
PROXY_PORT : integer, None : default=None¶
- The port on which to listen for ProxyDHCP requests, often referred to as PXE, if required
- ProxyDHCP normally runs on
4011
Caching¶
Caches are only enabled if the database engine supports them and USE_CACHE is set.
CACHING_MODEL : text : default=”in-process”¶
- The database-engine to use for handling static lease data
'in-process'
: manage the cache using in-process constructs, either memory or an on-disk file accessed exclusively by staticDHCPd'memcached'
: use a memcached server as an external store
CACHE_ON_DISK : boolean : default=False¶
- Causes the local cache to be managed as a local file, rather than a purely
in-memory construct
- For largeish caches that are accessed infrequently, but where local access through disk (or hotspot-cached pages in RAM) is still expected to be more efficient than a remote database call
- This file will be temporary, unless PERSISTENT_CACHE is set; in that case, the file will be the same
PERSISTENT_CACHE : text : default=None¶
- Causes the cache to be written to a local database file, which will be used when staticDHCPd is restarted, to provide durability against unstable databases
- The value of this option is the path to the file;
'/var/tmp/staticDHCPd.db'
is usually a good choice - If CACHE_ON_DISK is set, this file will be used directly as a buffer; if not, the contents of this file will be read into memory and this file will be write-only at runtime
MEMCACHED_HOST : text : default=None¶
- The address of the memcached server to use with the corresponding model
MEMCACHED_PORT : integer : default=11211¶
- The port of the memcached server to use with the corresponding model
MEMCACHED_AGE_TIME : integer : default=300¶
- The lifetime to apply to cached data within the memcached server
Database¶
DATABASE_ENGINE : text, None : MUST BE SPECIFIED¶
- The database-engine to use for handling static lease data
- One of
None
,'SQLite'
,'PostgreSQL'
,'Oracle'
,'MySQL'
,'INI'
- One of
- Only parameters related to the chosen database engine need to be supplied
- You may alternatively supply a callable that provides an instance of
databases.generic.Database
, if you want to implement your own engine without messing with core code- The callable must require no arguments
- To keep
conf.py
clean, define your engine in a separate module, likeextensions/_mydb.py
and import it just before DATABASE_ENGINE is set, referencing a callable declared therein - If you need to configure it differently for each server, declare a lambda
or short function in
conf.py
and make changes to that as needed - It is sane to inherit from subclasses like
databases.generic.CachingDatabase
; it is probably safe to inherit from thedatabases._sql._SQLDatabase
family, too, but its internal implementation is technically private - If you need to tie into callbacks, like
reinitialisation, you should do this as part of the callable’s logic; the
callbacks
object is not available at the time thatconf.py
is first processed, but it is available while the callable is executed- Alternatively, you can create the object at the
conf.py
level, write a simplelambda : _MY_INSTANTIATED_DATABASE_OBJECT
as the callable, and operate on_MY_INSTANTIATED_DATABASE_OBJECT
ininit()
, for consistency - Note: the database object’s
reinitialise()
method is automatically registered, so you only need to tie into callbacks if you need behaviour that cannot be captured there
- Alternatively, you can create the object at the
Database:None¶
No parameters to set. This database is only useful if you are exclusively using
handleUnknownMAC()
, described in the scripting guide,
to provision addresses.
Database:SQLite¶
CASE_INSENSITIVE_MACS : boolean : default=False¶
- Forces case-insensitive comparisons for MACs
- If this matters to you, you should create a NOCASE index over maps:mac instead, for greater efficiency
USE_CACHE : boolean : default=False¶
- Causes data retrieved from the database to be stored in memory until the cache is flushed via reinitialisation
- For SQLite, this should normally be
False
EXTRA_MAPS : list : default=None¶
- Any non-standard fields to read from the maps table, which will be
provided in
definition.extra
, keyed as maps.$COLUMN
EXTRA_SUBNETS : list : default=None¶
- Any non-standard fields to read from the subnets table, which will be
provided in
definition.extra
, keyed as subnets.$COLUMN
SQLITE_FILE : text : MUST BE SPECIFIED if using SQLite¶
- The path to the file that contains your SQLite database
Database:PostgreSQL¶
CASE_INSENSITIVE_MACS : boolean : default=False¶
- Forces case-insensitive comparisons for MACs
- If this matters to you, you should create a lower() index over maps:mac instead, for greater efficiency
USE_CACHE : boolean : default=False¶
- Causes data retrieved from the database to be stored in memory until the cache is flushed via reinitialisation
- Can greatly improve performance in stable, high-load environments
EXTRA_MAPS : list : default=None¶
- Any non-standard fields to read from the maps table, which will be
provided in
definition.extra
, keyed as maps.$COLUMN
EXTRA_SUBNETS : list : default=None¶
- Any non-standard fields to read from the subnets table, which will be
provided in
definition.extra
, keyed as subnets.$COLUMN
USE_POOL : boolean : default=True¶
- Causes database connections to pull from a pool by default, reducing connection overhead considerably
- Requires that the eventlet library is installed; will fall back to direct connections if it’s not available
POSTGRESQL_DATABASE : text : MUST BE SPECIFIED if using PostgreSQL¶
- The name of your database
POSTGRESQL_USERNAME : text : MUST BE SPECIFIED if using PostgreSQL¶
- The name of a user with SELECT permissions
POSTGRESQL_PASSWORD : text : MUST BE SPECIFIED if using PostgreSQL¶
- The user’s password
POSTGRESQL_HOST : text, None : default=None¶
- The host on which PostgreSQL is running
- If
None
, a local socket will be used
POSTGRESQL_PORT : integer : default=5432¶
- The port on which PostgreSQL is running
- If POSTGRESQL_HOST is
None
, a local socket will be used and this value will be ignored
POSTGRESQL_SSLMODE : text : default=’disable’¶
- The SSL mode to use
- Ignored in local socket situations
POSTGRESQL_MAXIMUM_CONNECTIONS : integer : default=4¶
- The maximum number of threads that may connect to the database at once
Database:Oracle¶
CASE_INSENSITIVE_MACS : boolean : default=False¶
- Forces case-insensitive comparisons for MACs
- If this matters to you, you should create a lower() index over maps:mac instead, for greater efficiency
USE_CACHE : boolean : default=False¶
- Causes data retrieved from the database to be stored in memory until the cache is flushed via reinitialisation
- Can greatly improve performance in stable, high-load environments
EXTRA_MAPS : list : default=None¶
- Any non-standard fields to read from the maps table, which will be
provided in
definition.extra
, keyed as maps.$COLUMN
EXTRA_SUBNETS : list : default=None¶
- Any non-standard fields to read from the subnets table, which will be
provided in
definition.extra
, keyed as subnets.$COLUMN
USE_POOL : boolean : default=True¶
- Causes database connections to pull from a pool by default, reducing connection overhead considerably
- Requires that the eventlet library is installed; will fall back to direct connections if it’s not available
ORACLE_DATABASE : text : MUST BE SUPPLIED if using Oracle¶
- The name of your database (from tnsnames.ora)
ORACLE_USERNAME : text : MUST BE SUPPLIED if using Oracle¶
- The name of a user with SELECT permissions
ORACLE_PASSWORD : text : MUST BE SUPPLIED if using Oracle¶
- The user’s password
ORACLE_MAXIMUM_CONNECTIONS : integer : default=4¶
- The maximum number of threads that may connect to the database at once
Database:MySQL¶
CASE_INSENSITIVE_MACS : boolean : default=False¶
- Forces case-insensitive comparisons for MACs
- MySQL is normally case-insensitive, so this isn’t likely to be helpful
USE_CACHE : boolean : default=False¶
- Causes data retrieved from the database to be stored in memory until the cache is flushed via reinitialisation
- Can greatly improve performance in stable, high-load environments
EXTRA_MAPS : list : default=None¶
- Any non-standard fields to read from the maps table, which will be
provided in
definition.extra
, keyed as maps.$COLUMN
EXTRA_SUBNETS : list : default=None¶
- Any non-standard fields to read from the subnets table, which will be
provided in
definition.extra
, keyed as subnets.$COLUMN
USE_POOL : boolean : default=True¶
- Causes database connections to pull from a pool by default, reducing connection overhead considerably
- Requires that the eventlet library is installed; will fall back to direct connections if it’s not available
MYSQL_DATABASE : text : MUST BE SPECIFIED if using MySQL¶
- The name of your database
MYSQL_USERNAME : text : MUST BE SPECIFIED if using MySQL¶
- The name of a user with SELECT permissions
MYSQL_PASSWORD : text : MUST BE SPECIFIED if using MySQL¶
- The user’s password
MYSQL_HOST : text, None : default=None¶
- The host on which MySQL is running
- If
None
, a local socket will be used
MYSQL_PORT : integer : default=3306¶
- The port on which MySQL is running
- If MYSQL_HOST is
None
, a local socket will be used and this value will be ignored
MYSQL_MAXIMUM_CONNECTIONS : integer : default=4¶
- The maximum number of threads that may connect to the database at once
Server behaviour¶
ALLOW_LOCAL_DHCP : boolean : default=True¶
- Whether link-local DHCP requests will be handled
ALLOW_DHCP_RELAYS : boolean : default=False¶
- Whether relayed DHCP requests will be handled
ALLOWED_DHCP_RELAYS : list : default=[]¶
- If relayed requests are allowed, providing a list of IPs, like
['192.168.1.1', '192.168.2.1']
, will limit which ones will be accepted - If empty, all relays are considered acceptable
ENABLE_RAPIDCOMMIT : boolean : default=True¶
- Whether rapid-commit (RFC 4039) semantics should be processed for supporting clients.
- If this causes problems, please report it as a bug and provide details.
AUTHORITATIVE : boolean : default=False¶
- Controls whether unknown MACs should be NAKed instead of ignored
- If you are likely to run multiple DHCP servers that do not share the same lease-status information, this should be False, or else clients will experience intermittent stability issues, as one server contradicts the other instead of staying silent
NAK_RENEWALS : boolean : default=False¶
- Whether REBIND and RENEW requests should be NAKed when received, forcing clients to either wait out their lease or return to the DISCOVER phase
- This is good if you expect that you will be changing your configuration in the near future
UNAUTHORIZED_CLIENT_TIMEOUT : integer : default=60¶
- The number of seconds for which unknown MACs should be ignored, to avoid wasting processing resources unnecessarily
MISBEHAVING_CLIENT_TIMEOUT : integer : default=150¶
- The number of seconds for which MACs that are sending invalid requests should be ignored; with dynamic servers, these could be trying to trigger a DoS scenario, so there’s no point in wasting resources on them
ENABLE_SUSPEND : boolean : default=True¶
- Whether MACs that are flooding the server will be considered as misbehaving
SUSPEND_THRESHOLD : integer : default=10¶
- The number of times a well-behaved MAC can interact with the server before being being considered as misbehaving
- The number of interactions in memory is reduced by one per second
Logging¶
LOG_FILE : text, None : default=None¶
- The path to which logs should be written
- The specified file must be writeable if it already exists, or containing directory must allow file-creation
'/var/log/staticDHCPd/staticDHCPd.log'
is a good choice, but you must create the directory and set appropriate permissions first
LOG_FILE_HISTORY : integer, None : default=7¶
- If logging to a file, this will cause logs to rotate once per day, with retention up to the specified number of days
- If None, which is not recommended, the specified file will grow indefinitely
LOG_FILE_SEVERITY : text : default=’WARN’¶
- Controls how much information appears in the log-file: only events at least this important
- One of
'DEBUG'
,'INFO'
,'WARN'
,'ERROR'
,'CRITICAL'
LOG_CONSOLE_SEVERITY : text : default=’INFO’¶
- Controls how much information appears in the console: only events at least this important
- Console-based logging is disabled when running as a daemon
- One of
'DEBUG'
,'INFO'
,'WARN'
,'ERROR'
,'CRITICAL'
Webservice¶
WEB_ENABLED : boolean : default=True¶
- Whether the webservice engine should be enabled
WEB_IP : text : default=‘0.0.0.0’¶
- The IP on which HTTP traffic should be served
- By default, this will listen on all interfaces; to restrict it, provide a specific IP
WEB_PORT : integer : default=30880¶
- The port on which HTTP traffic should be served
WEB_LOG_HISTORY : integer : default=200¶
- The number of events to present in the dashboard’s log
- If
0
, no log will be present in the dashboard
WEB_LOG_SEVERITY : text : default=’INFO’¶
- Controls how much information appears in the dashboard: only events at least this important
- One of
'DEBUG'
,'INFO'
,'WARN'
,'ERROR'
,'CRITICAL'
WEB_LOG_MAX_HEIGHT : integer, None : default=400¶
- The maximum height, in pixels, of the web-log, before it scrolls
- A value of
None
disables this restriction
WEB_DIGEST_USERNAME : text, None : default=None¶
- The username to use for DIGEST-based authentication
- If
None
, authentication is disabled
WEB_DIGEST_PASSWORD : text, None : default=None¶
- The password to use for DIGEST-based authentication
- If
None
, authentication is disabled
WEB_DASHBOARD_SECURE : boolean : default=False¶
- Whether authentication is needed to access the dashboard
WEB_REINITIALISE_CONFIRM : boolean : default=True¶
- Whether confirmation is required to reinitialise the server
WEB_REINITIALISE_SECURE : boolean : default=False¶
- Whether authentication is requires to reinitialise the server
WEB_REINITIALISE_ENABLED : boolean : default=True¶
- Whether the reinitilise option should be available at all
WEB_DASHBOARD_ORDER_LOG : integer : default=1000¶
- Sets the ordering bias of the log in the web-dashboard
WEB_HEADER_TITLE : boolean : default=True¶
- Whether the default title should be included in the web interface
- This is the same as the value you supplied for SYSTEM_NAME
WEB_HEADER_CSS : boolean : default=True¶
- Whether the defualt CSS should be included in the web interface
WEB_HEADER_FAVICON : boolean : default=True¶
- Whether the defualt favicon should be included in the web interface
E-mail¶
EMAIL_ENABLED : boolean : False¶
- Whether e-mail notification of CRITICAL-severity events should occur
- These issues usually reflect very unusual conditions in your network, and are therefore generally very helpful
EMAIL_SERVER : text : MUST BE SPECIFIED if using e-mail¶
- Your SMTP server’s address
EMAIL_PORT : integer : default=25¶
- The SMTP port your server uses
EMAIL_SOURCE : text : MUST BE SPECIFIED if using e-mail¶
- The address to put in the FROM field
EMAIL_DESTINATION : text : MUST BE SPECIFIED if using e-mail¶
- The address to put in the TO field
EMAIL_SUBJECT : text : default=’staticDHCPd encountered a problem’¶
- The subject-line to use for e-mail issues
"staticDHCPd running on " + DHCP_SERVER_IP + " encountered a problem"
might be a better choice for a larger environment
EMAIL_USER : text, None : default=None¶
- The username to use in authentication to the server
- If
None
, authentication is not performed
EMAIL_PASSWORD : text : MUST BE SPECIFIED if using e-mail and EMAIL_USER is set¶
- The password to use in authentication to the server