hostapd Wired 802.1x com Bridge

1

Eu tenho uma APU PCEngines executando o Debian Jessie.

Estou tentando configurar o hostapd para executar a autenticação 802.1x com fio em um controlador de domínio remoto que executa o NPS em 2008 R2.

Eu gostaria que duas de suas portas de rede se juntassem a uma interface de ponte, uma vez autenticadas, que terão nossa sub-rede configurada, o DHCP relay executando & roteador IP com o qual nossos clientes podem conversar.

Após algumas pesquisas, a opção de configuração "bridge" no hostapd parece ser aplicável apenas a determinados drivers WiFi, não ao driver com fio.

Se eu adicionar as portas à bridge na inicialização, mas tiver o hostapd em execução em cada interface, os usuários poderão passar o tráfego e usar as interfaces sem autenticação.

Sem isso, os clientes podem se conectar e autenticar corretamente, mas obviamente não há rede para eles falarem (tentei conectar a opção de configuração, esperando que ela fosse automaticamente associada à ponte, mas isso não ocorre). / p>

Minha configuração do hostapd é a seguinte:

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

Alguém sabe se o que eu estou procurando é possível ou o que estou fazendo de errado?

Editar:

Eu li que o hostapd não implementa a pilha completa do autenticador para o driver "com fio", portanto não pode ser usado para proteger uma porta com o 802.1x pronto para uso.

Eu também li que deveria ser possível usar a interface de controle para ouvir eventos, então use um programa externo para controlar a ponte.

Eu fiz isso e ele funciona inicialmente, mas após cerca de 3 minutos os clientes sempre são desconectados. Está logado no syslog como devido à inatividade.

Mesmo assim, incluirei meu código CGo abaixo:

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("
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
0") 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) }
    
por iamacarpet 13.06.2016 / 17:23

0 respostas