802.1X Authentication on Wired Networks

CESNET technical report number 37/2007
also available in PDF, PostScript, and XML formats.

Roškot Stanislav, Cejp Jiří
9.12.2007

1   Abstract

This report briefly describes how to use the IEEE 802.1X authentication protocol on wired networks. It points out the differences between configuration of wireless and wired networks.

2   Introduction

The IEEE 802.1x standard defines a client-server based access control and authentication protocol that prevents unauthorized clients from connecting to a LAN through publicly accessible ports unless they are properly authenticated. The authentication server authenticates each client connected to a switch port before making available any services offered by the switch or the LAN. To provide a standard authentication mechanism for IEEE 802.1X, IEEE uses the Extensible Authentication Protocol (EAP). EAP messages were originally defined for PPP frames. The IEEE 802.1X standard defines EAP over LAN (EAPOL), which is a method of encapsulating EAP messages so that they can be sent over Ethernet or wireless LAN.

This authentication mechanism is used for example by eduroam project.

The most of educational institutions use Cisco network devices and Freeradius RADIUS servers. This is the reason, why we explain their configuration.

3   The IEEE 802.1x on a switch

3.1   Device roles

[Figure]

Figure 1: Device roles

3.2   Authentication process

3.3   VLAN assignment

When configured on the switch and on the RADIUS server, VLAN assignment works as follows:

The IEEE 802.1x authentication with VLAN assignment feature is not supported on trunk ports, dynamic ports, or with dynamic-access port assignment through a VLAN Membership Policy Server (VMPS). If we want to use RADIUS server VLAN assignment, server must return these attributes:

Tunnel-Type = VLAN
Tunnel-Medium-Type = 802
Tunnel-Private-Group-ID = VLAN ID 

3.4   Configuring

The following commands enable a RADIUS authentication and specify the RADIUS server:

aaa new-model
aaa authentication dot1x default group radius
dot1x system-auth-control
radius-server host 192.168.193.7 auth-port 1812 acct-port 1813 key XXXX
      

To enable RADIUS server supplied VLAN assignment:

aaa authorization network default group radius
      

To enable accounting, the switch sends an accounting information to the RADIUS server.

aaa accounting dot1x default start-stop group radius 
      

Example configuration of a single port:

interface GigabitEthernet0/1
 switchport mode access
 dot1x pae authenticator
 dot1x port-control auto
 dot1x timeout quiet-period 3
 dot1x timeout tx-period 15
 dot1x guest-vlan 135
 dot1x auth-fail vlan 134
 dot1x auth-fail max-attempts 2 
      

The dot1x timeout tx-period command sets the number of seconds that the switch waits for a response to an EAP-request from the client before resending the request. If the authentication fails, the switch remains in idle state and then tries to authenticate the user again. The dot1x timeout quiet-period command sets the idle period. The auth-fail vlan command specifies the restricted VLAN ID. The auth-fail max-attempts command sets the count of authentication attempts. The guest-vlan command is supported by IOS version 12.2(25)SEE and later.

4   Freeradius

The configuration of a Freeradius server for wired networks is the same as for wireless ones [as05]. However, Cisco switches use IOS 12.2.x, whereas APs use version 12.3.x or even 13.4.x. These versions work slightly differently and cause a problem in the accounting. While the AP generates the attribute Acct-Session-Id as an 8 character hash, the switch generates it as a long string, consisting of the ip address, username, date, time and sequence number. It may look as follows:

"192.168.193.125 novak99@fel.cvut.cz 12/09/07 11:53:25 00000001"

Freeradius stores accounting data in a flat file, but it can additionally insert them into mysql database. How it works?

When the RADIUS server receives an accounting packet contaning the attribute Acct-Status-Type=1 (session start)from NAS, it inserts the new row into the radacct DB table.:

INSERT into ${acct_table1} (AcctSessionId, 
                            AcctUniqueId, 
                            UserName, 
                            Realm, 
                            NASIPAddress, 
                            NASPortId,
                            NASPortType, 
                            AcctStartTime, 
                            AcctStopTime, 
                            AcctSessionTime,
                            AcctAuthentic,
                            ConnectInfo_start,
                            ConnectInfo_stop, 
                            AcctInputOctets, 
                            AcctOutputOctets, 
                            CalledStationId, 
                            CallingStationId, 
                            AcctTerminateCause, 
                            ServiceType, 
                            FramedProtocol, 
                            FramedIPAddress, 
                            AcctStartDelay, 
                            AcctStopDelay) 
                     values('%{Acct-Session-Id}', 
                           '%{Acct-Unique-Session-Id}', 
                           '%{SQL-User-Name}', 
                           '%{Realm}', 
                           '%{NAS-IP-Address}', 
                           '%{NAS-Port}', 
                           '%{NAS-Port-Type}', 
                           '%S', 
                           '0', 
                           '0', 
                           '%{Acct-Authentic}', 
                           '%{Connect-Info}', 
                           '', 
                           '0', 
                           '0', 
                           '%{Called-Station-Id}', 
                           '%{Calling-Station-Id}', 
                           '', 
                           '%{Service-Type}', 
                           '%{Framed-Protocol}', 
                           '%{Framed-IP-Address}', 
                           '%{Acct-Delay-Time}', 
                           '0');

It is obvious, that the attributes, that are not known at this moment, have a value of 0 or an empty string, depending on their type.

When the RADIUS server receives an accounting packet contaning the attribute Acct-Status-Type=2 (session stop), it invokes the statement:

UPDATE ${acct_table1} 
          SET FramedIPAddress = '%{Framed-IP-Address}', 
              AcctSessionTime = '%{Acct-Session-Time}', 
              AcctInputOctets = '%{Acct-Input-Octets}', 
              AcctOutputOctets = '%{Acct-Output-Octets}' 
          WHERE AcctSessionId = '%{Acct-Session-Id}' 
              AND UserName = '%{SQL-User-Name}' 
              AND NASIPAddress= '%{NAS-IP-Address}'

If this statement fails, an alternate statement is invoked:

INSERT into ${acct_table1} (AcctSessionId, 
                            AcctUniqueId, 
                            UserName, 
                            Realm, 
                            NASIPAddress, 
                            NASPortId,
                            NASPortType, 
                            AcctStartTime, 
                            AcctStopTime, 
                            AcctSessionTime,
                            AcctAuthentic,
                            ConnectInfo_start,
                            ConnectInfo_stop, 
                            AcctInputOctets, 
                            AcctOutputOctets, 
                            CalledStationId, 
                            CallingStationId, 
                            AcctTerminateCause, 
                            ServiceType, 
                            FramedProtocol, 
                            FramedIPAddress, 
                            AcctStartDelay, 
                            AcctStopDelay) 
                     values('%{Acct-Session-Id}', 
                           '%{Acct-Unique-Session-Id}', 
                           '%{SQL-User-Name}', 
                           '%{Realm}', 
                           '%{NAS-IP-Address}', 
                           '%{NAS-Port}', 
                           '%{NAS-Port-Type}', 
                           DATE_SUB('%S', INTERVAL (%{Acct-Session-Time:-0} 
                                       + %{Acct-Delay-Time:-0}) SECOND), 
                           '%S', 
                           '%{Acct-Session-Time}'
                           '%{Acct-Authentic}', 
                           '', 
                           '%{Connect-Info}', 
                           '%{Acct-Input-Octets}', 
                           '%{Acct-Output-Octets}', 
                           '%{Called-Station-Id}', 
                           '%{Calling-Station-Id}', 
                           '%{Acct-Terminate-Cause}'
                           '%{Service-Type}', 
                           '%{Framed-Protocol}', 
                           '%{Framed-IP-Address}',
                           '0', 
                           '%{Acct-Delay-Time}';

All sql statements are defined as variables in the sql.conf configuration file.

The problem is caused by the fact, that the length of the corresponding column in the database table is only 32 characters. The length of the Acct-Session-Id attribute value therefore exceeds the length of the AcctSessionId column in the database table. The insert statement stores only the first 32 characters of that value. The update statement then fails, because it uses the original Acct-Session-Id value. The new row is inserted instead. That means, that there are two rows for each session. The first one misses attributes such as AcctStopTime, so the session looks unfinished. The second one is complete. To solve this problem, we need to increase the length of the column:

mysql -u root radius
alter table radacct modify AcctSessionId varchar(80) not null;
      

Another way is to modify the accounting_stop_query variable (containing the update statement), placed in the sql.conf file. Whe need to change the where clause of the statement:

where  AcctUniqueId='%{Acct-Unique-Session-Id}'

If we want to allow wired connection for local users only, and wireless connection for both local and guest users, we should add the following line to the users file:

DEFAULT Realm!="fel.cvut.cz", NAS-Port-Type=="Ethernet", Auth-Type:=Reject
      

5   Client configuration

5.1   Windows

Configuring is the same as in case of wireless networks. The only difference is, that we configure directly a network interface instead of SSIDs.

5.2   Linux - wpa_supplicant

The configuration file might look as follows:

ctrl_interface=/var/run/wpa_supplicant
network={
        key_mgmt=WPA-EAP
        eap=PEAP
        pairwise=CCMP TKIP
        group=CCMP TKIP
        identity="novakj99@fel.cvut.cz"
        password="xxxx"
        ca_cert="/etc/ssl/certs/cesnet-ca.cz.pem.crt"
        phase1="peaplabel=0"
        phase2="auth=MSCHAPV2"
}

Then we invoke the command:

# wpa_supplicant -Dwired -ieth0 -c/etc/wpa_supplicant.conf

If we use Debian, we simply insert the following lines into the /etc/network/interfaces file.

iface eth0 inet dhcp
        wpa-driver wired
        wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

6   Conclusion

The IEEE 802.1x authentication provides a protection of freely accessible network sockets (located in corridors or halls) against unauthorized access to the LAN. It is also useful for granting guest user access during conferences or workshops. While the local users authenticate through 802.1x and get full access to the network, the guest users are assigned a restricted VLAN with an access to the Internet.

These scenarios were tested and are used at Czech Technical University, Faculty of Electrical Engineering.

References

[as05] Adamec P., Satrapa P.: Konfigurace lokální sítě připojené k eduroam.cz. Technical report 5/2005. CESNET, 2005.
další weby:fond rozvojemetacentrumCzechLightpřenosyvideoservereduroameduID.cz