Last active
July 12, 2024 07:12
-
-
Save acheong08/40032a4da5c77b7b32b94c16ba25c422 to your computer and use it in GitHub Desktop.
Port forwarding utility
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Default protocol is tcp | |
PROTOCOL="tcp" | |
# Use wireguard as default | |
INTERFACE="wg0" | |
# Config file path | |
CONFIG_FILE="${HOME}/.config/portfwd/config" | |
# Usage function to display help | |
usage() { | |
echo "Usage: $0 [--udp|--tcp] [--list|--delete|--refresh] [--interface <network-interface>] --source <source-port> --dest <destination-ip:port>" | |
echo "Example (TCP): $0 --source 80 --dest 172.20.10.2:80" | |
echo "Example (UDP): $0 --udp --source 53 --dest 172.20.10.2:53" | |
echo "Example (Delete): $0 --delete --source 80 --dest 172.20.10.2:80" | |
echo "Example (List): $0 --list" | |
echo "Example (Refresh): $0 --refresh" | |
exit 1 | |
} | |
# Function to list current forwarding rules | |
list_rules() { | |
echo "Current forwarding rules:" | |
iptables -t nat -L PREROUTING --line-numbers -n | |
iptables -L FORWARD --line-numbers -n | |
iptables -t nat -L POSTROUTING --line-numbers -n | |
} | |
# Function to delete a forwarding rule | |
delete_rule() { | |
# Enable IP Forwarding | |
echo 1 > /proc/sys/net/ipv4/ip_forward | |
# Delete PREROUTING rule | |
iptables -t nat -D PREROUTING "${PREROUTING_RULE}" | |
# Delete FORWARD rule | |
iptables -D FORWARD "${FORWARD_RULE}" | |
# Delete POSTROUTING rule | |
iptables -t nat -D POSTROUTING "${POSTROUTING_RULE}" | |
echo "Port forwarding rule deleted from *:${SOURCE_PORT} to ${DEST_IP}:${DEST_PORT} over ${PROTOCOL}" | |
# Remove rule from config file | |
sed -i "/^${PROTOCOL}:${SOURCE_PORT}:${DEST_IP}:${DEST_PORT}$/d" "${CONFIG_FILE}" | |
} | |
# Function to refresh rules from config file | |
refresh_rules() { | |
# Clear existing rules | |
iptables -t nat -F PREROUTING | |
iptables -F FORWARD | |
iptables -t nat -F POSTROUTING | |
# Enable IP Forwarding | |
echo 1 > /proc/sys/net/ipv4/ip_forward | |
# Read rules from config file and apply them | |
while IFS=':' read -r PROTOCOL SOURCE_PORT DEST_IP DEST_PORT; do | |
iptables -t nat -A PREROUTING -p "${PROTOCOL}" --dport "${SOURCE_PORT}" -j DNAT --to-destination "${DEST_IP}:${DEST_PORT}" | |
iptables -A FORWARD -p "${PROTOCOL}" -d "${DEST_IP}" --dport "${DEST_PORT}" -j ACCEPT | |
iptables -t nat -A POSTROUTING -o "${INTERFACE}" -p "${PROTOCOL}" --dport "${DEST_PORT}" -d "${DEST_IP}" -j MASQUERADE | |
echo "Port forwarding rule reloaded from *:${SOURCE_PORT} to ${DEST_IP}:${DEST_PORT} over ${PROTOCOL}" | |
done < "${CONFIG_FILE}" | |
} | |
# Parse arguments | |
while [[ "$#" -gt 0 ]]; do | |
case $1 in | |
--udp) PROTOCOL="udp" ;; | |
--tcp) PROTOCOL="tcp" ;; | |
--list) list_rules; exit 0 ;; | |
--delete) DELETE=true ;; | |
--refresh) refresh_rules; exit 0 ;; | |
--source) SOURCE_PORT="$2"; shift ;; | |
--interface) INTERFACE="$2"; shift ;; | |
--dest) IFS=":" read -r DEST_IP DEST_PORT <<< "$2"; shift ;; | |
*) usage ;; | |
esac | |
shift | |
done | |
# Check if both ports are specified | |
if [ -z "${SOURCE_PORT}" ] || [ -z "${DEST_IP}" ] || [ -z "${DEST_PORT}" ]; then | |
usage | |
fi | |
# Check if delete option is specified | |
if [ "${DELETE}" = true ]; then | |
# Fetch existing rule line numbers | |
PREROUTING_RULE=$(iptables -t nat -L PREROUTING --line-numbers -n | awk "\$4==\"${PROTOCOL}\" && \$5==\"dpt:${SOURCE_PORT}\" && \$9==\"dnat\" && \$10==\"to:${DEST_IP}:${DEST_PORT}\" {print \$1}") | |
FORWARD_RULE=$(iptables -L FORWARD --line-numbers -n | awk "\$4==\"${PROTOCOL}\" && \$5==\"dpt:${DEST_PORT}\" && \$6==\"dst=${DEST_IP}\" {print \$1}") | |
POSTROUTING_RULE=$(iptables -t nat -L POSTROUTING --line-numbers -n | awk "\$4==\"${PROTOCOL}\" && \$5==\"dpt:${DEST_PORT}\" && \$7==\"dst=${DEST_IP}\" {print \$1}") | |
# Check if rules exist | |
if [ -z "${PREROUTING_RULE}" ] || [ -z "${FORWARD_RULE}" ] || [ -z "${POSTROUTING_RULE}" ]; then | |
echo "No forwarding rule found for *:${SOURCE_PORT} to ${DEST_IP}:${DEST_PORT} over ${PROTOCOL}" | |
exit 1 | |
fi | |
delete_rule | |
exit 0 | |
fi | |
# Enable IP Forwarding | |
echo 1 > /proc/sys/net/ipv4/ip_forward | |
# Set up NAT PREROUTING | |
iptables -t nat -A PREROUTING -p "${PROTOCOL}" --dport "${SOURCE_PORT}" -j DNAT --to-destination "${DEST_IP}:${DEST_PORT}" | |
# Set up forwarding rule | |
iptables -A FORWARD -p "${PROTOCOL}" -d "${DEST_IP}" --dport "${DEST_PORT}" -j ACCEPT | |
# Set up NAT POSTROUTING | |
iptables -t nat -A POSTROUTING -o "${INTERFACE}" -p "${PROTOCOL}" --dport "${DEST_PORT}" -d "${DEST_IP}" -j MASQUERADE | |
echo "Port forwarding set up from *:${SOURCE_PORT} to ${DEST_IP}:${DEST_PORT} over ${PROTOCOL}" | |
# Save rule to config file | |
mkdir -p "$(dirname "${CONFIG_FILE}")" | |
echo "${PROTOCOL}:${SOURCE_PORT}:${DEST_IP}:${DEST_PORT}" >> "${CONFIG_FILE}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment