How to configure SASL enabled memcached username and password on mac - memcached

I installed memcached version 1.4.34 on my mac using homebrew. I wanted to configure a username and password to enable SASL support when interacting with memcache. Can you point me the right direction for this?
Ran below command to install memcache on mac.
brew install memcached --enable-sasl-pwdb
Above command installed memcache with sasl support.
echo "mech_list: plain" > memcached.conf
echo "myuser:mypass" > /tmp/memcached-sasl-db
export MEMCACHED_SASL_PWDB=/tmp/memcached-sasl-db
export SASL_CONF_PATH=`pwd`/memcached.conf
memcached -u myuser -m 1024 -p 8010 -S -B binary -vvv
Initialized SASL.
Now when I connect via memcache client it says Password verification failed on the terminal.
mech: ``PLAIN'' with 15 bytes of data
INFO: User <myuser#mylocal-macbook.local> failed to authenticate
SASL (severity 2): Password verification failed
sasl result code: -20
Unknown sasl response: -20
Here's the java code I'm using:
public class MemcacheTest {
public static void main(String[] args) {
System.setProperty("net.spy.memcached.auth.AuthThreshold", "10");
AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" },
new PlainCallbackHandler(
"myuser", "mypass"));
ConnectionFactory connFactory = new ConnectionFactoryBuilder()
.setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
.setAuthWaitTime(10000)
.setOpTimeout(10000)
.setShouldOptimize(true)
.setAuthDescriptor(ad).build();
List<InetSocketAddress> servers = AddrUtil
.getAddresses("localhost:8010");
MemcachedClient cacheClient = null;
try {
cacheClient = new MemcachedClient(connFactory, servers);
cacheClient.set("foo", 50000, "bar");
System.out.println("Value: " + cacheClient.get("foo"));
} catch (IOException iox) {
iox.printStackTrace();
}
}
}
Here are my intellij logs:
2017-02-23 15:19:04.223 INFO net.spy.memcached.MemcachedConnection: Reconnection due to exception handling a memcached operation on {QA sa=localhost/127.0.0.1:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=1}. This may be due to an authentication failure.
OperationException: SERVER: Auth failure.
at net.spy.memcached.protocol.BaseOperationImpl.handleError(BaseOperationImpl.java:192)
at net.spy.memcached.protocol.binary.OperationImpl.finishedPayload(OperationImpl.java:204)
at net.spy.memcached.protocol.binary.SASLBaseOperationImpl.finishedPayload(SASLBaseOperationImpl.java:98)
at net.spy.memcached.protocol.binary.OperationImpl.readPayloadFromBuffer(OperationImpl.java:196)
at net.spy.memcached.protocol.binary.OperationImpl.readFromBuffer(OperationImpl.java:139)
at net.spy.memcached.MemcachedConnection.readBufferAndLogMetrics(MemcachedConnection.java:861)
at net.spy.memcached.MemcachedConnection.handleReads(MemcachedConnection.java:840)
at net.spy.memcached.MemcachedConnection.handleReadsAndWrites(MemcachedConnection.java:720)
at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:683)
at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:436)
at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1446)

Yay! I got the issue. Couch base client automatically adds hostname at the end of the username. In my case when I set the username as myuser:mypassword but when I pass myuser in my java code, memcacheclient pass that information as myuser#mylocalhost-mac and that's where the mismatch was happening. To solve that I added the complete username with local host of the ssl db.
Instead of below line
echo "myuser:mypass" > /tmp/memcached-sasl-db
is replaced by
echo "myuser#mylocalhostMacBook-Pro-2.local:mypass" > /tmp/memcached-sasl-db
Now in java client I just pass myuser and client add the hostname automatically.

Related

MongoDB connection URI for SSL

I'm working on JDK8 and using mongo-java-driver(v3.5.0) to connect MongoDB(v3.6.3).
I've enabled SSL by following this article. I don't have /etc/mongod.conf file, instead I've /etc/mongodb.conf file; so I've updated the SSL settings in that file:
# SSL options
# Enable SSL on normal ports
sslOnNormalPorts = true
# SSL Key file and password
sslPEMKeyFile = /etc/ssl/mongodb.pem
sslPEMKeyPassword = PASSWORD
I'm able to access mongo via mongo shell using:
mongo --ssl --sslCAFile /etc/ssl/rootCA.pem --sslPEMKeyFile /etc/ssl/mongodb.pem --host localhost
I want to connect MongoDB using Java driver. I initially tried the following JDBC connection string:
mongodb://USER:PASSWORD#localhost:27017/?ssl=true&sslAllowInvalidCertificates=true&sslPEMKeyFile=/etc/ssl/mongodb.pem
but as per documentation, there are no such options available. Also, I get error:
The connection string contains an invalid host 'localhost:27017/?ssl=true&sslAllowInvalidCertificates=true&sslPEMKeyFile=/etc/ssl'. The port '27017/?ssl=true&sslAllowInvalidCertificates=true&sslPEMKeyFile=/etc/ssl' is not a valid, it must be an integer between 0 and 65535
And when I try with the following connection string:
url=mongodb://USER:PASSWORD#localhost:27017/?ssl=true
I get following error:
com.mongodb.MongoSocketWriteException: Exception sending message
at com.mongodb.connection.InternalStreamConnection.translateWriteException(InternalStreamConnection.java:445) ~[mongo-java-driver-3.5.0.jar:?]
.
...
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
.
...
Here's the code that I've used:
String url = "mongodb://USER:PASSWORD#localhost/?authSource=admin&ssl=true"
MongoClientURI connectionURI = new MongoClientURI(url)
mongoClient = new MongoClient(connectionURI)
Could someone help me with what JDBC connection string I need to configure to connect successfully. Thank you.

How to successfully connect to kerberos authenticated mongod instance from java application?I'm getting exception initializing GSSAPI Credentials

I've started mongod instance in kerberos auth mode.I'm able to connect from mongo shell.While connecting from java application,I get the following exception:
Key for the principal mongodb/****#**** not available in ***.keytab
[Krb5LoginModule] authentication failed
Unable to obtain password from user
My gss-jaas.conf is
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
useTicketCache=false
principal="mongodb/***#***"
doNotPrompt=true
keyTab="D:\***.keytab"
debug=true;};
I've used ktuil and executed following commands to write principal to keytab file.Can anyone help me to find out what's going wrong?
ktutil: add_entry -password -p mongodb/***#*** -k 1 -e des-cbc-md4
Password for mongodb/***#***:
ktutil: wkt /tmp/***.keytab
ktutil: quit
I've entered the password and also tried by skipping it with enter.In both the cases,I'm getting the above exception.I've used the following system properties in java application:
System.setProperty("java.security.krb5.conf","D:\\krb5.conf");
System.setProperty("java.security.auth.login.config","D:\\gss-jaas.conf");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
System.setProperty("java.security.krb5.realm","****");
System.setProperty("java.security.krb5.kdc","*****");
kerberosCredential = MongoCredential.createGSSAPICredential(userName);

Start MongoDb Test Container with credentials

I am able to start the mongo image, insert and read data just fine using the snippet below. Similar to the redis example on testcontainers.org.
private static final int MONGO_PORT = 27017;
#ClassRule
public static MongoDBContainer mongo = new MongoDBContainer("mongo:3.2.4")
.withExposedPorts(MONGO_PORT);
By default mongo doesn't have credentials but I'm looking for a way to set the credentials so that my app's MongoClient can get user/password from system properties and connect properly. I've tried adding the root user/password with the below but that didn't set the credentials properly.
#ClassRule
public static MongoDBContainer mongo = new MongoDBContainer("mongo:3.2.4")
.withExposedPorts(MONGO_PORT)
.withEnv("MONGO_INITDB_ROOT_USERNAME", "admin")
.withEnv("MONGO_INITDB_ROOT_PASSWORD", "admin");
My question is: How can I start the test container with a username and password to allow my app to connect to it during my integration test using wiremock.
Checking the docs you can have a GenericContainer rather than specifically a MongoDbContainer (not certain this makes much difference given it looks largely like I've got the same as what you've already tried)...
I've then run:
private static final int MONGO_PORT = 27017;
/**
* https://hub.docker.com/_/mongo shows:
*
* $ docker run -d --network some-network --name some-mongo \
* -e MONGO_INITDB_ROOT_USERNAME=mongoadmin \
* -e MONGO_INITDB_ROOT_PASSWORD=secret \
* mongo
*/
public static GenericContainer mongo = new GenericContainer(DockerImageName.parse("mongo:4.4.1"));
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("MONGO_INITDB_ROOT_USERNAME=mongoadministrator");
list.add("MONGO_INITDB_ROOT_PASSWORD=secret");
list.add("MONGO_INITDB_DATABASE=db");
mongo.setEnv(list);
mongo.withExposedPorts(MONGO_PORT);
mongo.start();
}
the logs from the container show:
docker logs [container_id]:
...
Successfully added user: {
"user" : "mongoadministrator", <<<<<
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
...
I can login successfully inside the container with my new administrative user:
> docker exec -it 3ae15f01074c bash
Error: No such container: 3ae15f01074c
> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
755e214f23d6 mongo:4.4.1 "docker-entrypoint.s…" 2 seconds ago Up 2 seconds 0.0.0.0:32803->27017/tcp elegant_keldysh
cdb4f55930f4 testcontainers/ryuk:0.3.0 "/app" 3 seconds ago Up 3 seconds 0.0.0.0:32802->8080/tcp testcontainers-ryuk-ef84751e-bfd4-41eb-b381-1c1206186eda
> docker exec -it 755e214f23d6 bash
root#755e214f23d6:/# mongo admin -u mongoadministrator
MongoDB shell version v4.4.1
Enter password: <<<<<<<<<<<<<<<< BAD PASSWORD ENTERED HERE
connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb
Error: Authentication failed. :
connect#src/mongo/shell/mongo.js:374:17
#(connect):2:6
exception: connect failed
exiting with code 1
root#755e214f23d6:/# mongo admin -u mongoadministrator
MongoDB shell version v4.4.1
Enter password: <<<<<<<< GOOD PASSWORD secret ENTERED HERE
connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("63279398-d9c6-491d-9bd9-6b619dc4a99d") }
MongoDB server version: 4.4.1
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
https://community.mongodb.com
---
The server generated these startup warnings when booting:
2020-10-24T22:06:24.914+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
---
---
Enable MongoDBs free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).
The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
>
In short, you can find working example of test with MongoDB container here.
To provide, more details: you can configure authentication to MongoDB test container by using GenericContainer and setting environment with following properties MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD:
#ClassRule
public static final GenericContainer<?> MONGODB = new GenericContainer<>(DockerImageName.parse(MONGO_IMAGE))
.withEnv("MONGO_INITDB_ROOT_USERNAME", USERNAME)
.withEnv("MONGO_INITDB_ROOT_PASSWORD", PASSWORD)
.withEnv("MONGO_INITDB_DATABASE", TEST_DATABASE)
.withExposedPorts(MONGO_PORT);
Then you should use MongoClient with corresponding MongoCredential. For example, below is the test, that writes and reads document to/from MongoDB container.
#Test
public void shouldWriteAndReadMongoDocument() {
ServerAddress serverAddress = new ServerAddress(MONGODB.getHost(), MONGODB.getMappedPort(MONGO_PORT));
MongoCredential credential = MongoCredential.createCredential(USERNAME, AUTH_SOURCE_DB, PASSWORD.toCharArray());
MongoClientOptions options = MongoClientOptions.builder().build();
MongoClient mongoClient = new MongoClient(serverAddress, credential, options);
MongoDatabase database = mongoClient.getDatabase(TEST_DATABASE);
MongoCollection<Document> collection = database.getCollection(TEST_COLLECTION);
Document expected = new Document("name", "foo").append("foo", 1).append("bar", "string");
collection.insertOne(expected);
Document actual = collection.find(new Document("name", "foo")).first();
assertThat(actual).isEqualTo(expected);
}
Notes:
To find more details on environment variables, you check documentation here (specifically, Environment Variables section)
To find more details on authenticated connection to MongoDB, you check documentation here

Authenticating with MongoDB from JavaScript file

I'm trying to write a MongoDB script as part of automating customer data deletion in accordance with GDPR (current process is manual), but I'm having problems authenticating from the script. Authentication works perfectly from the command line, but not from a script.
I'm not certain which mechanism I should use, but since there are only two that don't require external files (which I don't use in the command line), I figured I'd try both.
When running from the command line, this is the command I use:
$ mongo -u [adminusr] -p '[adminpwd]' --authenticationDatabase admin
This script:
var host = '127.0.0.1';
var port = '27017';
var user = 'admin';
var pwd = 'secrets';
var authDB = 'admin';
try {
var conn = new Mongo('mongodb://' + host + ':' + port + '/' + authDB);
conn.auth({
user: user,
pwd: pwd,
mechanism: 'SCRAM-SHA-1',
digest: false
});
// deletion commands...
} catch (e) {
print(e);
}
gives this error:
$ mongo erasure.js
MongoDB shell version v3.4.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.10
Error: Authentication failed.
Changing the auth part to this:
conn.auth({
user: user,
pwd: pwd,
mechanism: 'MONGODB-CR',
db: authDB,
digest: false
});
gives me this error:
$ mongo erasure.js
MongoDB shell version v3.4.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.10
Error: auth failed
The official documentation on writing MongoDB scripts and authentication is also very scarce on how to do this.
How can I get the auth to work?
Thanks.

MongoDB db.serverStatus() gives error when running using tunnel that is targeted to api.cloudfoundry.com

Following is the console session...
C:\Users\xxx>vmc tunnel myMongoDB
Getting tunnel connection info: OK
Service connection info:
username : uuuu
password : pppp
name : db
url : mongodb://uuuu:pppp#172.30.xx.xx:25200/db
Starting tunnel to myMongoDB on port 10000.
1: none
2: mongo
3: mongodump
4: mongorestore
Which client would you like to start?: 2
Launching 'mongo --host localhost --port 10000 -u uuuu -p pppp db'
MongoDB shell version: 2.0.6
connecting to: localhost:10000/db
> db.serverStatus()
{ "errmsg" : "need to login", "ok" : 0 }
>
Which credentials should I use to login (assuming should use db.auth) to get rid of the error "{ "errmsg" : "need to login", "ok" : 0 }".
When I run the same in micro CF on my machine it works ok and gives me the expected output.
P.S. I'm trying this to get to know the current connections on my application, written in node.js. Trying to debug some issues with connections to the DB. If there is any other alternative that I can use please suggest that as well.
this should work! Not sure why your tunnel isn't connecting, my immediate suggestion is to try another instance of MongoDB and see if the same error occurs.
If you are trying to inspect the bound services on you node.js app you should be able to inspect them in the VCAP_SERVICES environment variable. For example;
var http = require('http');
var util = require('util');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(util.inspect(process.env.VCAP_SERVICES));
res.write("\n\n************\n\n");
res.end(util.inspect(req.headers));
}).listen(3000);
This code is currently running at http://node-headers.cloudfoundry.com/ to serve as an example. However, mongodb connections for node.js applications should automatically configure to the bound service. If this does not work for you, then please do let me know.