如何在 Docker 上的 Apache 服务器 运行 中安装 mod_auth_openidc 模块

How to install mod_auth_openidc module in an Apache server running on Docker

我正在尝试将 mod_auth_openidc module 添加到 Docker 上的 Apache 服务器 运行ning。添加 LoadModule auth_openidc_module modules/mod_auth_openidc.so 后,我创建图像并 运行 它,出现此错误:

httpd: Syntax error on line 69 of /usr/local/apache2/conf/httpd.conf: Cannot load modules/mod_auth_openidc.so into server: libcjose.so.0: cannot open shared object file: No such file or directory

所以我downloaded that dependency并添加了必要的 LoadModule 语句:

LoadModule libcjose_module modules/libcjose.so.0

现在错误是关于 libjansson.so.4:

httpd: Syntax error on line 68 of /usr/local/apache2/conf/httpd.conf: Cannot load modules/libcjose.so.0 into server: libjansson.so.4: cannot open shared object file: No such file or directory

我重复了前面的步骤,从 https://packages.debian.org/wheezy/libjansson4 下载 libjansson.so.4,将其添加到 Docker 文件,Apache 配置 LoadModule libjansson_module modules/libjansson.so.4 和:

httpd: Syntax error on line 67 of /usr/local/apache2/conf/httpd.conf: Can't locate API module structure `libjansson_module' in file /usr/local/apache2/modules/libjansson.so.4: /usr/local/apache2/modules/libjansson.so.4: undefined symbol: libjansson_module

那么如何加载jansson模块呢???

这是我的Docker文件:

FROM httpd:2.4
RUN apt-get update && apt-get install -y \
curl
COPY ./libjansson.so.4 /usr/local/apache2/modules/libjansson.so.4
COPY ./libcjose.so.0 /usr/local/apache2/modules/libcjose.so.0
COPY ./mod_auth_openidc.so /usr/local/apache2/modules/mod_auth_openidc.so
COPY ./my-httpd.conf /usr/local/apache2/conf/httpd.conf

httpd.conf:

LoadModule libjansson_module modules/libjansson.so.4
LoadModule libcjose_module modules/libcjose.so.0
LoadModule auth_openidc_module modules/mod_auth_openidc.so

我没有手动下载必要的库,而是将该过程移至 Dockerfile,现在已正确创建映像:

FROM httpd:2.4

COPY ./my-httpd.conf /usr/local/apache2/conf/httpd.conf
COPY ./server.crt /usr/local/apache2/conf/
COPY ./server.key /usr/local/apache2/conf/
COPY ./mod_auth_openidc.so /usr/local/apache2/modules/mod_auth_openidc.so

RUN apt-get update && apt-get install -y curl && apt-get install -y libjansson4 && apt-get install -y wget && apt-get install -y libhiredis0.10 && apt-get install -y apache2-bin
RUN wget https://github.com/zmartzone/mod_auth_openidc/releases/download/v2.3.0/libcjose0_0.5.1-1.jessie.1_amd64.deb && dpkg -i libcjose0_0.5.1-1.jessie.1_amd64.deb
RUN wget https://github.com/zmartzone/mod_auth_openidc/releases/download/v2.3.3/libapache2-mod-auth-openidc_2.3.3-1.jessie.1_amd64.deb && \
dpkg -i libapache2-mod-auth-openidc_2.3.3-1.jessie.1_amd64.deb

您可以使用 https://github.com/zmartzone/mod_auth_openidc/blob/master/Dockerfile-alpine 来构建图像,之后只需针对您的网站进行 post 配置。

FROM alpine:3.10

ENV MOD_AUTH_OPENIDC_REPOSITORY https://github.com/zmartzone/mod_auth_openidc.git

ENV MOD_AUTH_OPENIDC_BRANCH master

ENV BUILD_DIR /tmp/mod_auth_openidc

ENV APACHE_LOG_DIR /var/log/apache2

ENV APACHE_DEFAULT_CONF /etc/apache2/httpd.conf

# add testing repository (for cjose library)
RUN echo "http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories

# ADD source
RUN mkdir ${BUILD_DIR}

# add dependencies, build and install mod_auth_openidc, need atomic operation for image size
RUN apk update && apk add --no-cache \
  apache2 \
  apache2-proxy \
  wget \
  jansson \
  hiredis \
  cjose \
  cjose-dev \
  git \
  autoconf \
  build-base \
  automake \
  curl \
  apache2-dev \
  curl-dev \
  pcre-dev \
  libtool \
  && \
  cd ${BUILD_DIR} && \
  git clone -b ${MOD_AUTH_OPENIDC_BRANCH} ${MOD_AUTH_OPENIDC_REPOSITORY} && \
  cd mod_auth_openidc && \
  ./autogen.sh && \
  ./configure CFLAGS="-g -O0" LDFLAGS="-lrt" && \
  make test && \
  make install && \
  cd ../.. && \
  rm -fr ${BUILD_DIR} && \
  apk del git cjose-dev apache2-dev autoconf automake build-base wget curl-dev pcre-dev libtool

# configure apache 
RUN  apk add --no-cache sed && \
  echo "LoadModule auth_openidc_module /usr/lib/apache2/mod_auth_openidc.so" >>  ${APACHE_DEFAULT_CONF} && \
  ln -sfT /dev/stderr "${APACHE_LOG_DIR}/error.log" && \
  ln -sfT /dev/stdout "${APACHE_LOG_DIR}/access.log" && \
  ln -sfT /dev/stdout "${APACHE_LOG_DIR}/other_vhosts_access.log" && \
  chown -R --no-dereference "apache:users" "${APACHE_LOG_DIR}" && \
  apk del sed

# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
# stop gracefully when docker stops, create issue with interactive mode because it's the signal use by the docker engine on windows.
STOPSIGNAL WINCH

# port to expose, referes to the Listen 80 in the embedded httpd.conf
EXPOSE 80

# launch apache
CMD exec /usr/sbin/httpd -D FOREGROUND -f ${APACHE_DEFAULT_CONF}

2021 年,zmartzone 模块作为 Debian 软件包提供。所以我能够使用一个简单的 Dockerfile 构建一个图像,但我只需要 https(而不是 php 等)。我选择使用 httpd buster 基础镜像,buster 中的 zmartzone 包版本是 2.3.10.2-1,今天最新最好的是 2.4.9.4。这是我的 Dockerfile,只需要两个命令:

# Build image with Apache HTTPD and OpenID connect module
FROM httpd:2.4-buster

RUN apt-get update && \
    apt-get install --no-install-recommends -y \
    ca-certificates libapache2-mod-auth-openidc

# leave entrypoint etc. unchanged from base image

有一件事我完全不明白,那个 apache httpd 基础镜像 在 /usr/local/apache2/modules 中有模块,但软件包在 /usr/lib/apache2/modules 中安装 auth_openidc_module。也许有人可以向我解释一下?

无论如何,要使此答案完整,使用此图像需要更改基本图像文件 /usr/local/apache2/httpd.conf/usr/local/apache2/extra/httpd-ssl.conf。这是第一组差异:

% diff httpd.conf.orig httpd.conf 
94c98
< #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
---
> LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
142c146
< #LoadModule proxy_module modules/mod_proxy.so
---
> LoadModule proxy_module modules/mod_proxy.so
161c165
< #LoadModule ssl_module modules/mod_ssl.so
---
> LoadModule ssl_module modules/mod_ssl.so
199a204
> LoadModule auth_openidc_module /usr/lib/apache2/modules/mod_auth_openidc.so
241c246
< #ServerName www.example.com:80
---
> ServerName server.my.company.com:80
541c546
< #Include conf/extra/httpd-ssl.conf
---
> Include conf/extra/httpd-ssl.conf

还有extra/httpd-ssl.conf:

% diff httpd-ssl.conf.orig httpd-ssl.conf
125c129
< ServerName www.example.com:443
---
> ServerName server.my.company.com:443
290c294,319
< </VirtualHost>                                  
---
> OIDCProviderMetadataURL https://oidserver.my.company.com/.well-known/openid-configuration
> OIDCClientID my-company-client-id
> OIDCClientSecret my-company-client-scret
> OIDCRedirectURI https://server.my.company.com/secure/redirect_uri
> OIDCCryptoPassphrase my-company-crypto-passphrase
> 
> <Location /secure>
>    AuthType openid-connect
>    Require valid-user
> </Location>
> 
> </VirtualHost>

如果您的容器不信任您的 OIDC 服务器使用的证书,尽管安装了包 ca-certificates,您可能必须将此条目添加到您的 httpd-ssl.conf 文件,但这是一个丑陋的 hack:

# https://github.com/zmartzone/mod_auth_openidc/issues/56
OIDCSSLValidateServer Off

在我的部署中,我选择将那些 httpd 配置文件装载到容器中,这避免了将 OID 客户端机密构建到 docker 映像中。这是一个示例 docker-compose.yml,在 image 行中使用您应用于从上面显示的 Dockerfile 构建的映像的标签:

version: "3"
services:
  # httpd starts as root, binds ports then switches to daemon (UID 1)
  httpd:
    image: httpd-openidc:local
    ports:
      - 80:80
      - 443:443
    volumes:
      - /Users/me/apache-httpd/httpd.conf:/usr/local/apache2/conf/httpd.conf
      - /Users/me/apache-httpd/httpd-ssl.conf:/usr/local/apache2/conf/extra/httpd-ssl.conf
      - /Users/me/apache-httpd/my-dev.key:/usr/local/apache2/conf/server.key
      - /Users/me/apache-httpd/my-dev.crt:/usr/local/apache2/conf/server.crt

到目前为止一切正常,HTH

(2022 年 1 月更新以安装 ca 证书,感谢@uupascal!)