-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathC2C_Command.py
585 lines (476 loc) · 20.6 KB
/
C2C_Command.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
import paramiko
import datetime
import time
def display_menu():
print("\nCertified True Copy")
print("=" * 30)
print("1: Server Security")
print("2: User Management")
print("3: Server Management")
print("4: Install Website")
print("99: Exit")
print("=" * 30)
def server_security_menu(client):
while True:
print("\nServer Security")
print("1: Change SSH Port")
print("99: Back to Main Menu")
choice = input("Enter your choice: ")
if choice == '1':
change_ssh_port(client)
elif choice == '99':
return
else:
print("Invalid choice. Please try again.")
server_security_menu(client)
def user_management_menu(client):
while True:
print("\nUser Management")
print("1: Add user")
print("2: Delete user")
print("3: Change user password")
print("4: List of users")
print("99: Back to Main Menu")
choice = input("Enter your choice: ")
if choice == '1':
add_user(client)
elif choice == '2':
delete_user(client)
elif choice == '3':
change_user_password(client)
elif choice == '4':
list_users(client)
elif choice == '99':
return
else:
print("Invalid choice. Please try again.")
user_management_menu(client)
def server_management_menu(client):
while True:
print("\nServer Management")
print("1: Tunnel Setup")
print("2: UDPGW")
print("3: Block Domains")
print("4: Active user limit")
print("99: Back to Main Menu")
choice = input("Enter your choice: ")
if choice == '1':
tunnel_setup(client)
elif choice == '2':
setup_udpgw(client)
elif choice == '3':
block_domains(client)
elif choice == '4':
activate_user_limit(client)
elif choice == '99':
return
else:
print("Invalid choice. Please try again.")
server_management_menu(client)
def install_website_menu(client):
while True:
print("\nInstall Website")
print("1: Install Nginx")
print("2: Upload Website")
print("3: Certbot + SSL")
print("99: Back to Main Menu")
choice = input("Enter your choice: ")
if choice == '1':
install_nginx(client)
elif choice == '2':
upload_website(client)
elif choice == '3':
install_certbot_and_get_ssl(client)
elif choice == '99':
return
else:
print("Invalid choice. Please try again.")
install_website_menu(client)
def perform_action(client, choice):
if choice == '1':
server_security_menu(client)
elif choice == '2':
user_management_menu(client)
elif choice == '3':
server_management_menu(client)
elif choice == '4':
install_website_menu(client)
elif choice == '99':
print("Exiting.")
exit(0)
else:
print("Invalid choice. Please try again.")
def add_user(client):
# Get user input via console
username = input("Enter Username: ")
if not username: return
password = input("Enter Password: ")
if not password: return
max_connections = input("Enter Max Connection: ")
if not max_connections: return
expires = input("Enter Expires (in days): ")
if not expires: return
traffic_limit = input("Enter Traffic Limit: ")
if not traffic_limit: return
# Checking if the file already has a header
command = 'cat /var/log/users.csv'
stdin, stdout, stderr = client.exec_command(command)
content = stdout.read().decode()
header = "Username,Password,Max_Connection,Created,Expires,Traffic_Limit\n"
if not content.startswith(header):
command = f'echo "{header.strip()}" | sudo tee -a /var/log/users.csv'
stdin, stdout, stderr = client.exec_command(command)
# Prepare the CSV row data
csv_data = f"{username},{password},{max_connections},0,{expires},{traffic_limit}\n"
# Append the data to the remote CSV file
command = f'echo "{csv_data.strip()}" | sudo tee -a /var/log/users.csv'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors:
print(f'Error updating users.csv file: {errors}')
return
print(f'Successfully created user {username}')
# Check if the check_users.sh script exists
command = 'if [ -f /var/log/check_users.sh ]; then echo "exists"; else echo "not exists"; fi'
stdin, stdout, stderr = client.exec_command(command)
result = stdout.read().decode().strip()
# If the check_users.sh script does not exist, download it, make it executable, and set it to run every minute via crontab
if result == "not exists":
download_cmd = 'sudo wget -O /var/log/check_users.sh https://raw.githubusercontent.com/certifiedtruecopy/C2C_SSH/main/check_users.sh 2>&1'
make_executable_cmd = 'sudo chmod +x /var/log/check_users.sh'
add_cronjob_cmd = '(crontab -l 2>/dev/null; echo "* * * * * /var/log/check_users.sh") | crontab -'
# Execute the commands
for cmd in [download_cmd, make_executable_cmd, add_cronjob_cmd]:
stdin, stdout, stderr = client.exec_command(cmd)
errors = stderr.read().decode()
if errors:
print(f"Error during command '{cmd}': {errors}")
return
print(f'Successfully set up the check_users.sh script for user {username}')
def delete_user(client):
username = input("Enter username to delete: ")
if not username:
print("Username cannot be empty!")
return
# Delete user
stdin, stdout, stderr = client.exec_command(f'sudo userdel {username}')
errors = stderr.read().decode()
if errors:
print(f'Error deleting user: {errors}\n')
return
print(f'Successfully deleted user {username}\n')
def change_user_password(client):
username = input("Enter username: ")
if not username:
print("Username cannot be empty!")
return
new_password = input("Enter new password: ")
if not new_password:
print("Password cannot be empty!")
return
# Change user password
stdin, stdout, stderr = client.exec_command(f'echo "{username}:{new_password}" | sudo chpasswd')
errors = stderr.read().decode()
if errors:
print(f'Error changing user password: {errors}\n')
return
print(f'Successfully changed password for user {username}\n')
def list_users(client):
# Ask the user for the username prefix
username_prefix = input("Please enter the username prefix:")
print("\n{:<20} {:<20} {:<20} {:<20} {:<20} {:<20}".format("Username", "Production Date", "Expiry Date", "Amount of Traffic", "Traffic Used", "Online User"))
print("-" * 120)
# Get the list of users
stdin, stdout, stderr = client.exec_command('grep "/usr/sbin/nologin" /etc/passwd | cut -d: -f1')
user_list = stdout.read().decode().split('\n')
for user in user_list:
if user and user.startswith(username_prefix):
# Get the user's information
stdin, stdout, stderr = client.exec_command(f'sudo chage -l {user}')
chage_output = stdout.read().decode()
# Parse the user's information
created_date = ""
validity_days = ""
traffic_limit = ""
traffic_usage = ""
online = ""
lines = chage_output.split('\n')
for line in lines:
if "Last password change" in line:
created_date = line.split(":")[1].strip()
elif "Account expires" in line:
validity_days = line.split(":")[1].strip()
# Get the traffic limit and usage for the user
stdin, stdout, stderr = client.exec_command(f'sudo iptables -v -L OUTPUT')
iptables_output = stdout.read().decode()
# Parse the traffic limit and usage information
lines = iptables_output.split('\n')
for line in lines:
if user in line:
parts = line.split()
traffic_limit = float(parts[14]) / (1000 ** 3)
traffic_limit = round(traffic_limit, 2)
traffic_usage = parts[1]
# Check if the user is online
stdin, stdout, stderr = client.exec_command(f'ps aux | grep "sshd: {user}" | awk "!/priv/" | grep -v grep | wc -l')
w_output = stdout.read().decode()
if w_output:
online = w_output.strip()
# Print the user's information
print("{:<20} {:<20} {:<20} {:<20} {:<20} {:<20}".format(user, created_date, validity_days, str(traffic_limit), traffic_usage, online))
print("-" * 120)
def tunnel_setup(client):
# Install iptables
stdin, stdout, stderr = client.exec_command('sudo apt-get install iptables -y')
errors = stderr.read().decode()
if errors:
print(f'Error installing iptables: \n{errors}\n')
else:
print('Iptables installation successful')
# Get IPs
iranip = input("Enter Iran IP:")
kharegip = input("Enter Foreign IP:")
rc_local_path = "/etc/rc.local"
# Check if the file exists and create if not
stdin, stdout, stderr = client.exec_command(f'if ! test -f {rc_local_path}; then sudo touch {rc_local_path}; echo "#!/bin/sh -e" | sudo tee {rc_local_path}; echo "exit 0" | sudo tee -a {rc_local_path}; fi')
errors = stderr.read().decode()
if errors:
print(f'Error checking/creating /etc/rc.local: {errors}')
return
# Empty the file
stdin, stdout, stderr = client.exec_command(f'echo "#!/bin/sh -e" | sudo tee {rc_local_path}; echo "exit 0" | sudo tee -a {rc_local_path}')
errors = stderr.read().decode()
if errors:
print(f'Error emptying /etc/rc.local: {errors}')
return
rc_local_commands = [
f"sysctl net.ipv4.ip_forward=1",
f"iptables -t nat -A PREROUTING -p tcp --dport 22 -j DNAT --to-destination {iranip}",
f"iptables -t nat -A PREROUTING -j DNAT --to-destination {kharegip}",
f"iptables -t nat -A POSTROUTING -j MASQUERADE",
]
# Add the commands before "exit 0" in the rc.local file
for command in rc_local_commands:
stdin, stdout, stderr = client.exec_command(f'sudo sed -i "/exit 0/i {command}" {rc_local_path}')
errors = stderr.read().decode()
if errors:
print(f'Error adding command to rc.local: {errors}')
return
# Change permissions of rc.local
stdin, stdout, stderr = client.exec_command(f"sudo chmod +x {rc_local_path}")
errors = stderr.read().decode()
if errors:
print(f'Error changing permissions of rc.local: {errors}')
return
print('Tunnel setup successful')
def setup_udpgw(client):
import time
# Check if 'screen' package is installed
command = 'dpkg -s screen'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode().strip()
if errors:
# If 'screen' is not installed, install it
command = 'sudo apt-get install -y screen'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode().strip()
if errors: # Check if a real error occurred
print(f'Error executing command "{command}": {errors}')
return
else:
print('Screen installed successfully')
# Ask the user for the UDPGW port
udpgw_port = int(input("Please enter the UDPGW port:"))
# Kill any processes using the file
command = 'pkill -f /usr/bin/badvpn-udpgw'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors: # Check if a real error occurred
print(f'Error executing command "{command}": {errors}')
return
# Check if the file exists
command = 'ls /usr/bin/badvpn-udpgw'
stdin, stdout, stderr = client.exec_command(command)
file_exists = stdout.read().decode().strip()
# If the file doesn't exist, download it
if not file_exists:
command = 'wget -O /usr/bin/badvpn-udpgw "https://raw.githubusercontent.com/daybreakersx/premscript/master/badvpn-udpgw64"'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if "Saving to" not in errors: # Check if a real error occurred
print(f'Error executing command "{command}": {errors}')
return
# Wait for the file to download
time.sleep(8)
# Create the rc.local file if it doesn't exist
command = 'touch /etc/rc.local'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors: # Check if a real error occurred
print(f'Error executing command "{command}": {errors}')
return
# Create and edit the rc.local file
rc_local_commands = [
"#!/bin/sh -e",
f"screen -AmdS badvpn badvpn-udpgw --listen-addr 127.0.0.1:{udpgw_port}",
"exit 0",
]
rc_local_content = "\n".join(rc_local_commands)
# Write the content to the rc.local file
command = f'echo "{rc_local_content}" > /etc/rc.local'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors:
print(f'Error executing command "{command}": {errors}')
return
# Run the final command
command = f"chmod +x /etc/rc.local && chmod +x /usr/bin/badvpn-udpgw && systemctl daemon-reload && sleep 0.5 && systemctl start rc-local.service && screen -AmdS badvpn badvpn-udpgw --listen-addr 127.0.0.1:{udpgw_port}"
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors:
print(f'Error executing command "{command}": {errors}')
return
print('UDPGW setup successful')
def block_domains(client):
# Ask the user to enter the path to the file
filename = input("Enter the path to the text file containing the domains to block (one per line): ")
if not filename:
print('No file selected')
return
try:
# Open the file and read the domains
with open(filename, 'r') as file:
domains = file.read().strip().split('\n')
# Use paramiko's SFTPClient to upload the file
sftp = client.open_sftp()
sftp.put(filename, '/tmp/domains.txt')
sftp.close()
# Block each domain
for domain in domains:
if domain: # Make sure the domain is not an empty string
command = f'sudo iptables -A INPUT -s {domain} -j DROP'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors:
print(f'Failed to block domain {domain}: {errors}')
else:
print(f'Successfully blocked domain {domain}')
except Exception as e:
print(f'Failed to block domains: {str(e)}')
def activate_user_limit(client):
# Download the script
command = 'sudo wget -O /var/log/userlimit.sh https://raw.githubusercontent.com/certifiedtruecopy/C2C_SSH/main/userlimit.sh 2>&1'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
time.sleep(5)
# Change the mode of the script to executable
command = 'sudo chmod +x /var/log/userlimit.sh'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors:
print(f'Error changing script mode: {errors}')
return
# Execute the script
time.sleep(5)
command = 'nohup sudo bash /var/log/userlimit.sh > /dev/null 2>&1 &'
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors:
print(f'Error executing script: {errors}')
return
print('userlimit.sh executed successfully')
def change_ssh_port(client):
# Ask the user for the new SSH port
new_ssh_port = int(input("Please enter the new SSH port: "))
confirm = input("Changing the SSH port will remove any user restrictions. Do you want to continue? (yes/no): ")
if confirm.lower() == 'yes':
# Create a temporary copy of the sshd_config file
backup_command = "sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak"
stdin, stdout, stderr = client.exec_command(backup_command)
# Modify the SSH port in the temporary copy of sshd_config
modify_command = f"sudo sed -i 's/#Port .*/Port {new_ssh_port}/' /etc/ssh/sshd_config.bak"
stdin, stdout, stderr = client.exec_command(modify_command)
# Replace the original sshd_config file with the modified one
replace_command = "sudo mv /etc/ssh/sshd_config.bak /etc/ssh/sshd_config"
stdin, stdout, stderr = client.exec_command(replace_command)
# Restart the SSH service to apply the changes
restart_command = "sudo service ssh restart"
stdin, stdout, stderr = client.exec_command(restart_command)
print(f'SSH port has been changed to {new_ssh_port}. Please reconnect to the server.')
else:
print('SSH port change cancelled by user.')
def install_nginx(client):
print("Installing Nginx...")
# Always assume the operating system is Debian
command = 'sudo DEBIAN_FRONTEND=noninteractive apt-get install nginx -y'
# Execute the installation command
stdin, stdout, stderr = client.exec_command(command)
errors = stderr.read().decode()
if errors:
print(f'Error installing nginx: {errors}')
return
print('Nginx installation successful')
def upload_website(client):
print("Please provide the path to the zip file of your website:")
filename = input("Path to zip file: ")
if not filename:
print('No file provided')
return
try:
# Use paramiko's SFTPClient to upload the file
sftp = client.open_sftp()
sftp.put(filename, '/var/www/html/website.zip')
sftp.close()
# Wait for 5 seconds
time.sleep(5)
# Install unzip
stdin, stdout, stderr = client.exec_command('sudo DEBIAN_FRONTEND=noninteractive apt-get install unzip -y')
errors = stderr.read().decode()
if errors:
print(f'Error installing unzip: {errors}')
return
# Unzip the file
stdin, stdout, stderr = client.exec_command('unzip /var/www/html/website.zip -d /var/www/html/')
errors = stderr.read().decode()
if errors:
print(f'Error unzipping file: {errors}')
return
print('Upload and extraction successful')
except Exception as e:
print(f'Failed to upload file: {str(e)}')
def install_certbot_and_get_ssl(client):
command = 'sudo DEBIAN_FRONTEND=noninteractive apt install certbot python3-certbot-nginx -y'
print(f"Running command: {command}")
stdin, stdout, stderr = client.exec_command(command)
out = stdout.read().decode()
err = stderr.read().decode()
print(out)
print(err)
time.sleep(20) # wait for 20 seconds
domain = input("Please enter your domain: ")
if not domain:
print("No domain provided.")
return
command = f'sudo DEBIAN_FRONTEND=noninteractive certbot --nginx -d {domain} --register-unsafely-without-email --agree-tos'
print(f"Running command: {command}")
stdin, stdout, stderr = client.exec_command(command)
out = stdout.read().decode()
err = stderr.read().decode()
print(out)
print(err)
def main():
hostname = input("Enter the server's hostname or IP: ")
port = int(input("Enter the server's port: "))
username = input("Enter the username: ")
password = input("Enter the password: ")
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname, port=port, username=username, password=password)
print("Connected to the server.")
while True:
display_menu()
choice = input("Enter your choice (1-7): ")
perform_action(client, choice)
client.close()
if __name__ == "__main__":
main()