有线802.1x与桥

我有一台运行Debian Jessie的PCEngines APU。

我试图configurationhostapd对2008 R2上运行NPS的远程域控制器执行有线802.1xauthentication。

我希望有2个networking端口join一个网桥接口,一旦validation,将有我们的子网configuration,DHCP中继运行和路由器IP我们的客户可以谈。

经过一番挖掘,hostapd中的“桥”configuration选项似乎只适用于某些WiFi驱动程序,而不是有线驱动程序。

如果在启动时将端口添加到网桥,但在每个接口上运行hostapd,则用户可以在不通过身份validation的情况下传输stream量并使用接口。

如果没有这样做,客户端可以正确连接和authentication,但显然没有networking让他们交谈(我试图桥接configuration选项,希望它会自动join桥梁,但它不)。

我的hostapdconfiguration如下:

interface=eth1 driver=wired ieee8021x=1 use_pae_group_addr=1 eap_reauth_period=3600 eapol_version=2 # RADIUS authentication server auth_server_addr=**secret** auth_server_port=1812 auth_server_shared_secret=**secret** # RADIUS accounting server acct_server_addr=**secret** acct_server_port=1813 acct_server_shared_secret=**secret** logger_syslog=-1 logger_syslog_level=2 

有谁知道我以后是否有可能,或者我做错了什么?

编辑:

我读了hostapd没有实现“有线”驱动程序的完整身份validation堆栈,所以不能用来保护开箱即用的802.1x端口。

我也读过它应该可以使用控制界面来监听事件,然后使用外部程序来控制桥。

我做到了这一点,它起初工作,但大约3分钟后,客户端总是断开连接。 它由于不活动而被logging在syslog中。

即使如此,我将在下面包含我的CGo代码:

 package main /* #cgo CFLAGS: -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX #include <stdlib.h> #include <stdio.h> #include <string.h> #include "libbridge.h" #include "wpa_ctrl.h" */ import "C" import "unsafe" import "fmt" import "time" import "strings" var briface string = "br0" var auiface string = "eth1" var hostapd_path string = "/var/run/hostapd/" var connected bool var current_mac string var wpa_ctl *C.struct_wpa_ctrl func main() { br_del() hostapd_connect() defer func(){ if wpa_ctl != nil { C.wpa_ctrl_detach(wpa_ctl) C.wpa_ctrl_close(wpa_ctl) } }() for { for C.wpa_ctrl_pending(wpa_ctl) > 0 { log(fmt.Sprintf("Reading message from hostapd...")) var buf [256]C.char var llen C.size_t = C.size_t(unsafe.Sizeof(buf) - 1) if C.wpa_ctrl_recv(wpa_ctl, &buf[0], &llen) == 0 { null := C.CString("\000") buf[llen] = *null C.free(unsafe.Pointer(null)) //fmt.Printf("%s\n", C.GoString(&buf[0])) msg := C.GoString(&buf[0]) mData := strings.Split(msg, " ") if len(mData) < 2 { log(fmt.Sprintf("Event data too short when processing message: %s", msg)) continue } switch (mData[0]){ case "<3>AP-STA-CONNECTED": log(fmt.Sprintf("Got Device Authentication, adding to bridge...")) br_add() connected = true current_mac = mData[1] case "<3>AP-STA-DISCONNECTED": log(fmt.Sprintf("Got Device Disconnect, removing from bridge...")) br_del() connected = false case "<3>CTRL-EVENT-EAP-STARTED": if connected { if mData[1] != current_mac { log(fmt.Sprintf("Got active MAC different from current MAC. %s vs %s - Disconnecting current.", mData[1], current_mac)) hostapd_disconnect(current_mac) } } } } else { break } } if ! hostapd_ping() { C.wpa_ctrl_detach(wpa_ctl) C.wpa_ctrl_close(wpa_ctl) log(fmt.Sprintf("Lost connection to hostapd, reconnecting...")) hostapd_connect() } time.Sleep(time.Millisecond * 100) } } func hostapd_connect(){ ci := C.CString(hostapd_path + auiface) defer C.free(unsafe.Pointer(ci)) for { wpa_ctl = C.wpa_ctrl_open(ci) if wpa_ctl != nil { log(fmt.Sprintf("Connected to hostapd OK, attach...")) if C.wpa_ctrl_attach(wpa_ctl) == 0 { log(fmt.Sprintf("Attached event listener...")) break } else { fmt.Printf("Failed to attach to event listener.") C.wpa_ctrl_close(wpa_ctl) } } else { log(fmt.Sprintf("Failed to connect to hostapd control socket, waiting for retry...")) } time.Sleep(time.Millisecond * 100) } } func hostapd_disconnect(mac string){ ci := C.CString(hostapd_path + auiface) defer C.free(unsafe.Pointer(ci)) dc := C.wpa_ctrl_open(ci) if dc == nil { log(fmt.Sprintf("Error opening connection to disconnect current station.")) return } defer C.wpa_ctrl_close(dc) var buf [4096]C.char var len C.size_t = C.size_t(unsafe.Sizeof(buf) - 1) cping := C.CString("deauthenticate " + mac) defer C.free(unsafe.Pointer(cping)) ret := C.wpa_ctrl_request(dc, cping, C.strlen(cping), &buf[0], &len, nil) if (ret == -2) { log(fmt.Sprintf("Station disconnect failed with timeout...")) } else if (ret < 0) { log(fmt.Sprintf("Station disconnect failed...")) } log(fmt.Sprintf("Station disconnect requested.")) } func hostapd_ping() (bool) { var buf [4096]C.char var len C.size_t = C.size_t(unsafe.Sizeof(buf) - 1) cping := C.CString("PING") defer C.free(unsafe.Pointer(cping)) ret := C.wpa_ctrl_request(wpa_ctl, cping, C.strlen(cping), &buf[0], &len, nil) if (ret == -2) { log(fmt.Sprintf("PING failed with timeout...")) return false } else if (ret < 0) { log(fmt.Sprintf("PING failed...")) return false } return true } func br_add(){ br := C.CString(briface) defer C.free(unsafe.Pointer(br)) ifa := C.CString(auiface) defer C.free(unsafe.Pointer(ifa)) if ( C.br_init() > 0 ) { log(fmt.Sprintf("Can't setup bridge control in br_add. Failed to add interface to bridge.")) return } ret := C.br_add_interface(br, ifa) if ret > 0 { log(fmt.Sprintf("Failed to add interface to bridge, error code: %d", ret)) return } } func br_del(){ br := C.CString(briface) defer C.free(unsafe.Pointer(br)) ifa := C.CString(auiface) defer C.free(unsafe.Pointer(ifa)) if ( C.br_init() > 0 ) { log(fmt.Sprintf("Can't setup bridge control in br_del. Failed to remove interface from bridge.")) return } ret := C.br_del_interface(br, ifa) if ret > 0 { log(fmt.Sprintf("Failed to remove interface from bridge, error code: %d", ret)) return } } func log(data string) { fmt.Printf("%s\n", data) }