-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnginx_config.py
More file actions
executable file
·232 lines (200 loc) · 9.89 KB
/
nginx_config.py
File metadata and controls
executable file
·232 lines (200 loc) · 9.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
import argparse
import subprocess
import socket
import sys
import os
def run_command(command):
"""Execute a shell command and return its output, capturing errors."""
print(f"Executing command: {command}")
try:
result = subprocess.run(command, check=True, shell=True, text=True, capture_output=True)
return result.stdout.strip(), result.stderr.strip()
except subprocess.CalledProcessError as e:
error_output = e.stderr.strip()
print(f"Command '{command}' failed with error: {error_output}")
return None, error_output
def install_nginx():
"""Install Nginx using the appropriate package manager."""
print("Installing Nginx...")
if sys.platform.startswith('linux'):
print("Detected Linux platform.")
if run_command('which apt')[0]: # Check output of 'which apt'
print("Using apt package manager.")
run_command('sudo apt update')
run_command('sudo apt install nginx -y')
elif run_command('which yum')[0]: # Check output of 'which yum'
print("Using yum package manager.")
run_command('sudo yum install nginx -y')
else:
print("Unsupported Linux distribution. Please install Nginx manually.")
sys.exit(1)
else:
print("Unsupported operating system. Please install Nginx manually.")
sys.exit(1)
print("Nginx installed successfully.")
def generate_self_signed_cert(cert_dir, cert_name="nginx-selfsigned"):
"""Generate a self-signed SSL certificate."""
print(f"Generating self-signed SSL certificate in {cert_dir} with name {cert_name}...")
os.makedirs(cert_dir, exist_ok=True)
cert_path = os.path.join(cert_dir, f"{cert_name}.crt")
key_path = os.path.join(cert_dir, f"{cert_name}.key")
run_command(
f"openssl req -x509 -nodes -days 365 -newkey rsa:2048 "
f"-keyout {key_path} -out {cert_path} "
f'-subj "/C=US/ST=State/L=Location/O=Organization/CN=example.com"',
)
print(f"Certificate created at {cert_path} and key at {key_path}")
return cert_path, key_path
def clear_nginx_error_log():
"""Clear the Nginx error log file."""
error_log_path = '/var/log/nginx/error.log'
if os.path.exists(error_log_path):
print(f"Clearing old Nginx error log entries at {error_log_path}...")
run_command(f'sudo truncate -s 0 {error_log_path}')
def configure_nginx(args, cert_path, key_path):
"""Create a full Nginx configuration file based on provided arguments."""
print(f"Configuring Nginx with HTTP port {args.http_port} and HTTPS port {args.https_port}...")
config = f"""
user root;
worker_processes 1;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {{
worker_connections 1024;
}}
http {{
server {{
listen {args.http_port};
listen {args.https_port} ssl http2;
listen [::]:{args.https_port} ssl http2;
keepalive_timeout 70;
server_name {args.server_name};
ssl_ciphers {args.ssl_ciphers};
ssl_certificate {cert_path};
ssl_certificate_key {key_path};
ssl_protocols {args.ssl_protocols};
ssl_session_cache {args.ssl_session_cache};
ssl_session_tickets {args.ssl_session_tickets};
ssl_early_data {args.ssl_early_data};
ssl_ecdh_curve {args.ssl_ecdh_curve};
ssl_session_timeout {args.ssl_session_timeout};
root /var/www/html;
location / {{
}}
}}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
}}
"""
config_path = '/etc/nginx/nginx.conf'
try:
print(f"Writing configuration to {config_path}...")
with open(config_path, 'w') as f:
f.write(config)
print(f"Configuration written to {config_path}")
clear_nginx_error_log()
print("Testing Nginx configuration...")
stdout, stderr = run_command('sudo nginx -t')
if "successful" not in stdout.lower():
print("Nginx configuration test failed with the following error:")
print(stderr)
return
print(stdout) # Print successful test output
print("Restarting Nginx service...")
_, restart_error = run_command('sudo systemctl restart nginx')
if restart_error:
print("Failed to restart Nginx. Check if the service is configured correctly.")
print("For more details, examine the Nginx error log at /var/log/nginx/error.log.")
return
print("Nginx has been configured and restarted successfully.")
except Exception as e:
print(f"An error occurred while configuring Nginx: {e}")
def start_nginx():
"""Start the Nginx service."""
print("Starting Nginx service...")
_, start_error = run_command('sudo systemctl start nginx')
if start_error:
print(f"Failed to start Nginx: {start_error}")
else:
print("Nginx started successfully.")
def check_nginx_ports(http_port, https_port):
"""Check if Nginx is listening on specified ports."""
print(f"Checking if Nginx is listening on ports {http_port} and {https_port}...")
for port in (http_port, https_port):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
result = s.connect_ex(('localhost', int(port)))
if result == 0:
print(f"Nginx is listening on port {port}.")
else:
print(f"Error: Nginx is NOT listening on port {port}. Ensure the service is running and configured properly.")
print(f"Suggestions: Verify firewall settings, and ensure no other service is using port {port}.")
configure_firewall_and_check_services(port)
def configure_firewall_and_check_services(port):
"""Check firewall settings and if other services are using the port."""
print(f"Configuring firewall settings for port {port}...")
firewall_status, firewall_error = run_command(f'sudo ufw status | grep {port}')
if firewall_error:
print(f"Firewall command failed with error: {firewall_error}")
elif firewall_status and port in firewall_status:
print(f"Port {port} is allowed through the firewall.")
else:
print(f"Port {port} is not allowed through the firewall. You may need to open it.")
run_command(f'sudo ufw allow {port}/tcp')
print(f"Checking for other services using port {port}...")
port_usage, port_error = run_command(f'sudo lsof -i:{port}')
if port_error:
print(f"Port check command failed with error: {port_error}")
elif port_usage:
print(f"Another service might be using port {port}. Consider stopping or reconfiguring the conflicting service.")
def verify_nginx_configuration(args, cert_path, key_path):
"""Verify if the settings are applied in the Nginx configuration."""
print("Verifying Nginx configuration...")
try:
if os.path.exists('/etc/nginx/nginx.conf'):
with open('/etc/nginx/nginx.conf', 'r') as f:
config_content = f.read()
for setting in [
f"listen {args.http_port};",
f"listen {args.https_port} ssl http2;",
f"server_name {args.server_name};",
f"ssl_ciphers {args.ssl_ciphers};",
f"ssl_certificate {cert_path};",
f"ssl_certificate_key {key_path};",
f"ssl_protocols {args.ssl_protocols};",
f"ssl_session_cache {args.ssl_session_cache};",
f"ssl_session_timeout {args.ssl_session_timeout};",
]:
if setting in config_content:
print(f"Verified setting: {setting.strip()}")
else:
print(f"Missing setting: {setting.strip()}")
else:
print("Error: Configuration file not found at /etc/nginx/nginx.conf.")
except Exception as e:
print(f"An error occurred while verifying configuration: {e}")
def main():
"""Main function to parse arguments and configure Nginx."""
parser = argparse.ArgumentParser(description='Configure Nginx with dynamic options.')
parser.add_argument('--http-port', default='80', help='HTTP listen port (default: 80)')
parser.add_argument('--https-port', default='443', help='HTTPS listen port (default: 443)')
parser.add_argument('--server-name', default='ssl-automation.com', help='Server name (default: ssl-automation.com)')
parser.add_argument('--ssl-cert-dir', default='/etc/nginx/certs', help='Directory to store SSL certificates')
parser.add_argument('--ssl-protocols', default='TLSv1.1 TLSv1.2 TLSv1.3', help='SSL protocols (default: TLSv1.1 TLSv1.2 TLSv1.3)')
parser.add_argument('--ssl-ciphers', default='ALL:COMPLEMENTOFALL', help='SSL ciphers (default: ALL:COMPLEMENTOFALL)')
parser.add_argument('--ssl-session-cache', default='shared:SSL:10m', help='SSL session cache (default: shared:SSL:10m)')
parser.add_argument('--ssl-session-timeout', default='5m', help='SSL session timeout (default: 5m)')
parser.add_argument('--ssl-session-tickets', default='on', help='SSL session tickets (default: on)') # Added
parser.add_argument('--ssl-early-data', default='off', help='SSL early data (default: off)')
parser.add_argument('--ssl-ecdh-curve', default='auto', help='SSL ECDH curve (default: auto)')
args = parser.parse_args()
install_nginx()
cert_path, key_path = generate_self_signed_cert(args.ssl_cert_dir)
configure_nginx(args, cert_path, key_path)
start_nginx()
check_nginx_ports(args.http_port, args.https_port)
verify_nginx_configuration(args, cert_path, key_path)
if __name__ == "__main__":
main()