🔒 Setting Up Remote Access to OpenWebUI Without VPN
Welcome! In this guide, I’ll show you how to access an internal web service from anywhere without VPN.
Table of Contents
The Challenge
I had an OpenWebUI service running on our internal server that I could only access through VPN. Every time I needed to use it, I had to:
- Start GlobalProtect VPN service
- Run an SSH tunnel command to forward ports
- Access through localhost
This was cumbersome. I wanted a simpler solution that would:
- Work from anywhere without VPN
- Be persistent and auto-restart
- Use proper authentication
- Start automatically after server reboots
Environment Setup
Here’s what we’re working with:
- OpenWebUI service on internal server:
<INTERNAL_IP>:3000
- Jump server accessible from internet:
<JUMP_SERVER_IP>
- My username:
<USERNAME>
Solution 1: Quick SSH Tunnel
Let’s start with the simplest solution. First, set up your SSH config:
# In ~/.ssh/config on your local machine
Host jump-server
HostName <JUMP_SERVER_IP>
User <USERNAME>
Port <JUMP_SSH_PORT>
Host webui-server
HostName <INTERNAL_IP>
User <USERNAME>
Port <INTERNAL_SSH_PORT>
ProxyJump jump-server
Now you can create the tunnel with a single command:
ssh -L 30000:localhost:3000 -J jump-server webui-server -N &
This works! Access OpenWebUI at http://localhost:30000
. But running this manually gets old fast.
Solution 2: Permanent System Service
Let’s make it permanent. On the jump server:
Create the tunnel service:
sudo nano /etc/systemd/system/webui-tunnel.service
Add this configuration:
[Unit] Description=Public SSH tunnel for OpenWebUI After=network.target [Service] ExecStart=/usr/bin/ssh -N -o GatewayPorts=yes -L *:30000:localhost:3000 <USERNAME>@<INTERNAL_IP> -p <INTERNAL_SSH_PORT> Restart=always RestartSec=60 User=<USERNAME> Environment=AUTOSSH_GATETIME=0 TimeoutStartSec=10min [Install] WantedBy=multi-user.target
Start and enable the service:
sudo systemctl daemon-reload sudo systemctl start webui-tunnel sudo systemctl enable webui-tunnel
Verify it’s working:
# Install netstat if needed sudo apt install net-tools # Check if tunnel is listening sudo netstat -tulpn | grep 30000
You should see:
tcp 0 0 0.0.0.0:30000 0.0.0.0:* LISTEN xxxxx/ssh tcp6 0 0 :::30000 :::* LISTEN xxxxx/ssh
Failed Experiment: Nginx Authentication
I tried adding Nginx as an authentication layer, but it didn’t play nice with OpenWebUI’s login system. Here’s what I tried:
Install Nginx:
sudo apt update sudo apt install nginx apache2-utils
Create password file:
sudo htpasswd -c /etc/nginx/.htpasswd <USERNAME>
Configure Nginx:
sudo nano /etc/nginx/sites-available/webui
With this config:
server { listen 30001; server_name <JUMP_SERVER_IP>; location / { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://localhost:30000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
This caused authentication loops, so I removed it:
sudo apt remove nginx nginx-common sudo apt autoremove
The Result
After all this work:
- OpenWebUI is accessible at
http://<JUMP_SERVER_IP>:30000
from anywhere - It uses its built-in authentication
- The tunnel auto-restarts if it fails
- Everything comes back after server reboots
Additional Notes
Some important details:
- No firewall configuration needed (UFW was inactive)
- Service runs under user account
- Internal server still needs proper SSH key setup
- Replace all
<PLACEHOLDERS>
with your actual values!
Future Improvements
Potential enhancements I’m considering:
- Adding HTTPS support
- Implementing rate limiting
- Setting up monitoring and alerts
- Adding IP-based access control
Need Help?
If you’re implementing this:
- Double-check all your IP addresses and ports
- Make sure SSH keys are set up correctly
- Test the tunnel before enabling the service
- Keep your original manual tunnel command handy as backup
License
Feel free to use and modify this setup as needed. Just remember to secure your services properly! 🔒