LXD Websites with Iframe wil not connect?

I am experimenting with apache2 websites running within LXD containers. I can access the websites from
the internet, however one of the functions of the website is not working.

I have an iframe on the page that will not connect. The “src” of the iframe is local to the container. So the iframe looks like this:

iframe width=“640” height=“360” src=“http://localhost:3000/Embed/0x35e01199f8137077346fdd476191f1967a52bdb5” frameborder=“0”>/iframe
(note I purposely left off the <> in the iframe tag.)

I am using HAproxy to forward a subdomain URL to access the container. Browsing to it I get:

Unable to connect
Firefox can’t establish a connection to the server at localhost:3000.

Any ideas why this is happening?

Thanks,

Ray

The following

<iframe width=“640” height=“360” src=“http://localhost:3000/Embed/0x35e01199f8137077346fdd476191f1967a52bdb5” frameborder=“0”>/iframe>

is HTML code that is rendered by your web browser. Therefore, the URL should not have been localhost, because localhost is the computer that runs your Web browser.
You need to replace it with the proper hostname that you use to access this Apache2 server.

Thanks for the reply.

So I used your article about " How to Host Multiple Web Sites with Nginx and HAProxy Using LXD on Ubuntu 16.04" This works fine for accessing the website inside the container from the internet.

But the webpage in the container has an iFrame inside it that will not connect. I have a video player running on port 3000 in the same container. That is why I use localhost.

I have tried using: 127.0.0.1, localhost, lpc1.streamingworld.us as the src in the iFrame and none of them will connect?

My container is LPC1. From inside the container I can ping LPC1.lxd. From the HOST, I cannot ping LPC1.lxd.

Again, I can access the webpage from the internet. It’s the iFrame src that will not connect.

Here are the headers from the Chrome network console:

General
Request URL: http://lpc1.streamingworld.us:3000/Embed/0x35e01199f8137077346fdd476191f1967a52bdb5

Referrer Policy: no-referrer-when-downgrade

Request Headers

Provisional headers are shown

Referer: http://lpc1.streamingworld.us/
Upgrade-Insecure-Requests:
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Mobile Safari/537.36

Here are the FireFox headers:

Request URL: http://lpc1.streamingworld.us:3000/Embed/0x35e01199f8137077346fdd476191f1967a52bdb5

Request method: GET

Referrer Policy: no-referrer-when-downgrade

Request headers (608 B)
Accept text/html,application/xhtml+xm…ml;q=0.9,image/webp,/;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Cookie ad-con=a%3A2%3A%7Bs%3A4%3A%26q…0%3A%7B%7D%7D; _us=1548366652
Host lpc1.streamingworld.us:3000
Referer http://lpc1.streamingworld.us/
Upgrade-Insecure-Requests 1
User-Agent Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/65.0

This error is something very specific and relates to the way that the website is set up.
You can get a Let’s Encrypt certificate for lpc1.streamingworld.us and add that to the streaming server.

So question: As far as certs goes, do I need separate certs for host and containers?
Does the host need to do SSL if the container does SSL?

Thanks,

Ray

If you set up using a reverse proxy, then you setup the Let’s Encrypt certificate(s) on the reverse proxy that is fronting your containers. Thus, you do not need to setup certificates in any containers.
Otherwise, you would need to setup TLS to each website in the containers.

I do not know what software is running on the lpc1:3000 service. If it is something that gets direct access to the Internet, then you need to see how you can add TLS support to it. The same certificate for lpc1 can be used for lpc1:3000.

Thanks Simos.

I am using your tutorial on running multiple websites from multiple LXD containers.

So I install letsencrypt certs on the HAPROXY container? It seems that the containers holding the websites also need certs?

Ray

So I am using https://serversforhackers.com/c/letsencrypt-with-haproxy but I am getting an error
when I try to run:

sudo certbot certonly --standalone -d lpc1.streamingworld.us --non-interactive --agree-tos --email xxxxxxxx@gmail.com --http-01-port=8888

There error is:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for lpc1.streamingworld.us
Waiting for verification…
Cleaning up challenges
Failed authorization procedure. lpc1.streamingworld.us (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://lpc1.streamingworld.us/.well-known/acme-challenge/ZQ-BZfOfqZBn8St1YljTxERsL4K3lNn3mpeTOyJM7lw: Connection refused

IMPORTANT NOTES:

  • The following errors were reported by the server:

    Domain: lpc1.streamingworld.us
    Type: connection
    Detail: Fetching
    http://lpc1.streamingworld.us/.well-known/acme-challenge/ZQ-BZfOfqZBn8St1YljTxERsL4K3lNn3mpeTOyJM7lw:
    Connection refused

    To fix these errors, please make sure that your domain name was
    entered correctly and the DNS A/AAAA record(s) for that domain
    contain(s) the right IP address. Additionally, please check that
    your computer has a publicly routable IP address and that no
    firewalls are preventing the server from communicating with the
    client. If you’re using the webroot plugin, you should also verify
    that you are serving files from the webroot path you provided.

I can ping lpc1.streamingworld.us from https://www.ipaddressguide.com/ping and it comes back with the internet facing host IP. The lpc1 container IP is actually 10.106.37.15

Remember, my HAPROXY is in a container. Am I missing something here?

Ray

And here is my haproxy.cfg:

frontend www_frontend
bind *:80 #bind to port 80

# Test URI to see if its a letsencrypt request
    acl letsencrypt-acl path_beg /.well-known/acme-challenge/
    use_backend letsencrypt-backend if letsencrypt-acl

    # it matches if the http host: field mentions any of the hostnames (after the '-i').
    acl host_LPC1 hdr(host) -i lpc1.streamingworld.us
   #acl host_LPC2 hdr(host) -i lpc2.streamingworld.us
    # Redirect the connection to the proper server container, depending on the match.
    use_backend cont_LPC1  if host_LPC1
   #use_backend cont_LPC2  if host LPC2

  # LE Backend
 backend letsencrypt-backend
server letsencrypt 127.0.0.1:8888

 backend cont_LPC1
      balance leastconn
    # We set the X-Client-IP HTTP header. This is useful if we want the web server to know the real client IP.
    http-request set-header X-Client-IP %[src]
    # This backend, named here "LPC1", directs to container "LPC1.lxd" (hostname).
    server LPC1 LPC1.lxd:80 check

  # backend cont_LPC2
  #      balance leastconn
  #      http-request set-header X-Client-IP %[src]
  #      server LPC2 LPC2.lxd:80 check

Is there a difference between using Haproxy on the host versus using Haproxy in a separate container?
Right now I am using a container for haproxy and I have incoming http on port 80 of the host iptable’ed to
the haproxy container. Like your tutorial specifies.

Ray

Both work, haproxy on the host and haproxy in a container. The main difference is that in the latter, you need to use iptables to forward both port 80 and 443 to the haproxy container.

Indeed, that’s the proper way to run certbot. Do you run this from within the haproxy container? If so, then most likely you do not have port 8888 forwarded from the host to the container. Alternatively, you can use the default port (i.e. 80), shutdown temporarily haproxy, then run certbot. certbot will get the certificates and you can then install them in haproxy. certbot will be able to accept the connection from the Let’s Encrypt servers through the port 80 port forwarding.

Yes I am running the Letsencrypt procedures from inside the haproxy container.

The instructions here: https://serversforhackers.com/c/letsencrypt-with-haproxy do not say
anything about forwarding 8888 from host to container?

Ray

Your haproxy container does not have a public IP, meaning that it is not directly accessible from the Internet.

And, Let’s Encrypt needs you to pass a challenge in order to verify that you are owner of your claimed domain name. The http-01 challenge requires from the Let’s Encrypt server to connect back to your server and retrieve the challenge file. However, in the case of your container, anything that runs in the container is inaccessible from the Internet. Therefore, you would need to either use port forwarding or a LXD proxy device in order to make certbot's temporary Web server accessible from the Internet.

So adding the port 8888 forwarding did not help. Here are my rules for iptables:

root@localhost:~# iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 119 packets, 7902 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp – eth0 * 0.0.0.0/0 23.239.31.177 tcp dpt:8888 to:10.106.37.15:8888
25 1088 DNAT tcp – eth0 * 0.0.0.0/0 23.239.31.177 tcp dpt:443 to:10.106.37.15:443
12800 671K DNAT tcp – eth0 * 0.0.0.0/0 23.239.31.177 tcp dpt:80 to:10.106.37.15:80
29 1544 DNAT tcp – eth0 * 0.0.0.0/0 23.239.31.177 tcp dpt:80 to:10.106.37.15:80
2764 144K DNAT tcp – eth0 * 0.0.0.0/0 23.239.31.177 tcp dpt:80 to:10.106.37.15:80

Chain INPUT (policy ACCEPT 117 packets, 7782 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 4 packets, 296 bytes)
pkts bytes target prot opt in out source destination

Chain POSTROUTING (policy ACCEPT 74 packets, 3952 bytes)
pkts bytes target prot opt in out source destination
2842 171K MASQUERADE all – * * 10.106.37.0/24 !10.106.37.0/24 /* generated for LXD network lxdbr0 */

As usual, your recommendations are highly appreciated.

Ray

They all look OK.
Let’s verify that they are OK as well.

First, run on the host

sudo tcpdump -nl -i eth0 port 8888

and on your computer make a connection to the host on port 8888. For example,

telnet  23.239.31.177 8888

If the tcpdump command shows activity and packets, then all is fine for the connection towards the host. Obviously, there is no service listening to port 8888, and the connection will terminate.

Repeat by running the tcpdump line in the proxy container. And again, for your computer run the telnet command.
You should be able to see again packets being received.

If everything went well, then you are at the point able to run the certbot command with the standalone http-01 challenge. Run the command and show both the command and any output.

I see packets in both cases, host and haproxy container.

And here:
root@HAPROXY:/etc/ssl# sudo certbot certonly --standalone -d lpc1.streamingworld.us --non-interactive --agree-tos --email rayjender@gmail.com --http-01-port=8888
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for lpc1.streamingworld.us
Waiting for verification…
Cleaning up challenges
Failed authorization procedure. lpc1.streamingworld.us (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://lpc1.streamingworld.us/.well-known/acme-challenge/5eWJyJoZlKcu3LFokz3e5gum0iywLiCgxcpYAnvLv_A: Connection refused

IMPORTANT NOTES:

  • The following errors were reported by the server:

    Domain: lpc1.streamingworld.us
    Type: connection
    Detail: Fetching
    http://lpc1.streamingworld.us/.well-known/acme-challenge/5eWJyJoZlKcu3LFokz3e5gum0iywLiCgxcpYAnvLv_A:
    Connection refused

    To fix these errors, please make sure that your domain name was
    entered correctly and the DNS A/AAAA record(s) for that domain
    contain(s) the right IP address. Additionally, please check that
    your computer has a publicly routable IP address and that no
    firewalls are preventing the server from communicating with the
    client. If you’re using the webroot plugin, you should also verify
    that you are serving files from the webroot path you provided.

According to https://github.com/certbot/certbot/issues/2697 Let’s Encrypt will connect to your server to port 80 to perform the challenge. The --http-01-port is only used on the client side.

Therefore, for the duration of running certbot, you can stop haproxy so that certbot can bind to port 80 in the container and do the challenge successfully. Then, start haproxy.

So I stopped the haproxy service in the container and re-ran cerbot but I am still getting the same error?
I am running certbot inside the haproxy container…right?

Yes, you run certbot in the haproxy container.

The command is now (note, no 8888 anymore)

certbot certonly --standalone -d lpc1.streamingworld.us --non-interactive --agree-tos --email rayjender@gmail.com