🔒 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:

  1. Start GlobalProtect VPN service
  2. Run an SSH tunnel command to forward ports
  3. 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:

  1. Create the tunnel service:

    sudo nano /etc/systemd/system/webui-tunnel.service
    
  2. 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
    
  3. Start and enable the service:

    sudo systemctl daemon-reload
    sudo systemctl start webui-tunnel
    sudo systemctl enable webui-tunnel
    
  4. 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:

  1. Install Nginx:

    sudo apt update
    sudo apt install nginx apache2-utils
    
  2. Create password file:

    sudo htpasswd -c /etc/nginx/.htpasswd <USERNAME>
    
  3. 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! 🔒