Skip to content

Instantly share code, notes, and snippets.

@FlorianHeigl
Last active June 7, 2025 16:07
Show Gist options
  • Save FlorianHeigl/d127ec26266f3d4fd95193f432fbc1ae to your computer and use it in GitHub Desktop.
Save FlorianHeigl/d127ec26266f3d4fd95193f432fbc1ae to your computer and use it in GitHub Desktop.
bavarian wifi
# dont execute hook if dhcp req failed
if [ $1 != 0 ]; then
return 0
fi
# get bayernwlan interface name
interface=$( ifconfig | grep -B1 "BAYERNWLAN" | grep -v description: | awk -F: '{print $1}' )
# some validation might be [a-z]+[0-9]
# get bayernwlan interface address
ip=$( ifconfig vtnet2 | grep -w inet | awk '{print $2}' )
# some validation might be a classic ip address regex
# make sure the resulting vars are passed on
export ip interface
# trigger api request
/usr/local/bin/by.py
#!/usr/bin/python3
# Logs into BayernWLAN automatically
# Created on Alpine Linux - I'll make a prod grade version for use on pfSense clusters.
# Likely this is also a nice workaround for OSX clients where the login button is broken all the time.
# Source: https://github.com/asdil12/wifi_autologin/blob/master/wifi_autologin/networks/bayernwlan.py
# Source: https://gist.githubusercontent.com/alexhorn/f1a7f32430e79f835b7dbc180b9ee727/raw/584ba5b79ffc20b9674cabcaded9c9f33c733193/login.py
# Extended to bind to the correct nic ip address when POST'ing to the captive portal
import os
import requests
from requests_toolbelt.adapters import source
ip = os.environ.get('ip')
interface = os.environ.get('interface')
print("will bind to ip %s of %s and try to login to bayernwlan" % (ip, interface))
# per $1 reingeben und als linkup script nehmen
source = source.SourceAddressAdapter(ip)
with requests.Session() as session:
session.mount('https://', source)
sid = session.get('https://hotspot.vodafone.de/api/v4/session').json()['session']
r = session.post('https://hotspot.vodafone.de/api/v4/login?sessionID=%s&action=redirect&portal=bayern' % sid, data={
'loginProfile': '6',
'accessType': 'termsOnly',
'session': sid})
if r.ok:
print("got positive confirmation from portal")
else:
print(r.text)
#!/usr/bin/env bash
# do we need to create a hardlink to post-renew also?
if [[ ${interface} = "wlan0" ]]; then
/usr/local/bin/by.py ${ip}
fi
/etc/udhcpc # ./post-renew
will bind to ip 100.xx.xx.xx of wlan0 and try to login to bayernwlan
got positive confirmation from portal
@FlorianHeigl
Copy link
Author

FlorianHeigl commented Jun 7, 2025

OSX

tested on OSX now, you can use this whenever the "Verbinden" ('connect') button on the captive portal isn't working.
(and that's an ever that's also a given, blocking a little canal of it's own...)

You'll just need your wifi device name, and if you know how to do the wifi connect from cli you could fully automate it.

sanitized history / commands

python setup crap

$  cd bayernwlan
$  python3 -m venv .venv
$  . .venv/bin/activate
$  pip3 install requests
$  pip3 install requests_toolbelt

connection

Ok, now connect to the WiFi via the GUI icon
Then you need the ip address they assigned to you:

$ ifconfig en0 < checked my assigned ip address

use that info and setup env for script, and call script


$  export ip=100.xxxxxxx
$  export interface=en0
$  ./by.py 

result / example

(.venv) [utopia.bayernwlan]% ./by.py               
will bind to ip 100.xxxxx of en0 and try to login to bayernwlan
got positive confirmation from portal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment