一、安装 freeradius 3.0
将用户信息配置在RADIUS服务器上,通过RADIUS服务器对用户进行认证。
其特点时认证和授权结合,不能分离,认证成功授权也成功。
该协议定义了基于UDP的RADIUS报文格式及其传输机制,并规定UDP端口1812,1813分别作为了认证,计费端口。
当用户输入用户名和密码,请求发给中继请求服务,将发送一个请求报文给RADIUS服务器,
这时服务器会比对其保存的账户密码,正确与否,将会发送一个接受或者拒绝报文。
通知到用户认证结果,认证成功,发送一个计费开始请求报文,服务器将回应一个开始响应报文。
apt-get install freeradius
二、配置费挑战用户
编辑/etc/freeradius/3.0/users文件,89行下面加入以下内容(89行有用户例子)
admin Cleartext-Password := "admin"
admin Cleartext-Password := "click1"
array Cleartext-Password := "click1"
三、freeradius 挑战认证配置过程:
1.编辑/etc/freeradius/3.0/sites-enabled/default 文件中加入下面这段
ip根据自己的环境去修改
server foo {
listen {
ipaddr = 192.168.120.218
port = 2000
type = auth
}
listen {
ipaddr = 182.16.10.201
port = 2000
type = auth
}
authorize {
update {
control:Auth-Type := perl
}
perl
}
authenticate {
perl
}
client private-network-1 {
ipaddr = 192.168.120.0/24
secret = testing123
}
}
2. 把附件 perl 放到 /etc/freeradius/3.0/mods-enabled/ 并加 777 权限, chown -R root:root perl
chown -R root:root perl
perl文件内容如下:
# -*- text -*-
#
# $Id: fa04cdabb71767050aaa0664da792fd6086adb19 $
# Persistent, embedded Perl interpreter.
#
perl {
#
# The Perl script to execute on authorize, authenticate,
# accounting, xlat, etc. This is very similar to using
# 'rlm_exec' module, but it is persistent, and therefore
# faster.
#
filename = /etc/freeradius/3.0/perl_otp.pl
#
# Options which are passed to the Perl interpreter.
# These are (mostly) the same options as are passed
# to the "perl" command line.
#
# The most useful flag is "-T". This sets tainting on. And
# as of 3.0.18, makes it impossible to leverage bad
# User-Names into local command execution.
#
perl_flags = "-T"
#
# The following hashes are given to the module and
# filled with value-pairs (Attribute names and values)
#
# %RAD_CHECK Check items
# %RAD_REQUEST Attributes from the request
# %RAD_REPLY Attributes for the reply
# %RAD_REQUEST_PROXY Attributes from the proxied request
# %RAD_REQUEST_PROXY_REPLY Attributes from the proxy reply
#
# The interface between FreeRADIUS and Perl is strings.
# That is, attributes of type "octets" are converted to
# printable strings, such as "0xabcdef". If you want to
# access the binary values of the attributes, you should
# call the Perl "pack" function. Then to send any binary
# data back to FreeRADIUS, call the Perl "unpack" function,
# so that the contents of the hashes are printable strings.
#
# IP addresses are sent as strings, e.g. "192.0.2.25", and
# not as a 4-byte binary value. The same applies to other
# attribute data types.
#
# Attributes of type "string" are copied to Perl as-is.
# They are not escaped or interpreted.
#
# The return codes from functions in the perl_script
# are passed directly back to the server. These
# codes are defined in mods-config/example.pl
#
# You can define configuration items (and nested sub-sections) in perl "config" section.
# These items will be accessible in the perl script through %RAD_PERLCONF hash.
# For instance: $RAD_PERLCONF{'name'} $RAD_PERLCONF{'sub-config'}->{'name'}
#
#config {
# name = "value"
# sub-config {
# name = "value of name from config.sub-config"
# }
#}
#
# List of functions in the module to call.
# Uncomment and change if you want to use function
# names other than the defaults.
#
func_authenticate = authenticate
func_authorize = authorize
#func_preacct = preacct
#func_accounting = accounting
#func_checksimul = checksimul
#func_pre_proxy = pre_proxy
#func_post_proxy = post_proxy
#func_post_auth = post_auth
#func_recv_coa = recv_coa
#func_send_coa = send_coa
#func_xlat = xlat
#func_detach = detach
#
# Uncomment the following lines if you wish
# to use separate functions for Start and Stop
# accounting packets. In that case, the
# func_accounting function is not called.
#
#func_start_accounting = accounting_start
#func_stop_accounting = accounting_stop
}
3. 把 perl_otp.pl 放到 /etc/freeradius/3.0/ 并加 777 权限
chown -R freerad:freerad perl_otp.pl
/etc/freeradius/3.0/mods-enabled/
chown -R freerad:freerad perl_otp.pl
perl_otp.pl文件内容如下:
#
# 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 St, Fifth Floor, Boston, MA 02110-1301, USA
#
# Copyright 2002 The FreeRADIUS server project
# Copyright 2002 Boian Jordanov <bjordanov@orbitel.bg>
#
#
# Example code for use with rlm_perl
#
# You can use every module that comes with your perl distribution!
#
# If you are using DBI and do some queries to DB, please be sure to
# use the CLONE function to initialize the DBI connection to DB.
#
#use strict;
use warnings;
# use ...
use Data::Dumper;
# Bring the global hashes into the package scope
our (%RAD_REQUEST, %RAD_REPLY, %RAD_CHECK, %RAD_STATE);
# This is hash wich hold original request from radius
#my %RAD_REQUEST;
# In this hash you add values that will be returned to NAS.
#my %RAD_REPLY;
#This is for check items
#my %RAD_CHECK;
# This is the session-sate
#my %RAD_STATE;
# This is configuration items from "config" perl module configuration section
#my %RAD_PERLCONF;
# Multi-value attributes are mapped to perl arrayrefs.
#
# update request {
# Filter-Id := 'foo'
# Filter-Id += 'bar'
# }
#
# This results to the following entry in %RAD_REQUEST:
#
# $RAD_REQUEST{'Filter-Id'} = [ 'foo', 'bar' ];
#
# Likewise, you can assign an arrayref to return multi-value attributes
#
# This the remapping of return values
#
use constant {
RLM_MODULE_REJECT => 0, # immediately reject the request
RLM_MODULE_OK => 2, # the module is OK, continue
RLM_MODULE_HANDLED => 3, # the module handled the request, so stop
RLM_MODULE_INVALID => 4, # the module considers the request invalid
RLM_MODULE_USERLOCK => 5, # reject the request (user is locked out)
RLM_MODULE_NOTFOUND => 6, # user not found
RLM_MODULE_NOOP => 7, # module succeeded without doing anything
RLM_MODULE_UPDATED => 8, # OK (pairs modified)
RLM_MODULE_NUMCODES => 9, # How many return codes there are
RLM_MODULE_CHALLENGE => 11, # How many return codes there are
};
# Same as src/include/log.h
use constant {
L_AUTH => 2, # Authentication message
L_INFO => 3, # Informational message
L_ERR => 4, # Error message
L_WARN => 5, # Warning
L_PROXY => 6, # Proxy messages
L_ACCT => 7, # Accounting messages
L_DBG => 16, # Only displayed when debugging is enabled
L_DBG_WARN => 17, # Warning only displayed when debugging is enabled
L_DBG_ERR => 18, # Error only displayed when debugging is enabled
L_DBG_WARN_REQ => 19, # Less severe warning only displayed when debugging is enabled
L_DBG_ERR_REQ => 20, # Less severe error only displayed when debugging is enabled
};
# Global variables can persist across different calls to the module.
#
#
# {
# my %static_global_hash = ();
#
# sub post_auth {
# ...
# }
# ...
# }
#func_authenticate = authenticate;
#func_authorize = authorize;
# Function to handle authorize
sub authorize {
# For debugging purposes only
# &log_request_attributes;
# Here's where your authorization code comes
# You can call another function from here:
&test_call;
return RLM_MODULE_OK;
}
# Function to handle authenticate
sub authenticate {
# For debugging purposes only
# &log_request_attributes;
if ($RAD_REQUEST{'User-Name'} =~ /^otp_test/i) {
if($RAD_REQUEST{'User-Password'} =~ /hahaha/i){
$RAD_REPLY{'Reply-Message'} = "accept after challenged";
return RLM_MODULE_OK;
}else{
$RAD_REPLY{'Reply-Message'} = "hahahaha";
$RAD_CHECK{'Response-Packet-Type'} = "Access-Challenge";
}
return RLM_MODULE_HANDLED;
} else {
# Accept user and set some attribute
if (&radiusd::xlat("%{client:group}") eq 'UltraAllInclusive') {
# User called from NAS with unlim plan set, set higher limits
$RAD_REPLY{'h323-credit-amount'} = "1000000";
} else {
$RAD_REPLY{'h323-credit-amount'} = "100";
}
return RLM_MODULE_OK;
}
}
# Function to handle preacct
sub preacct {
# For debugging purposes only
# &log_request_attributes;
return RLM_MODULE_OK;
}
# Function to handle accounting
sub accounting {
# For debugging purposes only
# &log_request_attributes;
# You can call another subroutine from here
&test_call;
return RLM_MODULE_OK;
}
# Function to handle checksimul
sub checksimul {
# For debugging purposes only
# &log_request_attributes;
return RLM_MODULE_OK;
}
# Function to handle pre_proxy
sub pre_proxy {
# For debugging purposes only
# &log_request_attributes;
return RLM_MODULE_OK;
}
# Function to handle post_proxy
sub post_proxy {
# For debugging purposes only
# &log_request_attributes;
return RLM_MODULE_OK;
}
# Function to handle post_auth
sub post_auth {
# For debugging purposes only
# &log_request_attributes;
return RLM_MODULE_OK;
}
# Function to handle xlat
sub xlat {
# For debugging purposes only
# &log_request_attributes;
# Loads some external perl and evaluate it
my ($filename,$a,$b,$c,$d) = @_;
&radiusd::radlog(L_DBG, "From xlat $filename ");
&radiusd::radlog(L_DBG,"From xlat $a $b $c $d ");
local *FH;
open FH, $filename or die "open '$filename' $!";
local($/) = undef;
my $sub = <FH>;
close FH;
my $eval = qq{ sub handler{ $sub;} };
eval $eval;
eval {main->handler;};
}
# Function to handle detach
sub detach {
# For debugging purposes only
# &log_request_attributes;
}
#
# Some functions that can be called from other functions
#
sub test_call {
# Some code goes here
}
sub log_request_attributes {
# This shouldn't be done in production environments!
# This is only meant for debugging!
for (keys %RAD_REQUEST) {
&radiusd::radlog(L_DBG, "RAD_REQUEST: $_ = $RAD_REQUEST{$_}");
}
}
4.修改client.conf文件
在目录 /etc/freeradius/3.0下,修改client.conf文件
5. service freeradius restart
测试挑战用户
otp_test/click1
挑战密码:
hahahaha
配置挑战的时候端口号不是1812,而是2000
评论区