Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
ha
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
ha
Commits
0295dd2d
Commit
0295dd2d
authored
Jun 30, 2025
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new file
parent
847ab59a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1667 additions
and
0 deletions
+1667
-0
rat.sh
rat.sh
+1667
-0
No files found.
rat.sh
0 → 100644
View file @
0295dd2d
#!/bin/bash
# Check if the script is run as root
if
[[
$EUID
-ne
0
]]
;
then
echo
"This script must be run as root"
sleep
1
exit
1
fi
# just press key to continue
press_key
(){
read
-p
"Press any key to continue..."
}
# Define a function to colorize text
colorize
()
{
local
color
=
"
$1
"
local
text
=
"
$2
"
local
style
=
"
${
3
:-
normal
}
"
# Define ANSI color codes
local
black
=
"
\0
33[30m"
local
red
=
"
\0
33[31m"
local
green
=
"
\0
33[32m"
local
yellow
=
"
\0
33[33m"
local
blue
=
"
\0
33[34m"
local
magenta
=
"
\0
33[35m"
local
cyan
=
"
\0
33[36m"
local
white
=
"
\0
33[37m"
local
reset
=
"
\0
33[0m"
# Define ANSI style codes
local
normal
=
"
\0
33[0m"
local
bold
=
"
\0
33[1m"
local
underline
=
"
\0
33[4m"
# Select color code
local
color_code
case
$color
in
black
)
color_code
=
$black
;;
red
)
color_code
=
$red
;;
green
)
color_code
=
$green
;;
yellow
)
color_code
=
$yellow
;;
blue
)
color_code
=
$blue
;;
magenta
)
color_code
=
$magenta
;;
cyan
)
color_code
=
$cyan
;;
white
)
color_code
=
$white
;;
*
)
color_code
=
$reset
;;
# Default case, no color
esac
# Select style code
local
style_code
case
$style
in
bold
)
style_code
=
$bold
;;
underline
)
style_code
=
$underline
;;
normal
|
*
)
style_code
=
$normal
;;
# Default case, normal text
esac
# Print the colored and styled text
echo
-e
"
${
style_code
}${
color_code
}${
text
}${
reset
}
"
}
# Function to install unzip if not already installed
install_unzip
()
{
if
!
command
-v
unzip &> /dev/null
;
then
# Check if the system is using apt package manager
if
command
-v
apt-get &> /dev/null
;
then
echo
-e
"
${
RED
}
unzip is not installed. Installing...
${
NC
}
"
sleep
1
sudo
apt-get update
sudo
apt-get
install
-y
unzip
else
echo
-e
"
${
RED
}
Error: Unsupported package manager. Please install unzip manually.
${
NC
}
\n
"
press_key
exit
1
fi
fi
}
# Install unzip
install_unzip
#Function to install cron if not already installed
install_cron
()
{
if
!
command
-v
cron &> /dev/null
;
then
# Check if the system is using apt package manager
if
command
-v
apt-get &> /dev/null
;
then
echo
-e
"
${
RED
}
cron is not installed. Installing...
${
NC
}
"
sleep
1
sudo
apt-get update
sudo
apt-get
install
-y
cron
else
echo
-e
"
${
RED
}
Error: Unsupported package manager. Please install cron manually.
${
NC
}
\n
"
press_key
exit
1
fi
fi
}
# Install cron
install_cron
# Function to install jq if not already installed
install_jq
()
{
if
!
command
-v
jq &> /dev/null
;
then
# Check if the system is using apt package manager
if
command
-v
apt-get &> /dev/null
;
then
echo
-e
"
${
RED
}
jq is not installed. Installing...
${
NC
}
"
sleep
1
sudo
apt-get update
sudo
apt-get
install
-y
jq
else
echo
-e
"
${
RED
}
Error: Unsupported package manager. Please install jq manually.
${
NC
}
\n
"
press_key
exit
1
fi
fi
}
# Install jq
install_jq
config_dir
=
"/root/rathole-core"
# Function to download and extract Rathole Core
download_and_extract_rathole
()
{
# check if core installed already
if
[[
-f
"
${
config_dir
}
/rathole"
]]
;
then
if
[[
"
$1
"
==
"sleep"
]]
;
then
echo
colorize green
"Rathole Core is already installed."
bold
sleep
1
fi
return
1
fi
# Define the entry to check/add
ENTRY
=
"185.199.108.133 raw.githubusercontent.com"
# Check if the github entry exists in /etc/hosts
if
!
grep
-q
"
$ENTRY
"
/etc/hosts
;
then
echo
"Github Entry not found. Adding to /etc/hosts..."
echo
"
$ENTRY
"
>>
/etc/hosts
else
echo
"Github entry already exists in /etc/hosts."
fi
# Check operating system
if
[[
$(
uname
)
==
"Linux"
]]
;
then
ARCH
=
$(
uname
-m
)
DOWNLOAD_URL
=
$(
curl
-sSL
https://api.github.com/repos/rapiz1/rathole/releases/latest |
grep
-o
"https://.*
$ARCH
.*linux.*zip"
|
head
-n
1
)
else
echo
-e
"
${
RED
}
Unsupported operating system.
${
NC
}
"
sleep
1
exit
1
fi
if
[[
"
$ARCH
"
==
"x86_64"
]]
;
then
DOWNLOAD_URL
=
'https://github.com/Musixal/rathole-tunnel/raw/main/core/rathole.zip'
fi
if
[
-z
"
$DOWNLOAD_URL
"
]
;
then
echo
-e
"
${
RED
}
Failed to retrieve download URL.
${
NC
}
"
sleep
1
exit
1
fi
DOWNLOAD_DIR
=
$(
mktemp
-d
)
echo
-e
"Downloading Rathole from
$DOWNLOAD_URL
...
\n
"
sleep
1
curl
-sSL
-o
"
$DOWNLOAD_DIR
/rathole.zip"
"
$DOWNLOAD_URL
"
echo
-e
"Extracting Rathole...
\n
"
sleep
1
unzip
-q
"
$DOWNLOAD_DIR
/rathole.zip"
-d
"
$config_dir
"
echo
-e
"
${
GREEN
}
Rathole installation completed.
${
NC
}
\n
"
chmod
u+x
${
config_dir
}
/rathole
rm
-rf
"
$DOWNLOAD_DIR
"
}
#Download and extract the Rathole core
download_and_extract_rathole
# Get server IP
#SERVER_IP=$(hostname -I | awk '{print $1}')
# Fetch server country
SERVER_COUNTRY
=
$(
curl
--max-time
3
-sS
"http://ipwhois.app/json/
$SERVER_IP
"
| jq
-r
'.country'
)
# Fetch server isp
SERVER_ISP
=
$(
curl
--max-time
3
-sS
"http://ipwhois.app/json/
$SERVER_IP
"
| jq
-r
'.isp'
)
# Function to display ASCII logo
# Function to display ASCII logo
display_logo
()
{
echo
-e
"
${
CYAN
}
"
cat
<<
"EOF"
__ .__ .__
____________ _/ |_| |__ ____ | | ____
\_
__
\_
_
\\
__| |
\
/ _
\|
| _/ __
\
| |
\/
/ __
\|
| | Y
(
<_> | |_
\
___/
|__|
(
____ |__| |___| /
\_
___/|____/
\_
__
>
\/
\/
\/
EOF
echo
-e
"
${
NC
}${
GREEN
}
"
echo
-e
"Version:
${
YELLOW
}
v2.0
${
GREEN
}
"
echo
-e
"Github:
${
YELLOW
}
github.com/Musixal/Rathole-Tunnel
${
GREEN
}
"
echo
-e
"Telegram Channel:
${
YELLOW
}
@Gozar_Xray
${
NC
}
"
}
# Function to display server location and IP
display_server_info
()
{
echo
-e
"
\e
[93m═════════════════════════════════════════════
\e
[0m"
# Hidden for security issues
#echo -e "${CYAN}IP Address:${NC} $SERVER_IP"
echo
-e
"
${
CYAN
}
Location:
${
NC
}
$SERVER_COUNTRY
"
echo
-e
"
${
CYAN
}
Datacenter:
${
NC
}
$SERVER_ISP
"
}
# Function to display Rathole Core installation status
display_rathole_core_status
()
{
if
[[
-f
"
${
config_dir
}
/rathole"
]]
;
then
echo
-e
"
${
CYAN
}
Rathole Core:
${
NC
}
${
GREEN
}
Installed
${
NC
}
"
else
echo
-e
"
${
CYAN
}
Rathole Core:
${
NC
}
${
RED
}
Not installed
${
NC
}
"
fi
echo
-e
"
\e
[93m═════════════════════════════════════════════
\e
[0m"
}
# Function to check if a given string is a valid IPv6 address
check_ipv6
()
{
local
ip
=
$1
# Define the IPv6 regex pattern
ipv6_pattern
=
"^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)
$|
^(([0-9a-fA-F]{1,4}:){1,7}|:):((:[0-9a-fA-F]{1,4}){1,7}|:)$"
# Remove brackets if present
ip
=
"
${
ip
#[
}
"
ip
=
"
${
ip
%]
}
"
if
[[
$ip
=
~
$ipv6_pattern
]]
;
then
return
0
# Valid IPv6 address
else
return
1
# Invalid IPv6 address
fi
}
check_port
()
{
local
PORT
=
$1
local
TRANSPORT
=
$2
if
[
-z
"
$PORT
"
]
;
then
echo
"Usage: check_port <port> <transport>"
return
1
fi
if
[[
"
$TRANSPORT
"
==
"tcp"
]]
;
then
if
ss
-tlnp
"sport = :
$PORT
"
|
grep
"
$PORT
"
>
/dev/null
;
then
return
0
else
return
1
fi
elif
[[
"
$TRANSPORT
"
==
"udp"
]]
;
then
if
ss
-ulnp
"sport = :
$PORT
"
|
grep
"
$PORT
"
>
/dev/null
;
then
return
0
else
return
1
fi
else
return
1
fi
}
# Function for configuring tunnel
configure_tunnel
()
{
# check if the rathole-core installed or not
if
[[
!
-d
"
$config_dir
"
]]
;
then
echo
-e
"
\n
${
RED
}
Rathole-core directory not found. Install it first through 'Install Rathole core' option.
${
NC
}
\n
"
read
-p
"Press Enter to continue..."
return
1
fi
clear
colorize green
"Essential tips:"
bold
colorize yellow
" Enable TCP_NODELAY to improve the latency but decrease the bandwidth.
For the high number of connections, I recommend turning off the Heartbeat option"
echo
colorize green
"1) Configure for IRAN server"
bold
colorize magenta
"2) Configure for KHAREJ server"
bold
echo
read
-p
"Enter your choice: "
configure_choice
case
"
$configure_choice
"
in
1
)
iran_server_configuration
;;
2
)
kharej_server_configuration
;;
*
)
echo
-e
"
${
RED
}
Invalid option!
${
NC
}
"
&&
sleep
1
;;
esac
echo
read
-p
"Press Enter to continue..."
}
#Global Variables
service_dir
=
"/etc/systemd/system"
# Function to configure Iran server
iran_server_configuration
()
{
clear
colorize cyan
"Configuring IRAN server"
bold
echo
#Add IPv6 Support
local_ip
=
'0.0.0.0'
read
-p
"[-] Listen for IPv6 address? (y/n): "
answer
if
[
"
$answer
"
=
"y"
]
||
[
"
$answer
"
=
"Y"
]
;
then
colorize yellow
"IPv6 Enabled"
local_ip
=
'[::]'
elif
[
"
$answer
"
=
"n"
]
;
then
colorize yellow
"IPv4 Enabled"
local_ip
=
'0.0.0.0'
else
colorize yellow
"Invalid choice. IPv4 enabled by default."
local_ip
=
'0.0.0.0'
fi
echo
while
true
;
do
echo
-ne
"[*] Tunnel port: "
read
-r
tunnel_port
if
[[
"
$tunnel_port
"
=
~ ^[0-9]+
$
]]
&&
[
"
$tunnel_port
"
-gt
22
]
&&
[
"
$tunnel_port
"
-le
65535
]
;
then
if
check_port
"
$tunnel_port
"
"tcp"
;
then
colorize red
"Port
$tunnel_port
is in use."
else
break
fi
else
colorize red
"Please enter a valid port number between 23 and 65535"
fi
done
echo
# Initialize nodelay variable
local
nodelay
=
""
# Keep prompting the user until a valid input is provided
while
[[
"
$nodelay
"
!=
"true"
&&
"
$nodelay
"
!=
"false"
]]
;
do
echo
-ne
"[*] Enable TCP_NODELAY (true/false): "
read
-r
nodelay
if
[[
"
$nodelay
"
!=
"true"
&&
"
$nodelay
"
!=
"false"
]]
;
then
colorize red
"Invalid TCP_NODELAY value. Please enter 'true' or 'false'"
fi
done
echo
# Initialize HEARTBEAT variable
local
HEARTBEAT
=
""
# Keep prompting the user until a valid input is provided
while
[[
"
$HEARTBEAT
"
!=
"true"
&&
"
$HEARTBEAT
"
!=
"false"
]]
;
do
echo
-ne
"[*] Enable HEARTBEAT (true/false): "
read
-r
HEARTBEAT
if
[[
"
$HEARTBEAT
"
!=
"true"
&&
"
$HEARTBEAT
"
!=
"false"
]]
;
then
colorize red
"Invalid HEARTBEAT value. Please enter 'true' or 'false'"
fi
done
if
[[
"
$HEARTBEAT
"
==
"true"
]]
;
then
HEARTBEAT
=
"30"
else
HEARTBEAT
=
"0"
fi
echo
# Initialize transport variable
local
transport
=
""
# Keep prompting the user until a valid input is provided
while
[[
"
$transport
"
!=
"tcp"
&&
"
$transport
"
!=
"udp"
]]
;
do
# Prompt the user to input transport type
echo
-ne
"[*] Transport type(tcp/udp): "
read
-r
transport
# Check if the input is either tcp or udp
if
[[
"
$transport
"
!=
"tcp"
&&
"
$transport
"
!=
"udp"
]]
;
then
colorize red
"Invalid transport type. Please enter 'tcp' or 'udp'"
fi
done
echo
echo
-ne
"[-] Security Token (press enter to use default value): "
read
-r
token
if
[[
-z
"
$token
"
]]
;
then
token
=
"musixal"
fi
echo
# Prompt for Ports
echo
-ne
"[*] Enter your ports separated by commas (e.g. 2070,2080): "
read
-r
input_ports
input_ports
=
$(
echo
"
$input_ports
"
|
tr
-d
' '
)
# Convert the input into an array, splitting by comma
IFS
=
','
read
-r
-a
ports
<<<
"
$input_ports
"
declare
-a
config_ports
# Iterate through each port and perform an action
for
port
in
"
${
ports
[@]
}
"
;
do
if
[[
"
$port
"
=
~ ^[0-9]+
$
]]
&&
[
"
$port
"
-gt
22
]
&&
[
"
$port
"
-le
65535
]
;
then
if
check_port
"
$port
"
"
$transport
"
;
then
colorize red
"[ERROR] Port
$port
is in use."
else
colorize green
"[INFO] Port
$port
added to your configs"
config_ports+
=(
"
$port
"
)
fi
else
colorize red
"[ERROR] Port
$port
is Invalid. Please enter a valid port number between 23 and 65535"
fi
done
if
[
${#
config_ports
[@]
}
-eq
0
]
;
then
colorize red
"No ports were entered. Exiting."
bold
sleep
2
return
1
fi
# Generate server configuration file
cat
<<
EOF
> "
${
config_dir
}
/iran
${
tunnel_port
}
.toml"
[server]
bind_addr = "
${
local_ip
}
:
${
tunnel_port
}
"
default_token = "
$token
"
heartbeat_interval =
$HEARTBEAT
[server.transport]
type = "tcp"
[server.transport.tcp]
nodelay =
$nodelay
EOF
# Add each config port to the configuration file
for
port
in
"
${
config_ports
[@]
}
"
;
do
cat
<<
EOF
>> "
${
config_dir
}
/iran
${
tunnel_port
}
.toml"
[server.services.
${
port
}
]
type = "
$transport
"
bind_addr = "
${
local_ip
}
:
${
port
}
"
EOF
done
echo
# Create the systemd service unit file
cat
<<
EOF
> "
${
service_dir
}
/rathole-iran
${
tunnel_port
}
.service"
[Unit]
Description=Rathole Iran Port
$tunnel_port
(Iran)
After=network.target
[Service]
Type=simple
ExecStart=
${
config_dir
}
/rathole
${
config_dir
}
/iran
${
tunnel_port
}
.toml
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd to read the new unit file
systemctl daemon-reload
>
/dev/null 2>&1
# Enable and start the service to start on boot
if
systemctl
enable
--now
"
${
service_dir
}
/rathole-iran
${
tunnel_port
}
.service"
>
/dev/null 2>&1
;
then
colorize green
"Iran service with port
$tunnel_port
enabled to start on boot and started."
else
colorize red
"Failed to enable service with port
$tunnel_port
. Please check your system configuration."
return
1
fi
echo
colorize green
"IRAN server configuration completed successfully."
}
#Function for configuring Kharej server
kharej_server_configuration
()
{
clear
colorize cyan
"Configuring kharej server"
bold
echo
# Prompt for IRAN server IP address
while
true
;
do
echo
-ne
"[*] IRAN server IP address [IPv4/IPv6]: "
read
-r
SERVER_ADDR
if
[[
-n
"
$SERVER_ADDR
"
]]
;
then
break
else
colorize red
"Server address cannot be empty. Please enter a valid address."
echo
fi
done
echo
# Read the tunnel port
while
true
;
do
echo
-ne
"[*] Tunnel port: "
read
-r
tunnel_port
if
[[
"
$tunnel_port
"
=
~ ^[0-9]+
$
]]
&&
[
"
$tunnel_port
"
-gt
22
]
&&
[
"
$tunnel_port
"
-le
65535
]
;
then
break
else
colorize red
"Please enter a valid port number between 23 and 65535"
fi
done
echo
# Initialize nodelay variable
local
nodelay
=
""
# Keep prompting the user until a valid input is provided
while
[[
"
$nodelay
"
!=
"true"
&&
"
$nodelay
"
!=
"false"
]]
;
do
echo
-ne
"[*] TCP_NODELAY (true/false): "
read
-r
nodelay
if
[[
"
$nodelay
"
!=
"true"
&&
"
$nodelay
"
!=
"false"
]]
;
then
colorize red
"Invalid nodelay input. Please enter 'true' or 'false'"
fi
done
echo
# Initialize HEARTBEAT variable
local
HEARTBEAT
=
""
# Keep prompting the user until a valid input is provided
while
[[
"
$HEARTBEAT
"
!=
"true"
&&
"
$HEARTBEAT
"
!=
"false"
]]
;
do
echo
-ne
"[*] Enable HEARTBEAT (true/false): "
read
-r
HEARTBEAT
if
[[
"
$HEARTBEAT
"
!=
"true"
&&
"
$HEARTBEAT
"
!=
"false"
]]
;
then
colorize red
"Invalid HEARTBEAT value. Please enter 'true' or 'false'"
fi
done
if
[[
"
$HEARTBEAT
"
==
"true"
]]
;
then
HEARTBEAT
=
"40"
else
HEARTBEAT
=
"0"
fi
echo
# Initialize transport variable
local
transport
=
""
# Keep prompting the user until a valid input is provided
while
[[
"
$transport
"
!=
"tcp"
&&
"
$transport
"
!=
"udp"
]]
;
do
# Prompt the user to input transport type
echo
-ne
"[*] Transport type (tcp/udp): "
read
-r
transport
# Check if the input is either tcp or udp
if
[[
"
$transport
"
!=
"tcp"
&&
"
$transport
"
!=
"udp"
]]
;
then
colorize red
"Invalid transport type. Please enter 'tcp' or 'udp'"
fi
done
echo
echo
-ne
"[-] Security Token (press enter to use default value): "
read
-r
token
if
[[
-z
"
$token
"
]]
;
then
token
=
"musixal"
fi
echo
# Prompt for Ports
echo
-ne
"[*] Enter your ports separated by commas (e.g. 2070,2080): "
read
-r
input_ports
input_ports
=
$(
echo
"
$input_ports
"
|
tr
-d
' '
)
declare
-a
config_ports
# Convert the input into an array, splitting by comma
IFS
=
','
read
-r
-a
ports
<<<
"
$input_ports
"
# Iterate through each port and perform an action
for
port
in
"
${
ports
[@]
}
"
;
do
if
[[
"
$port
"
=
~ ^[0-9]+
$
]]
&&
[
"
$port
"
-gt
22
]
&&
[
"
$port
"
-le
65535
]
;
then
if
!
check_port
"
$port
"
"
$transport
"
;
then
colorize yellow
"[INFO] Port
$port
is not in LISTENING state."
fi
colorize green
"[INFO] Port
$port
added to your configs"
config_ports+
=(
"
$port
"
)
else
colorize red
"[ERROR] Port
$port
is Invalid. Please enter a valid port number between 23 and 65535"
fi
done
if
[
${#
config_ports
[@]
}
-eq
0
]
;
then
colorize red
"No ports were entered. Exiting."
bold
sleep
2
return
1
fi
#Add IPv6 Support
local_ip
=
'0.0.0.0'
if
check_ipv6
"
$SERVER_ADDR
"
;
then
local_ip
=
'[::]'
# Remove brackets if present
SERVER_ADDR
=
"
${
SERVER_ADDR
#[
}
"
SERVER_ADDR
=
"
${
SERVER_ADDR
%]
}
"
fi
# Generate server configuration file
cat
<<
EOF
> "
${
config_dir
}
/kharej
${
tunnel_port
}
.toml"
[client]
remote_addr = "
${
SERVER_ADDR
}
:
${
tunnel_port
}
"
default_token = "
$token
"
heartbeat_timeout =
$HEARTBEAT
retry_interval = 1
[client.transport]
type = "tcp"
[client.transport.tcp]
nodelay =
$nodelay
EOF
# Add each config port to the configuration file
for
port
in
"
${
config_ports
[@]
}
"
;
do
cat
<<
EOF
>> "
${
config_dir
}
/kharej
${
tunnel_port
}
.toml"
[client.services.
${
port
}
]
type = "
$transport
"
local_addr = "
${
local_ip
}
:
${
port
}
"
EOF
done
echo
# Create the systemd service unit file
cat
<<
EOF
> "
${
service_dir
}
/rathole-kharej
${
tunnel_port
}
.service"
[Unit]
Description=Rathole Kharej Port
$tunnel_port
After=network.target
[Service]
Type=simple
ExecStart=
${
config_dir
}
/rathole
${
config_dir
}
/kharej
${
tunnel_port
}
.toml
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd to read the new unit file
systemctl daemon-reload
>
/dev/null 2>&1
# Enable and start the service to start on boot
if
systemctl
enable
--now
"
${
service_dir
}
/rathole-kharej
${
tunnel_port
}
.service"
>
/dev/null 2>&1
;
then
colorize green
"Kharej service with port
$tunnel_port
enabled to start on boot and started."
else
colorize red
"Failed to enable service with port
$tunnel_port
. Please check your system configuration."
return
1
fi
echo
colorize green
"Kharej server configuration completed successfully."
}
# Function for checking tunnel status
check_tunnel_status
()
{
echo
# Check for .toml files
if
!
ls
"
$config_dir
"
/
*
.toml 1> /dev/null 2>&1
;
then
colorize red
"No config files found in the rathole directory."
bold
echo
press_key
return
1
fi
clear
colorize yellow
"Checking all services status..."
bold
sleep
1
echo
for
config_path
in
"
$config_dir
"
/iran
*
.toml
;
do
if
[
-f
"
$config_path
"
]
;
then
# Extract config_name without directory path and change it to service name
config_name
=
$(
basename
"
$config_path
"
)
config_name
=
"
${
config_name
%.toml
}
"
service_name
=
"rathole-
${
config_name
}
.service"
config_port
=
"
${
config_name
#iran
}
"
# Check if the rathole-client-kharej service is active
if
systemctl is-active
--quiet
"
$service_name
"
;
then
colorize green
"Iran service with tunnel port
$config_port
is running"
else
colorize red
"Iran service with tunnel port
$config_port
is not running"
fi
fi
done
for
config_path
in
"
$config_dir
"
/kharej
*
.toml
;
do
if
[
-f
"
$config_path
"
]
;
then
# Extract config_name without directory path and change it to service name
config_name
=
$(
basename
"
$config_path
"
)
config_name
=
"
${
config_name
%.toml
}
"
service_name
=
"rathole-
${
config_name
}
.service"
config_port
=
"
${
config_name
#kharej
}
"
# Check if the rathole-client-kharej service is active
if
systemctl is-active
--quiet
"
$service_name
"
;
then
colorize green
"Kharej service with tunnel port
$config_port
is running"
else
colorize red
"Kharej service with tunnel port
$config_port
is not running"
fi
fi
done
echo
press_key
}
# Function for destroying tunnel
tunnel_management
()
{
echo
# Check for .toml files
if
!
ls
"
$config_dir
"
/
*
.toml 1> /dev/null 2>&1
;
then
colorize red
"No config files found in the rathole directory."
bold
echo
press_key
return
1
fi
clear
colorize cyan
"List of existing services to manage:"
bold
echo
#Variables
local
index
=
1
declare
-a
configs
for
config_path
in
"
$config_dir
"
/iran
*
.toml
;
do
if
[
-f
"
$config_path
"
]
;
then
# Extract config_name without directory path
config_name
=
$(
basename
"
$config_path
"
)
# Remove "iran" prefix and ".toml" suffix
config_port
=
"
${
config_name
#iran
}
"
config_port
=
"
${
config_port
%.toml
}
"
configs+
=(
"
$config_path
"
)
echo
-e
"
${
MAGENTA
}${
index
}${
NC
}
)
${
GREEN
}
Iran
${
NC
}
service, Tunnel port:
${
YELLOW
}
$config_port
${
NC
}
"
((
index++
))
fi
done
for
config_path
in
"
$config_dir
"
/kharej
*
.toml
;
do
if
[
-f
"
$config_path
"
]
;
then
# Extract config_name without directory path
config_name
=
$(
basename
"
$config_path
"
)
# Remove "kharej" prefix and ".toml" suffix
config_port
=
"
${
config_name
#kharej
}
"
config_port
=
"
${
config_port
%.toml
}
"
configs+
=(
"
$config_path
"
)
echo
-e
"
${
MAGENTA
}${
index
}${
NC
}
)
${
GREEN
}
Kharej
${
NC
}
service, Tunnel port:
${
YELLOW
}
$config_port
${
NC
}
"
((
index++
))
fi
done
echo
echo
-ne
"Enter your choice (0 to return): "
read
choice
# Check if the user chose to return
if
((
choice
==
0
))
;
then
return
fi
# validation
while
!
[[
"
$choice
"
=
~ ^[0-9]+
$
]]
||
((
choice < 0
||
choice
>
${#
configs
[@]
}
))
;
do
colorize red
"Invalid choice. Please enter a number between 1 and
${#
configs
[@]
}
."
bold
echo
echo
-ne
"Enter your choice (0 to return): "
read
choice
if
((
choice
==
0
))
;
then
return
fi
done
selected_config
=
"
${
configs
[
$((
choice
-
1
))
]
}
"
config_name
=
$(
basename
"
${
selected_config
%.toml
}
"
)
service_name
=
"rathole-
${
config_name
}
.service"
clear
colorize cyan
"List of available commands for
$config_name
:"
bold
echo
colorize red
"1) Remove this tunnel"
colorize yellow
"2) Restart this tunnel"
colorize green
"3) Add a new config for this tunnel"
colorize reset
"4) Add a cronjob for this tunnel"
colorize reset
"5) Remove existing cronjob for this tunnel"
colorize reset
"6) View service logs"
colorize reset
"7) View service status"
echo
read
-p
"Enter your choice (0 to return): "
choice
case
$choice
in
1
)
destroy_tunnel
"
$selected_config
"
;;
2
)
restart_service
"
$service_name
"
;;
3
)
add_new_config
"
$selected_config
"
;;
4
)
add_cron_job_menu
"
$service_name
"
;;
5
)
delete_cron_job
"
$service_name
"
;;
6
)
view_service_logs
"
$service_name
"
;;
7
)
view_service_status
"
$service_name
"
;;
0
)
return
1
;;
*
)
echo
-e
"
${
RED
}
Invalid option!
${
NC
}
"
&&
sleep
1
&&
return
1
;;
esac
}
remove_core
(){
echo
# If user try to remove core and still a service is running, we should prohibit this.
# Check if any .toml file exists
if
find
"
$config_dir
"
-type
f
-name
"*.toml"
|
grep
-q
.
;
then
colorize red
"You should delete all services first and then delete the rathole-core."
sleep
3
return
1
else
colorize cyan
"No .toml file found in the directory."
fi
echo
# Prompt to confirm before removing Rathole-core directory
colorize yellow
"Do you want to remove rathole-core? (y/n)"
read
-r
confirm
echo
if
[[
$confirm
==
[
yY]
]]
;
then
if
[[
-d
"
$config_dir
"
]]
;
then
rm
-rf
"
$config_dir
"
>
/dev/null 2>&1
colorize green
"Rathole-core directory removed."
bold
else
colorize red
"Rathole-core directory not found."
bold
fi
else
colorize yellow
"Rathole core removal canceled."
fi
echo
press_key
}
destroy_tunnel
(){
echo
#Vaiables
config_path
=
"
$1
"
config_name
=
$(
basename
"
${
config_path
%.toml
}
"
)
service_name
=
"rathole-
${
config_name
}
.service"
service_path
=
"
$service_dir
/
$service_name
"
# Check if config exists and delete it
if
[
-f
"
$config_path
"
]
;
then
rm
-f
"
$config_path
"
>
/dev/null 2>&1
fi
delete_cron_job
$service_name
# Stop and disable the client service if it exists
if
[[
-f
"
$service_path
"
]]
;
then
if
systemctl is-active
"
$service_name
"
&>/dev/null
;
then
systemctl disable
--now
"
$service_name
"
>
/dev/null 2>&1
fi
rm
-f
"
$service_path
"
>
/dev/null 2>&1
fi
echo
# Reload systemd to read the new unit file
if
systemctl daemon-reload
>
/dev/null 2>&1
;
then
echo
-e
"Systemd daemon reloaded.
\n
"
else
echo
-e
"
${
RED
}
Failed to reload systemd daemon. Please check your system configuration.
${
NC
}
"
fi
echo
-e
"
${
GREEN
}
Tunnel destroyed successfully!
${
NC
}
"
echo
sleep
1
}
#Function to restart services
restart_service
()
{
echo
service_name
=
"
$1
"
colorize yellow
"Restarting
$service_name
"
bold
echo
# Check if service exists
if
systemctl list-units
--type
=
service |
grep
-q
"
$service_name
"
;
then
systemctl restart
"
$service_name
"
colorize green
"Service restarted successfully"
else
colorize red
"Cannot restart the service"
fi
echo
press_key
}
# Function to add cron-tab job
add_cron_job
()
{
local
restart_time
=
"
$1
"
local
reset_path
=
"
$2
"
local
service_name
=
"
$3
"
# Save existing crontab to a temporary file
crontab
-l
>
/tmp/crontab.tmp
# Append the new cron job to the temporary file
echo
"
$restart_time
$reset_path
#
$service_name
"
>>
/tmp/crontab.tmp
# Install the modified crontab from the temporary file
crontab /tmp/crontab.tmp
# Remove the temporary file
rm
/tmp/crontab.tmp
}
delete_cron_job
()
{
echo
local
service_name
=
"
$1
"
crontab
-l
|
grep
-v
"#
$service_name
"
| crontab -
rm
-f
"
$config_dir
/
${
service_name
%.service
}
.sh"
>
/dev/null 2>&1
colorize green
"Cron job for
$service_name
deleted successfully."
bold
sleep
2
}
add_new_config
(){
echo
local
config_path
=
"
$1
"
#Add IPv6 Support
local_ip
=
'0.0.0.0'
read
-p
"[-] Listen for IPv6 address? (y/n): "
answer
if
[
"
$answer
"
=
"y"
]
||
[
"
$answer
"
=
"Y"
]
;
then
colorize yellow
"IPv6 Enabled"
local_ip
=
'[::]'
elif
[
"
$answer
"
=
"n"
]
;
then
colorize yellow
"IPv4 Enabled"
local_ip
=
'0.0.0.0'
else
colorize yellow
"Invalid choice. IPv4 enabled by default."
local_ip
=
'0.0.0.0'
fi
echo
# Initialize transport variable
local
transport
=
""
# Keep prompting the user until a valid input is provided
while
[[
"
$transport
"
!=
"tcp"
&&
"
$transport
"
!=
"udp"
]]
;
do
# Prompt the user to input transport type
echo
-ne
"[*] Transport type(tcp/udp): "
read
-r
transport
# Check if the input is either tcp or udp
if
[[
"
$transport
"
!=
"tcp"
&&
"
$transport
"
!=
"udp"
]]
;
then
colorize red
"Invalid transport type. Please enter 'tcp' or 'udp'"
fi
done
echo
# Prompt for Ports
echo
-ne
"[*] Enter your ports separated by commas (e.g. 2070,2080): "
read
-r
input_ports
input_ports
=
$(
echo
"
$input_ports
"
|
tr
-d
' '
)
# Convert the input into an array, splitting by comma
IFS
=
','
read
-r
-a
ports
<<<
"
$input_ports
"
declare
-a
config_ports
# Iterate through each port and perform an action
for
port
in
"
${
ports
[@]
}
"
;
do
if
[[
"
$port
"
=
~ ^[0-9]+
$
]]
&&
[
"
$port
"
-gt
22
]
&&
[
"
$port
"
-le
65535
]
;
then
config_ports+
=(
"
$port
"
)
else
colorize red
"[ERROR] Port
$port
is Invalid. Please enter a valid port number between 23 and 65535"
fi
done
if
[
${#
config_ports
[@]
}
-eq
0
]
;
then
colorize red
"No ports were entered. Exiting."
bold
sleep
2
return
1
fi
echo
if
grep
-q
"iran"
<<<
"
$config_path
"
;
then
# Add each config port to the configuration file
for
port
in
"
${
config_ports
[@]
}
"
;
do
cat
<<
EOF
>> "
$config_path
"
[server.services.
${
port
}
]
type = "
$transport
"
bind_addr = "
${
local_ip
}
:
${
port
}
"
EOF
done
else
# Add each config port to the configuration file
for
port
in
"
${
config_ports
[@]
}
"
;
do
cat
<<
EOF
>> "
$config_path
"
[client.services.
${
port
}
]
type = "
$transport
"
local_addr = "
${
local_ip
}
:
${
port
}
"
EOF
done
fi
colorize green
"All ports added to your config successfully"
done
sleep
1
config_name
=
$(
basename
"
${
config_path
%.toml
}
"
)
service_name
=
"rathole-
${
config_name
}
.service"
restart_service
"
$service_name
"
}
add_cron_job_menu
()
{
echo
service_name
=
"
$1
"
# Prompt user to choose a restart time interval
colorize cyan
"Select the restart time interval:"
bold
echo
echo
"1. Every 30th minute"
echo
"2. Every 1 hour"
echo
"3. Every 2 hours"
echo
"4. Every 4 hours"
echo
"5. Every 6 hours"
echo
"6. Every 12 hours"
echo
"7. Every 24 hours"
echo
read
-p
"Enter your choice: "
time_choice
# Validate user input for restart time interval
case
$time_choice
in
1
)
restart_time
=
"*/30 * * * *"
;;
2
)
restart_time
=
"0 * * * *"
;;
3
)
restart_time
=
"0 */2 * * *"
;;
4
)
restart_time
=
"0 */4 * * *"
;;
5
)
restart_time
=
"0 */6 * * *"
;;
6
)
restart_time
=
"0 */12 * * *"
;;
7
)
restart_time
=
"0 0 * * *"
;;
*
)
echo
-e
"
${
RED
}
Invalid choice. Please enter a number between 1 and 7.
${
NC
}
\n
"
return
1
;;
esac
# remove cronjob created by this script
delete_cron_job
$service_name
>
/dev/null 2>&1
# Path ro reset file
reset_path
=
"
$config_dir
/
${
service_name
%.service
}
.sh"
#add cron job to kill the running rathole processes
cat
<<
EOF
> "
$reset_path
"
#! /bin/bash
pids=
\$
(pgrep rathole)
sudo kill -9
\$
pids
sudo systemctl daemon-reload
sudo systemctl restart
$service_name
EOF
# make it +x !
chmod
+x
"
$reset_path
"
# Add cron job to restart the specified service at the chosen time
add_cron_job
"
$restart_time
"
"
$reset_path
"
"
$service_name
"
echo
colorize green
"Cron-job added successfully to restart the service '
$service_name
'."
bold
sleep
2
}
view_service_logs
(){
clear
journalctl
-eu
"
$1
"
}
view_service_status
(){
clear
systemctl status
"
$1
"
}
update_script
(){
# Define the destination path
DEST_DIR
=
"/usr/bin/"
RATHOLE_SCRIPT
=
"rathole"
SCRIPT_URL
=
"https://github.com/Musixal/rathole-tunnel/raw/main/rathole_v2.sh"
echo
# Check if rathole.sh exists in /bin/bash
if
[
-f
"
$DEST_DIR
/
$RATHOLE_SCRIPT
"
]
;
then
# Remove the existing rathole
rm
"
$DEST_DIR
/
$RATHOLE_SCRIPT
"
if
[
$?
-eq
0
]
;
then
echo
-e
"
${
GREEN
}
Existing
$RATHOLE_SCRIPT
has been successfully removed from
$DEST_DIR
.
${
NC
}
"
else
echo
-e
"
${
RED
}
Failed to remove existing
$RATHOLE_SCRIPT
from
$DEST_DIR
.
${
NC
}
"
sleep
1
return
1
fi
else
echo
-e
"
${
YELLOW
}
$RATHOLE_SCRIPT
does not exist in
$DEST_DIR
. No need to remove.
${
NC
}
"
fi
# Download the new rathole.sh from the GitHub URL
#echo -e "${CYAN}Downloading the new $RATHOLE_SCRIPT from $SCRIPT_URL...${NC}"
curl
-s
-L
-o
"
$DEST_DIR
/
$RATHOLE_SCRIPT
"
"
$SCRIPT_URL
"
echo
if
[
$?
-eq
0
]
;
then
#echo -e "${GREEN}New $RATHOLE_SCRIPT has been successfully downloaded to $DEST_DIR.${NC}\n"
chmod
+x
"
$DEST_DIR
/
$RATHOLE_SCRIPT
"
colorize yellow
"Type 'rathole' to run the script.
\n
"
bold
colorize yellow
"For removing script type: 'rm -rf /usr/bin/rathole
\n
"
bold
press_key
exit
0
else
echo
-e
"
${
RED
}
Failed to download
$RATHOLE_SCRIPT
from
$SCRIPT_URL
.
${
NC
}
"
sleep
1
return
1
fi
}
# _________________________ HAWSHEMI SCRIPT OPT FOR UBUNTU _________________________
# Declare Paths & Settings.
SYS_PATH
=
"/etc/sysctl.conf"
PROF_PATH
=
"/etc/profile"
# Ask Reboot
ask_reboot
()
{
echo
-ne
"
${
YELLOW
}
Reboot now? (Recommended) (y/n):
${
NC
}
"
while
true
;
do
read
choice
echo
if
[[
"
$choice
"
==
'y'
||
"
$choice
"
==
'Y'
]]
;
then
sleep
0.5
reboot
exit
0
fi
if
[[
"
$choice
"
==
'n'
||
"
$choice
"
==
'N'
]]
;
then
break
fi
done
}
# SYSCTL Optimization
sysctl_optimizations
()
{
## Make a backup of the original sysctl.conf file
cp
$SYS_PATH
/etc/sysctl.conf.bak
echo
echo
-e
"
${
YELLOW
}
Default sysctl.conf file Saved. Directory: /etc/sysctl.conf.bak
${
NC
}
"
echo
sleep
1
echo
echo
-e
"
${
YELLOW
}
Optimizing the Network...
${
NC
}
"
echo
sleep
0.5
sed
-i
-e
'/fs.file-max/d'
\
-e
'/net.core.default_qdisc/d'
\
-e
'/net.core.netdev_max_backlog/d'
\
-e
'/net.core.optmem_max/d'
\
-e
'/net.core.somaxconn/d'
\
-e
'/net.core.rmem_max/d'
\
-e
'/net.core.wmem_max/d'
\
-e
'/net.core.rmem_default/d'
\
-e
'/net.core.wmem_default/d'
\
-e
'/net.ipv4.tcp_rmem/d'
\
-e
'/net.ipv4.tcp_wmem/d'
\
-e
'/net.ipv4.tcp_congestion_control/d'
\
-e
'/net.ipv4.tcp_fastopen/d'
\
-e
'/net.ipv4.tcp_fin_timeout/d'
\
-e
'/net.ipv4.tcp_keepalive_time/d'
\
-e
'/net.ipv4.tcp_keepalive_probes/d'
\
-e
'/net.ipv4.tcp_keepalive_intvl/d'
\
-e
'/net.ipv4.tcp_max_orphans/d'
\
-e
'/net.ipv4.tcp_max_syn_backlog/d'
\
-e
'/net.ipv4.tcp_max_tw_buckets/d'
\
-e
'/net.ipv4.tcp_mem/d'
\
-e
'/net.ipv4.tcp_mtu_probing/d'
\
-e
'/net.ipv4.tcp_notsent_lowat/d'
\
-e
'/net.ipv4.tcp_retries2/d'
\
-e
'/net.ipv4.tcp_sack/d'
\
-e
'/net.ipv4.tcp_dsack/d'
\
-e
'/net.ipv4.tcp_slow_start_after_idle/d'
\
-e
'/net.ipv4.tcp_window_scaling/d'
\
-e
'/net.ipv4.tcp_adv_win_scale/d'
\
-e
'/net.ipv4.tcp_ecn/d'
\
-e
'/net.ipv4.tcp_ecn_fallback/d'
\
-e
'/net.ipv4.tcp_syncookies/d'
\
-e
'/net.ipv4.udp_mem/d'
\
-e
'/net.ipv6.conf.all.disable_ipv6/d'
\
-e
'/net.ipv6.conf.default.disable_ipv6/d'
\
-e
'/net.ipv6.conf.lo.disable_ipv6/d'
\
-e
'/net.unix.max_dgram_qlen/d'
\
-e
'/vm.min_free_kbytes/d'
\
-e
'/vm.swappiness/d'
\
-e
'/vm.vfs_cache_pressure/d'
\
-e
'/net.ipv4.conf.default.rp_filter/d'
\
-e
'/net.ipv4.conf.all.rp_filter/d'
\
-e
'/net.ipv4.conf.all.accept_source_route/d'
\
-e
'/net.ipv4.conf.default.accept_source_route/d'
\
-e
'/net.ipv4.neigh.default.gc_thresh1/d'
\
-e
'/net.ipv4.neigh.default.gc_thresh2/d'
\
-e
'/net.ipv4.neigh.default.gc_thresh3/d'
\
-e
'/net.ipv4.neigh.default.gc_stale_time/d'
\
-e
'/net.ipv4.conf.default.arp_announce/d'
\
-e
'/net.ipv4.conf.lo.arp_announce/d'
\
-e
'/net.ipv4.conf.all.arp_announce/d'
\
-e
'/kernel.panic/d'
\
-e
'/vm.dirty_ratio/d'
\
-e
'/^#/d'
\
-e
'/^$/d'
\
"
$SYS_PATH
"
## Add new parameteres.
cat
<<
EOF
>> "
$SYS_PATH
"
################################################################
################################################################
# /etc/sysctl.conf
# These parameters in this file will be added/updated to the sysctl.conf file.
# Read More: https://github.com/hawshemi/Linux-Optimizer/blob/main/files/sysctl.conf
## File system settings
## ----------------------------------------------------------------
# Set the maximum number of open file descriptors
fs.file-max = 67108864
## Network core settings
## ----------------------------------------------------------------
# Specify default queuing discipline for network devices
net.core.default_qdisc = fq_codel
# Configure maximum network device backlog
net.core.netdev_max_backlog = 32768
# Set maximum socket receive buffer
net.core.optmem_max = 262144
# Define maximum backlog of pending connections
net.core.somaxconn = 65536
# Configure maximum TCP receive buffer size
net.core.rmem_max = 33554432
# Set default TCP receive buffer size
net.core.rmem_default = 1048576
# Configure maximum TCP send buffer size
net.core.wmem_max = 33554432
# Set default TCP send buffer size
net.core.wmem_default = 1048576
## TCP settings
## ----------------------------------------------------------------
# Define socket receive buffer sizes
net.ipv4.tcp_rmem = 16384 1048576 33554432
# Specify socket send buffer sizes
net.ipv4.tcp_wmem = 16384 1048576 33554432
# Set TCP congestion control algorithm to BBR
net.ipv4.tcp_congestion_control = bbr
# Configure TCP FIN timeout period
net.ipv4.tcp_fin_timeout = 25
# Set keepalive time (seconds)
net.ipv4.tcp_keepalive_time = 1200
# Configure keepalive probes count and interval
net.ipv4.tcp_keepalive_probes = 7
net.ipv4.tcp_keepalive_intvl = 30
# Define maximum orphaned TCP sockets
net.ipv4.tcp_max_orphans = 819200
# Set maximum TCP SYN backlog
net.ipv4.tcp_max_syn_backlog = 20480
# Configure maximum TCP Time Wait buckets
net.ipv4.tcp_max_tw_buckets = 1440000
# Define TCP memory limits
net.ipv4.tcp_mem = 65536 1048576 33554432
# Enable TCP MTU probing
net.ipv4.tcp_mtu_probing = 1
# Define minimum amount of data in the send buffer before TCP starts sending
net.ipv4.tcp_notsent_lowat = 32768
# Specify retries for TCP socket to establish connection
net.ipv4.tcp_retries2 = 8
# Enable TCP SACK and DSACK
net.ipv4.tcp_sack = 1
net.ipv4.tcp_dsack = 1
# Disable TCP slow start after idle
net.ipv4.tcp_slow_start_after_idle = 0
# Enable TCP window scaling
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_adv_win_scale = -2
# Enable TCP ECN
net.ipv4.tcp_ecn = 1
net.ipv4.tcp_ecn_fallback = 1
# Enable the use of TCP SYN cookies to help protect against SYN flood attacks
net.ipv4.tcp_syncookies = 1
## UDP settings
## ----------------------------------------------------------------
# Define UDP memory limits
net.ipv4.udp_mem = 65536 1048576 33554432
## IPv6 settings
## ----------------------------------------------------------------
# Enable IPv6
net.ipv6.conf.all.disable_ipv6 = 0
# Enable IPv6 by default
net.ipv6.conf.default.disable_ipv6 = 0
# Enable IPv6 on the loopback interface (lo)
net.ipv6.conf.lo.disable_ipv6 = 0
## UNIX domain sockets
## ----------------------------------------------------------------
# Set maximum queue length of UNIX domain sockets
net.unix.max_dgram_qlen = 256
## Virtual memory (VM) settings
## ----------------------------------------------------------------
# Specify minimum free Kbytes at which VM pressure happens
vm.min_free_kbytes = 65536
# Define how aggressively swap memory pages are used
vm.swappiness = 10
# Set the tendency of the kernel to reclaim memory used for caching of directory and inode objects
vm.vfs_cache_pressure = 250
## Network Configuration
## ----------------------------------------------------------------
# Configure reverse path filtering
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
# Disable source route acceptance
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Neighbor table settings
net.ipv4.neigh.default.gc_thresh1 = 512
net.ipv4.neigh.default.gc_thresh2 = 2048
net.ipv4.neigh.default.gc_thresh3 = 16384
net.ipv4.neigh.default.gc_stale_time = 60
# ARP settings
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
# Kernel panic timeout
kernel.panic = 1
# Set dirty page ratio for virtual memory
vm.dirty_ratio = 20
################################################################
################################################################
EOF
sudo
sysctl
-p
echo
echo
-e
"
${
GREEN
}
Network is Optimized.
${
NC
}
"
echo
sleep
0.5
}
# System Limits Optimizations
limits_optimizations
()
{
echo
echo
-e
"
${
YELLOW
}
Optimizing System Limits...
${
NC
}
"
echo
sleep
0.5
## Clear old ulimits
sed
-i
'/ulimit -c/d'
$PROF_PATH
sed
-i
'/ulimit -d/d'
$PROF_PATH
sed
-i
'/ulimit -f/d'
$PROF_PATH
sed
-i
'/ulimit -i/d'
$PROF_PATH
sed
-i
'/ulimit -l/d'
$PROF_PATH
sed
-i
'/ulimit -m/d'
$PROF_PATH
sed
-i
'/ulimit -n/d'
$PROF_PATH
sed
-i
'/ulimit -q/d'
$PROF_PATH
sed
-i
'/ulimit -s/d'
$PROF_PATH
sed
-i
'/ulimit -t/d'
$PROF_PATH
sed
-i
'/ulimit -u/d'
$PROF_PATH
sed
-i
'/ulimit -v/d'
$PROF_PATH
sed
-i
'/ulimit -x/d'
$PROF_PATH
sed
-i
'/ulimit -s/d'
$PROF_PATH
## Add new ulimits
## The maximum size of core files created.
echo
"ulimit -c unlimited"
|
tee
-a
$PROF_PATH
## The maximum size of a process's data segment
echo
"ulimit -d unlimited"
|
tee
-a
$PROF_PATH
## The maximum size of files created by the shell (default option)
echo
"ulimit -f unlimited"
|
tee
-a
$PROF_PATH
## The maximum number of pending signals
echo
"ulimit -i unlimited"
|
tee
-a
$PROF_PATH
## The maximum size that may be locked into memory
echo
"ulimit -l unlimited"
|
tee
-a
$PROF_PATH
## The maximum memory size
echo
"ulimit -m unlimited"
|
tee
-a
$PROF_PATH
## The maximum number of open file descriptors
echo
"ulimit -n 1048576"
|
tee
-a
$PROF_PATH
## The maximum POSIX message queue size
echo
"ulimit -q unlimited"
|
tee
-a
$PROF_PATH
## The maximum stack size
echo
"ulimit -s -H 65536"
|
tee
-a
$PROF_PATH
echo
"ulimit -s 32768"
|
tee
-a
$PROF_PATH
## The maximum number of seconds to be used by each process.
echo
"ulimit -t unlimited"
|
tee
-a
$PROF_PATH
## The maximum number of processes available to a single user
echo
"ulimit -u unlimited"
|
tee
-a
$PROF_PATH
## The maximum amount of virtual memory available to the process
echo
"ulimit -v unlimited"
|
tee
-a
$PROF_PATH
## The maximum number of file locks
echo
"ulimit -x unlimited"
|
tee
-a
$PROF_PATH
echo
echo
-e
"
${
GREEN
}
System Limits are Optimized.
${
NC
}
"
echo
sleep
0.5
}
# _________________________ END OF HAWSHEMI SCRIPT OPT FOR UBUNTU _________________________
hawshemi_script
(){
clear
echo
-e
"
${
MAGENTA
}
Special thanks to Hawshemi, the author of optimizer script...
${
NC
}
"
sleep
2
# Get the operating system name
os_name
=
$(
lsb_release
-is
)
echo
-e
# Check if the operating system is Ubuntu
if
[
"
$os_name
"
==
"Ubuntu"
]
;
then
echo
-e
"
${
GREEN
}
The operating system is Ubuntu.
${
NC
}
"
sleep
1
else
echo
-e
"
${
RED
}
The operating system is not Ubuntu.
${
NC
}
"
sleep
2
return
fi
sysctl_optimizations
limits_optimizations
ask_reboot
read
-p
"Press Enter to continue..."
}
install_modified_core
(){
echo
DOWNLOAD_URL
=
'https://github.com/Musixal/rathole-tunnel/raw/main/core/rathole_modified.zip'
if
[
-z
"
$DOWNLOAD_URL
"
]
;
then
echo
-e
"
${
RED
}
Failed to retrieve download URL.
${
NC
}
"
sleep
1
return
1
fi
DOWNLOAD_DIR
=
$(
mktemp
-d
)
echo
-e
"Downloading modifed rathole-core from
$DOWNLOAD_URL
...
\n
"
sleep
1
curl
-sSL
-o
"
$DOWNLOAD_DIR
/rathole_modified.zip"
"
$DOWNLOAD_URL
"
echo
-e
"Extracting Rathole...
\n
"
sleep
1
unzip
-q
"
$DOWNLOAD_DIR
/rathole_modified.zip"
-d
"
$config_dir
"
mv
-f
${
config_dir
}
/rathole_modified
${
config_dir
}
/rathole
echo
-e
"
${
GREEN
}
Rathole installation completed.
${
NC
}
"
chmod
u+x
${
config_dir
}
/rathole
rm
-rf
"
$DOWNLOAD_DIR
"
echo
}
change_core
(){
echo
ARCH
=
$(
uname
-m
)
if
!
[[
"
$ARCH
"
==
"x86_64"
]]
;
then
colorize red
"Only x86_64 arch. is supported right now!"
bold
sleep
2
return
1
fi
colorize cyan
"Select your rathole-core:"
bold
echo
colorize green
"1) Default Core"
colorize yellow
"2) Modified Core (Lower connections, maybe higher latency)"
colorize reset
"3) return "
echo
read
-p
"Enter your choice [1-3]: "
choice
case
$choice
in
1
)
rm
-f
"
${
config_dir
}
/rathole"
&> /dev/null
download_and_extract_rathole
;;
2
)
rm
-f
"
${
config_dir
}
/rathole"
&> /dev/null
install_modified_core
;;
3
)
return
1
;;
*
)
echo
-e
"
${
RED
}
Invalid option!
${
NC
}
"
&&
sleep
1
&&
return
1
;;
esac
colorize red
"IMPORTANT!"
bold
colorize yellow
"To load the new core, restart all services."
bold
echo
press_key
}
# Color codes
RED
=
'\033[0;31m'
GREEN
=
'\033[0;32m'
YELLOW
=
'\033[0;33m'
CYAN
=
'\e[36m'
MAGENTA
=
"
\e
[95m"
NC
=
'\033[0m'
# No Color
# Function to display menu
display_menu
()
{
clear
display_logo
display_server_info
display_rathole_core_status
echo
colorize green
" 1. Configure a new tunnel [IPv4/IPv6]"
bold
colorize red
" 2. Tunnel management menu"
bold
colorize cyan
" 3. Check tunnels status"
bold
echo
-e
" 4. Optimize network & system limits"
echo
-e
" 5. Install rathole core"
echo
-e
" 6. Update & install script"
echo
-e
" 7. Change core [experimental]"
echo
-e
" 8. Remove rathole core"
echo
-e
" 0. Exit"
echo
echo
"-------------------------------"
}
# Function to read user input
read_option
()
{
read
-p
"Enter your choice [0-8]: "
choice
case
$choice
in
1
)
configure_tunnel
;;
2
)
tunnel_management
;;
3
)
check_tunnel_status
;;
4
)
hawshemi_script
;;
5
)
download_and_extract_rathole
"sleep"
;;
6
)
update_script
;;
7
)
change_core
;;
8
)
remove_core
;;
0
)
exit
0
;;
*
)
echo
-e
"
${
RED
}
Invalid option!
${
NC
}
"
&&
sleep
1
;;
esac
}
# Main script
while
true
do
display_menu
read_option
done
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment