Hi,
After a lot of troubleshooting I got the deauthentication to work. I wasn't
able to get it to work using the whole module you made, nor the $SNMP::HTTP so
I had to "cheat" and re-use $SNMP::SSH.
I'm still hard-coding the controller IP and stuff like that, but the client is
being deauthenticated which is great!
Any recommendations on how I can make this script "PacketFence best practice"?
Next step is to get the authentication between the two to work, but I think it
will be enough with some kind of redirect that sends the controller a POST. How
did you solve that part?
See below for the script:
--
[root@PacketFence-ZEN-5-3 HP]# cat Controller_MSM710.pm
package pf::Switch::HP::Controller_MSM710;
=head1 NAME
pf::Switch::HP::Controller_MSM710
=head1 SYNOPSIS
The pf::Switch::HP::Controller_MSM710 module manages access to HP Procurve
Controller MSM710
=head1 STATUS
Should work on all HP Wireless E series
Developed and tested on HP MSM 710 running firmware version 5.4.1.0
=head1 BUGS AND LIMITATIONS
Firmware version 5.5.2.14 and 5.5.3 are known to have problematic
deauthentication. Firmware version 5.7.0 also
presents some issues, the SNMP deauthentication is not working.
=cut
use strict;
use warnings;
use Log::Log4perl;
use POSIX;
use base ('pf::Switch');
use pf::constants;
use pf::config;
sub description { 'HP ProCurve MSM710 Mobility Controller' }
# importing switch constants
use pf::Switch::constants;
use pf::util;
use Net::Appliance::Session;
use pf::accounting qw(node_accounting_current_sessionid);
=head1 SUBROUTINES
=over
=cut
# CAPABILITIES
# access technology supported
sub supportsWirelessDot1x { return $TRUE; }
sub supportsWirelessMacAuth { return $TRUE; }
# inline capabilities
sub inlineCapabilities { return ($MAC,$SSID); }
=item getVersion - obtain image version information from switch
=cut
sub getVersion {
my ($this) = @_;
my $oid_sysDescr = '1.3.6.1.2.1.1.1.0'; #SNMPv2-MIB
my $logger = Log::Log4perl::get_logger( ref($this) );
if ( !$this->connectRead() ) {
return '';
}
$logger->trace("SNMP get_request for sysDescr: $oid_sysDescr");
my $result = $this->{_sessionRead}->get_request( -varbindlist =>
[$oid_sysDescr] );
my $sysDescr = ( $result->{$oid_sysDescr} || '' );
if ( $sysDescr =~ m/V(\d{1}\.\d{2}\.\d{2})/ ) {
return $1;
} elsif ( $sysDescr =~ m/Version (\d+\.\d+\([^)]+\)[^,\s]*)(,|\s)+/ ) {
return $1;
} else {
return $sysDescr;
}
}
=item parseTrap - interpret traps and populate a trap hash
=cut
sub parseTrap {
my ( $this, $trapString ) = @_;
my $trapHashRef;
my $logger = Log::Log4perl::get_logger( ref($this) );
# COLUBRIS-DEVICE-EVENT-MIB :: coDeviceEventSuccessfulDeAuthentication ::
1.3.6.1.4.1.8744.5.26.2.0.9
# COLUBRIS-DEVICE-EVENT-MIB :: coDevEvDetMacAddress ::
1.3.6.1.4.1.8744.5.26.1.2.2.1.2
if ( $trapString =~
/\.1\.3\.6\.1\.4\.1\.8744\.5\.26\.2\.0\.9[|]\.1\.3\.6\.1\.4\.1\.8744\.5\.26\.1\.2\.2\.1\.2.+$SNMP::MAC_ADDRESS_FORMAT/
) {
$trapHashRef->{'trapType'} = 'dot11Deauthentication';
$trapHashRef->{'trapMac'} = parse_mac_from_trap($1);
} else {
$logger->debug("trap currently not handled");
$trapHashRef->{'trapType'} = 'unknown';
}
return $trapHashRef;
}
=item deauthenticateMacDefault - deauthenticate a MAC address from wireless
network (including 802.1x) through SNMP
=cut
sub deauthenticateMacDefault {
my ($this, $mac) = @_;
my $logger = Log::Log4perl::get_logger(ref($this));
my $OID_coDevWirCliStaMACAddress = '1.3.6.1.4.1.8744.5.25.1.7.1.1.2'; #
from COLUBRIS-DEVICE-WIRELESS-MIB
my $OID_coDevWirCliDisassociate = '1.3.6.1.4.1.8744.5.25.1.7.1.1.27'; #
from COLUBRIS-DEVICE-WIRELESS-MIB
# handles if deauth should be performed against controller or actual
device. Returns sessionWrite hash key to use.
my $performDeauthOn = $this->getDeauthSnmpConnectionKey();
if ( !defined($performDeauthOn) ) {
return;
}
# Query the controller to get the index of the MAc in the
coDeviceWirelessClientStatusTable
# CAUTION: we need to use the sessionWrite in order to have access to that
table
$logger->trace("SNMP get_table for coDevWirCliStaMACAddress:
$OID_coDevWirCliStaMACAddress");
my $result = $this->{$performDeauthOn}->get_table(-baseoid =>
"$OID_coDevWirCliStaMACAddress");
if (keys %{$result}) {
my $count = 0;
foreach my $key ( keys %{$result} ) {
$result->{$key} =~
/0x([A-Z0-9]{2})([A-Z0-9]{2})([A-Z0-9]{2})([A-Z0-9]{2})([A-Z0-9]{2})([A-Z0-9]{2})/i;
my $coDevWirCliStaMACAddress = "$1:$2:$3:$4:$5:$6";
if ($coDevWirCliStaMACAddress eq $mac) {
$key =~ /^$OID_coDevWirCliStaMACAddress\.(\d+).(\d+).(\d+)$/;
my $coDevWirCliStaIndex = "$1.$2.$3";
$logger->debug("deauthenticating $mac on controller " .
$this->{$performDeauthOn}->hostname());
$logger->trace("SNMP set_request for coDevWirCliDisassociate: "
. "$OID_coDevWirCliDisassociate.$coDevWirCliStaIndex =
$HP::DISASSOCIATE"
);
$result = $this->{$performDeauthOn}->set_request(-varbindlist
=> [
"$OID_coDevWirCliDisassociate.$coDevWirCliStaIndex",
Net::SNMP::INTEGER, $HP::DISASSOCIATE
]);
$count++;
last;
}
}
$logger->warn("Can't deauthenticate $mac on controller $this->{_ip}
because it does not seem to be associated!")
if ($count == 0);
} else {
$logger->error("Can not get the list of associated devices on
controller " . $this->{_ip});
}
}
=item extractSsid
Find RADIUS SSID parameter out of RADIUS REQUEST parameters
HP / Colubris specific parser. See pf::Switch for base implementation.
=cut
sub extractSsid {
my ($this, $radius_request) = @_;
my $logger = Log::Log4perl::get_logger(ref($this));
if (defined($radius_request->{'Colubris-AVPair'})) {
# With HP Procurve AP Ccontroller, we receive an array of settings in
Colubris-AVPair:
# Colubris-AVPair = ssid=Inv_Controller
# Colubris-AVPair = group=Default Group
# Colubris-AVPair = phytype=IEEE802dot11g
foreach (@{$radius_request->{'Colubris-AVPair'}}) {
if (/^ssid=(.*)$/) { return $1; }
}
$logger->info("Unable to extract SSID of Colubris-AVPair:
".@{$radius_request->{'Colubris-AVPair'}});
}
$logger->warn(
"Unable to extract SSID for module " . ref($this) . ". SSID-based VLAN
assignments won't work. "
. "Please let us know so we can add support for it."
);
return;
}
=item _deauthenticateMacWithSSH
Method to deauthenticate a node with SSH
=cut
sub _deauthenticateMacWithSSH {
my ( $this, $mac ) = @_;
my $logger = Log::Log4perl::get_logger( ref($this) );
my $session;
my @addition_ops;
if (defined $this->{_controllerPort} && $this->{_cliTransport} eq 'SSH' ) {
@addition_ops = (
connect_options => {
ops => [ '-p' => $this->{_controllerPort} ]
}
);
}
eval {
$session = Net::Appliance::Session->new(
Host => $this->{_controllerIp},
Timeout => 20,
Transport => $this->{_cliTransport},
Platform => 'HP',
Source => $lib_dir.'/pf/Switch/HP/nas-pb.yml',
@addition_ops
);
$session->connect(
Name => $this->{_cliUser},
Password => $this->{_cliPwd}
);
};
if ($@) {
$logger->error( "ERROR: Can not connect to controller
$this->{'_controllerIp'} using "
. $this->{_cliTransport} );
return 1;
}
$session->cmd("enable");
$session->cmd("disassociate controlled-ap wireless client $mac");
$session->close();
return 1;
}
=item _deauthenticateMacWithSOAP
Method to deauthenticate a MAC with a SOAP Call.
Requires the SOAP API to be enabled on the MSM controller.
=cut
sub _deauthenticateMacWithSOAP {
my ( $this, $mac ) = @_;
my $logger = Log::Log4perl::get_logger( ref($this) );
$logger->info("Deauthenticating $mac with SOAP call");
my $sessionid = node_accounting_current_sessionid($mac);
$logger->debug("Session ID: $sessionid");
my $postdata
= qq(<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://www.procurve_mobility_msm.com/SOAP/API/1.7/">
<soapenv:Header/>
<soapenv:Body>
<ns:ExecuteNOCLogout>
<ns:sessionID>$sessionid</ns:sessionID>
</ns:ExecuteNOCLogout>
</soapenv:Body>
</soapenv:Envelope>
);
my $HP_default_port = 448;
my $soap_port = $this->{'_wsPort'} || $HP_default_port;
my $authentication = '';
if ( $this->{'_wsUser'} and $this->{'_wsPwd'} ) {
$authentication = $this->{'_wsUser'} . ':' . $this->{'_wsPwd'} . '@';
}
use WWW::Curl::Easy;
my ( $curl_return_code, $curl_info );
# until there is a way to find out on which controller a device associated,
we have to
# try every controller in turn until we find one that returns an http 200.
my $controller = $this->{_controllerIp};
$logger->info("Attempting deauthentication on controller at $controller");
my $curl = WWW::Curl::Easy->new;
# my $url = $this->{'_wsTransport'} . '://' . $authentication .
$this->{_controllerIp} . ':' . $soap_port;
my $url = "http://10.81.0.33:448";
my $response_body = '';
open(my $fileb, ">", \$response_body);
$curl->setopt(CURLOPT_URL, $url );
$curl->setopt(CURLOPT_SSL_VERIFYPEER, 0) if $this->{'_wsTransport'} eq
'https'; # do not validate MSM certificate
$curl->setopt(CURLOPT_HEADER, 1);
$curl->setopt(CURLOPT_POSTFIELDS, $postdata);
$curl->setopt(CURLOPT_WRITEDATA,$fileb);
$curl_return_code = $curl->perform;
$curl_info = $curl->getinfo(CURLINFO_HTTP_CODE); # or
CURLINFO_RESPONSE_CODE depending on libcurl version
if ( $curl_return_code != 0 or $curl_info != 200 ) {
$logger->debug("Deauthentication failed for mac $mac on $url");
$logger->debug("This is probably normal on a cluster.");
$logger->debug("$response_body");
}
else {
$logger->info("Device $mac deauthenticated on $url");
}
return $curl_return_code;
}
=item deauthTechniques
Return the reference to the deauth technique or the default deauth technique.
=cut
sub deauthTechniques {
my ($this, $method) = @_;
my $logger = Log::Log4perl::get_logger( ref($this) );
my $default = $SNMP::SNMP;
my %tech = (
$SNMP::SNMP => '_deauthenticateMacDefault',
# $SNMP::SSH => '_deauthenticateMacWithSSH',
$SNMP::SSH => '_deauthenticateMacWithSOAP',
);
if (!defined($method) || !defined($tech{$method})) {
$method = $default;
}
return $method,$tech{$method};
}
=back
=head1 AUTHOR
Inverse inc. <[email protected]>
=head1 COPYRIGHT
Copyright (C) 2005-2015 Inverse inc.
=head1 LICENSE
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
=cut
1;
# vim: set shiftwidth=4:
# vim: set expandtab:
# vim: set backspace=indent,eol,start:
--
Best Regards,
Simon Gottschlag
From: Simon Gottschlag
Sent: den 25 september 2015 18:14
To: [email protected]
Subject: RE: [PacketFence-users] Soap deauthentication with HP MSM760
Hi,
This is great! I'll go ahead and try it right away.
I've got one client on the network right now, so isn't a load issue (most
likely).
I'll get back to you in a 30min.
Best Regards,
Simon Gottschlag
From: Louis Munro [mailto:[email protected]]
Sent: den 25 september 2015 18:05
To:
[email protected]<mailto:[email protected]>
Subject: Re: [PacketFence-users] Soap deauthentication with HP MSM760
Hi Simon,
The HP controllers are known to have issues with disconnection when under load,
regardless of the method used to disconnect.
We have been working with some clients for years on these issues.
When the load is sufficiently high the controller may simply stop to respond to
disconnections whether they are called over RADIUS, ssh, SOAP or SNMP.
That said, I have implemented a _deauthenticateMacWithSOAP for the MSM710 a
while ago (more than two years).
Since it did not really fix the problem (because the issue really is with the
controller and not the deauth method) and it was a bit of a hack, this code
never made it into the PF release.
You can still have a look and see if it could be useful to you:
https://github.com/louismunro/packetfence/blob/feature/MSM_Controller/lib/pf/SNMP/HP/Cluster_MSM710.pm
Best regards,
--
Louis Munro
[email protected]<mailto:[email protected]> ::
www.inverse.ca<http://www.inverse.ca>
+1.514.447.4918 x125 :: +1 (866) 353-6153 x125
Inverse inc. :: Leaders behind SOGo (www.sogo.nu<http://www.sogo.nu>) and
PacketFence (www.packetfence.org<http://www.packetfence.org>)
On Sep 25, 2015, at 11:36 , Simon Gottschlag
<[email protected]<mailto:[email protected]>> wrote:
Hi!
I've been struggling with integrating HP MSM760 with PacketFence. I'm using the
latest version of both and seems like the deauthentication doesn't work. I've
seen a few other threads where they've been having the same problem.
I've figured out an easy way to deauthenticate the user using SOAP manually,
but need some help to understand how I can get it to work automatically when a
user gets a violation etc.
I've been able to write a perl script that does it for me.
Logoff / deauthentication:
--
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
my $userAgent = LWP::UserAgent->new(agent => 'perl post');
my $message = "<x:Envelope
xmlns:x=\"http://schemas.xmlsoap.org/soap/envelope/\<http://schemas.xmlsoap.org/soap/envelope/>"
xmlns:ns=\"http://www.procurve_mobility_msm.com/SOAP/API/1.7/\<http://www.procurve_mobility_msm.com/SOAP/API/1.7/>">
<x:Header/>
<x:Body>
<ns:ExecuteNOCLogout>
<ns:sessionID>[Acct-Session-ID]</ns:sessionID>
</ns:ExecuteNOCLogout>
</x:Body>
</x:Envelope>";
my $response = $userAgent->request(POST 'http://[Controller IP]:448/SOAP',
Content_Type => 'text/xml; charset=utf-8',
SOAPAction =>
'http://www.procurve_mobility_msm.com/SOAP/API/1.7/ExecuteNOCLogout',
Content => $message);
print $response->error_as_HTML unless $response->is_success;
print $response->as_string;
--
Logon / authentication:
--
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
my $userAgent = LWP::UserAgent->new(agent => 'perl post');
my $message = "<x:Envelope
xmlns:x=\"http://schemas.xmlsoap.org/soap/envelope/\<http://schemas.xmlsoap.org/soap/envelope/>"
xmlns:ns=\"http://www.procurve_mobility_msm.com/SOAP/API/1.7/\<http://www.procurve_mobility_msm.com/SOAP/API/1.7/>">
<x:Header/>
<x:Body>
<ns:ExecuteNOCLoginRequest>
<ns:userIPAddr>[Guest IP]</ns:userIPAddr>
<ns:username>[Guest Username]</ns:username>
<ns:password>[Guest Password / any will
work]</ns:password>
</ns:ExecuteNOCLoginRequest>
</x:Body>
</x:Envelope>";
my $response = $userAgent->request(POST 'http://[Controller IP]:448/SOAP',
Content_Type => 'text/xml; charset=utf-8',
SOAPAction =>
'http://www.procurve_mobility_msm.com/SOAP/API/1.7/ExecuteNOCLoginRequest',
Content => $message);
print $response->error_as_HTML unless $response->is_success;
print $response->as_string;
--
My question to all of you! Any idea how I can get the deauthentication to work
"automatically" instead of it trying SNMP / SSH?
Best regards,
Simon Gottschlag
------------------------------------------------------------------------------
_______________________________________________
PacketFence-users mailing list
[email protected]<mailto:[email protected]>
https://lists.sourceforge.net/lists/listinfo/packetfence-users
------------------------------------------------------------------------------
_______________________________________________
PacketFence-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/packetfence-users