I have made my cert and key using the following
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
And configured it in my Golang code
log.Fatal(http.ListenAndServeTLS(":4201", "cert.pem", "key.pem", router))
It worked well when accessing using chrome but it throws the error on the console when accessing using firefox.
2018/03/02 16:54:11 http: TLS handshake error from 100.67.56.121:54397: remote error: tls: unknown certificate authority
How can I solve the issue?
"Remote error" means error sent from client (firefox in this case).
Solution is to figure out why firefox doesn't like the certificate and fix it.
There is something that firefox doesn't like about the certificate. Open up firefox dev tools and see if you can find any warnings regarding the certificate. If you had to manually accept the certificate in Firefox then it is possible that Firefox is still reporting to the server that it doesn't like the certificate even though you have told firefox to load the page anyway (see chrome example below).
However as this is a self generated/signed certificate the warning is probably because firefox doesn't trust this certificate. Solution is to either add this certificate to firefox's trusted certificates if this server is only for your own personal use...or to get a certificate signed by a commercial CA or letsencrypt.
"Fixing this server-side" means fixing whatever it is about how your certificate/app is served in order to make it trusted by firefox. Or I suppose ignoring the errors if you are just doing development.
More details...
Key thing here is that this is a "remote error" meaning it is an error from the tls CLIENT connecting to your server. In your case it is Firefox complaining during the TLS handshake that the certificate is invalid in some way.
I noticed the same thing with chrome. Cert is signed by a public CA (ie a CA that should be trusted by most browsers) but as I am developing on my local machine, the certificate is invalid because hostname (localhost) doesn't match the certificate CommonName (CN) or Subject Alternative Names (SAN).
Easiest thing to do is just look at the TLS handshake in wireshark.
I told chrome to accept the certificate, started capture and did a SINGLE refresh of the page (https://localhost:8081 in this case). Chrome does not present me with a warning page and shows the content. There is a red warning in the address bar however.
The interesting thing (to me) is that it appears (I'm no TLS expert) that there are two TLS handshakes.
Client Hello Server Hello Alert (client error) Client Hello Server Hello Client complete handshake ...encrypted application data...
Since chrome doesn't interrupt my refresh of the page I am not sure why chrome does the handshake twice (first time with Alert/failure) for a single page refresh.
The interesting bit I learned here (obvious in hindsight) is that it is possible to get reporting from browsers/clients when they reject your certificate. This can be used on the server side (if monitored) to discover subtle certificate mis-configurations in production that your test cases might not cover. Unfortunately as this is pre-http you won't get user-agent or anything useful to help with reproducing....but a large number of these errors as a percentage of server traffic indicates you need to do some serious cross browser/os/device testing