Go postgres connection SSL not enabled - postgresql

I'm trying to connect to my localhost postgresql server without SSL and I'm getting this error:
pq: SSL is not enabled on the server
That's fine, I know how to fix it:
type App struct {
Router *mux.Router
DB *sql.DB
}
func (a *App) Initialize(dbname string) {
connectionString := fmt.Sprintf("dbname=%s sslmode=disable", dbname)
var err error
a.DB, err = sql.Open("postgres", connectionString)
if err != nil {
log.Fatal(err)
}
defer a.DB.Close()
}
However I'm still getting the error!

I was able to recreate your error with a fresh install of postgres. While the error output was
pq: SSL is not enabled on the server
the real error was not having any databases created. To create a testdb let's run
createdb testdb
in your terminal with postgres already running in the background.

I think the answer comes more just to assign a parameter flag to your Postgres connection string url.
I was connecting to an AWS RDS by URL and I've just change to localhost on 5432 default port.
http://127.0.0.1:5432?sslmode=disable
or
http://localhost:5432?sslmode=disable

I stumbled upon this trying to connect to Postgresql server from my Go program with wrong password.

Related

Can't connect to PostgreSQL database using pgx driver but can using terminal

From code
The code bellow outputs the following:
2022/06/21 16:01:07 Failed to connect to db: failed to connect to 'host=localhost user=postgres database=local': server error (FATAL: Ident authentication failed for user "postgres" (SQLSTATE 28000)) exit status 1
import (
"context"
"log"
"github.com/jackc/pgx/v4"
)
func main() {
dbCtx := context.Background()
db, err := pgx.Connect(
dbCtx,
"postgres://postgres:smashthestate#localhost:5432/local",
)
if err != nil {
log.Fatalf("Failed to connect to db: %v\n", err)
}
defer db.Close(dbCtx)
// do stuff with db...
}
From terminal
However, connection to db is possible from terminal. For example, this command if run with the same parameters (db name, user name, password) will give correct output:
psql -d local -U postgres -W -c 'select * from interest;'
Notes
Command works correctly even if sent by user that is neither root nor postgres.
Authentication method for local connection is set to trust inside pg_hba.conf:
local all all trust
So, what am I missing here? Why everything works fine from the command line but doesn't work from code?
Go's defaults are different from psql's. If no hostname is given, Go defaults to using localhost, while psql defaults to using the Unix domain sockets.
To specify a Unix domain socket to Go, you need to do it oddly to get it to survive URI validation:
postgres://postgres:smashthestate#:5432/local?host=%2Ftmp
Though the end might need to be more like ?host=%2Fvar%2Frun%2Fpostgresql, depending on how the server was configured.
But why are you specifying a password which is not needed? That is going to cause pointless confusion.

Golang PostgreSQL Error: "getaddrinfow: The specified class was not found."

I am having an issue with Go and performing standard operations on my PostgreSQL database.
I first started coding with GORM, and was getting the following error message while connecting:
dial tcp: lookup tcp/fullstack_api: getaddrinfow: The specified class was not found.
After switching to the standard "database/sql" package with the _ "github.com/lib/pq" postgreSQL dialect, connecting was no longer throwing this error. However, now I get this error when trying to perform any query on the connected database, which I assume GORM was doing initially.
The following code causes this error on my system:
// Connect initiates a DB connection.
func (dbConn *PostgresConnection) Connect() error {
handle, connErr := sql.Open("postgres", dbConn.getConnectionString())
if connErr != nil { // Does NOT cause an error
return connErr
}
if pingErr := handle.Ping(); pingErr != nil { // Causes the above error
return pingErr
}
dbConn.handle = handle
return nil
}
I have checked that the PostgreSQL service is running, and the database exists.
While writing this question, I checked my connection string / env variables again.
I realized that I had a stupid copy/paste error from the day before that I hadn't validated:
Connection string: host=127.0.0.1 port=5432 port=new_database user=db_user password=XXXXXX
As you can see, there is an additional port variable that should have been the dbname. After fixing this issue, everything worked as expected.
Connection string: host=127.0.0.1 port=5432 dbname=new_database user=db_user password=XXXXXX
TLDR: Always re-validate every piece of your connection information when getting this (cryptic) error!

Gorm can't connect to local postgres db

I'm new to GoLang and I`ve an issue with connecting my Go webserver with Postgres Database.
Can someone tell me what I'm doing wrong here?
All these credentials are correct btw. User exists, Password is correct, DB exists and belongs to the user.
package app
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
func connectDB(){
db, err := gorm.Open("postgres", "host=localhost port=5432 user=power_user dbname=local_db password=power_user")
if err != nil {
log.Fatal("DB Connection failed")
}
}
If you're sure about psql server is running, try to modify pg_hba.conf, locates at /etc/postgresql/${version}/main/pg_hba.conf usually:
# TYPE DATABASE USER ADDRESS METHOD
local all all trust

How to connect to Google CloudSQL PostgresSQL

I tried to connect to Google CloudSQL PostgresSQL using Gorm golang and seems like it is not working.
Here's the code
func InitDB() *gorm.DB {
psqlInfo := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"))
db, err := gorm.Open("postgres", psqlInfo)
if err != nil {
fmt.Println("Failed to connect to the Database")
}
fmt.Println("Connected to the Database")
DB = db
return DB
}
If im using the localhost config everything works fine. See my .env file for cloudSQL config
DB_HOST=trader-234509:us-central1:testv1
DB_PORT=5432
DB_USER=username
DB_NAME=testv1
DB_PASSWORD=
Error is saying
dial tcp: lookup trader-234509:us-central1:testv1: no such host
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x164681d]
My local config (This one works fine)
DB_HOST=localhost
DB_PORT=5432
DB_USER=username
DB_NAME=test
DB_PASSWORD=
Did i do anything wrong?
Here's roughly how I connect from AppEngine:
import (
_ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/postgres"
"fmt"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func New() (*gorm.DB, error) {
user := "theuser"
password := "apassword"
dbHost := "my-project:the-region:my-db-instance-name"
databaseName := "mydbname"
connString := fmt.Sprintf("host=%s user=%s dbname=%s sslmode=disable password=%s", dbHost, user, databaseName, password)
return gorm.Open(postgres.New(postgres.Config{
DriverName: "cloudsqlpostgres",
DSN: connString,
}))
}
Cloud SQL doesn't support direct connection to instance name for 3rd party application yet, for details: https://cloud.google.com/sql/docs/mysql/connect-external-app
Based on my experience, there are 2 solutions:
As per above instruction, you can setup a Cloud Proxy following the steps and the connections flow would be: Golang app -> Cloud Proxy -> Cloud SQL
This approach is flexible and you're able to control the connection using firewall.
But you have to spend extra $$ to maintain the server and this cloud proxy instance, I've also heard that the cloud proxy may have some performance issues but I don't have exact evidence so far
Assign a Private IP to the Cloud SQL instance, refer to https://cloud.google.com/sql/docs/mysql/private-ip, so that you application can access the DB directly using this IP.
The trade-off is obvious that the app must be in the same network of the project, but this is a much more convenient approach, esp. all your applications are hosted in the same network
I didn't try out the public IP access approach as Cloud Proxy is just what I need if remote network connection is needed
In short, you need to deploy your code in a VM or other Google Managed service using option 2, or setup the cloud proxy to support your local debugging for option 1
Hope it helps

Connecting to a PostgreSQL database through pq returns a "bad connection" error

I am making a web app in Go and PostgreSQL using two different computers. The setup is the same on both computers (Ubuntu with last versions of Go and PostgreSQL). The problem is that I cannot get my app to connect to the database on my laptop.
I use this piece of code:
func (db *Database) Dial(user string, password string, dbname string) {
var err error
db.Conn, err = sql.Open("postgres", "user="+user+" password="+password+" dbname="+dbname+" sslmode=require")
if err != nil {
fmt.Println("Connection to " + dbname + " not possible!")
log.Fatal(err)
}
err = db.Conn.Ping()
if err != nil {
fmt.Println("Ping to " + dbname + " not possible!")
fmt.Println(err)
}
}
And I get:
Ping to my_database not possible!
driver: bad connection
I found many questions on SO with the same error, but I found no solution that would solve my case.
Also, on my laptop, just like on my desktop computer, there is a user postgres and I can connect to the database through psql, so the daemon is active and the password is right. I use the exact same setup and code on both computers.
My question is: how do I get more information about the error? I find "bad connection" to be too vague. I'm sure that a bit more of information would help me a lot.
Also, do you have an idea of would could cause the error?
Update
The PostgreSQL log says this:
2014-09-29 14:23:26 EDT FATAL: password authentication failed for user "postgres"
2014-09-29 14:23:26 EDT DETAIL: Connection matched pg_hba.conf line 92: "host all all 127.0.0.1/32 md5"
But I double checked the password and it shoud be fine. I can also log in as the posgres user, run the psql command and execute queries.
I found a way to fix this.
I log in as postgres and run psql postgres. In other words, I connect to the postgres database. Then I run the command \password and enter a new password.
I entered the exact same password that I have been using since the beginning and somehow now it works.
The problem is solved, but if someone has an idea about what could have been the cause, I'm interested. Maybe it has something to do with password expiration?