BetterCloud / vault-java-driver

Zero-dependency Java client for HashiCorp's Vault
https://bettercloud.github.io/vault-java-driver/
335 stars 224 forks source link

Unexpected end of file from server #107

Closed mmukherjee closed 6 years ago

mmukherjee commented 6 years ago

Hi,

I starting to play around with vault and used these examples to connect to a vault instance running out of a docker container on my local system.

I am using this command to start the docker container - docker run -p 8200:8200 --cap-add IPC_LOCK -e 'VAULT_LOCAL_CONFIG={"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h", "listener": {"tcp":{"address":"127.0.0.1:8200", "tls_disable": "true"}}}' --hostname vault --name vault docker.artifactory.abc/shared/vault:0.9.5 server

Post which, I am logging into the container, and executing the following commands to initialise the vault -

/ # export VAULT_ADDR=http://127.0.0.1:8200
/ # vault operator init

From the output of this command, I note the root token and am using it for the test case outlined below.

Now, I have the following test case and intend to write to the vault and read from it.

package abc.co.nz;

import org.junit.Test;
import org.junit.Assert.*;
import static org.junit.Assert.assertEquals;

import java.util.Map;
import java.util.HashMap;
import com.bettercloud.vault.response.*;
import com.bettercloud.vault.*;

public class VaultTest {

  @Test
  public void testVault() throws Exception {
    final VaultConfig config = new VaultConfig()
            .address("http://127.0.0.1:8200")
            .token("6d14c36e-c975-ee50-62fc-fd3afefad4e0")
            .openTimeout(5)
            .readTimeout(3)
            .sslConfig(new SslConfig().verify(false).build())
            .build();

    final Vault vault = new Vault(config);
    final Map<String, Object> secrets = new HashMap<String, Object>();
    secrets.put("value", "world");
    secrets.put("other_value", "You can store multiple name/value pairs under a single key");

    // Write operation
    final LogicalResponse writeResponse = vault.logical().write("secret/hello", secrets);

    // Read operation
    //return vault.logical().read("secret/hello").getData().get("value");

    assertEquals("world", vault.logical().read("secret/hello").getData().get("value"));
  }
}

I get an error - com.bettercloud.vault.VaultException: com.bettercloud.vault.rest.RestException: java.net.SocketException: Unexpected end of file from server

What am I missing?

chris-pollard-assurity commented 6 years ago

The socket connection fails because the vault inside docker is listening on 127.0.0.1 inside the container - with this setting, I was not even able to vault init from outside the container.

Starting the container to listen on 0.0.0.0 (any network interface inside the container) now works for me. vault init works, but the vault will respond as follows to the client test code:

com.bettercloud.vault.VaultException: Expecting HTTP status 204 or 200, but instead receiving 503
Response body: {"errors":["Vault is sealed"]}

so the next step is to unseal the vault (with your container config, it takes 3 unseal keys):

> vault operator unseal $UNSEAL_KEY1
...
> vault operator unseal $UNSEAL_KEY2
...
> vault operator unseal $UNSEAL_KEY3
Key             Value
---             -----
Seal Type       shamir
Sealed          false <------- !!!
Total Shares    5
Threshold       3
Version         0.9.5
Cluster Name    vault-cluster-9ab891cc
Cluster ID      c08b3cac-ed13-920a-ad98-a68b652508a2
HA Enabled      false

Now running the test code passes.

mmukherjee commented 6 years ago

Thanks Chris. However, I would need a bit more help (spoon-feeding perhaps!)

Are you suggesting that the docker-run command should be -

docker run -p 8200:8200 --cap-add IPC_LOCK -e 'VAULT_LOCAL_CONFIG={"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h", "listener": {"tcp":{"address":"0.0.0.0:8200", "tls_disable": "1"}}}' --hostname vault --network host --name vault docker.artifactory.abc/shared/vault:0.9.5 server

I put in an additional --network host so as to ensure the docker container uses the host's network.

On the client end, I am still using - final VaultConfig config = new VaultConfig() .address("http://127.0.0.1:8200")

Where am I going wrong?

mmukherjee commented 6 years ago

the --network host was causing the issue. Removed it and it seems to be working now. Thanks so much for your help @chris-pollard-assurity