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/
     &lt;/VirtualHost&gt;
     &lt;/IfModule&gt;
    

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
vrao
  • 117

2 Answers2

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

Turdie
  • 2,564