Secure Remote MySQL Access via Nginx Stream Proxy: Step‑by‑Step Guide
This guide explains how to use Nginx’s stream module as a jump‑host to securely proxy MySQL connections, covering module compilation, core directives, configuration examples for single and clustered servers, and IP‑based access restrictions to protect database traffic.
1. Introduction
In many production environments MySQL runs on cloud servers and is not exposed to the public Internet for security reasons. When developers need to connect remotely to diagnose issues, a common solution is to use an Nginx server as a proxy (jump host) to forward MySQL traffic.
2. Setting Up Nginx as a Stream Proxy
You need a server that runs Nginx and resides in the same internal network as the MySQL server. The ngx_stream_core_module is required; it is not built by default and must be enabled during compilation with the --with-stream option.
2.1 Core Directives
The module provides several directives:
stream – defines a stream block at the main level. Syntax: stream { ... } server – defines a virtual host inside a stream block, similar to HTTP server. Syntax: server { ... } listen – specifies the address and port the virtual host listens on. Syntax:
listen address:port; stream {
server {
...
}
} stream {
server {
...
}
server {
...
}
} listen 127.0.0.1:3306;
listen *:3306; # same as above
listen 3306;
listen localhost:3306;2.2 Configuration Examples
Single MySQL instance (port 3306) :
stream {
server {
listen 3306;
proxy_pass 192.168.110.101:3306;
}
}Clustered MySQL (using upstream) :
stream {
upstream mysql_socket {
server 192.168.110.101:3306;
}
server {
listen 3306;
proxy_pass mysql_socket;
}
}Clients such as Navicat can now connect to the MySQL service through the Nginx proxy.
3. Restricting Access by IP
To limit which hosts can use the proxy, enable the ngx_stream_access_module, which provides simple allow and deny directives.
3.1 allow
Grants access to specified IPs or CIDR ranges. Scope: stream, server. Syntax:
allow address | CIDR | unix: | all; # Allow a single IP
allow 192.168.110.1;
# Allow an entire /16 network
allow 192.168.110.0/16;
# Allow all IPs
allow all;3.2 deny
Denies access to specified IPs or CIDR ranges. Scope: stream, server. Syntax:
deny address | CIDR | unix: | all; # Deny a single IP
deny 192.168.110.1;
# Deny a /24 network
deny 192.168.110.0/24;
# Deny all IPs
deny all;Tip: When you use allow , you should also configure a corresponding deny rule; otherwise the configuration will effectively allow all IP addresses.
4. Complete Example
The following configuration permits only 192.168.110.100 to connect to MySQL via Nginx and blocks all other IPs:
stream {
allow 192.168.110.100;
deny all;
server {
listen 3306;
proxy_pass 192.168.110.101:3306;
}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
