Как подключиться к SQL-серверу с помощью sqlsrv в CentOS 7.6?

Я настраиваю новый сервер и пытаюсь подключиться к базе данных Microsoft SQL Server Express 2014 с помощью расширения/модуля «sqlsrv» с PHP 7.3, работающим в CentOS 7.6, но не удалось. Однако тот же метод в XAMPP работает!

Я установил php с драйверами в соответствии с инструкциями со страницы Microsoft: https://docs.microsoft.com/en-us/sql/connect/php/installation-tutorial-linux-mac?view=sql-server-2017

На шаге 3 первые два метода не работали, поэтому вместо этого я установил драйвер PHP из репозитория Remi:

[~]$ sudo yum установить php-sqlsrv

А вот и список установленных пакетов:

$ sudo yum list installed *php*
Installed Packages
php.x86_64                                                7.3.4-1.el7.remi                                   @remi-php73
php-cli.x86_64                                            7.3.4-1.el7.remi                                   @remi-php73
php-common.x86_64                                         7.3.4-1.el7.remi                                   @remi-php73
php-devel.x86_64                                          7.3.4-1.el7.remi                                   @remi-php73
php-fedora-autoloader.noarch                              1.0.0-1.el7                                        @epel
php-json.x86_64                                           7.3.4-1.el7.remi                                   @remi-php73
php-pdo.x86_64                                            7.3.4-1.el7.remi                                   @remi-php73
php-pear.noarch                                           1:1.10.9-2.el7.remi                                @remi-php73
php-process.x86_64                                        7.3.4-1.el7.remi                                   @remi-php73
php-sqlsrv.x86_64                                         5.6.1-1.el7.remi.7.3                               @remi-php73
php-xml.x86_64                                            7.3.4-1.el7.remi                                   @remi-php73

$ sudo yum list installed unixODBC*
Installed Packages
unixODBC.x86_64                                    2.3.7-1.rh                               @packages-microsoft-com-prod
unixODBC-devel.x86_64                              2.3.7-1.rh                               @packages-microsoft-com-prod

$ sudo yum list installed msodbcsql*
Installed Packages
msodbcsql.x86_64                                  13.1.9.2-1                                @packages-microsoft-com-prod
msodbcsql17.x86_64                                17.3.1.1-1                                @packages-microsoft-com-prod

Хотя я не использую именованные экземпляры, но согласно этому FAQ: https://github.com/Microsoft/msphpsql/wiki/FAQ#connect-to-named-instances

Я могу подключиться к серверу Microsoft SQL с помощью драйвера ODBC, независимого от драйвера PHP. Используя "isql":

[~]$ isql -v MSSQLTest uid пароль

Некоторые похожие вопросы, которые я прошел:

https://github.com/Microsoft/msphpsql/issues/703
https://github.com/Microsoft/msphpsql/issues/679
https://github.com/Microsoft/msphpsql/issues/470

Но при использовании sqlsrv ничего не работает.

Мой код подключения PHP (работает в XAMPP):

// xx.xx.xx.xx = My Public IP
// yyyy = My Port
$serverName = "xx.xx.xx.xx,yyyy"; //serverName\instanceName
$connectionInfo = array( "Database"=>"MyDB", "UID"=>"MyUID", "PWD"=>"MyPWD", "CharacterSet" => "UTF-8");
$conn = sqlsrv_connect( $serverName, $connectionInfo);

if( $conn ) {
     echo "Connection established.<br />";
}else{
     echo "Connection could not be established.<br />";
     die( print_r( sqlsrv_errors(), true));
} 

// ...Query part

Выход:

Connection could not be established.
Array ( [0] => Array ( [0] => HYT00 [SQLSTATE] => HYT00 [1] => 0 [code] => 0 [2] => [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired [message] => [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired ) [1] => Array ( [0] => 08001 [SQLSTATE] => 08001 [1] => 10013 [code] => 10013 [2] => [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: Error code 0x271D [message] => [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: Error code 0x271D ) [2] => Array ( [0] => 08001 [SQLSTATE] => 08001 [1] => 10013 [code] => 10013 [2] => [Microsoft][ODBC Driver 17 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. [message] => [Microsoft][ODBC Driver 17 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. ) ) 

Как получить "Соединение установлено"?


Обновлено на основе ответа Реми Колле:

$ sqlcmd -S mypublicip,myport -U пользователь -P секрет -Q "ВЫБЕРИТЕ @@версию"

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
        Feb 20 2014 20:04:26
        Copyright (c) Microsoft Corporation
        Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 14393: )

$ php -r 'echo"+ Соединение:\n"; $conn = sqlsrv_connect("mypublicip,myport", array("UID" => "пользователь", "PWD" => "секрет")); if ($conn) { echo"+ Запрос: \n"; $query = sqlsrv_query($conn, "SELECT @@version"); if ($query) { echo"+ Результат:\n"; print_r($row = sqlsrv_fetch_array($query, SQLSRV_FETCH_NUMERIC)); } } '

+ Connection:
+ Query:
+ Result:
Array
( 
    [0] => Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
        Feb 20 2014 20:04:26
        Copyright (c) Microsoft Corporation
        Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 14393: )

) 

Как видите, и sqlcmd, и запуск PHP-скриптов в командной строке работают!

Но после загрузки тех же PHP-скриптов через FTP и доступа из браузера вот результат:

+ Connection:

Всего одна линия. Затем я обновил php-sqlsrv до 5.6.1-2.el7.remi.7.3.

И конфигурация SELinux была выполнена:

$ sudo setsebool -P httpd_can_network_connect_db 1

Это значения из "getsebool":

httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> on
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> on
httpd_execmem --> off
httpd_graceful_shutdown --> on
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_ipa --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off

Не повезло, все равно получаю те же результаты, что и при использовании версии 5.6.1-1.el7.remi.7.3

Примечание. У меня все еще есть две версии драйвера Microsoft ODBC для SQL Server, 13 и 17 (я не уверен, что это вызывает проблему, и не знаю, как удалить старую версию).

P.S. Я не пробовал другие методы, так как сейчас меня интересует только расширение sqlsrv, поэтому другие могут работать!



Последнее обновление:

Причина. Значение "httpd_can_network_connect" в конфигурации SELinux установлено на "off".

Решение. Включите значение "httpd_can_network_connect" с помощью этой команды.

$ sudo setsebool -P httpd_can_network_connect 1

Затем перезапустите httpd один раз:

$ sudo systemctl перезапустить httpd

Проверьте результат, и теперь все работает как часы!


person 009    schedule 10.04.2019    source источник


Ответы (1)


Извините, но используются все примеры из Microsoft SQL Server. из PHP, я не могу воспроизвести вашу проблему. Подключение работает.

  • проверьте, что сервер готов к клиентским соединениям с сервером
  • проверьте конфигурацию брандмауэра (должно быть разрешено не менее 1433, проверьте с помощью netstat используемые порты)
  • проверить из командной строки с помощью команды sqlcmd (из пакета mssql-tools)
  • проверить из командной строки с помощью простого PHP-скрипта
  • проверьте конфигурацию SElinux (httpd_can_network_connect)

P.S. обратите внимание, что у меня есть небольшое обновление php-sqlsrv, которое правильно извлекает msodbcsql17 вместо msodbcsql.

person Remi Collet    schedule 10.04.2019
comment
Спасибо за информацию. Сервер готов для клиента / я уверен, что перенаправление портов и конфигурация брандмауэра в порядке / не уверен, что я тестировал на sqlcmd (проверю еще раз) / попробую PHP-скрипт в командной строке... больше всего меня интересует ваш PS IMO, это будет конфликт драйверов, но я понятия не имею, как правильно удалить msodbcsql без его зависимостей, поэтому попытаюсь обновить php-sqlsrv. - person 009; 10.04.2019
comment
проверьте selinux (см. значение getsebool / setsebool и httpd_can_network*). Microsoft/msphpsql/issues/679#issuecomment-475783597 - person Remi Collet; 11.04.2019
comment
Поскольку он работает из CLI, проблема, вероятно, связана с конфигурацией SElinux, которая контролирует права HTTP-сервера Apache (а также NGINX с использованием php-fpm) - person Remi Collet; 11.04.2019
comment
На самом деле, я пробовал это заранее, также только что проверил еще раз, но ничего. Однако я только что понял, что установил самозаверяющий сертификат SSL/HTTPS на httpd. Должен ли это быть доверенный корневой ЦС? Если это мешает подключению, как это решить? - person 009; 11.04.2019
comment
Извини, моя ошибка. Проблема решена. Я обновлю свой ОП, большое спасибо. - person 009; 11.04.2019