NitroExpose 1.1__py3-none-any.whl
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.
- nitroexpose/__init__.py +3 -0
- nitroexpose/cli.py +239 -0
- nitroexpose-1.1.dist-info/METADATA +48 -0
- nitroexpose-1.1.dist-info/RECORD +8 -0
- nitroexpose-1.1.dist-info/WHEEL +5 -0
- nitroexpose-1.1.dist-info/entry_points.txt +2 -0
- nitroexpose-1.1.dist-info/licenses/LICENSE +7 -0
- nitroexpose-1.1.dist-info/top_level.txt +1 -0
nitroexpose/__init__.py
ADDED
nitroexpose/cli.py
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
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 run_command(cmd):
|
|
25
|
+
process = subprocess.Popen(cmd, shell=True)
|
|
26
|
+
process.wait()
|
|
27
|
+
return process.returncode
|
|
28
|
+
|
|
29
|
+
def is_installed(cmd):
|
|
30
|
+
return subprocess.call(f"{cmd} > /dev/null 2>&1", shell=True) == 0
|
|
31
|
+
|
|
32
|
+
def is_certbot_nginx_plugin_installed():
|
|
33
|
+
try:
|
|
34
|
+
result = subprocess.check_output(
|
|
35
|
+
"dpkg -l | grep python3-certbot-nginx", shell=True, text=True
|
|
36
|
+
)
|
|
37
|
+
return "python3-certbot-nginx" in result
|
|
38
|
+
except subprocess.CalledProcessError:
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
def is_port_listening(port):
|
|
42
|
+
try:
|
|
43
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
44
|
+
sock.settimeout(2)
|
|
45
|
+
result = sock.connect_ex(('127.0.0.1', int(port)))
|
|
46
|
+
sock.close()
|
|
47
|
+
return result == 0
|
|
48
|
+
except Exception:
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
def restricted_input(prompt, allowed_pattern):
|
|
52
|
+
def handle_sigint(signum, frame):
|
|
53
|
+
print("\n\n")
|
|
54
|
+
sys.exit(1)
|
|
55
|
+
|
|
56
|
+
signal.signal(signal.SIGINT, handle_sigint)
|
|
57
|
+
|
|
58
|
+
sys.stdout.write("\033[1;32m" + prompt + "\033[0m")
|
|
59
|
+
sys.stdout.flush()
|
|
60
|
+
|
|
61
|
+
fd = sys.stdin.fileno()
|
|
62
|
+
old_settings = termios.tcgetattr(fd)
|
|
63
|
+
tty.setraw(fd)
|
|
64
|
+
|
|
65
|
+
buffer = ""
|
|
66
|
+
try:
|
|
67
|
+
while True:
|
|
68
|
+
r, _, _ = select.select([fd], [], [], 0)
|
|
69
|
+
if r:
|
|
70
|
+
ch = sys.stdin.read(1)
|
|
71
|
+
if ch == "\n" or ch == "\r":
|
|
72
|
+
print()
|
|
73
|
+
break
|
|
74
|
+
elif ch == "\x03":
|
|
75
|
+
raise KeyboardInterrupt
|
|
76
|
+
elif ch == "\x7f":
|
|
77
|
+
if buffer:
|
|
78
|
+
buffer = buffer[:-1]
|
|
79
|
+
sys.stdout.write("\b \b")
|
|
80
|
+
sys.stdout.flush()
|
|
81
|
+
elif re.match(allowed_pattern, ch):
|
|
82
|
+
buffer += ch
|
|
83
|
+
sys.stdout.write(ch)
|
|
84
|
+
sys.stdout.flush()
|
|
85
|
+
except KeyboardInterrupt:
|
|
86
|
+
print("\n\n")
|
|
87
|
+
sys.exit(1)
|
|
88
|
+
finally:
|
|
89
|
+
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
|
90
|
+
return buffer
|
|
91
|
+
|
|
92
|
+
def main():
|
|
93
|
+
if os.geteuid() != 0:
|
|
94
|
+
print_red("Please Use Root Environment.")
|
|
95
|
+
sys.exit(1)
|
|
96
|
+
|
|
97
|
+
if not is_installed("nginx -v"):
|
|
98
|
+
print_green("Installing NGINX ...")
|
|
99
|
+
run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
|
|
100
|
+
run_command("sudo apt install -y nginx")
|
|
101
|
+
run_command("sudo systemctl start nginx")
|
|
102
|
+
run_command("sudo systemctl enable nginx")
|
|
103
|
+
else:
|
|
104
|
+
print_green("NGINX installed.")
|
|
105
|
+
|
|
106
|
+
if not is_installed("certbot --version"):
|
|
107
|
+
print_green("Installing Certbot ...")
|
|
108
|
+
run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
|
|
109
|
+
run_command("sudo apt install -y certbot python3-certbot-nginx")
|
|
110
|
+
else:
|
|
111
|
+
print_green("Certbot installed.")
|
|
112
|
+
|
|
113
|
+
if not is_certbot_nginx_plugin_installed():
|
|
114
|
+
print_green("Installing python3-certbot-nginx plugin ...")
|
|
115
|
+
run_command("sudo apt update -o Acquire::AllowInsecureRepositories=true")
|
|
116
|
+
run_command("sudo apt install -y python3-certbot-nginx")
|
|
117
|
+
else:
|
|
118
|
+
print_green("python3-certbot-nginx plugin installed.")
|
|
119
|
+
print("\n")
|
|
120
|
+
|
|
121
|
+
print_yellow("┌─╼ Enter Domain Or Subdomain")
|
|
122
|
+
domain = restricted_input("\033[1;33m└────╼ ❯❯❯ \033[0m", r"[a-zA-Z0-9\.\-]")
|
|
123
|
+
|
|
124
|
+
print("\n")
|
|
125
|
+
|
|
126
|
+
if "." not in domain:
|
|
127
|
+
print_red("Domain is invalid, Operation Failed.")
|
|
128
|
+
sys.exit(1)
|
|
129
|
+
|
|
130
|
+
print_yellow("┌─╼ Enter Port To Expose")
|
|
131
|
+
port = restricted_input("\033[1;33m└────╼ ❯❯❯ \033[0m", r"[0-9]+")
|
|
132
|
+
|
|
133
|
+
print("\n")
|
|
134
|
+
|
|
135
|
+
if not is_port_listening(port):
|
|
136
|
+
print_red("Port Not Listening, Operation Failed.")
|
|
137
|
+
sys.exit(1)
|
|
138
|
+
|
|
139
|
+
nginx_temp_conf = f"""
|
|
140
|
+
server {{
|
|
141
|
+
server_name {domain};
|
|
142
|
+
|
|
143
|
+
location /nitroverify/auth.txt {{
|
|
144
|
+
default_type text/plain;
|
|
145
|
+
return 200 "nitroverify-success";
|
|
146
|
+
}}
|
|
147
|
+
|
|
148
|
+
location / {{
|
|
149
|
+
return 404;
|
|
150
|
+
}}
|
|
151
|
+
|
|
152
|
+
listen 80;
|
|
153
|
+
}}
|
|
154
|
+
"""
|
|
155
|
+
conf_path = f"/etc/nginx/sites-available/{domain}"
|
|
156
|
+
with open(conf_path, "w") as f:
|
|
157
|
+
f.write(nginx_temp_conf)
|
|
158
|
+
|
|
159
|
+
run_command(f"sudo ln -sf /etc/nginx/sites-available/{domain} /etc/nginx/sites-enabled/")
|
|
160
|
+
run_command("sudo systemctl reload nginx")
|
|
161
|
+
|
|
162
|
+
print_yellow("Domain verifying...")
|
|
163
|
+
time.sleep(5)
|
|
164
|
+
|
|
165
|
+
verified = False
|
|
166
|
+
for url in [f"http://{domain}/nitroverify/auth.txt", f"https://{domain}/nitroverify/auth.txt"]:
|
|
167
|
+
try:
|
|
168
|
+
r = requests.get(url, timeout=5)
|
|
169
|
+
if "nitroverify-success" in r.text:
|
|
170
|
+
verified = True
|
|
171
|
+
break
|
|
172
|
+
except Exception:
|
|
173
|
+
continue
|
|
174
|
+
|
|
175
|
+
if not verified:
|
|
176
|
+
print_red("Domain Verification Failed, Check Records Carefully.")
|
|
177
|
+
run_command(f"sudo rm -f /etc/nginx/sites-available/{domain}")
|
|
178
|
+
run_command(f"sudo rm -f /etc/nginx/sites-enabled/{domain}")
|
|
179
|
+
run_command("sudo systemctl reload nginx")
|
|
180
|
+
sys.exit(1)
|
|
181
|
+
|
|
182
|
+
print_green("Domain Verification Success.\n")
|
|
183
|
+
|
|
184
|
+
run_command(f"sudo rm -f /etc/nginx/sites-available/{domain}")
|
|
185
|
+
run_command(f"sudo rm -f /etc/nginx/sites-enabled/{domain}")
|
|
186
|
+
run_command("sudo systemctl reload nginx")
|
|
187
|
+
|
|
188
|
+
nginx_conf = f"""
|
|
189
|
+
server {{
|
|
190
|
+
server_name {domain};
|
|
191
|
+
|
|
192
|
+
location / {{
|
|
193
|
+
proxy_pass http://127.0.0.1:{port};
|
|
194
|
+
proxy_set_header Host $host;
|
|
195
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
196
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
197
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
198
|
+
}}
|
|
199
|
+
|
|
200
|
+
listen 80;
|
|
201
|
+
}}
|
|
202
|
+
"""
|
|
203
|
+
conf_path = f"/etc/nginx/sites-available/{domain}"
|
|
204
|
+
with open(conf_path, "w") as f:
|
|
205
|
+
f.write(nginx_conf)
|
|
206
|
+
|
|
207
|
+
run_command(f"sudo ln -sf /etc/nginx/sites-available/{domain} /etc/nginx/sites-enabled/")
|
|
208
|
+
run_command("sudo systemctl reload nginx")
|
|
209
|
+
|
|
210
|
+
run_command(f"sudo certbot --nginx -d {domain} --non-interactive --agree-tos --email nitroexpose@gmail.com")
|
|
211
|
+
run_command("sudo systemctl reload nginx")
|
|
212
|
+
|
|
213
|
+
print_yellow("\nSSL Certificate Checking...")
|
|
214
|
+
time.sleep(2)
|
|
215
|
+
|
|
216
|
+
ssl_installed = False
|
|
217
|
+
try:
|
|
218
|
+
r = requests.get(f"https://{domain}", timeout=10)
|
|
219
|
+
if r.status_code == 200:
|
|
220
|
+
ssl_installed = True
|
|
221
|
+
except requests.exceptions.SSLError:
|
|
222
|
+
ssl_installed = False
|
|
223
|
+
except requests.exceptions.RequestException:
|
|
224
|
+
ssl_installed = False
|
|
225
|
+
|
|
226
|
+
print("\n")
|
|
227
|
+
if ssl_installed:
|
|
228
|
+
print_green(f"Exposed Successfully To Domain\n")
|
|
229
|
+
print_green(f"Exposed On: https://{domain}\n")
|
|
230
|
+
print_green(f"Port: {port}\n")
|
|
231
|
+
print_green(f"SSL Installed Using Let's Encrypt.\n\n")
|
|
232
|
+
else:
|
|
233
|
+
print_green(f"Exposed Successfully To Domain\n")
|
|
234
|
+
print_green(f"Exposed On: http://{domain}\n")
|
|
235
|
+
print_green(f"Port: {port}\n")
|
|
236
|
+
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")
|
|
237
|
+
|
|
238
|
+
if __name__ == "__main__":
|
|
239
|
+
main()
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: NitroExpose
|
|
3
|
+
Version: 1.1
|
|
4
|
+
Summary: Advanced CLI To Expose Port To Domain.
|
|
5
|
+
Home-page: https://github.com/yuvrajmodz/NitroExpose
|
|
6
|
+
Author: @NacDevs
|
|
7
|
+
Author-email: yuvrajmodz@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: requests
|
|
15
|
+
Dynamic: author
|
|
16
|
+
Dynamic: author-email
|
|
17
|
+
Dynamic: classifier
|
|
18
|
+
Dynamic: description
|
|
19
|
+
Dynamic: description-content-type
|
|
20
|
+
Dynamic: home-page
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
25
|
+
|
|
26
|
+
# NitroExpose
|
|
27
|
+
|
|
28
|
+
**Letest Version:** 1.1
|
|
29
|
+
**Developer:** @Nactire
|
|
30
|
+
**Git Repo:** [GitHub](https://github.com/yuvrajmodz/NitroExpose)
|
|
31
|
+
|
|
32
|
+
NitroExpose is a Python CLI tool to easily Expose Your Port to Domain.
|
|
33
|
+
|
|
34
|
+
## Installation & Usage
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install NitroExpose --break-system-packages
|
|
38
|
+
NitroExpose
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Optional installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
sudo apt update -y
|
|
45
|
+
sudo apt install nginx -y
|
|
46
|
+
sudo apt install certbot -y
|
|
47
|
+
sudo apt install python3-certbot-nginx -y
|
|
48
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
nitroexpose/__init__.py,sha256=jzli5z-wSkAiPccBUXLYoXWqtFxcoSs4cfupy9yjmFM,161
|
|
2
|
+
nitroexpose/cli.py,sha256=w-_FkSHlesCNsj8wGsr72OHkj2KqEN0vLGizs5RyxdA,7368
|
|
3
|
+
nitroexpose-1.1.dist-info/licenses/LICENSE,sha256=i_D1gc46cD__O4L8jy8izzueLV1F5ut89qyA6EOynaQ,255
|
|
4
|
+
nitroexpose-1.1.dist-info/METADATA,sha256=3VWltLjr975ofD2Q9DQ2Bvfw9XC1MWTM1ryYQ806_-s,1138
|
|
5
|
+
nitroexpose-1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
nitroexpose-1.1.dist-info/entry_points.txt,sha256=xmBtMDqH7wn0ZT8MtQYWLsEIZNvVqAi-F9nUrxVoq8w,53
|
|
7
|
+
nitroexpose-1.1.dist-info/top_level.txt,sha256=plDtsFeO3ei4PeJvvK2DjGFjFxZ4lnKSHHH4xeC8ei8,12
|
|
8
|
+
nitroexpose-1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nitroexpose
|