NitroExpose 2.0__tar.gz → 2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of NitroExpose might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NitroExpose
3
- Version: 2.0
3
+ Version: 2.2
4
4
  Summary: Advanced CLI To Expose Port To Your Domain.
5
5
  Home-page: https://github.com/yuvrajmodz/NitroExpose
6
6
  Author: @NacDevs
@@ -12,6 +12,7 @@ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: requests
15
+ Requires-Dist: supercore
15
16
  Dynamic: author
16
17
  Dynamic: author-email
17
18
  Dynamic: classifier
@@ -25,7 +26,7 @@ Dynamic: summary
25
26
 
26
27
  ## NitroExpose
27
28
 
28
- **Letest Version:** 2.0
29
+ **Letest Version:** 2.2
29
30
  **Developer:** @Nactire
30
31
  **Git Repo:** [NitroExpose](https://github.com/yuvrajmodz/NitroExpose)
31
32
 
@@ -35,6 +36,8 @@ Dynamic: summary
35
36
  **NitroExpose** is an advanced CLI tool that allows you to **instantly expose any local port to your custom domain,**
36
37
  **automatic SSL installation** Powered by Let's Encrypt.
37
38
 
39
+ If You Don't Have Domain, No Problem We Also Provide Free Subdomain To Host Your Local Port Service On Subdomain With Https.
40
+
38
41
  It provides a **one-command deployment system** for developers who want to run their local apps (Flask, FastAPI, Node.js, etc.) directly on a live domain without manually configuring NGINX or DNS records.
39
42
 
40
43
 
@@ -56,21 +59,12 @@ It provides a **one-command deployment system** for developers who want to run t
56
59
  - **apt** Package Manager Required
57
60
 
58
61
 
59
- ## 🌐 Module installation
62
+ ## 🌊 Module installation
60
63
 
61
64
  ```bash
62
65
  pip install NitroExpose --break-system-packages
63
66
  ```
64
67
 
65
- ## 🌊 Optional installation
66
-
67
- ```bash
68
- sudo apt update -y
69
- sudo apt install nginx -y
70
- sudo apt install certbot -y
71
- sudo apt install python3-certbot-nginx -y
72
- ```
73
-
74
68
  ## 🧭 Usage Guide
75
69
 
76
70
  Step 1 – Point Your Vps/Server IP in Your Domain Records:
@@ -80,25 +74,55 @@ Step 1 – Point Your Vps/Server IP in Your Domain Records:
80
74
  **IPv4**: Your Vps Server IP
81
75
  **TTL**: Auto
82
76
 
83
-
84
77
  Step 2 – **Launch NitroExpose**
85
78
  ```bash
86
79
  NitroExpose
87
80
  ```
88
81
 
89
-
90
82
  Step 3 – **Enter Your Domain Or Subdomain**
91
83
  ```bash
92
84
  ┌─╼ Enter Domain Or Subdomain
93
85
  └────╼ ❯❯❯ myproject.example.com
94
86
  ```
95
87
 
96
-
97
- Step 4 – **Enter the Local Port to Expose**
88
+ Step 4 – **Enter Your Local Port to Expose**
98
89
  ```bash
99
90
  ┌─╼ Enter Port To Expose
100
91
  └────╼ ❯❯❯ 8000
101
92
  ```
102
93
 
94
+ ✨ **Now it Will Take 8 to 9 Seconds For Verification And Then Boom! Your Local Port Successfully Exposed To Your Public Domain/Subdomain**.
103
95
 
104
- **Now it Will Take 8 to 9 Seconds For Verification And Then Boom! Your Local Port Successfully Exposed To Your Public Domain/Subdomain**.
96
+ ## 🌐 Host On Free Subdomain (Cloudflared).
97
+
98
+ Step 1 – **Launch NitroExpose With FreeHost**
99
+ ```bash
100
+ NitroExpose --freehost
101
+ ```
102
+
103
+ Step 2 – **Enter Your Local Port To Expose On Subdomain**
104
+ ```bash
105
+ ┌─╼ Enter Port To Expose
106
+ └────╼ ❯❯❯ 8001
107
+ ```
108
+
109
+ ✨ **Now it Will Take 8 to 9 Seconds To Connect CloudServer And Then Your Service Successfully Exposed To Our Subdomain With 24/7.**
110
+
111
+
112
+ ## 🎯 To Remove Domain/Subdomain
113
+
114
+ ```bash
115
+ NitroExpose remove <domain/subdomain>
116
+ ```
117
+
118
+ ## 🎯 Domain/Subdomain Remove Example
119
+
120
+ ```bash
121
+ NitroExpose remove myproject.example.com
122
+ ```
123
+
124
+ ## To Check Package Version
125
+
126
+ ```bash
127
+ NitroExpose --v
128
+ ```
@@ -0,0 +1,2 @@
1
+ requests
2
+ supercore
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NitroExpose
3
- Version: 2.0
3
+ Version: 2.2
4
4
  Summary: Advanced CLI To Expose Port To Your Domain.
5
5
  Home-page: https://github.com/yuvrajmodz/NitroExpose
6
6
  Author: @NacDevs
@@ -12,6 +12,7 @@ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: requests
15
+ Requires-Dist: supercore
15
16
  Dynamic: author
16
17
  Dynamic: author-email
17
18
  Dynamic: classifier
@@ -25,7 +26,7 @@ Dynamic: summary
25
26
 
26
27
  ## NitroExpose
27
28
 
28
- **Letest Version:** 2.0
29
+ **Letest Version:** 2.2
29
30
  **Developer:** @Nactire
30
31
  **Git Repo:** [NitroExpose](https://github.com/yuvrajmodz/NitroExpose)
31
32
 
@@ -35,6 +36,8 @@ Dynamic: summary
35
36
  **NitroExpose** is an advanced CLI tool that allows you to **instantly expose any local port to your custom domain,**
36
37
  **automatic SSL installation** Powered by Let's Encrypt.
37
38
 
39
+ If You Don't Have Domain, No Problem We Also Provide Free Subdomain To Host Your Local Port Service On Subdomain With Https.
40
+
38
41
  It provides a **one-command deployment system** for developers who want to run their local apps (Flask, FastAPI, Node.js, etc.) directly on a live domain without manually configuring NGINX or DNS records.
39
42
 
40
43
 
@@ -56,21 +59,12 @@ It provides a **one-command deployment system** for developers who want to run t
56
59
  - **apt** Package Manager Required
57
60
 
58
61
 
59
- ## 🌐 Module installation
62
+ ## 🌊 Module installation
60
63
 
61
64
  ```bash
62
65
  pip install NitroExpose --break-system-packages
63
66
  ```
64
67
 
65
- ## 🌊 Optional installation
66
-
67
- ```bash
68
- sudo apt update -y
69
- sudo apt install nginx -y
70
- sudo apt install certbot -y
71
- sudo apt install python3-certbot-nginx -y
72
- ```
73
-
74
68
  ## 🧭 Usage Guide
75
69
 
76
70
  Step 1 – Point Your Vps/Server IP in Your Domain Records:
@@ -80,25 +74,55 @@ Step 1 – Point Your Vps/Server IP in Your Domain Records:
80
74
  **IPv4**: Your Vps Server IP
81
75
  **TTL**: Auto
82
76
 
83
-
84
77
  Step 2 – **Launch NitroExpose**
85
78
  ```bash
86
79
  NitroExpose
87
80
  ```
88
81
 
89
-
90
82
  Step 3 – **Enter Your Domain Or Subdomain**
91
83
  ```bash
92
84
  ┌─╼ Enter Domain Or Subdomain
93
85
  └────╼ ❯❯❯ myproject.example.com
94
86
  ```
95
87
 
96
-
97
- Step 4 – **Enter the Local Port to Expose**
88
+ Step 4 – **Enter Your Local Port to Expose**
98
89
  ```bash
99
90
  ┌─╼ Enter Port To Expose
100
91
  └────╼ ❯❯❯ 8000
101
92
  ```
102
93
 
94
+ ✨ **Now it Will Take 8 to 9 Seconds For Verification And Then Boom! Your Local Port Successfully Exposed To Your Public Domain/Subdomain**.
103
95
 
104
- **Now it Will Take 8 to 9 Seconds For Verification And Then Boom! Your Local Port Successfully Exposed To Your Public Domain/Subdomain**.
96
+ ## 🌐 Host On Free Subdomain (Cloudflared).
97
+
98
+ Step 1 – **Launch NitroExpose With FreeHost**
99
+ ```bash
100
+ NitroExpose --freehost
101
+ ```
102
+
103
+ Step 2 – **Enter Your Local Port To Expose On Subdomain**
104
+ ```bash
105
+ ┌─╼ Enter Port To Expose
106
+ └────╼ ❯❯❯ 8001
107
+ ```
108
+
109
+ ✨ **Now it Will Take 8 to 9 Seconds To Connect CloudServer And Then Your Service Successfully Exposed To Our Subdomain With 24/7.**
110
+
111
+
112
+ ## 🎯 To Remove Domain/Subdomain
113
+
114
+ ```bash
115
+ NitroExpose remove <domain/subdomain>
116
+ ```
117
+
118
+ ## 🎯 Domain/Subdomain Remove Example
119
+
120
+ ```bash
121
+ NitroExpose remove myproject.example.com
122
+ ```
123
+
124
+ ## To Check Package Version
125
+
126
+ ```bash
127
+ NitroExpose --v
128
+ ```
@@ -1,6 +1,6 @@
1
1
  ## NitroExpose
2
2
 
3
- **Letest Version:** 2.0
3
+ **Letest Version:** 2.2
4
4
  **Developer:** @Nactire
5
5
  **Git Repo:** [NitroExpose](https://github.com/yuvrajmodz/NitroExpose)
6
6
 
@@ -10,6 +10,8 @@
10
10
  **NitroExpose** is an advanced CLI tool that allows you to **instantly expose any local port to your custom domain,**
11
11
  **automatic SSL installation** Powered by Let's Encrypt.
12
12
 
13
+ If You Don't Have Domain, No Problem We Also Provide Free Subdomain To Host Your Local Port Service On Subdomain With Https.
14
+
13
15
  It provides a **one-command deployment system** for developers who want to run their local apps (Flask, FastAPI, Node.js, etc.) directly on a live domain without manually configuring NGINX or DNS records.
14
16
 
15
17
 
@@ -31,21 +33,12 @@ It provides a **one-command deployment system** for developers who want to run t
31
33
  - **apt** Package Manager Required
32
34
 
33
35
 
34
- ## 🌐 Module installation
36
+ ## 🌊 Module installation
35
37
 
36
38
  ```bash
37
39
  pip install NitroExpose --break-system-packages
38
40
  ```
39
41
 
40
- ## 🌊 Optional installation
41
-
42
- ```bash
43
- sudo apt update -y
44
- sudo apt install nginx -y
45
- sudo apt install certbot -y
46
- sudo apt install python3-certbot-nginx -y
47
- ```
48
-
49
42
  ## 🧭 Usage Guide
50
43
 
51
44
  Step 1 – Point Your Vps/Server IP in Your Domain Records:
@@ -55,25 +48,55 @@ Step 1 – Point Your Vps/Server IP in Your Domain Records:
55
48
  **IPv4**: Your Vps Server IP
56
49
  **TTL**: Auto
57
50
 
58
-
59
51
  Step 2 – **Launch NitroExpose**
60
52
  ```bash
61
53
  NitroExpose
62
54
  ```
63
55
 
64
-
65
56
  Step 3 – **Enter Your Domain Or Subdomain**
66
57
  ```bash
67
58
  ┌─╼ Enter Domain Or Subdomain
68
59
  └────╼ ❯❯❯ myproject.example.com
69
60
  ```
70
61
 
71
-
72
- Step 4 – **Enter the Local Port to Expose**
62
+ Step 4 – **Enter Your Local Port to Expose**
73
63
  ```bash
74
64
  ┌─╼ Enter Port To Expose
75
65
  └────╼ ❯❯❯ 8000
76
66
  ```
77
67
 
68
+ ✨ **Now it Will Take 8 to 9 Seconds For Verification And Then Boom! Your Local Port Successfully Exposed To Your Public Domain/Subdomain**.
69
+
70
+ ## 🌐 Host On Free Subdomain (Cloudflared).
71
+
72
+ Step 1 – **Launch NitroExpose With FreeHost**
73
+ ```bash
74
+ NitroExpose --freehost
75
+ ```
76
+
77
+ Step 2 – **Enter Your Local Port To Expose On Subdomain**
78
+ ```bash
79
+ ┌─╼ Enter Port To Expose
80
+ └────╼ ❯❯❯ 8001
81
+ ```
82
+
83
+ ✨ **Now it Will Take 8 to 9 Seconds To Connect CloudServer And Then Your Service Successfully Exposed To Our Subdomain With 24/7.**
84
+
85
+
86
+ ## 🎯 To Remove Domain/Subdomain
87
+
88
+ ```bash
89
+ NitroExpose remove <domain/subdomain>
90
+ ```
91
+
92
+ ## 🎯 Domain/Subdomain Remove Example
78
93
 
79
- ✨ **Now it Will Take 8 to 9 Seconds For Verification And Then Boom! Your Local Port Successfully Exposed To Your Public Domain/Subdomain**.
94
+ ```bash
95
+ NitroExpose remove myproject.example.com
96
+ ```
97
+
98
+ ## To Check Package Version
99
+
100
+ ```bash
101
+ NitroExpose --v
102
+ ```
@@ -0,0 +1,564 @@
1
+ import os
2
+ import subprocess
3
+ import sys
4
+ import re
5
+ import termios
6
+ import tty
7
+ import select
8
+ import time
9
+ import requests
10
+ import signal
11
+ import socket
12
+ import importlib.metadata
13
+ import random
14
+ import string
15
+ import threading
16
+
17
+ # cli.py (Main File)
18
+ # 𝗠𝗮𝗻𝗮𝗴𝗲𝗱 𝗕𝘆 @Nactire
19
+
20
+ def print_green(text):
21
+ print("\033[1;32m" + text + "\033[0m")
22
+
23
+ def print_red(text):
24
+ print("\033[1;31m" + text + "\033[0m")
25
+
26
+ def print_yellow(text):
27
+ print("\033[1;33m" + text + "\033[0m")
28
+
29
+ def print_turquoise(text):
30
+ print("\033[38;2;0;255;234m" + text + "\033[0m")
31
+
32
+ def get_version():
33
+ try:
34
+ version = importlib.metadata.version('nitroexpose')
35
+ return version
36
+ except importlib.metadata.PackageNotFoundError:
37
+ return "Unknown"
38
+
39
+ def run_command(cmd):
40
+ process = subprocess.Popen(
41
+ cmd,
42
+ shell=True,
43
+ stdout=subprocess.DEVNULL,
44
+ stderr=subprocess.DEVNULL
45
+ )
46
+ process.wait()
47
+ return process.returncode
48
+
49
+ def is_installed(cmd):
50
+ return subprocess.call(
51
+ f"{cmd} > /dev/null 2>&1",
52
+ shell=True,
53
+ stdout=subprocess.DEVNULL,
54
+ stderr=subprocess.DEVNULL
55
+ ) == 0
56
+
57
+ def is_certbot_nginx_plugin_installed():
58
+ try:
59
+ result = subprocess.check_output(
60
+ "dpkg -l | grep python3-certbot-nginx",
61
+ shell=True,
62
+ text=True,
63
+ stderr=subprocess.DEVNULL
64
+ )
65
+ return "python3-certbot-nginx" in result
66
+ except subprocess.CalledProcessError:
67
+ return False
68
+
69
+ def is_port_listening(port):
70
+ try:
71
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
72
+ sock.settimeout(2)
73
+ result = sock.connect_ex(('127.0.0.1', int(port)))
74
+ sock.close()
75
+ return result == 0
76
+ except Exception:
77
+ return False
78
+
79
+ def get_system_architecture():
80
+ try:
81
+ result = subprocess.check_output("uname -m", shell=True, text=True).strip()
82
+ return result
83
+ except Exception:
84
+ return None
85
+
86
+ def generate_random_process_name():
87
+ letters = ''.join(random.choices(string.ascii_lowercase, k=5))
88
+ numbers = ''.join(random.choices(string.digits, k=5))
89
+ return letters + numbers
90
+
91
+ def restricted_input(prompt, allowed_pattern):
92
+ def handle_sigint(signum, frame):
93
+ print("\n\n")
94
+ sys.exit(1)
95
+
96
+ signal.signal(signal.SIGINT, handle_sigint)
97
+
98
+ sys.stdout.write("\033[1;32m" + prompt + "\033[0m")
99
+ sys.stdout.flush()
100
+
101
+ fd = sys.stdin.fileno()
102
+ old_settings = termios.tcgetattr(fd)
103
+ tty.setraw(fd)
104
+
105
+ buffer = ""
106
+ try:
107
+ while True:
108
+ r, _, _ = select.select([fd], [], [], 0)
109
+ if r:
110
+ ch = sys.stdin.read(1)
111
+ if ch == "\n" or ch == "\r":
112
+ print()
113
+ break
114
+ elif ch == "\x03":
115
+ raise KeyboardInterrupt
116
+ elif ch == "\x7f":
117
+ if buffer:
118
+ buffer = buffer[:-1]
119
+ sys.stdout.write("\b \b")
120
+ sys.stdout.flush()
121
+ elif re.match(allowed_pattern, ch):
122
+ buffer += ch
123
+ sys.stdout.write(ch)
124
+ sys.stdout.flush()
125
+ except KeyboardInterrupt:
126
+ print("\n\n")
127
+ sys.exit(1)
128
+ finally:
129
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
130
+ return buffer
131
+
132
+ def install_and_verify_package(package_name, check_cmd, install_cmds):
133
+ print_green(f"Installing {package_name} ...")
134
+
135
+ for cmd in install_cmds:
136
+ run_command(cmd)
137
+
138
+ if check_cmd():
139
+ print_green(f"{package_name} installed.")
140
+ return True
141
+ else:
142
+ print_red(f"{package_name} installing Error.")
143
+ sys.exit(1)
144
+
145
+ def is_valid_domain(domain):
146
+ if "http://" in domain or "https://" in domain or " " in domain:
147
+ return False
148
+
149
+ if "." not in domain:
150
+ return False
151
+
152
+ pattern = r'^[a-zA-Z0-9\.\-]+$'
153
+ if not re.match(pattern, domain):
154
+ return False
155
+
156
+ return True
157
+
158
+ def is_subdomain(domain):
159
+ parts = domain.split(".")
160
+ return len(parts) > 2
161
+
162
+ def remove_domain(domain):
163
+ if os.geteuid() != 0:
164
+ print_red("\nPlease Use Root Environment.\n")
165
+ sys.exit(1)
166
+
167
+ if not is_valid_domain(domain):
168
+ print_red("\nDomain Format Not Valid.\n")
169
+ sys.exit(1)
170
+
171
+ if not is_installed("nginx -v"):
172
+ install_and_verify_package(
173
+ "NGINX",
174
+ lambda: is_installed("nginx -v"),
175
+ [
176
+ "sudo apt update -o Acquire::AllowInsecureRepositories=true",
177
+ "sudo apt install -y nginx",
178
+ "sudo systemctl start nginx",
179
+ "sudo systemctl enable nginx"
180
+ ]
181
+ )
182
+ else:
183
+ print_green("NGINX installed.")
184
+
185
+ if not is_installed("certbot --version"):
186
+ install_and_verify_package(
187
+ "Certbot",
188
+ lambda: is_installed("certbot --version"),
189
+ [
190
+ "sudo apt update -o Acquire::AllowInsecureRepositories=true",
191
+ "sudo apt install -y certbot python3-certbot-nginx"
192
+ ]
193
+ )
194
+ else:
195
+ print_green("Certbot installed.")
196
+
197
+ if not is_certbot_nginx_plugin_installed():
198
+ install_and_verify_package(
199
+ "python3-certbot-nginx plugin",
200
+ is_certbot_nginx_plugin_installed,
201
+ [
202
+ "sudo apt update -o Acquire::AllowInsecureRepositories=true",
203
+ "sudo apt install -y python3-certbot-nginx"
204
+ ]
205
+ )
206
+ else:
207
+ print_green("python3-certbot-nginx plugin installed.")
208
+
209
+ print("\n")
210
+
211
+ available_path = f"/etc/nginx/sites-available/{domain}"
212
+ enabled_path = f"/etc/nginx/sites-enabled/{domain}"
213
+
214
+ available_exists = os.path.exists(available_path)
215
+ enabled_exists = os.path.exists(enabled_path)
216
+
217
+ domain_type = "Subdomain" if is_subdomain(domain) else "Domain"
218
+
219
+ if not available_exists and not enabled_exists:
220
+ run_command(f"sudo rm -f {available_path}")
221
+ run_command(f"sudo rm -f {enabled_path}")
222
+ run_command("sudo systemctl reload nginx")
223
+ print_red(f"Targeted {domain_type} Doesn't Exist in Your Server.\n")
224
+ sys.exit(1)
225
+ elif not available_exists or not enabled_exists:
226
+ run_command(f"sudo rm -f {available_path}")
227
+ run_command(f"sudo rm -f {enabled_path}")
228
+ run_command("sudo systemctl reload nginx")
229
+ print_red(f"Targeted {domain_type} Doesn't Exist in Your Server.\n")
230
+ sys.exit(1)
231
+ else:
232
+ run_command(f"sudo rm -f {available_path}")
233
+ run_command(f"sudo rm -f {enabled_path}")
234
+ run_command("sudo systemctl reload nginx")
235
+ print_green(f"\n{domain_type} Removed Successfully.\n")
236
+ sys.exit(0)
237
+
238
+ def freehost_mode():
239
+ if os.geteuid() != 0:
240
+ print_red("\nPlease Use Root Environment.\n")
241
+ sys.exit(1)
242
+
243
+ if not is_installed("expect -v"):
244
+ print_green("Installing Expect ...")
245
+ run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
246
+ run_command("sudo apt install -y expect")
247
+
248
+ if not is_installed("expect -v"):
249
+ print_red("Expect installing Error.")
250
+ sys.exit(1)
251
+ print_green("Expect installed.")
252
+
253
+ if not is_installed("cloudflared --version"):
254
+ print_green("Installing CloudServer ...")
255
+
256
+ arch = get_system_architecture()
257
+
258
+ if arch in ["x86_64", "aarch64"]:
259
+ install_cmds = [
260
+ "wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64",
261
+ "chmod +x cloudflared-linux-amd64",
262
+ "sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared"
263
+ ]
264
+ elif arch in ["armv7l", "armhf"]:
265
+ install_cmds = [
266
+ "wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm",
267
+ "chmod +x cloudflared-linux-arm",
268
+ "sudo mv cloudflared-linux-arm /usr/local/bin/cloudflared"
269
+ ]
270
+ else:
271
+ print_red("Unsupported architecture.")
272
+ sys.exit(1)
273
+
274
+ for cmd in install_cmds:
275
+ run_command(cmd)
276
+
277
+ if is_installed("cloudflared --version"):
278
+ print_green("CloudServer installed.")
279
+ else:
280
+ print_red("CloudServer installing Error.")
281
+ sys.exit(1)
282
+ else:
283
+ print_green("CloudServer installed.")
284
+
285
+ print("\n")
286
+
287
+ print_turquoise("┌─╼ Enter Port To Expose")
288
+ port = restricted_input("\033[38;2;0;255;234m└────╼ ❯❯❯ \033[0m", r"[0-9]+")
289
+
290
+ print("\n")
291
+
292
+ if not is_port_listening(port):
293
+ print_red("Port Not Listening, Operation Failed.")
294
+ sys.exit(1)
295
+
296
+ process_name = generate_random_process_name()
297
+
298
+ expect_script = f"""#!/usr/bin/expect -f
299
+ set timeout 20
300
+ spawn supercore cloudflared tunnel --url http://localhost:{port}
301
+ expect "└────╼ ❯❯❯"
302
+ send "{process_name}\\r"
303
+ expect eof
304
+ """
305
+
306
+ script_path = f"/tmp/cloudflared_tunnel_{port}.exp"
307
+ with open(script_path, "w") as f:
308
+ f.write(expect_script)
309
+
310
+ os.chmod(script_path, 0o755)
311
+
312
+ try:
313
+ process = subprocess.Popen(
314
+ [script_path],
315
+ stdout=subprocess.PIPE,
316
+ stderr=subprocess.STDOUT,
317
+ text=True,
318
+ bufsize=1
319
+ )
320
+
321
+ output_lines = []
322
+ url_found = False
323
+ extracted_url = None
324
+
325
+ print_yellow("Connecting to CloudServer...")
326
+
327
+ start_time = time.time()
328
+ while time.time() - start_time < 15:
329
+ line = process.stdout.readline()
330
+ if line:
331
+ output_lines.append(line)
332
+ url_pattern = r'https://[a-z0-9\-]+\.trycloudflare\.com'
333
+ match = re.search(url_pattern, line)
334
+ if match:
335
+ extracted_url = match.group(0)
336
+ url_found = True
337
+ break
338
+
339
+ if process.poll() is not None:
340
+ break
341
+
342
+ time.sleep(0.1)
343
+
344
+ if not url_found:
345
+ remaining = process.stdout.read()
346
+ if remaining:
347
+ output_lines.append(remaining)
348
+ full_output = ''.join(output_lines)
349
+ url_pattern = r'https://[a-z0-9\-]+\.trycloudflare\.com'
350
+ match = re.search(url_pattern, full_output)
351
+ if match:
352
+ extracted_url = match.group(0)
353
+ url_found = True
354
+
355
+ process.wait()
356
+
357
+ if url_found and extracted_url:
358
+ print("\n")
359
+ print_green(f"Exposed Successfully On Free Subdomain.\n")
360
+ print_green(f"Exposed On: {extracted_url}\n")
361
+ print_green(f"Port: {port}\n")
362
+ print_green(f"SSL Installed Using Google Trust Services\n")
363
+ print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -")
364
+ print_yellow(f"If You Like NitroExpose, Please Support Us by:\n")
365
+ print_yellow(f" * Join Our Telegram Channel: https://t.me/NacDevs")
366
+ print_yellow(f" * Please Star Our Project: https://github.com/yuvrajmodz/NitroExpose")
367
+ print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n")
368
+ sys.exit(0)
369
+ else:
370
+ print_red("Server is Busy, Try Again Later.")
371
+ os.remove(script_path)
372
+ sys.exit(1)
373
+
374
+ except Exception as e:
375
+ print_red("Server is Busy, Try Again Later.")
376
+ if os.path.exists(script_path):
377
+ os.remove(script_path)
378
+ sys.exit(1)
379
+
380
+ def main():
381
+ if len(sys.argv) == 2 and sys.argv[1] in ["-v", "--v"]:
382
+ version = get_version()
383
+ print_green(f"V{version}")
384
+ sys.exit(0)
385
+
386
+ if len(sys.argv) == 2 and sys.argv[1] == "--freehost":
387
+ freehost_mode()
388
+ return
389
+
390
+ if len(sys.argv) == 3 and sys.argv[1] == "remove":
391
+ domain = sys.argv[2]
392
+ remove_domain(domain)
393
+ return
394
+
395
+ if os.geteuid() != 0:
396
+ print_red("\nPlease Use Root Environment.\n")
397
+ sys.exit(1)
398
+
399
+ if not is_installed("nginx -v"):
400
+ install_and_verify_package(
401
+ "NGINX",
402
+ lambda: is_installed("nginx -v"),
403
+ [
404
+ "sudo apt update -o Acquire::AllowInsecureRepositories=true",
405
+ "sudo apt install -y nginx",
406
+ "sudo systemctl start nginx",
407
+ "sudo systemctl enable nginx"
408
+ ]
409
+ )
410
+ else:
411
+ print_green("NGINX installed.")
412
+
413
+ if not is_installed("certbot --version"):
414
+ install_and_verify_package(
415
+ "Certbot",
416
+ lambda: is_installed("certbot --version"),
417
+ [
418
+ "sudo apt update -o Acquire::AllowInsecureRepositories=true",
419
+ "sudo apt install -y certbot python3-certbot-nginx"
420
+ ]
421
+ )
422
+ else:
423
+ print_green("Certbot installed.")
424
+
425
+ if not is_certbot_nginx_plugin_installed():
426
+ install_and_verify_package(
427
+ "python3-certbot-nginx plugin",
428
+ is_certbot_nginx_plugin_installed,
429
+ [
430
+ "sudo apt update -o Acquire::AllowInsecureRepositories=true",
431
+ "sudo apt install -y python3-certbot-nginx"
432
+ ]
433
+ )
434
+ else:
435
+ print_green("python3-certbot-nginx plugin installed.")
436
+
437
+ print("\n")
438
+
439
+ print_turquoise("┌─╼ Enter Domain Or Subdomain")
440
+ domain = restricted_input("\033[38;2;0;255;234m└────╼ ❯❯❯ \033[0m", r"[a-zA-Z0-9\.\-]")
441
+
442
+ print("\n")
443
+
444
+ if "." not in domain:
445
+ print_red("Domain is invalid, Operation Failed.")
446
+ sys.exit(1)
447
+
448
+ print_turquoise("┌─╼ Enter Port To Expose")
449
+ port = restricted_input("\033[38;2;0;255;234m└────╼ ❯❯❯ \033[0m", r"[0-9]+")
450
+
451
+ print("\n")
452
+
453
+ if not is_port_listening(port):
454
+ print_red("Port Not Listening, Operation Failed.")
455
+ sys.exit(1)
456
+
457
+ nginx_temp_conf = f"""
458
+ server {{
459
+ server_name {domain};
460
+
461
+ location /nitroverify/auth.txt {{
462
+ default_type text/plain;
463
+ return 200 "nitroverify-success";
464
+ }}
465
+
466
+ location / {{
467
+ return 404;
468
+ }}
469
+
470
+ listen 80;
471
+ }}
472
+ """
473
+ conf_path = f"/etc/nginx/sites-available/{domain}"
474
+ with open(conf_path, "w") as f:
475
+ f.write(nginx_temp_conf)
476
+
477
+ run_command(f"sudo ln -sf /etc/nginx/sites-available/{domain} /etc/nginx/sites-enabled/")
478
+ run_command("sudo systemctl reload nginx")
479
+
480
+ print_yellow("Domain verifying...")
481
+ time.sleep(5)
482
+
483
+ verified = False
484
+ for url in [f"http://{domain}/nitroverify/auth.txt", f"https://{domain}/nitroverify/auth.txt"]:
485
+ try:
486
+ r = requests.get(url, timeout=5)
487
+ if "nitroverify-success" in r.text:
488
+ verified = True
489
+ break
490
+ except Exception:
491
+ continue
492
+
493
+ if not verified:
494
+ print_red("Domain Verification Failed, Check Records Carefully.")
495
+ run_command(f"sudo rm -f /etc/nginx/sites-available/{domain}")
496
+ run_command(f"sudo rm -f /etc/nginx/sites-enabled/{domain}")
497
+ run_command("sudo systemctl reload nginx")
498
+ sys.exit(1)
499
+
500
+ print_green("Domain Verification Success.\n")
501
+
502
+ run_command(f"sudo rm -f /etc/nginx/sites-available/{domain}")
503
+ run_command(f"sudo rm -f /etc/nginx/sites-enabled/{domain}")
504
+ run_command("sudo systemctl reload nginx")
505
+
506
+ print_yellow("SSL Cert installing...")
507
+
508
+ nginx_conf = f"""
509
+ server {{
510
+ server_name {domain};
511
+
512
+ location / {{
513
+ proxy_pass http://127.0.0.1:{port};
514
+ proxy_set_header Host $host;
515
+ proxy_set_header X-Real-IP $remote_addr;
516
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
517
+ proxy_set_header X-Forwarded-Proto $scheme;
518
+ }}
519
+
520
+ listen 80;
521
+ }}
522
+ """
523
+ conf_path = f"/etc/nginx/sites-available/{domain}"
524
+ with open(conf_path, "w") as f:
525
+ f.write(nginx_conf)
526
+
527
+ run_command(f"sudo ln -sf /etc/nginx/sites-available/{domain} /etc/nginx/sites-enabled/")
528
+ run_command("sudo systemctl reload nginx")
529
+
530
+ run_command(f"sudo certbot --nginx -d {domain} --non-interactive --agree-tos --email nitroexpose@gmail.com")
531
+ run_command("sudo systemctl reload nginx")
532
+
533
+ print_yellow("SSL Certificate Checking...")
534
+ time.sleep(2)
535
+
536
+ ssl_installed = False
537
+ try:
538
+ r = requests.get(f"https://{domain}", timeout=10)
539
+ if r.status_code == 200:
540
+ ssl_installed = True
541
+ except requests.exceptions.SSLError:
542
+ ssl_installed = False
543
+ except requests.exceptions.RequestException:
544
+ ssl_installed = False
545
+
546
+ print("\n")
547
+ if ssl_installed:
548
+ print_green(f"Exposed Successfully On Your Domain\n")
549
+ print_green(f"Exposed On: https://{domain}\n")
550
+ print_green(f"Port: {port}\n")
551
+ print_green(f"SSL Installed Using Let's Encrypt.\n")
552
+ print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -")
553
+ print_yellow(f"If You Like NitroExpose, Please Support Us by:\n")
554
+ print_yellow(f" * Join Our Telegram Channel: https://t.me/NacDevs")
555
+ print_yellow(f" * Please Star Our Project: https://github.com/yuvrajmodz/NitroExpose")
556
+ print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n")
557
+ else:
558
+ print_green(f"Exposed Successfully On Your Domain\n")
559
+ print_green(f"Exposed On: http://{domain}\n")
560
+ print_green(f"Port: {port}\n")
561
+ print_yellow(f"Unfortunately, please verify your records carefully. Your server is exposed on your domain, and we are experiencing difficulties while attempting to install an SSL certificate.\n\n")
562
+
563
+ if __name__ == "__main__":
564
+ main()
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="NitroExpose",
5
- version="2.0",
5
+ version="2.2",
6
6
  author="@NacDevs",
7
7
  author_email="yuvrajmodz@gmail.com",
8
8
  description="Advanced CLI To Expose Port To Your Domain.",
@@ -12,7 +12,8 @@ setup(
12
12
  packages=find_packages(),
13
13
  python_requires='>=3.8',
14
14
  install_requires=[
15
- "requests"
15
+ "requests",
16
+ "supercore"
16
17
  ],
17
18
  entry_points={
18
19
  'console_scripts': [
@@ -1 +0,0 @@
1
- requests
@@ -1,247 +0,0 @@
1
- import os
2
- import subprocess
3
- import sys
4
- import re
5
- import termios
6
- import tty
7
- import select
8
- import time
9
- import requests
10
- import signal
11
- import socket
12
-
13
- # 𝗠𝗮𝗻𝗮𝗴𝗲𝗱 𝗕𝘆 @Nactire
14
-
15
- def print_green(text):
16
- print("\033[1;32m" + text + "\033[0m")
17
-
18
- def print_red(text):
19
- print("\033[1;31m" + text + "\033[0m")
20
-
21
- def print_yellow(text):
22
- print("\033[1;33m" + text + "\033[0m")
23
-
24
- def print_turquoise(text):
25
- print("\033[38;2;0;255;234m" + text + "\033[0m")
26
-
27
- def run_command(cmd):
28
- process = subprocess.Popen(cmd, shell=True)
29
- process.wait()
30
- return process.returncode
31
-
32
- def is_installed(cmd):
33
- return subprocess.call(f"{cmd} > /dev/null 2>&1", shell=True) == 0
34
-
35
- def is_certbot_nginx_plugin_installed():
36
- try:
37
- result = subprocess.check_output(
38
- "dpkg -l | grep python3-certbot-nginx", shell=True, text=True
39
- )
40
- return "python3-certbot-nginx" in result
41
- except subprocess.CalledProcessError:
42
- return False
43
-
44
- def is_port_listening(port):
45
- try:
46
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
47
- sock.settimeout(2)
48
- result = sock.connect_ex(('127.0.0.1', int(port)))
49
- sock.close()
50
- return result == 0
51
- except Exception:
52
- return False
53
-
54
- def restricted_input(prompt, allowed_pattern):
55
- def handle_sigint(signum, frame):
56
- print("\n\n")
57
- sys.exit(1)
58
-
59
- signal.signal(signal.SIGINT, handle_sigint)
60
-
61
- sys.stdout.write("\033[1;32m" + prompt + "\033[0m")
62
- sys.stdout.flush()
63
-
64
- fd = sys.stdin.fileno()
65
- old_settings = termios.tcgetattr(fd)
66
- tty.setraw(fd)
67
-
68
- buffer = ""
69
- try:
70
- while True:
71
- r, _, _ = select.select([fd], [], [], 0)
72
- if r:
73
- ch = sys.stdin.read(1)
74
- if ch == "\n" or ch == "\r":
75
- print()
76
- break
77
- elif ch == "\x03":
78
- raise KeyboardInterrupt
79
- elif ch == "\x7f":
80
- if buffer:
81
- buffer = buffer[:-1]
82
- sys.stdout.write("\b \b")
83
- sys.stdout.flush()
84
- elif re.match(allowed_pattern, ch):
85
- buffer += ch
86
- sys.stdout.write(ch)
87
- sys.stdout.flush()
88
- except KeyboardInterrupt:
89
- print("\n\n")
90
- sys.exit(1)
91
- finally:
92
- termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
93
- return buffer
94
-
95
- def main():
96
- if os.geteuid() != 0:
97
- print_red("\nPlease Use Root Environment.\n")
98
- sys.exit(1)
99
-
100
- if not is_installed("nginx -v"):
101
- print_green("Installing NGINX ...")
102
- run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
103
- run_command("sudo apt install -y nginx")
104
- run_command("sudo systemctl start nginx")
105
- run_command("sudo systemctl enable nginx")
106
- else:
107
- print_green("NGINX installed.")
108
-
109
- if not is_installed("certbot --version"):
110
- print_green("Installing Certbot ...")
111
- run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
112
- run_command("sudo apt install -y certbot python3-certbot-nginx")
113
- else:
114
- print_green("Certbot installed.")
115
-
116
- if not is_certbot_nginx_plugin_installed():
117
- print_green("Installing python3-certbot-nginx plugin ...")
118
- run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
119
- run_command("sudo apt install -y python3-certbot-nginx")
120
- else:
121
- print_green("python3-certbot-nginx plugin installed.")
122
- print("\n")
123
-
124
- print_turquoise("┌─╼ Enter Domain Or Subdomain")
125
- domain = restricted_input("\033[38;2;0;255;234m└────╼ ❯❯❯ \033[0m", r"[a-zA-Z0-9\.\-]")
126
-
127
- print("\n")
128
-
129
- if "." not in domain:
130
- print_red("Domain is invalid, Operation Failed.")
131
- sys.exit(1)
132
-
133
- print_turquoise("┌─╼ Enter Port To Expose")
134
- port = restricted_input("\033[38;2;0;255;234m└────╼ ❯❯❯ \033[0m", r"[0-9]+")
135
-
136
- print("\n")
137
-
138
- if not is_port_listening(port):
139
- print_red("Port Not Listening, Operation Failed.")
140
- sys.exit(1)
141
-
142
- nginx_temp_conf = f"""
143
- server {{
144
- server_name {domain};
145
-
146
- location /nitroverify/auth.txt {{
147
- default_type text/plain;
148
- return 200 "nitroverify-success";
149
- }}
150
-
151
- location / {{
152
- return 404;
153
- }}
154
-
155
- listen 80;
156
- }}
157
- """
158
- conf_path = f"/etc/nginx/sites-available/{domain}"
159
- with open(conf_path, "w") as f:
160
- f.write(nginx_temp_conf)
161
-
162
- run_command(f"sudo ln -sf /etc/nginx/sites-available/{domain} /etc/nginx/sites-enabled/")
163
- run_command("sudo systemctl reload nginx")
164
-
165
- print_yellow("Domain verifying...")
166
- time.sleep(5)
167
-
168
- verified = False
169
- for url in [f"http://{domain}/nitroverify/auth.txt", f"https://{domain}/nitroverify/auth.txt"]:
170
- try:
171
- r = requests.get(url, timeout=5)
172
- if "nitroverify-success" in r.text:
173
- verified = True
174
- break
175
- except Exception:
176
- continue
177
-
178
- if not verified:
179
- print_red("Domain Verification Failed, Check Records Carefully.")
180
- run_command(f"sudo rm -f /etc/nginx/sites-available/{domain}")
181
- run_command(f"sudo rm -f /etc/nginx/sites-enabled/{domain}")
182
- run_command("sudo systemctl reload nginx")
183
- sys.exit(1)
184
-
185
- print_green("Domain Verification Success.\n")
186
-
187
- run_command(f"sudo rm -f /etc/nginx/sites-available/{domain}")
188
- run_command(f"sudo rm -f /etc/nginx/sites-enabled/{domain}")
189
- run_command("sudo systemctl reload nginx")
190
-
191
- nginx_conf = f"""
192
- server {{
193
- server_name {domain};
194
-
195
- location / {{
196
- proxy_pass http://127.0.0.1:{port};
197
- proxy_set_header Host $host;
198
- proxy_set_header X-Real-IP $remote_addr;
199
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
200
- proxy_set_header X-Forwarded-Proto $scheme;
201
- }}
202
-
203
- listen 80;
204
- }}
205
- """
206
- conf_path = f"/etc/nginx/sites-available/{domain}"
207
- with open(conf_path, "w") as f:
208
- f.write(nginx_conf)
209
-
210
- run_command(f"sudo ln -sf /etc/nginx/sites-available/{domain} /etc/nginx/sites-enabled/")
211
- run_command("sudo systemctl reload nginx")
212
-
213
- run_command(f"sudo certbot --nginx -d {domain} --non-interactive --agree-tos --email nitroexpose@gmail.com")
214
- run_command("sudo systemctl reload nginx")
215
-
216
- print_yellow("\nSSL Certificate Checking...")
217
- time.sleep(2)
218
-
219
- ssl_installed = False
220
- try:
221
- r = requests.get(f"https://{domain}", timeout=10)
222
- if r.status_code == 200:
223
- ssl_installed = True
224
- except requests.exceptions.SSLError:
225
- ssl_installed = False
226
- except requests.exceptions.RequestException:
227
- ssl_installed = False
228
-
229
- print("\n")
230
- if ssl_installed:
231
- print_green(f"Exposed Successfully To Domain\n")
232
- print_green(f"Exposed On: https://{domain}\n")
233
- print_green(f"Port: {port}\n")
234
- print_green(f"SSL Installed Using Let's Encrypt.\n")
235
- print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -")
236
- print_yellow(f"If You Like NitroExpose, Please Support Us by:\n")
237
- print_yellow(f" * Join Our Telegram Channel: https://t.me/NacDevs")
238
- print_yellow(f" * Please Star Our Project: https://github.com/yuvrajmodz/NitroExpose")
239
- print_yellow(f"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n")
240
- else:
241
- print_green(f"Exposed Successfully To Domain\n")
242
- print_green(f"Exposed On: http://{domain}\n")
243
- print_green(f"Port: {port}\n")
244
- print_yellow(f"Unfortunately, please verify your records carefully. Your server is exposed on your domain, and we are experiencing difficulties while attempting to install an SSL certificate.\n\n")
245
-
246
- if __name__ == "__main__":
247
- main()
File without changes
File without changes
File without changes