DEV Community

바람의평온
바람의평온

Posted on

Secure Remote MySQL with DBeaver: SSH Tunneling Without Opening Port 3306

Secure Remote MySQL with DBeaver: SSH Tunneling Without Opening Port 3306

I almost forgot again. I was working with a MySQL database on a remote server and wanted to easily view the data using DBeaver on my MacBook. Checking via CLI every time I connect to the server gets tedious after a while; a GUI tool is much more convenient. But I almost made a big mistake by trying to do it the easy way. The simplest method is to open port 3306 on the server firewall for my specific IP, but this always carries the risk of accidentally opening it to 0.0.0.0. Even if I restrict it to a specific IP, it increases the management overhead, which made me uneasy. I had a scary experience in the past where MySQL was exposed externally. So, I pondered, 'How can I connect and use it safely?' and remembered the method of using an SSH tunnel.

Target Audience: Solo developers or small team developers who want to access a remote database with a GUI tool but are reluctant to expose port 3306 due to security concerns.Difficulty: Intermediate

Key Takeaways

How to connect to a remote MySQL database without exposing port 3306 externally.The process of connecting to a remote DB using SSH tunnel settings in DBeaver.How to keep MySQL server's bind-address setting secure.Security benefits and working principles of SSH tunnel connections.How to verify that the remote DB connection is securely configured.### Remote DB Connection: Balancing Convenience and Security
After initially installing MySQL on a remote server, I was eager to connect to it directly from DBeaver on my MacBook. When developing, it's common to visually inspect data structures or run simple queries. But I paused for a moment. 'Ah, do I have to open port 3306 again?' I thought. The simplest way is to open 3306 on the server firewall for my IP, but this method always feels insecure. I worry about accidentally opening it to all IPs. I actually had a terrifying experience in a previous project where the MySQL port was completely exposed to the internet, even showing its banner. I broke out in a cold sweat then. So this time, I was determined not to repeat the same mistake. I needed to find a way to connect conveniently yet securely.

Why Not Directly Open Port 3306 and Finding Alternatives

For a MySQL database client to connect to a DB on a remote server, a network path is naturally required. However, the moment port 3306 is directly opened to the internet, that port becomes exposed to all attack attempts worldwide. My server's MySQL configuration was initially set with bind-address to 127.0.0.1. This setting means the MySQL server only allows connections from itself (localhost), which is very secure. The problem, however, was that an external client like DBeaver couldn't connect directly. To satisfy both 'MySQL only allows local connections' and 'DBeaver remote access' simultaneously, the only option was to route DB traffic through an already open and securely protected channel. My secure channel was SSH.

Configuring a Secure DBeaver Connection Using an SSH Tunnel

The solution was to use an SSH tunnel. The SSH port (default 22) is already a securely protected channel with SSH key authentication, so this method routes 3306 traffic through that channel. It was fortunate that DBeaver's connection settings included this feature. The MySQL server configuration remained with bind-address set to 127.0.0.1. This is because traffic coming through the tunnel appears to the server as if it originated from localhost. The concept for setting up the connection in DBeaver was as follows: # Server: MySQL is local only # /etc/mysql/mysql.conf.d/mysqld.cnf bind-address = 127.0.0.1 With this setting, MySQL still only accepts local connections. In DBeaver's settings, you enter Host as 127.0.0.1 and Port as 3306 in the General tab, then enable the SSH tab to specify the server's actual IP, SSH port, and the key file for authentication. DBeaver will first connect to the server via SSH, then send the 3306 request through that encrypted tunnel. # DBeaver Connection Settings (Concept) # General : Host=127.0.0.1 Port=3306 (localhost from the server's perspective) # SSH : Check Use SSH Tunnel / Host=ServerIP / Port=SSHPort / Auth=KeyFile As a result, port 3306 is never directly exposed to the internet.

Thoroughly Verifying Secure Connection

After configuration, connecting from DBeaver with the SSH tunnel enabled successfully accessed the DB. Just in case, I tried connecting directly to the server IP and port 3306 with the SSH tunnel setting disabled in DBeaver, and as expected, the connection was refused. This alone was reassuring. To further confirm there was no external exposure, I tried connecting to the server's 3306 port from another PC using the telnet command. # External Exposure Check (from another PC) telnet ServerIP 3306 # Should be refused If this command results in a connection refusal, it's proof of no external exposure. Finally, I checked which address MySQL was listening on from the server itself. # Server Listen Address Check sudo ss -tlnp | grep 3306 # Should be 127.0.0.1:3306 The result was indeed 127.0.0.1:3306. This conclusively verified that it is not exposed externally at all and is only accessible via the SSH tunnel. Local applications running on the same server (e.g., a Next.js backend) were already connecting to MySQL via 127.0.0.1, so this configuration change had no impact on them.

Conclusion

By utilizing an SSH tunnel, I was able to conveniently access a remote MySQL database with a GUI tool while maintaining strong security. I realized once again that the thought of 'opening a port for convenience' is often the beginning of the most common security incidents. When there's already a secure SSH channel protected by keys, why take the risk of separately opening the DB port to the internet? An SSH tunnel reuses an existing secure channel instead of opening a new port, making it a smart way to achieve both convenience and security. I hope this helps others who, like me, tend to forget these things from time to time.

Top comments (0)