Last active
September 28, 2017 20:18
-
-
Save gizmoguy/085a13bbdb4aa61675c409c294385f74 to your computer and use it in GitHub Desktop.
Reconfigure FAUCET configuration based on hostapd events, more information here: https://faucet-sdn.blogspot.co.nz/2016/07/8021x-authentication-on-faucet-nfv.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: 2 | |
acls: | |
eapoll_offload: | |
# Send EAP over LAN packets towards hostapd port | |
- rule: | |
dl_type: 0x888e # EAP over LAN | |
actions: | |
output: | |
vlan_vid: 10 | |
port: 7 | |
# Allow other protocols | |
- rule: | |
actions: | |
allow: 1 | |
vlans: | |
untrusted: | |
name: "untrusted" | |
description: "client untrusted network" | |
vid: 10 | |
wan: | |
name: "wan" | |
description: "wan vlan" | |
vid: 20 | |
dps: | |
at-x230-1: | |
description: at-x230-1 | |
dp_id: 115621608155 | |
hardware: Allied-Telesis | |
interfaces: | |
1: | |
acl_in: eapoll_offload | |
max_hosts: 1 | |
name: port1.0.1 | |
native_vlan: untrusted | |
permanent_learn: true | |
2: | |
acl_in: eapoll_offload | |
max_hosts: 1 | |
name: port1.0.2 | |
native_vlan: untrusted | |
permanent_learn: true | |
3: | |
acl_in: eapoll_offload | |
max_hosts: 1 | |
name: port1.0.3 | |
native_vlan: untrusted | |
permanent_learn: true | |
4: | |
acl_in: eapoll_offload | |
max_hosts: 1 | |
name: port1.0.4 | |
native_vlan: untrusted | |
permanent_learn: true | |
5: | |
acl_in: eapoll_offload | |
max_hosts: 1 | |
name: port1.0.5 | |
native_vlan: untrusted | |
permanent_learn: true | |
6: | |
name: wan | |
native_vlan: wan | |
permanent_learn: true | |
7: | |
name: nfv | |
native_vlan: wan | |
permanent_learn: true | |
tagged_vlans: | |
- untrusted |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import fcntl | |
import logging | |
import os | |
import re | |
import requests | |
import subprocess | |
import time | |
import yaml | |
# which vlans shall we configure when we authenticate/deauthenticate clients? | |
UNTRUSTED_VLAN = 'untrusted' | |
TRUSTED_VLAN = 'wan' | |
faucet_config = '/etc/ryu/faucet/faucet.yaml' | |
prometheus_host = 'http://localhost:9090' | |
log_file = '/var/log/hostapd-trigger.log' | |
hostapd_cli = subprocess.Popen( | |
['/usr/sbin/hostapd_cli', '-p', '/var/run/hostapd'], | |
stdin=subprocess.PIPE, | |
stdout=subprocess.PIPE, | |
shell=True) | |
fcntl.fcntl(hostapd_cli.stdout, fcntl.F_SETFL, os.O_NONBLOCK) | |
logging.basicConfig(filename=log_file,level=logging.DEBUG) | |
def change_port_vlan(dpid, port, vlan): | |
try: | |
with open(faucet_config, 'r') as stream: | |
conf = yaml.safe_load(stream) | |
except yaml.YAMLError as ex: | |
logging.error('Error in file %s (%s)', config_file, str(ex)) | |
return None | |
config_changed = False | |
for key, dp_config in conf['dps'].iteritems(): | |
if dp_config['dp_id'] != dpid: | |
continue | |
if dp_config['interfaces'][port]['native_vlan'] == vlan: | |
continue | |
dp_config['interfaces'][port]['native_vlan'] = vlan | |
config_changed = True | |
if config_changed: | |
with open(faucet_config, 'w') as stream: | |
yaml.dump(conf, stream, default_flow_style=False) | |
os.system("pkill -HUP ryu-manager") | |
else: | |
logging.error('no config changes required in faucet.yaml') | |
def promote_port(dpid, port): | |
change_port_vlan(dpid, port, TRUSTED_VLAN) | |
def demote_port(dpid, port): | |
change_port_vlan(dpid, port, UNTRUSTED_VLAN) | |
def mac_lookup(mac): | |
mac_int = int(mac.replace(':', ''), 16) | |
api_query = {"query": "learned_macs == %s" % mac_int} | |
r = requests.get('%s/api/v1/query' % prometheus_host, params=api_query) | |
interfaces = [] | |
if r.status_code == requests.codes.ok: | |
response = r.json() | |
for metric in response['data']['result']: | |
interface = metric['metric'] | |
interfaces.append({ | |
'dpid': int(interface['dpid'], 16), | |
'port': int(interface['port']), | |
'vlan': interface['vlan'] | |
}) | |
return interfaces | |
while True: | |
hostapi_log = '' | |
try: | |
hostapi_log = hostapd_cli.stdout.readline() | |
except IOError: | |
pass | |
status_change = False | |
# was a MAC authenticated or de-authenticated | |
if hostapi_log: | |
connected_m = re.search('AP-STA-CONNECTED (\S+)', hostapi_log) | |
disconnected_m = re.search('AP-STA-DISCONNECTED (\S+)', hostapi_log) | |
if connected_m: | |
mac = connected_m.group(1) | |
logging.info('mac %s authenticated', mac) | |
for interface in mac_lookup(mac): | |
logging.info('promoting port %s on dpid %s from vlan %s to %s', | |
interface['port'], interface['dpid'], interface['vlan'], TRUSTED_VLAN) | |
promote_port(interface['dpid'], interface['port']) | |
elif disconnected_m: | |
mac = disconnected_m.group(1) | |
logging.info('mac %s not authenticated', mac) | |
for interface in mac_lookup(mac): | |
logging.info('demoting port %s on dpid %s from vlan %s to %s', | |
interface['port'], interface['dpid'], interface['vlan'], UNTRUSTED_VLAN) | |
demote_port(interface['dpid'], interface['port']) | |
else: | |
time.sleep(0.5) | |
hostapd_cli.stdin.write('\n') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface=enp1s0.10 | |
driver=wired | |
logger_stdout=-1 | |
logger_stdout_level=2 | |
ieee8021x=1 | |
skip_inactivity_poll=1 | |
ap_max_inactivity=3600 | |
eap_reauth_period=3600 | |
eap_server=0 | |
eapol_version=1 | |
own_ip_addr=127.0.0.1 | |
auth_server_addr=127.0.0.1 | |
auth_server_port=1812 | |
auth_server_shared_secret=testing123 | |
ctrl_interface=/var/run/hostapd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment