everydayminder

learn something everyday

Archive for October 2013

FreeRADIUS(2.2.10) + Oracle 연동 설정 (InstantClient 활용)

leave a comment »

– 환경 : CentOS6.4 (64비트)
– 준비물 : FreeRADIUS(2.2.10), Oracle Instantclient

1. 기본 설정
CentOS에서는 yum 명령어로 프로그램/라이브러리를 쉽게 설치할 수 있다.
설치 과정에서 ssl 관련 라이브러리에 대한 설정이 필요할 수 있으므로, 미리 다음과 같이 설치한다.

yum install openssl, openssl-devel

2. FreeRADIUS 설치를 위한 사전 준비
마찬가지로, FreeRADIUS도 yum 명령어로 설치할 수 있다.
만약, 설치하고자 한다면,

yum install freeradius

와 같이 실행하면 된다.

yum list | grep freeradius

를 수행하여 관련 라이브러리를 살펴보자.

freeradius-mysql.x86_64는 보이는데,
freeradius-oracle은 보이지 않는다.

결국, yum 명령어로는 FreeRADIUS와 Oracle을 위한 설정을 온전하게 할 수 없다.
따라서, FreeRADIUS 소스를 직접 다운로드하여 빌드해야 한다.

3. Oracle 클라이언트(라이브러리 준비)
Oracle을 해당 서버에 full installation을 했다면, 당연히 클라이언트까지 설치되어 있으므로,
아래 설치 관련 내용은 무시해도 된다.

본 설명은, Oracle Instantclient를 사용하는 방법을 기준으로 진행한다.
http://www.oracle.com으로부터 linux용(64비트) instantclient 라이브러리(basic, sdk)를 다운로드 한다.

- instantclient-basic-linux.x64-11.2.0.4.0.zip
- instantclient-sdk-linux.x64-11.2.0.4.0.zip

해당 파일들을 원하는 디렉토리에 압축풀어 놓자. (이하 $ORACLE_HOME)
basic과 관련된 파일들은 $ORACLE_HOME에,
sdk와 관련된 파일들은 $ORACLE_HOME/sdk/*에 풀리게 될 것이다.

4. FreeRADIUS 다운로드
http://www.freeradius.org로부터 freeradius-server-.2.2.1.tar.gz (또는 bz2) 파일을 다운로드하고,
원하는 디렉토리에 압축 푼다. (이하 $FREERADIUS_SRC)

5. FreeRADIUS 빌드
FreeRADIUS와 Oracle 라이브러리 연동이 잘 안된다는 블로그를 발견하여,
참고한 내용이다. (from Atif’s Blog : http://atif-razzaq.blogspot.kr/2011/01/freeradius-with-oracle.html)

해당 블로그 본문에 소개된 바와 같이 configure.in의 내용을 복사하여,
$FREERADIUS_SRC/src/modules/rlm_sql/drivers/rlm_sql_oracle/configure.in으로 덮어쓴다.

configure.in의 내용 참고

AC_INIT(sql_oracle.c)
AC_REVISION($Revision: 1.10 $)
AC_DEFUN(modname,[rlm_sql_oracle])

fail=
sql_oracle_ldflags=
sql_oracle_cflags=
if test x$with_[]modname != xno; then

AC_MSG_CHECKING([for oci.h])

dnl #
dnl # See if the user passed in the oracle_home_dir option and
dnl # use that first. If not, use $ORACLE_HOME. If that's
dnl # not defined, give up. There's no point in blindly
dnl # hunting around for Oracle - there's no standard place
dnl # for it. Any sane Oracle user/developer should have $ORACLE_HOME
dnl # defined anyways.
dnl #

dnl ############################################################
dnl # Check for command line options
dnl ############################################################

dnl extra argument: --with-oracle-version=VER
oracle_version=
AC_ARG_WITH(oracle-version,
[AS_HELP_STRING([--with-oracle-version=VER],
[Version of Oracle to search for. Should be 10 for Oracle 10g and 11 for 11g])],
[case "$withval" in
11)
oracle_version="$withval"
;;
10)
oracle_version="$withval"
;;
*)
AC_MSG_ERROR(Need oracle-version)
;;
esac])

dnl extra argument: --with-oracle-include-dir=DIR
oracle_include_dir=
AC_ARG_WITH(oracle-include-dir,
[AS_HELP_STRING([--with-oracle-include-dir=DIR],
[Directory where the Oracle includes may be found. It should be located under ORACLE_HOME if you have client SDK installed. Use --with-oracle-include-dir=yes if you are sure that your compiler include path includes Oracle include dir. Hint: you might try to do: locate oci.h])],
[case "$withval" in
no)
AC_MSG_ERROR(Need oracle-include-dir)
;;
yes)
;;
*)
oracle_include_dir="$withval"
;;
esac])

dnl extra argument: --with-oracle-lib-dir=DIR
oracle_lib_dir=
AC_ARG_WITH(oracle-lib-dir,
[AS_HELP_STRING([--with-oracle-lib-dir=DIR],
[Directory where the oracle libraries may be found. It should be located under ORACLE_HOME. iUse --with-oracle-lib-dir=yes if you are sure that your linker will find the necessary Oracle client libs. Hint: you might try to do: locate libclntsh.so])],
[case "$withval" in
no)
AC_MSG_ERROR(Need oracle-lib-dir)
;;
yes)
;;
*)
oracle_lib_dir="$withval"
;;
esac])

AC_TRY_COMPILE([#include ],
[ int a = 1;],
ORACLE_INCLUDE=" ",
ORACLE_INCLUDE=
)

RLM_SQL_ORA_WORKING_CFLAGS_FOR_LINKING_TEST=
if test "x$ORACLE_INCLUDE" = "x" ; then
old_CFLAGS="$CFLAGS"
CFLAGS="$old_CFLAGS -I$oracle_include_dir"
AC_TRY_COMPILE([#include ],
[ int a = 1;],
ORACLE_INCLUDE="-I$oracle_include_dir",
ORACLE_INCLUDE=
)

RLM_SQL_ORA_WORKING_CFLAGS_FOR_LINKING_TEST="$CFLAGS"
CFLAGS="$old_CFLAGS"
fi

# Proceed to linking makes only sense if include dir is OK.
if test "x$ORACLE_INCLUDE" != "x" ; then
old_LIBS="$LIBS"
old_CFLAGS="$CFLAGS"
CFLAGS="$RLM_SQL_ORA_WORKING_CFLAGS_FOR_LINKING_TEST"

ORACLE_LIBDIR_SWITCH=
if test "x$oracle_lib_dir" != "x" ; then
ORACLE_LIBDIR_SWITCH="-L${oracle_lib_dir} "
fi
if test "x$oracle_version" = "x" ; then
AC_MSG_RESULT(no)
AC_MSG_WARN([oracle version not found. Use --with-oracle-version={10|11}.])
fail="$fail Oracle version"
else
LIBS="$old_LIBS $ORACLE_LIBDIR_SWITCH -lclntsh -lnnz${oracle_version}"

AC_TRY_LINK([#include

static OCIEnv *p_env;
static OCIError *p_err;
static OCISvcCtx *p_svc;
static OCIStmt *p_sql;
static OCIDefine *p_dfn = (OCIDefine *) 0;
static OCIBind *p_bnd = (OCIBind *) 0;
],
[
int p_bvi;
char p_sli[20];
int rc;
char errbuf[100];
int errcode;

rc = OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0, /* Initialize OCI */
(dvoid * (*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *)) 0 );

],
ORACLE_LIBS="$ORACLE_LIBDIR_SWITCH -lclntsh -lnnz${oracle_version}",
ORACLE_LIBS=
)

LIBS="$old_LIBS"
CFLAGS="$old_CFLAGS"
fi
fi

if test "x$ORACLE_INCLUDE" = "x"; then
AC_MSG_RESULT(no)
AC_MSG_WARN([oracle headers not found. Use --with-oracle-include-dir=.])
fail="$fail oci.h"
else
sql_oracle_cflags="${sql_oracle_cflags} ${ORACLE_INCLUDE}"
AC_MSG_RESULT(yes)

if test "x$ORACLE_LIBS" = "x"; then
AC_MSG_WARN([oracle libraries not found. Use --with-oracle-lib-dir=.])
fail="$fail libclntsh libnnz${oracle_version}"
else
sql_oracle_ldflags="${sql_oracle_ldflags} $ORACLE_LIBS"
AC_MSG_RESULT(yes)
fi
fi

targetname=modname
else
targetname=
echo *** module modname is disabled.
fi

dnl Don't change this section.
if test "x$fail" != x; then
if test "x${enable_strict_dependencies}" = xyes; then
AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
else
AC_MSG_WARN([silently not building ]modname[.])
AC_MSG_WARN([FAILURE: ]modname[ requires:$fail.]);
targetname=
fi
fi

AC_SUBST(sql_oracle_ldflags)
AC_SUBST(sql_oracle_cflags)
AC_SUBST(targetname)
AC_OUTPUT(Makefile)

$FREERADIUS_SRC로부터 다음과 같이 실행한다.

./configure --with-oracle-version=11 --with-oracle-include-dir=$ORACLE_HOME/sdk/include --with-oracle-lib-dir=$ORACLE_HOME
make
make install

만약, 성공적으로 설정이 되고, 빌드되었다면, /usr/local/lib에 rlm_sql_oracle.* 파일들이 보여야 한다.

그러나, 나의 경우 rlm_sql_oralce.* 파일들이 존재하지 않았다.
$FREERADIUS_SRC/src/modules/rlm_sql/drivers/rlm_sql_oracle/config.log 파일을 열어 실패 사유를 찾아보자.

내 경우는, 오라클 라이브러리 설정을 해줬는데도 불구하고, 관련 라이브러리를 찾을 수 없으니,
–with-oracle-lib-dir 옵션을 사용하여 위치를 지정하라는 에러 메시지가 있었다.
(그러나, 위에서 이미 옵션을 제대로 준 상태임)

다시, $ORACLE_HOME으로 이동해 보자.
내 경우, config.log상, libnnz와 libclntsh를 찾을 수 없다는 에러가 있었기에, 다음과 같이 soft link를 걸어 주었다.

ln -s libclntsh.so $ORACLE_HOME/libclntsh.so.11.1
ln -s libnnz.so $ORACLE_HOME/libnnz11.so

그리고 다시, 위의 과정 (configure 부터 make install까지 )을 반복하였다.
그랬더니, 빌드 성공!

/usr/local/lib/rlm_sql_oracle* 파일들이 생긴 것을 확인할 수 있다.

4. 시범 운전 확인
radiusd -X를 실행하여, 정상적으로 일단 뜨는지 보자.
별 에러 없이 뜨고, 사용자로부터 인증 요청 대기한다는 메시지가 뜬다면 일단 설치/ 1차 설정은 성공한 것이다.

5. file 기반 사용자 추가/ 인증 테스트
빌드를 성공적으로 했다면, 기본적으로 /usr/local/etc/raddb에 설정파일 들이 복사가 되었을 것이다. (이하 $FREERADIUS_CONF)
radiusd를 종료시키고, $FREERADIUS_CONF/users 파일을 편집하자.

빈 칸에,

 luran Cleartext-Password := "letmein"
 Reply-Message = "Hello, %{User-Name}"
 

이라고 추가로 적어주고, users 파일을 저장한다.

다시, radiusd -X를 실행시키고,

 radtest luran letmein localhost 0 testing123
 

이라고 입력한다.

($FREERADIUS_CONF/clients.conf에 기본적으로 localhost에서 접속하는 클라이언트의 경우,
secret이 testing123으로 설정되어 있다.)

정상적으로 동작한다면,
Access-Accept 메시지를 수신한다.

6. FreeRADIUS – SQL 인증 설정

– radiusd.conf 편집
$FREERADIUS_CONF/radiusd.conf 파일내 sql 설정 주석을 없앤다.

 $INCLUDE sql.conf
 

– sql.conf 편집
$FREERADIUS_CONF/sql.conf 파일을 열고, oracle 관련 설정을 해준다.

 database = "oracle"
 server = "DB서버 IP"
 port = 포트번호
 login = 사용자계정
 password = 계정비밀번호
 

등으로 내용을 고친다.

 # radius_db = "radius"
 radius_db = "(DESCRPTION=(ADDRESS(=(PROTOCOL=TCP)(HOST=DB서버IP)(PORT=DB포트))(CONNECT_DATA=(SID=SID이름)))"
 

– sites-enabled/default
$FREERADIUS_CONF/sites-enabled/default 파일을 열어서,
sql 이 필요한 모듈 별로, sql 옵션을 주석 해제한다.

내 경우는 일단, authorize 모듈에서만 sql 주석을 해제했다.

7. 인증에 필요한 스키마 생성
$FREERADIUS_CONF/sql/oracle 디렉토리내 관련 sql 들이 복사되어 있을 것이다.
이중 schema.sql을 사용하여, 필요한 스키마를 생성해준다.

8. 재실행 및 환경 변수 확인

 radiusd -X
 

를 실행한다.

내 경우, libclntsh.so.11.1을 찾을 수 없다고 에러가 발생하면서, FreeRADIUS가 시작되지 않았다.
그래서, 환경변수에 LD_LIBRARY_PATH=$ORACLE_HOME을 추가해 주었다.

 export LD_LIBRARY_PATH=$ORACLE_HOME
 

그리고, 다시 radiusd -X를 실행하여 정상 실행을 확인하였다.

9. 인증 데이터 생성/ 인증 확인
DB에 테스트용 사용자를 넣고, 정상적으로 인증되는지 확인해 보자.

 INSERT INTO radcheck VALUES(radcheck_seq.NEXTVAL, 'dbuser', 'Cleartext-Password', ':=', 'dbpass');
 commit;
 

이제 사용자가 추가되었으므로, 접속 테스트를 한다.

 radtest dbuser dbpass localhost 0 testing123
 

이제 앞서 파일 기반으로 인증 테스트 했던 것과 동일하게 Access-Accept 메시지가 뜨는 것을 확인할 수 있다.

10. 기타
$FREERADIUS_CONF/sql.conf 파일의 맨 끝에 보면,

 $INCLUDE sql/${database}/dialup.conf
 

라는 설정이 눈에 띈다.

이 파일에 기록된 내용을 보면,
authorize_check_query, authorize_reply_query 등의 설정이 있다.
해당 설정부를 보면, “SELECT ~ FROM”과 같은 쿼리문이 보이는데,
앞서 생성한 스키마에 이 쿼리문을 수행하여 인증한다고 보면 된다.

즉, 우리가 사용할 쿼리문이 따로 있거나, 스토어드 프로시저를 호출해야 한다면, 이 부분을 변경하면 될 것이다.
(검증은 나중에 다시)

Written by everydayminder

October 25, 2013 at 01:48

Posted in linux

yum lock 해제하기

leave a comment »

만약, 비정상적인 종료 등으로 인해 yum이 lock이 걸렸고,
기다려도 풀리지 않는다면, 다음과 같이 강제로 lock을 해제시킬 수 있다.

cat /var/run/yum.pid

을 실행시켜서 확인 후,

불필요하다면 해당파일을 지워준다.

Written by everydayminder

October 23, 2013 at 08:21

Posted in linux