1
0
mirror of https://github.com/haiwen/seafile-server.git synced 2025-05-12 02:01:34 +00:00

Add ca_path and skip_verify option for mysql ()

* Add ca_path and skip_verify option for mysql

* Add comment

---------

Co-authored-by: 杨赫然 <heran.yang@seafile.com>
This commit is contained in:
feiniks 2023-04-23 14:39:40 +08:00 committed by GitHub
parent b5993456e3
commit b558426da8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 8 deletions

View File

@ -68,6 +68,8 @@ mysql_db_new (const char *host,
const char *db_name,
const char *unix_socket,
gboolean use_ssl,
gboolean skip_verify,
const char *ca_path,
const char *charset);
static DBConnection *
mysql_db_get_connection (SeafDB *db);
@ -234,12 +236,14 @@ seaf_db_new_mysql (const char *host,
const char *db_name,
const char *unix_socket,
gboolean use_ssl,
gboolean skip_verify,
const char *ca_path,
const char *charset,
int max_connections)
{
SeafDB *db;
db = mysql_db_new (host, port, user, passwd, db_name, unix_socket, use_ssl, charset);
db = mysql_db_new (host, port, user, passwd, db_name, unix_socket, use_ssl, skip_verify, ca_path, charset);
if (!db)
return NULL;
db->type = SEAF_DB_TYPE_MYSQL;
@ -751,6 +755,8 @@ typedef struct MySQLDB {
char *db_name;
char *unix_socket;
gboolean use_ssl;
gboolean skip_verify;
char *ca_path;
char *charset;
} MySQLDB;
@ -775,6 +781,8 @@ mysql_db_new (const char *host,
const char *db_name,
const char *unix_socket,
gboolean use_ssl,
gboolean skip_verify,
const char *ca_path,
const char *charset)
{
MySQLDB *db = g_new0 (MySQLDB, 1);
@ -786,6 +794,8 @@ mysql_db_new (const char *host,
db->db_name = g_strdup(db_name);
db->unix_socket = g_strdup(unix_socket);
db->use_ssl = use_ssl;
db->skip_verify = skip_verify;
db->ca_path = g_strdup(ca_path);
db->charset = g_strdup(charset);
mysql_library_init (0, NULL, NULL);
@ -803,6 +813,7 @@ mysql_db_get_connection (SeafDB *vdb)
int read_write_timeout = 5;
MYSQL *db_conn;
MySQLDBConnection *conn = NULL;
int ssl_mode;
db_conn = mysql_init (NULL);
if (!db_conn) {
@ -810,8 +821,18 @@ mysql_db_get_connection (SeafDB *vdb)
return NULL;
}
if (db->use_ssl)
mysql_ssl_set(db_conn, 0,0,0,0,0);
if (db->use_ssl && !db->skip_verify) {
// Set ssl_mode to SSL_MODE_VERIFY_IDENTITY to verify server cert.
// When ssl_mode is set to SSL_MODE_VERIFY_IDENTITY, MYSQL_OPT_SSL_CA is required to verify server cert.
// Refer to: https://dev.mysql.com/doc/c-api/5.7/en/mysql-options.html
ssl_mode = SSL_MODE_VERIFY_IDENTITY;
mysql_options(db_conn, MYSQL_OPT_SSL_MODE, &ssl_mode);
mysql_options(db_conn, MYSQL_OPT_SSL_CA, db->ca_path);
} else if (db->use_ssl && db->skip_verify) {
// Set ssl_mode to SSL_MODE_PREFERRED to skip verify server cert.
ssl_mode = SSL_MODE_PREFERRED;
mysql_options(db_conn, MYSQL_OPT_SSL_MODE, &ssl_mode);
}
if (db->charset)
mysql_options(db_conn, MYSQL_SET_CHARSET_NAME, db->charset);

View File

@ -25,6 +25,8 @@ seaf_db_new_mysql (const char *host,
const char *db,
const char *unix_socket,
gboolean use_ssl,
gboolean skip_verify,
const char *ca_path,
const char *charset,
int max_connections);

View File

@ -62,6 +62,8 @@ mysql_db_start (SeafileSession *session)
char *host, *user, *passwd, *db, *unix_socket, *charset;
int port;
gboolean use_ssl = FALSE;
gboolean skip_verify = FALSE;
char *ca_path = NULL;
int max_connections = 0;
GError *error = NULL;
@ -100,6 +102,18 @@ mysql_db_start (SeafileSession *session)
use_ssl = g_key_file_get_boolean (session->config,
"database", "use_ssl", NULL);
skip_verify = g_key_file_get_boolean (session->config,
"database", "skip_verify", NULL);
if (use_ssl && !skip_verify) {
ca_path = seaf_key_file_get_string (session->config,
"database", "ca_path", NULL);
if (!ca_path) {
seaf_warning ("ca_path is required if use ssl and don't skip verify.\n");
return -1;
}
}
charset = seaf_key_file_get_string (session->config,
"database", "connection_charset", NULL);
@ -113,7 +127,7 @@ mysql_db_start (SeafileSession *session)
max_connections = DEFAULT_MAX_CONNECTIONS;
}
session->db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, charset, max_connections);
session->db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, skip_verify, ca_path, charset, max_connections);
if (!session->db) {
seaf_warning ("Failed to start mysql db.\n");
return -1;
@ -252,6 +266,8 @@ ccnet_init_mysql_database (SeafileSession *session)
char *host, *user, *passwd, *db, *unix_socket, *charset;
int port;
gboolean use_ssl = FALSE;
gboolean skip_verify = FALSE;
char *ca_path = NULL;
int max_connections = 0;
host = ccnet_key_file_get_string (session->ccnet_config, "Database", "HOST");
@ -286,6 +302,15 @@ ccnet_init_mysql_database (SeafileSession *session)
unix_socket = ccnet_key_file_get_string (session->ccnet_config,
"Database", "UNIX_SOCKET");
use_ssl = g_key_file_get_boolean (session->ccnet_config, "Database", "USE_SSL", NULL);
skip_verify = g_key_file_get_boolean (session->ccnet_config, "Database", "SKIP_VERIFY", NULL);
if (use_ssl && !skip_verify) {
ca_path = seaf_key_file_get_string (session->ccnet_config,
"Database", "CA_PATH", NULL);
if (!ca_path) {
seaf_warning ("ca_path is required if use ssl and don't skip verify.\n");
return -1;
}
}
charset = ccnet_key_file_get_string (session->ccnet_config,
"Database", "CONNECTION_CHARSET");
@ -298,7 +323,7 @@ ccnet_init_mysql_database (SeafileSession *session)
g_clear_error (&error);
}
session->ccnet_db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, charset, max_connections);
session->ccnet_db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, skip_verify, ca_path, charset, max_connections);
if (!session->ccnet_db) {
seaf_warning ("Failed to open ccnet database.\n");
return -1;

View File

@ -2,10 +2,13 @@
package main
import (
"crypto/tls"
"crypto/x509"
"database/sql"
"flag"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/signal"
@ -14,7 +17,7 @@ import (
"strings"
"syscall"
_ "github.com/go-sql-driver/mysql"
"github.com/go-sql-driver/mysql"
"github.com/gorilla/mux"
"github.com/haiwen/seafile-server/fileserver/blockmgr"
"github.com/haiwen/seafile-server/fileserver/commitmgr"
@ -120,8 +123,15 @@ func loadCcnetDB() {
}
var dsn string
if unixSocket == "" {
if skipVerify {
if useTLS && skipVerify {
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify", user, password, host, port, dbName)
} else if useTLS && !skipVerify {
capath := ""
if key, err = section.GetKey("CA_PATH"); err == nil {
capath = key.String()
}
registerCA(capath)
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom", user, password, host, port, dbName)
} else {
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, useTLS)
}
@ -143,6 +153,21 @@ func loadCcnetDB() {
}
}
// registerCA registers CA to verify server cert.
func registerCA(capath string) {
rootCertPool := x509.NewCertPool()
pem, err := ioutil.ReadFile(capath)
if err != nil {
log.Fatal(err)
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
log.Fatal("Failed to append PEM.")
}
mysql.RegisterTLSConfig("custom", &tls.Config{
RootCAs: rootCertPool,
})
}
func loadSeafileDB() {
seafileConfPath := filepath.Join(centralDir, "seafile.conf")
@ -197,8 +222,15 @@ func loadSeafileDB() {
var dsn string
if unixSocket == "" {
if skipVerify {
if useTLS && skipVerify {
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify", user, password, host, port, dbName)
} else if useTLS && !skipVerify {
capath := ""
if key, err = section.GetKey("ca_path"); err == nil {
capath = key.String()
}
registerCA(capath)
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom", user, password, host, port, dbName)
} else {
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, useTLS)
}