Converting mode_wsgi-express config setup to vanilla mod_wsgi module config

26 views
Skip to first unread message

OwlHoot

unread,
May 12, 2020, 11:06:20 AM5/12/20
to modwsgi

I have used mod_wsgi-express to produce an Apache config, but I would like to convert my httpd.conf file to run Apache using the "vanilla" mod_wsgi module.

My intention from the outset was to use "express" only to get the actual config running, but currently it returns "500 Internal Server" for both "http" and "httpd" URLS, with no error indication that I can see in _any_ of the Apache logs or in the Django app log! I have been struggling with this Apache + Django setup for nearly a week now, despite mod_wsgi-express maybe making it easier.

I can see from the httpd output that all the TLS certificate validation works fine. So that is one less thing to worry about.

As I explained in my previous post, this is all running in a Docker container, and I have managed to install all the relevant Django modules and other modules need by the app in the system-wide python3, by adding the option "--prefix=/usr" to every "pip3 install" and "python3 setup.py install" command in my Dockefile So I can run the httpd server as user "apache" without having to worry about pipenv etc. ( I have no desire whatever to run python in a virtual environment, as I have not used these before and this would add to the many complications besetting me!! In general virtual python environments should not be needed in Docker containers! )

I am aware the present httpd.conf (copied below) is somewhat lax in security. But for now I am _only_ interested in getting the blasted thing to a state where Apache at least works, and only then I will worry about nailing down the security, such as further limiting the "Allow all" scope.

When Apache is running, I don't see a separate process with port 8443 in its name. So I'm not convinced anything is listening on port 8443.


<IfModule !version_module>
LoadModule version_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_version.so'
</IfModule>

Include /application/apache/ssl.conf

ServerName jrsurveys.com
ServerRoot '/application/apache'
PidFile '/application/apache/httpd.pid'

DefaultRuntimeDir '/application/apache'

WSGIScriptAlias / /application/source/bos2.wsgi

ServerTokens ProductOnly
ServerSignature Off

User ${MOD_WSGI_USER}
Group ${MOD_WSGI_GROUP}

Listen 8000
Listen 8443

<IfModule !mpm_event_module>
<IfModule !mpm_worker_module>
<IfModule !mpm_prefork_module>
LoadModule mpm_event_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_mpm_event.so'
</IfModule>
</IfModule>
</IfModule>

<IfModule !access_compat_module>
LoadModule access_compat_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_access_compat.so'
</IfModule>

<IfModule !unixd_module>
LoadModule unixd_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_unixd.so'
</IfModule>

<IfModule !authn_core_module>
LoadModule authn_core_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_authn_core.so'
</IfModule>

<IfModule !authz_core_module>
LoadModule authz_core_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_authz_core.so'
</IfModule>

<IfModule !authz_host_module>
LoadModule authz_host_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_authz_host.so'
</IfModule>

<IfModule !mime_module>
LoadModule mime_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_mime.so'
</IfModule>

<IfModule !rewrite_module>
LoadModule rewrite_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_rewrite.so'
</IfModule>

<IfModule !alias_module>
LoadModule alias_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_alias.so'
</IfModule>

<IfModule !dir_module>
LoadModule dir_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_dir.so'
</IfModule>

<IfModule !env_module>
LoadModule env_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_env.so'
</IfModule>

<IfModule !headers_module>
LoadModule headers_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_headers.so'
</IfModule>

<IfModule !filter_module>
LoadModule filter_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_filter.so'
</IfModule>

<IfModule !reqtimeout_module>
LoadModule reqtimeout_module '${MOD_WSGI_MODULES_DIRECTORY}/mod_reqtimeout.so'
</IfModule>

<IfModule mpm_prefork_module>
</IfModule>

LoadModule wsgi_module '/usr/lib64/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so'

TypesConfig '/etc/mime.types'

HostnameLookups Off
MaxMemFree 64
Timeout 60
ListenBacklog 500

RequestReadTimeout header=15-30,MinRate=500 body=15,MinRate=500

LimitRequestBody 10485760

<Directory />
     AllowOverride None
     Require all granted
     Options FollowSymLinks
</Directory>

WSGIPythonHome '/usr'

WSGIVerboseDebugging 'Off'

WSGISocketPrefix /application/apache/wsgi

WSGISocketRotation Off

WSGIRestrictEmbedded On

WSGIDaemonProcess localhost:8000 \
   display-name='(wsgi:localhost:8000:0)' \
   home='/application/apache' \
   threads=5 \
   maximum-requests=0 \
   python-path='' \
   python-eggs='/application/apache/python-eggs' \
   lang='en_US.UTF-8' \
   locale='en_US.UTF-8' \
   listen-backlog=100 \
   queue-timeout=45 \
   socket-timeout=60 \
   connect-timeout=15 \
   request-timeout=60 \
   inactivity-timeout=0 \
   startup-timeout=15 \
   deadlock-timeout=60 \
   graceful-timeout=15 \
   eviction-timeout=0 \
   restart-interval=0 \
   cpu-time-limit=0 \
   shutdown-timeout=5 \
   send-buffer-size=0 \
   receive-buffer-size=0 \
   response-buffer-size=0 \
   response-socket-timeout=0 \
   server-metrics=Off

WSGICallableObject 'application'
WSGIPassAuthorization On
WSGIMapHEADToGET Auto

WSGIServerMetrics Off

KeepAlive Off

ErrorLog "/application/apache/error.log"
LogLevel warn

<IfModule !log_config_module>
LoadModule log_config_module ${MOD_WSGI_MODULES_DIRECTORY}/mod_log_config.so
</IfModule>
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
LogFormat "undefined" custom
CustomLog "/application/apache/access.log" common

<IfModule !ssl_module>
LoadModule ssl_module ${MOD_WSGI_MODULES_DIRECTORY}/mod_ssl.so
</IfModule>

<IfModule mpm_prefork_module>
ServerLimit 20
StartServers 1
MaxClients 20
MinSpareServers 1
MaxSpareServers 2
MaxRequestsPerChild 0
</IfModule>

<IfModule mpm_worker_module>
ServerLimit 2
ThreadLimit 10
StartServers 1
MaxClients 20
MinSpareThreads 10
MaxSpareThreads 10
ThreadsPerChild 10
MaxRequestsPerChild 0
ThreadStackSize 262144
</IfModule>

<IfModule mpm_event_module>
ServerLimit 2
ThreadLimit 10
StartServers 1
MaxClients 20
MinSpareThreads 10
MaxSpareThreads 10
ThreadsPerChild 10
MaxRequestsPerChild 0
ThreadStackSize 262144
</IfModule>

# See https://httpd.apache.org/docs/2.4/vhosts/name-based.html

<VirtualHost *:8000>
ServerName  jrsurveys.com
ServerAlias jrsurveys.com *.jrsurveys.com
<Directory />
    Require all granted
</Directory>
LogLevel trace4
ErrorLog  /application/apache/error_https.log
CustomLog /application/apache/access_https.log combined
</VirtualHost>

<VirtualHost *:8443>
ServerName  jrsurveys.com
ServerAlias jrsurveys.com *.jrsurveys.com
<Directory />
    Require all granted
</Directory>
LogLevel trace4
ErrorLog  /application/apache/error_https.log
CustomLog /application/apache/access_https.log combined
SSLEngine On
SSLCertificateFile /etc/pki/tls/certs/jrsurveys.com.crt
SSLCertificateKeyFile /etc/pki/tls/private/jrsurveys.com.key
</VirtualHost>

DocumentRoot '/application/apache'

AccessFileName .htaccess

<Directory '/application/apache'>
    AllowOverride None
    RewriteEngine On
    Include /application/apache/rewrite.conf
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule .* - [H=wsgi-handler]
    Require all granted
</Directory>

WSGIHandlerScript wsgi-handler '/application/apache/handler.wsgi' \
    process-group='localhost:8000' application-group=%{GLOBAL}
WSGIImportScript '/application/apache/handler.wsgi' \
    process-group='localhost:8000' application-group=%{GLOBAL}



Regards

John R



Message has been deleted

OwlHoot

unread,
May 12, 2020, 2:06:06 PM5/12/20
to modwsgi
On Tuesday, 12 May 2020 16:06:20 UTC+1, OwlHoot wrote:

I have used mod_wsgi-express to produce an Apache config, but I would like to convert my httpd.conf file to run Apache using the "vanilla" mod_wsgi module.
  :::

Further to my previous post, I have confirmed that the app runs fine (with "http") when run with "django-admin runserver 0.0.0.0:8000"

Also, for reference, some other relevant files are:

myapp.wsgi  (my WSGI script, called "bos2.wsgi" in the previous post, not the handler.wsgi generated by mod_wsgi-express) :

    #!/usr/bin/python3

    import os

    from django.core.wsgi import get_wsgi_application

    os.environ['HTTPS'] = 'on'

    os.environ['wsgi.url_scheme'] = 'https'

    application = get_wsgi_application()


ssl.conf :

    # https://www.linuxminion.com/ssl-session-caching-in-apache-http-webserver/
    # https://stackoverflow.com/questions/20127138/apache-2-4-configuration-for-ssl-not-working
    #
    LoadModule socache_shmcb_module /usr/lib64/httpd/modules/mod_socache_shmcb.so

    SSLSessionCache         shmcb:/run/httpd/sslcache(512000)
    SSLSessionCacheTimeout  300


All the log output looks fine, except for this suspicious output

    [Tue May 12 15:27:40.149404 2020] [wsgi:error] [pid 673:tid 140277188122368] [client 172.31.0.1:36766] Embedded mode of mod_wsgi disabled by runtime configuration: /application/source/myapp.wsgi
    [Tue May 12 15:27:40.149420 2020] [http:trace3] [pid 673:tid 140277188122368] http_filters.c(1128): [client 172.31.0.1:36766] Response sent with status 500, headers:
    [Tue May 12 15:27:40.149424 2020] [http:trace4] [pid 673:tid 140277188122368] http_filters.c(957): [client 172.31.0.1:36766]   Content-Length: 531
    [Tue May 12 15:27:40.149427 2020] [http:trace4] [pid 673:tid 140277188122368] http_filters.c(957): [client 172.31.0.1:36766]   Connection: close
    [Tue May 12 15:27:40.149429 2020] [http:trace4] [pid 673:tid 140277188122368] http_filters.c(957): [client 172.31.0.1:36766]   Content-Type: text/html; charset=iso-8859-1
    [Tue May 12 15:27:40.163487 2020] [http:trace4] [pid 673:tid 140277188654848] http_request.c(437): [client 172.31.0.1:36770] Headers received from client:
    [Tue May 12 15:27:40.163515 2020] [http:trace4] [pid 673:tid 140277188654848] http_request.c(441): [client 172.31.0.1:36770]   Host: jrsurveys.com:8000
    [Tue May 12 15:27:40.163520 2020] [http:trace4] [pid 673:tid 140277188654848] http_request.c(441): [client 172.31.0.1:36770]   User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0)     Gecko/20100101 Firefox/76.0


Not sure why WSGI treats "embedded mode disabled" as an error, because isn't this the recommended config?!


Also, the above log output was for an "https" request, which is what I need to work, and in fact I'd be more than happy to disable "http".


Regards

John R


OwlHoot

unread,
May 12, 2020, 2:14:39 PM5/12/20
to modwsgi
One last file, in case it is relevant. Immediately after an "apachectl start" the log file error_https.log contains the following, none of which looks at all like an error, except possibly "mod_md support is unavailable" :

[Tue May 12 19:08:20.483622 2020] [ssl:info] [pid 2043:tid 140027496089856] AH01914: Configuring server jrsurveys.com:443 for SSL protocol
[Tue May 12 19:08:20.483646 2020] [ssl:debug] [pid 2043:tid 140027496089856] ssl_engine_init.c(1809): AH10083: Init: (jrsurveys.com:443) mod_md support is unavailable.
[Tue May 12 19:08:20.483652 2020] [ssl:trace3] [pid 2043:tid 140027496089856] ssl_engine_init.c(576): Using OpenSSL/system default SSL/TLS protocols
[Tue May 12 19:08:20.483655 2020] [ssl:trace3] [pid 2043:tid 140027496089856] ssl_engine_init.c(597): Creating new SSL context (protocols: default)
[Tue May 12 19:08:20.483837 2020] [ssl:trace1] [pid 2043:tid 140027496089856] ssl_engine_init.c(935): Configuring permitted SSL ciphers [ALL:!COMPLEMENTOFDEFAULT:!eNULL:!aNULL:!eNULL:!EXP]
[Tue May 12 19:08:20.483879 2020] [ssl:debug] [pid 2043:tid 140027496089856] ssl_engine_init.c(489): AH01893: Configuring TLS extension handling
[Tue May 12 19:08:20.484000 2020] [ssl:trace3] [pid 2043:tid 140027496089856] ssl_util_ssl.c(433): [jrsurveys.com:443] modssl_X509_match_name: expecting name 'jrsurveys.com', matched by ID 'jrsurveys.com'
[Tue May 12 19:08:20.484027 2020] [ssl:debug] [pid 2043:tid 140027496089856] ssl_util_ssl.c(444): AH02412: [jrsurveys.com:443] Cert matches for name 'jrsurveys.com' [subject: emailAddress=ad...@jrsurveys.com,CN=jrsurveys.com,OU=IT,O=JR Ltd,L=London,ST=London,C=GB / issuer: emailAddress=ad...@jrsurveys.com,CN=jrsurveys.com,OU=IT,O=JR Ltd,L=London,ST=London,C=GB / serial: 29EDA9A99C38A9305E42248AE412865918FED259 / notbefore: May 11 14:07:54 2020 GMT / notafter: May 11 14:07:54 2021 GMT]
[Tue May 12 19:08:20.484032 2020] [ssl:info] [pid 2043:tid 140027496089856] AH02568: Certificate and private key jrsurveys.com:443:0 configured from /etc/pki/tls/certs/jrsurveys.com.crt and /etc/pki/tls/private/jrsurveys.com.key
[Tue May 12 19:08:20.488789 2020] [ssl:info] [pid 2046:tid 140027496089856] AH01914: Configuring server jrsurveys.com:443 for SSL protocol
[Tue May 12 19:08:20.488803 2020] [ssl:debug] [pid 2046:tid 140027496089856] ssl_engine_init.c(1809): AH10083: Init: (jrsurveys.com:443) mod_md support is unavailable.
[Tue May 12 19:08:20.488806 2020] [ssl:trace3] [pid 2046:tid 140027496089856] ssl_engine_init.c(576): Using OpenSSL/system default SSL/TLS protocols
[Tue May 12 19:08:20.488809 2020] [ssl:trace3] [pid 2046:tid 140027496089856] ssl_engine_init.c(597): Creating new SSL context (protocols: default)
[Tue May 12 19:08:20.489005 2020] [ssl:trace1] [pid 2046:tid 140027496089856] ssl_engine_init.c(935): Configuring permitted SSL ciphers [ALL:!COMPLEMENTOFDEFAULT:!eNULL:!aNULL:!eNULL:!EXP]
[Tue May 12 19:08:20.489044 2020] [ssl:debug] [pid 2046:tid 140027496089856] ssl_engine_init.c(489): AH01893: Configuring TLS extension handling
[Tue May 12 19:08:20.489170 2020] [ssl:trace3] [pid 2046:tid 140027496089856] ssl_util_ssl.c(433): [jrsurveys.com:443] modssl_X509_match_name: expecting name 'jrsurveys.com', matched by ID 'jrsurveys.com'
[Tue May 12 19:08:20.489193 2020] [ssl:debug] [pid 2046:tid 140027496089856] ssl_util_ssl.c(444): AH02412: [jrsurveys.com:443] Cert matches for name 'jrsurveys.com' [subject: emailAddress=ad...@jrsurveys.com,CN=jrsurveys.com,OU=IT,O=JR Ltd,L=London,ST=London,C=GB / issuer: emailAddress=ad...@jrsurveys.com,CN=jrsurveys.com,OU=IT,O=JR Ltd,L=London,ST=London,C=GB / serial: 29EDA9A99C38A9305E42248AE412865918FED259 / notbefore: May 11 14:07:54 2020 GMT / notafter: May 11 14:07:54 2021 GMT]
[Tue May 12 19:08:20.489198 2020] [ssl:info] [pid 2046:tid 140027496089856] AH02568: Certificate and private key jrsurveys.com:443:0 configured from /etc/pki/tls/certs/jrsurveys.com.crt and /etc/pki/tls/private/jrsurveys.com.key


Graham Dumpleton

unread,
May 13, 2020, 12:09:55 AM5/13/20
to mod...@googlegroups.com

On 13 May 2020, at 1:06 am, 'OwlHoot' via modwsgi <mod...@googlegroups.com> wrote:


I have used mod_wsgi-express to produce an Apache config, but I would like to convert my httpd.conf file to run Apache using the "vanilla" mod_wsgi module.

It would be a really bad idea to try and copy what mod_wsgi-express created if you are not experienced in how to configure Apache. That configuration also relies on bits installed by the mod_wsgi Python package, which you wouldn't necessarily have access to. I can't recommend strongly enough, don't try and use the generated configuration. If you insist on configuring Apache manually, start with the Apache default config and system mod_wsgi package and then add bits to it, following the Django documentation (https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/modwsgi/) on what you need to add for it.

What is the reasons you can' t use mod_wsgi-express to do everything? It is designed to be used in containers and make it easy explicitly because setting up Apache yourself to work in a container is painful and hard to get right.

My intention from the outset was to use "express" only to get the actual config running, but currently it returns "500 Internal Server" for both "http" and "httpd" URLS, with no error indication that I can see in _any_ of the Apache logs or in the Django app log! I have been struggling with this Apache + Django setup for nearly a week now, despite mod_wsgi-express maybe making it easier.

So you have in part struggled for a week with this because you don't want to use a Python virtual environment, when you could work out what Python virtual environments are and what they do in an hour or so.

I can see from the httpd output that all the TLS certificate validation works fine. So that is one less thing to worry about.

As I explained in my previous post, this is all running in a Docker container, and I have managed to install all the relevant Django modules and other modules need by the app in the system-wide python3, by adding the option "--prefix=/usr" to every "pip3 install" and "python3 setup.py install" command in my Dockefile So I can run the httpd server as user "apache" without having to worry about pipenv etc. ( I have no desire whatever to run python in a virtual environment, as I have not used these before and this would add to the many complications besetting me!! In general virtual python environments should not be needed in Docker containers! )

And I pointed you at a blog post which laid out why not using a virtual environment is a bad idea.

That it is taking more than a week is because it seems at every point you are choosing the hardest way possible to do things which goes against all advice.

There isn't really much I can do to help you if you are going to go off on a path which is not recommended. It will consume a lot of my time to try and fix the problems you are creating for yourself by not following the guidance as to what is the simpler path. I don't have that much free time.

--
You received this message because you are subscribed to the Google Groups "modwsgi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modwsgi+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/modwsgi/3f36b53b-c370-4bfa-83c2-fef94f9b541a%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages