Last active
May 23, 2022 16:03
-
-
Save caHarkness/f30a064416292b9c686258f856ec5aaa to your computer and use it in GitHub Desktop.
port-forwarding
This file contains 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
use warnings; | |
use strict; | |
use IO::Socket::INET; | |
use IO::Select; | |
my @allowed_ips = ('all', '10.10.10.5'); | |
my $ioset = IO::Select->new; | |
my %socket_map; | |
my $debug = 1; | |
sub new_conn { | |
my ($host, $port) = @_; | |
return IO::Socket::INET->new( | |
PeerAddr => $host, | |
PeerPort => $port | |
) || die "Unable to connect to $host:$port: $!"; | |
} | |
sub new_server { | |
my ($host, $port) = @_; | |
my $server = IO::Socket::INET->new( | |
LocalAddr => $host, | |
LocalPort => $port, | |
ReuseAddr => 1, | |
Listen => 100 | |
) || die "Unable to listen on $host:$port: $!"; | |
} | |
sub new_connection { | |
my $server = shift; | |
my $remote_host = shift; | |
my $remote_port = shift; | |
my $client = $server->accept; | |
my $client_ip = client_ip($client); | |
unless (client_allowed($client)) { | |
print "Connection from $client_ip denied.\n" if $debug; | |
$client->close; | |
return; | |
} | |
print "Connection from $client_ip accepted.\n" if $debug; | |
my $remote = new_conn($remote_host, $remote_port); | |
$ioset->add($client); | |
$ioset->add($remote); | |
$socket_map{$client} = $remote; | |
$socket_map{$remote} = $client; | |
} | |
sub close_connection { | |
my $client = shift; | |
my $client_ip = client_ip($client); | |
my $remote = $socket_map{$client}; | |
$ioset->remove($client); | |
$ioset->remove($remote); | |
delete $socket_map{$client}; | |
delete $socket_map{$remote}; | |
$client->close; | |
$remote->close; | |
print "Connection from $client_ip closed.\n" if $debug; | |
} | |
sub client_ip { | |
my $client = shift; | |
return inet_ntoa($client->sockaddr); | |
} | |
sub client_allowed { | |
my $client = shift; | |
my $client_ip = client_ip($client); | |
return grep { $_ eq $client_ip || $_ eq 'all' } @allowed_ips; | |
} | |
die "Usage: $0 <local port> <remote_host:remote_port>" unless @ARGV == 2; | |
my $local_port = shift; | |
my ($remote_host, $remote_port) = split ':', shift(); | |
print "Starting a server on 0.0.0.0:$local_port\n"; | |
my $server = new_server('0.0.0.0', $local_port); | |
$ioset->add($server); | |
while (1) { | |
for my $socket ($ioset->can_read) { | |
if ($socket == $server) { | |
new_connection($server, $remote_host, $remote_port); | |
} | |
else { | |
next unless exists $socket_map{$socket}; | |
my $remote = $socket_map{$socket}; | |
my $buffer; | |
my $read = $socket->sysread($buffer, 4096); | |
if ($read) { | |
$remote->syswrite($buffer); | |
} | |
else { | |
close_connection($socket); | |
} | |
} | |
} | |
} |
This file contains 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/sh | |
### BEGIN INIT INFO | |
# Provides: port-forwarding | |
# Required-Start: $local_fs $network $named $time $syslog | |
# Required-Stop: $local_fs $network $named $time $syslog | |
# Default-Start: 2 3 4 5 | |
# Default-Stop: 0 1 6 | |
# Description: Simple TCP port forwarding in Debian | |
### END INIT INFO | |
# | |
# To install this, run as root: | |
# export SERVICE_NAME="port-forwarding"; curl "https://gist.githubusercontent.com/caHarkness/f30a064416292b9c686258f856ec5aaa/raw/port-forwarding" > /etc/init.d/$SERVICE_NAME; chmod +x /etc/init.d/$SERVICE_NAME; ln -s /etc/init.d/$SERVICE_NAME /etc/rc2.d/S99$SERVICE_NAME; nano /etc/init.d/$SERVICE_NAME; sleep 3; systemctl daemon-reload | |
# | |
WORKING_DIRECTORY="/opt/port-forwarding" | |
forward_port () { | |
LISTEN_PORT="$1" | |
DESTINATION="$2" | |
PERL_SCRIPT=$(curl -k "https://gist.githubusercontent.com/caHarkness/f30a064416292b9c686258f856ec5aaa/raw/forward.pl") | |
perl -e "$PERL_SCRIPT" "$LISTEN_PORT" "$DESTINATION" & | |
PERL_PROCESS="$!" | |
touch $WORKING_DIRECTORY/pids/$PERL_PROCESS | |
echo $DESTINATION > $WORKING_DIRECTORY/ports/$LISTEN_PORT | |
} | |
start_forwarding () { | |
mkdir $WORKING_DIRECTORY | |
mkdir $WORKING_DIRECTORY/pids | |
mkdir $WORKING_DIRECTORY/ports | |
forward_port 54303 192.168.1.10:54303 | |
} | |
list_forwarded_ports () { | |
for i in "$WORKING_DIRECTORY/ports/"* | |
do | |
PORT=$(basename $i) | |
DEST=$(< $i) | |
echo "$PORT $DEST" | |
done | |
} | |
stop_forwarding () { | |
for i in "$WORKING_DIRECTORY/pids/"* | |
do | |
KPID=$(basename $i) | |
kill $KPID | |
done | |
for i in "$WORKING_DIRECTORY/ports/"* | |
do | |
rm "$i" | |
done | |
} | |
edit_service () { | |
SERVICE_NAME=$(basename $0) | |
nano /etc/init.d/$SERVICE_NAME | |
sleep 3 | |
systemctl daemon-reload | |
} | |
uninstall_service () { | |
SERVICE_NAME=$(basename $0) | |
rm /etc/init.d/$SERVICE_NAME | |
rm /etc/rc2.d/S99$SERVICE_NAME | |
echo "Service uninstalled." | |
} | |
PATH=/sbin:/usr/sbin:/bin:/usr/bin | |
. /lib/lsb/init-functions | |
case "$1" in | |
start) | |
start_forwarding | |
;; | |
stop) | |
stop_forwarding | |
;; | |
restart) | |
stop_forwarding | |
sleep 3 | |
start_forwarding | |
;; | |
list) | |
list_forwarded_ports | |
;; | |
edit) | |
edit_service | |
;; | |
uninstall) | |
uninstall_service | |
;; | |
*) | |
echo "Usage: $0 {start|stop|restart|list|edit|uninstall}" | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment