Kerberos uses the IP instead of hostname - java

I'm writing a Java class to access to Solr (with SolrJ) in a Kerberized Cloudera Virtual Machine with a static IP address (I'm using VMWare) from a windows machine. The problem is that Kerberos returns me the following error: Server not found in Kerberos database (7) - UNKNOWN_SERVER.
This is the complete error:
KRBError:
cTime is Sun Mar 06 03:49:00 CET 1994 762922140000
sTime is Thu Dec 29 16:11:14 CET 2016 1483024274000
suSec is 413432
error code is 7
error Message is Server not found in Kerberos database
cname is cloudera#CLOUDERA
sname is HTTP/192.168.59.200#CLOUDERA
msgType is 30
The problem is that Kerberos uses the IP address of the Virtual Machines (in which Kerberos is installed) instead of the FQDN (= quickstart.cloudera). In fact in Kerberos exists only HTTP/quickstart.cloudera#CLOUDERA principal.
I also tried to rename the service principal from HTTP/quickstart.cloudera#CLOUDERA to HTTP/192.168.59.200#CLOUDERA and it worked, but I broke all cloudera's internal services that use the HTTP original principal.
In the windows hosts file I put: 192.168.59.200 quickstart.cloudera
This is my krb5.conf:
[libdefaults]
default_realm = CLOUDERA
rdns = true
dns_lookup_kdc = true
dns_lookup_realm = true
dns_canonicalize_hostname = true
ignore_acceptor_hostname = true
ticket_lifetime = 86400
renew_lifetime = 604800
forwardable = true
default_tgs_enctypes = rc4-hmac
default_tkt_enctypes = rc4-hmac
permitted_enctypes = rc4-hmac
udp_preference_limit = 1
kdc_timeout = 3000
[realms]
CLOUDERA = {
kdc = quickstart.cloudera
admin_server = quickstart.cloudera
default_domain = quickstart.cloudera
}
[domain_realm]
.cloudera = CLOUDERA
quickstart.cloudera = CLOUDERA
This is my jaas.conf:
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="C:/Binaries/Kerberos/cloudera.keytab"
doNotPrompt=true
useTicketCache=false
storeKey=true
debug=true
principal="cloudera#CLOUDERA";
};
And this is my java test code:
#Test
public void testSecureSolr() {
try {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("java.security.krb5.conf","C:\\Binaries\\Kerberos\\krb5.conf");
System.setProperty("java.security.auth.login.config","C:\\Binaries\\Kerberos\\jaas.conf");
LOG.info("-------------------------------------------------");
LOG.info("------------------- TESTS SOLR ------------------");
LOG.info("-------------------------------------------------");
HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());
SolrServer solrServer = new HttpSolrServer(CLUSTER_URI_SOLR);
SolrPingResponse pingResponse = solrServer.ping();
LOG.info("Solr Ping Status: "+ pingResponse.getStatus());
LOG.info("Solr Ping Time: "+ pingResponse.getQTime());
} catch (SolrServerException | IOException e) {
e.printStackTrace();
}
}
Any suggestion? Thanks.

Related

Connect to Postgres DB with Kerberos from Java/Windows7

I've looked everywhere and asked loads of people but no one is able to help me so far. I'm trying to connect to a postgres (9.6) database on a remote machine from my windows (7) laptop through a Java (8) application. We use Kerberos for securing access but i have a valid Kerberos account and can create tickets via de Ticket Manager. I can also log on to other 'services' which require Kerberos authentication, although not through java but via a browser.
But whatever i try, i can't get my java program to work. Here's what i've got:
krb5.ini
[libdefaults]
default_realm = <domain>
forwardable = true
kdc_timesync = 1
ccache_type = 4
proxiable = true
dns_lookup_kdc = true
dns_lookup_realm = true
[realms]
<domain>.NET = {
admin_server = <domain-server>
default_domain = <domain>
}
[domain_realm]
.<domain> = <domain>
<domain> = <domain>
.local.nl.<company>.com = <domain>
local.nl.<company>.com = <domain>
[login]
krb4_convert = true
krb4_get_tickets = false
jaas.conf:
pgjdbc {
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true
doNotPrompt=false
useTicketCache=false
renewTGT=false
useKeyTab=true
keyTab="<location>/<filename>.keytab"
debug=true
client=true
principal="<username>#<domain>";
};
.keytab file
public class KerberosPostgresClient {
static {
System.setProperty("java.security.krb5.conf","c:/tmp/krb5.ini");
System.setProperty("java.security.krb5.realm","<domain>");
System.setProperty("java.security.krb5.kdc","<domain>");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
System.setProperty("java.security.auth.login.config","c:/tmp/jaas.conf"); }
#Test
public void test() throws Exception {
String url = "jdbc:postgresql://<hostname>:<port>/<database>";
Properties properties = new Properties();
properties.setProperty("JAASConfigName", "pgjdbc");
try (Connection conn = DriverManager.getConnection(url, connInfo)) {
conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The very simple java code can find the keytab, jaas.conf. I created the keytab file on a different machine but with the same principal and password.
When i run the program i see:
Debug is true storeKey false useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator true KeyTab is c:/tmp/<username>.keytab refreshKrb5Config is true principal is <username>#<domain> tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
and after a short while i get an exception:
[Krb5LoginModule] authentication failed
Receive timed out
org.postgresql.util.PSQLException: GSS Authentication failed
at org.postgresql.gss.MakeGSS.authenticate(MakeGSS.java:65)
....
Caused by: java.net.SocketTimeoutException: Receive timed out
at java.net.DualStackPlainDatagramSocketImpl.socketReceiveOrPeekData(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.receive0(DualStackPlainDatagramSocketImpl.java:120)
at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:144)
at java.net.DatagramSocket.receive(DatagramSocket.java:812)
at sun.security.krb5.internal.UDPClient.receive(NetClient.java:206)
at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:411)
at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:364)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.krb5.KdcComm.send(KdcComm.java:348)
at sun.security.krb5.KdcComm.sendIfPossible(KdcComm.java:253)
at sun.security.krb5.KdcComm.send(KdcComm.java:229)
at sun.security.krb5.KdcComm.send(KdcComm.java:200)
at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:316)
at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:776)
... 45 more
I used to get other exceptions which indicated that it couldn't find the keytab file but with the above setup it seems to work. I can also ping the postgres database from my machine.
I found: Error connecting to PostgreSQL 9.4 with MIT Kerberos via JDBC vs CLI but has no solution
i finally got it working with the following settings in my jaas.conf:
pgjdbc {
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true
doNotPrompt=true
useTicketCache=true
renewTGT=true
useKeyTab=true
keyTab="c:/<locationto>/<user>.keytab"
debug=true
client=true
principal="<user>#<domain>";
};
namely the combination of doNotPrompt, useTicketCache, renewTGT finally got it working

JDBC connection between Docker containers (docker-compose)

I try to connect a web application which runs on a tomcat 8 to an oracle database. Both of them run as Docker containers:
docker-compose.yml:
version: "3"
services:
appweb:
build: ./app
image: "servlet-search-app:0.1"
ports:
- "8888:8080"
links:
- appdb
environment:
- DATA_SOURCE_NAME="jdbc:oracle:thin:#appdb:1521/XE"
appdb:
build: ./db
image: "servlet-search-db:0.1"
ports:
- "49160:22"
- "1521:1521"
- "8889:8080"
Dockerfile of my oracle DB image (build: ./db):
FROM wnameless/oracle-xe-11g
ADD createUser.sql /docker-entrypoint-initdb.d/
ENV ORACLE_ALLOW_REMOTE=true
Dockerfile of the tomcat image (build: ./app)
FROM tomcat:8.0.20-jre8
COPY servlet.war /usr/local/tomcat/webapps/
COPY ojdbc14-1.0.jar /usr/local/tomcat/lib/
So the app starts up as expected but throws an exception when trying to connect to the database:
java.lang.IllegalStateException: java.sql.SQLException: Io exception: Invalid connection string format, a valid format is: "host:port:sid"
org.se.lab.ui.ControllerServlet.createConnection(ControllerServlet.java:115)
org.se.lab.ui.ControllerServlet.handleSearch(ControllerServlet.java:78)
org.se.lab.ui.ControllerServlet.doPost(ControllerServlet.java:53)
org.se.lab.ui.ControllerServlet.doGet(ControllerServlet.java:38)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Now the issue seems obvious, however when I fix the DATA_SOURCE_NAME string to:
DATA_SOURCE_NAME="jdbc:oracle:thin:#appdb:1521:XE"
I get the following exception:
java.lang.IllegalStateException: java.sql.SQLException: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
The Connection descriptor used by the client was:
appdb:1521:XE"
org.se.lab.ui.ControllerServlet.createConnection(ControllerServlet.java:115)
org.se.lab.ui.ControllerServlet.handleSearch(ControllerServlet.java:78)
org.se.lab.ui.ControllerServlet.doPost(ControllerServlet.java:53)
org.se.lab.ui.ControllerServlet.doGet(ControllerServlet.java:38)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Now I tried to find out which one of them should actually work. Thus, I started only the DB container:
docker build -t dbtest .
docker run -it -d --rm -p 1521:1521 --name dbtest dbtest
docker inspect dbtest | grep IPAddress
>> "IPAddress": "172.17.0.4"
Next, I try to connect with sqlplus:
sqlplus system/oracle#172.17.0.4:1521/XE # works
sqlplus system/oracle#172.17.0.4:1521:XE #ERROR: ORA-12545: Connect failed because target host or object does not exist
So what's the problem? Due to the link in the docker-compose file, the tomcat container can resolve "appdb" to the container's IP.
Here's the code which should establish the connection:
protected Connection createConnection() {
String datasource = System.getenv("DATA_SOURCE_NAME");
try {
// debug
InetAddress address = null;
try {
address = InetAddress.getByName("appdb");
System.out.println(address); // resolves in appdb/10.0.0.2
System.out.println(address.getHostAddress()); // resolves in 10.0.0.2
} catch (UnknownHostException e) {
e.printStackTrace();
}
Class.forName("oracle.jdbc.driver.OracleDriver");
return DriverManager.getConnection(datasource, "system", "oracle");
} catch (SQLException | ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}
Lastly here's the tnsnames.ora file:
cat $ORACLE_HOME/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File:
XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = fcffb044d69d)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
)
Thanks!
The oracle default listener resolved the configured host to the wrong IP address:
vim $ORACLE_HOME/network/admin/listener.ora:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/xe)
(PROGRAM = extproc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE))
(ADDRESS = (PROTOCOL = TCP)(HOST = f4c4a3638c11)(PORT = 1521))
)
)
DEFAULT_SERVICE_LISTENER = (XE)
The HOST value is the Docker container id. If we look at /etc/hosts it is set up correctly for the service link in the docker-compose link:
10.0.0.5 f4c4a3638c11
It gets also resolved correctly from the tomcat container
ping f4c4a3638c11
PING f4c4a3638c11 (10.0.0.5): 56 data bytes
...
If I try to connect with an IP address of the other interface, which is the docker interface from the host system, the connection from the web application to the database works
String datasource = "jdbc:oracle:thin:#172.17.0.4:1521:XE";
So the solution is to configure the listener to listen to the correct IP address
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.5)(PORT = 1521))
Now this connection string works:
jdbc:oracle:thin:#appdb:1521:XE
I will report this behavior to wnameless/oracle-xe-11g as a bug
Sorry, this is not a definitive answer. Let's treat it as long comment :)
Your setup is quite complex for me to recreate however your error message is intriguing:
The Connection descriptor used by the client was:
appdb:1521:XE"
...
It looks like the environment value was chopped to appdb:1521:XE. How about if you try hard-coding:
String datasource = "jdbc:oracle:thin:#appdb:1521/XE";
If that works, then probably need to somehow escape your docker DATA_SOURCE_NAME environment variable.
I could be completely wrong but I think it is worth a try.

SASL LOGIN authentication failed: UGFzc3dvcmQ6

CentOS6.6, Postfix, dovecot 2.0.9 and MySQL 5.1.73
dovecot configuration (/etc/dovecot/dovecot-sql.conf.ext):
driver = mysql
connect = host=127.0.0.1 dbname=postfix user=root password=lingo
default_pass_scheme = SHA512
password_query = SELECT email as user, password FROM virtual_user WHERE email='%u';
MySQL database:
mysql> SELECT email as user, password FROM virtual_user WHERE email='lingo.lin1#radicasys.com';
+--------------------------+------------------------------------------------------------------------------------------------------------+
| user | password |
+--------------------------+------------------------------------------------------------------------------------------------------------+
| lingo.lin1#example.com | 0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c |
+--------------------------+------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
The password is generated by commons-codec, Java code:
System.out.println(DigestUtils.sha512Hex("lingo".getBytes()));
//print :0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c
Now I wrote some Java-code to authenticate:
public static void sendEmail() throws EmailException, GeneralSecurityException {
SimpleEmail email = new SimpleEmail();
// smtp host
email.setHostName("192.168.15.139");
email.setSmtpPort(25);
email.setDebug(true);
// DigestUtils.sha512Hex("lingo".getBytes())
email.setAuthentication("lingo.lin1#example.com", "lingo");
email.setStartTLSEnabled(true);
MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
Properties propsSSL = email.getMailSession().getProperties();
propsSSL.put("mail.smtp.port", "465");
propsSSL.put("mail.smtp.ssl.checkserveridentity", "false");
propsSSL.put("mail.smtp.ssl.socketFactory", socketFactory);
email.addTo("lingo.lin#qamail.rimanggis.com", "John Doe");
email.setFrom("lingo.lin#radicasys.com", "Me");
email.setSubject("Test message");
email.setMsg("This is a simple test of commons-email");
email.send();
System.out.println("success");
}
public static void main(String[] args) throws Exception {
SendEmailTest.sendEmail();
// System.out.println(DigestUtils.sha512Hex("lingo".getBytes()));
}
But it fails with following error:
Sep 12 13:30:51 localhost dovecot: auth: Debug: sql(lingo.lin1#radicasys.com,192.168.15.243): query: SELECT email as user, password FROM virtual_user WHERE email='lingo.lin1#radicasys.com';
Sep 12 13:30:51 localhost dovecot: auth: Error: sql(lingo.lin1#radicasys.com,192.168.15.243): Password in passdb is not in expected scheme SHA512
Sep 12 13:30:53 localhost postfix/smtpd[1872]: warning: unknown[192.168.15.243]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
Sep 12 13:30:53 localhost dovecot: auth: Debug: client out: FAIL#0115#011user=lingo.lin1#radicasys.com
Sep 12 13:30:53 localhost postfix/smtpd[1872]: lost connection after AUTH from unknown[192.168.15.243]
Sep 12 13:30:53 localhost postfix/smtpd[1872]: disconnect from unknown[192.168.15.243]
How can I fix the authentication?
This is a dovecot configuration issue. Dovecot knows two hash encodings, the "traditional" hex encoding (ie. SHA512.HEX) and Base64-encoding (ie. SHA512.b64). The latter is more space-efficient when stored as strings and default in Dovecot. An example for generating the hash with sha512, sha512.b64 and sha512.hex encodings:
$ doveadm pw -p lingo -s sha512
{SHA512}DaO0sDhcQyqADKFerhqEheX3q617cLThwrnPFfaK/SVs7bICnG987AnhIh5rEBQggeG7jlyAL7l+g8iTwo2GFA==
$ doveadm pw -p lingo -s sha512.b64
{SHA512.b64}DaO0sDhcQyqADKFerhqEheX3q617cLThwrnPFfaK/SVs7bICnG987AnhIh5rEBQggeG7jlyAL7l+g8iTwo2GFA==
$ doveadm pw -p lingo -s sha512.hex
{SHA512.HEX}0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c802fb97e83c893c28d8614
Use default_pass_scheme = SHA512.HEX if you create hex-encoded passwords hashes in Java. The better solution would be to use Dovecot's {SCHEME}hash encoding instead of setting the default_pass_scheme, though: doing so, you can easily change/upgrade the hash method later without invalidating all user's passwords at once. An example for the hash you used in this scheme:
{SHA512.hex}0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c
Finally: plain hashing of passwords is never save, also not when using large SHA512 hashes. Never store unsalted password hashes, you're vulnerable to rainbow table attacks if the database leaks.
i generate by this code:
private String SHA(final String strText, final String strType) {
String strResult = null;
if (strText != null && strText.length() > 0) {
try {
MessageDigest messageDigest = MessageDigest.getInstance(strType);
messageDigest.update(strText.getBytes());
byte byteBuffer[] = messageDigest.digest();
StringBuffer strHexString = new StringBuffer();
for (int i = 0; i < byteBuffer.length; i++) {
String hex = Integer.toHexString(0xff & byteBuffer[i]);
if (hex.length() == 1) {
strHexString.append('0');
}
strHexString.append(hex);
}
strResult = strHexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
return strResult;
}
public static void main(String[] args) {
EncryptUtils et=new EncryptUtils();
String pas=et.SHA512("lingo");
System.out.println("{SHA512.HEX}"+pas);
}

SPNEGO / ActiveDirectory / AES256: Checksum failed

I am trying to use SPNEGO / Kerberos5 authentication with Active Directory 2008 and Java. I followed this guide: http://spnego.sourceforge.net/ - "preflight" went well, but later I get the famous exception:
Exception in thread "main" GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:906)
at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:556)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at de.meona.auth.spnego.TestSpnegoAes.main(TestSpnegoAes.java:45)
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:102)
I had a close look at this post, as the problem seems similar:
checksum failed: Kerberos / Spring / Active Directory (2008)
In order to make the problems reproducible, I wrote a small Java class. I was able to single-step to the line where the exception happens. I think it is because the secret service key used for decryption is different from the secret service key the Active Directory used to encrypt the service ticket. How can this be?
public class TestSpnegoAes {
private static Oid spnegoOid = null;
private static String negotiate = "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";
private static GSSManager manager;
// -Dsun.security.krb5.debug=true
// -Djava.security.auth.login.config=login.conf
public static void main(String[] args) throws GSSException, LoginException, PrivilegedActionException {
spnegoOid = new Oid("1.3.6.1.5.5.2");
manager = GSSManager.getInstance();
LoginContext loginContext = new LoginContext("spnego-server");
loginContext.login();
Subject subject = loginContext.getSubject();
GSSCredential serviceCredentials = getServerCredential(subject);
GSSContext context = manager.createContext(serviceCredentials);
byte[] token = Base64.decode(negotiate);
context.acceptSecContext(token, 0, token.length);
}
static GSSCredential getServerCredential(final Subject subject) throws PrivilegedActionException {
final PrivilegedExceptionAction<GSSCredential> action = new PrivilegedExceptionAction<GSSCredential>() {
public GSSCredential run() throws GSSException {
return manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, spnegoOid,
GSSCredential.ACCEPT_ONLY);
}
};
return Subject.doAs(subject, action);
}
}
This is my login.conf file:
spnego-server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
isInitiator=false
keyTab="file:///C:/Temp/krbtest/meona-service.keytab"
principal=meona-service;
};
I you would like to reproduce, I am happy to give the keytab file as well. It was produced on the PDC using "kpass /out keytab /princ meona-service#meona.intra /pass ... /crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL".
As the LoginContext login succeeds, I think the key is recovered successfully.
This is the stdout:
Java config name: null
Native config name: C:\Windows\krb5.ini
Found KeyTab C:\Temp\krbtest\meona-service.keytab for meona-service#meona.intra
Found KeyTab C:\Temp\krbtest\meona-service.keytab for meona-service#meona.intra
Entered Krb5Context.acceptSecContext with state=STATE_NEW
>>> KeyTabInputStream, readName(): MEONA.INTRA
>>> KeyTabInputStream, readName(): meona-service
>>> KeyTab: load() entry length: 75; type: 18
Looking for keys for: meona-service#meona.intra
Added key: 18version: 1
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
Exception in thread "main" GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)
If I do not use a keytab, but use pre-authentication, I am able to recover the key, but get the same error later on.
Any ideas?
Here is the krb5.conf I used to generate the SPNEGO negotiate header.
[libdefaults]
default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
default_realm = MEONA.INTRA
[realms]
MEONA.INTRA = {
kdc = pdc.meona.intra
default_domain = MEONA.INTRA
}
[domain_realm]
.MEONA.INTRA = MEONA.INTRA
I tried different variants (with/without ".intra", uppercase/lowercase), without success. But after changing the ticket encryption (using the settings of the AD service user) to ARC4/HMAC1, everything works as expected - what is the problem with AES256?
I seen this issue while using Java 17 and Spnego
My Keytab-file contained entries for AES128/256. We have enabled AES-token for the AD account through Support. Then I see a error "checksum failed" (KVN and password are not changed).
Support generates keytab via ktpass. I replace it on the server and after restarting the application the error was resolved.
I re-generated the keytab-file via ktab with the new kvn - keytab also worked.
After enabling AES, you need "refresh" the account in AD for change the KVN parameter. And then the integration will work.

mongodb insert fails due to socket exception

I am working on a Java project in Eclipse. I have a staging server and a live server. Those two also have their own mongodbs, which run on a different server on two different ports (29017 and 27017).
Via a Junit Test I want to copy data from the live mongo to the devel mongo.
Weirdest thing: sometimes it works and sometimes I get a socket error. I wonder why mongo sometimes completely refuses to write inserts and on other days it works flawlessly. Here is an excerpt of the mongo log file (the one where code gets inserted) and the Junit test script:
mongo log:
Thu Mar 14 21:01:04 [initandlisten] connection accepted from xx.xxx.xxx.183:60848 #1 (1 connection now open)
Thu Mar 14 21:01:04 [conn1] run command admin.$cmd { isMaster: 1 }
Thu Mar 14 21:01:04 [conn1] command admin.$cmd command: { isMaster: 1 } ntoreturn:1 keyUpdates:0 reslen:90 0ms
Thu Mar 14 21:01:04 [conn1] opening db: repgain
Thu Mar 14 21:01:04 [conn1] query repgain.editorconfigs query: { $and: [ { customer: "nokia" }, { category: "restaurant" } ] } ntoreturn:0 keyUpdates:0 locks(micros) W:5302 r:176 nreturned:0 reslen:20 0ms
Thu Mar 14 21:01:04 [conn1] Socket recv() errno:104 Connection reset by peer xx.xxx.xxx.183:60848
Thu Mar 14 21:01:04 [conn1] SocketException: remote: xx.xxx.xxx.183:60848 error: 9001 socket exception [1] server [xx.xxx.xxx.183:60848]
Thu Mar 14 21:01:04 [conn1] end connection xx.xxx.xxx.183:60848 (0 connections now open)
junit test script:
public class CopyEditorConfig {
protected final Log logger = LogFactory.getLog(getClass());
private static final String CUSTOMER = "customerx";
private static final String CATEGORY = "categoryx";
#Test
public void test() {
try {
ObjectMapper om = new ObjectMapper();
// script copies the config from m2 to m1.
Mongo m1 = new Mongo("xxx.xxx.com", 29017); // devel
Mongo m2 = new Mongo("yyy.yyy.com", 27017); // live
Assert.assertNotNull(m1);
Assert.assertNotNull(m2);
logger.info("try to connect to db \"dbname\"");
DB db2 = m2.getDB("dbname");
logger.info("get collection \"config\"");
DBCollection c2 = db2.getCollection("config");
JacksonDBCollection<EditorTabConfig, ObjectId> ec2 = JacksonDBCollection.wrap(c2, EditorTabConfig.class, ObjectId.class);
logger.info("find entry with customer {" + CUSTOMER + "} and category {" + CATEGORY + "}");
EditorTabConfig config2 = ec2.findOne(DBQuery.and(DBQuery.is("customer", CUSTOMER), DBQuery.is("category", CATEGORY)));
// config
if (config2 == null) {
logger.info("no customer found to copy.");
} else {
logger.info("Found config with id: {" + config2.objectId + "}");
config2.objectId = null;
logger.info("copy config");
boolean found = false;
DB db1 = m1.getDB("dbname");
DBCollection c1 = db1.getCollection("config");
JacksonDBCollection<EditorTabConfig, ObjectId> ec1 = JacksonDBCollection.wrap(c1, EditorTabConfig.class, ObjectId.class);
EditorTabConfig config1 = ec1.findOne(DBQuery.and(DBQuery.is("customer", CUSTOMER), DBQuery.is("category", CATEGORY)));
if (config1 != null) {
found = true;
}
if (found == false) {
WriteResult<EditorTabConfig, ObjectId> result = ec1.insert(config2);
ObjectId id = result.getSavedId();
logger.info("INSERT config with id: " + id);
} else {
logger.info("UPDATE config with id: " + config1.objectId);
ec1.updateById(config1.objectId, config2);
}
StringWriter sw = new StringWriter();
om.writeValue(sw, config2);
logger.info(sw);
}
} catch (Exception e) {
logger.error("exception occured: ", e);
}
}
}
Running this script seems like a success when I read the log in eclipse. I get an id for both c1 and c2 and the data is also here. The log even states, that it didn't find the config on devel and inserts it. That also is true, if I put it there manually. It gets "updated" then. But the mongo log stays the same.
The socket exception occurs, and the data is never written to the db.
I am out of good ideas to debug this. If you could, I'd be glad to get some tips how to go from here. Also, if any information is missing, please tell me, I'd be glad to share.
Regards,
Alex
It seems you have a connection issue with mongo server. Below ways may help you better diagnose the mongo servers:
Try to get more information from log files:
$less /var/log/mongo/mongod.log
or customized log files defined in mongod.conf
Try to use mongostat to monitor the server state:
$ mongostat -u ADMIN_USER -p ADMIN_PASS
Try to use mongo cli to check server runing status:
$ mongo admin -u ADMIN_USER -p ADMIN_PASS
$ db.serverStatus()
More useful commands is at: http://docs.mongodb.org/manual/reference/method/
Sometimes it may come across with Linux system configs. Try to tune Linux for more connections and limits, and it may help.
To check current Linux limits, run:
$ ulimit -a
Below suggestions may be helpful:
Each connection is seen by Linux as an open file. The default maximum number of open file is 1024. To increase this limit:
modify /etc/security/limits.conf:
root soft nofile 500000
root hard nofile 512000
root soft nproc 500000
root hard nproc 512000
modify /etc/sysctl.conf
fs.file-max=360000
net.ipv4.ip_local_port_range=1024 65000
Comment out the line in your mongod.conf that binds the IP to 127.0.0.1.
Usually, it is set to 127.0.0.1 by default.
For Linux, this config file location should be be /etc/mongod.conf. Once you comment that out , it will receive connections from all interfaces. This fixed it for me as i was getting these socket exceptions as well.

Categories