Иногда бывает нужно обеспечить аутентификацию для запускаемых микросервисов при их обращении к внешним источникам данных.
Для этого можно использовать istio, а можно - делать это с помощью вспомогательных контейнеров nginx.
Тут я собираю различные варианты конфигов для nginx, подходящие для аутентификации в разных ситуациях.

proxy_pass с аутентификацией по сертификату

    server {
        listen      8011;

        location / {
            proxy_pass                    https://api.domain.local:8443;
            proxy_ssl_certificate         /etc/nginx/ssl/api.domain.local/client.pem;
            proxy_ssl_certificate_key     /etc/nginx/ssl/api.domain.local/key_nopasswd.pem;
            proxy_ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
            proxy_ssl_ciphers             HIGH:!aNULL:!MD5;
            proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;

            proxy_ssl_verify        on;
            proxy_ssl_verify_depth  2;
            proxy_ssl_session_reuse on;
        }
    }

proxy_pass с kerberos-аутентификацией на upstream

https://blog.inf.ed.ac.uk/squinney/2018/03/29/easy-gssapi-authentication/
https://stackoverflow.com/a/38664954
https://www.ibm.com/support/knowledgecenter/en/SSPT3X_3.0.0/com.ibm.swg.im.infosphere.biginsights.admin.doc/doc/kerberos_webconsole.html
http://www.unstructureddatatips.com/hadoop-rest-api-webhdfs-on-onefs/

С реализацией аутентификации kerberos всё несколько сложнее. Я не нашел готовой реализации этого функционала, поэтому - сделал из подручных средств.
Нужно:

  • иметь nginx с поддержкой lua - openresty
  • установить билиотеки kerberos и настроить krb5.conf
  • curl, nslookup

В моей реализации при попытке ображения к заданному location будет запускаться curl с заданными параметрами (логином, паролем и URL) и возвращать ответ.
То есть весь функционал по реализации аутентификации переездает в curl.
Список переменных среды будет такой:

DOMAIN=domain.local
DOMAIN_USER="username"
DOMAIN_USER_PASS="userpassword"
KRB5_CLIENT_KTNAME=/keytab
KRB5CCNAME=/krb5cc
CURL_CA_BUNDLE=/etc/ssl/certs/ca.pem
CURL_OPTS='--http1.1 -H "Content-Type: application/xml; charset=utf-8" -X POST -v --negotiate -u :'
URL='https://krb-protected-server.domain.local:1111/location/method'
PORT=8088

А стартовый скрипт контейнера такой:

#!/bin/bash
DOMAIN_CONTROLLERS=`nslookup -query=any _ldap._tcp.dc._msdcs.$DOMAIN | grep "_ldap._tcp.dc._msdcs.$DOMAIN" | grep 389 | awk '{print $7}'`
DEFAULT_REALM="${DOMAIN^^}"
#########################################
### Setup Kerberos /etc/krb5.conf
#########################################
LIBDEFAULTS=$(cat <<EOF
[libdefaults]
dns_lookup_kdc = true
dns_lookup_realm = false
default_realm = $DEFAULT_REALM
clockskew = 300
#default_ccache_name = FILE:/tmp/krb5cc_%{uid}
EOF
)

REALMS_KDC=$(for i in $DOMAIN_CONTROLLERS; do echo "kdc = $i";done)

REALMS=$(cat <<EOF

[realms]
$DEFAULT_REALM = {
$REALMS_KDC
default_domain = $DEFAULT_REALM
}
EOF
)

DOMAIN_REALM=$(cat <<EOF

[domain_realm]
.$DOMAIN = $DEFAULT_REALM
$DOMAIN = $DEFAULT_REALM

[appdefaults]
pam = {
        ticket_lifetime = 1d
        renew_lifetime = 1d
        forwardable = true
        proxiable = false
        minimum_uid = 1
}
EOF
)

echo "$LIBDEFAULTS" > /etc/krb5.conf
echo "$REALMS" >> /etc/krb5.conf
echo "$DOMAIN_REALM" >> /etc/krb5.conf

#####################################
### Create keytab and kcc
#####################################
{
printf "%b" "addent -password -p $DOMAIN_USER -k 1 -e aes256-cts-hmac-sha1-96\n" 
sleep 3
printf "%b" "$DOMAIN_USER_PASS\nwrite_kt /$KRB5_CLIENT_KTNAME"
} | ktutil 
kinit -k -t $KRB5_CLIENT_KTNAME $DOMAIN_USER


########################################
### Создаем файл конфига для openresty
########################################
cat <<EOF > /etc/nginx/conf.d/default.conf:

server {
    listen       $PORT;


    location / {
      content_by_lua_block {
        ngx.req.read_body()
        local request_body = ngx.req.get_body_data()
        command = "curl $CURL_OPTS -d '"..request_body.."' $URL";
        local handle = io.popen(command);
        local result = handle:read("*a");
        handle:close();
        ngx.print(result);
      } 
    }
}
EOF

Иногда бывает нужно обеспечить аутентификацию для запускаемых микросервисов при их обращении к внешним источникам данных.
Для этого можно использовать istio, а можно - делать это с помощью вспомогательных контейнеров nginx.
Тут я собираю различные варианты конфигов для nginx, подходящие для аутентификации в разных ситуациях.

FROM openresty/openresty:buster
RUN set -ex \
  && apt-get update \
  && apt-get upgrade -y \
  && apt-get install -y \
  curl \
  krb5-user \
  gss-ntlmssp \
  libsasl2-modules-gssapi-mit \
  ca-certificates
Enter your comment. Wiki syntax is allowed:
 
  • devops/proxy_pass_auth.txt
  • Last modified: 2021/02/11 16:31
  • by admin