Where to get a certificate?

I have cardano-sl running on an Amazon Linux EC2, and I’m trying to call it from my url example.com/api..etc however the ssl certificate that comes with cardano-sl (scripts/tls-files/ca.crt) is only valid for ‘localhost’.

Where can I get a free SSl certificate to use? I’ve looked at AWS Certificate Manger but that only provisions them for things like beanstalk, you can’t actually download the cert to use on things like EC2.

I’ve also looked at lets encrypt, and they don’t support Amazon Linux. I considered whipping up a new RHEL/Ubuntu EC2 but from what I read on the website, the cert is only valid for certain web servers and directories, I’m not sure if I could use it for cardano-sl?


1 Like

Here’s one that’s used widely

Sorry, I see you already looked into let’s encrypt

Amazon has its own CA but that one only works with Amazon scaling services.

On vanilla Linux the only good option perhaps is to use certbot with the dns option.

In default, Cardano creates a startup script called connect-to-mainnet which generates a self-signed certificate for localhost if there is no any existing cert available.
But, that’s for reason and you should not open any public port and only play /w Cardano SL’s API on your local machine or on a VM.

The pool staking would require some additional infrastructure (different type of nodes), registration and proper certificates.

1 Like

@_ilap Hey. Yep, that’s the script I used to generate the localhost certificate.

The “proper certificate” you refer to is what I’m trying to achieve. I’m not sure why you say I shouldn’t open this up to be accessed from a browser?

For security reason. The cardano have different type of nodes w/ different network topologies e.g. Daedalus Wallet is an edge node where the backend opens the API’s port only on the loopback device (localhost), that prevents any connection from outside. The other example is the explorer, which opens a public port w/ only limited API access (Cardano SL Explorer Web API).

So, if you start cardano-sl as an edge node backend on some public port and you create some wallet w/ some ADA in it then anybody (who has a proper client cert) could steal your money if no spending password is set.

If you want play w/ cardano-sl use a VM, or generate a self signed cert together w/ a client cert (signed w/ that self signed cert’s key) and use that client cert (install it in your browser) to connect to the backend (not recommended).

1 Like

Yes it’s the explorer that you linked that I’m trying to get working. As you say, it does open up to the public.

If I were to use a custom certificate, as you mention, how do I set the ./connect-to-mainnet to use that certificate?

It depends on the installation. How did you install it? nix or build? if you built it then prod or dev?

I followed this guide for nix-build:

So, you ran this for installing explorer: nix-build -A cardano-sl-explorer-static --cores 0 --max-jobs 2 --no-build-output --out-link master

Sorry no I ran nix-build -A connectScripts.mainnetWallet -o connect-to-mainnet

You should run this instead: nix-build -A connectScripts.mainnetExplorer -o connect-explorer-to-mainnet

okay but either way I can’t see a way of using a custom certificate as per my original question

The answer is depends on what you want to achieve. I am trying to explain it.

I have mentioned already, that there are different configs together w/ some network topologies that represent a node. For example Explorer, has a frontend and a backend either.

The frontend is which opens the port 3100 for public, while the backend (cardano-sl) uses the localhost:8090 to which the frontend connects to. So, there are two possible TLS (certificate) config here.

  • Between the frontend and backend (similar to Daedalus Wallet) and
  • for the frontend (not required as it can be achieved w/ ngix, apache or similar config).

So, what I wanted to say previously, that you should never ever open cardano-sl’s port to public for the Explorer and/or Daedalus. Unfortunately, I do not know the topology for the Pools (priv-, unpriv relay and core nodes), but I assume that core and the un/privileged nodes will use Kadmelia wo/ any opened ports to public.

So, if you try to explain what you really want ot achieve then I could probably help.

1 Like

@_ilap What I am trying to achieve is to be able to run a query like this from anywhere:


I’ve managed to be able to call it from anywhere with a curl -k:

curl -k https://my-cardano-sl-server.com:8090/api/v1/wallets/Ae2tdPwUPEZMeiDfNHZ45V7RoaSqd4oSMuG4jo7asvmNHS193EEad1tUkeT

by setting these:

sudo sysctl -w net.ipv4.conf.all.route_localnet=1
sudo iptables -t nat -A PREROUTING -p tcp --dport 8090 -j DNAT --to-destination

However the problem is that when I call that above URL from a browser, I obviously get a certificate verification failed message, because that certificate is only valid for localhost.

(this is the point at which my cert knowledge ends)

So, I figure I could get that fixed by either disabling completely ssl on cardano-sl (doesn’t seem possible) or generating a certificate for my-cardano-server.com, and having cardano-sl start up with that?

That won’t work in this config, as you have the cardano-sl running on localhost:8090 and DNAT-ing the incoming tls to the localhost. You can’t even proxying TLS.

What you can do is force cardano-sl to listen on the my-cardano-server.com:8090 instead, by modifying your connect-to-mainnet script:

--wallet-address <IP of my-cardano-server.com, not the DNS name>:8090 

Assuming, you have some older cardano-sl installed which does not require client cert cos the “curl -k” would not work (it would show ERR_BAD_SSL_CLIENT_AUTH_CERT):

Then, create a valid server cert either by

  1. using certbot or
  2. generate a CSR manually and sign it /w zerossl.com

zerossl.com example:

$ openssl genrsa -out server.key 4096 # Private key
$ find /etc/ -name openssl.cnf 2>/dev/null
$ export SAN_CFG=$(printf "\n[SAN]\nsubjectAltName = DNS:my-cardano-server.com,DNS:my-cardano-server\nextendedKeyUsage = serverAuth")
$ openssl req \
	-subj "/CN=my-cardano-server.com" \
	-sha256 \
	-new -key server.key \
	-out my-cardano-server.com.csr  \
	-reqexts SAN -extensions SAN \
	-config <(cat /etc/ssl/openssl.cnf <(echo "${SAN_CFG}")) # CSR
# Test it
$ openssl req -in my-cardano-server.com.csr -noout -text | grep -i DNS

Sign it by using zerossl.com

  • Modify connect-to-mainnet to reflect to the server cert, key and CA e.g. using zerossl.com
 --tlscert server.crt   # Signed cert by zerossl
 --tlskey server.key # Generated private key
 --tlsca ca.crt # use system wide CA file e.g. /etc/ssl/certs/ca-certificates.crt on Ubuntu

I have not checked these above, so it probably contains errors.


Tried all of this and it still just provides a localhost cert

What did you exactly do?

Also, did you remove the iptables rule below?

In that case, something is wrong w/ your connect-to-mainnet script and/or w/ the certificates.
Can you pls copy your connect-to-mainnet script here?

--tlscert server.crt # it must be full path to the signed cert
--tlskey server.key # full path to the generated private key 
--tlsca ca.crt # full path to a valid CA cert file.

UPDATE: I have tested and it works, so you missed something.


The good old CA. I have been an Assurer since its beginning (~2003-2004).

Unfortunately, it’s not widely accepted and only a few distr includes its root CA.
So, it’s like a self-signed cert from the browser/OS’s point of view.