I am not of the field of information security so sorry if something I wrote below seems pathetic to you.

I am to defend my server's DB and for that I filtered port 3306 with CSF-LFD and now control my DB only internally through port 80, mainly via PHPmyadmin (PMA) for 2 hours each time (I made PMA to be installed and deleted automatically after 2 hours by a script).

These 2 actions (locking the port and using temporary PMAs) are considered quite safe, but there is one last thing I want to do to ensure extra protection:

I've been told I could make every port-80 based data transition between my PC and my VPS, to be encrypted.

I thought of doing this with a tunnel via OpenSSH so at first I tried a command similar to the following, with my user, ip and private key. The execution brought me into my VPS and I could operate it just fine but there was no encryption for actions I did from my web browser:

ssh user@ -L 22:localhost:22 -L 80:localhost:80 -i ~/.ssh/user_private_key 

Because the command seemingly didn't answer my need I turned to the hosting company and a support adviser told me it's obvious because I already use OpenSSH to login to my VPS itself and any extra encryption I do with it is always only session (CLI) based rather than GUI based hence won't effect data transition done from the browser (I must say it sounds illogical to me - If we tunnel a course between one port to another, like 80 to 80, then everything going through it whether from CLI or GUI should be encrypted).

I learned I could use the SOCKS proxy instead. Is SOCKS really the only way possible way for me to achieve this encryption. Can't I really use OpenSSH?


Update for Xiong Chaimov:

Xiong asked me in the comments below:

What lead you to the conclusion that actions you took were not encrypted?

Two things led me to believe that there was no tunneling between the two edges of port 80:

.1. Command error (as is):

bind: Address already in use
channel_setup_fwd_listener: cannot listen to port: 22
bind: Address already in use

.2. Netstat I/O:

netstat -n --protocol inet | grep ':22':

tcp        0     ESTABLISHED


netstat -n --protocol inet | grep ':80'

No output...
  • What lead you to the conclusion that actions you took were not encrypted? – Xiong Chiamiov Dec 28 '16 at 7:54
  • Updated the question with such main data. – user123574 Dec 28 '16 at 8:08
  • The error on #1 suggests to me that you have something that binds on port 22 of your local machine. This could happen if you have sshd on your local machine, or if you have multiple ssh local port forwarding the same port. It's also very strange to port forward port 22, what do you intend to achieve by local forwarding port 22? – Lie Ryan Dec 28 '16 at 14:58

Since it's SSH port forwarding, it should be encrypted. There's also a solution in which you don't use the underlying webserver or phpmyadmin, to simply forward the mysql port, such as -L 3306:localhost:3306 and connect to the database using a client such as MySQL workbench (or most IDEs have similar integrated anyways).

| improve this answer | |
  • This is certainly the standard way to do it. You can then turn off any access to 3306 except from localhost on the server. You should, of course, be blocking all unused ports anyway. – Julian Knight Dec 28 '16 at 10:55

For proper encryption you may as well just use HTTPS (it's also more proper), but for a solution like yours you'd tunnel a localhost port to your OpenSSH server and connect via the SOCKS proxy settings as described in this DigitalOcean article.

| improve this answer | |
  • The important point being that SOCKS is client-side, it provides a slightly more general-purpose interface into the SSH VPN that you are creating. – Julian Knight Dec 28 '16 at 10:56

Generally, you should configure your database server to listen for database connection on a Unix domain socket or to listen only on localhost. MySQL shouldn't be configured to listen on external IP address, or worst, to listen on all addresses, unless the regular user of the database (usually a web application) is not running on the same machine. And if the application is remote, there are a number of things you need to consider.

The way you do this, is to set bind-address config to the loopback address ( If you do this, then nobody can connect to MySQL remotely, unless they already have a connection to the server (e.g. SSH) and make a "local" connection from there. In this case, you'll be relying on SSH to do encryption and authentication, and the OS to not route remote packets coming to the loopback address to your application. Additionally, you can configure MySQL to require password/authentication, to restrict local, unprivileged users from connecting to the database. Note that you cannot restrict privileged users (root and someone with unrestrained physical access). Additionally, you can configure a host firewall (i.e. iptable in Linux) to further limit open ports on the system.

You can do remote administration by using SSH local forwarding. You'll configure Workbench to connect to your local machine's local port, and SSH will forward that connection to the MySQL port on the server.

Another way to do remote administration is to configure PHPMyAdmin to listen on a public HTTPS port. In this configuration, you'll be relying on PHPMyAdmin to do authentication and HTTPS for encryption. Note that using PHPMyAdmin via unencrypted HTTP is insecure, you must use HTTPS, also PHPMyAdmin, while convenient, exposes a large attack surface as it's a complex PHP application. For example, it may be vulnerable to CSRF or XSS.

You can further secure PHPMyAdmin by configuring your webserver (e.g. Apache) to require a "TLS client certificate" to access the PHPMyAdmin application. In this configuration, you'll be relying on Apache for authentication and HTTPS for encryption. You should use this in conjunction with PHPMyAdmin's own authentication mechanism.

If your application isn't running on the same machine as your database (common in databases with large number of users or which is shared by multiple applications), you can let MySQL to bind on a privileged network's IP Address. In this security model, anyone that are connected to the privileged network and is allowed by the network admin to send IP packets to the database server is considered trusted. In this case, you'll depend on the server's network administrator. Unless you're experienced with networking and trusts whoever configured the network admin and their firewall configuration, I wouldn't recommend this. Remote administration, in this case, would be done by connecting to the privileged network using a VPN. There need to be a network firewall that prevents connections from outside the privileged network from being routed to the database server. In this configuration, authentication is done by the VPN server, and by the routers enforcing the LAN routing table.

Additionally, you can configure MySQL to require a TLS client certificate. With this configuration, the MySQL server is also doing authentication. This can be used if you don't fully trust the network administrator or if you don't trust all users in the network that's allowed to connect to the database machine.

Finally, you can expose MySQL to bind to a public IP Address. I do not recommend this, as MySQL is not an application designed to be exposed on a public port (even though MySQL can require TLS client certificate). Apache, sshd, and VPN gateway, on the other hand, are designed so they can be configured to be exposed in a public address securely.

Unless you know you need it, I'd recommend against configuring MySQL to listen on non loopback address. And there's no good reason to deliberately expose a database server on a public IP address for any length of time. This can only be considered misconfiguration or incompetence.

You shouldn't need SOCKS (OpenSSH Dynamic forwarding). SOCKS is only useful if you have large number of target machines and you don't want to configure what local port goes where. In this case, you have a specific target machine, which is your database server on the database port, so you only need to forward that port.

| improve this answer | |

You don't need socks, indeed it is an added complication you really don't want now. Port forwarding over ssh provides encryption regardless of the client.

The command you are using with ssh doesn't make any sense. With this model of tunneling you tell ssh to listen on a local port and forward ghe connection to a remote system. SSH cannot listen onaport which is already in use. You need to spend a lot more time learning the basics and less time on byzantine schemes like temporary pma installations.

The folowing (run from your PC) will make the dbms available at on pirt 3307 (note that mysql clients usually assume that connections to 'localhost' should use a filesystem socket)

ssh -L 3307:localhost:3306 $yourvps

However giving the remote system an ip address you can connect to (and define network rules around) is a lot more flexible- personally I'd go for a sshbased vpn like this

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy