peapod.conf - configuration file for the EAPOL proxy daemon peapod
peapod requires a config file to determine the network interfaces on which it should listen for EAPOL packets and how packets should be received and sent on those interfaces. "EAPOL packet" in this sense is an Ethernet frame with the EAPOL EtherType of 0x888e encapsulating either an EAP packet or certain EAPOL control messages.
The syntax is mostly self-explanatory.
Comment lines start with # (a number sign), and paths containing spaces may be enclosed in "" (double quotes).
Some options have a stanza form, requiring one or more suboptions between a { (opening curly brace) and an accompanying } (closing curly brace) as part of the option definition.
All option/suboption definitions end with ; (a semicolon).
The config file must contain at least two interface definitions. Two forms are acceptable:
iface name;
iface name {
ingress stanza
egress stanza
set-mac definition OR set-mac-from definition
promiscuous definition
};
In the simpler first form, the interface just grabs all EAPOL packets it sees off the wire and hands them off to be proxied to (sent out on) other configured interfaces without ever doing anything special to or with the packets.
In the second form, iface is a stanza, and suboptions are provided to influence peapod's behavior with respect to the named interface.
Additionally, log verbosity may be specified at the beginning of the config file:
verbosity number;
number may be from 0 to 3. This has the same effect as providing the -v command-line option the corresponding number of times, but the verbosity specified in the config file takes precedence.
The minimum config file is therefore:
iface eth0;
iface eth1;
See peapod(8), "OPERATION" to understand how and where options exert an effect within the context of peapod's control flow.
The options set-mac and set-mac-from cannot be combined on the same interface.
ingress {
exec definition(s)
filter definition(s)
};
Stanza with options for an interface during the ingress phase.
See also "ingress stanza options" below.
egress {
dot1q stanza OR no dot1q definition
filter definition(s)
exec definition(s)
};
Stanza with options for an interface during the egress phase.
See also "egress stanza options" below.
set-mac xx:xx:xx:xx:xx:xx;
Set a user-specified MAC address on an interface during program startup.
Typically defined on an authenticator-facing interface with the address of a supplicant device. Once the supplicant establishes an EAPOL session, traffic originated by the device running peapod appears to be authorized (as long as MACsec is not in use).
Cannot be combined on the same interface with set-mac-from.
set-mac-from from-name;
Automatically set the MAC address of an interface to that of the sender of the first EAPOL packet received on from-name. from-name must be the name of another interface configured with its own iface definition elsewhere in the config file.
Similarly to set-mac, typically defined on an authenticator-facing interface, but with the name of a supplicant-facing interface. Once the supplicant establishes an EAPOL session, traffic originated by the device running peapod appears to be authorized (as long as MACsec is not in use).
Cannot be combined on the same interface with set-mac.
promiscuous;
Put interface into promiscuous mode instead of the normal multicast mode during startup.
Practically never needed. Only necessary when the interface or its drivers do not properly support Ethernet multicast (highly unlikely on a recent system).
Ingress script execution occurs before, and does not affect, ingress filtering.
See also "TYPES" for a listing of the type keywords used with the exec and filter options.
exec type script-path;
Execute a script upon receiving a given type of EAPOL/EAP packet on an interface.
See also "SCRIPTS" for more information on script execution.
filter type, type, …;
filter type;
Filter (drop) packets of the given type(s) received on an interface.
In the ingress phase, filtered packets are dropped entirely and not proxied to other interfaces.
Egress filtering occurs before, and may prevent, egress script execution.
See also "TYPES" for a listing of the type keywords used with the filter and exec options.
dot1q {
priority definition
drop-eligible definition
id definition
};
no dot1q;
In the stanza form, if a packet ready to be sent on an interface has an existing 802.1Q VLAN tag (was received tagged on its ingress interface), modify the tag fields according to the dot1q stanza options contained in the stanza before sending it out. If it was received untagged, add a blank tag first and treat it as an existing tag.
In the second form, prevent any packets from being sent on an interface tagged. Any existing tags are removed.
Unlikely to be needed, but implemented for the sake of flexibility.
See also "dot1q stanza options" below.
filter type, type, …;
filter type;
Filter (drop) packets of the given type(s) received on an interface.
In the egress phase, filtered packets are dropped only on the interface on which they are filtered, and may still be sent on other interfaces.
exec type script-path;
Execute a script immediately before a given type of EAPOL/EAP packet is sent on an interface.
See also "SCRIPTS" for more information on script execution.
IEEE 802.1Q VLAN tags are 32 bits long, and contain several fields. They are inserted immediately after the destination and source MAC addresses in an Ethernet frame, and their main use is to signify to upstream networking equipment that the frame should be treated as belonging to a particular virtual LAN.
802.1Q VLAN Tag Format (cf. IEEE Std 802.1Q) | ||||
---|---|---|---|---|
Bits | 16 | 3 | 1 | 12 |
Field | TPID | PCP | DEI | VID |
Tag Protocol ID (always 0x8100) |
Tag Control Information (configurable) |
The IEEE 802.1X specification states that EAPOL packets may be encapsulated (contained) within "priority tagged" Ethernet frames. In this special use case of VLAN tags, the VID and DEI fields in the tag are set to 0, and only the three priority bits in the PCP field are meaningful. The value of the PCP field, 0 to 7, indicates the priority of the frame.
As the 802.1X specification also states that both priority tagged and untagged EAPOL traffic should be understood and treated equally, most users will not need to define any of these options. For the sake of flexibility, peapod allows the 802.1Q Tag Control Information to be manipulated in proxied EAPOL traffic. This accounts for the possibility of misconfigured networks that, for example, expect EAPOL authentication to occur on a VLAN (with a specific VID).
priority number;
Set the Priority Code Point (PCP) field to a number from 0 to 7.
drop-eligible number;
Set the Drop Eligible Indicator (DEI) bit to 0 (off) or 1 (on).
The meaning and function of this field has changed in recent versions of the 802.1Q standard. Practically never needed in any case.
id number;
Set the VLAN Identifier (VID) field to a number from 0 to 4094.
Below are the type keywords that may be used in exec and filter option definitions, and the corresponding EAPOL Packet Types/EAP Codes.
EAPOL Packet Types (cf. IEEE Std 802.1X-2010) | ||
---|---|---|
Type | Description | Keyword |
0 | EAPOL-EAP | eap |
1 | EAPOL-Start | start |
2 | EAPOL-Logoff | logoff |
3 | EAPOL-Key | key |
4 | EAPOL-Encapsulated-ASF-Alert | encapsulated-asf-alert |
5 | EAPOL-MKA | mka |
6 | EAPOL-Announcement (Generic) | announcement-generic |
7 | EAPOL-Announcement (Specific) | announcement-specific |
8 | EAPOL-Announcement-Req | announcement-req |
EAP Codes (cf. IETF RFC 2284) | ||
---|---|---|
Code | Description | Keyword |
1 | EAP-Request | request |
2 | EAP-Response | response |
3 | EAP-Success | success |
4 | EAP-Failure | failure |
Additionally, the keyword all means the same as all nine keywords corresponding to EAPOL Packet Types; i.e. the following:
exec eap "/path/to/script.sh";
exec start "/path/to/script.sh";
…
exec announcement-req "/path/to/script.sh";
filter eap, start, …, announcement-req;
is equivalent to:
exec all "/path/to/script.sh";
filter all;
As to the distinction between EAPOL Packet Types and EAP Codes, it is important to consider that EAP came first. EAPOL is an extension of the earlier EAP protocol that enables EAP to function over LANs.
EAPOL packets have a Packet Type field to distinguish between different sorts of EAPOL packets. A Packet Type of 0, or EAPOL-EAP, indicates that an EAPOL packet encapsulates (contains) an EAP packet. Other Packet Types are reserved for various EAPOL control messages.
In turn, EAP packets themselves have a Code field to distinguish between different sorts of EAP packets.
As explained in "OPTIONS", the script option may be defined in an ingress or egress stanza and has the form:
exec type script-path;
script-path is an absolute and canonical path to a executable binary or script (a text file with "#!interpreter-path" as its first line). Script paths are validated at startup to ensure that peapod's effective user ID has execute permissions on them.
Scripts run in a sanitized environment, but with a number of environment variables set. Depending upon why and when a script is being executed, the environment includes information such as the type of EAPOL packet being proxied, where the packet is in the program's control flow (ingress or egress phase), the interface on which the packet was received or is about to be sent, and the raw packet itself (Base64-encoded). Scripts can therefore do quite a few useful things, from logging failed authentications to saving packets to .pcap files.
Given that scripts run in the background (without an attached terminal), peapod reports nonzero script exit codes to facilitate debugging. It is also possible for scripts to write their own logs, of course.
Packet receipt timestamp.
Format: unixtime.microsecs
Destination and source MAC addresses.
Format: six colon-delimited hexdigit pairs
EAPOL Packet Type and description.
Format: number 0 to 9, text description
Ingress interface (interface on which packet was originally received) and ingress interface MTU.
Base64-encoded raw packet and its length in bytes as received on ingress interface.
Current interface and current interface MTU.
Values same as …_ORIG in ingress phase; will differ in egress phase (i.e. current interface will be an egress interface).
Current Base64-encoded raw packet and its length in bytes.
Values same as …_ORIG in ingress phase; will differ in egress phase if dot1q option is defined on current interface (i.e. current interface is configured to add a missing 802.1Q VLAN tag, or edit/remove an existing one).
EAP Code, description, and EAP Identifier.
Available if the EAPOL packet encapsulates (contains) an EAP packet; EAPOL Packet Type ("PKT_TYPE") is 0.
Format: number 1 to 4, text description, number 1 to 255
EAP-Request/EAP-Response Type and description.
Available if the EAPOL packet encapsulates an EAP-Request or an EAP-Response; EAPOL Packet Type ("PKT_TYPE") is 0 and EAP Code ("PKT_CODE") is 1 or 2.
Format: number 1 to 255, text description
Raw 802.1Q VLAN Tag Control Information as received on ingress interface.
Available if packet was received tagged.
Format: four hexdigits
Current raw 802.1Q VLAN TCI.
Available in ingress phase: if packet was received tagged, value same as …_ORIG; in egress phase: if packet is about to be sent tagged on current interface.
Other environment variables may be available depending on the script interpreter or system-specific runtime factors.
See also the example script env.sh to help determine the exact environment variables available to scripts.
All example config files and scripts mentioned in this section are included in peapod's shared resources in /usr/share/peapod/examples, as well as in the doc/examples subdirectory of the program sources.
This HTML rendition of peapod.conf(5) also has links to the raw files/scripts.
Silently proxy all EAPOL packets between eth0 and eth1.
iface eth0;
iface eth1;
Packets received on a configured interface are proxied to all other configured interfaces, so creating a port mirror for the traffic between two interfaces is as easy as adding a third. We also ensure that any packets that somehow enter on eth2 are not proxied to eth0 and eth1.
iface eth0;
iface eth1;
# External protocol analyzer (e.g. a laptop running WireShark)
iface eth2 {
ingress {
# Do not proxy any EAPOL packets received on eth2
filter all;
};
};
Impersonate a supplicant from the network's point of view. Connectivity on eth0 may be achieved by static IP, gateway, and DHCP assignment.
# Network with an EAPOL authenticator
iface eth0 {
# Manually spoof MAC address of supplicant
set-mac xx:xx:xx:xx:xx:xx;
# Alternative: learn supplicant's MAC address from the first
# EAPOL packet it sends, then clone the address to eth0
# set-mac-from eth1;
};
# Supplicant behind proxy
iface eth1;
Save all EAPOL packets proxied between eth0 and eth1 to a .pcap file.
iface eth0 {
ingress {
# Runs when any EAPOL packet received on eth0
exec all "/path/to/pcap.sh";
};
};
iface eth1 {
ingress {
# Runs when any EAPOL packet received on eth1
exec all "/path/to/pcap.sh";
};
};
Demonstrates more advanced usage. Impersonate a supplicant, also inserting priority tags into its EAPOL packets (authenticator is priority tagging but supplicant isn't; remedy the lack). Run scripts to "borrow" the DHCP assignment intended for supplicant and log any failed authentication attempts.
# Network with an EAPOL authenticator
iface eth0 {
ingress {
# Proxy only EAPOL-EAP (EAP packets) from authenticator
filter start, logoff, key, encapsulated-asf-alert, mka,
announcement-generic, announcement-specific,
announcement-req;
# Runs when EAP-Success received from authenticator
# restartdhcp.sh restarts the system's DHCP client on eth0
exec success "/path/to/restartdhcp.sh";
# Runs when EAP-Failure received
# exec failure "/path/to/logfailure.sh";
};
egress {
# Priority tag all packets leaving eth0 with priority 7
dot1q {
priority 7;
};
};
};
# Supplicant behind proxy
iface eth1 {
ingress {
# Proxy only EAPOL-EAP (EAP packets) from supplicant
# Equivalent ingress filters defined on both interfaces
filter start, logoff, key, encapsulated-asf-alert, mka;
filter announcement-generic, announcement-specific;
filter announcement-req;
};
egress {
# Runs when EAP-Failure sent to supplicant
# logfailure.sh is written so as to ensure that running
# it here as an egress script on eth1 is equivalent to
# running it above as an ingress script on eth0
exec failure "/path/to/logfailure.sh";
};
};
/usr/sbin/peapod
/etc/peapod.conf
/var/log/peapod.log
/var/run/peapod.pid