Generating GCP compatible Cloudflare SSL certificate - google-app-engine

I'm trying to configure SSL for Google Cloud's App Engine.
You can upload your own custom SSL certificate + private key in GCP (see screenshot).
I'm using Cloudflare for DNS, and would like to use the "Full (strict)" SSL policy in Cloudflare. This would mean I have to add a certificate and key, created by Cloudflare, in GCP (in same screenshot).
I've managed to convert the private key to a valid (PEM) format that GCP will accept. The only thing not working is the Certificate part.
When entering both certificate and key in GCP, upon clicking upload, the following error is returned:
The certificate data is invalid. Please ensure that the private key and public certificate match.
After some googling, I found the following resources on GCP's documentation, explaining I need a have the full certificate-chain uploaded in the certificate field. So next thing I tried, is to concat my certificate from cloudflare together with the root certificate of cloudflare itself, as explained in the GCP docs.
So I ran the following command to create this chain:
cat domain.crt cloudflare-root-ca.crt > concat.crt
... and uploaded that one in GCP in the certificate field.
That didn't work either, even while the checksums of both private key and the certificate-chain match as explained by GCP docs, by running:
openssl x509 -noout -modulus -in concat.crt | openssl md5
openssl rsa -noout -modulus -in myserver.key.pem | openssl md5
...and comparing the md5 outputs.
So now I'm completely without Idea's. GCP's error messages are limited to the one above, and one other saying your PK is not a valid format.
Same problems when trying via CLI (gcloud)
When trying this process through the cli gcloud, we get the same errors.
Trying the following command:
gcloud app ssl-certificates create --display-name example.com --certificate ./cloudflare-concat.crt --private-key cloudflare-pk.key
...yields the following error:
ERROR: (gcloud.app.ssl-certificates.create)
INVALID_ARGUMENT: Invalid certificate.
`CertificateRawData` must contain a PEM encoded x.509 public key certificate, with header and footer included,
and an unencrypted PEM encoded RSA private key, with header and footer included and with size at most 2048 bits.
The requested private key and public certificate must match.
Any help on uploading a valid certificate (from Cloudflare) and private key in GCP is much appreciated.
Update 1
I found this (cached) paged describing all the root and intermediate certs of Cloudflare. I've tried a couple of them to concatenate agains my domain cert, but no luck so far. It's also not clear which one to use...
Update 2
I've beginning to think that this won't work, ever. Because I'm using an 'Origin Certificate' from Cloudflare, I believe this is a self-signed cert from Cloudflare itself, meaning that App Engine won't ever recognize this as valid.
The reason I think this is the case, is because I tried to use the cfssl tool from cloudflare to 'create a bundle-cert' automatically. The response I get from running
cfssl bundle -cert domain.crt
Returns the following result:
[INFO] bundling certificate for {Country:[] Organization:[CloudFlare, Inc.] OrganizationalUnit:[CloudFlare Origin CA] Locality:[] Province:[] StreetAddress:[] PostalCode:[] SerialNumber: CommonName:CloudFlare Origin Certificate Names:[{Type:2.5.4.10 Value:CloudFlare, Inc.} {Type:2.5.4.11 Value:CloudFlare Origin CA} {Type:2.5.4.3 Value:CloudFlare Origin Certificate}] ExtraNames:[]}
{"code":1220,"message":"x509: certificate signed by unknown authority"}
Extra info
I'm using a free Cloudflare subscription.
Everything works fine when using the 'flexible' setting from Cloudflare,
But I would like to use the 'full (strict)' setting

I discovered a recent blogpost, describing how to solve this.
After following the steps described, the certificate was accepted in Google Cloud, and everything worked for the 'full (strict) ssl' option in cloudflare!
In short: it involved a bit of tweaking the keys, by manually adding 'RSA' to it, as described in the blogpost.
See this link:
https://blog.woohoosvcs.com/2019/11/running-google-app-engine-behind-cloudflare/
EDIT:
This is probably the same end-result as using the shell commands as described by #Andrei

Can you please verify you are using free Cloudflare or paid Cloudflare account.
Because if you are free using than I think SSL strict is not going to work make it flexible and redirect all HTTP request to https request.

Related

gcloud cli app engine domain mapping error

I am trying to get multiple microservices to run on a single app engine of a single project. I am following this official documentation from GCP
https://cloud.google.com/appengine/docs/standard/python3/mapping-custom-domains
When I try to create a wild card mapping like this
gcloud app domain-mappings create '*.example.com'
So that GCP backend engines can match the request accordingly:
[VERSION_ID].[SERVICE_ID].example.com
I get the following error
ERROR: (gcloud.app.domain-mappings.create) INVALID_ARGUMENT: A managed certificate cannot be created on a wildcard domain mapping. Set `ssl_management_type` to `MANUAL` and retry the domain mapping creation. You can manually create an SSL certificate with `AuthorizedCertificates.CREATE` and map it to this domain mapping with `AuthorizedCertificates.UPDATE`.
Could anyone help with this?
It looks like by default the command attempts to configure managed SSL certificates, which aren't compatible with wildcard domain mappings. From Wildcard mappings:
**Note**: Wildcard mappings are not supported for managed SSL certificates.
As the error message suggests you can disable that with an option. From gcloud beta app domain-mappings create:
--certificate-management=CERTIFICATE_MANAGEMENT
Type of certificate management. 'automatic' will provision an SSL
certificate automatically while 'manual' requires the user to provide
a certificate id to provision. CERTIFICATE_MANAGEMENT must be one
of: automatic, manual.
So just try instead:
gcloud app domain-mappings create '*.example.com' --certificate-management=manual
I see a discrepancy: the error message mentions the ssl_management_type option while the doc page shows certificate-management. Try both if needed - it may be just an error or it may be a renamed option (which may or may not still be supported under the hood).
Of course, if you want SSL, you'd have to manage the SSL certificate(s) yourself (maybe using the --certificate-id option, documented on the same page?). In that case also check out the related Google App Engine custom subdomain mapping for a specific version for potential implications of variable domain nesting.

Gcloud app module (subdomain) with ssl: certificate error [duplicate]

I want to use SSL on the non-default version of my GAE app. For the normal https://my-app.appspot.com I know I don't have to do a thing. However I have another version, which would be under https://v2.my-app.appspot.com and there SSL doesn't work. It gives following error in the browser:
Your connection is not private
Attackers might be trying to steal your
information from dev.replimeapp.appspot.com (for example, passwords,
messages, or credit cards). NET::ERR_CERT_COMMON_NAME_INVALID
Use following address instead: https://v2-dot-my-app.appspot.com/
Google does not issue SSL certificates for double-wildcard domains hosted at appspot.com. Therefore with HTTPS you must use the string "-dot-" instead of "." to separate subdomains, as shown in the examples below. You can use a simple "." with your own custom domain or with HTTP addresses.
From there: https://cloud.google.com/appengine/docs/java/config/webxml#Secure_URLs

Google App Engine SSL with Let's Encrypt "could not be inserted"

When trying to "Add a new SSL certificate" using App Engine's Settings tab that was generated with Let's Encrypt via Google App Engine's console results in a dialog error and a 400 response to the POST request.
Error
"The SSL certificate provided could not be inserted."
A previously generated (about 2 months ago - not yet expired of course) SSL key/certificate via the exact same method is inserted just fine - but any newly generated one does not. I attempted both traditional Let's Encrypt and the relatively new Certbot method. Also tried multiple subdomains, naked domains, singular domains and each results in the same error.
I've seen several people spec that --rsa-key-size 2048 solved the same issue, but I've tried specifying that as well (even though it is the default for Certbot as is). Other answers have been "waiting 2 hours and now its working" - looking for a real solution as unreliable inserts and expired certs can become a real pain.
If you use certbot in Apache it defaults to 4096. So force key length to 2048.
certbot-auto --rsa-key-size 2048
From docs [https://certbot.eff.org/docs/using.html]
This creates PEM certificates in /etc/letsencrypt/live/example.net
Convert to RSA (change the url in cmd to your site).
sudo openssl rsa -inform pem -in /etc/letsencrypt/live/example.net/privkey.pem -outform pem > rsaprivatekey.pem
Above command is from this blog post http://blog.seafuj.com/lets-encrypt-on-google-app-engine. This also explains how to setup your webapp2 webserver.
Go to App Engine > Settings > SSL Certificates
Upload fullchain.pem
Upload rsaprivatekey.pem
The file upload button works fine - no need to paste unless its more secure.
I ran into similar problems as well a few weeks ago when trying to upload my new certificate using the same recipe I successfully used before.
What worked for me in the end was:
copy-pasting the entire content of the certificate file into the box marked Or paste the public key certificate in the box below:
and,
copy-pasting just the full key at the end of my private key .pem file into the box marked Or paste the RSA private key in the box below: (though I don't exactly recall if I included the leading -----BEGIN RSA PRIVATE KEY----- and tailing -----END RSA PRIVATE KEY----- lines or not).
I (kinda blindly) made several attempts for each of the 2 copy-paste operations with whatever crossed my mind - the success/failure feedback is immediate.
Side note - you may want to also double-check your certificate, in my case the 1st certificate file I managed to upload successfully was an incomplete one (missing intermediate entities), which appeared to be working fine from my desktop, but was failing when browsing from Android, I had to re-generate another one. I used digicert to confirm the problem and verify the 2nd certificate (following suggestions from an SO answer, of course ;)
I had this problem. I had generated the certificates in the Google Cloud Shell.
I was first trying to use the fullchain.pem, but this did not work.
/etc/letsencrypt/live/mydomain.com/cert.pem
I issued
sudo less /etc/letsencrypt/live/whysaurus.com/cert.pem
in the google cloud shell, and uploaded that as the pem 509 cert in appengine, and then it was accepted.

SSL on appspot.com subdomain of non-default version

I want to use SSL on the non-default version of my GAE app. For the normal https://my-app.appspot.com I know I don't have to do a thing. However I have another version, which would be under https://v2.my-app.appspot.com and there SSL doesn't work. It gives following error in the browser:
Your connection is not private
Attackers might be trying to steal your
information from dev.replimeapp.appspot.com (for example, passwords,
messages, or credit cards). NET::ERR_CERT_COMMON_NAME_INVALID
Use following address instead: https://v2-dot-my-app.appspot.com/
Google does not issue SSL certificates for double-wildcard domains hosted at appspot.com. Therefore with HTTPS you must use the string "-dot-" instead of "." to separate subdomains, as shown in the examples below. You can use a simple "." with your own custom domain or with HTTP addresses.
From there: https://cloud.google.com/appengine/docs/java/config/webxml#Secure_URLs

The SSL certificate provided could not be inserted

I use google app engine trying to add ssl for custom domain. I use naked domain. After "PEM encoded X.509 public key certificate" and "Unencrypted PEM encoded RSA private key" uploaded. "The SSL certificate provided could not be inserted." is returned. I use https://www.sslchecker.com check private key/ssl match. It matches. What's wrong? I use key size "RSA 2048", nothing wrong ordering the concatenated certificates. Thank you.
I spent a long time working with this error and found a solution for my problem here:
http://qiita.com/yogurito/items/550b50b262418e93da22
If I understand correctly, the key file needed to be without a password, so running:
openssl rsa -in appengine.key -out appengine-nopass.key
provided a key that GAE liked.

Resources