Google Cloud Storage for dynamic website using HTTPS - https

Currently I'm hosting a client application written in AngularJS on Google Cloud Storage using the configuration described here.
I like this configuration because it acts as a CDN and we don't have to use a dedicated machine to host the frontend files.
The problem is that Google Cloud doesn't support HTTPS for custom domain names, and we want to improve our security standards serving at least the login page on an https domain.
¿Is there anyway we can keep the static files hosted on Google Cloud/some other CDN for fast serving and use an https domain?
Update
For anyone interested, we finally migrated all our CDN with HTTPS requirements to Amazon S3 + CloudFront and it works like a charm.

While Google Cloud Storage does support HTTPS, it does not support HTTPS for custom domain names.

Although you've found a solution not connected with your original question, I'm answering in case someone gets here with the same question like I did.
Google Firebase link is an excellent way to serve websites (and apps) as it is automatically through SSL (https) and Google Edge servers (effectively CDN function). And https will work using your own domain name. You can push your site from your local machine (Node.js needed) or from GitHub, Gitlab, etc. using continuous integration/deploy.
There is a generous free trial plan to try it first, then a reasonable monthly rate to pay as you go as your usage grows. plans

Related

Deploying an Internal API

I basically have an API that is going to be used with a web app and a mobile app. I don't want the API to publically available, where should I deploy it then? is there a way without using AWS? Thanks, Nav :)
There are multiple ways of doing this. This is a sensitive topic, as this is an opinion-based field.
However, I will try to answer below - and challange your way of approaching this.
It really depends on your 'operational' skills, funds, need for security, deadline(s) etc.
Basically you need to make an endpoint available on the www, without everybody being able to connect.
You could either:
Deploy a virtual machine or web app. in Azure/AWS/GCP/... and whitelist the IP's you need to connect from.
Rent a VPS from any provider, and deploy your application here - Again, whitelisting. (Edit: Not phones, since this IP changes constantly. A proxy can be implemented here (potential bottleneck), or any authentication mechanism like OAuth, JWT, Certificates etc. can be implemented either on the ingress controller (e.g. NGINX) or the application itself.)
Deploy the application on your Home-PC, order a static IP to your home and make a forwarded port and set up security on your premise (not recommended, and raises and bunch of other headaches)
Get in touch with a company that hosts web applications (Can be quite expensive)
Based on the limited information provided in your question, there is a ton of options, nice-2-haves and factors that comes in to play when choosing the setup that suits your needs.
You should also consider; VPN usage, Backup/disaster recovery, data leaks, redundancy, the need for future deploys, how you would access your environment in six months....
I hope this answered your question, but also raised a few for you to answer yourself.
Finally, I'd recommend you looking for inspiration here.
EDIT:
Question:
Whitelisting mobile IP's.
VPS selected.
Answer:
This becomes quite a task when mobile phones tend to change IP's frequently.
Since you are looking further into the VPS setup, you are more in control of the setup and can choose to look into OAuth and JWT.
Links:
OAuth - https://oauth.net/getting-started/ https://developer.okta.com/blog/2019/01/22/oauth-api-keys-arent-safe-in-mobile-apps
NGINX JWT - https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-jwt-authentication/
So - At the end of the day, you can make your app use a proxy (potential bottleneck) and whitelist this IP, or make the endpoint open (any -> 443) and implement an authentication mechanism like the ones mentioned above.
Consider implementing a DMZ zone for incoming traffic from the web.
https://en.wikipedia.org/wiki/DMZ_(computing)
and put your application behind this zone, making sure that the only the DMZ zone is facing the internet, and the server hosting your application is talking to the server in the DMZ.
Again, this is quite a big topic and is hard to simplify to a stackoverflow post.
If you are hosting the app on AWS you have a couple of options.
API Gateway now supports private endpoints. These endpoints can not be called via the public internet. That means if your app is hosted on AWS only the internal services of the app can call the end point. i.e. front end to database etc. I've used this method for internal micro services such as placing in house app data onto kinesis streams.
Alternatively, if you don't want to use API Gateway you have lots of options. Most of which would involve you creating rest APIs from where ever you plan on hosting your code. This could be on the server it's self or some sort of container.
API Gateway Private Endpoint Reference:
https://aws.amazon.com/blogs/compute/introducing-amazon-api-gateway-private-endpoints/

How to deploy a Hugo website from a Google Cloud VM?

I've started up a Google Cloud VM with the external IP address 35.225.45.169:
Just to check that I can serve a website from there, I've cloned a Hugo started project and run hugo server --bind=0.0.0.0 --baseURL=http://0.0.0.0:1313:
kurt_peek#mdm:~/synamdm$ hugo server --bind=0.0.0.0 --baseURL=http://0.0.0.0:1313
Building sites … WARN 2020/01/02 04:36:44 .File.Dir on zero object. Wrap it in if or with: {{ with .File }}{{ .Dir }
}{{ end }}
| EN
+------------------+----+
Pages | 16
Paginator pages | 0
Non-page files | 0
Static files | 20
Processed images | 0
Aliases | 0
Sitemaps | 1
Cleaned | 0
Built in 112 ms
Watching for changes in /home/kurt_peek/synamdm/{content,layouts,static,themes}
Watching for config changes in /home/kurt_peek/synamdm/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://0.0.0.0:1313/ (bind address 0.0.0.0)
Press Ctrl+C to stop
Now I would expect to be able to go to http://35.225.45.169:1313/ in my browser and for the website to be visible, but I find that it is not; instead the operation times out (as shown below with a curl command):
> curl http://35.225.45.169:1313
curl: (7) Failed to connect to 35.225.45.169 port 1313: Operation timed out
Am I missing something here? How should I deploy this static website from the Google Cloud Compute instance to the internet?
Update
Following Ahmet's comment, I edited the VM to allow HTTP and HTTPS traffic. This appears to have created several Firewall Rules in the VPC Network tab (see below).
However, I'm still not able to access http://35.225.45.169:1313/ after this; are there specific rules that I must define?
You have to create a new Firewall rule which allows tcp:1313 port.
But why do you want to host Hugo website on a GCP VM?
Did you checked out hosting Hugo website on GCS or using Firebase?
https://gohugo.io/hosting-and-deployment/hosting-on-firebase/
How to deploy a Hugo website from a Google Cloud VM?
As pradeep mentioned, you will need to create a new Firewall rule that allows the port tcp:1313 to receive and egress traffic.
Here you will find more details on how to create Firewalls rules in Google Cloud Platform.
Nonetheless, I think there are better approaches depending on the website that you would like to serve. Here you will find the different options available for serving websites in Google Cloud Platform, but mainly there are three:
Using Google Cloud Storage.
Using Google App Engine.
Firebase Hosting.
Google Cloud Storage
If you are serving a static website, I highly recommend you to go with Google Cloud Storage or Firebase Hosting. It is true that they do not have either Load Balancing capabilities or Logging, but they are an easy way if you are new to Google Cloud Platform.
As shown here if you would like to host a static site, you could do it within Cloud Storage, but you will need to create a Cloud Storage Bucket, and upload the content to it.
Here you will find more information and a tutorial on how host static websites within Google Cloud Platform using Google Cloud Storage.
Google App Engine
Another option would be to use App Engine, not only is fully managed by Google's infrastructure but also is more simpler than spinning up a VM and making sure that X ports are open or not, Google does it for you.
I attached you a tutorial on how to host Hugo on Google App Engine.
Firebase Hosting
Finally, you could also use Firebase Hosting in order to serve your Hugo website. I attached some documentation regarding more detail information about Firebase Hosting here.
I hope it helps.

Reverse proxy same naked domain to different hosts

I'm managing the DNS of my domain with Cloudflare.
The marketing pages for are hosted with Netlify.
The main application is hosted with Heroku.
Is it possible with cloudflare + a naked domain (my-example.com) to have some paths being served by Netlify and other paths by Heroku?
Or am I forced to put one of the hosting services on a subdomain?
Disclaimer: I work for Netlify.
You can definitely do this without running your own server or paying anything extra.
Since Netlify already has a CDN, it's suboptimal to put cloudflare's CDN (activated with the 'orange cloud' in their settings) in front of Netlify's. Besides being inefficient, doing so breaks Netlify's atomic deploys and rollbacks and also slows down page service from our observations. It may work, but is not recommended. However, CloudFlare's DNS is quite performant and can be used without their CDN (turn off the 'orange cloud'). Their DNS works well with content hosted on Netlify's CDN.
Here's how to set things up to accomplish this via Netlify.
Deploy your static assets to a Netlify site at your main custom domain, let's say it's my-example.com. For testing purposes you can use the built-in sitename at Netlify (something-something-1234.netlify.com) instead of my-example.com. The below example redirects are "host agnostic" so will work with the Netlify hostname, Netlify deploy previews, AND the production hostname.
Find all the paths for your dynamic content - for this example, let's say it's /main/* and /app/* that are dynamic and your backend is hosted on Heroku.
Create proxy redirect rules to point to those paths. They could be hosted via CloudFlare's CDN to protect your API if you wanted to - Netlify proxying to CloudFlare-fronted sites on Heroku works fine. You could also choose just to proxy straight to Heroku which would be less complicated. Netlify has some DDoS protection built-in and is still "in front of" your Heroku app. Up to you.
Deploy those proxy rules and test.
Netlify's proxying (technically reverse proxying) can connect to whatever backend you'd like and does NOT show the URL to the visitor - it looks to them (URL bar in the browser, HTTPS connection) as though they are connected to my-example.com the whole time, but the content is returned from your backend (including HTTP status codes. This response is cached on Netlify's CDN if indicated by your Cache-Control: HTTP Header directives which the Heroku app sends. Note that CloudFlare WILL CHANGE your Cache-Control header in case you set it on content they proxy to! Netlify won't.)
Here's a common setup:
/main/* https://yourapp.herokuapp.com/main/:splat 200!
/app/* https://yourapp.herokuapp.com/main/:splat 200!
Note that if you deploy ANY assets under /main or /app to Netlify, they will be ignored due to the trailing ! on those rules. See https://www.netlify.com/docs/redirects/#note-on-shadowing for some more details about how that works and the alternatives (TL;DR: deploying some things like /main/logo.png on Netlify but nothing that Heroku should serve vs deploying ALL needed content for /main/* on Heroku).
Note that I suggest using identical paths on Netlify and Heroku (/main/*) rather than proxying to /somethingelse/* since it is easier to debug asset loading when paths match up. This isn't a requirement, though.
As mentioned in the comment, its possible using cloudflare enterprise service.
But you can do it with a simple nginx reverse proxy setup.
Have DNS resolve to nginx reverse proxy and based on the path, appropriately call the upstreams.
eg. example.com, and then direct queries for /path1 to 100.100.100.100 and for /path2 to 200.200.200.200

Firebase hosting, and external APIs

Background
I'm currently using Heroku, running a single Hobby Dyno to serve both static assets and a simple API using node.js. I'm now looking to separate the static delivery and API into different dependencies. Having looked around, I'm now considering Firebase for static hosting.
Question
Using Firebase static hosting, is it possible to configure the DNS, or setup a URL rewrite, to make external API calls for a given URL, e.g.
http://myapp.com/api -> external API call to http://myapp.herokuapp.com/
http://myapp.com/* -> serve static file
If not, is it possible to configure a DNS entry to point www to Firebase, and api to Heroku?
Bonus Question
If possible; would this API call count as a cross-origin request? Preferably all requests would be made against the Firebase domain, and then everything done behind closed doors.
It is not possible to have Firebase Hosting rewrite the URL to a different server. While it is possible to have Firebase Hosting redirect the request to the Heroku server, that likely won't help you.
The common approach is indeed to split this in the DNS. Have api.myapp.com point to Heroku and www.myapp.com to Firebase Hosting.

Can I host index.html (homepage) on the Rackspace CloudFiles CDN?

I want to make my web app fast, especially the first page load (index.html).
Can I do this by hosting myfastapp.com on Rackspace CloudFiles and then have a subdomain called nodeserver.myfastapp.com which connects to a Node Server on Joyent.
Note: The node server will only connect via socket.io to tell the client which additional files to grab from the CDN (myfastapp.com).
There's a guide for this in the Cloud Files docs at Create Static Website.
There should be no issue with that the logistics of that.
The main issue is getting the main site on Cloud Files due to cname restrictions, at least in the Rackspace system, but it can probably be done.

Resources