Quero executar SSL para o servidor web https://www.domainname.com na porta 443 e o servidor python REST api https://mgmt.domainname.com com Flask. Eu configurei o Apache SSL e ele está rodando em 443. Executei um programa python simples do flask
import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Howdy world!'
if __name__ == "__main__":
app.run(ssl_context='adhoc')
Saída:
* 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
Habilitou o seguinte:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo systemctl restart apache2
Questões:
O servidor web e o programa python podem escutar em 443? A única diferenciação seriam URLs separados para servidor web e API REST. Eu li que preciso implementar o Apache mod_ssl. Portanto, modifique o arquivo /etc/apache2/sites-available/default-ssl.conf existente para proxy reverso
<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>
Não sei se esta modificação do Proxy Reverso é boa o suficiente ou o que mais precisa ser feito?
Devo modificar o servidor WSGI com este código:
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()
Da mesma forma, daqui para frente, a API REST deve ser capaz de chamar diferentes partes do programa Python com base no caminho/parâmetros de consulta de URL, o que significa que algum tipo de roteamento precisa ser configurado usando Apache mod_proxy e mod_ssl ou algum aspecto do servidor WSGI? Quero saber por onde e como começar: Configure o Apache e ou WSGI. Entendo que há outros problemas que precisam ser resolvidos em qualquer caminho. Por favor, informe para que eu possa começar e avançar gradativamente
EDIÇÕES: Seguiu o URL de exemplo fornecido por @vidarlo Editou /etc/apache2/sites-available/default-ssl.conf e adicionou o código VirtualHost conforme sugerido para encaminhar https://api.domainname.com para localhost:5000. Iniciou um servidor WSGI na porta 5000 assim: conteúdo do arquivo wsgi.py:
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()
Executei python3 wsgi.py e verifiquei que o processo está sendo executado na porta 5000. Agora, quando acesso https:// https://api.domainname.com , recebo um pop-up de erro na janela do meu console como este:
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
Não se eles estiverem vinculados ao mesmo endereço IP. A configuração usual é executar a API no host local apenas em uma porta diferente e usar o Apache (ou nginx) para fazer proxy reverso da URL específica para a API. Nesse caso, o Apache também cuidaria de encerrar o TLS, portanto, nenhum TLS adicional precisaria ser implementado para a API.
Não, dois serviços não podem escutar na mesma porta. Qual é a prática mais comum: permitir que o Apache ou Nginx seja executado em 443 e faça proxy com Apache ou Nginx para suas cargas de trabalho em execução em uma porta diferente. O Apache ou Nginx então busca o conteúdo da carga de trabalho e o apresenta da mesma maneira que estava sendo executado no 443. Isso requer a configuração adequada das configurações de proxy no Apache ou Nginx. Também apresenta uma camada de segurança porque a carga de trabalho não é apresentada diretamente à Internet, mas é servida pelo Apache ou nginx