Issue access django via vpn

Hello,
Im kinda stumped on why I cant access my django applicaiton served by apache through my openVPN setup.

My end goal is to be able to turn on my vpn on a mobile device and access the django server through a local network connection.

I have tested the vpn with apache to show just a simple html file as a test.

/var/www.test.com

and enable a virtual host like so

<VirtualHost 10.124.0.2:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/test.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ServerName 10.124.0.2
ServerAlias 10.124.0.2

This setup worked, while the vpn was on I would insert the IP into my browser and the test webpage appears.

I then created a virtual host for my django project.

<VirtualHost 10.124.0.2:80>
ServerAdmin webmaster@localhost
ServerName 10.124.0.2
ServerAlias 10.124.0.2

WSGIDaemonProcess classicoutdoor processes=2 threads=12 python-path=/var/www/webapp/work_management:/var/www/webapp/myprojectenv/lib/python3.12/site-packages
WSGIProcessGroup classicoutdoor
WSGIScriptAlias / /var/www/webapp/work_management/work_management/wsgi.py

# This alias makes serving media files possible.

Alias /media/ /var/www/webapp/media/
<Directory /var/www/webapp/media>
Require all granted

Alias /static/ /var/www/webapp/work_management/staticfiles/

<Directory /var/www/webapp/work_management/work_management>
<Files wsgi.py>
Require all granted
</Files>
</Directory>



    LogLevel warn

# PROJECT_NAME is used to seperate the log files of this application
ErrorLog    ${APACHE_LOG_DIR}/classicoutdoor_error.log
CustomLog   ${APACHE_LOG_DIR}/classicoutdoor_access.log combined

When I attempt to connect the connection times out. The url does seem to be sending me to my login page it just never gets there.

If I change the virtual host to the public IP and add it to my settings.py file everything works as it should, just not through the local network over the vpn.

My biggest confusion is that Apache worked when using a simple html doc, when I add WSGIDaemonProcess,WSGIProcessGroup and WSGIScriptAlias to run the dynamic django site over the vpn, it seems to break it somehow.

Any idea on what Im doing wrong here?

Thanks for the help!

Have you verified that your application works in Apache without the VPN involved?

What (if anything) do you have in the Apache access and error logs? Are you seeing the requests being made?

Is your Apache server one endpoint of the VPN, or does your VPN terminate on a different system?

You’re showing two different VirtualHost entries for the same host/port combination. Are you sure that only one is active while you’re trying to do this?

Have you verified that your application works in Apache without the VPN involved?

  • Yes I ran the set-up on the public IP and I was able to access the application.

What (if anything) do you have in the Apache access and error logs? Are you seeing the requests being made?

  • access log
    `

10.8.0.2 - - [08/Feb/2025:00:47:34 +0000] “GET / HTTP/1.1” 302 385 “-” “Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36”

10.8.0.2 - - [08/Feb/2025:00:47:35 +0000] “GET /members/login_user?next=/ HTTP/1.1” 200 2528 “-” “Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36”
`

  • Error log does not show anything

Is your Apache server one endpoint of the VPN, or does your VPN terminate on a different system?

  • Apache and openVPN are running on the same server

You’re showing two different VirtualHost entries for the same host/port combination. Are you sure that only one is active while you’re trying to do this?

  • Yes currently looking at my /etc/apache2/sites-enabled and only my classic-outdoor.conf is listed

Please confirm that these requests are coming from your test with the VPN, because:

This says that it works. You requested the /members/login_user page and the server returned a valid reponse containing 2528 bytes of data.

That’s right the 10.8.0.2 is the ip of my client on the VPN. However the page never loads on the device

I guess the next thing I’d check is whether Apache is actually returning this response. I’d use tcpdump to capture the traffic to/from the server to verify that there is a valid response being returned from Apache, to determine if it is a Django, Apache, or network configuration issue.

Ok, so I ran it on my tun0 interface which is where the vpn is at and here is the results I get.

root@ubuntu-s-1vcpu-512mb-10gb-sfo3-01:~# tcpdump -i tun0 
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
01:20:49.960137 IP 10.8.0.2.55504 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [F.], seq 1422434156, ack 89523296, win 274, options [nop,nop,TS val 466681282 ecr 4108475211,nop,nop,sack 1 {1389:2524}], length 0
01:20:49.960182 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.55504: Flags [.], ack 1, win 1004, options [nop,nop,TS val 4108499228 ecr 466681282], length 0
01:20:49.970285 IP 10.8.0.2.39294 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [S], seq 2545247222, win 65535, options [mss 1400,sackOK,TS val 466681291 ecr 0,nop,wscale 8], length 0
01:20:49.970345 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [S.], seq 3149441740, ack 2545247223, win 65160, options [mss 1460,sackOK,TS val 4108499238 ecr 466681291,nop,wscale 6], length 0
01:20:50.040138 IP 10.8.0.2.39294 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [.], ack 1, win 256, options [nop,nop,TS val 466681363 ecr 4108499238], length 0
01:20:50.045243 IP 10.8.0.2.39294 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [P.], seq 1:460, ack 1, win 256, options [nop,nop,TS val 466681363 ecr 4108499238], length 459: HTTP: GET / HTTP/1.1
01:20:50.045296 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], ack 460, win 1011, options [nop,nop,TS val 4108499313 ecr 466681363], length 0
01:20:50.048775 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [P.], seq 1:386, ack 460, win 1011, options [nop,nop,TS val 4108499317 ecr 466681363], length 385: HTTP: HTTP/1.1 302 Found
01:20:50.115123 IP 10.8.0.2.39294 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [.], ack 386, win 261, options [nop,nop,TS val 466681441 ecr 4108499317], length 0
01:20:50.125117 IP 10.8.0.2.39294 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [P.], seq 460:944, ack 386, win 261, options [nop,nop,TS val 466681446 ecr 4108499317], length 484: HTTP: GET /members/login_user?next=/ HTTP/1.1
01:20:50.131324 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108499399 ecr 466681446], length 1388: HTTP: HTTP/1.1 200 OK
01:20:50.131339 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [P.], seq 1774:2891, ack 944, win 1004, options [nop,nop,TS val 4108499399 ecr 466681446], length 1117: HTTP
01:20:50.131898 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [P.], seq 2891:2911, ack 944, win 1004, options [nop,nop,TS val 4108499400 ecr 466681446], length 20: HTTP
01:20:50.205071 IP 10.8.0.2.39294 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [.], ack 386, win 269, options [nop,nop,TS val 466681529 ecr 4108499317,nop,nop,sack 1 {1774:2891}], length 0
01:20:50.205114 IP 10.8.0.2.39294 > ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http: Flags [.], ack 386, win 274, options [nop,nop,TS val 466681529 ecr 4108499317,nop,nop,sack 1 {1774:2911}], length 0
01:20:50.223734 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108499492 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:20:50.500752 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108499769 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:20:51.100747 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108500369 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:20:52.252748 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108501521 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:20:54.492757 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108503761 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:20:59.231784 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108508500 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:21:00.764749 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.55504: Flags [.], seq 1:1389, ack 1, win 1004, options [nop,nop,TS val 4108510033 ecr 466681282], length 1388: HTTP: HTTP/1.1 200 OK
01:21:08.444760 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108517713 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:21:26.364768 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.39294: Flags [.], seq 386:1774, ack 944, win 1004, options [nop,nop,TS val 4108535633 ecr 466681529], length 1388: HTTP: HTTP/1.1 200 OK
01:21:37.116774 IP ubuntu-s-1vcpu-512mb-10gb-sfo3-01.http > 10.8.0.2.55504: Flags [.], seq 1:1389, ack 1, win 1004, options [nop,nop,TS val 4108546385 ecr 466681282], length 1388: HTTP: HTTP/1.1 200 OK

Not sure the best way to share that, Im trying to pick through it now to see if anything stands out.

When you’re sharing a block of preformatted text such as code (or log records like this), surround the block between lines of three backticks instead of one. You can also highlight the block and click on the “preformatted text” icon in the editor. It’s the </> icon. (I’ve taken the liberty of modifying your post.)

So yes, the server is sending the response, in fact it’s getting retried multiple times, but it’s not getting acknowledged by the client.

Note that these are all 200 codes being returned with a length of 1388, which is the size of the original response packet.

My gut reaction to this is that this is likely an MTU-related issue with the VPN, but I have no knowledge of OpenVPN, so that’s really just a WAG.

Ok, figured out my issue. When I was troubleshooting I removed my {% extends “index.html” %} from my login page and it rendered the webpage.

Looking at my index template I noticed I had stylesheets and scripts that need internet access. So I asked the brilliant question. Do I have internet access on this interface? After a ping to google the answer was NO.

Solution for ubuntu
/etc/default/ufw

DEFAULT_FORWARD_POLICY="ACCEPT"

/etc/ufw/sysctl.conf

net.ipv4.ip_forward=1 

/etc/ufw/before.rules

# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
# Allow traffic from local network to eth0 (change to the interface you discovered!)
-A POSTROUTING -s 10.124.0.0/20 -o eth0 -j MASQUERADE
COMMIT

Also Ken you were right on the MTU issues as well. When I would try to access the vpn with my cell network the webpage would time out again, but if I went through standard internet through wifi it would work.

Im using openvpn. To fix this I just added these lines to the bottom of my client .opvn file

# to fix cell network connection issues
tun-mtu 1380;
mssfix 1340;