Обсуждение: GSSAPI Authentication using a CNAME
Description
I am not able to connect to my PostgreSQL Server using the PostgreSQL JDBC Driver with GSSAPI when using the short name if the short name is a CNAME Record.
The fully qualified domain name does work when it is a CNAME.
For comparison, the psql client is able to connect using the short name when it is a CNAME.
Jason Breitman
JDBC Version
postgresql-42.2.16.jar
Dependancies
commons-cli-1.4
$ cat /opt/pgsql/conf/jaas.conf
pgjdbc {
com.sun.security.auth.module.Krb5LoginModule required
doNotPrompt=true
useTicketCache=true
renewTGT=true
debug=false
client=true;
};
Code Snippet
$ cat JDBCExample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
public class JDBCExample {
public static void main(String[] args) throws ParseException {
Options options = new Options();
Option host = Option.builder()
.longOpt("host")
.argName("host")
.hasArg()
.desc("Name of the PostgreSQL Server.")
.build();
options.addOption(host);
Option db = Option.builder()
.longOpt("db")
.argName("db")
.hasArg()
.desc("Name of the PostgreSQL Database.")
.build();
options.addOption(db);
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
String jdbcUrl = "jdbc:postgresql://" + cmd.getOptionValue("host") + ":5432/" + cmd.getOptionValue("db");
try (Connection conn = DriverManager.getConnection(jdbcUrl)) {
if (conn != null) {
System.out.println("Connected to the database!");
} else {
System.out.println("Failed to make connection!");
}
} catch (SQLException e) {
System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Compilation Steps
javac -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample.java
Results
$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host cname-hostname --db mydb
SQL State: 08006
GSS Authentication failed
$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host cname-hostname.example.com --db mydb
Connected to the database!
$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host hostname --db mydb
Connected to the database!
Jason Breitman
HI Jason,
Top posting because I don't want to delete below. I am wondering if this is a java thing. The docs for GSSAPI for java are pretty horrible.
Is there a setting to deal with CNAME's ?
Dave
On Wed, 26 Aug 2020 at 19:00, Jason Breitman <jbreitman@tildenparkcapital.com> wrote:
DescriptionI am not able to connect to my PostgreSQL Server using the PostgreSQL JDBC Driver with GSSAPI when using the short name if the short name is a CNAME Record.The fully qualified domain name does work when it is a CNAME.For comparison, the psql client is able to connect using the short name when it is a CNAME.JDBC Versionpostgresql-42.2.16.jarDependanciescommons-cli-1.4$ cat /opt/pgsql/conf/jaas.confpgjdbc {com.sun.security.auth.module.Krb5LoginModule requireddoNotPrompt=trueuseTicketCache=truerenewTGT=truedebug=falseclient=true;};Code Snippet$ cat JDBCExample.javaimport java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import org.apache.commons.cli.CommandLine;import org.apache.commons.cli.CommandLineParser;import org.apache.commons.cli.DefaultParser;import org.apache.commons.cli.Option;import org.apache.commons.cli.Options;import org.apache.commons.cli.ParseException;public class JDBCExample {public static void main(String[] args) throws ParseException {Options options = new Options();Option host = Option.builder().longOpt("host").argName("host").hasArg().desc("Name of the PostgreSQL Server.").build();options.addOption(host);Option db = Option.builder().longOpt("db").argName("db").hasArg().desc("Name of the PostgreSQL Database.").build();options.addOption(db);CommandLineParser parser = new DefaultParser();CommandLine cmd = parser.parse( options, args);String jdbcUrl = "jdbc:postgresql://" + cmd.getOptionValue("host") + ":5432/" + cmd.getOptionValue("db");try (Connection conn = DriverManager.getConnection(jdbcUrl)) {if (conn != null) {System.out.println("Connected to the database!");} else {System.out.println("Failed to make connection!");}} catch (SQLException e) {System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());} catch (Exception e) {e.printStackTrace();}}}Compilation Stepsjavac -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample.javaResults$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host cname-hostname --db mydbSQL State: 08006GSS Authentication failed$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host cname-hostname.example.com --db mydbConnected to the database!$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host hostname --db mydbConnected to the database!
Jason Breitman
Thank you for replying.
I do not believe this is the case for two reasons.
Using the CNAME with a fully qualified domain name does work as shown below which suggests that CNAME Records are ok.
Jason Breitman
The error code received when using the CNAME with a short name, 08006, is a connection failure.
I ran the same command with a dummy host that could not be resolved and receive the error code 08001 which means sqlclient unable to establish sqlconnection.
This suggests that the Java resolver is working and when the hostname cannot be resolved, we receive a different error code.
Please let me know if I am missing your point.
Reference
Jason Breitman
On Aug 27, 2020, at 7:24 AM, Dave Cramer <davecramer@postgres.rocks> wrote:
HI Jason,
Top posting because I don't want to delete below. I am wondering if this is a java thing. The docs for GSSAPI for java are pretty horrible.
Is there a setting to deal with CNAME's ?
Dave
On Wed, 26 Aug 2020 at 19:00, Jason Breitman <jbreitman@tildenparkcapital.com> wrote:
DescriptionI am not able to connect to my PostgreSQL Server using the PostgreSQL JDBC Driver with GSSAPI when using the short name if the short name is a CNAME Record.The fully qualified domain name does work when it is a CNAME.For comparison, the psql client is able to connect using the short name when it is a CNAME.JDBC Versionpostgresql-42.2.16.jarDependanciescommons-cli-1.4$ cat /opt/pgsql/conf/jaas.confpgjdbc {com.sun.security.auth.module.Krb5LoginModule requireddoNotPrompt=trueuseTicketCache=truerenewTGT=truedebug=falseclient=true;};Code Snippet$ cat JDBCExample.javaimport java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import org.apache.commons.cli.CommandLine;import org.apache.commons.cli.CommandLineParser;import org.apache.commons.cli.DefaultParser;import org.apache.commons.cli.Option;import org.apache.commons.cli.Options;import org.apache.commons.cli.ParseException;public class JDBCExample {public static void main(String[] args) throws ParseException {Options options = new Options();Option host = Option.builder().longOpt("host").argName("host").hasArg().desc("Name of the PostgreSQL Server.").build();options.addOption(host);Option db = Option.builder().longOpt("db").argName("db").hasArg().desc("Name of the PostgreSQL Database.").build();options.addOption(db);CommandLineParser parser = new DefaultParser();CommandLine cmd = parser.parse( options, args);String jdbcUrl = "jdbc:postgresql://" + cmd.getOptionValue("host") + ":5432/" + cmd.getOptionValue("db");try (Connection conn = DriverManager.getConnection(jdbcUrl)) {if (conn != null) {System.out.println("Connected to the database!");} else {System.out.println("Failed to make connection!");}} catch (SQLException e) {System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());} catch (Exception e) {e.printStackTrace();}}}Compilation Stepsjavac -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample.javaResults$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host cname-hostname --db mydbSQL State: 08006GSS Authentication failed$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host cname-hostname.example.com --db mydbConnected to the database!$ java -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=EXAMPLE.COM -Djava.security.auth.login.config=/opt/pgsql/conf/jaas.conf -cp .:postgresql-42.2.16.jar:commons-cli-1.4/commons-cli-1.4.jar JDBCExample --host hostname --db mydbConnected to the database!
Jason Breitman