IPNS publishing after generating a key

If I publish at multiple API’s using the same ipfs hash and use the exact same key, then I get different ipns hashes as a result. Though both ipns resolve to the same ipfs hash.

Is it because the peer ID is added for routing purposes/DHT? In other words, it’s not possible to update an ipns hash from different public daemons? And therefore TXT records do need to be changed in that situation…

Seems that you are following a short guide to hosting your site on ipfs :thumbsup:

To answer your question:

Correct. Right now you can only publish to PeerID of your Identity key.
Support for publishing to alternative key is planned, but not implemented yet (v0.4.8-DEV):

$ ipfs name publish --help
(...)

Examples:
  
  Publish an <ipfs-path> to your identity name:
  
    > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
    Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
  
  Publish an <ipfs-path> to another public key (not implemented):
  
    > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
    Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

Hi Lidel.

Well, not completely. It saves keys, and it already creates non peerid ipns hashes with it (0.4.7).

First I generate a key: https://ipfs.io/docs/api/#apiv0keygen
Then I sent that key to publish: https://ipfs.io/docs/api/#apiv0namepublish

Sending with different keys, creates different hashes. So it is possible to publish multiple sites from the same setup, all good till so far.
But if I repeat it, with the same key, generated at another daemon, it results in a different ipns hash.

Will that be implemented, or isn’t that possible?

Wow, I tested it via HTTP APIs you linked and it seems to… work just fine. :rocket:

Not sure why you had different IPNS hash, but I got the feeling you were regenerating key instead of generating it only once and copying it to all nodes that should be able to publish with it.

I wrote a short instruction, check if you were following the same steps:

Publishing with the same key from two different nodes

I generated a new key under alias “test”:

nodeA $ curl 'http://localhost:5001/api/v0/key/gen?arg=test&type=ed25519'
{"Name":"test","Id":"QmbSSmC6ftFTz86twGypbfdRgq3apoixQQ2MgEdZmzNiMf"}

Then I published a picture /ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR in IPNS under PeerID of that key:

nodeA $ curl 'http://localhost:5001/api/v0/name/publish?arg=/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR&key=test'
{"Name":"QmbSSmC6ftFTz86twGypbfdRgq3apoixQQ2MgEdZmzNiMf","Value":"/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"}

I tested it and when I opened IPNS location for generated key:

/ipns/QmbSSmC6ftFTz86twGypbfdRgq3apoixQQ2MgEdZmzNiMf

I could see content from /ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR

Now, the important part: I wanted to publish to the same IPNS address from a different node.

I copied $IPFS_PATH/keystore/test to the same location at a different machine and used it to publish different picture with it:

nodeB $ curl 'http://localhost:5001/api/v0/name/publish?arg=/ipfs/QmYHNYAaYK5hm3ZhZFx5W9H6xydKDGimjdgJMrMSdnctEm&key=test'
{"Name":"QmbSSmC6ftFTz86twGypbfdRgq3apoixQQ2MgEdZmzNiMf","Value":"/ipfs/QmYHNYAaYK5hm3ZhZFx5W9H6xydKDGimjdgJMrMSdnctEm"}

Then, I opened the same IPNS location (for copied key):

/ipns/QmbSSmC6ftFTz86twGypbfdRgq3apoixQQ2MgEdZmzNiMf

I could see updated picture from /ipfs/QmYHNYAaYK5hm3ZhZFx5W9H6xydKDGimjdgJMrMSdnctEm

2 Likes

What I did was lookup if a key exists before generating: https://ipfs.io/docs/api/#apiv0keylist
But it’s true that I (re)generated the key at different nodes using the same input parameters.

So there’s only one way to publish at multiple nodes behind a load balancer at the moment:

  • Manual copy of keystore file

It’s an easy job, but not when you run a lot of domains at the nodes. So it would be nice if sharing keystores could be automated.

  • key/pull?arg=<name>&peer=<peerid_of_node>

Or send a custom peer id to the existing generate endpoint:

  • key/gen?arg=<name>&peer=<peerid_of_other_node>

But that’s what you aswered here, right?

Correct. Right now you can only publish to PeerID of your Identity key.
Support for publishing to alternative key is planned, but not implemented yet (v0.4.8-DEV):
.

Yes, you generated them, so those are different keys.
They just happened to have the same local alias (I feel this UX needs to be improved).

Correct. This is by design. This is how public key crypto works (eg. TLS in HTTPS, PGP/GPG).
Private key is generated once and needs to be copied to all locations where it will be used.

Exposing private keys via open HTTP API smells like a huge security risk.
Someone could download your private key and publish content to your IPNS site without your knowledge or control.

If this type of thing is to be implemented, we need some kind of access control for HTTP API first.
(See “HTTP API, access control and API tokens” in ipfs/notes #159).

No, the main point of public key crypto is that it is not possible to calculate/generate PrivKey from PublicKey (or PeerID). :slight_smile:

Hey!
At some point i’m going to be implementing an ipfs key send command, paired with an ipfs key recv. To send a key to someone you will have to run ipfs key send <peerID> and the other peer will have to run (at the same time) ipfs key recv <peerID>

This is still being thought through, but if you have any ideas about the UX there, please let me know

2 Likes

Hi guys,

First of all I really appreciate your fast and good replies.
Ipfs is designed to be distributed. What i’m trying to use it for atm, is more like decentralized. So I understand is not a 100% match.
The distributed way would be signing from a local daemon, and not with a public node. In that case the keys are safe anyway.

The main point of public key crypto is that it is not possible to calculate/generate PrivKey from PublicKey (or PeerID)

Exactly. But the fact is, it is possible to publish content to somebody else his IPNS site at the moment. And it’s pretty easy too. <-- Only at public nodes, with API access

I think a send+recv is a solution. But not the most practical in all situations. Because it needs 2 actions, 1 at both ends.

What would work is create a keypair at the third party software before any ipfs API call. And sign the ipns with that public key. After publishing the keys need to be auto removed too.
To re-publish, the author needs to own the private key to be able to recreate the same public key. At the moment i’m using a strong mnemonic with sha256 encryption, using the alias as salt.

So if we would be able to send a strong key as alias/name and tell ipfs not to add the peerid… It would be even more secure, plus publishing from all nodes is possible with the same ipns as a result. Without sharing at all.

No. I know it is annoying, but I feel we can’t do such mental shortcuts and need to be more formal and specific when we walk about these things :eyes:

It is not someone’s key. It is yours. You created it, you distributed it to nodes you control.
I – for example – can’t publish to IPNS site for your key, because I don’t have copy of it on my node.

I think 2 actions are required to avoid various attacks, for example unsolicited key-spam.
Without mutual confirmation I could spam people with advertisement in key name etc.

In general, Don’t Roll Your Own [Cryptography/Security].
I strongly feel we should use a battle-tested and formally documented schemes for these things.

And when there is a choice between convenience and security, always pick the latter.

Okay, I get it. Without advanced API access control it’s not smart to run a public node.

Publishing with someone’s key is only possible with API access. I should have added that, i’ll edit.
I think there’s no need to be specific about that. The keys are stored at the node, so it just takes 2 calls.

Should rather be “You can publish to others IPNS address if their node is running a open API”, which very few people do since it’s something you have to explicitly enable when starting the daemon. Also, this is not only a security risk for IPNS but overall, since with an open API you allow anyone full control of your IPFS node.