PawsBrake
PawsBrake

Reputation: 21

Creating internet function in django webapp

I have been tinkering around with Django for about a year now and I have created a little webapp that I can put in a VPC or remote server, currently the vpn uses a full tunnel, not split. So the users have to use the internet and dns provided through the VPC. Currently the webapp has login, auth, sessions via django-redis, file transfer, chat and dm (functions like iMessage), and in admin all of the permissions for these are setup and handled. The one function I'm having a hard time with is:

  1. User requires permissions for external internet access (http/https)
  2. If user has permissions, internet access doesn't enable until user also clicks the 'Internet' button to activate it.

I had come up with this for the django bit:

@login_required
@permission_required('accounts.proxy_access', raise_exception=True)
def proxy(request):
    try:
        # Get the remote IP address of the incoming request
        remote_ip = request.META['REMOTE_ADDR']
        
        # Add iptables rule to allow traffic from the remote IP
        subprocess.run(['iptables', '-A', 'OUTPUT', '-d', remote_ip, '-j', 'ACCEPT'])
        
        messages.success(request, 'Proxy connected. You may now open a new tab and browse the web normally.')
    except:
        messages.error(request, 'Proxy failed. Please contact your administrator.')

    return redirect('home')

can get the incoming IP from the request metadata. Then set a iptables rule that would allow the incoming IP to be routed anywhere instead of just the app. Nginix will then take the requests and reverse proxy them onto the FW and then internet?

I'm not sure. But I don't like the concept of iptables or firewall settings being modified by the app.

Solution #2 was to use something like Traefik with the ForwardAuth forwarding auth requests to an endpoint in the django app.

Like so:

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.http import JsonResponse
from .models import InternetAccess
from .forms import InternetAccessForm

@login_required
def internet_access_view(request):
    user_access, created = InternetAccess.objects.get_or_create(user=request.user)
    if request.method == 'POST':
        form = InternetAccessForm(request.POST)
        if form.is_valid() and user_access.has_permission:
            user_access.has_clicked_button = form.cleaned_data['access_internet']
            user_access.save()
            return redirect('some-success-url')
    else:
        form = InternetAccessForm()
    return render(request, 'internet_access.html', {'form': form})

def forward_auth_view(request):
    # Extract user information from the request (e.g., a token or session ID)
    user = get_user_from_request(request)
    if user:
        user_access, created = InternetAccess.objects.get_or_create(user=user)
        if user_access.has_permission and user_access.has_clicked_button:
            return JsonResponse({'auth': 'success'})
    return JsonResponse({'auth': 'failure'}, status=403)

But I'm unsure if this is any better due to it still being effectively an app modifying the reverse proxy. Any insight into how you would/should do this would be helpful, thank you.

Upvotes: 2

Views: 31

Answers (0)

Related Questions