Reputation: 7506
In my Spring Boot
app WAR, I have an application.properties
file wherein I have defined following datasource
properties:
spring.datasource.url=jdbc:mysql://localhost/test?autoReconnect=true&useSSL=false&rewriteBatchedStatements=true
spring.datasource.username=used
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
with this, I am able to connect to the database.
Now, I want to connect to another database through SSH tunnel
. How should I specify spring.datasource.url
to get such connection?
Please note I don't want to write any boiler plate Java code to do this SSH tunneling!
P.S. I Googled but could not find satisfactory answer anywhere.
Upvotes: 7
Views: 20055
Reputation: 251
I try this dependency and config. Is is worked
<dependency>
<groupId>com.hierynomus</groupId>
<artifactId>sshj</artifactId>
<version>0.30.0</version>
</dependency>
import com.hierynomus.sshj.SSHClient;
import com.hierynomus.sshj.connection.ConnectionException;
import com.hierynomus.sshj.connection.channel.direct.Session;
import com.hierynomus.sshj.transport.TransportException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.SQLException;
@Configuration
public class DatabaseConfig {
@Bean
public SSHClient sshClient() throws IOException {
SSHClient sshClient = new SSHClient();
sshClient.addHostKeyVerifier((hostname, port, key) -> true); // Skip host key verification (for demonstration only)
sshClient.connect("your-ssh-server-hostname");
sshClient.authPassword("ssh-username", "ssh-password");
return sshClient;
}
@Bean
public DataSource dataSource(SSHClient sshClient) throws IOException, TransportException, ConnectionException, SQLException {
int localPort = 3306; // Local port to tunnel through
sshClient.setPortForwardingL(localPort, "database-hostname", 3306); // Tunnel MySQL's port 3306
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:" + localPort + "/your-database-name");
dataSource.setUsername("database-username");
dataSource.setPassword("database-password");
return dataSource;
}
}
Upvotes: 1
Reputation: 3926
same problem with me.
my solution resolved,
Step 1: create ec2 instance inside VPC public subnet
Step 2: in the security groups this ec2 instance must be allow port 22 (SSH)
Step 3: RDS MySQL must be allow private-ip for ec2 instance to access
Step 4: In Dev Local ~> setup forward listener tcp_ip open terminal
ssh -f <user>@<ec2-public-dns> -L <localhost_ip>:<localhost_port>:<rds_mysql_host_ip>:<rds_mysql_host_port> -N -i <private_key>.pem
Example:
ssh -f ec2-user@ec2-public-dns -L dev-mysql-c-lib.internal:3306:***.ap-southeast-1.rds.amazonaws.com:3306 -N -i ~/.ssh/ec2-instance.pem
Step 5: in file config application-dev.yml
changed host from public-dns to internal-dns
Example:
host: '***.ap-southeast-1.rds.amazonaws.com'
to
host: 'dev-mysql-c-lib.internal'
spring.datasource.url: jdbc:mysql://dev-mysql-c-lib.internal:3306/mydb
Finally to Running Spring Boot
Lookup MySQL Connected
Work for me. ^____^
Upvotes: 6
Reputation: 1289
I don't think spring can create a SSH tunnel for you if that's what you're looking for. If you want to do it in the code, you need a framework like jsch.
The best solution would be to create the SSH tunnel on the server manually or by using autossh (to keep it up). To create a tunnel manually, log on to your app server and run this command in a screen:
ssh -L 3307:localhost:3306 serverIp
3306 is the port mysql is running on. 3307 is the port you are forwarding. With this tunnel you can now connect by using:
spring.datasource.url=jdbc:mysql://localhost:3307/
Upvotes: 14
Reputation: 185
The same as you used in your question except useSSL=true and possibly verifyServerCertificate=false if your database uses self-signed certificate.
Upvotes: -3