Port forwarding is a technique commonly used to access remote services, such as databases or web applications, via SSH. Using Java, you can achieve this by leveraging the JSch (Java Secure Channel) library. Below, you’ll find a step-by-step guide to setting up port forwarding.
1. Understanding Port Forwarding with JSch
Port forwarding allows you to create an SSH tunnel where traffic from a specified local port is forwarded to a specific destination on the remote server. With this setup:
- Local Port: A port on your machine that clients (e.g., a database client) use to connect through the tunnel.
- Remote Host: The machine your SSH server forwards traffic to. When accessing services on the SSH server itself, this is typically
localhost
. - Remote Port: The port of the service running on the remote host (e.g., 3306 for MySQL).
2. Example Code for Local Port Forwarding
Below is an example Java program to set up local port forwarding using JSch:
package org.kodejava.jsch;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class JSchPortForwardingExample {
public static void main(String[] args) {
// SSH connection configuration
String username = "username"; // SSH username
String host = "example.com"; // SSH server address
int sshPort = 22; // SSH server port (default is 22)
String password = "password"; // SSH password
// Port forwarding configuration
int localPort = 9999; // Local port to listen on
String remoteHost = "localhost"; // The remote server (service runs on SSH server itself)
int remotePort = 3306; // Remote port of the service, e.g., MySQL or a web app
try {
// Initialize JSch instance
JSch jsch = new JSch();
// Create and configure the SSH session
Session session = jsch.getSession(username, host, sshPort);
session.setPassword(password);
// Avoid strict key checks for simplicity (not recommended in production)
session.setConfig("StrictHostKeyChecking", "no");
// Connect to the remote server via SSH
System.out.println("Connecting to SSH server...");
session.connect();
System.out.println("SSH connection established.");
// Configure local port forwarding
session.setPortForwardingL(localPort, remoteHost, remotePort);
System.out.printf("Port forwarding established: localhost:%d -> %s:%d%n",
localPort, remoteHost, remotePort);
// Keep the program running to maintain the port forwarding
System.out.println("Press Enter to terminate the program...");
System.in.read(); // Wait for user input to terminate
// Disconnect the SSH session
session.disconnect();
System.out.println("SSH session disconnected.");
} catch (Exception e) {
System.err.println("An error occurred: " + e.getMessage());
e.printStackTrace();
}
}
}
3. Key Points to Understand
3.1 Local Port Forwarding (setPortForwardingL
)
localPort
: Specifies the port on your local machine where applications connect (e.g., a database client).remoteHost
: Specifies the target host to forward traffic to. This often defaults tolocalhost
, meaning traffic is sent to a service running on the same machine as the SSH server.remotePort
: Specifies the port on the remote machine where the service is running.
In the example above:
- Applications on your local machine connect to
localhost:9999
. - Traffic is forwarded through the SSH tunnel to
localhost:3306
on the remote server (example.com
).
3.2 Why Use remoteHost = "localhost"
?
If the service you want to access is on the same server as the SSH connection (e.g., running directly on example.com
), you must use localhost
as the remoteHost
. This tells the SSH server to forward traffic to its own machine’s local interface.
If the desired service is not on the SSH server but on another machine accessible via the SSH server, you can replace localhost
with the hostname or IP address of that machine. For example:
String remoteHost = "192.168.1.100"; // Service is running on another machine
4. Testing the Connection
To confirm that port forwarding is working correctly:
- Start your program and ensure it doesn’t throw any exceptions.
- Use a client (e.g.,
mysql
, a browser, Postman) to connect tolocalhost:9999
(local endpoint). - If configured correctly, the traffic will be securely forwarded to the remote service.
Example for accessing a database:
mysql -h 127.0.0.1 -P 9999 -u your-database-user -p
5. Reverse Port Forwarding (Optional)
If you want to forward traffic from the remote host to your local machine, you can set up “reverse port forwarding” using the setPortForwardingR
method:
session.setPortForwardingR(remotePort, "localhost", localPort);
This is useful when you need to expose a local service (running on your machine) to the remote server.
6. Security Considerations
- Strict Host Key Checking: The example disables this (
StrictHostKeyChecking=no
) for simplicity. In production, you should handle host key verification to ensure secure connections. - Authentication: Use private key-based authentication instead of passwords for better security.
Conclusion
Port forwarding with JSch is a powerful way to connect to remote services securely. With the steps above, you can start forwarding ports for use cases like database client connections or accessing web services running on remote servers.
Maven Dependencies
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>