Running behind a proxy using basic auth

I installed a vanilla editoria, but for security reasons I have to run this behind a reverse proxy and protect that with authentication, like this in nginx:

location / {
satisfy any;
deny all;
auth_basic “Restricted”;
auth_basic_user_file /etc/nginx/REDACTED.pw;
proxy_pass http://INTERNAL_IP:8080;
}

And as a result, I do get the initial web pages (after a long delay), and I can reach the login and registration web pages, but any attempt to do anything there will result in a time out and a crashed server.

Is there any way to run it behind a reverse proxy that adds a basic-auth layer?

(the server side error is:

error: message=request aborted, stack=BadRequestError: request aborted
at IncomingMessage.onAborted (/var/www/editoria-vanilla/node_modules/raw-body/index.js:231:10)
at emitNone (events.js:106:13)
at IncomingMessage.emit (events.js:208:7)
at abortIncoming (_http_server.js:445:9)
at socketOnClose (_http_server.js:438:3)
at emitOne (events.js:121:20)
at Socket.emit (events.js:211:7)
at TCP._handle.close [as _onclose] (net.js:561:12), name=BadRequestError, code=ECONNABORTED, expected=260, length=260, received=0, type=request.aborted

Hello @Johnsinteur and welcome to our community!
Up until now we haven’t bumped to the case of running the app behind an auth proxy but I can’t think of any reason why this could cause any issues.
If i had to guess what your problem is I would say that maybe is relevant to port forwarding or for some reason your proxy breaks the request.
As I am not expert in this kind of things I suggest @kominoshja (devops) to tell us his thoughts and also it will be very helpful if you could share with us your setup as well as how you deployed and configured the app.

Well, you basically have all you need to reproduce: set up a generic vanilla install following the github instructions on an internal host, set up nginx on another host and insert the config I pasted in my first message, modifying it for your specific internal host IP address

could you dm me your <profile>.env file that you are using for editoria?

(done)

Thanks it seems fine to me. So maybe we could wait for @kominoshja to hear his thoughts on this.

@Johnsinteur seems like the setup methodology is right, but you need some changes on the nginx server. Can you try the following nginx? You’d also need to follow the password creation process in https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/#creating-a-password-file (I already configured nginx for you) (Assuming file will be in /etc/nginx/.htpasswd)

server {
    listen 80; listen [::]:80;
    server_name _;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name _;

    auth_basic           "Editoria Vanilla";
    auth_basic_user_file /etc/nginx/.htpasswd;

    ssl_certificate /etc/letsencrypt/live/_/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/_/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.2;
    ssl_ciphers EECDH+AESGCM:EECDH+AES;
    ssl_ecdh_curve secp384r1;
    ssl_prefer_server_ciphers on;

    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";

    location / {
        proxy_pass http://127.0.0.1:3050/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect http://127.0.0.1:3050/ https://_;
    }
}

Let us know if it works

1 Like

Well, the server stopped crashing. Instead the login page throws me back to the login page. If I remove the lines auth_basic and auth_basic_user_file the login page works.

1 Like

The popup login is from nginx, the login page is from Editoria itself

Yes, I know… The nginx prompt accepts my username./password as stored in the htpasswd file. It’s the login page that doesn’t let me log in.

And to be even more complete: the registration page works and lets me register a new editoria user, which then cannot log on.

The nginx server is never sending a command to the editoria server which is weird…
I am unable to even register. @Johnsinteur what are the logs editoria is outputting? They must be in the logs folder of editoria

Your interaction with the site:

{“level”:“info”,“message”:"::ffff:10.1.1.3 - kominoshja [27/Mar/2020:15:07:10 +0000] “GET / HTTP/1.1” 200 300 “https://discourse.coko.foundation/” “Mozilla/5.0 (X11; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0”\n",“timestamp”:“2020-03-27T15:07:10.280Z”}
{“level”:“info”,“message”:"::ffff:10.1.1.3 - kominoshja [27/Mar/2020:15:15:59 +0000] “GET /signup HTTP/1.1” 200 300 “-” “Mozilla/5.0 (X11; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0”\n",“timestamp”:“2020-03-27T15:15:59.008Z”}
{“level”:“info”,“message”:"::ffff:10.1.1.3 - kominoshja [27/Mar/2020:15:23:23 +0000] “GET /signup HTTP/1.1” 304 - “-” “Mozilla/5.0 (X11; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0”\n",“timestamp”:“2020-03-27T15:23:23.912Z”}
{“level”:“info”,“message”:"::ffff:10.1.1.3 - kominoshja [27/Mar/2020:15:26:07 +0000] “GET /login HTTP/1.1” 200 300 “-” “Mozilla/5.0 (X11; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0”\n",“timestamp”:“2020-03-27T15:26:07.029Z”}

I do notice your basic auth username is in the logs - my suspicion is that editoria is attempting to take that info and somehow use it in it’s own authentication attempts, which it shouldn’t

Hello, is there any chance the proxy layer to mutate the Authorization: Bearer <token> header property of the request @kominoshja ? The pubsweet platform uses JWT

I tried this:

proxy_set_header Authorization “”;

And the result is that the basic auth user does indeed no longer appear in the editoria logs. Instead:

{“error”:{“message”:“Variable “$input” got invalid value {}; Field username of required type String! was not provided.”,“locations”:[{“line”:1,“column”:11}],“extensions”:{“code”:“INTERNAL_SERVER_ERROR”,“exception”:{“stacktrace”:[“GraphQLError: Variable “$input” got invalid value {}; Field username of required type String! was not provided.”," at /var/www/editoria-vanilla/node_modules/graphql/execution/values.js:114:15"," at coerceInputValueImpl (/var/www/editoria-vanilla/node_modules/graphql/utilities/coerceInputValue.js:99:11)"," at coerceInputValue (/var/www/editoria-vanilla/node_modules/graphql/utilities/coerceInputValue.js:37:10)"," at _loop (/var/www/editoria-vanilla/node_modules/graphql/execution/values.js:107:69)"," at coerceVariableValues (/var/www/editoria-vanilla/node_modules/graphql/execution/values.js:119:16)"," at getVariableValues (/var/www/editoria-vanilla/node_modules/graphql/execution/values.js:48:19)"," at buildExecutionContext (/var/www/editoria-vanilla/node_modules/graphql/execution/execute.js:184:61)"," at executeImpl (/var/www/editoria-vanilla/node_modules/graphql/execution/execute.js:89:20)"," at Object.execute (/var/www/editoria-vanilla/node_modules/graphql/execution/execute.js:64:35)"," at /var/www/editoria-vanilla/node_modules/apollo-server-core/dist/requestPipeline.js:246:46"," at Generator.next ()"," at /var/www/editoria-vanilla/node_modules/apollo-server-core/dist/requestPipeline.js:8:71"," at new Promise ()"," at __awaiter (/var/www/editoria-vanilla/node_modules/apollo-server-core/dist/requestPipeline.js:4:12)"," at execute (/var/www/editoria-vanilla/node_modules/apollo-server-core/dist/requestPipeline.js:225:20)"," at Object. (/var/www/editoria-vanilla/node_modules/apollo-server-core/dist/requestPipeline.js:165:42)"]}}},“level”:“error”,“message”:“Variable “$input” got invalid value {}; Field username of required type String! was not provided.”,“timestamp”:“2020-03-27T15:52:03.025Z”}

Oh, and behind the same nginx setup, with nearly similar configs, I have a gitlabs instance and a rocket chat instance, so I know this basic auth layer in front of something that requires logging on works just fine…

@Johnsinteur I see that on your nginx config you have this line:
proxy_redirect http://[redacted]/ https://_;

Can you replace https://_ with https://[domain name you're serving from]?