Реализация mtls с phpPhp

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Реализация mtls с php

Сообщение Anonymous »

Я хочу получить mTLS на фиктивной веб-странице PHP от гостя к моему серверу Openldap.
У меня проблема, и кажется, что мой php никогда не отправляет сертификат клиента на мой сервер даже тогда, когда я указал соответствующие параметры. У меня установлен PHP 8.2 на моем гостевом клиенте, а версия slapd для моего сервера openldap находится в версии 2.5.13.
Я включил TLS и принудительно включил взаимный TLS (mTLS) на моем сервере:
olcTLSCACertificateFile: /etc/ldap/certs/issuing_ca.crt
olcTLSCertificateFile: /etc/ldap/certs/ldap.test.local.crt
olcTLSCertificateKeyFile: /etc/ldap/certs/ldap.test.local.key
olcTLSVerifyClient: demand

Я могу успешно подключиться к ldapsearch в csh с помощью сертификата клиента от гостя, поэтому они верны и действительны:
setenv LDAPTLS_CACERT /var/run/certs/f03dd1db.crt
setenv LDAPTLS_CERT /var/run/certs/229c13f4.crt
setenv LDAPTLS_KEY /var/run/certs/229c13f4.key
ldapsearch -H ldaps://ldap.domain.local -b "dc=domain,dc=local" -D "uid=ldap_srv,ou=users,dc=domain,dc=local" -W -d 256 -x -LLL

Однако я не могу заставить его работать с моим PHP:
function simple_test(){
$ldapUri = 'ldaps://ldap.domain.local:636';
$caFile = '/var/run/certs/f03dd1db.crt';
$certFile = '/var/run/certs/229c13f4.crt';
$keyFile = '/var/run/certs/229c13f4.key';
$ldapbindun = 'uid=ldap_srv,ou=users,dc=domain,dc=local';
$ldapbindpw = 'password';

$ldapOptions = [
LDAP_OPT_X_TLS_CACERTFILE => $caFile,
LDAP_OPT_X_TLS_CERTFILE => $certFile,
LDAP_OPT_X_TLS_KEYFILE => $keyFile,
LDAP_OPT_PROTOCOL_VERSION => 3,
LDAP_OPT_REFERRALS => 0,
];
//set global options
foreach($ldapOptions as $k => $v) {
ldap_set_option(null, $k, $v);
}

$error = false;
// initial connection seems to work and return success:
if (!($ldapResource = ldap_connect($ldapserver))) {
$error = true;
}
// Also tried to set options here especially for $ldap without luck also :
//ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, "/var/run/certs/229c13f4.crt");
//ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, "/var/run/certs/229c13f4.key");
//try to bind and check for errors (that I have):
//Same error if I switch to ldap_bind($ldapResource)
if (!($res = ldap_bind($ldapResource, $ldapbindun, $ldapbindpw))) {
$error = true;
}

if ($error == true) {
ldap_get_option($ldapResource, LDAP_OPT_DIAGNOSTIC_MESSAGE, $errMsg);
log_error(sprintf(gettext("%s (%d): %s\n"),ldap_error($ldapResource), ldap_errno($ldapResource),$errMsg));
@ldap_close($ldapResource);
}
}

Журналы клиентов показывают мне:
LDAP bind failed: Can't contact LDAP server (-1):

Журналы сервера показывают мне:
slap_listener_activate(8):
>>> slap_listener(ldaps:///)
conn=1022 fd=14 ACCEPT from IP=:32896 (IP=0.0.0.0:636)
connection_get(14): got connid=1022
connection_read(14): checking for input on id=1022
connection_get(14): got connid=1022
connection_read(14): checking for input on id=1022
TLS: can't accept: Certificate is required..
connection_read(14): TLS accept failure error=-1 id=1022, closing
connection_close: conn=1022 sd=14
conn=1022 fd=14 closed (TLS negotiation failure)

Однако, когда я печатаю параметры $ldap непосредственно перед привязкой, кажется, что все правильно:
Option LDAP_OPT_DEREF: 'LDAP_DEREF_SEARCHING (Searching)'
Option LDAP_OPT_SIZELIMIT: 0
Option LDAP_OPT_TIMELIMIT: 25
Option LDAP_OPT_NETWORK_TIMEOUT: 25
Option LDAP_OPT_PROTOCOL_VERSION: '3 (LDAPv3)'
Option LDAP_OPT_ERROR_NUMBER: -1
Option LDAP_OPT_ERROR_STRING: Unable to retrieve value
Option LDAP_OPT_REFERRALS: '0 (Disable)'
Option LDAP_OPT_RESTART: '0 (Disable)'
Option LDAP_OPT_HOST_NAME: 'ldap.domain.local:636'
Option LDAP_OPT_MATCHED_DN: Unable to retrieve value
Option LDAP_OPT_SERVER_CONTROLS: Unable to retrieve value
Option LDAP_OPT_CLIENT_CONTROLS: Unable to retrieve value
Option LDAP_OPT_X_KEEPALIVE_IDLE: 0
Option LDAP_OPT_X_KEEPALIVE_PROBES: 0
Option LDAP_OPT_X_KEEPALIVE_INTERVAL: 0
Option LDAP_OPT_X_TLS_CACERTDIR: '/var/run/certs'
Option LDAP_OPT_X_TLS_CACERTFILE: '/var/run/certs/f03dd1db.crt'
Option LDAP_OPT_X_TLS_CERTFILE: '/var/run/certs/229c13f4.crt'
Option LDAP_OPT_X_TLS_CIPHER_SUITE: Unable to retrieve value
Option LDAP_OPT_X_TLS_CRLCHECK: 'LDAP_OPT_X_TLS_CRL_NONE (No CRL Checking)'
Option LDAP_OPT_X_TLS_CRLFILE: Unable to retrieve value
Option LDAP_OPT_X_TLS_DHFILE: Unable to retrieve value
Option LDAP_OPT_X_TLS_KEYFILE: '/var/run/certs/229c13f4.key'
Option LDAP_OPT_X_TLS_PACKAGE: 'OpenSSL'
Option LDAP_OPT_X_TLS_PROTOCOL_MIN: 'LDAP_OPT_X_TLS_PROTOCOL_SSL2 (SSLv2)'
Option LDAP_OPT_X_TLS_REQUIRE_CERT: 'LDAP_OPT_X_TLS_HARD (Hard)'
Option LDAP_OPT_X_TLS_RANDOM_FILE: Unable to retrieve value

Но почему-то мой PHP явно делает что-то не так. Если я верю этому комментарию пользователя из руководства по PHP или этому комментарию из проекта github php, это должно сработать. Я не понимаю, в чем здесь проблема.
РЕДАКТИРОВАТЬ
По мере того, как мои тесты продолжаются, ситуация становится супер странно.
Вызвав один и тот же файл test.php от root и из cli как
env -i php -c /usr/local/etc/php.ini -d scan.dir=/usr/local/etc/php /usr/local/www/test.php все работает, сертификаты отправляются, привязка прошла успешно.
При получении этого же файла с моего веб-сервера (nginx/1.24.0) это не удается.
Мои журналы чисты:
  • Файл CA (это цепочка) установлен /var /run/certs/f03dd1db.0
  • Файл сертификата имеет значение /var/run/certs/229c13f4.crt
  • Файл ключа установлен. в /var/run/certs/229c13f4.key
Все эти три файла в обоих случаях корректно прочитаны (и записаны в мой debug.log из моего test.php)
Кажется, что ldap_connect работает в обоих сценариях, но тогда работает только ldap_bind при вызове в cli env -i php -c /usr/local/etc/php.ini -d scan.dir=/usr/local/etc/php /usr/local/www/test.php, но не при доступе с моего веб-сервера nginx.
Чтобы быть как можно ближе к моей среде nginx в cli (получил информацию, вызвав phpinfo() из test.php и проверив значения при обращении к nginx):
  • Я очищаю свою среду с помощью env -i
  • Я устанавливаю точно такой же загруженный файл конфигурации -c /usr /local/etc/php.ini
  • Я также сканирую этот каталог на наличие дополнительных файлов .ini -d scan.dir=/usr/local/etc/php
Тем не менее, работайте в cli, а не с моего веб-сервера.
EDIT2
Для информации я использую Nginx + PHP-FPM.
Вот моя очень простая конфигурация nginx:
#
# nginx configuration file

user root wheel;
error_log /var/log/nginx/error.log;

events {
worker_connections 1024;
}

http {
include /usr/local/etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;

server {
listen 80;
listen [::]:80;
root "/usr/local/www/";

location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.socket;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_read_timeout 180;
include /usr/local/etc/nginx/fastcgi_params_dummy;
}

}
}

И мой fastcgi_params_dummy будет таким:
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

Я пытался жестко запрограммировать значения, добавив эти строки, результат не изменился.
fastcgi_param LDAPTLS_CERT /var/run/certs/229c13f4.crt;
fastcgi_param LDAPTLS_KEY /var/run/certs/229c13f4.key;
fastcgi_param LDAPTLS_CACERT /var/run/certs/f03dd1db.0;


Подробнее здесь: https://stackoverflow.com/questions/792 ... s-with-php
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»