由systemd启动时,数据库连接到postgresql在mod_wsgi下被flask应用程序拒绝

我有一个奇怪的问题,我试图在Apache下CentOS 7 mod_wsgi下运行一个烧瓶应用程序( https://github.com/pyfarm/pyfarm-master )无法连接到本地postgresql服务器 – 但只有当说apache已经使用systemctl从systemd启动。 如果我在命令行上使用/usr/sbin/httpd -DFOREGROUND手动启动apache(systemd说明使用相同的命令),一切正常。

Apache,Postgresql和mod_wsgi几乎没有改变来自CentOS仓库或EPEL的默认安装。 pyfarm-core和pyfarm-master已经在pip的帮助下安装了。

除了将基于主机的身份validation设置为“信任”localhost的所有内容之外,postgresqlconfiguration与默认值没有任何关系:

 # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust 

之后,我创build了一个用户和一个数据库

 CREATE USER pyfarm WITH PASSWORD 'pyfarmpw'; CREATE DATABASE pyfarm WITH OWNER pyfarm; 

之后我可以用psql用户pyfarmlogin数据库pyfarm。

Apache也与默认configuration几乎没有变化。 我改变的唯一的东西是添加一个新的文件/etc/httpd/conf.d/pyfarm.conf与以下内容:

 <VirtualHost *> ServerName pyfarm.produktion.local ServerAlias pyfarm SetEnv PYFARM_APP_INSTANCE True SetEnv PYFARM_SECRET_KEY 2qgsd4hHaalvAn7 SetEnv PYFARM_CONFIG Prod SetEnv PYFARM_DB_PREFIX "" SetEnv PYFARM_DATABASE_URI postgresql+psycopg2://pyfarm:[email protected]/pyfarm SetEnv TDB_DRIVER psycopg2 WSGIScriptAlias / /var/www/pyfarm/pyfarm.wsgi DocumentRoot /var/www/pyfarm <Directory /var/www/pyfarm> Order allow,deny Allow from all </Directory> </VirtualHost> 

(这些configuration文件中的密码和密钥不是很重要,无论如何都会改变…)

这个文件引用/var/www/pyfarm/pyfarm.wsgi,看起来像这样:

 import os def application(environ, start_response): for key in environ: if key.startswith("PYFARM_") or key.startswith("TDB_"): os.environ[key] = environ[key] from pyfarm.master.entrypoints import app as application_ return application_(environ, start_response) 

(它需要非常复杂,否则应用程序将看不到在apache中设置的环境variables。)

在应用程序中访问任何实际上不需要数据库的页面都可以正常工作,但是一旦我尝试访问这个页面,就会得到500个返回代码,并且在Apache的error_log中出现以下错误:

 [Thu Jul 03 18:01:20.099007 2014] [:info] [pid 18094] mod_wsgi (pid=18094): Initializing Python. [Thu Jul 03 18:01:20.106601 2014] [:info] [pid 18094] mod_wsgi (pid=18094): Attach interpreter ''. [Thu Jul 03 18:01:20.116951 2014] [:error] [pid 18080] \x1b[31m2014-07-03 18:01:20 ERROR - pyfarm.master - Exception on /api/v1/agents/ [GET] [Thu Jul 03 18:01:20.116964 2014] [:error] [pid 18080] Traceback (most recent call last): [Thu Jul 03 18:01:20.116968 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app [Thu Jul 03 18:01:20.116971 2014] [:error] [pid 18080] response = self.full_dispatch_request() [Thu Jul 03 18:01:20.116974 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request [Thu Jul 03 18:01:20.116977 2014] [:error] [pid 18080] rv = self.handle_user_exception(e) [Thu Jul 03 18:01:20.116989 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception [Thu Jul 03 18:01:20.116993 2014] [:error] [pid 18080] reraise(exc_type, exc_value, tb) [Thu Jul 03 18:01:20.116996 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request [Thu Jul 03 18:01:20.116999 2014] [:error] [pid 18080] rv = self.dispatch_request() [Thu Jul 03 18:01:20.117001 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request [Thu Jul 03 18:01:20.117005 2014] [:error] [pid 18080] return self.view_functions[rule.endpoint](**req.view_args) [Thu Jul 03 18:01:20.117007 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/flask/views.py", line 84, in view [Thu Jul 03 18:01:20.117010 2014] [:error] [pid 18080] return self.dispatch_request(*args, **kwargs) [Thu Jul 03 18:01:20.117013 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/flask/views.py", line 149, in dispatch_request [Thu Jul 03 18:01:20.117016 2014] [:error] [pid 18080] return meth(*args, **kwargs) [Thu Jul 03 18:01:20.117019 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/pyfarm/master/api/agents.py", line 412, in get [Thu Jul 03 18:01:20.117021 2014] [:error] [pid 18080] for host in query: [Thu Jul 03 18:01:20.117024 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2405, in __iter__ [Thu Jul 03 18:01:20.117027 2014] [:error] [pid 18080] return self._execute_and_instances(context) [Thu Jul 03 18:01:20.117030 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2418, in _execute_and_instances [Thu Jul 03 18:01:20.117033 2014] [:error] [pid 18080] close_with_result=True) [Thu Jul 03 18:01:20.117037 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2409, in _connection_from_session [Thu Jul 03 18:01:20.117040 2014] [:error] [pid 18080] **kw) [Thu Jul 03 18:01:20.117043 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 846, in connection [Thu Jul 03 18:01:20.117046 2014] [:error] [pid 18080] close_with_result=close_with_result) [Thu Jul 03 18:01:20.117048 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 850, in _connection_for_bind [Thu Jul 03 18:01:20.117051 2014] [:error] [pid 18080] return self.transaction._connection_for_bind(engine) [Thu Jul 03 18:01:20.117054 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 315, in _connection_for_bind [Thu Jul 03 18:01:20.117057 2014] [:error] [pid 18080] conn = bind.contextual_connect() [Thu Jul 03 18:01:20.117060 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1737, in contextual_connect [Thu Jul 03 18:01:20.117063 2014] [:error] [pid 18080] self.pool.connect(), [Thu Jul 03 18:01:20.117065 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/pool.py", line 332, in connect [Thu Jul 03 18:01:20.117068 2014] [:error] [pid 18080] return _ConnectionFairy._checkout(self) [Thu Jul 03 18:01:20.117071 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/pool.py", line 630, in _checkout [Thu Jul 03 18:01:20.117074 2014] [:error] [pid 18080] fairy = _ConnectionRecord.checkout(pool) [Thu Jul 03 18:01:20.117076 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/pool.py", line 433, in checkout [Thu Jul 03 18:01:20.117079 2014] [:error] [pid 18080] rec = pool._do_get() [Thu Jul 03 18:01:20.117082 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/pool.py", line 949, in _do_get [Thu Jul 03 18:01:20.117085 2014] [:error] [pid 18080] return self._create_connection() [Thu Jul 03 18:01:20.117091 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/pool.py", line 278, in _create_connection [Thu Jul 03 18:01:20.117094 2014] [:error] [pid 18080] return _ConnectionRecord(self) [Thu Jul 03 18:01:20.117097 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/pool.py", line 404, in __init__ [Thu Jul 03 18:01:20.117099 2014] [:error] [pid 18080] self.connection = self.__connect() [Thu Jul 03 18:01:20.117102 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/pool.py", line 530, in __connect [Thu Jul 03 18:01:20.117105 2014] [:error] [pid 18080] connection = self.__pool._creator() [Thu Jul 03 18:01:20.117108 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/engine/strategies.py", line 95, in connect [Thu Jul 03 18:01:20.117111 2014] [:error] [pid 18080] connection_invalidated=invalidated [Thu Jul 03 18:01:20.117113 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 189, in raise_from_cause [Thu Jul 03 18:01:20.117116 2014] [:error] [pid 18080] reraise(type(exception), exception, tb=exc_tb) [Thu Jul 03 18:01:20.117119 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/engine/strategies.py", line 89, in connect [Thu Jul 03 18:01:20.117122 2014] [:error] [pid 18080] return dialect.connect(*cargs, **cparams) [Thu Jul 03 18:01:20.117125 2014] [:error] [pid 18080] File "/usr/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 376, in connect [Thu Jul 03 18:01:20.117127 2014] [:error] [pid 18080] return self.dbapi.connect(*cargs, **cparams) [Thu Jul 03 18:01:20.117130 2014] [:error] [pid 18080] File "/usr/lib64/python2.7/site-packages/psycopg2/__init__.py", line 164, in connect [Thu Jul 03 18:01:20.117133 2014] [:error] [pid 18080] conn = _connect(dsn, connection_factory=connection_factory, async=async) [Thu Jul 03 18:01:20.117136 2014] [:error] [pid 18080] OperationalError: (OperationalError) could not connect to server: Permission denied [Thu Jul 03 18:01:20.117138 2014] [:error] [pid 18080] \tIs the server running on host "127.0.0.1" and accepting [Thu Jul 03 18:01:20.117141 2014] [:error] [pid 18080] \tTCP/IP connections on port 5432? [Thu Jul 03 18:01:20.117144 2014] [:error] [pid 18080] None None\x1b[39m 

但是,当我用systemctl stop httpd.service停止apache并使用/usr/sbin/httpd -DFOREGROUND重新启动时,一切正常,包括需要数据库访问的页面。

当Apache像这样运行时,我可以看到在tcpdump -i lo创build和使用数据库连接的应用程序。 从systemd启动Apache时,在tcpdump中不会看到这样的连接,甚至不会看到SYN包。

显然,每次手动启动Apache都不是一个长期的解决scheme。 有没有人知道这里出了什么问题? 也许某种特定于系统的能力限制,使某些服务不能进行出站TCP连接?

启用S​​ELinux后,除非明确指出,否则Web服务器(及其运行的进程,如mod_wsgi和EL 7上的类似服务器进程甚至与Web服务器分开运行)不允许进行传出networking连接允许他们这样做,例如使用SELinux布尔值。

要解决此问题,请将布尔值设置为允许networking连接到数据库:

 setsebool -P httpd_can_network_connect_db 1