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.
- {nitroexpose-2.0 → nitroexpose-2.2/NitroExpose.egg-info}/PKG-INFO +41 -17
- nitroexpose-2.2/NitroExpose.egg-info/requires.txt +2 -0
- {nitroexpose-2.0/NitroExpose.egg-info → nitroexpose-2.2}/PKG-INFO +41 -17
- {nitroexpose-2.0 → nitroexpose-2.2}/README.md +39 -16
- nitroexpose-2.2/nitroexpose/cli.py +564 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/setup.py +3 -2
- nitroexpose-2.0/NitroExpose.egg-info/requires.txt +0 -1
- nitroexpose-2.0/nitroexpose/cli.py +0 -247
- {nitroexpose-2.0 → nitroexpose-2.2}/LICENSE +0 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/NitroExpose.egg-info/SOURCES.txt +0 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/NitroExpose.egg-info/dependency_links.txt +0 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/NitroExpose.egg-info/entry_points.txt +0 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/NitroExpose.egg-info/top_level.txt +0 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/nitroexpose/__init__.py +0 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/pyproject.toml +0 -0
- {nitroexpose-2.0 → nitroexpose-2.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: NitroExpose
|
|
3
|
-
Version: 2.
|
|
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.
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
Metadata-Version: 2.4
|
|
2
2
|
Name: NitroExpose
|
|
3
|
-
Version: 2.
|
|
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.
|
|
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
|
-
##
|
|
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
|
-
|
|
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.
|
|
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
|
-
##
|
|
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
|
-
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|