0

I want to run SSL for web server https://www.domainname.com on port 443 and python REST api server https://mgmt.domainname.com with Flask. I have configured Apache SSL and it is running on 443. I ran a simple python program from flask

import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Howdy world!'

if __name__ == "__main__":
    app.run(ssl_context='adhoc')

Output:

* Serving Flask app 'backend2'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on https://127.0.0.1:5000

Enabled the following:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo systemctl restart apache2

Questions:

  1. Can both web server and python program listen on 443? The only differentiation would be seperate URLs for web server and REST api. I read that I need to implement Apache mod_ssl. So modify existing /etc/apache2/sites-available/default-ssl.conf file for Reverse proxy

         <IfModule mod_ssl.c>
         <VirtualHost _default_:443>
         DocumentRoot /srv/www/wordpress
         ServerName www.domain-name.com
         SSLEngine on
         SSLCertificateFile /root/cert/domainname.com.crt
         SSLCertificateKeyFile /root/cert/domainname.com.key
    
         ProxyPreserveHost On
         ProxyPass / http://IPAddr:443/
         ProxyPassReverse / http://IPAddr:443/
         </VirtualHost>
         </IfModule>
    

Don't know if this modification for Reverse Proxy is good enough or what else needs to be done?

  1. Should I modify WSGI server with this code:

    import wsgiserver
    
    def my_app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['WSGIserver is running!']
    server = wsgiserver.WSGIServer(my_app, certfile='cert.pem', keyfile='privkey.pem')
    server.start()
    

Also going forward the REST api should be able to call different parts of Python program based on URL query path/parameters, which means some kind of routing needs to be set up using Apache mod_proxy and mod_ssl or some aspect of WSGI server? I want to know where and how to start: Configure Apache and or WSGI. I understand there are other issues that need to be resolved in either path. Please advise so I can start and move incrementally

EDITS: Followed the example URL given by @vidarlo Edited /etc/apache2/sites-available/default-ssl.conf and added VirtualHost code as suggested to forward the https://api.domainname.com to localhost:5000. Started a WSGI server on port 5000 like this: wsgi.py file contents:

import wsgiserver
def gs_app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['WSGIserver is running!']
server = wsgiserver.WSGIServer(gs_app, host='127.0.0.1', port=5000)
server.start()

Ran python3 wsgi.py & Verified the process is running on port 5000 Now when I access https:// https://api.domainname.com I get error popup in my console window like this:

ValueError('WSGI Applications must yield bytes')
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/wsgiserver.py", line 1394, in communicate
    req.respond()
  File "/usr/local/lib/python3.8/dist-packages/wsgiserver.py", line 848, in respond
    self.server.gateway(self).respond()
  File "/usr/local/lib/python3.8/dist-packages/wsgiserver.py", line 2347, in respond
    raise ValueError("WSGI Applications must yield bytes")
ValueError: WSGI Applications must yield bytes
6
  • 2
    Does this answer your question? How can I forward requests from my web server?
    – vidarlo
    Dec 4 at 0:32
  • @vidarlo what you suggested almost works, with the exception of an error. I edited the original posting above with the changes and error output. Can you please review and suggest?
    – vrao
    2 days ago
  • Then your wsgi application is misconfigured. Go back to a state where it works and proxy that...
    – vidarlo
    2 days ago
  • It never worked. What do you mean go back to a state where it worked? may be my wsgi server config is not right or my program mostly. Dont know how to fix it, searching ..
    – vrao
    yesterday
  • worked just had to return bytes. I have upvoted your response.
    – vrao
    yesterday

2 Answers 2

1

Can both web server and python program listen on 443? The only differentiation would be seperate URLs for web server and REST api

Not if they are bound to the same IP address. The usual setup is to run the API on localhost only on a different port and use Apache (or nginx) to reverse proxy the specific URL to the API. In this case Apache would also take care of terminating TLS, so no additional TLS need to be implemented for the API.

1

No, two services can't listen on the same port. What the most common practice is to, to let Apache or Nginx run on 443, and proxy with apache or Nginx to your workloads running on a different port. Apache or Nginx then fetches the content of the workload and present it the same way as it was running on 443. That does require proper configuration of the proxy settings within apache or Nginx. It also presents a layer of security because the workload isn't directly presented to the internet, but is served by apache or nginx

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .