This website is hosted on Amazon S3 and is using cloudfront to distribute the data. It is also using aws credential manager in order to use ssl, so that no one knows what you are looking at. Basically I upload the data onto S3, configure the bucket policy so as not to allow listing or getting of objects by the public, set up cloudfront, under the origins area
Essentially the way to set it up is as follows:
cnames
that are set up in your dns.For the page my ip address, I am using AWS Lambda in order to find out what the client ip address is. You can use lambda@edge in order to trigger a lambda expression when someone vists a certain link. This has the drawback of costing money for each request, however for a million requests it's still pretty cheap. A fun thing with it is it also works with ipv6 so if you goto ipv6.paulwendelboe.com/myip and you are on the ipv6 internet you will see what your ipv6 ip address is! This works because you can set up cloudfront to work on ipv6 and when it does it will pass that as the requesting ip address.
/myip
for example.callback(null, response);
at the end of it, where response
is the object you want to return. (for the rest of the code see the next section)viewer request
type so that it triggers before hitting the cache. If you do any of the others you will either get an error or you will have this stuck in the cache. Because viewer request
applies before the cache this becomes a non-issue. Additionally if lambda gets rate limited and you hit the page you can have a default value there...Some of the problems I had were things like 5xx server errors, because lambda would pass the json object to the origin and the origin, S3 in this case, wasn't expecting it, and it would not work because if there is an error the viewer request
would not trigger. Overall the problems were annoying but nothing to bad really. The caching was the most annoying part really, although since that's the point of cloudfront it is sort of to be expected.
The code in lambda I was using is below.
'use strict';
exports.handler = (event, context, callback) => {
const response = {
body: 'content',
headers: {
'content-type': [{
key: 'Content-Type',
value: 'text/html'
}],
},
status: '200',
statusDescription: 'OK'
};
const ip = event.Records[0].cf.request.clientIp;
response.statusDescription = 'OK';
response.body = "<!doctype html> <html> <head> <title>IP: ";
response.body += ip;
response.body += " </title></head><body>Your ip is: ";
response.body += ip;
response.body += " </body> </html> ";
callback(null, response);
};
I may be adding some api commands soon, however it's hard to say what api to implement so I'm not sure about that yet...