So kam es, dass in unserem Unternehmen C # als Hauptsprache für die Backend-Entwicklung ausgewählt wurde. Übrigens waren wir mit dieser Wahl immer zufrieden, und als MS mit der Entwicklung der .net Core-Plattform begann, wurde sie noch interessanter, da C # gut ist, C # unter Linux jedoch noch besser.
Ich werde den Übergangspfad zur plattformübergreifenden Entwicklung nicht beschreiben, da so viele bereits den Übergangspfad von Framework zu Core eingeschlagen haben.
Ich werde mich auf einen Punkt konzentrieren. Docker hat uns unter anderem dazu gedrängt, unsere Anwendungen für Linux zu hosten, weil ich mich wirklich dem Jugendstrom der Containerisierung von allem anschließen wollte, was möglich war.
Da wir ein Unternehmen entwickeln, mussten wir auch Linux mit Pass-Through-Windows-Authentifizierung ausführen. Eigentlich war dies der Anstoß zum Schreiben des Artikels. Da die Informationen sehr schwierig waren, in getrennten Teilen und mit vielen Menschen zu kommunizieren, schien die Idee, alles, was Sie brauchen, an einem Ort zu sammeln und eine Arbeitsoption zu beschreiben, nett zu sein.
Als Lösung wurde unter nginx mit Kerberos-Authentifizierung eine Reverse-Proxy-Option ausgewählt. Damit Genossen aus verschiedenen Projekten die Lösung nutzen konnten, wurde beschlossen, das Docker-Image abzulegen, das das Grundproblem lösen und von anderen geerbt oder unverändert verwendet werden konnte.
Damit Kerberos funktioniert, mussten Sie Nginx mit zusätzlichen Modulen erstellen.
Infolgedessen sind wir zu einem solchen Team gekommen. Alles wird in zwei Aufrufen zusammengeschustert, um weniger Ebenen zu erstellen.
Werfen wir einen Blick auf unsere Docker-Datei. Wir werden auf einem sehr kompakten Bild mit alpinen basieren
FROM alpine:3.7
Als nächstes ziehen wir die erforderlichen Pakete, die Quellen von Nginx und das erforderliche Modul spnego-http-auth-nginx-module fest. Das Ergebnis ist so etwas wie dieser Befehl
ENV NGINX_VERSION 1.15.1 RUN set -ex \ && apk add --no-cache \ git \ krb5 \ krb5-dev \ ca-certificates \ libressl \ pcre \ zlib \ && apk add --no-cache --virtual .build-deps \ build-base \ linux-headers \ libressl-dev \ pcre-dev \ wget \ zlib-dev \ && cd /tmp \ && wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz \ && tar xzf nginx-${NGINX_VERSION}.tar.gz \ && git clone https://github.com/stnoonan/spnego-http-auth-nginx-module.git nginx-${NGINX_VERSION}/spnego-http-auth-nginx-module
Dieser Block wurde separat zugewiesen, damit diese Schicht beim Zusammensetzen aus dem Cache entnommen werden kann, da sie die längste Zeit ist.
Mit den nächsten Befehlen erstellen wir Nginx und bereinigen es, damit das Bild nicht umsonst anschwillt
RUN cd /tmp/nginx-${NGINX_VERSION} \ && ./configure \ \ --prefix=/etc/nginx \ --sbin-path=/usr/sbin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --pid-path=/var/run/nginx.pid \ --lock-path=/var/run/nginx.lock \ --user=nginx \ --group=nginx \ --with-threads \ --with-file-aio \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_addition_module \ --with-http_sub_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_auth_request_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_slice_module \ --with-http_stub_status_module \ --http-log-path=/var/log/nginx/access.log \ --http-client-body-temp-path=/var/cache/nginx/client_temp \ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \ --with-mail \ --with-mail_ssl_module \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ --add-module=spnego-http-auth-nginx-module \ && make -j$(getconf _NPROCESSORS_ONLN) \ && make install \ && sed -i -e 's/#access_log logs\/access.log main;/access_log \/dev\/stdout;/' -e 's/#error_log logs\/error.log notice;/error_log stderr notice;/' /etc/nginx/nginx.conf \ && adduser -D nginx \ && mkdir -p /var/cache/nginx \ && apk del .build-deps \ && rm -rf /tmp/*
Und damit dies alles Sinn macht, erhöhen Sie Nginx
CMD ["nginx", "-g", "daemon off;"]
Wir können davon ausgehen, dass das Image fertig ist. Jetzt stellen wir sicher, dass unser Server Benutzer autorisieren kann.
Um dies zu tun, müssen Sie einen Domain-Administrator finden. Ich hatte großes Glück mit ihm - der Typ reagierte schnell und tat sehr schnell, was er gefragt wurde. Und Sie müssen Folgendes tun.
Angenommen, der Hostname auf dem Hostcomputer lautet "Host-Linux" und Ihre Domain lautet "DOMAIN.LOCAL".
In der Domäne müssen Sie einen Computer mit dem Namen "Host-Linux" starten und ein Konto erstellen, an das wir ihn binden, z. B. "Host-Linux-Benutzer". Als nächstes müssen wir einen SPN erstellen und eine Keytab-Datei generieren, die wir beim Anheben des Containers benötigen.
Unser Team stellte sich als so etwas heraus
C:\Windows\system32>ktpass -princ HTTP/HOST-LINUX.domain.local@DOMAIN.LOCAL -mapuser host-linux-user@DOMAIN.LOCAL -pass yourpassword -cryptoAll -ptype KRB5_NT_PRINCIPAL -out C:\Temp\web.keytab
Nachdem ich die Datei erhalten hatte, konnte ich experimentieren. Als Ergebnis habe ich die folgende nginx.conf erhalten
http { #Whatever is there by default server { listen 80; server_name localhost; #Here kerberos stuff starts auth_gss on; auth_gss_realm DOMAIN.LOCAL; #Keytab file from the mounted folder auth_gss_keytab /home/spnego/config/web.keytab; auth_gss_service_name HTTP/HOST-LINUX.domain.local; auth_gss_allow_basic_fallback off; #Here kerberos stuff ends location / { root html; index index.html index.htm; } #bla-bla-bla
Damit nun alles startet, müssen Sie beim Anheben des Containers die aktuelle nginx.conf ablegen und in die empfangene web.keytab einspeisen. Verwenden Sie dazu Docker-Compose-Magie
version: "2" services: nginx-spnego: image: fclmman/alpine-nginx-spnego
Gehen wir zu dem Verzeichnis, in dem wir docker-compose.yml haben. In unserem Fall sollte sich im selben Ordner das Verzeichnis ./config mit den Dateien nginx.conf und web.keytab befinden. Führen Sie den Befehl aus
docker-compose -f ./docker-compose.yml up -d
Der Behälter erhob sich und starb nicht. Dies gibt Hoffnung auf Erfolg.
Öffnen wir den Browser auf dem Windows-Domänencomputer.
Öffnen Sie auf einer Registerkarte chrome: // net-internals / und notieren Sie die Anfragen, die wir haben. Öffnen Sie auf einer anderen Registerkarte http: // host-linux: 80 / . Kehren wir zu chrome: // net-internals / zurück und sehen uns die Ergebnisse an.
# negotiate t= 3 [st= 3] HTTP_TRANSACTION_READ_RESPONSE_HEADERS --> HTTP/1.1 401 Unauthorized Server: nginx/1.15.1 Date: Fri, 10 Aug 2018 14:15:54 GMT Content-Type: text/html Content-Length: 597 Connection: keep-alive WWW-Authenticate: Negotiate t= 4 [st= 4] HTTP_TRANSACTION_SEND_REQUEST_HEADERS --> GET / HTTP/1.1 Host: host-linux Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Authorization: Negotiate # Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7 t= 4 [st= 4] -HTTP_TRANSACTION_SEND_REQUEST t= 4 [st= 4] +HTTP_TRANSACTION_READ_HEADERS [dt=47] t= 4 [st= 4] HTTP_STREAM_PARSER_READ_HEADERS [dt=47] t=51 [st=51] HTTP_TRANSACTION_READ_RESPONSE_HEADERS --> HTTP/1.1 200 OK Server: nginx/1.15.1 Date: Fri, 10 Aug 2018 14:15:54 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Fri, 10 Aug 2018 12:21:36 GMT Connection: keep-alive WWW-Authenticate: Negotiate # ETag: "5b6d8350-264" Accept-Ranges: bytes
Als Ergebnis sehen wir, dass die Operation erfolgreich war, und wir sehen den Nginx-Begrüßungsbildschirm.
Es lohnt sich, eine Klarstellung zu machen, alles wird nur mit dem Hostnamen funktionieren, aber so wie ich es richtig verstehe, haben wir die Kerberos daran gebunden.
Vielen Dank für Ihre Aufmerksamkeit, wenn Sie bis zu diesem Ort lesen, und ich hoffe wirklich, dass der Artikel nützlich sein wird.