Category Archives: amazon-cloudfront

How can I host my website on an EC2 Server using Apache but host my images on S3 under the same sub domain?

So I have my website hosted on an EC2 server running apache. All works fine and well.

The issue I'm having is that I want my images hosted on S3 (and possibly cached on CloudFront), not on my EC2 server, but want both accessible under the same domain/subdomain.

For example say my website is www.helloworld.com. I want my images to be accessible at www.helloworld.com/images/foobar.png. I want foobar.png to be hosted on S3 and not each one of my EC2 servers though. How can I go about doing this?

Is there and configuration I can do in the AWS console or are there any rewrite rules I can use in Apache? I know I could always just set up a controller that will download the images from S3 and forward them to the user, but this seems wrong to me.

Why is AWS CloudFront no longer delivering assets after I updated an expired SSL certificate?

We use AWS CloudFront as our CDN in front of an Apache website running on an EC2 server. The website uses SSL (https) and CloudFront is configured to use the default CloudFront certificate, so our application loads static assets using https://xxxxxxcloudfront.net/path/to/asset, rather than https://ourdomain.com/path/to/asset.

Our SSL certificate, issues by Go Daddy, expired yesterday. After installing a new certificate on the web server, CloudFront no longer seems able to deliver any assets. It is simply returning a 502 error with the message CloudFront wasn't able to connect to the origin.

The Apache logs don't seem to indicate any problems with the new certificate, when I visit the site I can see the little green lock icon and I no longer see any warnings about an invalid certificate. Further, if I try to load the assets directly from our webserver, using https://ourdomain.com/path/to/asset, instead of the CloudFront URL, the assets seem to load without any problems.

I don't recall doing anything with CloudFront the last time we replaced a certificate. Is there something that needs to be updated in CloudFront when the webserver's SSL certificate gets updated? Any tips on what to look for?

AWS Cloudfront + Load Balancer, url changes from main domain to load balancer subdomain

My setup is as follows:

  1. user types example.com on the browser
  2. request goes to AWS CloudFront, which redirects HTTP to HTTPS, and forwards the request to the AWS Elastic LoadBalancer (elb.example.com)
  3. LoadBalancer forwards the request to the EC2 instance running PHP Laravel framework
  4. EC2 responds normally
  5. user views the page correctly at example.com with everything else transparent to him

All this is perfectly what I want, HOWEVER .....

  • If the user navigates to any button on the page, the url on the browser will become elb.example.com (it should stay example.com)
  • If I go to view page source, all the links to any button on the page has the base url of elb.example.com (it should be example.com)

The reason is because EC2 see the request coming from the load balancer so it assumes the base url is elb.example.com and generates all links accordingly.

How do make EC2 see the base url as example.com ?

How to can I use custom headers from CloudFront in Apache virtualhost

I have been given a task that I am not really sure how to handle. What I am requested to do is add a custom header to CloudFront and make Apache use this custom header to serve the site. I also need a fallback to normal use when the header is not set.

I have my main website: www.domain.com that is setup on CloudFront with the origin set to prod.domain.com. The site is setup on the server as www.domain.com (this cannot be changed)

What I want to do is set a custom header in CloudFront that will define the site name and use this header in my virtualhost to load the correct site.

For sake of example, I have added the header: company-host-name and set the value to www.domain.com. CloudFront origin is prod.domain.com and have updated the DNS to point to the server IP for this new domain. So far so good but this is now trying to load the prod.domain.com from the server.

What I want to do is use the custom header to load the site instead of the default way Apache handles this. Although I still need the fallback if no header is set. I think simply setting this header to the HOST header should suffice.

My Server Specs:

# cat /etc/centos-release
CentOS release 6.8 (Final)

# httpd -v 
Server version: Apache/2.2.15 (Unix)
Server built:   May 11 2016 19:28:33

I will need to know how to do this in Apache 2.4 also but for now 2.2 is essential.

I have tried playing with the headers and added this to my http.conf

<IfModule mod_headers.c>
<IfDefine company_host_name>
    Header set Host "%{company_host_name}e"
</IfDefine>
</ifModule>

I was hoping to override the Host header with the custom header value. I think this should suffice but I cannot seem to get this to work.

Perhaps I am over-complicating it and need to take a step back. So I am here asking for help on something I didn't think would be too difficult.

Thanks for any help you can provide.

Virtualhost

<VirtualHost *:80>
    ServerName www.domain.com
    ServerAlias prod.domain.com

    RequestHeader set Host "www.domain.com"

    DocumentRoot /var/www/vhosts/domain.com/public_html

    <Directory /var/www/vhosts/domain.com/public_html>
    Options -Indexes +FollowSymLinks -MultiViews
    AllowOverride All
    </Directory>

    ErrorLog /var/www/vhosts/domain.com/logs/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/www/vhosts/domain.com/logs/access.log combined

    <IfModule mod_php5.c>
    php_value error_log /var/www/vhosts/domain.com/logs/php_error.log
    php_value newrelic.appname "domain.com - PHP"
    </IfModule>

    <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>


    #INCLUDES

</VirtualHost>

WordPress on Apache/Cloudfront trailingslash redirection issues

I have https://example.com set up in AWS Cloudfront that mirrors https://test.example.com by using it as an origin.

The test subdomain (test.example.com) is running a WordPress setup on an EC2 server behind a load balancer.

Currently, I am using AWS Route 53 to point test.example.com to the load balancer. And example.com points to the Cloudfront url.

.htaccess on the ec2-server is setup to route all requests to index.php like so:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

#RewriteCond %{HTTP:X-Forwarded-Proto} !https
#RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}/ [R,L]

SetEnvIf X-Forwarded-Proto ^https$ HTTPS=On

The good news is that all requests to example.com/sample-page/ work good. But requests to example.com/sample-page (without the trailing slash) get redirected to test.example.com/sample-page/.

Any way to solve this problem so requests to example.com/sample-page do not get redirected to test.example.com/sample-page/ ??

This might be more specific to Cloudfront or WordPress. Or maybe it is something really silly on my part. Not sure.

Okay, WordPress does redirect a URL with missing trailing slash to the one with a trailing slash. Knowing this still doesn't solve my problem though. :(

.htacess in aws elb & cloudfront

I use aws elb and CloudFront. and the web server on ec2 using nginx in my ec2 using .htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

how to keep this .htaccess can continue to operate despite using aws elb & cloudfront

Thanks

Certificate Mismatch Errors

I've seen variations of this question asked but none have the solution to this exact case.

I have a WP site that is dumping assets on to CloudFront via W3 Total Cache plugin. Accessing the domain via http://domain.com works fine, however using www.domain.com generates a stop message from Amazon.

ERROR The request could not be satisfied. Bad request. Generated by cloudfront (CloudFront)

I checked the SSL using SSL Checker. http://domain.com shows the correct chain however www shows a certificate mismatch and a broken chain.

Thoughts were I could edit the htaccess file to force requests to www to http or https, however nothing I have tired seems to perform the redirect.

I don't see any rewrites below that would prevent forcing www requests to non www.

Any suggestions on how to force this redirect or for that matter if this is the correct solution?

  # BEGIN W3TC Browser Cache
<IfModule mod_deflate.c>
    <IfModule mod_headers.c>
        Header append Vary User-Agent env=!dont-vary
    </IfModule>
        AddOutputFilterByType DEFLATE text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon application/json
    <IfModule mod_mime.c>
        # DEFLATE by extension
        AddOutputFilter DEFLATE js css htm html xml
    </IfModule>
</IfModule>
<FilesMatch "\.(css|htc|less|js|js2|js3|js4|CSS|HTC|LESS|JS|JS2|JS3|JS4)$">
    FileETag MTime Size
    <IfModule mod_headers.c>
        Header set Pragma "public"
        Header set Cache-Control "max-age=31536000, public"
         Header set X-Powered-By "W3 Total Cache/0.9.4.1"
    </IfModule>
</FilesMatch>
<FilesMatch "\.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|HTML|HTM|RTF|RTX|SVG|SVGZ|TXT|XSD|XSL|XML)$">
    FileETag MTime Size
    <IfModule mod_headers.c>
        Header set Pragma "public"
        Header set Cache-Control "max-age=3600, public"
         Header set X-Powered-By "W3 Total Cache/0.9.4.1"
    </IfModule>
</FilesMatch>
<FilesMatch "\.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|woff|xla|xls|xlsx|xlt|xlw|zip|ASF|ASX|WAX|WMV|WMX|AVI|BMP|CLASS|DIVX|DOC|DOCX|EOT|EXE|GIF|GZ|GZIP|ICO|JPG|JPEG|JPE|JSON|MDB|MID|MIDI|MOV|QT|MP3|M4A|MP4|M4V|MPEG|MPG|MPE|MPP|OTF|ODB|ODC|ODF|ODG|ODP|ODS|ODT|OGG|PDF|PNG|POT|PPS|PPT|PPTX|RA|RAM|SVG|SVGZ|SWF|TAR|TIF|TIFF|TTF|TTC|WAV|WMA|WRI|WOFF|XLA|XLS|XLSX|XLT|XLW|ZIP)$">
    FileETag MTime Size
    <IfModule mod_headers.c>
        Header set Pragma "public"
        Header set Cache-Control "max-age=31536000, public"
         Header set X-Powered-By "W3 Total Cache/0.9.4.1"
    </IfModule>
</FilesMatch>
# END W3TC Browser Cache
# BEGIN W3TC CDN
<FilesMatch "\.(ttf|ttc|otf|eot|woff|font.css)$">
<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
# END W3TC CDN
# BEGIN W3TC Page Cache core
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule .* - [E=W3TC_ENC:_gzip]
    RewriteCond %{HTTP_COOKIE} w3tc_preview [NC]
    RewriteRule .* - [E=W3TC_PREVIEW:_preview]
    RewriteCond %{REQUEST_METHOD} !=POST
    RewriteCond %{QUERY_STRING} =""
    RewriteCond %{REQUEST_URI} \/$
    RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle) [NC]
    RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" -f
    RewriteRule .* "/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" [L]
</IfModule>
# END W3TC Page Cache core
# BEGIN W3TC Skip 404 error handling by WordPress for static files
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !(robots\.txt|[a-z0-9_\-]*sitemap[a-z0-9_\-]*\.(xml|xsl|html)(\.gz)?)
    RewriteCond %{REQUEST_FILENAME} \.(css|htc|less|js|js2|js3|js4|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|woff|xla|xls|xlsx|xlt|xlw|zip)$ [NC]
    RewriteRule .* - [L]
</IfModule>
# END W3TC Skip 404 error handling by WordPress for static files
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

SSL error "Trying to load unsafe script" + AWS ELB

We have webserver (Apache + PHP) in AWS fronted by Elastic load balancer and cloudfront. We have installed SSL certificate in ELB and we are using SNI configuration for HTTPS connection.

Everything works well and website is also getting displaied in browser but we are getting error in crome browser "Page is trying to load scripts from unauthorized source" After clicking on load unsafe script everything works fine.

Does any one knows the cause and possible resolution? Am i missing any configuration in my Apache server?

really appriciate for any of your suggestions

Cloudfront max-age together with TTL usefull?

For a image gallery I use amazon cloudfront.

I have set at the origin:

Cache-Control:max-age=31536000 (1 Year)

1. Is it usefull to set the TTL 0 (24 hours) to 1 Year too when I have already set the max-age?

2. Will amazon check the file with TTL0 every 24 hours when I have set the max-age to 1 year?

Amazon is saying:

Objects are cached for the greater of the value of the Cache-Control max-age directive or the value of the CloudFront Minimum TTL

Amazon is also saying:

If an object in an edge location isn't frequently requested, CloudFront might evict the object—remove the object before its expiration date—to make room for objects that are more popular.

In that case, I think its usefull to set TTL to year, because the images will stay for sure and not before? Please correct me.

Thanks for clarification.