I am trying to proxy_pass to an http Wordpress site that is set up in a docker container through an Amazon ecs instance. The client gets to the site through a test server we have set up (https://test.xxxxxxx.com). When a user goes to https://test.xxxxxxx.com, I want it to show https://test.xxxxxxx.com in the address bar, but bring up the page for my Wordpress site (http://xx.xxx.xxx.xxx on port 80).
I can get it to go to my Wordpress site, but it looks funny. I am getting a lot of mixed content errors because I'm trying to access http files via an https request. I understand what's happening, but I can't seem to fix it, even after trying all of the suggestions I could find online.
I have tried changing several settings in both the Nginx file in the sites-available folder and by changing settings in wp-config.php on my Wordpress site. Below is one thing I tried. Almost all the tutorials I found, and everything I tried, was a variation of this.
#Nginx file
server {
listen 443;
location / {
proxy_pass http://xx.xxx.xxx.xxx:80;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
#wp-config.php
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
$_SERVER['HTTPS'] = '1';
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$_SERVER[HTTP_HOST'] = $_SERVER[HTTP_X_FORWARDED_HOST'];
}
define( 'WP_HOME', 'http://xx.xxx.xxx.xxx');
define( 'WP_SITEURL', 'http://xx.xxx.xxx.xxx');
What I would like to happen is that when a user enters https://test.xxxxxxx.com in the address bar, my Wordpress site loads with the proper theme and all my images, but https://test.xxxxxxx.com still shows in the address bar.
I wanna sugguest you use HA-Proxy reverse proxy in ECS.
I tried nginx reverse proxy, but failed. And success with HA-Proxy.
It is more simple than nginx configuration.
First, use "links" option of Docker and setting "environment variables" (eg. LINK_APP, LINK_PORT).
Second, fill this "environment variables" into haproxy.cfg.
Also, I recommend you use "dynamic port mapping" to ALB. it makes more flexible works.
taskdef.json :
# taskdef.json
{
"executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<APP_NAME>_ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "<APP_NAME>-rp",
"image": "gnokoheat/ecs-reverse-proxy:latest",
"essential": true,
"memoryReservation": <MEMORY_RESV>,
"portMappings": [
{
"hostPort": 0,
"containerPort": 80,
"protocol": "tcp"
}
],
"links": [
"<APP_NAME>"
],
"environment": [
{
"name": "LINK_PORT",
"value": "<SERVICE_PORT>"
},
{
"name": "LINK_APP",
"value": "<APP_NAME>"
}
]
},
{
"name": "<APP_NAME>",
"image": "<IMAGE_NAME>",
"essential": true,
"memoryReservation": <MEMORY_RESV>,
"portMappings": [
{
"protocol": "tcp",
"containerPort": <SERVICE_PORT>
}
],
"environment": [
{
"name": "PORT",
"value": "<SERVICE_PORT>"
},
{
"name": "APP_NAME",
"value": "<APP_NAME>"
}
]
}
],
"requiresCompatibilities": [
"EC2"
],
"networkMode": "bridge",
"family": "<APP_NAME>"
}
haproxy.cfg :
# haproxy.cfg
global
daemon
pidfile /var/run/haproxy.pid
defaults
log global
mode http
retries 3
timeout connect 5000
timeout client 50000
timeout server 50000
frontend http
bind *:80
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
compression algo gzip
compression type text/css text/javascript text/plain application/json application/xml
default_backend app
backend app
server static "${LINK_APP}":"${LINK_PORT}"
Dockerfile(haproxy) :
FROM haproxy:1.7
USER root
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
See :
Github : https://github.com/gnokoheat/ecs-reverse-proxy
Docker image : gnokoheat/ecs-reverse-proxy:latest
Related
I have a website hosted on Firebase, using static html, no server-side function is used to deliver the result.
When running curl -X PURGE https://mywebsite.com -v -L the result is:
{ "status": "ok", "id": "20755-1619059392-3560756" }
I need a way to restrict this action to specific IPs so that not anybody can reset my cache which might result in extra costs.
Also it seems that Firebase uses Varnish to manage cache (which is something am null at).
My client's security consultant sent us this recommendation on how to handle this issue, I'm not sure exactly if this is .htaccess syntax or what:
# Varnish recommends to using PURGE method only by valid user,
# for example by ip limiting and for other return 405 Not allowed:
acl purge {
"localhost";
"192.168.55.0"/24;
}
sub vcl_recv {
# allow PURGE from localhost and 192.168.55...
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(405,"Not allowed."));
}
return (purge);
}
}
I don't know how to apply this in Firebase Hosting, again am not using Server Functions, just the regular firebase.json with the following headers:
"headers": [
{
"source": "*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)",
"headers": [
{
"key": "Cache-Control",
"value": "public,max-age=31536000,immutable"
}
]
},
{
"source": "**/*.#(json|eot|otf|ttf|ttc|woff|font.css)",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
}
]
The following code is VCL code:
acl purge {
"localhost";
"192.168.55.0"/24;
}
sub vcl_recv {
# allow PURGE from localhost and 192.168.55...
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(405,"Not allowed."));
}
return (purge);
}
}
This code allows you to extend the behavior of Varnish. This code has to be added to your /etc/varnish/default.vcl file.
After adding this code to your VCL file, you have to reload your varnishd process to activate this VCL configuration.
If reloading varnishd is not an option, you can also activate the new VCL file using the following commands:
sudo varnishadm vcl.load purge_acl /etc/varnish/default.vcl
sudo varnishadm vcl.use purge_acl
For more information about Varnish and the VCL programming language, please have look at http://varnish-cache.org/docs/6.0/reference/index.html
There is no solution for the moment. This is the answer I received from the firebase support :
Hi Damien,
My name is Sergei, thanks for reaching out. I'll be assisting you.
The first thing to be addressed here is the fact that Varnish services
fall outside of our scope, so our information about its
implementations with our hosting services are not the most abundant.
Unfortunately, right now we can only control the caching behavior with
our existing tools.
I am sorry we cannot provide the functionality you need at the time,
if you would like to, we can submit the feature request so this is
visible to our engineering team.
gRPC services (developed in springboot) deployed as docker container on AWS linux (ec2). Started the docker image with port forwarding -p6565:6565.
Now when directly hit via BloomRPC on laptop, it worked : ec2.IP:6565 Package.Service.Method
Configured service & route in Kong:
{
"host": "ec2.IP",
"created_at": 1588403433,
"connect_timeout": 60000,
"id": "e657d8df-6247-458a-a8e8-bec00c41e03c",
"protocol": "grpc",
"name": "aws-grpc1",
"read_timeout": 60000,
"port": 6565,
"path": null,
"updated_at": 1588403433,
"retries": 5,
"write_timeout": 60000,
"tags": null,
"client_certificate": null
}
Route:
{
"strip_path": false,
"path_handling": "v0",
"updated_at": 1588403452,
"destinations": null,
"headers": null,
"protocols": [
"grpc",
"grpcs"
],
"created_at": 1588403452,
"snis": null,
"service": {
"id": "e657d8df-6247-458a-a8e8-bec00c41e03c"
},
"name": "aws-grpc1-route1",
"methods": null,
"preserve_host": false,
"regex_priority": 0,
"paths": [
"/grpc2"
],
"sources": null,
"id": "5739297e-3be7-4a0d-8afb-cfa8ed01cec2",
"https_redirect_status_code": 426,
"hosts": null,
"tags": null
}
Now hitting it via grpcurl -> its not working:
grpcurl -v -d "{}" -insecure ec2.ip:8443 package.service.pingMethod
Error invoking method "package.service.ping": target server does not expose service "package.service"
Here is kong config which looks related:
"proxy_listen": [
"0.0.0.0:8000 reuseport backlog=16384",
"0.0.0.0:8443 **http2** ssl reuseport backlog=16384"
],
So here are queries:
(1) can 8000 also be configured for https as insecure -> via passing a env KONG_PROXY_LISTEN variable at time of kong-container start by
-e "KONG_PROXY_LISTEN=0.0.0.0:8000 http2, 0.0.0.0:8443 http2 ssl"
Is this good to do?
(2) How to enable server side reflection? OR what is use of /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo ?
You need to expose HTTP2 Proxy Listener for Kong.
You can refer to this one: https://konghq.com/blog/manage-grpc-services-kong/
In short, you need to add env variable details for KONG_PROXY_LISTEN like so:
-e "KONG_PROXY_LISTEN=0.0.0.0:8000 http2, 0.0.0.0:8443 http2 ssl, 0.0.0.0:9080 http2, 0.0.0.0:9081 http2 ssl"
Note: apparently Kong uses the ports 9080 for HTTP2 and 9081 for HTTP2 SSL. But I think this can be changed.
And also expose those 9080 and 9081 ports like so, this is example for docker run command:
-p 127.0.0.1:9080:9080 \
-p 127.0.0.1:9081:9081
And use the 9080 port in grpcurl when you try to request, like so:
grpcurl -v -d '{"name": "Ken"}' -plaintext localhost:9080 facade.GreetingService/SayHello
More updates:
gRPC deployed behind kong.ingress is working fine:
grpcurl -v -d "{\"greeting\":\"111\"}" -insecure acfb0xxxxx.elb.us-east-2.amazonaws.com:443 hello.HelloService.SayHello
Response:
Resolved method descriptor:
rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse );
Request metadata to send:
(empty)
Response headers received:
content-type: application/grpc
date: Sat, 02 May 2020 07:00:17 GMT
server: openresty
trailer: Grpc-Status
trailer: Grpc-Message
trailer: Grpc-Status-Details-Bin
via: kong/2.0.3
x-kong-proxy-latency: 1
x-kong-upstream-latency: 9
Response contents:
{
"reply": "hello 111"
}
Response trailers received:
(empty)
Sent 1 request and received 1 response
when configured on kong-API-gateway, it is not working:
grpcurl -v -d "{\"greeting\":\"111\"}" -insecure kong.ce-gateway.ip:8443 hello.HelloService.SayHello
Error invoking method "hello.HelloService.SayHello": failed to query for service descriptor "hello.HelloService": rpc error: code = Internal desc = An invalid response was received from the upstream server
Http2 is now enabled by default for Kong, but if you are having issues, a good place to start is to inspect the proxy_listeners section of the global config. In my case, I found that http2 was only enabled for the SSL port, and not for the non SSL. A good way to see the global config is to send a GET request to the root url of the admin api, for example GET http://localhost:8001/.
I am trying to use lets encrypt with docker in order to put my website in https.
I use docker with nginx proxy and nginx companion. I have set up everything correctly regarding documentation. My containers are running.
Now, i have an issue with lets encrypt here is the debug file provided :
{
"identifier": {
"type": "dns",
"value": "jack-world.com"
},
"status": "invalid",
"expires": "2017-12-20T18:42:39Z",
"challenges": [
{
"type": "tls-sni-01",
"status": "pending",
"uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/G_0PYv_VpnEEUbV1PUjpJZyOIeP6b0zPxXeAlyYXclE/2728472678",
"token": "fXuUQ77koLDDTuAqEgeqQA1q_DHinF2wanQReSrgIdk"
},
{
"type": "dns-01",
"status": "pending",
"uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/G_0PYv_VpnEEUbV1PUjpJZyOIeP6b0zPxXeAlyYXclE/2728472680",
"token": "iab5h37N-Io6lzfi8-DKmccXsF8_Y5Ws_RYCcwzREBw"
},
{
"type": "http-01",
"status": "invalid",
"error": {
"type": "urn:acme:error:unauthorized",
"detail": "The key authorization file from the server did not match this challenge [fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0.K6eBCVMCFTPDy-GGls8jpd0O75tW9kFA9tsX7dEU_Zw] != [fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0.4E3VCTFsySjUrqnCg0ooULx-3kbdPBygi0aWkvg5Gd8]",
"status": 403
},
"uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/G_0PYv_VpnEEUbV1PUjpJZyOIeP6b0zPxXeAlyYXclE/2728472682",
"token": "fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0",
"keyAuthorization": "fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0.K6eBCVMCFTPDy-GGls8jpd0O75tW9kFA9tsX7dEU_Zw",
"validationRecord": [
{
"url": "http://jack-world.com/.well-known/acme-challenge/fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0",
"hostname": "jack-world.com",
"port": "80",
"addressesResolved": [
"149.202.73.189",
"2001:41d0:301::21"
],
"addressUsed": "2001:41d0:301::21",
"addressesTried": []
}
]
}
],
"combinations": [
[
0
],
[
1
],
[
2
]
]
}
Here is logs from companion :
argos#jackworld:~/JackProxy$ sudo docker exec jackproxy_nginx-proxy-companion_1 /app/force_renew -v --help
/etc/nginx/certs/jack-world.com /app
Creating/renewal jack-world.com certificates... (jack-world.com)
2017-12-13 19:03:34,715:INFO:simp_le:1538: Retrieving Let's Encrypt latest Terms of Service.
2017-12-13 19:03:36,629:INFO:simp_le:1455: Generating new certificate private key
2017-12-13 19:03:37,221:ERROR:simp_le:1421: CA marked some of the authorizations as invalid, which likely means it could not access http://example.com/.well-known/acme-challenge/X. Did you set correct path in -d example.com:path or --default_root? Are all your domains accessible from the internet? Please check your domains' DNS entries, your host's network/firewall setup and your webserver config. If a domain's DNS entry has both A and AAAA fields set up, some CAs such as Let's Encrypt will perform the challenge validation over IPv6. If you haven't setup correct CAA fields or if your DNS provider does not support CAA, validation attempts after september 8, 2017 will fail. Failing authorizations: https://acme-v01.api.letsencrypt.org/acme/authz/Xw790v5P8mgdjsh-A-_wvwcmAFRIu-6UxlT2l5I7JB8
Challenge validation has failed, see error log.
Debugging tips: -v improves output verbosity. Help is available under --help.
/app
I need some help to figure out why http-01 is invalid, and if this is the only issue.
Thanks by advance
Spec:
.net core 2
Identity Server 4
On local dev machine when I visit by Postman http://127.0.0.1:5000/.well-known/openid-configuration i can find for examply "jwks_uri" with address http: //127.0.0.1:5000/.well-known/openid-configuration/jwks
I can visit http: //127.0.0.1:5000/.well-known/openid-configuration/jwks and see result like:
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "6ca39c3dd4ffda97d502243e25fa4e54",
"e": "AQAB",
"n": "sZthlS0HE1pkbSnMlPyKNDkAqkQryeKG7YSRMeUbrDQARu-9f11iUFUblAdXUhuFRu0R77AQ-mhjy7kfjQMOT58gp3aMa17HTKcMxZRZEi-zcXZuxVA7Q0nuWrWp4_-0VAMV4OhGromZCFtUb26kRJXyKMNlHSM2irSJ9LWnx6NtSkHMrC_kv3kpciZWLx__9DkVM7wmYuGz9DMezoz7-FuwcJcGJHmVz7RNRwGNhdcvEG8nJE3fl8QQ16CjOim2X845gaIc9dWKi1MAA_LS1M2EK4aU8FZjVqgQgY472zrwGtUtwz25aUEZu130fthZabvOiWTDbztuYtOmrxP7BQ",
"alg": "RS256"
}
]
}
Port 5000 is the most important thing
DEV MACHINE SCREENSHOT
On local dev machine when I visit by Postman http://192.168.168.13:81/.well-known/openid-configuration i can find for examply "jwks_uri" with address http: //192.168.168.13/.well-known/openid-configuration/jwks
I cannot visit http://192.168.168.13/.well-known/openid-configuration/jwks beacuse i recieve error 404:
nginx error!
The page you are looking for is not found.
There is no port 81
I can visit http: //192.168.168.13:81/.well-known/openid-configuration/jwks and see result like:
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "6ca39c3dd4ffda97d502243e25fa4e54",
"e": "AQAB",
"n": "sZthlS0HE1pkbSnMlPyKNDkAqkQryeKG7YSRMeUbrDQARu-9f11iUFUblAdXUhuFRu0R77AQ-mhjy7kfjQMOT58gp3aMa17HTKcMxZRZEi-zcXZuxVA7Q0nuWrWp4_-0VAMV4OhGromZCFtUb26kRJXyKMNlHSM2irSJ9LWnx6NtSkHMrC_kv3kpciZWLx__9DkVM7wmYuGz9DMezoz7-FuwcJcGJHmVz7RNRwGNhdcvEG8nJE3fl8QQ16CjOim2X845gaIc9dWKi1MAA_LS1M2EK4aU8FZjVqgQgY472zrwGtUtwz25aUEZu130fthZabvOiWTDbztuYtOmrxP7BQ",
"alg": "RS256"
}
]
}
SERVER MACHINE SCREENSHOT
This is my Centos firewall settings:
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh dhcpv6-client
ports: 80/tcp 443/tcp 81/tcp 82/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
This is my nginx configuration for reverse proxy:
server {
listen 81;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
As far I have investigated the problem is that in .well-known/openid-configuration there is no proper ports (in that case 81) on server machine.
Endpoints exists, beacuse when I have manually added port 81 to endpoint, endpoint is avaiable.
Beacuse my application relly on .well-known/openid-configuration to autodiscover endpoints my authentication doesn't work. I don't know wether problem is on IdentityServer 4 configuration or on Centos configuration.
If anybody is facing the same issue, the following link will be helpful :)
http://amilspage.com/set-identityserver4-url-behind-loadbalancer/
Especially this part:
app.UseMiddleware<PublicFacingUrlMiddleware>
In my mup settings I have
"env": {
"ROOT_URL": "http://localhost",
"PORT": 3000,
"UPSTART_UID" : "meteoruser",
"MAIL_URL": "smtp://username:password#smtp.sendgrid.net:587",
"METEOR_ENV": "production"
},
I am following this.
http://johngibby.com/blog/How_to_deploy_your_meteor.js_app_on_Digital_Ocean
Should the port be 3000 or 80 and should the URL be my url?
ROOT_URL should be the url of your DigitalOcean droplet, which leads to your app. For example, if your droplet has an IP of 83.132.230.12, you could do:
"env": {
"ROOT_URL": "http://83.132.230.12",
"PORT": 3000,
"UPSTART_UID" : "meteoruser",
"MAIL_URL": "smtp://username:password#smtp.sendgrid.net:587",
"METEOR_ENV": "production" }
But it will be quite impractical for visitors to connect to http://83.132.230.12 in their web browser. It's better to have a domain name assigned to your droplet, in order to do:
"env": {
"ROOT_URL": "http://www.yourdomainname.com",
"PORT": 3000,
"UPSTART_UID" : "meteoruser",
"MAIL_URL": "smtp://username:password#smtp.sendgrid.net:587",
"METEOR_ENV": "production" }
PORT should be the port on which you want people to access your app. For example, if you give a 3000 port, your app will be accessed through http://www.yourdomainname.com:3000, which looks also impractical. On the other hand, web browsers use port 80 by default. So if you use "PORT": 80, your app will be accessible through http://www.yourdomainname.com (no port required in the url)