碰巧在我们公司中,C#被选作后端开发的主要语言。 顺便说一下,我们一直对这个选择感到满意,当MS开始开发.net Core平台时,它变得更加有趣,因为C#很好,但是Linux下的C#更好。
我不会描述跨平台开发的过渡路径,因为已经有很多人已经从框架过渡到核心。
我将只关注一点。 除其他事项外,Docker促使我们为Linux托管我们的应用程序,因为我真的很想加入年轻的容器化趋势,即一切可能的事情。
由于我们正在开发企业,因此我们也必须通过Linux进行传递Windows身份验证。 实际上,这就是撰写本文的动力。 由于信息非常困难,需要分开处理,并且需要与许多人进行交流,因此将您需要的所有信息收集在一个地方并描述工作方案的想法似乎不错。
作为解决方案,在具有kerberos身份验证的nginx下选择了反向代理选项。 为了使来自不同项目的同志可以使用该解决方案,因此决定归档docker映像,这将解决基本问题,其他人可以从中继承或按原样使用它。
为了使kerberos正常工作,您必须使用其他模块来构建nginx。
结果,我们组建了这样的团队。 两次调用将所有内容拼凑在一起,以创建更少的图层。
让我们看一下我们的Dockerfile。 我们将基于非常紧凑的高山图像
FROM alpine:3.7
接下来,我们收紧必要的软件包,nginx的来源和必需的模块spnego-http-auth-nginx-module。 结果是这样的命令
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
该块是单独分配的,因此重组时可以从高速缓存中获取此层,因为它的时间最长。
使用下一组命令,我们将构建nginx并将其清理,以使图像不会白白膨胀。
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/*
为了使所有这些都有意义,请提高nginx
CMD ["nginx", "-g", "daemon off;"]
我们可以假设映像已准备就绪,现在我们开始确保服务器具有授权用户的能力。
为此,您需要找到一个域管理员,我对他非常幸运-这个家伙反应灵敏,很快就回答了他的要求。 您需要执行以下操作。
假设主机上的主机名是“ host-linux”,而您的域是“ DOMAIN.LOCAL”。
在域中,您需要启动名称为“ host-linux”的计算机,并创建一个我们将其绑定到的帐户,例如“ host-linux-user”。 接下来,我们需要创建一个SPN并生成一个密钥表文件,这在提起容器时将需要。
我们的团队原来是这样的
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
收到文件后,我可以进行实验。 结果,我得到以下nginx.conf
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
现在,一切开始,抬起容器时,您需要将当前的nginx.conf拖放到该容器上,并将其输入到接收到的web.keytab中。 为此,请使用docker-compose magic
version: "2" services: nginx-spnego: image: fclmman/alpine-nginx-spnego
我们转到拥有docker-compose.yml的目录。 在我们的例子中,包含nginx.conf和web.keytab文件的./config目录应该在同一文件夹中。 运行命令
docker-compose -f ./docker-compose.yml up -d
容器上升了,没有死。 这给成功带来希望。
让我们在域Windows计算机上打开浏览器。
在一个标签中,打开chrome:// net-internals /并写下我们的请求。 在另一个选项卡中,打开http:// // host-linux:80 / 。 让我们回到chrome:// net-internals /并查看结果。
# 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
结果,我们看到该操作成功,并且看到了nginx欢迎屏幕。
有必要澄清一下,所有内容都只能按主机名运行,但据我所知,因为我们将kerberos绑定到了主机名。
感谢您的关注,如果您对这个地方有所了解,我真的希望这篇文章对您有所帮助。