Защита паролем ODBC в SAS - PullRequest
4 голосов
/ 16 ноября 2011

Мы хотим удалить жестко запрограммированные пароли из строк подключения ODBC в нашем коде SAS, а также предотвратить появление любых паролей в файлах журналов SAS.

Похоже, в большом количестве статей обсуждается, как это сделать.об этом, но я либо нахожу проблемы с ними, либо не могу заставить их работать.

Приглашение пользователя каждый раз для PW не является жизнеспособной альтернативой.Кроме того, хранение пароля в макропеременной является приемлемым подходом, если у вас есть способ запретить его печать в журнал с включенными параметрами MACROGEN и SYMBOLGEN.

ATTEMPT 1 - ENCODING ( ссылка на технический документ здесь )

proc pwencode in='mypassword' method=sasenc;
run;

дает:

{sasenc}ACFD24061BF77D7D5362EE7C2D00D08B

Если я заменю свой пароль в виде открытого текста на кодированное значение в моем коде, тоODBC сквозной оператор работает нормально.

proc sql noprint;
  connect to odbc as remote (datasrc=cmg_report user=myuser password='{sasenc}68B279564BD2695538CDCDB301E8A357563480B0');
  create table sqlo as 
  select *
  from connection to remote
  (
  select top 1 * from application
  )
  ;
  disconnect from remote;
quit;

И журнал правильно маскирует значения с помощью XXXXXXXs.

961  proc sql noprint;
962    connect to odbc as remote (datasrc=cmg_report user=&user_cmg password=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX);
963    create table sqlo as
964    select *
965    from connection to remote
966    (
967    select top 1 * from application
968    )
969    ;
971  quit;
NOTE: Table WORK.SQLO created, with 1 rows and 29 columns.
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.34 seconds
      cpu time            0.01 seconds

Проблема с вышеприведенным подходом состоит в том, что если кто-то имеет доступ к коду, он может войти в систему с использованием зашифрованного пароля без необходимости знать пароль в виде простого текста.Поэтому, хотя он скрывает действительный пароль, он не обеспечивает безопасность.Мне это кажется глупым или я что-то упустил? РЕДАКТИРОВАТЬ: Это обеспечивает некоторую безопасность, если ваш пароль ODBC используется в другом месте, вот и все.

ПОПЫТКА 2 - ИСПОЛЬЗОВАНИЕ SYMGET ( ссылка натехнический документ здесь )

Проблема в том, что я просто не могу заставить описанную технику работать в SAS.Я запускаю SAS 9.2 на XP, пытаюсь подключиться к БД SQL Server.

%let my_password = password;

proc sql noprint;
  connect to odbc (dsn=cmg_report uid=myuser pwd=symget('my_password'));
  create table sqlo as 
  select *
  from connection to remote
  (
  select top 1 * from application
  )
  ;
quit;

Я получаю следующее сообщение о том, что вход не выполнен:

1034      proc sql noprint;
1035        connect to odbc (dsn=cmg_report uid=myuser pwd=XXXXXX('my_password'));

ERROR: CLI error trying to establish connection: [Microsoft][SQL Server Native Client 10.0][SQL
Server]Login failed for user 'myuser'.

Похожеон пытается использовать «symget» в качестве фактического пароля (так как он был замаскирован в журнале).Есть несколько ответов на этот технический документ, в которых говорится об обертывании символа в вызове% sysfunc, но функция symget () - одна из немногих функций, которые SAS не разрешает в вызове% sysfunc, поэтому я не понимаю, как это возможно.

Любые другие советы / предложения / идеи будут высоко ценится.

Спасибо

РЕДАКТИРОВАТЬ: Было бы особенно хорошо, если бы была техникачтобы это работало при включенном options symbolgen macrogen.

Ответы [ 5 ]

4 голосов
/ 18 ноября 2011

Так что я также связался с SAS, чтобы узнать, что они рекомендуют для такого типа проблем, и это был их (как всегда своевременный) ответ.К сожалению, похоже, что их невозможно достичь без отключения symbolgen:

Чтобы пароли не были жестко запрограммированы в программах SAS или не появлялись в журналах SAS, предлагаются следующие методы.:

1) Наиболее безопасный вариант - выполнить оператор LIBNAME с использованием необходимого механизма SAS / Access и указать DBPROMPT = YES.Это запросит у вас информацию о соединении с базой данных во время выполнения кода SAS, поэтому информация о соединении не будет сохранена в вашей программе.

Однако, поскольку для этого требуется некоторое ручное взаимодействие при выполнении заданий, это может не произойти.возможно в вашей ситуации.

2) Информация о подключении к базе данных может храниться в реестре SAS, а пароль, необходимый для подключения, будет зашифрован.Чтобы настроить это, запустите SAS в интерактивном режиме и в окне проводника выделите «Библиотеки».В меню выберите File-New.Введите libref, который вы хотите использовать для подключения к базе данных, в поле «Имя», затем выберите используемый механизм базы данных в раскрывающемся меню.После выбора движка вы увидите окно, которое позволяет вам ввести имя пользователя, пароль, путь и параметры.Введите информацию о соединении, затем нажмите маленькую кнопку в правом верхнем углу, которая указывает «Включить при запуске».Этот метод сохраняет информацию о вашем соединении в реестре SAS и автоматически подключается при запуске SAS.При запуске SAS в пакетном режиме вы ДОЛЖНЫ указать -startlib при вызове, чтобы библиотека была распределена.Ваш пароль будет отображаться в журнале SAS в виде зашифрованного значения.

3) Если запущен PROC SQL Pass-Through, вы можете передать пароль в SAS через параметр -sysparm при вызове SAS и использовать & sysparm SASМакропеременная, в которой обычно кодируется пароль.Ниже приведен пример:

sas -nodms -sysparm mypassword

1?PROC SQL;2?CONNECT TO ORACLE (user = scott password = "& sysparm");

Обратите внимание, что, если действуют макропараметры MPRINT и / или SYMBOLGEN, разрешенная макропеременная появится в журнале SAS, и, следовательно, вашапароль появится в текстовом виде в вашем журнале SAS.NOMPRINT и NOSYMBOLGEN являются настройками по умолчанию.

4) Кроме того, при запуске PROC SQL Pass-Through вы можете сохранить оператор CONNECT в файле, защищенном разрешениями операционной системы, такими, что только у вас есть разрешение на чтение, затем используйтеоператор% INCLUDE для включения оператора CONNECT.Вот пример:

sas -nodms

1?ВАРИАНТЫ NOSOURCE2;2?PROC SQL;3?% INCLUDE 'myconnect.dat';

В приведенном выше примере OPTIONS NOSOURCE2 предотвращает отображение включенного кода в журнале SAS.Указание SOURCE2 перечисляет содержимое включенного файла в журнале SAS.NOSOURCE2 является настройкой по умолчанию.

5) В SAS 9.1 и более поздних версиях вы можете использовать процедуру Proc PWENCODE, которая будет создавать закодированный пароль вместо простых текстовых паролей в программах SAS в пакетном режиме.

http://support.sas.com/onlinedoc/913/getDoc/proc.hlp/a002595988.htm

и выберите процедуру PWENCODE.

Синтаксис Proc приведен ниже.Кодированный пароль выводится в журнал.

proc pwencode in = "plaintextPassword";беги;

4 голосов
/ 17 ноября 2011

Роб, мы столкнулись с подобной проблемой и придумали другой метод, который позволяет всем членам нашей команды запускать одну и ту же программу без сохранения наших идентификаторов / паролей в программах. Требуется, чтобы у каждого члена команды был безопасный текстовый файл (без прав доступа, кроме владельца), к которому SAS может получить доступ.

Вот пример содержимого файла ID / PW:

machine odbc login XX_odbc_id_XX password XXodbc_pw_XX
machine oracle login XX_oracle_id_XX password XX_oracle_pw_XX

Мы работаем на сервере UNIX, поэтому мы храним наши индивидуальные файлы id / pw, заблокированные в нашем домашнем каталоге, чтобы никто другой не мог получить к нему доступ, в этом случае он называется «.netrc». Макросы в конце этого потока должны быть где-то сохранены, тогда программа будет выглядеть следующим образом:

%let id_pw_text_file = ~/.netrc;

%ODBC_Acct;

proc sql;
   %ODBC_Connect
   create table sqlo as
      select * from connection to odbc
      (
          /*  [ Insert ODBC query here ]  */ 
      );
   %ODBC_Disconnect
   quit;
run;

Я пытался пересмотреть макросы для работы в вашей среде и удалить много кода, характерного для наших систем, но, очевидно, я не смог протестировать его, чтобы убедиться, что он работает. Дайте мне знать, если у вас есть проблема, и я постараюсь помочь ее исправить. Надеюсь, это поможет.

/*********************************************************************
*  Name:  ODBC_Acct                                                  *
*  Desc:  Set global macro vars containing a users ODBC username     *
*         and password. Retrieves this information from a users      *
*         specific ID/PW file.                                       *
*********************************************************************/
%macro ODBC_Acct( mprint );
   %local __mprint __symbolgen __mlogic;
   %if ( %length( &mprint ) = 0 ) %then %let mprint = NO;
   %if ( %upcase( &mprint ) = NO ) %then %do;
      %let __mprint = %sysfunc( getoption( mprint ));
      %let __symbolgen = %sysfunc( getoption( symbolgen ));
      %let __mlogic = %sysfunc( getoption( mlogic ));
      options nomprint nosymbolgen nomlogic;
   %end;
   %global  odbc_user  odbc_pw;
   %Get_ID_PW( &id_pw_text_file , odbc , odbc_user , odbc_pw )
   %if ( %upcase(&__mprint) ne NOMPRINT ) %then %do;
      options &__mprint &__symbolgen &__mlogic;
   %end;
%mend;

/*********************************************************************
*  Name:  ODBC_Connect, ODBC_Disconnect                              *
*  Desc:  Returns SAS/Access connect or disconnect statements        *
*         for accessing ODBC.                                        *
*********************************************************************/
%macro ODBC_Connect( mprint=no );
   %local __mprint __symbolgen;
   %if ( %upcase(&mprint) = NO ) %then %do;
      %let __mprint = %sysfunc( getoption( mprint ));
      %let __symbolgen = %sysfunc( getoption( symbolgen ));
      options nomprint nosymbolgen;
   %end;
   connect to odbc as remote (
      datasrc=cmg_report
          user = "&odbc_user"
      password = "&odbc_pw"
      );
   %if ( %upcase(&__mprint) ne NOMPRINT ) %then %do;
      options &__mprint &__symbolgen;
   %end;
%mend;
%macro ODBC_Disconnect;
   disconnect from odbc;
%mend;

/*******************************************************************************
*  Name:  GetID_PW                                                             *
*  Desc:  Get loginid and password from a secured file                         *
*------------------------------------------------------------------------------*
*  Arguments:                                                                  *
*    1st   Required. Source file containing IDs and passwords.                 *
*    2nd   Required. Host id.                                                  *
*    3rd   Required. Specify the macro variable to put the loginid.            *
*    4th   Required. Specify the macro variable to put the password.           *
*------------------------------------------------------------------------------*
*******************************************************************************/
%macro Get_ID_PW( source , rhost , usrvar , pw_var );
   %let source_file = &source
   %if ( %sysfunc( fileexist( &source_file ) ) ) %then %do;
      %let rc  = %sysfunc( filename( dummy , &source_file ) );
      %let fid = %sysfunc( fopen( &dummy ) );
      %do %while( %sysfunc( fread( &fid ) ) = 0 );
         %let rc = %sysfunc( fget( &fid , inrec , 500 ) );
         %let machine = %scan( &inrec , 2 , %str( ) );
         %if ( %upcase( &machine ) = %upcase( &rhost ) ) %then %do;
            %let &usrvar = %scan( &inrec , 4 , %str( ) );
            %let &pw_var = %scan( &inrec , 6 , %str( ) );
            %goto Break;
         %end;
      %end;
      %Break: %*;
      %let rc = %sysfunc( fclose( &fid ) );
      %let rc = %sysfunc( filename( dummy ) );
   %end;
   %else %do;
       %put ::: ID/PW file "&source_file" not found;
   %end;
%mend;
2 голосов
/ 15 марта 2015

Безопасного метода для определения соединения ODBC не существует!

Каждый может читать аутентификационные домены, имена пользователей и кодировать пароли с помощью API метаданных. Администратор Linux или пользователь root могут получить доступ к любой файловой системе, включая домашние каталоги и их файлы password.sas.

SAS также предоставляет ChangePassPhrase для понижения сохраненных паролей до более старого метода SAS PWENCODE. Если вы знаете зашифрованный пароль, то вы можете расшифровать его, например, онлайн на https://decrypt -password.appspot.com / sas-pwdecode /

Иногда учетные данные для входа используются для разных сервисов. Имя пользователя и пароль для FTP или MAIL также можно использовать для ssh. Файлы и метаданные не являются безопасным хранилищем.

1 голос
/ 07 августа 2013

Извините, не могу написать комментарий, но трюк %superq действительно работает. Используйте это так:

proc sql;
   select * from set_encrypedon (pw="%SUPERQ(_password)");
quit;

где у вас есть макропеременная с именем _password.

К сожалению, это не может быть заключено в макрос вроде

%macro pwd();
  "%SUPERQ(_password)"
%mend;

потому что тогда MPRINT снова зарегистрирует ваш пароль.

1 голос
/ 30 ноября 2011

когда SYMGET не работает в операторе CONNECT, попробуйте функцию цитирования %SUPERQ.Он также разрешает макро-переменную без всплытия в журнале.

...