Skip to content

Instantly share code, notes, and snippets.

@ankushKun
Created February 6, 2026 06:29
Show Gist options
  • Select an option

  • Save ankushKun/e0234e9f948296e9a8f11b5b0df396b6 to your computer and use it in GitHub Desktop.

Select an option

Save ankushKun/e0234e9f948296e9a8f11b5b0df396b6 to your computer and use it in GitHub Desktop.
Auto Fortinet Firewall Login for College WiFi
#!/bin/bash
# ============================================
# Firewall Auto-Login Script
# ============================================
# Automatically logs into the campus firewall
# when internet connectivity is lost.
#
# Usage:
# 1. Fill in your credentials below
# 2. chmod +x firewall-login.sh
# 3. ./firewall-login.sh
# ============================================
# --- Configuration ---
USERNAME="YOUR_STUDENT_ID"
PASSWORD="YOUR_PASWORD"
FIREWALL_URL="http://172.16.2.1:1000"
CHECK_URL="http://detectportal.firefox.com/canonical.html"
CHECK_INTERVAL=30 # seconds between connectivity checks
KEEPALIVE_INTERVAL=300 # seconds between keepalive pings (5 min)
LAST_KEEPALIVE=0
KEEPALIVE_URL=""
# --- Colors ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log() {
echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
check_internet() {
# The firewall allows ping/DNS through but blocks HTTP until authenticated.
# So we must check actual HTTP access. We fetch a known URL and check if
# the response contains the firewall login page (fgtauth) or not.
RESPONSE_BODY=$(curl -s --max-time 5 "http://www.gstatic.com/generate_204" -w "%{http_code}" -o /tmp/fw_check.txt 2>/dev/null)
HTTP_CODE="$RESPONSE_BODY"
BODY=$(cat /tmp/fw_check.txt 2>/dev/null)
# generate_204 returns HTTP 204 with empty body when internet works.
# If firewall intercepts, it returns 200/302 with the login page HTML.
if [ "$HTTP_CODE" = "204" ]; then
return 0 # internet is working
fi
# Also check: if body contains firewall/fgtauth, definitely not logged in
if echo "$BODY" | grep -q "fgtauth\|Firewall Authentication\|magic"; then
return 1 # firewall login page intercepted
fi
# If we got 200 with empty or non-firewall body, could be working
if [ "$HTTP_CODE" = "200" ] && [ -z "$BODY" ]; then
return 0
fi
return 1
}
do_login() {
log "${YELLOW}Internet not available. Attempting firewall login...${NC}"
# Step 1: Fetch the login page to get the current 'magic' token.
# The firewall redirects HTTP requests to http://172.16.2.1:1000/fgtauth?<id>
# We need to follow that redirect to get the actual login page with the magic token.
# First, try hitting CHECK_URL and follow redirects to land on the firewall page
LOGIN_PAGE=$(curl -s -L --max-time 10 "$CHECK_URL" 2>/dev/null)
EFFECTIVE_URL=$(curl -s -o /dev/null -w "%{url_effective}" -L --max-time 10 "$CHECK_URL" 2>/dev/null)
log "Redirected to: ${EFFECTIVE_URL}"
# If that didn't return a page with a magic token, the firewall might use
# a non-HTTP redirect (like HTML meta refresh or JS). Try to extract the
# redirect URL from the response body instead.
if ! echo "$LOGIN_PAGE" | grep -q 'name="magic"'; then
# Check if the response contains a redirect URL to the firewall
REDIRECT_URL=$(echo "$LOGIN_PAGE" | grep -o 'http://172\.16\.[0-9.]*:1000/fgtauth?[^"'"'"' <]*' | head -1)
if [ -n "$REDIRECT_URL" ]; then
log "Found firewall redirect URL: ${REDIRECT_URL}"
LOGIN_PAGE=$(curl -s --max-time 10 "$REDIRECT_URL" 2>/dev/null)
EFFECTIVE_URL="$REDIRECT_URL"
else
# Last resort: try any HTTP URL on the firewall host
LOGIN_PAGE=$(curl -s -L --max-time 10 "http://172.16.2.1:1000/" 2>/dev/null)
EFFECTIVE_URL="http://172.16.2.1:1000/"
fi
fi
if [ -z "$LOGIN_PAGE" ]; then
log "${RED}Could not reach the firewall login page.${NC}"
return 1
fi
# If the page doesn't contain a magic token at this point,
# we might already be logged in or got an unexpected page
if ! echo "$LOGIN_PAGE" | grep -q 'name="magic"'; then
log "${YELLOW}No login form found. Might already be authenticated. Waiting for next cycle.${NC}"
return 1
fi
# Step 2: Extract the magic token and redirect URL
MAGIC=$(echo "$LOGIN_PAGE" | grep -o 'name="magic" value="[^"]*"' | grep -o 'value="[^"]*"' | cut -d'"' -f2)
REDIR=$(echo "$LOGIN_PAGE" | grep -o 'name="4Tredir" value="[^"]*"' | grep -o 'value="[^"]*"' | cut -d'"' -f2)
if [ -z "$MAGIC" ]; then
log "${RED}Could not extract magic token. Dumping page for debugging:${NC}"
echo "$LOGIN_PAGE" | head -30
return 1
fi
log "Extracted magic token: ${MAGIC}"
# Step 3: Determine the POST URL
# The form action is "/" which is relative to the firewall host
FIREWALL_BASE=$(echo "$EFFECTIVE_URL" | grep -o 'http://[^/]*')
if [ -z "$FIREWALL_BASE" ]; then
FIREWALL_BASE="$FIREWALL_URL"
fi
POST_URL="${FIREWALL_BASE}/"
log "Posting login to: ${POST_URL}"
# Step 4: Submit the login form
RESPONSE=$(curl -s -L --max-time 10 \
-d "4Tredir=${REDIR}" \
-d "magic=${MAGIC}" \
-d "username=${USERNAME}" \
-d "password=${PASSWORD}" \
"$POST_URL" 2>/dev/null)
# Step 5: Check if login succeeded
# After successful login, the firewall returns a keepalive page with a JS redirect.
# Extract the keepalive URL so we can ping it to keep the session alive.
KEEPALIVE_URL=$(echo "$RESPONSE" | grep -o 'http://172\.16\.[0-9.]*:1000/keepalive?[^"'"'"' <]*' | head -1)
if [ -n "$KEEPALIVE_URL" ]; then
log "${GREEN}Login successful! Keepalive URL: ${KEEPALIVE_URL}${NC}"
LAST_KEEPALIVE=$(date +%s)
# Give the firewall a moment to activate the session
sleep 3
# Verify internet actually works now
if check_internet; then
log "${GREEN}Internet is now available.${NC}"
else
log "${YELLOW}Keepalive received but internet check not passing yet. Will retry on next cycle.${NC}"
fi
return 0
else
# No keepalive URL found - check if maybe internet works anyway
sleep 2
if check_internet; then
log "${GREEN}Login successful! Internet is now available.${NC}"
return 0
fi
log "${RED}Login attempt failed. Check your credentials.${NC}"
echo "$RESPONSE" | head -20
return 1
fi
}
# --- Main Loop ---
log "${GREEN}Firewall auto-login script started.${NC}"
log "Checking connectivity every ${CHECK_INTERVAL} seconds..."
if [ "$USERNAME" = "YOUR_STUDENT_ID" ] || [ "$PASSWORD" = "YOUR_PASSWORD" ]; then
log "${RED}ERROR: Please edit this script and set your USERNAME and PASSWORD.${NC}"
exit 1
fi
ping_keepalive() {
if [ -n "$KEEPALIVE_URL" ]; then
NOW=$(date +%s)
ELAPSED=$(( NOW - LAST_KEEPALIVE ))
if [ "$ELAPSED" -ge "$KEEPALIVE_INTERVAL" ]; then
curl -s --max-time 5 "$KEEPALIVE_URL" > /dev/null 2>&1
LAST_KEEPALIVE=$NOW
log "Pinged keepalive to maintain session."
fi
fi
}
while true; do
if check_internet; then
log "${GREEN}Internet is working.${NC}"
ping_keepalive
else
do_login
fi
sleep "$CHECK_INTERVAL"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment