Azure VM proxy tunnel - bcgov/common-service-showcase GitHub Wiki
Setting Up NGINX as a Proxy for Private Azure Services
This guide details how to set up NGINX on an Azure VM to act as a proxy for accessing private Azure services like Azure AI Search and Azure OpenAI, which might be accessible only through private endpoints.
1. Install and Configure NGINX on the VM
1.1 Install NGINX
# Install NGINX using package manager (for RHEL/CentOS/AlmaLinux)
sudo dnf install nginx
# Start NGINX service
sudo systemctl start nginx
# Enable NGINX to start on boot
sudo systemctl enable nginx
1.2 Create SSL Certificates (Recommended)
Generate self-signed SSL certificates for secure communication:
# Create directories for certificates
sudo mkdir -p /etc/ssl/private
sudo mkdir -p /etc/ssl/certs
# Generate self-signed certificate (valid for 365 days)
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/ssl/private/selfsigned.key \
-out /etc/ssl/certs/selfsigned.crt
When prompted, provide your organization details. For a development environment, default values are acceptable.
2. Create NGINX Configuration
2.1 Create Proxy Configuration File
Create a new configuration file in the NGINX configuration directory:
sudo nano /etc/nginx/conf.d/azure_proxy.conf
2.2 Configure NGINX as a Proxy for Multiple Private DNS Endpoints
For each Azure private DNS endpoint you need to access, you'll need a separate location block in your NGINX configuration:
Add the following configuration (modify as needed for your environment):
server {
listen 443 ssl;
server_name localhost;
# You'll need to generate or provide SSL certificates
# Replace these paths with your actual certificate files
ssl_certificate /etc/ssl/certs/selfsigned.crt;
ssl_certificate_key /etc/ssl/private/selfsigned.key;
location / {
proxy_pass https://css-ai-dev-aisearch.search.windows.net:443;
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
}
location /openai/ {
proxy_pass https://css-ai-dev-openai-east.openai.azure.com:443;
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
}
access_log /var/log/nginx/azure_search_access.log;
error_log /var/log/nginx/azure_search_error.log;
}
2.3 Enable SELinux Network Connections
If you encounter connection errors on RHEL-based systems (RHEL, CentOS, AlmaLinux), you'll need to configure SELinux to allow NGINX to make outbound connections:
# Solution: Enable outbound connections for web servers
sudo setsebool -P httpd_can_network_connect on
This is required because SELinux blocks web servers from making outbound network connections by default, which prevents NGINX from functioning as a proxy.
2.4 Test and Apply Configuration
# Test NGINX configuration for syntax errors
sudo nginx -t
# If the test is successful, reload NGINX to apply changes
sudo systemctl reload nginx
3. Testing the Proxy
3.1 Test from the VM
Test Azure AI Search through the proxy:
curl -vk "https://localhost/indexes/first_pdf_index3/docs/search?api-version=2023-07-01-Preview" \
-H "Host: css-ai-dev-aisearch.search.windows.net" \
-H "Content-Type: application/json" \
-H "api-key: YOUR_SEARCH_API_KEY" \
-d '{"search": "water", "top": 5}'
Test Azure OpenAI through the proxy:
curl -vk "https://localhost/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview" \
-H "Host: css-ai-dev-openai-east.openai.azure.com" \
-H "Content-Type: application/json" \
-H "api-key: YOUR_OPENAI_API_KEY" \
-d '{"messages": [{"role": "user", "content": "Hello, who are you?"}], "max_tokens": 50}'
3.2 Test from Your Local Machine
Set Up Port Forwarding via SSH Tunnel
First, create an SSH tunnel from your local machine to the VM as specified in azure_vm_proxy_tunnel.md.
To access multiple Azure private DNS endpoints from your local machine, you'll need to set up separate SSH tunnels for each service
Each tunnel creates a local port that forwards requests to the specified Azure service through the VM.
Test Local Access
Test Azure AI Search through the local tunnel:
curl -vk "https://localhost:8083/indexes/first_pdf_index3/docs/search?api-version=2023-07-01-Preview" \
-H "Host: css-ai-dev-aisearch.search.windows.net" \
-H "Content-Type: application/json" \
-H "api-key: YOUR_SEARCH_API_KEY" \
-d '{"search": "water", "top": 5}'
Test Azure OpenAI through the local tunnel:
curl -vk "https://localhost:8083/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview" \
-H "Host: css-ai-dev-openai-east.openai.azure.com" \
-H "Content-Type: application/json" \
-H "api-key: YOUR_OPENAI_API_KEY" \
-d '{"messages": [{"role": "user", "content": "Hello, who are you?"}], "max_tokens": 50}'
4. Security Considerations
- API Keys: Store API keys securely. Consider using Azure Key Vault for production environments.
- SSL/TLS: For production, use proper CA-signed certificates instead of self-signed ones.
- Access Control: Restrict access to the VM and proxy using Network Security Groups (NSGs).
- Logging: Enable NGINX access and error logs for monitoring and troubleshooting.
# Configure more detailed logging
sudo nano /etc/nginx/nginx.conf
# Add to the http section:
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$host" "$upstream_addr"';
access_log /var/log/nginx/access.log detailed;
error_log /var/log/nginx/error.log warn;
5. Troubleshooting
5.1 Common Issues
-
Connection Refused Errors:
- SELinux Restrictions: The most common cause on RHEL-based systems is SELinux blocking outbound connections
# Solution: Enable outbound connections for web servers sudo setsebool -P httpd_can_network_connect on
- Firewall Rules: Check if the firewall is blocking connections
# Check firewall status sudo firewall-cmd --state # Allow HTTP/HTTPS traffic sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload
-
DNS Resolution Issues:
- Check if the VM can resolve Azure service hostnames
nslookup css-ai-dev-aisearch.search.windows.net ping css-ai-dev-aisearch.search.windows.net
-
SSL Handshake Failures:
- Verify SSL configurations and certificates
-
General Troubleshooting Steps:
- Check NGINX error logs:
sudo tail -f /var/log/nginx/error.log
- Test connectivity to Azure services directly from the VM
- Verify the VM's network configuration and NSG rules
- Check NGINX error logs: