I have a web app written in Go, use oauth2 (package golang.org/x/oauth2) to sign user in by Google (follow this tutorial https://developers.google.com/identity/sign-in/web/server-side-flow).
When I test app on local, it works fine but when I deploy app and run inside a Docker container (base on alpine:latest, run binary file), it has an error:
Post https://accounts.google.com/o/oauth2/token: x509: certificate signed by unknown authority
Here is my code to exchange the accessToken:
ctx = context.Background()
config := &oauth2.Config{
ClientID: config.GoogleClientId,
ClientSecret: config.GoogleClientSecret,
RedirectURL: config.GoogleLoginRedirectUrl,
Endpoint: google.Endpoint,
Scopes: []string{"email", "profile"},
}
accessToken, err := config.Exchange(ctx, req.Code)
if err != nil {
log.Println(err.Error()) // Error here
}
The problem is not caused by Go but Alpine image.
Default Alpine image does not have certificates so the app cannot call to https address (this case is https://accounts.google.com/o/oauth2/token).
To fix this problem, install 2 packages openssl and ca-certificates. Example in Dockerfile:
apk add --no-cache ca-certificates openssl
You will need to add the Google Issuing CA certificate to the trusted cert store of the docker image.
The Google CA cert is this https://pki.google.com/GIAG2.crt .
More info on the certificate can be found from here
Then within the Dockerfile , you will need to do something like this
cp GIAG2.crt /usr/local/share/ca-certificates/GIAG2.crt
update-ca-certificates
Related
i read this post on official documentation
https://hyperledger-fabric.readthedocs.io/en/latest/certs_management.html#certificate-renewal
I have some certified expired. I configure my Fabric CA adding env var FABRIC_CA_SERVER_CA_REENROLLIGNORECERTEXPIRY=true
and changing also fabric-ca-server-config.yaml with reenrollIgnoreCertExpiry: true
After restart the docker i use the command
fabric-ca-client reenroll --csr.keyrequest.reusekey -u https://localhost:11054 --mspdir /usr/src/hyperledger/fabric-samples/my-network/crypto-config/peerOrganizations/network.eu/msp --caname ca-test but
have this response
Post "https://localhost:11054/reenroll": x509: certificate has expired or is not yet valid: current time 2022-11-30T12:15:04Z is after 2022-11-24T14:09:00Z
Can you help me?
After this configuration i think that the previous command create new certficate without control expired date.
inside docker golang image i am trying to go install a package and fail on this error:
go install google.golang.org/protobuf/cmd/protoc-gen-go#1.27.0: google.golang.org/protobuf/cmd/protoc-gen-go#1.27.0: invalid version: Get "https://proxy.golang.org/google.golang.org/protobuf/cmd/protoc-gen-go/#v/1.27.0.info": x509: certificate signed by unknown authority
i tried installing CA certificates unsuccessfully
any idea what could be the problem ?
Ok so the problem was my security client: Cisco AnyConnect "Umbrella".
it was acting like a man in the middle and re-sign the request with its own certificate.
in order for the in-docker go client to trust the traffic re-signed by the Cisco Umbrella, the "Cisco Umbrella Root CA" certificate was needed to be added to the docker file:
so clicking on the .cer URI we can see that certificate.
now inside my container i could:
$ wget http://www.cisco.com/security/pki/certs/ciscoumbrellaroot.cer
then convert it from .cer to a .crt file:
$ openssl x509 -inform DER -in ciscoumbrellaroot.cer -out ciscoumbrellaroot.crt
then copy it to the certificate folder:
$ cp ciscoumbrellaroot.crt /usr/local/share/ca-certificates/ciscoumbrellaroot.crt
and lastly update certificates:
$ update-ca-certificates
which outputs this:
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
done! now we can go get any package:
$ go install google.golang.org/protobuf/cmd/protoc-gen-go#v1.27.1
go: downloading google.golang.org/protobuf v1.27.1
this was written about cisco security client but can be applied to any client out there
I am facing an issue that I want to ask here.
I have a container that must reach an URL. But, because of root certificate problem, I cannot reach that URL.
When I am trying to curl from inside of container, I am getting below error.
***curl: (60) SSL certificate problem: certificate has expired
More details here .
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.***
I am trying to add this certificate and update them in Dockerfile with lines below.
ADD your_ca_root.crt /usr/local/share/ca-certificates/foo.crt
RUN chmod 644 /usr/local/share/ca-certificates/foo.crt && update-ca-certificates
but, getting this error.
What I have tried;
tried to delete entire certificates and install new ones.
tried to use "update ca-certificates -f"
But did not work.
So, any suggestions?
I am trying to write .netCore 3.1 API in an Ubuntu Linux container that runs the equivalent of this Curl command.
WORKING LINUX CONTAINER CURL COMMAND:
curl --cacert /etc/root/trustedroot.crt --cert /etc/mutualauth/tls.crt --key /etc/mutualauth/tls.key
--header "SOAPAction:actionName" --data #test.xml https://this.is.the/instance --verbose
Enter PEM pass phrase: *****
<Success...>
We use Windows development laptops so everything starts with Windows.
So far, I have the following HttpClientHandler that my HttpClient is using on a Windows development machine. This code works on Windows with the cert in my local machine and current user personal stores and does not work in Linux:
WORKING WINDOWS HTTPCLIENTHANDLER CODE:
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
try
{
var cert = store.Certificates.Find(X509FindType.FindByThumbprint, "<<cert thumbprint here>>", true);
var handler = new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
SslProtocols = SslProtocols.Tls12,
AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
handler.ClientCertificates.Add(cert[0]);
}
catch (Exception e)
{
//Handle errors
}
finally
{
store.Close();
}
The cert I imported was .PFX format so as I understand it, the password went in at the time of import and the code for Windows doesn't need to be concerned with it.
The Curl command mentioned above works from the container. So by that logic, if coded or configured properly, the code should be able to do the same thing. As I see it, the Curl command shown above contains four elements that I need to account for in my HttpClientHandler somehow:
The Trusted Root(CA) Certificate: /etc/root/trustedroot.crt
The TLS Certificate: /etc/mutualauth/tls.crt
The Private Key - /etc/mutualauth/tls.key
The PEM Passphrase
I have been reading into this for a couple of months now and have seen various articles and stack overflow posts but there is a staggering amount of variables and details involved with SSL and I cant find anything that directly addresses this in a way that makes sense to me with my limited understanding.
I also have the option of running a Linux script at the time of deployment to add different/other formats of certs/keys to the stores/filesystem in the container. This is how I get the certs and keys into the container in the first place, so I have some control over what I can make happen here as well:
LINUX CONFIG SCRIPT:
cp /etc/root/trustedroot.crt /usr/share/ca-certificates
cp /etc/mutualauth/tls.crt /usr/share/ca-certificates
cp /etc/mutualauth/tls.key /etc/ssl/private
echo "trustedroot.crt" >> /etc/ca-certificates.conf
echo "tls.crt" >> /etc/ca-certificates.conf
update-ca-certificates
dotnet wsdltest.dll --environment=Production --server.urls http://*:80
I do not believe I can get the binary .PFX file into the container due to security policies and limitations, but I definitely can get its string encoded cert and key formats into the container.
...so if there is a way of using different styles of certs that I can extract from the .PFX or specifying password and cert when the server 'spins up' to make my code not require a password, that would work too - I might just be missing something basic in the Linux config.
Would anyone be so kind as to point me in the proper direction to find out how I can uplift my HttpClientHandler code OR Linux config to be able to make this API call? Any ideas are welcome at this point, this has been a thorn in my side for a long time now... Thank you so much!
This was not the right approach.
The correct approach was an NGINX reverse proxy terminating mutual auth TLS so that Dotnetcore doesn't have to.
Save yourself some time and go NGINX!. :D
I'm trying to make requests to a private Docker registry but it requires me to login and responds with a 401 response. I've tried checking the docs but it doesn't say anything about the authorization process. So my questions is how to successfully make HTTP requests to a private Docker registry with authorization enabled using the REST API?
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04
That article was extremely helpful for me in setting up a secure private Docker registry. Goes through everything you'll need.
(This part, https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04#step-four-—-secure-your-docker-registry-with-nginx, talks about securing the registry with basic HTTP authentication.)
docker registry requires ssl to be set up; you will have to configure ssl to get it to work.
I tried following the tutorial on digitalocean (https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04)
But there are a number of little problems with it and I feel it doesn't quite do what I need it to. I tried the ssl instructions verbatim and it didn't work for me. Here is what I had to do to get set up with ssl (using fairly generic names) using a self-signed certificate:
Make a directory to store the ssl cert:
mkdir /etc/nginx/ssl
Create a certificate and key file:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
Remember to put your common name as per instructions everywhere else (domain name)
Create a new directory under the ca-certificates directory:
mkdir /usr/share/ca-certificates/nginx
Copy the certificate file to that directory:
cp /etc/nginx/ssl/nginx.crt /usr/share/ca-certificates/
Append the following to the /etc/ca-certificates.conf file:
nginx/nginx.crt
Then update the certificates:
update-ca-certificates --fresh