I have an api service that i wrote with FastApi and served with gunicorn. Apache is working on the server as reverse proxy and ssl manage.
Everything was fine until i decided to use SqlAdmin as admin panel.
The problem is that my api endpoints works fine with SSL but SqlAdmin endpoints are not.
e.g: Responses i get when i want reach https://example.com/admin: (FAIL)
--- I summarized responses ---
307 Temporary Redirect -> http://example.com/admin
302 Not Found
Somehow redirect -> https://example.comadmin/
e.g: Responses i get when i want reach https://example.com/users: (PASS) (API ENDPOINT)
Request URL: https://example.com/users/
Request Method: GET
Status Code: 200 OK
Apache Configuration:
<VirtualHost ip:80>
ServerName subdomain.example.com
ServerAlias www.subdomain.example.com
ServerAdmin ****#gmail.com
Redirect / https://subdomain.example.com
</VirtualHost>
<VirtualHost ip:443>
ServerName subdomain.example.com
ServerAlias www.subdomain.example.com
ServerAdmin ******#gmail.com
ProxyRequests On
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLEngine on
SSLCertificateFile *****
ProxyPass / http://example.com:8000/
ProxyPassReverse / http://example.com:8000/
<Location />
Order allow,deny
Allow from all
</Location>
</VirtualHost>
Gunicorn Configuration:
import json
import multiprocessing
import os
workers_per_core_str = os.getenv("WORKERS_PER_CORE", "1")
max_workers_str = os.getenv("MAX_WORKERS")
use_max_workers = None
if max_workers_str:
use_max_workers = int(max_workers_str)
web_concurrency_str = os.getenv("WEB_CONCURRENCY", None)
host = os.getenv("HOST", "0.0.0.0")
port = os.getenv("PORT", "80")
bind_env = os.getenv("BIND", None)
use_loglevel = os.getenv("LOG_LEVEL", "warning")
if bind_env:
use_bind = bind_env
else:
use_bind = f"{host}:{port}"
cores = multiprocessing.cpu_count()
workers_per_core = float(workers_per_core_str)
default_web_concurrency = workers_per_core * cores
if web_concurrency_str:
web_concurrency = int(web_concurrency_str)
assert web_concurrency > 0
else:
web_concurrency = max(int(default_web_concurrency), 2)
if use_max_workers:
web_concurrency = min(web_concurrency, use_max_workers)
accesslog_var = os.getenv("ACCESS_LOG", "/var/log/gunicorn/access_log")
use_accesslog = accesslog_var or "/var/log/gunicorn/access_log"
errorlog_var = os.getenv("ERROR_LOG", "/var/log/gunicorn/error_log")
use_errorlog = errorlog_var or "/var/log/gunicorn/error_log"
graceful_timeout_str = os.getenv("GRACEFUL_TIMEOUT", "120")
timeout_str = os.getenv("TIMEOUT", "120")
keepalive_str = os.getenv("KEEP_ALIVE", "5")
# Gunicorn config variables
loglevel = use_loglevel
workers = web_concurrency
bind = use_bind
errorlog = use_errorlog
worker_tmp_dir = "/dev/shm"
accesslog = use_accesslog
graceful_timeout = int(graceful_timeout_str)
timeout = int(timeout_str)
keepalive = int(keepalive_str)
# For debugging and testing
log_data = {
"loglevel": loglevel,
"workers": workers,
"bind": bind,
"graceful_timeout": graceful_timeout,
"timeout": timeout,
"keepalive": keepalive,
"errorlog": errorlog,
"accesslog": accesslog,
# Additional, non-gunicorn variables
"workers_per_core": workers_per_core,
"use_max_workers": use_max_workers,
"host": host,
"port": port,
}
print(json.dumps(log_data))
I dont have any idea how this behavior happend at all so any clue would be helpful :)
Thanks in advance.
I did try to add middleware to the FastApi. HTTPSRedirectMiddleware.
every requests reached to this response on gunicorn:
WARNING: Invalid HTTP request received.
I did try to start gunicorn with --forwarded-allow-ips='*' and --proxy-headers.
Nothing changed.
Related
I use ASP .NET CORE 2.
I use this code in Startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
options.AccessDeniedPath = new PathString(/Account/AccessDenied);
options.ExpireTimeSpan = TimeSpan.FromMinutes(3 * 60 + 1);
});
I am not login so my website redirects to
https://localhost/Account/Login?ReturnUrl=%252Fbbb.
It works in development. I get the URL
https://aaaaa.com/?ReturnUrl=%252Fbbb in production.
How to fix it? I searched Google but was unable to find anything.
My Apache proxy file 000-default.conf
<VirtualHost *:80>
ServerName aaaaa.com
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/ [R,L]
</VirtualHost>
<VirtualHost *:443>
ProxyPreserveHost On
ProxyPass "/" "http://localhost:5000/"
ProxyPassReverse "/" "http://localhost:5000/"
ErrorLog /var/log/httpd/aaaaa-error.log
CustomLog /var/log/httpd/aaaaa-access.log common
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
</VirtualHost>
The code in Startup.cs
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
options.AccessDeniedPath = new PathString(/Account/AccessDenied);
options.Events.OnRedirectToLogin = context =>
{
LogManager.GetLogger(this.GetType()).Info("OnRedirectToLogin->RedirectUri: " + context.RedirectUri);
#if DEBUG
context.Response.Redirect(context.RedirectUri);
#else
string strURL = context.RedirectUri.ToLower();
if (strURL.StartsWith("http://"))
{
strURL = strURL.Replace("http://", "https://", StringComparison.CurrentCultureIgnoreCase);
}
context.Response.Redirect(strURL);
#endif
return Task.CompletedTask;
};
});
Logging shows HTTP protocol http://aaaaa.com/Account/Logon?ReturnUrl=%252Fbbb and then Apache
redirect to HTTPS while cutting Account/Logon from URL.
Solution is simple replace HTTP with HTTPS so Apache won't redirects.
Edward and MarkG, I appreciate your hints!
We have a site running on Next.js and Express. This is on a cPanel server with Aapche and together with nginx serving as reverse proxy.
I need to have ssl on the site. But I am quite confuused with how the configurations should be.
My server.js :
const express = require('express')
const next = require('next')
const https = require('https');
const fs = require('fs');
//const forceSSL = require('express-force-ssl')
var ssl_options = {
key: fs.readFileSync('/home/myreactsite.key'),
cert: fs.readFileSync('/home/myreactsite.crt'),
};
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const favicon = require('serve-favicon')
const path = require('path')
app.prepare()
.then(() => {
const server = express()
server.use(favicon(path.join(__dirname, 'static', 'images', 'favicon.ico')))
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3007, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3007')
})
var httpsServer = https.createServer(ssl_options,server).listen('8445', (err) => {
if (err) throw err
console.log('> Ready on https://localhost:8445')
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
Apache runs on 8080
Nginx runs on 80
Next.js runs on both 3007 and 8445(I prefer it for ssl)
My Apache config contains the following to hide the port 3007
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://myreactsite.com:3007/
The site works fine if I access it as http://myreactsite.com . But it fails when I access https://myreactsite.com though I can access https version by specifying the port number as https://myreactsite.com:8445
I want to make it work without specifying the https port.
How can I get my site to force all pages to https without specifying the port?
You probably want to use Apache for all the SSL handling and listen to the 443 port, then proxy to your 3007 port. Try this config:
<VirtualHost *:443>
ProxyPreserveHost On
ProxyRequests Off
ServerName myreactsite.com
ServerAlias myreactsite.com
ProxyPass / http://0.0.0.0:3007/
ProxyPassReverse / http://0.0.0.0:3007/
SSLEngine On
SSLProxyEngine On
SSLCertificateFile /home/myreactsite.crt
SSLCertificateKeyFile /home/myreactsite.key
</VirtualHost>
To redirect all HTTP traffic then:
<VirtualHost *:80>
ServerName myreactsite.com
Redirect / https://myreactsite.com/
</VirtualHost>
Based on #fabian comment, I am posting my working configurations if it helps someone...
Added the following lines in the 443 virtual host section for the site in apache.conf :
ProxyPreserveHost On
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://example.com:3000/
ProxyPassReverse / http://example.com:3000/
SSLProxyEngine On
#To redirect to https and www version
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
Also, added the following line in the nginx vhost file for the site :
server {
...
...
#To redirect all http requests to https+www
return 301 https://www.example.com$request_uri;
...
...
}
I have configure apache2 into my ubuntu 14.04 with odoo.DB has over 100000 records i for partners. So we are loading them into background. Same way products are also loading. Products are loading fine, but partner are not loading. Can any one help me with this.
apache proxy configuration.
`
ServerName odoo-bhaviraj.com
ServerAlias odoo-bhaviraj.com
LogLevel warn
ErrorLog /var/log/apache2/odoo-bhaviraj.com.error.log
CustomLog /var/log/apache2/odoo-bhaviraj.com.access.log combined
ProxyRequests Off
ProxyPreserveHost On
ProxyVia full
ProxyTimeout 18000
KeepAlive On
ProxyPass / http://localhost:8069/
ProxyPassReverse / http://localhost:8069/
ProxyPass / http://127.0.0.1:8069/
ProxyPassReverse / http://127.0.0.1:8069/
</VirtualHost>
odoo.conf file
[options]
; This is the password that allows database operations:
admin_passwd = admin
db_host = localhost
db_port = 5432
db_user = acespritech
db_password = 123456
addons_path = /home/bhaviraj/project/erp/odoo/odoo_8/addons
## Logging Group - Logging Configuration
logfile = /var/log/odoo/odoo-server.log
logrotate = True
syslog = False
log_level = debug
log_handler = [':INFO']
log_level = info
db_filter = .*
workers = 4
proxy_mode = True
limit_memory_soft = 671088640
limit_memory_hard = 805306368
limit_time_cpu = 3000
limit_time_real = 3000
limit_request = 8192
max_cron_threads = 0
xmlrpc_interface = 127.0.0.1
longpolling_port = 8072`
It's very simple, execute this commande :
sudo gedit /etc/apache2/apache2.conf
And, verify the Timeout (The number of seconds before receives and sends time).
Timeout 300
I can't workout how to get WebSockets to work when I deploy my meteor app online. I keep getting this error:
WebSocket connection to 'ws://website.com/sockjs/***/********/websocket' failed: Unexpected response code: 400
I think this is due to the fact that apache sits in front of my meteor app. I know Apache 2.4 had a bug to make ws:// working, but I think this should be resolved by modules/mod_proxy_wstunnel.so, which I have enabled (of course I have enabled also modules/mod_proxy.so)
Here's my config. I'm running Meteor 1.2.1 as a systemd service (/etc/systemd/system/meteor.service) like so:
[Unit]
Description=meteor nodejs daemon
After=network.target remote-fs.target
[Service]
User=root
ExecStart=/usr/bin/node /home/root/www/main.js
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=meteor
Environment=ROOT_URL=http://website.com
Environment=PORT=3000
Environment=NODE_ENV=production
Environment=MONGO_URL=mongodb://127.0.0.1:27017/meteor
[Install]
WantedBy=multi-user.target
This is the output of httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built: Aug 28 2015 22:11:18
And this is the relevant part in my vhost config (/etc/httpd/conf/httpd.conf) for website.com:
<VirtualHost my.ser.ver.ip:8080>
ServerName website.com
ServerAlias www.website.com
ProxyRequests Off
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
<Proxy *>
Allow from all
</Proxy>
</VirtualHost>
I've already tried to add the RewriteCond as suggested here but no success...
Any idea? I'm also having issue getting oauth to work with the accounts-facebook package and I guess the problem is for the same reason? As in, there is something wrong in my proxy settings?
Solved the mystery. Of course it was my bad: I forgot all about Varnish.
I had Varnish set on port 80 forwarding the request to Apache, which was in turn proxying the request to node.js. I resolved by removing apache and thus configuring Varnish to serve straight to node.js for that specific domain.
This is what I did:
Implemented this default.vcl in /etc/varnish/
Removed import directors and all the content inside sub vcl_init {} (as I only have a single server)
Replaced set req.backend_hint = vdir.backend(); in sub vcl_recv {} with:
if (req.http.Host ~ "^(www\.)?website.com") {
set req.backend_hint = nodejs;
} else {
set req.backend_hint = apache;
}
Created the two backends like so:
backend apache {
.host = "127.0.0.1";
.port = "8080";
.max_connections = 300;
.probe = {
.request =
"HEAD / HTTP/1.1"
"Host: localhost"
"Connection: close";
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
}
.first_byte_timeout = 300s;
.connect_timeout = 5s;
.between_bytes_timeout = 2s;
}
backend nodejs {
.host = "127.0.0.1";
.port = "3000";
.connect_timeout = 1s;
.first_byte_timeout = 2s;
.between_bytes_timeout = 60s;
.max_connections = 800;
}
I wrote a cherrypy application and now I need SSL. I am working with apache/wsgi and have a working python file running and returning pages. Now I am trying to get POSTs to work.
This is my working script:
import sys
sys.stdout = sys.stderr
import atexit
import threading
import cherrypy
cherrypy.config.update({'environment': 'embedded'})
if cherrypy.engine.state == 0:
cherrypy.engine.start(blocking=False)
atexit.register(cherrypy.engine.stop)
class Root(object):
def index(self):
# restrict access by ip address
clientIP = cherrypy.request.headers["Remote-Addr"]
if clientIP not in self.allowedIPs:
return "Access Denied"
return cherrypy.url()
index.exposed = True
allowedIPs = ["127.0.0.1", "192.168.174.1"]
application = cherrypy.Application(Root(), None)
If i make modifications to catch the post:
class Root(object):
def index(self, files):
I receive the following error:
<h2>404 Not Found</h2>
<p>Nothing matches the given URI</p>
My apache config,
WSGISocketPrefix run/wsgi
NameVirtualHost *:443
<VirtualHost *:443>
DocumentRoot /var/www/ssl_html
ServerName 192.168.174.130:443
ServerAlias 192.168.174.130
SSLEngine On
SSLCertificateFile /etc/ssl/certs/devel.crt
SSLCertificateKeyFile /etc/ssl/certs/devel.key
<Location />
SSLRequireSSL
</Location>
WSGIDaemonProcess 192.168.174.130 processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup 192.168.174.130
WSGIScriptAlias / /var/www/wsgi-scripts/helloWorld.py
</VirtualHost>
any help would be greatly appreciated! :)
def index(self, files):
should be
def index(self, file):
ughh!! alas, fixed!